Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
245ac873
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
245ac873
编写于
6月 27, 2005
作者:
J
Jeff Garzik
浏览文件
操作
浏览文件
下载
差异文件
Merge upstream net/ieee80211.h changes into 'ieee80211' branch.
上级
716b4330
a5fe736e
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
934 addition
and
1375 deletion
+934
-1375
drivers/net/skge.c
drivers/net/skge.c
+829
-881
drivers/net/skge.h
drivers/net/skge.h
+104
-482
include/linux/etherdevice.h
include/linux/etherdevice.h
+1
-1
include/net/ieee80211.h
include/net/ieee80211.h
+0
-11
未找到文件。
drivers/net/skge.c
浏览文件 @
245ac873
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* of the original driver such as link fail-over and link management because
* of the original driver such as link fail-over and link management because
* those should be done at higher levels.
* those should be done at higher levels.
*
*
* Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
* Copyright (C) 2004,
2005
Stephen Hemminger <shemminger@osdl.org>
*
*
* This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by
...
@@ -42,19 +42,20 @@
...
@@ -42,19 +42,20 @@
#include "skge.h"
#include "skge.h"
#define DRV_NAME "skge"
#define DRV_NAME "skge"
#define DRV_VERSION "0.
6
"
#define DRV_VERSION "0.
7
"
#define PFX DRV_NAME " "
#define PFX DRV_NAME " "
#define DEFAULT_TX_RING_SIZE 128
#define DEFAULT_TX_RING_SIZE 128
#define DEFAULT_RX_RING_SIZE 512
#define DEFAULT_RX_RING_SIZE 512
#define MAX_TX_RING_SIZE 1024
#define MAX_TX_RING_SIZE 1024
#define MAX_RX_RING_SIZE 4096
#define MAX_RX_RING_SIZE 4096
#define RX_COPY_THRESHOLD 128
#define RX_BUF_SIZE 1536
#define PHY_RETRIES 1000
#define PHY_RETRIES 1000
#define ETH_JUMBO_MTU 9000
#define ETH_JUMBO_MTU 9000
#define TX_WATCHDOG (5 * HZ)
#define TX_WATCHDOG (5 * HZ)
#define NAPI_WEIGHT 64
#define NAPI_WEIGHT 64
#define BLINK_HZ (HZ/4)
#define BLINK_HZ (HZ/4)
#define LINK_POLL_HZ (HZ/10)
MODULE_DESCRIPTION
(
"SysKonnect Gigabit Ethernet driver"
);
MODULE_DESCRIPTION
(
"SysKonnect Gigabit Ethernet driver"
);
MODULE_AUTHOR
(
"Stephen Hemminger <shemminger@osdl.org>"
);
MODULE_AUTHOR
(
"Stephen Hemminger <shemminger@osdl.org>"
);
...
@@ -70,28 +71,17 @@ module_param(debug, int, 0);
...
@@ -70,28 +71,17 @@ module_param(debug, int, 0);
MODULE_PARM_DESC
(
debug
,
"Debug level (0=none,...,16=all)"
);
MODULE_PARM_DESC
(
debug
,
"Debug level (0=none,...,16=all)"
);
static
const
struct
pci_device_id
skge_id_table
[]
=
{
static
const
struct
pci_device_id
skge_id_table
[]
=
{
{
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940
,
{
PCI_DEVICE
(
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940
)
},
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940B
)
},
{
PCI_VENDOR_ID_3COM
,
PCI_DEVICE_ID_3COM_3C940B
,
{
PCI_DEVICE
(
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_GE
)
},
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_YU
)
},
{
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_GE
,
{
PCI_DEVICE
(
PCI_VENDOR_ID_SYSKONNECT
,
0x9E00
)
},
/* SK-9Exx */
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_DLINK
,
PCI_DEVICE_ID_DLINK_DGE510T
),
},
{
PCI_VENDOR_ID_SYSKONNECT
,
PCI_DEVICE_ID_SYSKONNECT_YU
,
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x4320
)
},
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x5005
)
},
/* Belkin */
{
PCI_VENDOR_ID_SYSKONNECT
,
0x9E00
,
/* SK-9Exx */
{
PCI_DEVICE
(
PCI_VENDOR_ID_CNET
,
PCI_DEVICE_ID_CNET_GIGACARD
)
},
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1032
)
},
{
PCI_VENDOR_ID_DLINK
,
PCI_DEVICE_ID_DLINK_DGE510T
,
{
PCI_DEVICE
(
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1064
)
},
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_MARVELL
,
0x4320
,
/* Gigabit Ethernet Controller */
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_MARVELL
,
0x5005
,
/* Marvell (11ab), Belkin */
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_CNET
,
PCI_DEVICE_ID_CNET_GIGACARD
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1032
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_LINKSYS
,
PCI_DEVICE_ID_LINKSYS_EG1064
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
0
}
{
0
}
};
};
MODULE_DEVICE_TABLE
(
pci
,
skge_id_table
);
MODULE_DEVICE_TABLE
(
pci
,
skge_id_table
);
...
@@ -99,19 +89,22 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
...
@@ -99,19 +89,22 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
static
int
skge_up
(
struct
net_device
*
dev
);
static
int
skge_up
(
struct
net_device
*
dev
);
static
int
skge_down
(
struct
net_device
*
dev
);
static
int
skge_down
(
struct
net_device
*
dev
);
static
void
skge_tx_clean
(
struct
skge_port
*
skge
);
static
void
skge_tx_clean
(
struct
skge_port
*
skge
);
static
void
skge_
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
skge_
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
);
static
void
genesis_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
);
static
void
genesis_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
);
static
void
yukon_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
);
static
void
yukon_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
);
static
void
yukon_init
(
struct
skge_hw
*
hw
,
int
port
);
static
void
yukon_init
(
struct
skge_hw
*
hw
,
int
port
);
static
void
yukon_reset
(
struct
skge_hw
*
hw
,
int
port
);
static
void
yukon_reset
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_mac_init
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_mac_init
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_reset
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_reset
(
struct
skge_hw
*
hw
,
int
port
);
static
void
genesis_link_up
(
struct
skge_port
*
skge
);
/* Avoid conditionals by using array */
static
const
int
txqaddr
[]
=
{
Q_XA1
,
Q_XA2
};
static
const
int
txqaddr
[]
=
{
Q_XA1
,
Q_XA2
};
static
const
int
rxqaddr
[]
=
{
Q_R1
,
Q_R2
};
static
const
int
rxqaddr
[]
=
{
Q_R1
,
Q_R2
};
static
const
u32
rxirqmask
[]
=
{
IS_R1_F
,
IS_R2_F
};
static
const
u32
rxirqmask
[]
=
{
IS_R1_F
,
IS_R2_F
};
static
const
u32
txirqmask
[]
=
{
IS_XA1_F
,
IS_XA2_F
};
static
const
u32
txirqmask
[]
=
{
IS_XA1_F
,
IS_XA2_F
};
static
const
u32
portirqmask
[]
=
{
IS_PORT_1
,
IS_PORT_2
};
/* Don't need to look at whole 16K.
/* Don't need to look at whole 16K.
* last interesting register is descriptor poll timer.
* last interesting register is descriptor poll timer.
...
@@ -154,7 +147,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
...
@@ -154,7 +147,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
static
int
wol_supported
(
const
struct
skge_hw
*
hw
)
static
int
wol_supported
(
const
struct
skge_hw
*
hw
)
{
{
return
!
((
hw
->
chip_id
==
CHIP_ID_GENESIS
||
return
!
((
hw
->
chip_id
==
CHIP_ID_GENESIS
||
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
chip_rev
(
hw
)
==
0
)));
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
hw
->
chip_rev
==
0
)));
}
}
static
void
skge_get_wol
(
struct
net_device
*
dev
,
struct
ethtool_wolinfo
*
wol
)
static
void
skge_get_wol
(
struct
net_device
*
dev
,
struct
ethtool_wolinfo
*
wol
)
...
@@ -170,7 +163,7 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
...
@@ -170,7 +163,7 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_hw
*
hw
=
skge
->
hw
;
struct
skge_hw
*
hw
=
skge
->
hw
;
if
(
wol
->
wolopts
!=
WAKE_MAGIC
&&
wol
->
wolopts
!=
0
)
if
(
wol
->
wolopts
!=
WAKE_MAGIC
&&
wol
->
wolopts
!=
0
)
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
if
(
wol
->
wolopts
==
WAKE_MAGIC
&&
!
wol_supported
(
hw
))
if
(
wol
->
wolopts
==
WAKE_MAGIC
&&
!
wol_supported
(
hw
))
...
@@ -190,6 +183,36 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
...
@@ -190,6 +183,36 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return
0
;
return
0
;
}
}
/* Determine supported/adverised modes based on hardware.
* Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
*/
static
u32
skge_supported_modes
(
const
struct
skge_hw
*
hw
)
{
u32
supported
;
if
(
iscopper
(
hw
))
{
supported
=
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_1000baseT_Half
|
SUPPORTED_1000baseT_Full
|
SUPPORTED_Autoneg
|
SUPPORTED_TP
;
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
supported
&=
~
(
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
);
else
if
(
hw
->
chip_id
==
CHIP_ID_YUKON
)
supported
&=
~
SUPPORTED_1000baseT_Half
;
}
else
supported
=
SUPPORTED_1000baseT_Full
|
SUPPORTED_FIBRE
|
SUPPORTED_Autoneg
;
return
supported
;
}
static
int
skge_get_settings
(
struct
net_device
*
dev
,
static
int
skge_get_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
ecmd
)
struct
ethtool_cmd
*
ecmd
)
...
@@ -198,38 +221,13 @@ static int skge_get_settings(struct net_device *dev,
...
@@ -198,38 +221,13 @@ static int skge_get_settings(struct net_device *dev,
struct
skge_hw
*
hw
=
skge
->
hw
;
struct
skge_hw
*
hw
=
skge
->
hw
;
ecmd
->
transceiver
=
XCVR_INTERNAL
;
ecmd
->
transceiver
=
XCVR_INTERNAL
;
ecmd
->
supported
=
skge_supported_modes
(
hw
);
if
(
iscopper
(
hw
))
{
if
(
iscopper
(
hw
))
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
ecmd
->
supported
=
SUPPORTED_1000baseT_Full
|
SUPPORTED_1000baseT_Half
|
SUPPORTED_Autoneg
|
SUPPORTED_TP
;
else
{
ecmd
->
supported
=
SUPPORTED_10baseT_Half
|
SUPPORTED_10baseT_Full
|
SUPPORTED_100baseT_Half
|
SUPPORTED_100baseT_Full
|
SUPPORTED_1000baseT_Half
|
SUPPORTED_1000baseT_Full
|
SUPPORTED_Autoneg
|
SUPPORTED_TP
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON
)
ecmd
->
supported
&=
~
SUPPORTED_1000baseT_Half
;
else
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
ecmd
->
supported
&=
~
(
SUPPORTED_1000baseT_Half
|
SUPPORTED_1000baseT_Full
);
}
ecmd
->
port
=
PORT_TP
;
ecmd
->
port
=
PORT_TP
;
ecmd
->
phy_address
=
hw
->
phy_addr
;
ecmd
->
phy_address
=
hw
->
phy_addr
;
}
else
{
}
else
ecmd
->
supported
=
SUPPORTED_1000baseT_Full
|
SUPPORTED_FIBRE
|
SUPPORTED_Autoneg
;
ecmd
->
port
=
PORT_FIBRE
;
ecmd
->
port
=
PORT_FIBRE
;
}
ecmd
->
advertising
=
skge
->
advertising
;
ecmd
->
advertising
=
skge
->
advertising
;
ecmd
->
autoneg
=
skge
->
autoneg
;
ecmd
->
autoneg
=
skge
->
autoneg
;
...
@@ -238,65 +236,57 @@ static int skge_get_settings(struct net_device *dev,
...
@@ -238,65 +236,57 @@ static int skge_get_settings(struct net_device *dev,
return
0
;
return
0
;
}
}
static
u32
skge_modes
(
const
struct
skge_hw
*
hw
)
{
u32
modes
=
ADVERTISED_Autoneg
|
ADVERTISED_1000baseT_Full
|
ADVERTISED_1000baseT_Half
|
ADVERTISED_100baseT_Full
|
ADVERTISED_100baseT_Half
|
ADVERTISED_10baseT_Full
|
ADVERTISED_10baseT_Half
;
if
(
iscopper
(
hw
))
{
modes
|=
ADVERTISED_TP
;
switch
(
hw
->
chip_id
)
{
case
CHIP_ID_GENESIS
:
modes
&=
~
(
ADVERTISED_100baseT_Full
|
ADVERTISED_100baseT_Half
|
ADVERTISED_10baseT_Full
|
ADVERTISED_10baseT_Half
);
break
;
case
CHIP_ID_YUKON
:
modes
&=
~
ADVERTISED_1000baseT_Half
;
break
;
case
CHIP_ID_YUKON_FE
:
modes
&=
~
(
ADVERTISED_1000baseT_Half
|
ADVERTISED_1000baseT_Full
);
break
;
}
}
else
{
modes
|=
ADVERTISED_FIBRE
;
modes
&=
~
ADVERTISED_1000baseT_Half
;
}
return
modes
;
}
static
int
skge_set_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
ecmd
)
static
int
skge_set_settings
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
ecmd
)
{
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
const
struct
skge_hw
*
hw
=
skge
->
hw
;
const
struct
skge_hw
*
hw
=
skge
->
hw
;
u32
supported
=
skge_supported_modes
(
hw
);
if
(
ecmd
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
ecmd
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
ecmd
->
advertising
&
skge_modes
(
hw
))
ecmd
->
advertising
=
supported
;
return
-
EINVAL
;
skge
->
duplex
=
-
1
;
skge
->
speed
=
-
1
;
}
else
{
}
else
{
u32
setting
;
switch
(
ecmd
->
speed
)
{
switch
(
ecmd
->
speed
)
{
case
SPEED_1000
:
case
SPEED_1000
:
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
setting
=
SUPPORTED_1000baseT_Full
;
else
if
(
ecmd
->
duplex
==
DUPLEX_HALF
)
setting
=
SUPPORTED_1000baseT_Half
;
else
return
-
EINVAL
;
return
-
EINVAL
;
break
;
break
;
case
SPEED_100
:
case
SPEED_100
:
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
setting
=
SUPPORTED_100baseT_Full
;
else
if
(
ecmd
->
duplex
==
DUPLEX_HALF
)
setting
=
SUPPORTED_100baseT_Half
;
else
return
-
EINVAL
;
break
;
case
SPEED_10
:
case
SPEED_10
:
if
(
iscopper
(
hw
)
||
hw
->
chip_id
==
CHIP_ID_GENESIS
)
if
(
ecmd
->
duplex
==
DUPLEX_FULL
)
setting
=
SUPPORTED_10baseT_Full
;
else
if
(
ecmd
->
duplex
==
DUPLEX_HALF
)
setting
=
SUPPORTED_10baseT_Half
;
else
return
-
EINVAL
;
return
-
EINVAL
;
break
;
break
;
default:
default:
return
-
EINVAL
;
return
-
EINVAL
;
}
}
if
((
setting
&
supported
)
==
0
)
return
-
EINVAL
;
skge
->
speed
=
ecmd
->
speed
;
skge
->
duplex
=
ecmd
->
duplex
;
}
}
skge
->
autoneg
=
ecmd
->
autoneg
;
skge
->
autoneg
=
ecmd
->
autoneg
;
skge
->
speed
=
ecmd
->
speed
;
skge
->
duplex
=
ecmd
->
duplex
;
skge
->
advertising
=
ecmd
->
advertising
;
skge
->
advertising
=
ecmd
->
advertising
;
if
(
netif_running
(
dev
))
{
if
(
netif_running
(
dev
))
{
...
@@ -393,7 +383,7 @@ static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data)
...
@@ -393,7 +383,7 @@ static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
{
int
i
;
int
i
;
switch
(
stringset
)
{
switch
(
stringset
)
{
case
ETH_SS_STATS
:
case
ETH_SS_STATS
:
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
memcpy
(
data
+
i
*
ETH_GSTRING_LEN
,
memcpy
(
data
+
i
*
ETH_GSTRING_LEN
,
...
@@ -511,14 +501,6 @@ static int skge_set_rx_csum(struct net_device *dev, u32 data)
...
@@ -511,14 +501,6 @@ static int skge_set_rx_csum(struct net_device *dev, u32 data)
return
0
;
return
0
;
}
}
/* Only Yukon II supports TSO (not implemented yet) */
static
int
skge_set_tso
(
struct
net_device
*
dev
,
u32
data
)
{
if
(
data
)
return
-
EOPNOTSUPP
;
return
0
;
}
static
void
skge_get_pauseparam
(
struct
net_device
*
dev
,
static
void
skge_get_pauseparam
(
struct
net_device
*
dev
,
struct
ethtool_pauseparam
*
ecmd
)
struct
ethtool_pauseparam
*
ecmd
)
{
{
...
@@ -540,9 +522,9 @@ static int skge_set_pauseparam(struct net_device *dev,
...
@@ -540,9 +522,9 @@ static int skge_set_pauseparam(struct net_device *dev,
skge
->
autoneg
=
ecmd
->
autoneg
;
skge
->
autoneg
=
ecmd
->
autoneg
;
if
(
ecmd
->
rx_pause
&&
ecmd
->
tx_pause
)
if
(
ecmd
->
rx_pause
&&
ecmd
->
tx_pause
)
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
else
if
(
ecmd
->
rx_pause
&&
!
ecmd
->
tx_pause
)
else
if
(
ecmd
->
rx_pause
&&
!
ecmd
->
tx_pause
)
skge
->
flow_control
=
FLOW_MODE_REM_SEND
;
skge
->
flow_control
=
FLOW_MODE_REM_SEND
;
else
if
(
!
ecmd
->
rx_pause
&&
ecmd
->
tx_pause
)
else
if
(
!
ecmd
->
rx_pause
&&
ecmd
->
tx_pause
)
skge
->
flow_control
=
FLOW_MODE_LOC_SEND
;
skge
->
flow_control
=
FLOW_MODE_LOC_SEND
;
else
else
skge
->
flow_control
=
FLOW_MODE_NONE
;
skge
->
flow_control
=
FLOW_MODE_NONE
;
...
@@ -559,8 +541,6 @@ static inline u32 hwkhz(const struct skge_hw *hw)
...
@@ -559,8 +541,6 @@ static inline u32 hwkhz(const struct skge_hw *hw)
{
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
return
53215
;
/* or: 53.125 MHz */
return
53215
;
/* or: 53.125 MHz */
else
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_EC
)
return
125000
;
/* or: 125.000 MHz */
else
else
return
78215
;
/* or: 78.125 MHz */
return
78215
;
/* or: 78.125 MHz */
}
}
...
@@ -643,30 +623,18 @@ static int skge_set_coalesce(struct net_device *dev,
...
@@ -643,30 +623,18 @@ static int skge_set_coalesce(struct net_device *dev,
static
void
skge_led_on
(
struct
skge_hw
*
hw
,
int
port
)
static
void
skge_led_on
(
struct
skge_hw
*
hw
,
int
port
)
{
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
B0_LED
,
LED_STAT_ON
);
skge_write8
(
hw
,
B0_LED
,
LED_STAT_ON
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_TST
),
LED_T_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_TST
),
LED_T_ON
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_VAL
),
100
);
skge_write32
(
hw
,
SK_REG
(
port
,
RX_LED_VAL
),
100
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
switch
(
hw
->
phy_type
)
{
/* For Broadcom Phy only */
case
SK_PHY_BCOM
:
xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_ON
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_ON
);
break
;
case
SK_PHY_LONE
:
skge_xm_phy_write
(
hw
,
port
,
PHY_LONE_LED_CFG
,
0x0800
);
break
;
default:
skge_write8
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_TST
),
LED_T_ON
);
skge_write32
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_VAL
),
100
);
skge_write8
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_CTRL
),
LED_START
);
}
}
else
{
}
else
{
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
PHY_M_LED_MO_DUP
(
MO_LED_ON
)
|
PHY_M_LED_MO_DUP
(
MO_LED_ON
)
|
PHY_M_LED_MO_10
(
MO_LED_ON
)
|
PHY_M_LED_MO_10
(
MO_LED_ON
)
|
PHY_M_LED_MO_100
(
MO_LED_ON
)
|
PHY_M_LED_MO_100
(
MO_LED_ON
)
|
...
@@ -678,28 +646,17 @@ static void skge_led_on(struct skge_hw *hw, int port)
...
@@ -678,28 +646,17 @@ static void skge_led_on(struct skge_hw *hw, int port)
static
void
skge_led_off
(
struct
skge_hw
*
hw
,
int
port
)
static
void
skge_led_off
(
struct
skge_hw
*
hw
,
int
port
)
{
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_OFF
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_OFF
);
skge_write8
(
hw
,
B0_LED
,
LED_STAT_OFF
);
skge_write8
(
hw
,
B0_LED
,
LED_STAT_OFF
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_VAL
),
0
);
skge_write32
(
hw
,
SK_REG
(
port
,
RX_LED_VAL
),
0
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_T_OFF
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_T_OFF
);
switch
(
hw
->
phy_type
)
{
/* Broadcom only */
case
SK_PHY_BCOM
:
xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_OFF
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
PHY_B_PEC_LED_OFF
);
break
;
case
SK_PHY_LONE
:
skge_xm_phy_write
(
hw
,
port
,
PHY_LONE_LED_CFG
,
PHY_L_LC_LEDT
);
break
;
default:
skge_write32
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_VAL
),
0
);
skge_write8
(
hw
,
SKGEMAC_REG
(
port
,
TX_LED_CTRL
),
LED_T_OFF
);
}
}
else
{
}
else
{
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
0
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
PHY_M_LED_MO_DUP
(
MO_LED_OFF
)
|
PHY_M_LED_MO_DUP
(
MO_LED_OFF
)
|
PHY_M_LED_MO_10
(
MO_LED_OFF
)
|
PHY_M_LED_MO_10
(
MO_LED_OFF
)
|
PHY_M_LED_MO_100
(
MO_LED_OFF
)
|
PHY_M_LED_MO_100
(
MO_LED_OFF
)
|
...
@@ -730,7 +687,7 @@ static int skge_phys_id(struct net_device *dev, u32 data)
...
@@ -730,7 +687,7 @@ static int skge_phys_id(struct net_device *dev, u32 data)
{
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
if
(
!
data
||
data
>
(
u32
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
))
if
(
!
data
||
data
>
(
u32
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
))
data
=
(
u32
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
);
data
=
(
u32
)(
MAX_SCHEDULE_TIMEOUT
/
HZ
);
/* start blinking */
/* start blinking */
...
@@ -763,8 +720,6 @@ static struct ethtool_ops skge_ethtool_ops = {
...
@@ -763,8 +720,6 @@ static struct ethtool_ops skge_ethtool_ops = {
.
set_pauseparam
=
skge_set_pauseparam
,
.
set_pauseparam
=
skge_set_pauseparam
,
.
get_coalesce
=
skge_get_coalesce
,
.
get_coalesce
=
skge_get_coalesce
,
.
set_coalesce
=
skge_set_coalesce
,
.
set_coalesce
=
skge_set_coalesce
,
.
get_tso
=
ethtool_op_get_tso
,
.
set_tso
=
skge_set_tso
,
.
get_sg
=
ethtool_op_get_sg
,
.
get_sg
=
ethtool_op_get_sg
,
.
set_sg
=
skge_set_sg
,
.
set_sg
=
skge_set_sg
,
.
get_tx_csum
=
ethtool_op_get_tx_csum
,
.
get_tx_csum
=
ethtool_op_get_tx_csum
,
...
@@ -793,6 +748,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
...
@@ -793,6 +748,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
for
(
i
=
0
,
e
=
ring
->
start
,
d
=
vaddr
;
i
<
ring
->
count
;
i
++
,
e
++
,
d
++
)
{
for
(
i
=
0
,
e
=
ring
->
start
,
d
=
vaddr
;
i
<
ring
->
count
;
i
++
,
e
++
,
d
++
)
{
e
->
desc
=
d
;
e
->
desc
=
d
;
e
->
skb
=
NULL
;
if
(
i
==
ring
->
count
-
1
)
{
if
(
i
==
ring
->
count
-
1
)
{
e
->
next
=
ring
->
start
;
e
->
next
=
ring
->
start
;
d
->
next_offset
=
base
;
d
->
next_offset
=
base
;
...
@@ -806,24 +762,23 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
...
@@ -806,24 +762,23 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
return
0
;
return
0
;
}
}
/* Setup buffer for receiving */
static
struct
sk_buff
*
skge_rx_alloc
(
struct
net_device
*
dev
,
unsigned
int
size
)
static
inline
int
skge_rx_alloc
(
struct
skge_port
*
skge
,
struct
skge_element
*
e
)
{
{
unsigned
long
bufsize
=
skge
->
netdev
->
mtu
+
ETH_HLEN
;
/* VLAN? */
struct
sk_buff
*
skb
=
dev_alloc_skb
(
size
);
struct
skge_rx_desc
*
rd
=
e
->
desc
;
struct
sk_buff
*
skb
;
u64
map
;
skb
=
dev_alloc_skb
(
bufsize
+
NET_IP_ALIGN
);
if
(
likely
(
skb
))
{
if
(
unlikely
(
!
skb
))
{
skb
->
dev
=
dev
;
printk
(
KERN_DEBUG
PFX
"%s: out of memory for receive
\n
"
,
skb_reserve
(
skb
,
NET_IP_ALIGN
);
skge
->
netdev
->
name
);
return
-
ENOMEM
;
}
}
return
skb
;
}
skb
->
dev
=
skge
->
netdev
;
/* Allocate and setup a new buffer for receiving */
skb_reserve
(
skb
,
NET_IP_ALIGN
);
static
void
skge_rx_setup
(
struct
skge_port
*
skge
,
struct
skge_element
*
e
,
struct
sk_buff
*
skb
,
unsigned
int
bufsize
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
u64
map
;
map
=
pci_map_single
(
skge
->
hw
->
pdev
,
skb
->
data
,
bufsize
,
map
=
pci_map_single
(
skge
->
hw
->
pdev
,
skb
->
data
,
bufsize
,
PCI_DMA_FROMDEVICE
);
PCI_DMA_FROMDEVICE
);
...
@@ -841,55 +796,69 @@ static inline int skge_rx_alloc(struct skge_port *skge,
...
@@ -841,55 +796,69 @@ static inline int skge_rx_alloc(struct skge_port *skge,
rd
->
control
=
BMU_OWN
|
BMU_STF
|
BMU_IRQ_EOF
|
BMU_TCP_CHECK
|
bufsize
;
rd
->
control
=
BMU_OWN
|
BMU_STF
|
BMU_IRQ_EOF
|
BMU_TCP_CHECK
|
bufsize
;
pci_unmap_addr_set
(
e
,
mapaddr
,
map
);
pci_unmap_addr_set
(
e
,
mapaddr
,
map
);
pci_unmap_len_set
(
e
,
maplen
,
bufsize
);
pci_unmap_len_set
(
e
,
maplen
,
bufsize
);
return
0
;
}
}
/* Free all unused buffers in receive ring, assumes receiver stopped */
/* Resume receiving using existing skb,
* Note: DMA address is not changed by chip.
* MTU not changed while receiver active.
*/
static
void
skge_rx_reuse
(
struct
skge_element
*
e
,
unsigned
int
size
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
rd
->
csum2
=
0
;
rd
->
csum2_start
=
ETH_HLEN
;
wmb
();
rd
->
control
=
BMU_OWN
|
BMU_STF
|
BMU_IRQ_EOF
|
BMU_TCP_CHECK
|
size
;
}
/* Free all buffers in receive ring, assumes receiver stopped */
static
void
skge_rx_clean
(
struct
skge_port
*
skge
)
static
void
skge_rx_clean
(
struct
skge_port
*
skge
)
{
{
struct
skge_hw
*
hw
=
skge
->
hw
;
struct
skge_hw
*
hw
=
skge
->
hw
;
struct
skge_ring
*
ring
=
&
skge
->
rx_ring
;
struct
skge_ring
*
ring
=
&
skge
->
rx_ring
;
struct
skge_element
*
e
;
struct
skge_element
*
e
;
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
;
e
=
e
->
next
)
{
e
=
ring
->
start
;
do
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
struct
skge_rx_desc
*
rd
=
e
->
desc
;
rd
->
control
=
0
;
rd
->
control
=
0
;
if
(
e
->
skb
)
{
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_len
(
e
,
maplen
),
pci_unmap_len
(
e
,
maplen
),
PCI_DMA_FROMDEVICE
);
PCI_DMA_FROMDEVICE
);
dev_kfree_skb
(
e
->
skb
);
dev_kfree_skb
(
e
->
skb
);
e
->
skb
=
NULL
;
e
->
skb
=
NULL
;
}
}
ring
->
to_clean
=
e
;
}
while
((
e
=
e
->
next
)
!=
ring
->
start
)
;
}
}
/* Allocate buffers for receive ring
/* Allocate buffers for receive ring
* For receive: to_use is refill location
* For receive: to_clean is next received frame.
* to_clean is next received frame.
*
* if (to_use == to_clean)
* then ring all frames in ring need buffers
* if (to_use->next == to_clean)
* then ring all frames in ring have buffers
*/
*/
static
int
skge_rx_fill
(
struct
skge_port
*
skge
)
static
int
skge_rx_fill
(
struct
skge_port
*
skge
)
{
{
struct
skge_ring
*
ring
=
&
skge
->
rx_ring
;
struct
skge_ring
*
ring
=
&
skge
->
rx_ring
;
struct
skge_element
*
e
;
struct
skge_element
*
e
;
int
ret
=
0
;
unsigned
int
bufsize
=
skge
->
rx_buf_size
;
for
(
e
=
ring
->
to_use
;
e
->
next
!=
ring
->
to_clean
;
e
=
e
->
next
)
{
e
=
ring
->
start
;
if
(
skge_rx_alloc
(
skge
,
e
))
{
do
{
ret
=
1
;
struct
sk_buff
*
skb
=
skge_rx_alloc
(
skge
->
netdev
,
bufsize
);
break
;
}
}
if
(
!
skb
)
ring
->
to_use
=
e
;
return
-
ENOMEM
;
skge_rx_setup
(
skge
,
e
,
skb
,
bufsize
);
}
while
(
(
e
=
e
->
next
)
!=
ring
->
start
);
return
ret
;
ring
->
to_clean
=
ring
->
start
;
return
0
;
}
}
static
void
skge_link_up
(
struct
skge_port
*
skge
)
static
void
skge_link_up
(
struct
skge_port
*
skge
)
...
@@ -919,50 +888,50 @@ static void skge_link_down(struct skge_port *skge)
...
@@ -919,50 +888,50 @@ static void skge_link_down(struct skge_port *skge)
printk
(
KERN_INFO
PFX
"%s: Link is down.
\n
"
,
skge
->
netdev
->
name
);
printk
(
KERN_INFO
PFX
"%s: Link is down.
\n
"
,
skge
->
netdev
->
name
);
}
}
static
u16
skge_xm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
static
u16
xm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
{
{
int
i
;
int
i
;
u16
v
;
u16
v
;
skge_xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
v
=
skge_xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
v
=
xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
{
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
if
(
skge_xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_RDY
)
goto
ready
;
}
printk
(
KERN_WARNING
PFX
"%s: phy read timed out
\n
"
,
/* Need to wait for external PHY */
hw
->
dev
[
port
]
->
name
);
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
return
0
;
udelay
(
1
);
ready:
if
(
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
v
=
skge_xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
&
XM_MMU_PHY_RDY
)
goto
ready
;
}
}
printk
(
KERN_WARNING
PFX
"%s: phy read timed out
\n
"
,
hw
->
dev
[
port
]
->
name
);
return
0
;
ready:
v
=
xm_read16
(
hw
,
port
,
XM_PHY_DATA
);
return
v
;
return
v
;
}
}
static
void
skge_
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
static
void
xm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
{
{
int
i
;
int
i
;
skge_
xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
xm_write16
(
hw
,
port
,
XM_PHY_ADDR
,
reg
|
hw
->
phy_addr
);
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
if
(
!
(
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
if
(
!
(
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
goto
ready
;
goto
ready
;
cpu_relax
(
);
udelay
(
1
);
}
}
printk
(
KERN_WARNING
PFX
"%s: phy write failed to come ready
\n
"
,
printk
(
KERN_WARNING
PFX
"%s: phy write failed to come ready
\n
"
,
hw
->
dev
[
port
]
->
name
);
hw
->
dev
[
port
]
->
name
);
ready:
ready:
skge_
xm_write16
(
hw
,
port
,
XM_PHY_DATA
,
val
);
xm_write16
(
hw
,
port
,
XM_PHY_DATA
,
val
);
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
udelay
(
1
);
if
(
!
(
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
if
(
!
(
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
XM_MMU_PHY_BUSY
))
return
;
return
;
}
}
printk
(
KERN_WARNING
PFX
"%s: phy write timed out
\n
"
,
printk
(
KERN_WARNING
PFX
"%s: phy write timed out
\n
"
,
...
@@ -999,34 +968,112 @@ static void genesis_init(struct skge_hw *hw)
...
@@ -999,34 +968,112 @@ static void genesis_init(struct skge_hw *hw)
static
void
genesis_reset
(
struct
skge_hw
*
hw
,
int
port
)
static
void
genesis_reset
(
struct
skge_hw
*
hw
,
int
port
)
{
{
int
i
;
const
u8
zero
[
8
]
=
{
0
};
u64
zero
=
0
;
/* reset the statistics module */
/* reset the statistics module */
skge_
xm_write32
(
hw
,
port
,
XM_GP_PORT
,
XM_GP_RES_STAT
);
xm_write32
(
hw
,
port
,
XM_GP_PORT
,
XM_GP_RES_STAT
);
skge_
xm_write16
(
hw
,
port
,
XM_IMSK
,
0xffff
);
/* disable XMAC IRQs */
xm_write16
(
hw
,
port
,
XM_IMSK
,
0xffff
);
/* disable XMAC IRQs */
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
0
);
/* clear Mode Reg */
xm_write32
(
hw
,
port
,
XM_MODE
,
0
);
/* clear Mode Reg */
skge_
xm_write16
(
hw
,
port
,
XM_TX_CMD
,
0
);
/* reset TX CMD Reg */
xm_write16
(
hw
,
port
,
XM_TX_CMD
,
0
);
/* reset TX CMD Reg */
skge_
xm_write16
(
hw
,
port
,
XM_RX_CMD
,
0
);
/* reset RX CMD Reg */
xm_write16
(
hw
,
port
,
XM_RX_CMD
,
0
);
/* reset RX CMD Reg */
/* disable all PHY IRQs */
/* disable Broadcom PHY IRQ */
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
xm_write16
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
0xffff
);
skge_xm_write16
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
0xffff
);
skge_xm_outhash
(
hw
,
port
,
XM_HSM
,
(
u8
*
)
&
zero
);
xm_outhash
(
hw
,
port
,
XM_HSM
,
zero
);
for
(
i
=
0
;
i
<
15
;
i
++
)
skge_xm_outaddr
(
hw
,
port
,
XM_EXM
(
i
),
(
u8
*
)
&
zero
);
skge_xm_outhash
(
hw
,
port
,
XM_SRC_CHK
,
(
u8
*
)
&
zero
);
}
}
static
void
genesis_mac_init
(
struct
skge_hw
*
hw
,
int
port
)
/* Convert mode to MII values */
static
const
u16
phy_pause_map
[]
=
{
[
FLOW_MODE_NONE
]
=
0
,
[
FLOW_MODE_LOC_SEND
]
=
PHY_AN_PAUSE_ASYM
,
[
FLOW_MODE_SYMMETRIC
]
=
PHY_AN_PAUSE_CAP
,
[
FLOW_MODE_REM_SEND
]
=
PHY_AN_PAUSE_CAP
|
PHY_AN_PAUSE_ASYM
,
};
/* Check status of Broadcom phy link */
static
void
bcom_check_link
(
struct
skge_hw
*
hw
,
int
port
)
{
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
port
]);
struct
net_device
*
dev
=
hw
->
dev
[
port
];
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
u16
status
;
/* read twice because of latch */
(
void
)
xm_phy_read
(
hw
,
port
,
PHY_BCOM_STAT
);
status
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_STAT
);
pr_debug
(
"bcom_check_link status=0x%x
\n
"
,
status
);
if
((
status
&
PHY_ST_LSYNC
)
==
0
)
{
u16
cmd
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
cmd
&=
~
(
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
);
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
);
/* dummy read to ensure writing */
(
void
)
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
if
(
netif_carrier_ok
(
dev
))
skge_link_down
(
skge
);
}
else
{
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
&&
(
status
&
PHY_ST_AN_OVER
))
{
u16
lpa
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUNE_LP
);
u16
aux
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_STAT
);
if
(
lpa
&
PHY_B_AN_RF
)
{
printk
(
KERN_NOTICE
PFX
"%s: remote fault
\n
"
,
dev
->
name
);
return
;
}
/* Check Duplex mismatch */
switch
(
aux
&
PHY_B_AS_AN_RES_MSK
)
{
case
PHY_B_RES_1000FD
:
skge
->
duplex
=
DUPLEX_FULL
;
break
;
case
PHY_B_RES_1000HD
:
skge
->
duplex
=
DUPLEX_HALF
;
break
;
default:
printk
(
KERN_NOTICE
PFX
"%s: duplex mismatch
\n
"
,
dev
->
name
);
return
;
}
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
switch
(
aux
&
PHY_B_AS_PAUSE_MSK
)
{
case
PHY_B_AS_PAUSE_MSK
:
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
break
;
case
PHY_B_AS_PRR
:
skge
->
flow_control
=
FLOW_MODE_REM_SEND
;
break
;
case
PHY_B_AS_PRT
:
skge
->
flow_control
=
FLOW_MODE_LOC_SEND
;
break
;
default:
skge
->
flow_control
=
FLOW_MODE_NONE
;
}
skge
->
speed
=
SPEED_1000
;
}
if
(
!
netif_carrier_ok
(
dev
))
genesis_link_up
(
skge
);
}
}
/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
* Phy on for 100 or 10Mbit operation
*/
static
void
bcom_phy_init
(
struct
skge_port
*
skge
,
int
jumbo
)
{
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
int
i
;
int
i
;
u32
r
;
u16
id1
,
r
,
ext
,
ctl
;
u16
id1
;
u16
ctrl1
,
ctrl2
,
ctrl3
,
ctrl4
,
ctrl5
;
/* magic workaround patterns for Broadcom */
/* magic workaround patterns for Broadcom */
static
const
struct
{
static
const
struct
{
...
@@ -1042,16 +1089,120 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
...
@@ -1042,16 +1089,120 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
{
0x17
,
0x0013
},
{
0x15
,
0x0A04
},
{
0x18
,
0x0420
},
{
0x17
,
0x0013
},
{
0x15
,
0x0A04
},
{
0x18
,
0x0420
},
};
};
pr_debug
(
"bcom_phy_init
\n
"
);
/* read Id from external PHY (all have the same address) */
id1
=
xm_phy_read
(
hw
,
port
,
PHY_XMAC_ID1
);
/* Optimize MDIO transfer by suppressing preamble. */
r
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
r
|=
XM_MMU_NO_PRE
;
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
r
);
switch
(
id1
)
{
case
PHY_BCOM_ID1_C0
:
/*
* Workaround BCOM Errata for the C0 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
C0hack
);
i
++
)
xm_phy_write
(
hw
,
port
,
C0hack
[
i
].
reg
,
C0hack
[
i
].
val
);
break
;
case
PHY_BCOM_ID1_A1
:
/*
* Workaround BCOM Errata for the A1 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
A1hack
);
i
++
)
xm_phy_write
(
hw
,
port
,
A1hack
[
i
].
reg
,
A1hack
[
i
].
val
);
break
;
}
/*
* Workaround BCOM Errata (#10523) for all BCom PHYs.
* Disable Power Management after reset.
*/
r
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
);
r
|=
PHY_B_AC_DIS_PM
;
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
r
);
/* Dummy read */
xm_read16
(
hw
,
port
,
XM_ISRC
);
ext
=
PHY_B_PEC_EN_LTR
;
/* enable tx led */
ctl
=
PHY_CT_SP1000
;
/* always 1000mbit */
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
/*
* Workaround BCOM Errata #1 for the C5 type.
* 1000Base-T Link Acquisition Failure in Slave Mode
* Set Repeater/DTE bit 10 of the 1000Base-T Control Register
*/
u16
adv
=
PHY_B_1000C_RD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Half
)
adv
|=
PHY_B_1000C_AHD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Full
)
adv
|=
PHY_B_1000C_AFD
;
xm_phy_write
(
hw
,
port
,
PHY_BCOM_1000T_CTRL
,
adv
);
ctl
|=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
if
(
skge
->
duplex
==
DUPLEX_FULL
)
ctl
|=
PHY_CT_DUP_MD
;
/* Force to slave */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_1000T_CTRL
,
PHY_B_1000C_MSE
);
}
/* Set autonegotiation pause parameters */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUNE_ADV
,
phy_pause_map
[
skge
->
flow_control
]
|
PHY_AN_CSMA
);
/* Handle Jumbo frames */
if
(
jumbo
)
{
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
PHY_B_AC_TX_TST
|
PHY_B_AC_LONG_PACK
);
ext
|=
PHY_B_PEC_HIGH_LA
;
}
xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
ext
);
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctl
);
/* Use link status change interrrupt */
xm_phy_write
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
PHY_B_DEF_MSK
);
bcom_check_link
(
hw
,
port
);
}
static
void
genesis_mac_init
(
struct
skge_hw
*
hw
,
int
port
)
{
struct
net_device
*
dev
=
hw
->
dev
[
port
];
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
int
jumbo
=
hw
->
dev
[
port
]
->
mtu
>
ETH_DATA_LEN
;
int
i
;
u32
r
;
const
u8
zero
[
6
]
=
{
0
};
/* Clear MIB counters */
xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* Clear two times according to Errata #3 */
xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* initialize Rx, Tx and Link LED */
/* initialize Rx, Tx and Link LED */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_ON
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
LNK_LED_REG
),
LINKLED_LINKSYNC_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
LNK_LED_REG
),
LINKLED_LINKSYNC_ON
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_LED_CTRL
),
LED_START
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_LED_CTRL
),
LED_START
);
/* Unreset the XMAC. */
/* Unreset the XMAC. */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
MFF_CLR_MAC_RST
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_CLR_MAC_RST
);
/*
/*
* Perform additional initialization for external PHYs,
* Perform additional initialization for external PHYs,
...
@@ -1059,67 +1210,56 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
...
@@ -1059,67 +1210,56 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* GMII mode.
* GMII mode.
*/
*/
spin_lock_bh
(
&
hw
->
phy_lock
);
spin_lock_bh
(
&
hw
->
phy_lock
);
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
{
/* Take external Phy out of reset */
/* Take PHY out of reset. */
r
=
skge_read32
(
hw
,
B2_GP_IO
);
r
=
skge_read32
(
hw
,
B2_GP_IO
);
if
(
port
==
0
)
if
(
port
==
0
)
r
|=
GP_DIR_0
|
GP_IO_0
;
r
|=
GP_DIR_0
|
GP_IO_0
;
else
else
r
|=
GP_DIR_2
|
GP_IO_2
;
r
|=
GP_DIR_2
|
GP_IO_2
;
skge_write32
(
hw
,
B2_GP_IO
,
r
);
skge_read32
(
hw
,
B2_GP_IO
);
/* Enable GMII mode on the XMAC. */
skge_xm_write16
(
hw
,
port
,
XM_HW_CFG
,
XM_HW_GMII_MD
);
id1
=
skge_xm_phy_read
(
hw
,
port
,
PHY_XMAC_ID1
);
/* Optimize MDIO transfer by suppressing preamble. */
skge_xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
skge_xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
|
XM_MMU_NO_PRE
);
if
(
id1
==
PHY_BCOM_ID1_C0
)
{
/*
* Workaround BCOM Errata for the C0 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
C0hack
);
i
++
)
skge_xm_phy_write
(
hw
,
port
,
C0hack
[
i
].
reg
,
C0hack
[
i
].
val
);
}
else
if
(
id1
==
PHY_BCOM_ID1_A1
)
{
/*
* Workaround BCOM Errata for the A1 type.
* Write magic patterns to reserved registers.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
A1hack
);
i
++
)
skge_xm_phy_write
(
hw
,
port
,
A1hack
[
i
].
reg
,
A1hack
[
i
].
val
);
}
/*
skge_write32
(
hw
,
B2_GP_IO
,
r
);
* Workaround BCOM Errata (#10523) for all BCom PHYs.
skge_read32
(
hw
,
B2_GP_IO
);
* Disable Power Management after reset.
spin_unlock_bh
(
&
hw
->
phy_lock
);
*/
r
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
r
|
PHY_B_AC_DIS_PM
);
}
/* Dummy read */
/* Enable GMII interfac */
skge_xm_read16
(
hw
,
port
,
XM_ISRC
);
xm_write16
(
hw
,
port
,
XM_HW_CFG
,
XM_HW_GMII_MD
);
bcom_phy_init
(
skge
,
jumbo
);
/* Set Station Address */
xm_outaddr
(
hw
,
port
,
XM_SA
,
dev
->
dev_addr
);
/* We don't use match addresses so clear */
for
(
i
=
1
;
i
<
16
;
i
++
)
xm_outaddr
(
hw
,
port
,
XM_EXM
(
i
),
zero
);
r
=
skge_xm_read32
(
hw
,
port
,
XM_MODE
);
/* configure Rx High Water Mark (XM_RX_HI_WM) */
skge_xm_write32
(
hw
,
port
,
XM_MODE
,
r
|
XM_MD_CSA
);
xm_write16
(
hw
,
port
,
XM_RX_HI_WM
,
1450
);
/* We don't need the FCS appended to the packet. */
/* We don't need the FCS appended to the packet. */
r
=
skge_xm_read16
(
hw
,
port
,
XM_RX_CMD
);
r
=
XM_RX_LENERR_OK
|
XM_RX_STRIP_FCS
;
skge_xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
|
XM_RX_STRIP_FCS
);
if
(
jumbo
)
r
|=
XM_RX_BIG_PK_OK
;
if
(
skge
->
duplex
==
DUPLEX_HALF
)
{
/*
* If in manual half duplex mode the other side might be in
* full duplex mode, so ignore if a carrier extension is not seen
* on frames received
*/
r
|=
XM_RX_DIS_CEXT
;
}
xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
);
/* We want short frames padded to 60 bytes. */
/* We want short frames padded to 60 bytes. */
r
=
skge_xm_read16
(
hw
,
port
,
XM_TX_CMD
);
xm_write16
(
hw
,
port
,
XM_TX_CMD
,
XM_TX_AUTO_PAD
);
skge_xm_write16
(
hw
,
port
,
XM_TX_CMD
,
r
|
XM_TX_AUTO_PAD
);
/*
* Bump up the transmit threshold. This helps hold off transmit
* underruns when we're blasting traffic from both ports at once.
*/
xm_write16
(
hw
,
port
,
XM_TX_THR
,
512
);
/*
/*
* Enable the reception of all error frames. This is is
* Enable the reception of all error frames. This is is
...
@@ -1135,19 +1275,22 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
...
@@ -1135,19 +1275,22 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
* case the XMAC will start transfering frames out of the
* case the XMAC will start transfering frames out of the
* RX FIFO as soon as the FIFO threshold is reached.
* RX FIFO as soon as the FIFO threshold is reached.
*/
*/
r
=
skge_xm_read32
(
hw
,
port
,
XM_MODE
);
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_DEF_MODE
);
skge_xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_RX_CRCE
|
XM_MD_RX_LONG
|
XM_MD_RX_RUNT
|
XM_MD_RX_ERR
|
XM_MD_RX_IRLE
);
skge_xm_outaddr
(
hw
,
port
,
XM_SA
,
hw
->
dev
[
port
]
->
dev_addr
);
skge_xm_outaddr
(
hw
,
port
,
XM_EXM
(
0
),
hw
->
dev
[
port
]
->
dev_addr
);
/*
/*
* Bump up the transmit threshold. This helps hold off transmit
* Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
* underruns when we're blasting traffic from both ports at once.
* - Enable all bits excepting 'Octets Rx OK Low CntOv'
* and 'Octets Rx OK Hi Cnt Ov'.
*/
*/
skge_xm_write16
(
hw
,
port
,
XM_TX_THR
,
512
);
xm_write32
(
hw
,
port
,
XM_RX_EV_MSK
,
XMR_DEF_MSK
);
/*
* Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
* - Enable all bits excepting 'Octets Tx OK Low CntOv'
* and 'Octets Tx OK Hi Cnt Ov'.
*/
xm_write32
(
hw
,
port
,
XM_TX_EV_MSK
,
XMT_DEF_MSK
);
/* Configure MAC arbiter */
/* Configure MAC arbiter */
skge_write16
(
hw
,
B3_MA_TO_CTRL
,
MA_RST_CLR
);
skge_write16
(
hw
,
B3_MA_TO_CTRL
,
MA_RST_CLR
);
...
@@ -1164,137 +1307,30 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
...
@@ -1164,137 +1307,30 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
skge_write8
(
hw
,
B3_MA_RCINI_TX2
,
0
);
skge_write8
(
hw
,
B3_MA_RCINI_TX2
,
0
);
/* Configure Rx MAC FIFO */
/* Configure Rx MAC FIFO */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_TIM_PAT
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_TIM_PAT
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
/* Configure Tx MAC FIFO */
/* Configure Tx MAC FIFO */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
MFF_TX_CTRL_DEF
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_TX_CTRL_DEF
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL2
),
MFF_ENA_OP_MD
);
if
(
hw
->
dev
[
port
]
->
mtu
>
ETH_DATA_LEN
)
{
if
(
jumbo
)
{
/* Enable frame flushing if jumbo frames used */
/* Enable frame flushing if jumbo frames used */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_FLUSH
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_FLUSH
);
}
else
{
}
else
{
/* enable timeout timers if normal frames */
/* enable timeout timers if normal frames */
skge_write16
(
hw
,
B3_PA_CTRL
,
skge_write16
(
hw
,
B3_PA_CTRL
,
port
==
0
?
PA_ENA_TO_TX1
:
PA_ENA_TO_TX2
);
(
port
==
0
)
?
PA_ENA_TO_TX1
:
PA_ENA_TO_TX2
);
}
}
r
=
skge_xm_read16
(
hw
,
port
,
XM_RX_CMD
);
if
(
hw
->
dev
[
port
]
->
mtu
>
ETH_DATA_LEN
)
skge_xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
|
XM_RX_BIG_PK_OK
);
else
skge_xm_write16
(
hw
,
port
,
XM_RX_CMD
,
r
&
~
(
XM_RX_BIG_PK_OK
));
switch
(
hw
->
phy_type
)
{
case
SK_PHY_XMAC
:
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
ctrl1
=
PHY_X_AN_FD
|
PHY_X_AN_HD
;
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
ctrl1
|=
PHY_X_P_NO_PAUSE
;
break
;
case
FLOW_MODE_LOC_SEND
:
ctrl1
|=
PHY_X_P_ASYM_MD
;
break
;
case
FLOW_MODE_SYMMETRIC
:
ctrl1
|=
PHY_X_P_SYM_MD
;
break
;
case
FLOW_MODE_REM_SEND
:
ctrl1
|=
PHY_X_P_BOTH_MD
;
break
;
}
skge_xm_phy_write
(
hw
,
port
,
PHY_XMAC_AUNE_ADV
,
ctrl1
);
ctrl2
=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
ctrl2
=
0
;
if
(
skge
->
duplex
==
DUPLEX_FULL
)
ctrl2
|=
PHY_CT_DUP_MD
;
}
skge_xm_phy_write
(
hw
,
port
,
PHY_XMAC_CTRL
,
ctrl2
);
break
;
case
SK_PHY_BCOM
:
ctrl1
=
PHY_CT_SP1000
;
ctrl2
=
0
;
ctrl3
=
PHY_SEL_TYPE
;
ctrl4
=
PHY_B_PEC_EN_LTR
;
ctrl5
=
PHY_B_AC_TX_TST
;
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
/*
* Workaround BCOM Errata #1 for the C5 type.
* 1000Base-T Link Acquisition Failure in Slave Mode
* Set Repeater/DTE bit 10 of the 1000Base-T Control Register
*/
ctrl2
|=
PHY_B_1000C_RD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Half
)
ctrl2
|=
PHY_B_1000C_AHD
;
if
(
skge
->
advertising
&
ADVERTISED_1000baseT_Full
)
ctrl2
|=
PHY_B_1000C_AFD
;
/* Set Flow-control capabilities */
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
ctrl3
|=
PHY_B_P_NO_PAUSE
;
break
;
case
FLOW_MODE_LOC_SEND
:
ctrl3
|=
PHY_B_P_ASYM_MD
;
break
;
case
FLOW_MODE_SYMMETRIC
:
ctrl3
|=
PHY_B_P_SYM_MD
;
break
;
case
FLOW_MODE_REM_SEND
:
ctrl3
|=
PHY_B_P_BOTH_MD
;
break
;
}
/* Restart Auto-negotiation */
ctrl1
|=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
if
(
skge
->
duplex
==
DUPLEX_FULL
)
ctrl1
|=
PHY_CT_DUP_MD
;
ctrl2
|=
PHY_B_1000C_MSE
;
/* set it to Slave */
}
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_1000T_CTRL
,
ctrl2
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUNE_ADV
,
ctrl3
);
if
(
skge
->
netdev
->
mtu
>
ETH_DATA_LEN
)
{
ctrl4
|=
PHY_B_PEC_HIGH_LA
;
ctrl5
|=
PHY_B_AC_LONG_PACK
;
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
ctrl5
);
}
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_P_EXT_CTRL
,
ctrl4
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctrl1
);
break
;
}
spin_unlock_bh
(
&
hw
->
phy_lock
);
/* Clear MIB counters */
skge_xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* Clear two times according to Errata #3 */
skge_xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_CLR_RXC
|
XM_SC_CLR_TXC
);
/* Start polling for link status */
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
}
static
void
genesis_stop
(
struct
skge_port
*
skge
)
static
void
genesis_stop
(
struct
skge_port
*
skge
)
{
{
struct
skge_hw
*
hw
=
skge
->
hw
;
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
int
port
=
skge
->
port
;
u32
reg
;
/* Clear Tx packet arbiter timeout IRQ */
/* Clear Tx packet arbiter timeout IRQ */
skge_write16
(
hw
,
B3_PA_CTRL
,
skge_write16
(
hw
,
B3_PA_CTRL
,
...
@@ -1304,33 +1340,30 @@ static void genesis_stop(struct skge_port *skge)
...
@@ -1304,33 +1340,30 @@ static void genesis_stop(struct skge_port *skge)
* If the transfer stucks at the MAC the STOP command will not
* If the transfer stucks at the MAC the STOP command will not
* terminate if we don't flush the XMAC's transmit FIFO !
* terminate if we don't flush the XMAC's transmit FIFO !
*/
*/
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
xm_write32
(
hw
,
port
,
XM_MODE
,
skge_
xm_read32
(
hw
,
port
,
XM_MODE
)
|
XM_MD_FTF
);
xm_read32
(
hw
,
port
,
XM_MODE
)
|
XM_MD_FTF
);
/* Reset the MAC */
/* Reset the MAC */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
MFF_SET_MAC_RST
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_SET_MAC_RST
);
/* For external PHYs there must be special handling */
/* For external PHYs there must be special handling */
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
{
reg
=
skge_read32
(
hw
,
B2_GP_IO
);
u32
reg
=
skge_read32
(
hw
,
B2_GP_IO
);
if
(
port
==
0
)
{
reg
|=
GP_DIR_0
;
if
(
port
==
0
)
{
reg
&=
~
GP_IO_0
;
reg
|=
GP_DIR_0
;
}
else
{
reg
&=
~
GP_IO_0
;
reg
|=
GP_DIR_2
;
}
else
{
reg
&=
~
GP_IO_2
;
reg
|=
GP_DIR_2
;
reg
&=
~
GP_IO_2
;
}
skge_write32
(
hw
,
B2_GP_IO
,
reg
);
skge_read32
(
hw
,
B2_GP_IO
);
}
}
skge_write32
(
hw
,
B2_GP_IO
,
reg
);
skge_read32
(
hw
,
B2_GP_IO
);
skge_
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
~
(
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
));
&
~
(
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
));
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
}
}
...
@@ -1341,11 +1374,11 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
...
@@ -1341,11 +1374,11 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
int
i
;
int
i
;
unsigned
long
timeout
=
jiffies
+
HZ
;
unsigned
long
timeout
=
jiffies
+
HZ
;
skge_
xm_write16
(
hw
,
port
,
xm_write16
(
hw
,
port
,
XM_STAT_CMD
,
XM_SC_SNP_TXC
|
XM_SC_SNP_RXC
);
XM_STAT_CMD
,
XM_SC_SNP_TXC
|
XM_SC_SNP_RXC
);
/* wait for update to complete */
/* wait for update to complete */
while
(
skge_
xm_read16
(
hw
,
port
,
XM_STAT_CMD
)
while
(
xm_read16
(
hw
,
port
,
XM_STAT_CMD
)
&
(
XM_SC_SNP_TXC
|
XM_SC_SNP_RXC
))
{
&
(
XM_SC_SNP_TXC
|
XM_SC_SNP_RXC
))
{
if
(
time_after
(
jiffies
,
timeout
))
if
(
time_after
(
jiffies
,
timeout
))
break
;
break
;
...
@@ -1353,68 +1386,60 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
...
@@ -1353,68 +1386,60 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data)
}
}
/* special case for 64 bit octet counter */
/* special case for 64 bit octet counter */
data
[
0
]
=
(
u64
)
skge_
xm_read32
(
hw
,
port
,
XM_TXO_OK_HI
)
<<
32
data
[
0
]
=
(
u64
)
xm_read32
(
hw
,
port
,
XM_TXO_OK_HI
)
<<
32
|
skge_
xm_read32
(
hw
,
port
,
XM_TXO_OK_LO
);
|
xm_read32
(
hw
,
port
,
XM_TXO_OK_LO
);
data
[
1
]
=
(
u64
)
skge_
xm_read32
(
hw
,
port
,
XM_RXO_OK_HI
)
<<
32
data
[
1
]
=
(
u64
)
xm_read32
(
hw
,
port
,
XM_RXO_OK_HI
)
<<
32
|
skge_
xm_read32
(
hw
,
port
,
XM_RXO_OK_LO
);
|
xm_read32
(
hw
,
port
,
XM_RXO_OK_LO
);
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
data
[
i
]
=
skge_
xm_read32
(
hw
,
port
,
skge_stats
[
i
].
xmac_offset
);
data
[
i
]
=
xm_read32
(
hw
,
port
,
skge_stats
[
i
].
xmac_offset
);
}
}
static
void
genesis_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
static
void
genesis_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
{
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
port
]);
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
port
]);
u16
status
=
skge_xm_read16
(
hw
,
port
,
XM_ISRC
);
u16
status
=
xm_read16
(
hw
,
port
,
XM_ISRC
);
pr_debug
(
"genesis_intr status %x
\n
"
,
status
);
if
(
netif_msg_intr
(
skge
))
if
(
hw
->
phy_type
==
SK_PHY_XMAC
)
{
printk
(
KERN_DEBUG
PFX
"%s: mac interrupt status 0x%x
\n
"
,
/* LInk down, start polling for state change */
skge
->
netdev
->
name
,
status
);
if
(
status
&
XM_IS_INP_ASS
)
{
skge_xm_write16
(
hw
,
port
,
XM_IMSK
,
skge_xm_read16
(
hw
,
port
,
XM_IMSK
)
|
XM_IS_INP_ASS
);
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
else
if
(
status
&
XM_IS_AND
)
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
if
(
status
&
XM_IS_TXF_UR
)
{
if
(
status
&
XM_IS_TXF_UR
)
{
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FTF
);
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FTF
);
++
skge
->
net_stats
.
tx_fifo_errors
;
++
skge
->
net_stats
.
tx_fifo_errors
;
}
}
if
(
status
&
XM_IS_RXF_OV
)
{
if
(
status
&
XM_IS_RXF_OV
)
{
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FRF
);
xm_write32
(
hw
,
port
,
XM_MODE
,
XM_MD_FRF
);
++
skge
->
net_stats
.
rx_fifo_errors
;
++
skge
->
net_stats
.
rx_fifo_errors
;
}
}
}
}
static
void
skge_
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
static
void
gm_phy_write
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
,
u16
val
)
{
{
int
i
;
int
i
;
skge_
gma_write16
(
hw
,
port
,
GM_SMI_DATA
,
val
);
gma_write16
(
hw
,
port
,
GM_SMI_DATA
,
val
);
skge_
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
GM_SMI_CT_PHY_AD
(
hw
->
phy_addr
)
|
GM_SMI_CT_REG_AD
(
reg
));
GM_SMI_CT_PHY_AD
(
hw
->
phy_addr
)
|
GM_SMI_CT_REG_AD
(
reg
));
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
udelay
(
1
);
if
(
!
(
skge_
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_BUSY
))
if
(
!
(
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_BUSY
))
break
;
break
;
}
}
}
}
static
u16
skge_
gm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
static
u16
gm_phy_read
(
struct
skge_hw
*
hw
,
int
port
,
u16
reg
)
{
{
int
i
;
int
i
;
skge_
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
gma_write16
(
hw
,
port
,
GM_SMI_CTRL
,
GM_SMI_CT_PHY_AD
(
hw
->
phy_addr
)
GM_SMI_CT_PHY_AD
(
hw
->
phy_addr
)
|
GM_SMI_CT_REG_AD
(
reg
)
|
GM_SMI_CT_OP_RD
);
|
GM_SMI_CT_REG_AD
(
reg
)
|
GM_SMI_CT_OP_RD
);
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
for
(
i
=
0
;
i
<
PHY_RETRIES
;
i
++
)
{
udelay
(
1
);
udelay
(
1
);
if
(
skge_
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_RD_VAL
)
if
(
gma_read16
(
hw
,
port
,
GM_SMI_CTRL
)
&
GM_SMI_CT_RD_VAL
)
goto
ready
;
goto
ready
;
}
}
...
@@ -1422,24 +1447,7 @@ static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg)
...
@@ -1422,24 +1447,7 @@ static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg)
hw
->
dev
[
port
]
->
name
);
hw
->
dev
[
port
]
->
name
);
return
0
;
return
0
;
ready:
ready:
return
skge_gma_read16
(
hw
,
port
,
GM_SMI_DATA
);
return
gma_read16
(
hw
,
port
,
GM_SMI_DATA
);
}
static
void
genesis_link_down
(
struct
skge_port
*
skge
)
{
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
pr_debug
(
"genesis_link_down
\n
"
);
skge_xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
skge_xm_read16
(
hw
,
port
,
XM_MMU_CMD
)
&
~
(
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
));
/* dummy read to ensure writing */
(
void
)
skge_xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
skge_link_down
(
skge
);
}
}
static
void
genesis_link_up
(
struct
skge_port
*
skge
)
static
void
genesis_link_up
(
struct
skge_port
*
skge
)
...
@@ -1450,7 +1458,7 @@ static void genesis_link_up(struct skge_port *skge)
...
@@ -1450,7 +1458,7 @@ static void genesis_link_up(struct skge_port *skge)
u32
mode
,
msk
;
u32
mode
,
msk
;
pr_debug
(
"genesis_link_up
\n
"
);
pr_debug
(
"genesis_link_up
\n
"
);
cmd
=
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
cmd
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
/*
/*
* enabling pause frame reception is required for 1000BT
* enabling pause frame reception is required for 1000BT
...
@@ -1458,14 +1466,15 @@ static void genesis_link_up(struct skge_port *skge)
...
@@ -1458,14 +1466,15 @@ static void genesis_link_up(struct skge_port *skge)
*/
*/
if
(
skge
->
flow_control
==
FLOW_MODE_NONE
||
if
(
skge
->
flow_control
==
FLOW_MODE_NONE
||
skge
->
flow_control
==
FLOW_MODE_LOC_SEND
)
skge
->
flow_control
==
FLOW_MODE_LOC_SEND
)
/* Disable Pause Frame Reception */
cmd
|=
XM_MMU_IGN_PF
;
cmd
|=
XM_MMU_IGN_PF
;
else
else
/* Enable Pause Frame Reception */
/* Enable Pause Frame Reception */
cmd
&=
~
XM_MMU_IGN_PF
;
cmd
&=
~
XM_MMU_IGN_PF
;
skge_
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
);
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
);
mode
=
skge_
xm_read32
(
hw
,
port
,
XM_MODE
);
mode
=
xm_read32
(
hw
,
port
,
XM_MODE
);
if
(
skge
->
flow_control
==
FLOW_MODE_SYMMETRIC
||
if
(
skge
->
flow_control
==
FLOW_MODE_SYMMETRIC
||
skge
->
flow_control
==
FLOW_MODE_LOC_SEND
)
{
skge
->
flow_control
==
FLOW_MODE_LOC_SEND
)
{
/*
/*
...
@@ -1479,10 +1488,10 @@ static void genesis_link_up(struct skge_port *skge)
...
@@ -1479,10 +1488,10 @@ static void genesis_link_up(struct skge_port *skge)
/* XM_PAUSE_DA = '010000C28001' (default) */
/* XM_PAUSE_DA = '010000C28001' (default) */
/* XM_MAC_PTIME = 0xffff (maximum) */
/* XM_MAC_PTIME = 0xffff (maximum) */
/* remember this value is defined in big endian (!) */
/* remember this value is defined in big endian (!) */
skge_
xm_write16
(
hw
,
port
,
XM_MAC_PTIME
,
0xffff
);
xm_write16
(
hw
,
port
,
XM_MAC_PTIME
,
0xffff
);
mode
|=
XM_PAUSE_MODE
;
mode
|=
XM_PAUSE_MODE
;
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_PAUSE
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_ENA_PAUSE
);
}
else
{
}
else
{
/*
/*
* disable pause frame generation is required for 1000BT
* disable pause frame generation is required for 1000BT
...
@@ -1491,125 +1500,68 @@ static void genesis_link_up(struct skge_port *skge)
...
@@ -1491,125 +1500,68 @@ static void genesis_link_up(struct skge_port *skge)
/* Disable Pause Mode in Mode Register */
/* Disable Pause Mode in Mode Register */
mode
&=
~
XM_PAUSE_MODE
;
mode
&=
~
XM_PAUSE_MODE
;
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL1
),
MFF_DIS_PAUSE
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL1
),
MFF_DIS_PAUSE
);
}
}
skge_
xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
msk
=
XM_DEF_MSK
;
msk
=
XM_DEF_MSK
;
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
)
/* disable GP0 interrupt bit for external Phy */
msk
|=
XM_IS_INP_ASS
;
/* disable GP0 interrupt bit */
msk
|=
XM_IS_INP_ASS
;
skge_
xm_write16
(
hw
,
port
,
XM_IMSK
,
msk
);
xm_write16
(
hw
,
port
,
XM_IMSK
,
msk
);
skge_
xm_read16
(
hw
,
port
,
XM_ISRC
);
xm_read16
(
hw
,
port
,
XM_ISRC
);
/* get MMU Command Reg. */
/* get MMU Command Reg. */
cmd
=
skge_
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
cmd
=
xm_read16
(
hw
,
port
,
XM_MMU_CMD
);
if
(
hw
->
phy_type
!=
SK_PHY_XMAC
&&
skge
->
duplex
==
DUPLEX_FULL
)
if
(
skge
->
duplex
==
DUPLEX_FULL
)
cmd
|=
XM_MMU_GMII_FD
;
cmd
|=
XM_MMU_GMII_FD
;
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
{
/*
/*
* Workaround BCOM Errata (#10523) for all BCom Phys
* Workaround BCOM Errata (#10523) for all BCom Phys
* Enable Power Management after link up
* Enable Power Management after link up
*/
*/
xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
,
xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
)
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_CTRL
)
&
~
PHY_B_AC_DIS_PM
);
&
~
PHY_B_AC_DIS_PM
);
xm_phy_write
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
PHY_B_DEF_MSK
);
skge_xm_phy_write
(
hw
,
port
,
PHY_BCOM_INT_MASK
,
PHY_B_DEF_MSK
);
}
/* enable Rx/Tx */
/* enable Rx/Tx */
skge_
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
xm_write16
(
hw
,
port
,
XM_MMU_CMD
,
cmd
|
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
);
cmd
|
XM_MMU_ENA_RX
|
XM_MMU_ENA_TX
);
skge_link_up
(
skge
);
skge_link_up
(
skge
);
}
}
static
void
genesis_bcom
_intr
(
struct
skge_port
*
skge
)
static
inline
void
bcom_phy
_intr
(
struct
skge_port
*
skge
)
{
{
struct
skge_hw
*
hw
=
skge
->
hw
;
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
int
port
=
skge
->
port
;
u16
stat
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_INT_STAT
);
u16
isrc
;
isrc
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_INT_STAT
);
if
(
netif_msg_intr
(
skge
))
printk
(
KERN_DEBUG
PFX
"%s: phy interrupt status 0x%x
\n
"
,
skge
->
netdev
->
name
,
isrc
);
pr_debug
(
"genesis_bcom intr stat=%x
\n
"
,
stat
);
if
(
isrc
&
PHY_B_IS_PSE
)
printk
(
KERN_ERR
PFX
"%s: uncorrectable pair swap error
\n
"
,
hw
->
dev
[
port
]
->
name
);
/* Workaround BCom Errata:
/* Workaround BCom Errata:
* enable and disable loopback mode if "NO HCD" occurs.
* enable and disable loopback mode if "NO HCD" occurs.
*/
*/
if
(
stat
&
PHY_B_IS_NO_HDCL
)
{
if
(
isrc
&
PHY_B_IS_NO_HDCL
)
{
u16
ctrl
=
skge_
xm_phy_read
(
hw
,
port
,
PHY_BCOM_CTRL
);
u16
ctrl
=
xm_phy_read
(
hw
,
port
,
PHY_BCOM_CTRL
);
skge_
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctrl
|
PHY_CT_LOOP
);
ctrl
|
PHY_CT_LOOP
);
skge_
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
xm_phy_write
(
hw
,
port
,
PHY_BCOM_CTRL
,
ctrl
&
~
PHY_CT_LOOP
);
ctrl
&
~
PHY_CT_LOOP
);
}
}
stat
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_STAT
);
if
(
isrc
&
(
PHY_B_IS_AN_PR
|
PHY_B_IS_LST_CHANGE
))
if
(
stat
&
(
PHY_B_IS_AN_PR
|
PHY_B_IS_LST_CHANGE
))
{
bcom_check_link
(
hw
,
port
);
u16
aux
=
skge_xm_phy_read
(
hw
,
port
,
PHY_BCOM_AUX_STAT
);
if
(
!
(
aux
&
PHY_B_AS_LS
)
&&
netif_carrier_ok
(
skge
->
netdev
))
genesis_link_down
(
skge
);
else
if
(
stat
&
PHY_B_IS_LST_CHANGE
)
{
if
(
aux
&
PHY_B_AS_AN_C
)
{
switch
(
aux
&
PHY_B_AS_AN_RES_MSK
)
{
case
PHY_B_RES_1000FD
:
skge
->
duplex
=
DUPLEX_FULL
;
break
;
case
PHY_B_RES_1000HD
:
skge
->
duplex
=
DUPLEX_HALF
;
break
;
}
switch
(
aux
&
PHY_B_AS_PAUSE_MSK
)
{
case
PHY_B_AS_PAUSE_MSK
:
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
break
;
case
PHY_B_AS_PRR
:
skge
->
flow_control
=
FLOW_MODE_REM_SEND
;
break
;
case
PHY_B_AS_PRT
:
skge
->
flow_control
=
FLOW_MODE_LOC_SEND
;
break
;
default:
skge
->
flow_control
=
FLOW_MODE_NONE
;
}
skge
->
speed
=
SPEED_1000
;
}
genesis_link_up
(
skge
);
}
else
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
}
}
/* Perodic poll of phy status to check for link transistion */
static
void
skge_link_timer
(
unsigned
long
__arg
)
{
struct
skge_port
*
skge
=
(
struct
skge_port
*
)
__arg
;
struct
skge_hw
*
hw
=
skge
->
hw
;
int
port
=
skge
->
port
;
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
||
!
netif_running
(
skge
->
netdev
))
return
;
spin_lock_bh
(
&
hw
->
phy_lock
);
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
genesis_bcom_intr
(
skge
);
else
{
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
skge_xm_read16
(
hw
,
port
,
XM_ISRC
)
&
XM_IS_INP_ASS
)
break
;
if
(
i
==
3
)
mod_timer
(
&
skge
->
link_check
,
jiffies
+
LINK_POLL_HZ
);
else
genesis_link_up
(
skge
);
}
spin_unlock_bh
(
&
hw
->
phy_lock
);
}
}
/* Marvell Phy Initailization */
/* Marvell Phy Initailization */
...
@@ -1621,31 +1573,27 @@ static void yukon_init(struct skge_hw *hw, int port)
...
@@ -1621,31 +1573,27 @@ static void yukon_init(struct skge_hw *hw, int port)
pr_debug
(
"yukon_init
\n
"
);
pr_debug
(
"yukon_init
\n
"
);
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
u16
ectrl
=
skge_
gm_phy_read
(
hw
,
port
,
PHY_MARV_EXT_CTRL
);
u16
ectrl
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_EXT_CTRL
);
ectrl
&=
~
(
PHY_M_EC_M_DSC_MSK
|
PHY_M_EC_S_DSC_MSK
|
ectrl
&=
~
(
PHY_M_EC_M_DSC_MSK
|
PHY_M_EC_S_DSC_MSK
|
PHY_M_EC_MAC_S_MSK
);
PHY_M_EC_MAC_S_MSK
);
ectrl
|=
PHY_M_EC_MAC_S
(
MAC_TX_CLK_25_MHZ
);
ectrl
|=
PHY_M_EC_MAC_S
(
MAC_TX_CLK_25_MHZ
);
/* on PHY 88E1111 there is a change for downshift control */
ectrl
|=
PHY_M_EC_M_DSC
(
0
)
|
PHY_M_EC_S_DSC
(
1
);
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_EC
)
ectrl
|=
PHY_M_EC_M_DSC_2
(
0
)
|
PHY_M_EC_DOWN_S_ENA
;
else
ectrl
|=
PHY_M_EC_M_DSC
(
0
)
|
PHY_M_EC_S_DSC
(
1
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_EXT_CTRL
,
ectrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_EXT_CTRL
,
ectrl
);
}
}
ctrl
=
skge_
gm_phy_read
(
hw
,
port
,
PHY_MARV_CTRL
);
ctrl
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_CTRL
);
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
)
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
)
ctrl
&=
~
PHY_CT_ANE
;
ctrl
&=
~
PHY_CT_ANE
;
ctrl
|=
PHY_CT_RESET
;
ctrl
|=
PHY_CT_RESET
;
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
ctrl
=
0
;
ctrl
=
0
;
ct1000
=
0
;
ct1000
=
0
;
adv
=
PHY_
SEL_TYPE
;
adv
=
PHY_
AN_CSMA
;
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
{
if
(
iscopper
(
hw
))
{
if
(
iscopper
(
hw
))
{
...
@@ -1661,41 +1609,12 @@ static void yukon_init(struct skge_hw *hw, int port)
...
@@ -1661,41 +1609,12 @@ static void yukon_init(struct skge_hw *hw, int port)
adv
|=
PHY_M_AN_10_FD
;
adv
|=
PHY_M_AN_10_FD
;
if
(
skge
->
advertising
&
ADVERTISED_10baseT_Half
)
if
(
skge
->
advertising
&
ADVERTISED_10baseT_Half
)
adv
|=
PHY_M_AN_10_HD
;
adv
|=
PHY_M_AN_10_HD
;
}
else
/* special defines for FIBER (88E1011S only) */
/* Set Flow-control capabilities */
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
adv
|=
PHY_B_P_NO_PAUSE
;
break
;
case
FLOW_MODE_LOC_SEND
:
adv
|=
PHY_B_P_ASYM_MD
;
break
;
case
FLOW_MODE_SYMMETRIC
:
adv
|=
PHY_B_P_SYM_MD
;
break
;
case
FLOW_MODE_REM_SEND
:
adv
|=
PHY_B_P_BOTH_MD
;
break
;
}
}
else
{
/* special defines for FIBER (88E1011S only) */
adv
|=
PHY_M_AN_1000X_AHD
|
PHY_M_AN_1000X_AFD
;
adv
|=
PHY_M_AN_1000X_AHD
|
PHY_M_AN_1000X_AFD
;
/* Set Flow-control capabilities */
/* Set Flow-control capabilities */
switch
(
skge
->
flow_control
)
{
adv
|=
phy_pause_map
[
skge
->
flow_control
];
case
FLOW_MODE_NONE
:
adv
|=
PHY_M_P_NO_PAUSE_X
;
break
;
case
FLOW_MODE_LOC_SEND
:
adv
|=
PHY_M_P_ASYM_MD_X
;
break
;
case
FLOW_MODE_SYMMETRIC
:
adv
|=
PHY_M_P_SYM_MD_X
;
break
;
case
FLOW_MODE_REM_SEND
:
adv
|=
PHY_M_P_BOTH_MD_X
;
break
;
}
}
/* Restart Auto-negotiation */
/* Restart Auto-negotiation */
ctrl
|=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
ctrl
|=
PHY_CT_ANE
|
PHY_CT_RE_CFG
;
}
else
{
}
else
{
...
@@ -1717,36 +1636,23 @@ static void yukon_init(struct skge_hw *hw, int port)
...
@@ -1717,36 +1636,23 @@ static void yukon_init(struct skge_hw *hw, int port)
ctrl
|=
PHY_CT_RESET
;
ctrl
|=
PHY_CT_RESET
;
}
}
if
(
hw
->
chip_id
!=
CHIP_ID_YUKON_FE
)
gm_phy_write
(
hw
,
port
,
PHY_MARV_1000T_CTRL
,
ct1000
);
skge_gm_phy_write
(
hw
,
port
,
PHY_MARV_1000T_CTRL
,
ct1000
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
adv
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
adv
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_CTRL
,
ctrl
);
/* Setup Phy LED's */
/* Setup Phy LED's */
ledctrl
=
PHY_M_LED_PULS_DUR
(
PULS_170MS
);
ledctrl
=
PHY_M_LED_PULS_DUR
(
PULS_170MS
);
ledover
=
0
;
ledover
=
0
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
{
ledctrl
|=
PHY_M_LED_BLINK_RT
(
BLINK_84MS
)
|
PHY_M_LEDC_TX_CTRL
;
/* on 88E3082 these bits are at 11..9 (shifted left) */
ledctrl
|=
PHY_M_LED_BLINK_RT
(
BLINK_84MS
)
<<
1
;
skge_gm_phy_write
(
hw
,
port
,
PHY_MARV_FE_LED_PAR
,
((
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_FE_LED_PAR
)
&
~
PHY_M_FELP_LED1_MSK
)
|
PHY_M_FELP_LED1_CTRL
(
LED_PAR_CTRL_ACT_BL
)));
}
else
{
/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
ledctrl
|=
PHY_M_LED_BLINK_RT
(
BLINK_84MS
)
|
PHY_M_LEDC_TX_CTRL
;
/* turn off the Rx LED (LED_RX) */
/* turn off the Rx LED (LED_RX) */
ledover
|=
PHY_M_LED_MO_RX
(
MO_LED_OFF
);
ledover
|=
PHY_M_LED_MO_RX
(
MO_LED_OFF
);
}
/* disable blink mode (LED_DUPLEX) on collisions */
/* disable blink mode (LED_DUPLEX) on collisions */
ctrl
|=
PHY_M_LEDC_DP_CTRL
;
ctrl
|=
PHY_M_LEDC_DP_CTRL
;
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
ledctrl
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_CTRL
,
ledctrl
);
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
||
skge
->
speed
==
SPEED_100
)
{
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
||
skge
->
speed
==
SPEED_100
)
{
/* turn on 100 Mbps LED (LED_LINK100) */
/* turn on 100 Mbps LED (LED_LINK100) */
...
@@ -1754,25 +1660,25 @@ static void yukon_init(struct skge_hw *hw, int port)
...
@@ -1754,25 +1660,25 @@ static void yukon_init(struct skge_hw *hw, int port)
}
}
if
(
ledover
)
if
(
ledover
)
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
ledover
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_LED_OVER
,
ledover
);
/* Enable phy interrupt on autonegotiation complete (or link up) */
/* Enable phy interrupt on autonegotiation complete (or link up) */
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
if
(
skge
->
autoneg
==
AUTONEG_ENABLE
)
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_IS_AN_COMPL
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_IS_AN_COMPL
);
else
else
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
}
}
static
void
yukon_reset
(
struct
skge_hw
*
hw
,
int
port
)
static
void
yukon_reset
(
struct
skge_hw
*
hw
,
int
port
)
{
{
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
/* disable PHY IRQs */
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
/* disable PHY IRQs */
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
0
);
/* clear MC hash */
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
0
);
/* clear MC hash */
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
0
);
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
0
);
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
0
);
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
skge_
gma_read16
(
hw
,
port
,
GM_RX_CTRL
)
gma_read16
(
hw
,
port
,
GM_RX_CTRL
)
|
GM_RXCR_UCF_ENA
|
GM_RXCR_MCF_ENA
);
|
GM_RXCR_UCF_ENA
|
GM_RXCR_MCF_ENA
);
}
}
...
@@ -1785,17 +1691,17 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
...
@@ -1785,17 +1691,17 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
/* WA code for COMA mode -- set PHY reset */
/* WA code for COMA mode -- set PHY reset */
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
skge_write32
(
hw
,
B2_GP_IO
,
skge_write32
(
hw
,
B2_GP_IO
,
(
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
|
GP_IO_9
));
(
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
|
GP_IO_9
));
/* hard reset */
/* hard reset */
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GPHY_CTRL
),
GPC_RST_SET
);
skge_write32
(
hw
,
SK_REG
(
port
,
GPHY_CTRL
),
GPC_RST_SET
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_RST_SET
);
skge_write32
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_RST_SET
);
/* WA code for COMA mode -- clear PHY reset */
/* WA code for COMA mode -- clear PHY reset */
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
skge_write32
(
hw
,
B2_GP_IO
,
skge_write32
(
hw
,
B2_GP_IO
,
(
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
)
(
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
)
&
~
GP_IO_9
);
&
~
GP_IO_9
);
...
@@ -1806,13 +1712,13 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
...
@@ -1806,13 +1712,13 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg
|=
iscopper
(
hw
)
?
GPC_HWCFG_GMII_COP
:
GPC_HWCFG_GMII_FIB
;
reg
|=
iscopper
(
hw
)
?
GPC_HWCFG_GMII_COP
:
GPC_HWCFG_GMII_FIB
;
/* Clear GMC reset */
/* Clear GMC reset */
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_SET
);
skge_write32
(
hw
,
SK_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_SET
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_CLR
);
skge_write32
(
hw
,
SK_REG
(
port
,
GPHY_CTRL
),
reg
|
GPC_RST_CLR
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
|
GMC_RST_CLR
);
skge_write32
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
|
GMC_RST_CLR
);
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
)
{
if
(
skge
->
autoneg
==
AUTONEG_DISABLE
)
{
reg
=
GM_GPCR_AU_ALL_DIS
;
reg
=
GM_GPCR_AU_ALL_DIS
;
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
|
reg
);
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
|
reg
);
switch
(
skge
->
speed
)
{
switch
(
skge
->
speed
)
{
case
SPEED_1000
:
case
SPEED_1000
:
...
@@ -1828,7 +1734,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
...
@@ -1828,7 +1734,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg
=
GM_GPCR_SPEED_1000
|
GM_GPCR_SPEED_100
|
GM_GPCR_DUP_FULL
;
reg
=
GM_GPCR_SPEED_1000
|
GM_GPCR_SPEED_100
|
GM_GPCR_DUP_FULL
;
switch
(
skge
->
flow_control
)
{
switch
(
skge
->
flow_control
)
{
case
FLOW_MODE_NONE
:
case
FLOW_MODE_NONE
:
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
skge_write32
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
reg
|=
GM_GPCR_FC_TX_DIS
|
GM_GPCR_FC_RX_DIS
|
GM_GPCR_AU_FCT_DIS
;
reg
|=
GM_GPCR_FC_TX_DIS
|
GM_GPCR_FC_RX_DIS
|
GM_GPCR_AU_FCT_DIS
;
break
;
break
;
case
FLOW_MODE_LOC_SEND
:
case
FLOW_MODE_LOC_SEND
:
...
@@ -1836,7 +1742,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
...
@@ -1836,7 +1742,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
reg
|=
GM_GPCR_FC_RX_DIS
|
GM_GPCR_AU_FCT_DIS
;
reg
|=
GM_GPCR_FC_RX_DIS
|
GM_GPCR_AU_FCT_DIS
;
}
}
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
skge_read16
(
hw
,
GMAC_IRQ_SRC
);
skge_read16
(
hw
,
GMAC_IRQ_SRC
);
spin_lock_bh
(
&
hw
->
phy_lock
);
spin_lock_bh
(
&
hw
->
phy_lock
);
...
@@ -1844,25 +1750,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
...
@@ -1844,25 +1750,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
spin_unlock_bh
(
&
hw
->
phy_lock
);
spin_unlock_bh
(
&
hw
->
phy_lock
);
/* MIB clear */
/* MIB clear */
reg
=
skge_
gma_read16
(
hw
,
port
,
GM_PHY_ADDR
);
reg
=
gma_read16
(
hw
,
port
,
GM_PHY_ADDR
);
skge_
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
|
GM_PAR_MIB_CLR
);
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
|
GM_PAR_MIB_CLR
);
for
(
i
=
0
;
i
<
GM_MIB_CNT_SIZE
;
i
++
)
for
(
i
=
0
;
i
<
GM_MIB_CNT_SIZE
;
i
++
)
skge_
gma_read16
(
hw
,
port
,
GM_MIB_CNT_BASE
+
8
*
i
);
gma_read16
(
hw
,
port
,
GM_MIB_CNT_BASE
+
8
*
i
);
skge_
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
);
gma_write16
(
hw
,
port
,
GM_PHY_ADDR
,
reg
);
/* transmit control */
/* transmit control */
skge_
gma_write16
(
hw
,
port
,
GM_TX_CTRL
,
TX_COL_THR
(
TX_COL_DEF
));
gma_write16
(
hw
,
port
,
GM_TX_CTRL
,
TX_COL_THR
(
TX_COL_DEF
));
/* receive control reg: unicast + multicast + no FCS */
/* receive control reg: unicast + multicast + no FCS */
skge_
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
GM_RXCR_UCF_ENA
|
GM_RXCR_CRC_DIS
|
GM_RXCR_MCF_ENA
);
GM_RXCR_UCF_ENA
|
GM_RXCR_CRC_DIS
|
GM_RXCR_MCF_ENA
);
/* transmit flow control */
/* transmit flow control */
skge_
gma_write16
(
hw
,
port
,
GM_TX_FLOW_CTRL
,
0xffff
);
gma_write16
(
hw
,
port
,
GM_TX_FLOW_CTRL
,
0xffff
);
/* transmit parameter */
/* transmit parameter */
skge_
gma_write16
(
hw
,
port
,
GM_TX_PARAM
,
gma_write16
(
hw
,
port
,
GM_TX_PARAM
,
TX_JAM_LEN_VAL
(
TX_JAM_LEN_DEF
)
|
TX_JAM_LEN_VAL
(
TX_JAM_LEN_DEF
)
|
TX_JAM_IPG_VAL
(
TX_JAM_IPG_DEF
)
|
TX_JAM_IPG_VAL
(
TX_JAM_IPG_DEF
)
|
TX_IPG_JAM_DATA
(
TX_IPG_JAM_DEF
));
TX_IPG_JAM_DATA
(
TX_IPG_JAM_DEF
));
...
@@ -1872,33 +1778,33 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
...
@@ -1872,33 +1778,33 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
if
(
hw
->
dev
[
port
]
->
mtu
>
1500
)
if
(
hw
->
dev
[
port
]
->
mtu
>
1500
)
reg
|=
GM_SMOD_JUMBO_ENA
;
reg
|=
GM_SMOD_JUMBO_ENA
;
skge_
gma_write16
(
hw
,
port
,
GM_SERIAL_MODE
,
reg
);
gma_write16
(
hw
,
port
,
GM_SERIAL_MODE
,
reg
);
/* physical address: used for pause frames */
/* physical address: used for pause frames */
skge_gm
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_1L
,
addr
);
gma
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_1L
,
addr
);
/* virtual address for data */
/* virtual address for data */
skge_gm
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_2L
,
addr
);
gma
_set_addr
(
hw
,
port
,
GM_SRC_ADDR_2L
,
addr
);
/* enable interrupt mask for counter overflows */
/* enable interrupt mask for counter overflows */
skge_
gma_write16
(
hw
,
port
,
GM_TX_IRQ_MSK
,
0
);
gma_write16
(
hw
,
port
,
GM_TX_IRQ_MSK
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_RX_IRQ_MSK
,
0
);
gma_write16
(
hw
,
port
,
GM_RX_IRQ_MSK
,
0
);
skge_
gma_write16
(
hw
,
port
,
GM_TR_IRQ_MSK
,
0
);
gma_write16
(
hw
,
port
,
GM_TR_IRQ_MSK
,
0
);
/* Initialize Mac Fifo */
/* Initialize Mac Fifo */
/* Configure Rx MAC FIFO */
/* Configure Rx MAC FIFO */
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_FL_MSK
),
RX_FF_FL_DEF_MSK
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_GMF_FL_MSK
),
RX_FF_FL_DEF_MSK
);
reg
=
GMF_OPER_ON
|
GMF_RX_F_FL_ON
;
reg
=
GMF_OPER_ON
|
GMF_RX_F_FL_ON
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
reg
&=
~
GMF_RX_F_FL_ON
;
reg
&=
~
GMF_RX_F_FL_ON
;
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_CTRL_T
),
reg
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_GMF_CTRL_T
),
reg
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_FL_THR
),
RX_GMF_FL_THR_DEF
);
skge_write16
(
hw
,
SK_REG
(
port
,
RX_GMF_FL_THR
),
RX_GMF_FL_THR_DEF
);
/* Configure Tx MAC FIFO */
/* Configure Tx MAC FIFO */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_CLR
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_OPER_ON
);
skge_write16
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_OPER_ON
);
}
}
static
void
yukon_stop
(
struct
skge_port
*
skge
)
static
void
yukon_stop
(
struct
skge_port
*
skge
)
...
@@ -1907,19 +1813,19 @@ static void yukon_stop(struct skge_port *skge)
...
@@ -1907,19 +1813,19 @@ static void yukon_stop(struct skge_port *skge)
int
port
=
skge
->
port
;
int
port
=
skge
->
port
;
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_LITE
&&
chip_rev
(
hw
)
==
CHIP_REV_YU_LITE_A3
)
{
hw
->
chip_rev
==
CHIP_REV_YU_LITE_A3
)
{
skge_write32
(
hw
,
B2_GP_IO
,
skge_write32
(
hw
,
B2_GP_IO
,
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
|
GP_IO_9
);
skge_read32
(
hw
,
B2_GP_IO
)
|
GP_DIR_9
|
GP_IO_9
);
}
}
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
gma_read16
(
hw
,
port
,
GM_GP_CTRL
)
&
~
(
GM_GPCR_RX_ENA
|
GM_GPCR_RX_ENA
));
&
~
(
GM_GPCR_RX_ENA
|
GM_GPCR_RX_ENA
));
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
/* set GPHY Control reset */
/* set GPHY Control reset */
skge_
gma_write32
(
hw
,
port
,
GPHY_CTRL
,
GPC_RST_SET
);
gma_write32
(
hw
,
port
,
GPHY_CTRL
,
GPC_RST_SET
);
skge_
gma_write32
(
hw
,
port
,
GMAC_CTRL
,
GMC_RST_SET
);
gma_write32
(
hw
,
port
,
GMAC_CTRL
,
GMC_RST_SET
);
}
}
static
void
yukon_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
)
static
void
yukon_get_stats
(
struct
skge_port
*
skge
,
u64
*
data
)
...
@@ -1928,39 +1834,40 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data)
...
@@ -1928,39 +1834,40 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data)
int
port
=
skge
->
port
;
int
port
=
skge
->
port
;
int
i
;
int
i
;
data
[
0
]
=
(
u64
)
skge_
gma_read32
(
hw
,
port
,
GM_TXO_OK_HI
)
<<
32
data
[
0
]
=
(
u64
)
gma_read32
(
hw
,
port
,
GM_TXO_OK_HI
)
<<
32
|
skge_
gma_read32
(
hw
,
port
,
GM_TXO_OK_LO
);
|
gma_read32
(
hw
,
port
,
GM_TXO_OK_LO
);
data
[
1
]
=
(
u64
)
skge_
gma_read32
(
hw
,
port
,
GM_RXO_OK_HI
)
<<
32
data
[
1
]
=
(
u64
)
gma_read32
(
hw
,
port
,
GM_RXO_OK_HI
)
<<
32
|
skge_
gma_read32
(
hw
,
port
,
GM_RXO_OK_LO
);
|
gma_read32
(
hw
,
port
,
GM_RXO_OK_LO
);
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
for
(
i
=
2
;
i
<
ARRAY_SIZE
(
skge_stats
);
i
++
)
data
[
i
]
=
skge_
gma_read32
(
hw
,
port
,
data
[
i
]
=
gma_read32
(
hw
,
port
,
skge_stats
[
i
].
gma_offset
);
skge_stats
[
i
].
gma_offset
);
}
}
static
void
yukon_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
static
void
yukon_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
{
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
port
]);
struct
net_device
*
dev
=
hw
->
dev
[
port
];
u8
status
=
skge_read8
(
hw
,
SKGEMAC_REG
(
port
,
GMAC_IRQ_SRC
));
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
u8
status
=
skge_read8
(
hw
,
SK_REG
(
port
,
GMAC_IRQ_SRC
));
if
(
netif_msg_intr
(
skge
))
printk
(
KERN_DEBUG
PFX
"%s: mac interrupt status 0x%x
\n
"
,
dev
->
name
,
status
);
pr_debug
(
"yukon_intr status %x
\n
"
,
status
);
if
(
status
&
GM_IS_RX_FF_OR
)
{
if
(
status
&
GM_IS_RX_FF_OR
)
{
++
skge
->
net_stats
.
rx_fifo_errors
;
++
skge
->
net_stats
.
rx_fifo_errors
;
skge_
gma_write8
(
hw
,
port
,
RX_GMF_CTRL_T
,
GMF_CLI_RX_FO
);
gma_write8
(
hw
,
port
,
RX_GMF_CTRL_T
,
GMF_CLI_RX_FO
);
}
}
if
(
status
&
GM_IS_TX_FF_UR
)
{
if
(
status
&
GM_IS_TX_FF_UR
)
{
++
skge
->
net_stats
.
tx_fifo_errors
;
++
skge
->
net_stats
.
tx_fifo_errors
;
skge_
gma_write8
(
hw
,
port
,
TX_GMF_CTRL_T
,
GMF_CLI_TX_FU
);
gma_write8
(
hw
,
port
,
TX_GMF_CTRL_T
,
GMF_CLI_TX_FU
);
}
}
}
}
static
u16
yukon_speed
(
const
struct
skge_hw
*
hw
,
u16
aux
)
static
u16
yukon_speed
(
const
struct
skge_hw
*
hw
,
u16
aux
)
{
{
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
)
switch
(
aux
&
PHY_M_PS_SPEED_MSK
)
{
return
(
aux
&
PHY_M_PS_SPEED_100
)
?
SPEED_100
:
SPEED_10
;
switch
(
aux
&
PHY_M_PS_SPEED_MSK
)
{
case
PHY_M_PS_SPEED_1000
:
case
PHY_M_PS_SPEED_1000
:
return
SPEED_1000
;
return
SPEED_1000
;
case
PHY_M_PS_SPEED_100
:
case
PHY_M_PS_SPEED_100
:
...
@@ -1981,15 +1888,15 @@ static void yukon_link_up(struct skge_port *skge)
...
@@ -1981,15 +1888,15 @@ static void yukon_link_up(struct skge_port *skge)
/* Enable Transmit FIFO Underrun */
/* Enable Transmit FIFO Underrun */
skge_write8
(
hw
,
GMAC_IRQ_MSK
,
GMAC_DEF_MSK
);
skge_write8
(
hw
,
GMAC_IRQ_MSK
,
GMAC_DEF_MSK
);
reg
=
skge_
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
reg
=
gma_read16
(
hw
,
port
,
GM_GP_CTRL
);
if
(
skge
->
duplex
==
DUPLEX_FULL
||
skge
->
autoneg
==
AUTONEG_ENABLE
)
if
(
skge
->
duplex
==
DUPLEX_FULL
||
skge
->
autoneg
==
AUTONEG_ENABLE
)
reg
|=
GM_GPCR_DUP_FULL
;
reg
|=
GM_GPCR_DUP_FULL
;
/* enable Rx/Tx */
/* enable Rx/Tx */
reg
|=
GM_GPCR_RX_ENA
|
GM_GPCR_TX_ENA
;
reg
|=
GM_GPCR_RX_ENA
|
GM_GPCR_TX_ENA
;
skge_
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
gma_write16
(
hw
,
port
,
GM_GP_CTRL
,
reg
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
PHY_M_DEF_MSK
);
skge_link_up
(
skge
);
skge_link_up
(
skge
);
}
}
...
@@ -1999,16 +1906,15 @@ static void yukon_link_down(struct skge_port *skge)
...
@@ -1999,16 +1906,15 @@ static void yukon_link_down(struct skge_port *skge)
int
port
=
skge
->
port
;
int
port
=
skge
->
port
;
pr_debug
(
"yukon_link_down
\n
"
);
pr_debug
(
"yukon_link_down
\n
"
);
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
gm_phy_write
(
hw
,
port
,
PHY_MARV_INT_MASK
,
0
);
skge_
gm_phy_write
(
hw
,
port
,
GM_GP_CTRL
,
gm_phy_write
(
hw
,
port
,
GM_GP_CTRL
,
skge_
gm_phy_read
(
hw
,
port
,
GM_GP_CTRL
)
gm_phy_read
(
hw
,
port
,
GM_GP_CTRL
)
&
~
(
GM_GPCR_RX_ENA
|
GM_GPCR_TX_ENA
));
&
~
(
GM_GPCR_RX_ENA
|
GM_GPCR_TX_ENA
));
if
(
hw
->
chip_id
!=
CHIP_ID_YUKON_FE
&&
if
(
skge
->
flow_control
==
FLOW_MODE_REM_SEND
)
{
skge
->
flow_control
==
FLOW_MODE_REM_SEND
)
{
/* restore Asymmetric Pause bit */
/* restore Asymmetric Pause bit */
skge_
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
gm_phy_write
(
hw
,
port
,
PHY_MARV_AUNE_ADV
,
skge_
gm_phy_read
(
hw
,
port
,
gm_phy_read
(
hw
,
port
,
PHY_MARV_AUNE_ADV
)
PHY_MARV_AUNE_ADV
)
|
PHY_M_AN_ASP
);
|
PHY_M_AN_ASP
);
...
@@ -2027,20 +1933,21 @@ static void yukon_phy_intr(struct skge_port *skge)
...
@@ -2027,20 +1933,21 @@ static void yukon_phy_intr(struct skge_port *skge)
const
char
*
reason
=
NULL
;
const
char
*
reason
=
NULL
;
u16
istatus
,
phystat
;
u16
istatus
,
phystat
;
istatus
=
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_INT_STAT
);
istatus
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_INT_STAT
);
phystat
=
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_PHY_STAT
);
phystat
=
gm_phy_read
(
hw
,
port
,
PHY_MARV_PHY_STAT
);
pr_debug
(
"yukon phy intr istat=%x phy_stat=%x
\n
"
,
istatus
,
phystat
);
if
(
netif_msg_intr
(
skge
))
printk
(
KERN_DEBUG
PFX
"%s: phy interrupt status 0x%x 0x%x
\n
"
,
skge
->
netdev
->
name
,
istatus
,
phystat
);
if
(
istatus
&
PHY_M_IS_AN_COMPL
)
{
if
(
istatus
&
PHY_M_IS_AN_COMPL
)
{
if
(
skge_
gm_phy_read
(
hw
,
port
,
PHY_MARV_AUNE_LP
)
if
(
gm_phy_read
(
hw
,
port
,
PHY_MARV_AUNE_LP
)
&
PHY_M_AN_RF
)
{
&
PHY_M_AN_RF
)
{
reason
=
"remote fault"
;
reason
=
"remote fault"
;
goto
failed
;
goto
failed
;
}
}
if
(
!
(
hw
->
chip_id
==
CHIP_ID_YUKON_FE
||
hw
->
chip_id
==
CHIP_ID_YUKON_EC
)
if
(
gm_phy_read
(
hw
,
port
,
PHY_MARV_1000T_STAT
)
&
PHY_B_1000S_MSF
)
{
&&
(
skge_gm_phy_read
(
hw
,
port
,
PHY_MARV_1000T_STAT
)
&
PHY_B_1000S_MSF
))
{
reason
=
"master/slave fault"
;
reason
=
"master/slave fault"
;
goto
failed
;
goto
failed
;
}
}
...
@@ -2054,10 +1961,6 @@ static void yukon_phy_intr(struct skge_port *skge)
...
@@ -2054,10 +1961,6 @@ static void yukon_phy_intr(struct skge_port *skge)
?
DUPLEX_FULL
:
DUPLEX_HALF
;
?
DUPLEX_FULL
:
DUPLEX_HALF
;
skge
->
speed
=
yukon_speed
(
hw
,
phystat
);
skge
->
speed
=
yukon_speed
(
hw
,
phystat
);
/* Tx & Rx Pause Enabled bits are at 9..8 */
if
(
hw
->
chip_id
==
CHIP_ID_YUKON_XL
)
phystat
>>=
6
;
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
/* We are using IEEE 802.3z/D5.0 Table 37-4 */
switch
(
phystat
&
PHY_M_PS_PAUSE_MSK
)
{
switch
(
phystat
&
PHY_M_PS_PAUSE_MSK
)
{
case
PHY_M_PS_PAUSE_MSK
:
case
PHY_M_PS_PAUSE_MSK
:
...
@@ -2075,9 +1978,9 @@ static void yukon_phy_intr(struct skge_port *skge)
...
@@ -2075,9 +1978,9 @@ static void yukon_phy_intr(struct skge_port *skge)
if
(
skge
->
flow_control
==
FLOW_MODE_NONE
||
if
(
skge
->
flow_control
==
FLOW_MODE_NONE
||
(
skge
->
speed
<
SPEED_1000
&&
skge
->
duplex
==
DUPLEX_HALF
))
(
skge
->
speed
<
SPEED_1000
&&
skge
->
duplex
==
DUPLEX_HALF
))
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
skge_write8
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_OFF
);
else
else
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
);
skge_write8
(
hw
,
SK_REG
(
port
,
GMAC_CTRL
),
GMC_PAUSE_ON
);
yukon_link_up
(
skge
);
yukon_link_up
(
skge
);
return
;
return
;
}
}
...
@@ -2161,6 +2064,12 @@ static int skge_up(struct net_device *dev)
...
@@ -2161,6 +2064,12 @@ static int skge_up(struct net_device *dev)
if
(
netif_msg_ifup
(
skge
))
if
(
netif_msg_ifup
(
skge
))
printk
(
KERN_INFO
PFX
"%s: enabling interface
\n
"
,
dev
->
name
);
printk
(
KERN_INFO
PFX
"%s: enabling interface
\n
"
,
dev
->
name
);
if
(
dev
->
mtu
>
RX_BUF_SIZE
)
skge
->
rx_buf_size
=
dev
->
mtu
+
ETH_HLEN
+
NET_IP_ALIGN
;
else
skge
->
rx_buf_size
=
RX_BUF_SIZE
;
rx_size
=
skge
->
rx_ring
.
count
*
sizeof
(
struct
skge_rx_desc
);
rx_size
=
skge
->
rx_ring
.
count
*
sizeof
(
struct
skge_rx_desc
);
tx_size
=
skge
->
tx_ring
.
count
*
sizeof
(
struct
skge_tx_desc
);
tx_size
=
skge
->
tx_ring
.
count
*
sizeof
(
struct
skge_tx_desc
);
skge
->
mem_size
=
tx_size
+
rx_size
;
skge
->
mem_size
=
tx_size
+
rx_size
;
...
@@ -2173,7 +2082,8 @@ static int skge_up(struct net_device *dev)
...
@@ -2173,7 +2082,8 @@ static int skge_up(struct net_device *dev)
if
((
err
=
skge_ring_alloc
(
&
skge
->
rx_ring
,
skge
->
mem
,
skge
->
dma
)))
if
((
err
=
skge_ring_alloc
(
&
skge
->
rx_ring
,
skge
->
mem
,
skge
->
dma
)))
goto
free_pci_mem
;
goto
free_pci_mem
;
if
(
skge_rx_fill
(
skge
))
err
=
skge_rx_fill
(
skge
);
if
(
err
)
goto
free_rx_ring
;
goto
free_rx_ring
;
if
((
err
=
skge_ring_alloc
(
&
skge
->
tx_ring
,
skge
->
mem
+
rx_size
,
if
((
err
=
skge_ring_alloc
(
&
skge
->
tx_ring
,
skge
->
mem
+
rx_size
,
...
@@ -2182,6 +2092,10 @@ static int skge_up(struct net_device *dev)
...
@@ -2182,6 +2092,10 @@ static int skge_up(struct net_device *dev)
skge
->
tx_avail
=
skge
->
tx_ring
.
count
-
1
;
skge
->
tx_avail
=
skge
->
tx_ring
.
count
-
1
;
/* Enable IRQ from port */
hw
->
intr_mask
|=
portirqmask
[
port
];
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
/* Initialze MAC */
/* Initialze MAC */
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
genesis_mac_init
(
hw
,
port
);
genesis_mac_init
(
hw
,
port
);
...
@@ -2189,7 +2103,7 @@ static int skge_up(struct net_device *dev)
...
@@ -2189,7 +2103,7 @@ static int skge_up(struct net_device *dev)
yukon_mac_init
(
hw
,
port
);
yukon_mac_init
(
hw
,
port
);
/* Configure RAMbuffers */
/* Configure RAMbuffers */
chunk
=
hw
->
ram_size
/
(
isdualport
(
hw
)
?
4
:
2
);
chunk
=
hw
->
ram_size
/
(
(
hw
->
ports
+
1
)
*
2
);
ram_addr
=
hw
->
ram_offset
+
2
*
chunk
*
port
;
ram_addr
=
hw
->
ram_offset
+
2
*
chunk
*
port
;
skge_ramset
(
hw
,
rxqaddr
[
port
],
ram_addr
,
chunk
);
skge_ramset
(
hw
,
rxqaddr
[
port
],
ram_addr
,
chunk
);
...
@@ -2227,7 +2141,6 @@ static int skge_down(struct net_device *dev)
...
@@ -2227,7 +2141,6 @@ static int skge_down(struct net_device *dev)
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
del_timer_sync
(
&
skge
->
led_blink
);
del_timer_sync
(
&
skge
->
led_blink
);
del_timer_sync
(
&
skge
->
link_check
);
/* Stop transmitter */
/* Stop transmitter */
skge_write8
(
hw
,
Q_ADDR
(
txqaddr
[
port
],
Q_CSR
),
CSR_STOP
);
skge_write8
(
hw
,
Q_ADDR
(
txqaddr
[
port
],
Q_CSR
),
CSR_STOP
);
...
@@ -2240,12 +2153,12 @@ static int skge_down(struct net_device *dev)
...
@@ -2240,12 +2153,12 @@ static int skge_down(struct net_device *dev)
yukon_stop
(
skge
);
yukon_stop
(
skge
);
/* Disable Force Sync bit and Enable Alloc bit */
/* Disable Force Sync bit and Enable Alloc bit */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TXA_CTRL
),
skge_write8
(
hw
,
SK_REG
(
port
,
TXA_CTRL
),
TXA_DIS_FSYNC
|
TXA_DIS_ALLOC
|
TXA_STOP_RC
);
TXA_DIS_FSYNC
|
TXA_DIS_ALLOC
|
TXA_STOP_RC
);
/* Stop Interval Timer and Limit Counter of Tx Arbiter */
/* Stop Interval Timer and Limit Counter of Tx Arbiter */
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
TXA_ITI_INI
),
0L
);
skge_write32
(
hw
,
SK_REG
(
port
,
TXA_ITI_INI
),
0L
);
skge_write32
(
hw
,
SK
GEMAC
_REG
(
port
,
TXA_LIM_INI
),
0L
);
skge_write32
(
hw
,
SK_REG
(
port
,
TXA_LIM_INI
),
0L
);
/* Reset PCI FIFO */
/* Reset PCI FIFO */
skge_write32
(
hw
,
Q_ADDR
(
txqaddr
[
port
],
Q_CSR
),
CSR_SET_RESET
);
skge_write32
(
hw
,
Q_ADDR
(
txqaddr
[
port
],
Q_CSR
),
CSR_SET_RESET
);
...
@@ -2260,13 +2173,13 @@ static int skge_down(struct net_device *dev)
...
@@ -2260,13 +2173,13 @@ static int skge_down(struct net_device *dev)
skge_write32
(
hw
,
Q_ADDR
(
rxqaddr
[
port
],
Q_CSR
),
CSR_SET_RESET
);
skge_write32
(
hw
,
Q_ADDR
(
rxqaddr
[
port
],
Q_CSR
),
CSR_SET_RESET
);
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_MFF_CTRL2
),
MFF_RST_SET
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_LED_CTRL
),
LED_STOP
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_LED_CTRL
),
LED_STOP
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_LED_CTRL
),
LED_STOP
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_LED_CTRL
),
LED_STOP
);
}
else
{
}
else
{
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
RX_GMF_CTRL_T
),
GMF_RST_SET
);
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_SET
);
skge_write8
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
GMF_RST_SET
);
}
}
/* turn off led's */
/* turn off led's */
...
@@ -2299,10 +2212,10 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -2299,10 +2212,10 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
local_irq_save
(
flags
);
local_irq_save
(
flags
);
if
(
!
spin_trylock
(
&
skge
->
tx_lock
))
{
if
(
!
spin_trylock
(
&
skge
->
tx_lock
))
{
/* Collision - tell upper layer to requeue */
/* Collision - tell upper layer to requeue */
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
return
NETDEV_TX_LOCKED
;
return
NETDEV_TX_LOCKED
;
}
}
if
(
unlikely
(
skge
->
tx_avail
<
skb_shinfo
(
skb
)
->
nr_frags
+
1
))
{
if
(
unlikely
(
skge
->
tx_avail
<
skb_shinfo
(
skb
)
->
nr_frags
+
1
))
{
netif_stop_queue
(
dev
);
netif_stop_queue
(
dev
);
...
@@ -2333,7 +2246,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -2333,7 +2246,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
* does. Looks like hardware is wrong?
* does. Looks like hardware is wrong?
*/
*/
if
(
ip
->
protocol
==
IPPROTO_UDP
if
(
ip
->
protocol
==
IPPROTO_UDP
&&
chip_rev
(
hw
)
==
0
&&
hw
->
chip_id
==
CHIP_ID_YUKON
)
&&
hw
->
chip_rev
==
0
&&
hw
->
chip_id
==
CHIP_ID_YUKON
)
control
=
BMU_TCP_CHECK
;
control
=
BMU_TCP_CHECK
;
else
else
control
=
BMU_UDP_CHECK
;
control
=
BMU_UDP_CHECK
;
...
@@ -2394,6 +2307,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
...
@@ -2394,6 +2307,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
static
inline
void
skge_tx_free
(
struct
skge_hw
*
hw
,
struct
skge_element
*
e
)
static
inline
void
skge_tx_free
(
struct
skge_hw
*
hw
,
struct
skge_element
*
e
)
{
{
/* This ring element can be skb or fragment */
if
(
e
->
skb
)
{
if
(
e
->
skb
)
{
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_addr
(
e
,
mapaddr
),
...
@@ -2438,16 +2352,17 @@ static void skge_tx_timeout(struct net_device *dev)
...
@@ -2438,16 +2352,17 @@ static void skge_tx_timeout(struct net_device *dev)
static
int
skge_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
static
int
skge_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
{
int
err
=
0
;
int
err
=
0
;
int
running
=
netif_running
(
dev
);
if
(
new_mtu
<
ETH_ZLEN
||
new_mtu
>
ETH_JUMBO_MTU
)
if
(
new_mtu
<
ETH_ZLEN
||
new_mtu
>
ETH_JUMBO_MTU
)
return
-
EINVAL
;
return
-
EINVAL
;
dev
->
mtu
=
new_mtu
;
if
(
netif_running
(
dev
))
{
if
(
running
)
skge_down
(
dev
);
skge_down
(
dev
);
dev
->
mtu
=
new_mtu
;
if
(
running
)
skge_up
(
dev
);
skge_up
(
dev
);
}
return
err
;
return
err
;
}
}
...
@@ -2462,7 +2377,9 @@ static void genesis_set_multicast(struct net_device *dev)
...
@@ -2462,7 +2377,9 @@ static void genesis_set_multicast(struct net_device *dev)
u32
mode
;
u32
mode
;
u8
filter
[
8
];
u8
filter
[
8
];
mode
=
skge_xm_read32
(
hw
,
port
,
XM_MODE
);
pr_debug
(
"genesis_set_multicast flags=%x count=%d
\n
"
,
dev
->
flags
,
dev
->
mc_count
);
mode
=
xm_read32
(
hw
,
port
,
XM_MODE
);
mode
|=
XM_MD_ENA_HASH
;
mode
|=
XM_MD_ENA_HASH
;
if
(
dev
->
flags
&
IFF_PROMISC
)
if
(
dev
->
flags
&
IFF_PROMISC
)
mode
|=
XM_MD_ENA_PROM
;
mode
|=
XM_MD_ENA_PROM
;
...
@@ -2473,17 +2390,16 @@ static void genesis_set_multicast(struct net_device *dev)
...
@@ -2473,17 +2390,16 @@ static void genesis_set_multicast(struct net_device *dev)
memset
(
filter
,
0xff
,
sizeof
(
filter
));
memset
(
filter
,
0xff
,
sizeof
(
filter
));
else
{
else
{
memset
(
filter
,
0
,
sizeof
(
filter
));
memset
(
filter
,
0
,
sizeof
(
filter
));
for
(
i
=
0
;
list
&&
i
<
count
;
i
++
,
list
=
list
->
next
)
{
for
(
i
=
0
;
list
&&
i
<
count
;
i
++
,
list
=
list
->
next
)
{
u32
crc
=
crc32_le
(
~
0
,
list
->
dmi_addr
,
ETH_ALEN
)
;
u32
crc
,
bit
;
u8
bit
=
63
-
(
crc
&
63
);
crc
=
ether_crc_le
(
ETH_ALEN
,
list
->
dmi_addr
);
bit
=
~
crc
&
0x3f
;
filter
[
bit
/
8
]
|=
1
<<
(
bit
%
8
);
filter
[
bit
/
8
]
|=
1
<<
(
bit
%
8
);
}
}
}
}
skge_xm_outhash
(
hw
,
port
,
XM_HSM
,
filter
);
xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
xm_outhash
(
hw
,
port
,
XM_HSM
,
filter
);
skge_xm_write32
(
hw
,
port
,
XM_MODE
,
mode
);
}
}
static
void
yukon_set_multicast
(
struct
net_device
*
dev
)
static
void
yukon_set_multicast
(
struct
net_device
*
dev
)
...
@@ -2497,7 +2413,7 @@ static void yukon_set_multicast(struct net_device *dev)
...
@@ -2497,7 +2413,7 @@ static void yukon_set_multicast(struct net_device *dev)
memset
(
filter
,
0
,
sizeof
(
filter
));
memset
(
filter
,
0
,
sizeof
(
filter
));
reg
=
skge_
gma_read16
(
hw
,
port
,
GM_RX_CTRL
);
reg
=
gma_read16
(
hw
,
port
,
GM_RX_CTRL
);
reg
|=
GM_RXCR_UCF_ENA
;
reg
|=
GM_RXCR_UCF_ENA
;
if
(
dev
->
flags
&
IFF_PROMISC
)
/* promiscious */
if
(
dev
->
flags
&
IFF_PROMISC
)
/* promiscious */
...
@@ -2510,23 +2426,23 @@ static void yukon_set_multicast(struct net_device *dev)
...
@@ -2510,23 +2426,23 @@ static void yukon_set_multicast(struct net_device *dev)
int
i
;
int
i
;
reg
|=
GM_RXCR_MCF_ENA
;
reg
|=
GM_RXCR_MCF_ENA
;
for
(
i
=
0
;
list
&&
i
<
dev
->
mc_count
;
i
++
,
list
=
list
->
next
)
{
for
(
i
=
0
;
list
&&
i
<
dev
->
mc_count
;
i
++
,
list
=
list
->
next
)
{
u32
bit
=
ether_crc
(
ETH_ALEN
,
list
->
dmi_addr
)
&
0x3f
;
u32
bit
=
ether_crc
(
ETH_ALEN
,
list
->
dmi_addr
)
&
0x3f
;
filter
[
bit
/
8
]
|=
1
<<
(
bit
%
8
);
filter
[
bit
/
8
]
|=
1
<<
(
bit
%
8
);
}
}
}
}
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H1
,
(
u16
)
filter
[
0
]
|
((
u16
)
filter
[
1
]
<<
8
));
(
u16
)
filter
[
0
]
|
((
u16
)
filter
[
1
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H2
,
(
u16
)
filter
[
2
]
|
((
u16
)
filter
[
3
]
<<
8
));
(
u16
)
filter
[
2
]
|
((
u16
)
filter
[
3
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H3
,
(
u16
)
filter
[
4
]
|
((
u16
)
filter
[
5
]
<<
8
));
(
u16
)
filter
[
4
]
|
((
u16
)
filter
[
5
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
gma_write16
(
hw
,
port
,
GM_MC_ADDR_H4
,
(
u16
)
filter
[
6
]
|
((
u16
)
filter
[
7
]
<<
8
));
(
u16
)
filter
[
6
]
|
((
u16
)
filter
[
7
]
<<
8
));
skge_
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
reg
);
gma_write16
(
hw
,
port
,
GM_RX_CTRL
,
reg
);
}
}
static
inline
int
bad_phy_status
(
const
struct
skge_hw
*
hw
,
u32
status
)
static
inline
int
bad_phy_status
(
const
struct
skge_hw
*
hw
,
u32
status
)
...
@@ -2545,28 +2461,76 @@ static void skge_rx_error(struct skge_port *skge, int slot,
...
@@ -2545,28 +2461,76 @@ static void skge_rx_error(struct skge_port *skge, int slot,
printk
(
KERN_DEBUG
PFX
"%s: rx err, slot %d control 0x%x status 0x%x
\n
"
,
printk
(
KERN_DEBUG
PFX
"%s: rx err, slot %d control 0x%x status 0x%x
\n
"
,
skge
->
netdev
->
name
,
slot
,
control
,
status
);
skge
->
netdev
->
name
,
slot
,
control
,
status
);
if
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
)
if
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
))
||
(
control
&
BMU_BBC
)
>
skge
->
netdev
->
mtu
+
VLAN_ETH_HLEN
)
skge
->
net_stats
.
rx_length_errors
++
;
skge
->
net_stats
.
rx_length_errors
++
;
else
{
else
if
(
skge
->
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
if
(
skge
->
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
if
(
status
&
(
XMR_FS_RUNT
|
XMR_FS_LNG_ERR
))
if
(
status
&
(
XMR_FS_RUNT
|
XMR_FS_LNG_ERR
))
skge
->
net_stats
.
rx_length_errors
++
;
skge
->
net_stats
.
rx_length_errors
++
;
if
(
status
&
XMR_FS_FRA_ERR
)
if
(
status
&
XMR_FS_FRA_ERR
)
skge
->
net_stats
.
rx_frame_errors
++
;
skge
->
net_stats
.
rx_frame_errors
++
;
if
(
status
&
XMR_FS_FCS_ERR
)
if
(
status
&
XMR_FS_FCS_ERR
)
skge
->
net_stats
.
rx_crc_errors
++
;
skge
->
net_stats
.
rx_crc_errors
++
;
}
else
{
}
else
{
if
(
status
&
(
GMR_FS_LONG_ERR
|
GMR_FS_UN_SIZE
))
if
(
status
&
(
GMR_FS_LONG_ERR
|
GMR_FS_UN_SIZE
))
skge
->
net_stats
.
rx_length_errors
++
;
skge
->
net_stats
.
rx_length_errors
++
;
if
(
status
&
GMR_FS_FRAGMENT
)
if
(
status
&
GMR_FS_FRAGMENT
)
skge
->
net_stats
.
rx_frame_errors
++
;
skge
->
net_stats
.
rx_frame_errors
++
;
if
(
status
&
GMR_FS_CRC_ERR
)
if
(
status
&
GMR_FS_CRC_ERR
)
skge
->
net_stats
.
rx_crc_errors
++
;
skge
->
net_stats
.
rx_crc_errors
++
;
}
}
/* Get receive buffer from descriptor.
* Handles copy of small buffers and reallocation failures
*/
static
inline
struct
sk_buff
*
skge_rx_get
(
struct
skge_port
*
skge
,
struct
skge_element
*
e
,
unsigned
int
len
)
{
struct
sk_buff
*
nskb
,
*
skb
;
if
(
len
<
RX_COPY_THRESHOLD
)
{
nskb
=
skge_rx_alloc
(
skge
->
netdev
,
len
+
NET_IP_ALIGN
);
if
(
unlikely
(
!
nskb
))
return
NULL
;
pci_dma_sync_single_for_cpu
(
skge
->
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
len
,
PCI_DMA_FROMDEVICE
);
memcpy
(
nskb
->
data
,
e
->
skb
->
data
,
len
);
pci_dma_sync_single_for_device
(
skge
->
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
len
,
PCI_DMA_FROMDEVICE
);
if
(
skge
->
rx_csum
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
nskb
->
csum
=
le16_to_cpu
(
rd
->
csum2
);
nskb
->
ip_summed
=
CHECKSUM_HW
;
}
}
skge_rx_reuse
(
e
,
skge
->
rx_buf_size
);
return
nskb
;
}
else
{
nskb
=
skge_rx_alloc
(
skge
->
netdev
,
skge
->
rx_buf_size
);
if
(
unlikely
(
!
nskb
))
return
NULL
;
pci_unmap_single
(
skge
->
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_len
(
e
,
maplen
),
PCI_DMA_FROMDEVICE
);
skb
=
e
->
skb
;
if
(
skge
->
rx_csum
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
skb
->
csum
=
le16_to_cpu
(
rd
->
csum2
);
skb
->
ip_summed
=
CHECKSUM_HW
;
}
skge_rx_setup
(
skge
,
e
,
nskb
,
skge
->
rx_buf_size
);
return
skb
;
}
}
}
}
static
int
skge_poll
(
struct
net_device
*
dev
,
int
*
budget
)
static
int
skge_poll
(
struct
net_device
*
dev
,
int
*
budget
)
{
{
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
struct
skge_port
*
skge
=
netdev_priv
(
dev
);
...
@@ -2575,13 +2539,12 @@ static int skge_poll(struct net_device *dev, int *budget)
...
@@ -2575,13 +2539,12 @@ static int skge_poll(struct net_device *dev, int *budget)
struct
skge_element
*
e
;
struct
skge_element
*
e
;
unsigned
int
to_do
=
min
(
dev
->
quota
,
*
budget
);
unsigned
int
to_do
=
min
(
dev
->
quota
,
*
budget
);
unsigned
int
work_done
=
0
;
unsigned
int
work_done
=
0
;
int
done
;
static
const
u32
irqmask
[]
=
{
IS_PORT_1
,
IS_PORT_2
};
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
&&
work_done
<
to_do
;
pr_debug
(
"skge_poll
\n
"
);
e
=
e
->
next
)
{
for
(
e
=
ring
->
to_clean
;
work_done
<
to_do
;
e
=
e
->
next
)
{
struct
skge_rx_desc
*
rd
=
e
->
desc
;
struct
skge_rx_desc
*
rd
=
e
->
desc
;
struct
sk_buff
*
skb
=
e
->
skb
;
struct
sk_buff
*
skb
;
u32
control
,
len
,
status
;
u32
control
,
len
,
status
;
rmb
();
rmb
();
...
@@ -2590,19 +2553,12 @@ static int skge_poll(struct net_device *dev, int *budget)
...
@@ -2590,19 +2553,12 @@ static int skge_poll(struct net_device *dev, int *budget)
break
;
break
;
len
=
control
&
BMU_BBC
;
len
=
control
&
BMU_BBC
;
e
->
skb
=
NULL
;
pci_unmap_single
(
hw
->
pdev
,
pci_unmap_addr
(
e
,
mapaddr
),
pci_unmap_len
(
e
,
maplen
),
PCI_DMA_FROMDEVICE
);
status
=
rd
->
status
;
status
=
rd
->
status
;
if
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
)
||
len
>
dev
->
mtu
+
VLAN_ETH_HLEN
if
(
unlikely
((
control
&
(
BMU_EOF
|
BMU_STF
))
!=
(
BMU_STF
|
BMU_EOF
)
||
bad_phy_status
(
hw
,
status
))
{
||
bad_phy_status
(
hw
,
status
)
))
{
skge_rx_error
(
skge
,
e
-
ring
->
start
,
control
,
status
);
skge_rx_error
(
skge
,
e
-
ring
->
start
,
control
,
status
);
dev_kfree_skb
(
skb
);
skge_rx_reuse
(
e
,
skge
->
rx_buf_size
);
continue
;
continue
;
}
}
...
@@ -2610,43 +2566,37 @@ static int skge_poll(struct net_device *dev, int *budget)
...
@@ -2610,43 +2566,37 @@ static int skge_poll(struct net_device *dev, int *budget)
printk
(
KERN_DEBUG
PFX
"%s: rx slot %td status 0x%x len %d
\n
"
,
printk
(
KERN_DEBUG
PFX
"%s: rx slot %td status 0x%x len %d
\n
"
,
dev
->
name
,
e
-
ring
->
start
,
rd
->
status
,
len
);
dev
->
name
,
e
-
ring
->
start
,
rd
->
status
,
len
);
skb_put
(
skb
,
len
);
skb
=
skge_rx_get
(
skge
,
e
,
len
);
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
if
(
likely
(
skb
))
{
skb_put
(
skb
,
len
);
if
(
skge
->
rx_csum
)
{
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
skb
->
csum
=
le16_to_cpu
(
rd
->
csum2
);
skb
->
ip_summed
=
CHECKSUM_HW
;
}
dev
->
last_rx
=
jiffies
;
dev
->
last_rx
=
jiffies
;
netif_receive_skb
(
skb
);
netif_receive_skb
(
skb
);
++
work_done
;
++
work_done
;
}
else
skge_rx_reuse
(
e
,
skge
->
rx_buf_size
);
}
}
ring
->
to_clean
=
e
;
ring
->
to_clean
=
e
;
*
budget
-=
work_done
;
dev
->
quota
-=
work_done
;
done
=
work_done
<
to_do
;
if
(
skge_rx_fill
(
skge
))
done
=
0
;
/* restart receiver */
/* restart receiver */
wmb
();
wmb
();
skge_write8
(
hw
,
Q_ADDR
(
rxqaddr
[
skge
->
port
],
Q_CSR
),
skge_write8
(
hw
,
Q_ADDR
(
rxqaddr
[
skge
->
port
],
Q_CSR
),
CSR_START
|
CSR_IRQ_CL_F
);
CSR_START
|
CSR_IRQ_CL_F
);
if
(
done
)
{
*
budget
-=
work_done
;
local_irq_disable
();
dev
->
quota
-=
work_done
;
hw
->
intr_mask
|=
irqmask
[
skge
->
port
];
/* Order is important since data can get interrupted */
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
__netif_rx_complete
(
dev
);
local_irq_enable
();
}
return
!
done
;
if
(
work_done
>=
to_do
)
return
1
;
/* not done */
local_irq_disable
();
__netif_rx_complete
(
dev
);
hw
->
intr_mask
|=
portirqmask
[
skge
->
port
];
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
local_irq_enable
();
return
0
;
}
}
static
inline
void
skge_tx_intr
(
struct
net_device
*
dev
)
static
inline
void
skge_tx_intr
(
struct
net_device
*
dev
)
...
@@ -2657,7 +2607,7 @@ static inline void skge_tx_intr(struct net_device *dev)
...
@@ -2657,7 +2607,7 @@ static inline void skge_tx_intr(struct net_device *dev)
struct
skge_element
*
e
;
struct
skge_element
*
e
;
spin_lock
(
&
skge
->
tx_lock
);
spin_lock
(
&
skge
->
tx_lock
);
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
;
e
=
e
->
next
)
{
for
(
e
=
ring
->
to_clean
;
e
!=
ring
->
to_use
;
e
=
e
->
next
)
{
struct
skge_tx_desc
*
td
=
e
->
desc
;
struct
skge_tx_desc
*
td
=
e
->
desc
;
u32
control
;
u32
control
;
...
@@ -2690,12 +2640,12 @@ static void skge_mac_parity(struct skge_hw *hw, int port)
...
@@ -2690,12 +2640,12 @@ static void skge_mac_parity(struct skge_hw *hw, int port)
:
(
port
==
0
?
"(port A)"
:
"(port B"
));
:
(
port
==
0
?
"(port A)"
:
"(port B"
));
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
skge_write16
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_MFF_CTRL1
),
skge_write16
(
hw
,
SK_REG
(
port
,
TX_MFF_CTRL1
),
MFF_CLR_PERR
);
MFF_CLR_PERR
);
else
else
/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
skge_write8
(
hw
,
SK
GEMAC
_REG
(
port
,
TX_GMF_CTRL_T
),
skge_write8
(
hw
,
SK_REG
(
port
,
TX_GMF_CTRL_T
),
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
chip_rev
(
hw
)
==
0
)
(
hw
->
chip_id
==
CHIP_ID_YUKON
&&
hw
->
chip_rev
==
0
)
?
GMF_CLI_TX_FC
:
GMF_CLI_TX_PE
);
?
GMF_CLI_TX_FC
:
GMF_CLI_TX_PE
);
}
}
...
@@ -2703,16 +2653,16 @@ static void skge_pci_clear(struct skge_hw *hw)
...
@@ -2703,16 +2653,16 @@ static void skge_pci_clear(struct skge_hw *hw)
{
{
u16
status
;
u16
status
;
status
=
skge_read16
(
hw
,
SKGEPCI_REG
(
PCI_STATUS
)
);
pci_read_config_word
(
hw
->
pdev
,
PCI_STATUS
,
&
status
);
skge_write8
(
hw
,
B2_TST_CTRL1
,
TST_CFG_WRITE_ON
);
skge_write8
(
hw
,
B2_TST_CTRL1
,
TST_CFG_WRITE_ON
);
skge_write16
(
hw
,
SKGEPCI_REG
(
PCI_STATUS
)
,
pci_write_config_word
(
hw
->
pdev
,
PCI_STATUS
,
status
|
PCI_STATUS_ERROR_BITS
);
status
|
PCI_STATUS_ERROR_BITS
);
skge_write8
(
hw
,
B2_TST_CTRL1
,
TST_CFG_WRITE_OFF
);
skge_write8
(
hw
,
B2_TST_CTRL1
,
TST_CFG_WRITE_OFF
);
}
}
static
void
skge_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
static
void
skge_mac_intr
(
struct
skge_hw
*
hw
,
int
port
)
{
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
genesis_mac_intr
(
hw
,
port
);
genesis_mac_intr
(
hw
,
port
);
else
else
yukon_mac_intr
(
hw
,
port
);
yukon_mac_intr
(
hw
,
port
);
...
@@ -2726,9 +2676,9 @@ static void skge_error_irq(struct skge_hw *hw)
...
@@ -2726,9 +2676,9 @@ static void skge_error_irq(struct skge_hw *hw)
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
{
/* clear xmac errors */
/* clear xmac errors */
if
(
hwstatus
&
(
IS_NO_STAT_M1
|
IS_NO_TIST_M1
))
if
(
hwstatus
&
(
IS_NO_STAT_M1
|
IS_NO_TIST_M1
))
skge_write16
(
hw
,
SK
GEMAC
_REG
(
0
,
RX_MFF_CTRL1
),
MFF_CLR_INSTAT
);
skge_write16
(
hw
,
SK_REG
(
0
,
RX_MFF_CTRL1
),
MFF_CLR_INSTAT
);
if
(
hwstatus
&
(
IS_NO_STAT_M2
|
IS_NO_TIST_M2
))
if
(
hwstatus
&
(
IS_NO_STAT_M2
|
IS_NO_TIST_M2
))
skge_write16
(
hw
,
SK
GEMAC
_REG
(
0
,
RX_MFF_CTRL2
),
MFF_CLR_INSTAT
);
skge_write16
(
hw
,
SK_REG
(
0
,
RX_MFF_CTRL2
),
MFF_CLR_INSTAT
);
}
else
{
}
else
{
/* Timestamp (unused) overflow */
/* Timestamp (unused) overflow */
if
(
hwstatus
&
IS_IRQ_TIST_OV
)
if
(
hwstatus
&
IS_IRQ_TIST_OV
)
...
@@ -2803,8 +2753,8 @@ static void skge_extirq(unsigned long data)
...
@@ -2803,8 +2753,8 @@ static void skge_extirq(unsigned long data)
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
)
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
)
yukon_phy_intr
(
skge
);
yukon_phy_intr
(
skge
);
else
if
(
hw
->
phy_type
==
SK_PHY_BCOM
)
else
genesis_bcom
_intr
(
skge
);
bcom_phy
_intr
(
skge
);
}
}
}
}
spin_unlock
(
&
hw
->
phy_lock
);
spin_unlock
(
&
hw
->
phy_lock
);
...
@@ -2824,19 +2774,14 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -2824,19 +2774,14 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
return
IRQ_NONE
;
return
IRQ_NONE
;
status
&=
hw
->
intr_mask
;
status
&=
hw
->
intr_mask
;
if
(
status
&
IS_R1_F
)
{
if
((
status
&
IS_R1_F
)
&&
netif_rx_schedule_prep
(
hw
->
dev
[
0
]))
{
status
&=
~
IS_R1_F
;
hw
->
intr_mask
&=
~
IS_R1_F
;
hw
->
intr_mask
&=
~
IS_R1_F
;
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
netif_rx_schedule
(
hw
->
dev
[
0
]);
__netif_rx_schedule
(
hw
->
dev
[
0
]);
}
}
if
((
status
&
IS_R2_F
)
&&
netif_rx_schedule_prep
(
hw
->
dev
[
1
]))
{
if
(
status
&
IS_R2_F
)
{
status
&=
~
IS_R2_F
;
hw
->
intr_mask
&=
~
IS_R2_F
;
hw
->
intr_mask
&=
~
IS_R2_F
;
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
netif_rx_schedule
(
hw
->
dev
[
1
]);
__netif_rx_schedule
(
hw
->
dev
[
1
]);
}
}
if
(
status
&
IS_XA1_F
)
if
(
status
&
IS_XA1_F
)
...
@@ -2845,9 +2790,27 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -2845,9 +2790,27 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
if
(
status
&
IS_XA2_F
)
if
(
status
&
IS_XA2_F
)
skge_tx_intr
(
hw
->
dev
[
1
]);
skge_tx_intr
(
hw
->
dev
[
1
]);
if
(
status
&
IS_PA_TO_RX1
)
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
0
]);
++
skge
->
net_stats
.
rx_over_errors
;
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_RX1
);
}
if
(
status
&
IS_PA_TO_RX2
)
{
struct
skge_port
*
skge
=
netdev_priv
(
hw
->
dev
[
1
]);
++
skge
->
net_stats
.
rx_over_errors
;
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_RX2
);
}
if
(
status
&
IS_PA_TO_TX1
)
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_TX1
);
if
(
status
&
IS_PA_TO_TX2
)
skge_write16
(
hw
,
B3_PA_CTRL
,
PA_CLR_TO_TX2
);
if
(
status
&
IS_MAC1
)
if
(
status
&
IS_MAC1
)
skge_mac_intr
(
hw
,
0
);
skge_mac_intr
(
hw
,
0
);
if
(
status
&
IS_MAC2
)
if
(
status
&
IS_MAC2
)
skge_mac_intr
(
hw
,
1
);
skge_mac_intr
(
hw
,
1
);
...
@@ -2859,8 +2822,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -2859,8 +2822,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
tasklet_schedule
(
&
hw
->
ext_tasklet
);
tasklet_schedule
(
&
hw
->
ext_tasklet
);
}
}
if
(
status
)
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
...
@@ -2904,9 +2866,6 @@ static const struct {
...
@@ -2904,9 +2866,6 @@ static const struct {
{
CHIP_ID_YUKON
,
"Yukon"
},
{
CHIP_ID_YUKON
,
"Yukon"
},
{
CHIP_ID_YUKON_LITE
,
"Yukon-Lite"
},
{
CHIP_ID_YUKON_LITE
,
"Yukon-Lite"
},
{
CHIP_ID_YUKON_LP
,
"Yukon-LP"
},
{
CHIP_ID_YUKON_LP
,
"Yukon-LP"
},
{
CHIP_ID_YUKON_XL
,
"Yukon-2 XL"
},
{
CHIP_ID_YUKON_EC
,
"YUKON-2 EC"
},
{
CHIP_ID_YUKON_FE
,
"YUKON-2 FE"
},
};
};
static
const
char
*
skge_board_name
(
const
struct
skge_hw
*
hw
)
static
const
char
*
skge_board_name
(
const
struct
skge_hw
*
hw
)
...
@@ -2930,8 +2889,8 @@ static const char *skge_board_name(const struct skge_hw *hw)
...
@@ -2930,8 +2889,8 @@ static const char *skge_board_name(const struct skge_hw *hw)
static
int
skge_reset
(
struct
skge_hw
*
hw
)
static
int
skge_reset
(
struct
skge_hw
*
hw
)
{
{
u16
ctst
;
u16
ctst
;
u8
t8
;
u8
t8
,
mac_cfg
;
int
i
,
ports
;
int
i
;
ctst
=
skge_read16
(
hw
,
B0_CTST
);
ctst
=
skge_read16
(
hw
,
B0_CTST
);
...
@@ -2952,12 +2911,9 @@ static int skge_reset(struct skge_hw *hw)
...
@@ -2952,12 +2911,9 @@ static int skge_reset(struct skge_hw *hw)
hw
->
phy_type
=
skge_read8
(
hw
,
B2_E_1
)
&
0xf
;
hw
->
phy_type
=
skge_read8
(
hw
,
B2_E_1
)
&
0xf
;
hw
->
pmd_type
=
skge_read8
(
hw
,
B2_PMD_TYP
);
hw
->
pmd_type
=
skge_read8
(
hw
,
B2_PMD_TYP
);
switch
(
hw
->
chip_id
)
{
switch
(
hw
->
chip_id
)
{
case
CHIP_ID_GENESIS
:
case
CHIP_ID_GENESIS
:
switch
(
hw
->
phy_type
)
{
switch
(
hw
->
phy_type
)
{
case
SK_PHY_XMAC
:
hw
->
phy_addr
=
PHY_ADDR_XMAC
;
break
;
case
SK_PHY_BCOM
:
case
SK_PHY_BCOM
:
hw
->
phy_addr
=
PHY_ADDR_BCOM
;
hw
->
phy_addr
=
PHY_ADDR_BCOM
;
break
;
break
;
...
@@ -2986,8 +2942,9 @@ static int skge_reset(struct skge_hw *hw)
...
@@ -2986,8 +2942,9 @@ static int skge_reset(struct skge_hw *hw)
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
hw
->
mac_cfg
=
skge_read8
(
hw
,
B2_MAC_CFG
);
mac_cfg
=
skge_read8
(
hw
,
B2_MAC_CFG
);
ports
=
isdualport
(
hw
)
?
2
:
1
;
hw
->
ports
=
(
mac_cfg
&
CFG_SNG_MAC
)
?
1
:
2
;
hw
->
chip_rev
=
(
mac_cfg
&
CFG_CHIP_R_MSK
)
>>
4
;
/* read the adapters RAM size */
/* read the adapters RAM size */
t8
=
skge_read8
(
hw
,
B2_E_0
);
t8
=
skge_read8
(
hw
,
B2_E_0
);
...
@@ -3010,9 +2967,9 @@ static int skge_reset(struct skge_hw *hw)
...
@@ -3010,9 +2967,9 @@ static int skge_reset(struct skge_hw *hw)
/* switch power to VCC (WA for VAUX problem) */
/* switch power to VCC (WA for VAUX problem) */
skge_write8
(
hw
,
B0_POWER_CTRL
,
skge_write8
(
hw
,
B0_POWER_CTRL
,
PC_VAUX_ENA
|
PC_VCC_ENA
|
PC_VAUX_OFF
|
PC_VCC_ON
);
PC_VAUX_ENA
|
PC_VCC_ENA
|
PC_VAUX_OFF
|
PC_VCC_ON
);
for
(
i
=
0
;
i
<
ports
;
i
++
)
{
for
(
i
=
0
;
i
<
hw
->
ports
;
i
++
)
{
skge_write16
(
hw
,
SK
GEMAC
_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_SET
);
skge_write16
(
hw
,
SK_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_SET
);
skge_write16
(
hw
,
SK
GEMAC
_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_CLR
);
skge_write16
(
hw
,
SK_REG
(
i
,
GMAC_LINK_CTRL
),
GMLC_RST_CLR
);
}
}
}
}
...
@@ -3022,8 +2979,8 @@ static int skge_reset(struct skge_hw *hw)
...
@@ -3022,8 +2979,8 @@ static int skge_reset(struct skge_hw *hw)
skge_write8
(
hw
,
B0_LED
,
LED_STAT_ON
);
skge_write8
(
hw
,
B0_LED
,
LED_STAT_ON
);
/* enable the Tx Arbiters */
/* enable the Tx Arbiters */
for
(
i
=
0
;
i
<
ports
;
i
++
)
for
(
i
=
0
;
i
<
hw
->
ports
;
i
++
)
skge_write8
(
hw
,
SK
GEMAC
_REG
(
i
,
TXA_CTRL
),
TXA_ENA_ARB
);
skge_write8
(
hw
,
SK_REG
(
i
,
TXA_CTRL
),
TXA_ENA_ARB
);
/* Initialize ram interface */
/* Initialize ram interface */
skge_write16
(
hw
,
B3_RI_CTRL
,
RI_RST_CLR
);
skge_write16
(
hw
,
B3_RI_CTRL
,
RI_RST_CLR
);
...
@@ -3050,16 +3007,14 @@ static int skge_reset(struct skge_hw *hw)
...
@@ -3050,16 +3007,14 @@ static int skge_reset(struct skge_hw *hw)
skge_write32
(
hw
,
B2_IRQM_INI
,
skge_usecs2clk
(
hw
,
100
));
skge_write32
(
hw
,
B2_IRQM_INI
,
skge_usecs2clk
(
hw
,
100
));
skge_write32
(
hw
,
B2_IRQM_CTRL
,
TIM_START
);
skge_write32
(
hw
,
B2_IRQM_CTRL
,
TIM_START
);
hw
->
intr_mask
=
IS_HW_ERR
|
IS_EXT_REG
|
IS_PORT_1
;
hw
->
intr_mask
=
IS_HW_ERR
|
IS_EXT_REG
;
if
(
isdualport
(
hw
))
hw
->
intr_mask
|=
IS_PORT_2
;
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
skge_write32
(
hw
,
B0_IMSK
,
hw
->
intr_mask
);
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
)
if
(
hw
->
chip_id
!=
CHIP_ID_GENESIS
)
skge_write8
(
hw
,
GMAC_IRQ_MSK
,
0
);
skge_write8
(
hw
,
GMAC_IRQ_MSK
,
0
);
spin_lock_bh
(
&
hw
->
phy_lock
);
spin_lock_bh
(
&
hw
->
phy_lock
);
for
(
i
=
0
;
i
<
ports
;
i
++
)
{
for
(
i
=
0
;
i
<
hw
->
ports
;
i
++
)
{
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
if
(
hw
->
chip_id
==
CHIP_ID_GENESIS
)
genesis_reset
(
hw
,
i
);
genesis_reset
(
hw
,
i
);
else
else
...
@@ -3071,7 +3026,8 @@ static int skge_reset(struct skge_hw *hw)
...
@@ -3071,7 +3026,8 @@ static int skge_reset(struct skge_hw *hw)
}
}
/* Initialize network device */
/* Initialize network device */
static
struct
net_device
*
skge_devinit
(
struct
skge_hw
*
hw
,
int
port
)
static
struct
net_device
*
skge_devinit
(
struct
skge_hw
*
hw
,
int
port
,
int
highmem
)
{
{
struct
skge_port
*
skge
;
struct
skge_port
*
skge
;
struct
net_device
*
dev
=
alloc_etherdev
(
sizeof
(
*
skge
));
struct
net_device
*
dev
=
alloc_etherdev
(
sizeof
(
*
skge
));
...
@@ -3104,6 +3060,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
...
@@ -3104,6 +3060,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
#endif
#endif
dev
->
irq
=
hw
->
pdev
->
irq
;
dev
->
irq
=
hw
->
pdev
->
irq
;
dev
->
features
=
NETIF_F_LLTX
;
dev
->
features
=
NETIF_F_LLTX
;
if
(
highmem
)
dev
->
features
|=
NETIF_F_HIGHDMA
;
skge
=
netdev_priv
(
dev
);
skge
=
netdev_priv
(
dev
);
skge
->
netdev
=
dev
;
skge
->
netdev
=
dev
;
...
@@ -3117,7 +3075,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
...
@@ -3117,7 +3075,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
skge
->
flow_control
=
FLOW_MODE_SYMMETRIC
;
skge
->
duplex
=
-
1
;
skge
->
duplex
=
-
1
;
skge
->
speed
=
-
1
;
skge
->
speed
=
-
1
;
skge
->
advertising
=
skge_modes
(
hw
);
skge
->
advertising
=
skge_
supported_
modes
(
hw
);
hw
->
dev
[
port
]
=
dev
;
hw
->
dev
[
port
]
=
dev
;
...
@@ -3125,10 +3083,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
...
@@ -3125,10 +3083,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port)
spin_lock_init
(
&
skge
->
tx_lock
);
spin_lock_init
(
&
skge
->
tx_lock
);
init_timer
(
&
skge
->
link_check
);
skge
->
link_check
.
function
=
skge_link_timer
;
skge
->
link_check
.
data
=
(
unsigned
long
)
skge
;
init_timer
(
&
skge
->
led_blink
);
init_timer
(
&
skge
->
led_blink
);
skge
->
led_blink
.
function
=
skge_blink_timer
;
skge
->
led_blink
.
function
=
skge_blink_timer
;
skge
->
led_blink
.
data
=
(
unsigned
long
)
skge
;
skge
->
led_blink
.
data
=
(
unsigned
long
)
skge
;
...
@@ -3232,14 +3186,11 @@ static int __devinit skge_probe(struct pci_dev *pdev,
...
@@ -3232,14 +3186,11 @@ static int __devinit skge_probe(struct pci_dev *pdev,
printk
(
KERN_INFO
PFX
"addr 0x%lx irq %d chip %s rev %d
\n
"
,
printk
(
KERN_INFO
PFX
"addr 0x%lx irq %d chip %s rev %d
\n
"
,
pci_resource_start
(
pdev
,
0
),
pdev
->
irq
,
pci_resource_start
(
pdev
,
0
),
pdev
->
irq
,
skge_board_name
(
hw
),
chip_rev
(
hw
)
);
skge_board_name
(
hw
),
hw
->
chip_rev
);
if
((
dev
=
skge_devinit
(
hw
,
0
))
==
NULL
)
if
((
dev
=
skge_devinit
(
hw
,
0
,
using_dac
))
==
NULL
)
goto
err_out_led_off
;
goto
err_out_led_off
;
if
(
using_dac
)
dev
->
features
|=
NETIF_F_HIGHDMA
;
if
((
err
=
register_netdev
(
dev
)))
{
if
((
err
=
register_netdev
(
dev
)))
{
printk
(
KERN_ERR
PFX
"%s: cannot register net device
\n
"
,
printk
(
KERN_ERR
PFX
"%s: cannot register net device
\n
"
,
pci_name
(
pdev
));
pci_name
(
pdev
));
...
@@ -3248,10 +3199,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
...
@@ -3248,10 +3199,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
skge_show_addr
(
dev
);
skge_show_addr
(
dev
);
if
(
isdualport
(
hw
)
&&
(
dev1
=
skge_devinit
(
hw
,
1
)))
{
if
(
hw
->
ports
>
1
&&
(
dev1
=
skge_devinit
(
hw
,
1
,
using_dac
)))
{
if
(
using_dac
)
dev1
->
features
|=
NETIF_F_HIGHDMA
;
if
(
register_netdev
(
dev1
)
==
0
)
if
(
register_netdev
(
dev1
)
==
0
)
skge_show_addr
(
dev1
);
skge_show_addr
(
dev1
);
else
{
else
{
...
@@ -3288,7 +3236,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
...
@@ -3288,7 +3236,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
struct
skge_hw
*
hw
=
pci_get_drvdata
(
pdev
);
struct
skge_hw
*
hw
=
pci_get_drvdata
(
pdev
);
struct
net_device
*
dev0
,
*
dev1
;
struct
net_device
*
dev0
,
*
dev1
;
if
(
!
hw
)
if
(
!
hw
)
return
;
return
;
if
((
dev1
=
hw
->
dev
[
1
]))
if
((
dev1
=
hw
->
dev
[
1
]))
...
@@ -3316,7 +3264,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state)
...
@@ -3316,7 +3264,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state)
struct
skge_hw
*
hw
=
pci_get_drvdata
(
pdev
);
struct
skge_hw
*
hw
=
pci_get_drvdata
(
pdev
);
int
i
,
wol
=
0
;
int
i
,
wol
=
0
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
struct
net_device
*
dev
=
hw
->
dev
[
i
];
struct
net_device
*
dev
=
hw
->
dev
[
i
];
if
(
dev
)
{
if
(
dev
)
{
...
@@ -3349,11 +3297,11 @@ static int skge_resume(struct pci_dev *pdev)
...
@@ -3349,11 +3297,11 @@ static int skge_resume(struct pci_dev *pdev)
skge_reset
(
hw
);
skge_reset
(
hw
);
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
struct
net_device
*
dev
=
hw
->
dev
[
i
];
struct
net_device
*
dev
=
hw
->
dev
[
i
];
if
(
dev
)
{
if
(
dev
)
{
netif_device_attach
(
dev
);
netif_device_attach
(
dev
);
if
(
netif_running
(
dev
))
if
(
netif_running
(
dev
))
skge_up
(
dev
);
skge_up
(
dev
);
}
}
}
}
...
...
drivers/net/skge.h
浏览文件 @
245ac873
...
@@ -7,31 +7,6 @@
...
@@ -7,31 +7,6 @@
/* PCI config registers */
/* PCI config registers */
#define PCI_DEV_REG1 0x40
#define PCI_DEV_REG1 0x40
#define PCI_DEV_REG2 0x44
#define PCI_DEV_REG2 0x44
#ifndef PCI_VPD
#define PCI_VPD 0x50
#endif
/* PCI_OUR_REG_2 32 bit Our Register 2 */
enum
{
PCI_VPD_WR_THR
=
0xff
<<
24
,
/* Bit 31..24: VPD Write Threshold */
PCI_DEV_SEL
=
0x7f
<<
17
,
/* Bit 23..17: EEPROM Device Select */
PCI_VPD_ROM_SZ
=
7
<<
14
,
/* Bit 16..14: VPD ROM Size */
/* Bit 13..12: reserved */
PCI_EN_DUMMY_RD
=
1
<<
3
,
/* Enable Dummy Read */
PCI_REV_DESC
=
1
<<
2
,
/* Reverse Desc. Bytes */
PCI_USEDATA64
=
1
<<
0
,
/* Use 64Bit Data bus ext */
};
/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
enum
{
PCI_VPD_FLAG
=
1
<<
15
,
/* starts VPD rd/wr cycle */
PCI_VPD_ADR_MSK
=
0x7fffL
,
/* Bit 14.. 0: VPD Address Mask */
VPD_RES_ID
=
0x82
,
VPD_RES_READ
=
0x90
,
VPD_RES_WRITE
=
0x81
,
VPD_RES_END
=
0x78
,
};
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
...
@@ -39,7 +14,6 @@ enum {
...
@@ -39,7 +14,6 @@ enum {
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
PCI_STATUS_PARITY)
enum
csr_regs
{
enum
csr_regs
{
B0_RAP
=
0x0000
,
B0_RAP
=
0x0000
,
B0_CTST
=
0x0004
,
B0_CTST
=
0x0004
,
...
@@ -229,8 +203,11 @@ enum {
...
@@ -229,8 +203,11 @@ enum {
IS_XA2_F
=
1
<<
1
,
/* Q_XA2 End of Frame */
IS_XA2_F
=
1
<<
1
,
/* Q_XA2 End of Frame */
IS_XA2_C
=
1
<<
0
,
/* Q_XA2 Encoding Error */
IS_XA2_C
=
1
<<
0
,
/* Q_XA2 Encoding Error */
IS_PORT_1
=
IS_XA1_F
|
IS_R1_F
|
IS_MAC1
,
IS_TO_PORT1
=
IS_PA_TO_RX1
|
IS_PA_TO_TX1
,
IS_PORT_2
=
IS_XA2_F
|
IS_R2_F
|
IS_MAC2
,
IS_TO_PORT2
=
IS_PA_TO_RX2
|
IS_PA_TO_TX2
,
IS_PORT_1
=
IS_XA1_F
|
IS_R1_F
|
IS_TO_PORT1
|
IS_MAC1
,
IS_PORT_2
=
IS_XA2_F
|
IS_R2_F
|
IS_TO_PORT2
|
IS_MAC2
,
};
};
...
@@ -288,14 +265,6 @@ enum {
...
@@ -288,14 +265,6 @@ enum {
CHIP_REV_YU_LITE_A3
=
7
,
/* Chip Rev. for YUKON-Lite A3 */
CHIP_REV_YU_LITE_A3
=
7
,
/* Chip Rev. for YUKON-Lite A3 */
};
};
/* B2_LD_TEST 8 bit EPROM loader test register */
enum
{
LD_T_ON
=
1
<<
3
,
/* Loader Test mode on */
LD_T_OFF
=
1
<<
2
,
/* Loader Test mode off */
LD_T_STEP
=
1
<<
1
,
/* Decrement FPROM addr. Counter */
LD_START
=
1
<<
0
,
/* Start loading FPROM */
};
/* B2_TI_CTRL 8 bit Timer control */
/* B2_TI_CTRL 8 bit Timer control */
/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
enum
{
enum
{
...
@@ -313,16 +282,6 @@ enum {
...
@@ -313,16 +282,6 @@ enum {
TIM_T_STEP
=
1
<<
0
,
/* Test step */
TIM_T_STEP
=
1
<<
0
,
/* Test step */
};
};
/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
enum
{
DPT_MSK
=
0x00ffffffL
,
/* Bit 23.. 0: Desc Poll Timer Bits */
DPT_START
=
1
<<
1
,
/* Start Descriptor Poll Timer */
DPT_STOP
=
1
<<
0
,
/* Stop Descriptor Poll Timer */
};
/* B2_GP_IO 32 bit General Purpose I/O Register */
/* B2_GP_IO 32 bit General Purpose I/O Register */
enum
{
enum
{
GP_DIR_9
=
1
<<
25
,
/* IO_9 direct, 0=In/1=Out */
GP_DIR_9
=
1
<<
25
,
/* IO_9 direct, 0=In/1=Out */
...
@@ -348,30 +307,6 @@ enum {
...
@@ -348,30 +307,6 @@ enum {
GP_IO_0
=
1
<<
0
,
/* IO_0 pin */
GP_IO_0
=
1
<<
0
,
/* IO_0 pin */
};
};
/* Rx/Tx Path related Arbiter Test Registers */
/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
enum
{
TX2_T_EV
=
1
<<
15
,
/* TX2 Timeout/Recv Event occured */
TX2_T_ON
=
1
<<
14
,
/* TX2 Timeout/Recv Timer Test On */
TX2_T_OFF
=
1
<<
13
,
/* TX2 Timeout/Recv Timer Tst Off */
TX2_T_STEP
=
1
<<
12
,
/* TX2 Timeout/Recv Timer Step */
TX1_T_EV
=
1
<<
11
,
/* TX1 Timeout/Recv Event occured */
TX1_T_ON
=
1
<<
10
,
/* TX1 Timeout/Recv Timer Test On */
TX1_T_OFF
=
1
<<
9
,
/* TX1 Timeout/Recv Timer Tst Off */
TX1_T_STEP
=
1
<<
8
,
/* TX1 Timeout/Recv Timer Step */
RX2_T_EV
=
1
<<
7
,
/* RX2 Timeout/Recv Event occured */
RX2_T_ON
=
1
<<
6
,
/* RX2 Timeout/Recv Timer Test On */
RX2_T_OFF
=
1
<<
5
,
/* RX2 Timeout/Recv Timer Tst Off */
RX2_T_STEP
=
1
<<
4
,
/* RX2 Timeout/Recv Timer Step */
RX1_T_EV
=
1
<<
3
,
/* RX1 Timeout/Recv Event occured */
RX1_T_ON
=
1
<<
2
,
/* RX1 Timeout/Recv Timer Test On */
RX1_T_OFF
=
1
<<
1
,
/* RX1 Timeout/Recv Timer Tst Off */
RX1_T_STEP
=
1
<<
0
,
/* RX1 Timeout/Recv Timer Step */
};
/* Descriptor Bit Definition */
/* Descriptor Bit Definition */
/* TxCtrl Transmit Buffer Control Field */
/* TxCtrl Transmit Buffer Control Field */
/* RxCtrl Receive Buffer Control Field */
/* RxCtrl Receive Buffer Control Field */
...
@@ -428,14 +363,6 @@ enum {
...
@@ -428,14 +363,6 @@ enum {
RI_RST_SET
=
1
<<
0
,
/* Set RAM Interface Reset */
RI_RST_SET
=
1
<<
0
,
/* Set RAM Interface Reset */
};
};
/* B3_RI_TEST 8 bit RAM Iface Test Register */
enum
{
RI_T_EV
=
1
<<
3
,
/* Timeout Event occured */
RI_T_ON
=
1
<<
2
,
/* Timeout Timer Test On */
RI_T_OFF
=
1
<<
1
,
/* Timeout Timer Test Off */
RI_T_STEP
=
1
<<
0
,
/* Timeout Timer Step */
};
/* MAC Arbiter Registers */
/* MAC Arbiter Registers */
/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
enum
{
enum
{
...
@@ -452,19 +379,6 @@ enum {
...
@@ -452,19 +379,6 @@ enum {
#define SK_PKT_TO_MAX 0xffff
/* Maximum value */
#define SK_PKT_TO_MAX 0xffff
/* Maximum value */
#define SK_RI_TO_53 36
/* RAM interface timeout */
#define SK_RI_TO_53 36
/* RAM interface timeout */
/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
enum
{
MA_ENA_REC_TX2
=
1
<<
7
,
/* Enable Recovery Timer TX2 */
MA_DIS_REC_TX2
=
1
<<
6
,
/* Disable Recovery Timer TX2 */
MA_ENA_REC_TX1
=
1
<<
5
,
/* Enable Recovery Timer TX1 */
MA_DIS_REC_TX1
=
1
<<
4
,
/* Disable Recovery Timer TX1 */
MA_ENA_REC_RX2
=
1
<<
3
,
/* Enable Recovery Timer RX2 */
MA_DIS_REC_RX2
=
1
<<
2
,
/* Disable Recovery Timer RX2 */
MA_ENA_REC_RX1
=
1
<<
1
,
/* Enable Recovery Timer RX1 */
MA_DIS_REC_RX1
=
1
<<
0
,
/* Disable Recovery Timer RX1 */
};
/* Packet Arbiter Registers */
/* Packet Arbiter Registers */
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
enum
{
enum
{
...
@@ -488,7 +402,7 @@ enum {
...
@@ -488,7 +402,7 @@ enum {
PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
/* Transmit Arbiter Registers MAC 1 and 2, use
MR_ADDR
() to access */
/* Transmit Arbiter Registers MAC 1 and 2, use
SK_REG
() to access */
/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
...
@@ -511,7 +425,7 @@ enum {
...
@@ -511,7 +425,7 @@ enum {
/*
/*
* Bank 4 - 5
* Bank 4 - 5
*/
*/
/* Transmit Arbiter Registers MAC 1 and 2, use
MR_ADDR
() to access */
/* Transmit Arbiter Registers MAC 1 and 2, use
SK_REG
() to access */
enum
{
enum
{
TXA_ITI_INI
=
0x0200
,
/* 32 bit Tx Arb Interval Timer Init Val*/
TXA_ITI_INI
=
0x0200
,
/* 32 bit Tx Arb Interval Timer Init Val*/
TXA_ITI_VAL
=
0x0204
,
/* 32 bit Tx Arb Interval Timer Value */
TXA_ITI_VAL
=
0x0204
,
/* 32 bit Tx Arb Interval Timer Value */
...
@@ -537,7 +451,7 @@ enum {
...
@@ -537,7 +451,7 @@ enum {
/* Queue Register Offsets, use Q_ADDR() to access */
/* Queue Register Offsets, use Q_ADDR() to access */
enum
{
enum
{
B8_Q_REGS
=
0x0400
,
/* base of Queue registers */
B8_Q_REGS
=
0x0400
,
/* base of Queue registers */
Q_D
=
0x00
,
/* 8*32 bit Current Descriptor */
Q_D
=
0x00
,
/* 8*32 bit Current Descriptor */
Q_DA_L
=
0x20
,
/* 32 bit Current Descriptor Address Low dWord */
Q_DA_L
=
0x20
,
/* 32 bit Current Descriptor Address Low dWord */
Q_DA_H
=
0x24
,
/* 32 bit Current Descriptor Address High dWord */
Q_DA_H
=
0x24
,
/* 32 bit Current Descriptor Address High dWord */
...
@@ -618,8 +532,7 @@ enum {
...
@@ -618,8 +532,7 @@ enum {
enum
{
enum
{
PHY_ADDR_XMAC
=
0
<<
8
,
PHY_ADDR_XMAC
=
0
<<
8
,
PHY_ADDR_BCOM
=
1
<<
8
,
PHY_ADDR_BCOM
=
1
<<
8
,
PHY_ADDR_LONE
=
3
<<
8
,
PHY_ADDR_NAT
=
0
<<
8
,
/* GPHY address (bits 15..11 of SMI control reg) */
/* GPHY address (bits 15..11 of SMI control reg) */
PHY_ADDR_MARV
=
0
,
PHY_ADDR_MARV
=
0
,
};
};
...
@@ -986,7 +899,7 @@ enum {
...
@@ -986,7 +899,7 @@ enum {
LINKLED_BLINK_OFF
=
0x10
,
LINKLED_BLINK_OFF
=
0x10
,
LINKLED_BLINK_ON
=
0x20
,
LINKLED_BLINK_ON
=
0x20
,
};
};
/* GMAC and GPHY Control Registers (YUKON only) */
/* GMAC and GPHY Control Registers (YUKON only) */
enum
{
enum
{
GMAC_CTRL
=
0x0f00
,
/* 32 bit GMAC Control Reg */
GMAC_CTRL
=
0x0f00
,
/* 32 bit GMAC Control Reg */
...
@@ -1151,54 +1064,6 @@ enum {
...
@@ -1151,54 +1064,6 @@ enum {
PHY_MARV_FE_SPEC_2
=
0x1c
,
/* 16 bit r/w Specific Control Reg. 2 */
PHY_MARV_FE_SPEC_2
=
0x1c
,
/* 16 bit r/w Specific Control Reg. 2 */
};
};
/* Level One-PHY Registers, indirect addressed over XMAC */
enum
{
PHY_LONE_CTRL
=
0x00
,
/* 16 bit r/w PHY Control Register */
PHY_LONE_STAT
=
0x01
,
/* 16 bit r/o PHY Status Register */
PHY_LONE_ID0
=
0x02
,
/* 16 bit r/o PHY ID0 Register */
PHY_LONE_ID1
=
0x03
,
/* 16 bit r/o PHY ID1 Register */
PHY_LONE_AUNE_ADV
=
0x04
,
/* 16 bit r/w Auto-Neg. Advertisement */
PHY_LONE_AUNE_LP
=
0x05
,
/* 16 bit r/o Link Part Ability Reg */
PHY_LONE_AUNE_EXP
=
0x06
,
/* 16 bit r/o Auto-Neg. Expansion Reg */
PHY_LONE_NEPG
=
0x07
,
/* 16 bit r/w Next Page Register */
PHY_LONE_NEPG_LP
=
0x08
,
/* 16 bit r/o Next Page Link Partner */
/* Level One-specific registers */
PHY_LONE_1000T_CTRL
=
0x09
,
/* 16 bit r/w 1000Base-T Control Reg */
PHY_LONE_1000T_STAT
=
0x0a
,
/* 16 bit r/o 1000Base-T Status Reg */
PHY_LONE_EXT_STAT
=
0x0f
,
/* 16 bit r/o Extended Status Reg */
PHY_LONE_PORT_CFG
=
0x10
,
/* 16 bit r/w Port Configuration Reg*/
PHY_LONE_Q_STAT
=
0x11
,
/* 16 bit r/o Quick Status Reg */
PHY_LONE_INT_ENAB
=
0x12
,
/* 16 bit r/w Interrupt Enable Reg */
PHY_LONE_INT_STAT
=
0x13
,
/* 16 bit r/o Interrupt Status Reg */
PHY_LONE_LED_CFG
=
0x14
,
/* 16 bit r/w LED Configuration Reg */
PHY_LONE_PORT_CTRL
=
0x15
,
/* 16 bit r/w Port Control Reg */
PHY_LONE_CIM
=
0x16
,
/* 16 bit r/o CIM Reg */
};
/* National-PHY Registers, indirect addressed over XMAC */
enum
{
PHY_NAT_CTRL
=
0x00
,
/* 16 bit r/w PHY Control Register */
PHY_NAT_STAT
=
0x01
,
/* 16 bit r/w PHY Status Register */
PHY_NAT_ID0
=
0x02
,
/* 16 bit r/o PHY ID0 Register */
PHY_NAT_ID1
=
0x03
,
/* 16 bit r/o PHY ID1 Register */
PHY_NAT_AUNE_ADV
=
0x04
,
/* 16 bit r/w Auto-Neg. Advertisement */
PHY_NAT_AUNE_LP
=
0x05
,
/* 16 bit r/o Link Partner Ability Reg */
PHY_NAT_AUNE_EXP
=
0x06
,
/* 16 bit r/o Auto-Neg. Expansion Reg */
PHY_NAT_NEPG
=
0x07
,
/* 16 bit r/w Next Page Register */
PHY_NAT_NEPG_LP
=
0x08
,
/* 16 bit r/o Next Page Link Partner Reg */
/* National-specific registers */
PHY_NAT_1000T_CTRL
=
0x09
,
/* 16 bit r/w 1000Base-T Control Reg */
PHY_NAT_1000T_STAT
=
0x0a
,
/* 16 bit r/o 1000Base-T Status Reg */
PHY_NAT_EXT_STAT
=
0x0f
,
/* 16 bit r/o Extended Status Register */
PHY_NAT_EXT_CTRL1
=
0x10
,
/* 16 bit r/o Extended Control Reg1 */
PHY_NAT_Q_STAT1
=
0x11
,
/* 16 bit r/o Quick Status Reg1 */
PHY_NAT_10B_OP
=
0x12
,
/* 16 bit r/o 10Base-T Operations Reg */
PHY_NAT_EXT_CTRL2
=
0x13
,
/* 16 bit r/o Extended Control Reg1 */
PHY_NAT_Q_STAT2
=
0x14
,
/* 16 bit r/o Quick Status Reg2 */
PHY_NAT_PHY_ADDR
=
0x19
,
/* 16 bit r/o PHY Address Register */
};
enum
{
enum
{
PHY_CT_RESET
=
1
<<
15
,
/* Bit 15: (sc) clear all PHY related regs */
PHY_CT_RESET
=
1
<<
15
,
/* Bit 15: (sc) clear all PHY related regs */
PHY_CT_LOOP
=
1
<<
14
,
/* Bit 14: enable Loopback over PHY */
PHY_CT_LOOP
=
1
<<
14
,
/* Bit 14: enable Loopback over PHY */
...
@@ -1253,8 +1118,29 @@ enum {
...
@@ -1253,8 +1118,29 @@ enum {
PHY_MARV_ID1_Y2
=
0x0C91
,
/* Yukon-2 (PHY 88E1112) */
PHY_MARV_ID1_Y2
=
0x0C91
,
/* Yukon-2 (PHY 88E1112) */
};
};
/* Advertisement register bits */
enum
{
enum
{
PHY_AN_NXT_PG
=
1
<<
15
,
/* Bit 15: Request Next Page */
PHY_AN_NXT_PG
=
1
<<
15
,
/* Bit 15: Request Next Page */
PHY_AN_ACK
=
1
<<
14
,
/* Bit 14: (ro) Acknowledge Received */
PHY_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault Bits */
PHY_AN_PAUSE_ASYM
=
1
<<
11
,
/* Bit 11: Try for asymmetric */
PHY_AN_PAUSE_CAP
=
1
<<
10
,
/* Bit 10: Try for pause */
PHY_AN_100BASE4
=
1
<<
9
,
/* Bit 9: Try for 100mbps 4k packets */
PHY_AN_100FULL
=
1
<<
8
,
/* Bit 8: Try for 100mbps full-duplex */
PHY_AN_100HALF
=
1
<<
7
,
/* Bit 7: Try for 100mbps half-duplex */
PHY_AN_10FULL
=
1
<<
6
,
/* Bit 6: Try for 10mbps full-duplex */
PHY_AN_10HALF
=
1
<<
5
,
/* Bit 5: Try for 10mbps half-duplex */
PHY_AN_CSMA
=
1
<<
0
,
/* Bit 0: Only selector supported */
PHY_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
PHY_AN_FULL
=
PHY_AN_100FULL
|
PHY_AN_10FULL
|
PHY_AN_CSMA
,
PHY_AN_ALL
=
PHY_AN_10HALF
|
PHY_AN_10FULL
|
PHY_AN_100HALF
|
PHY_AN_100FULL
,
};
/* Xmac Specific */
enum
{
PHY_X_AN_NXT_PG
=
1
<<
15
,
/* Bit 15: Request Next Page */
PHY_X_AN_ACK
=
1
<<
14
,
/* Bit 14: (ro) Acknowledge Received */
PHY_X_AN_ACK
=
1
<<
14
,
/* Bit 14: (ro) Acknowledge Received */
PHY_X_AN_RFB
=
3
<<
12
,
/* Bit 13..12: Remote Fault Bits */
PHY_X_AN_RFB
=
3
<<
12
,
/* Bit 13..12: Remote Fault Bits */
...
@@ -1263,82 +1149,6 @@ enum {
...
@@ -1263,82 +1149,6 @@ enum {
PHY_X_AN_FD
=
1
<<
5
,
/* Bit 5: Full Duplex */
PHY_X_AN_FD
=
1
<<
5
,
/* Bit 5: Full Duplex */
};
};
enum
{
PHY_B_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
PHY_B_AN_ASP
=
1
<<
11
,
/* Bit 11: Asymmetric Pause */
PHY_B_AN_PC
=
1
<<
10
,
/* Bit 10: Pause Capable */
PHY_B_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
};
enum
{
PHY_L_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
/* Bit 12: reserved */
PHY_L_AN_ASP
=
1
<<
11
,
/* Bit 11: Asymmetric Pause */
PHY_L_AN_PC
=
1
<<
10
,
/* Bit 10: Pause Capable */
PHY_L_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
};
/* PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement */
/* PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
enum
{
PHY_N_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
PHY_N_AN_100F
=
1
<<
11
,
/* Bit 11: 100Base-T2 FD Support */
PHY_N_AN_100H
=
1
<<
10
,
/* Bit 10: 100Base-T2 HD Support */
PHY_N_AN_SEL
=
0x1f
,
/* Bit 4..0: Selector Field, 00001=Ethernet*/
};
/* field type definition for PHY_x_AN_SEL */
enum
{
PHY_SEL_TYPE
=
1
,
/* 00001 = Ethernet */
};
enum
{
PHY_ANE_LP_NP
=
1
<<
3
,
/* Bit 3: Link Partner can Next Page */
PHY_ANE_LOC_NP
=
1
<<
2
,
/* Bit 2: Local PHY can Next Page */
PHY_ANE_RX_PG
=
1
<<
1
,
/* Bit 1: Page Received */
};
enum
{
PHY_ANE_PAR_DF
=
1
<<
4
,
/* Bit 4: Parallel Detection Fault */
PHY_ANE_LP_CAP
=
1
<<
0
,
/* Bit 0: Link Partner Auto-Neg. Cap. */
};
enum
{
PHY_NP_MORE
=
1
<<
15
,
/* Bit 15: More, Next Pages to follow */
PHY_NP_ACK1
=
1
<<
14
,
/* Bit 14: (ro) Ack1, for receiving a message */
PHY_NP_MSG_VAL
=
1
<<
13
,
/* Bit 13: Message Page valid */
PHY_NP_ACK2
=
1
<<
12
,
/* Bit 12: Ack2, comply with msg content */
PHY_NP_TOG
=
1
<<
11
,
/* Bit 11: Toggle Bit, ensure sync */
PHY_NP_MSG
=
0x07ff
,
/* Bit 10..0: Message from/to Link Partner */
};
enum
{
PHY_X_EX_FD
=
1
<<
15
,
/* Bit 15: Device Supports Full Duplex */
PHY_X_EX_HD
=
1
<<
14
,
/* Bit 14: Device Supports Half Duplex */
};
enum
{
PHY_X_RS_PAUSE
=
3
<<
7
,
/* Bit 8..7: selected Pause Mode */
PHY_X_RS_HD
=
1
<<
6
,
/* Bit 6: Half Duplex Mode selected */
PHY_X_RS_FD
=
1
<<
5
,
/* Bit 5: Full Duplex Mode selected */
PHY_X_RS_ABLMIS
=
1
<<
4
,
/* Bit 4: duplex or pause cap mismatch */
PHY_X_RS_PAUMIS
=
1
<<
3
,
/* Bit 3: pause capability mismatch */
};
/** Remote Fault Bits (PHY_X_AN_RFB) encoding */
enum
{
X_RFB_OK
=
0
<<
12
,
/* Bit 13..12 No errors, Link OK */
X_RFB_LF
=
1
<<
12
,
/* Bit 13..12 Link Failure */
X_RFB_OFF
=
2
<<
12
,
/* Bit 13..12 Offline */
X_RFB_AN_ERR
=
3
<<
12
,
/* Bit 13..12 Auto-Negotiation Error */
};
/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
enum
{
enum
{
PHY_X_P_NO_PAUSE
=
0
<<
7
,
/* Bit 8..7: no Pause Mode */
PHY_X_P_NO_PAUSE
=
0
<<
7
,
/* Bit 8..7: no Pause Mode */
...
@@ -1418,6 +1228,16 @@ enum {
...
@@ -1418,6 +1228,16 @@ enum {
PHY_B_PES_MLT3_ER
=
1
<<
0
,
/* Bit 0: MLT3 code Error */
PHY_B_PES_MLT3_ER
=
1
<<
0
,
/* Bit 0: MLT3 code Error */
};
};
/* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
/* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
enum
{
PHY_B_AN_RF
=
1
<<
13
,
/* Bit 13: Remote Fault */
PHY_B_AN_ASP
=
1
<<
11
,
/* Bit 11: Asymmetric Pause */
PHY_B_AN_PC
=
1
<<
10
,
/* Bit 10: Pause Capable */
};
/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
enum
{
enum
{
PHY_B_FC_CTR
=
0xff
,
/* Bit 7..0: False Carrier Counter */
PHY_B_FC_CTR
=
0xff
,
/* Bit 7..0: False Carrier Counter */
...
@@ -1478,7 +1298,9 @@ enum {
...
@@ -1478,7 +1298,9 @@ enum {
PHY_B_IS_LST_CHANGE
=
1
<<
1
,
/* Bit 1: Link Status Changed */
PHY_B_IS_LST_CHANGE
=
1
<<
1
,
/* Bit 1: Link Status Changed */
PHY_B_IS_CRC_ER
=
1
<<
0
,
/* Bit 0: CRC Error */
PHY_B_IS_CRC_ER
=
1
<<
0
,
/* Bit 0: CRC Error */
};
};
#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
#define PHY_B_DEF_MSK \
(~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \
PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE))
/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
enum
{
enum
{
...
@@ -1495,166 +1317,6 @@ enum {
...
@@ -1495,166 +1317,6 @@ enum {
PHY_B_RES_1000HD
=
6
<<
8
,
/* Bit 10..8: 1000Base-T Half Dup. */
PHY_B_RES_1000HD
=
6
<<
8
,
/* Bit 10..8: 1000Base-T Half Dup. */
};
};
/*
* Level One-Specific
*/
/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
enum
{
PHY_L_1000C_TEST
=
7
<<
13
,
/* Bit 15..13: Test Modes */
PHY_L_1000C_MSE
=
1
<<
12
,
/* Bit 12: Master/Slave Enable */
PHY_L_1000C_MSC
=
1
<<
11
,
/* Bit 11: M/S Configuration */
PHY_L_1000C_RD
=
1
<<
10
,
/* Bit 10: Repeater/DTE */
PHY_L_1000C_AFD
=
1
<<
9
,
/* Bit 9: Advertise Full Duplex */
PHY_L_1000C_AHD
=
1
<<
8
,
/* Bit 8: Advertise Half Duplex */
};
/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
enum
{
PHY_L_1000S_MSF
=
1
<<
15
,
/* Bit 15: Master/Slave Fault */
PHY_L_1000S_MSR
=
1
<<
14
,
/* Bit 14: Master/Slave Result */
PHY_L_1000S_LRS
=
1
<<
13
,
/* Bit 13: Local Receiver Status */
PHY_L_1000S_RRS
=
1
<<
12
,
/* Bit 12: Remote Receiver Status */
PHY_L_1000S_LP_FD
=
1
<<
11
,
/* Bit 11: Link Partner can FD */
PHY_L_1000S_LP_HD
=
1
<<
10
,
/* Bit 10: Link Partner can HD */
PHY_L_1000S_IEC
=
0xff
,
/* Bit 7..0: Idle Error Count */
/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
PHY_L_ES_X_FD_CAP
=
1
<<
15
,
/* Bit 15: 1000Base-X FD capable */
PHY_L_ES_X_HD_CAP
=
1
<<
14
,
/* Bit 14: 1000Base-X HD capable */
PHY_L_ES_T_FD_CAP
=
1
<<
13
,
/* Bit 13: 1000Base-T FD capable */
PHY_L_ES_T_HD_CAP
=
1
<<
12
,
/* Bit 12: 1000Base-T HD capable */
};
/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
enum
{
PHY_L_PC_REP_MODE
=
1
<<
15
,
/* Bit 15: Repeater Mode */
PHY_L_PC_TX_DIS
=
1
<<
13
,
/* Bit 13: Tx output Disabled */
PHY_L_PC_BY_SCR
=
1
<<
12
,
/* Bit 12: Bypass Scrambler */
PHY_L_PC_BY_45
=
1
<<
11
,
/* Bit 11: Bypass 4B5B-Decoder */
PHY_L_PC_JAB_DIS
=
1
<<
10
,
/* Bit 10: Jabber Disabled */
PHY_L_PC_SQE
=
1
<<
9
,
/* Bit 9: Enable Heartbeat */
PHY_L_PC_TP_LOOP
=
1
<<
8
,
/* Bit 8: TP Loopback */
PHY_L_PC_SSS
=
1
<<
7
,
/* Bit 7: Smart Speed Selection */
PHY_L_PC_FIFO_SIZE
=
1
<<
6
,
/* Bit 6: FIFO Size */
PHY_L_PC_PRE_EN
=
1
<<
5
,
/* Bit 5: Preamble Enable */
PHY_L_PC_CIM
=
1
<<
4
,
/* Bit 4: Carrier Integrity Mon */
PHY_L_PC_10_SER
=
1
<<
3
,
/* Bit 3: Use Serial Output */
PHY_L_PC_ANISOL
=
1
<<
2
,
/* Bit 2: Unisolate Port */
PHY_L_PC_TEN_BIT
=
1
<<
1
,
/* Bit 1: 10bit iface mode on */
PHY_L_PC_ALTCLOCK
=
1
<<
0
,
/* Bit 0: (ro) ALTCLOCK Mode on */
};
/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
enum
{
PHY_L_QS_D_RATE
=
3
<<
14
,
/* Bit 15..14: Data Rate */
PHY_L_QS_TX_STAT
=
1
<<
13
,
/* Bit 13: Transmitting */
PHY_L_QS_RX_STAT
=
1
<<
12
,
/* Bit 12: Receiving */
PHY_L_QS_COL_STAT
=
1
<<
11
,
/* Bit 11: Collision */
PHY_L_QS_L_STAT
=
1
<<
10
,
/* Bit 10: Link is up */
PHY_L_QS_DUP_MOD
=
1
<<
9
,
/* Bit 9: Full/Half Duplex */
PHY_L_QS_AN
=
1
<<
8
,
/* Bit 8: AutoNeg is On */
PHY_L_QS_AN_C
=
1
<<
7
,
/* Bit 7: AN is Complete */
PHY_L_QS_LLE
=
7
<<
4
,
/* Bit 6..4: Line Length Estim. */
PHY_L_QS_PAUSE
=
1
<<
3
,
/* Bit 3: LP advertised Pause */
PHY_L_QS_AS_PAUSE
=
1
<<
2
,
/* Bit 2: LP adv. asym. Pause */
PHY_L_QS_ISOLATE
=
1
<<
1
,
/* Bit 1: CIM Isolated */
PHY_L_QS_EVENT
=
1
<<
0
,
/* Bit 0: Event has occurred */
};
/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
enum
{
PHY_L_IS_AN_F
=
1
<<
13
,
/* Bit 13: Auto-Negotiation fault */
PHY_L_IS_CROSS
=
1
<<
11
,
/* Bit 11: Crossover used */
PHY_L_IS_POL
=
1
<<
10
,
/* Bit 10: Polarity correct. used */
PHY_L_IS_SS
=
1
<<
9
,
/* Bit 9: Smart Speed Downgrade */
PHY_L_IS_CFULL
=
1
<<
8
,
/* Bit 8: Counter Full */
PHY_L_IS_AN_C
=
1
<<
7
,
/* Bit 7: AutoNeg Complete */
PHY_L_IS_SPEED
=
1
<<
6
,
/* Bit 6: Speed Changed */
PHY_L_IS_DUP
=
1
<<
5
,
/* Bit 5: Duplex Changed */
PHY_L_IS_LS
=
1
<<
4
,
/* Bit 4: Link Status Changed */
PHY_L_IS_ISOL
=
1
<<
3
,
/* Bit 3: Isolate Occured */
PHY_L_IS_MDINT
=
1
<<
2
,
/* Bit 2: (ro) STAT: MII Int Pending */
PHY_L_IS_INTEN
=
1
<<
1
,
/* Bit 1: ENAB: Enable IRQs */
PHY_L_IS_FORCE
=
1
<<
0
,
/* Bit 0: ENAB: Force Interrupt */
};
/* int. mask */
#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
enum
{
PHY_L_LC_LEDC
=
3
<<
14
,
/* Bit 15..14: Col/Blink/On/Off */
PHY_L_LC_LEDR
=
3
<<
12
,
/* Bit 13..12: Rx/Blink/On/Off */
PHY_L_LC_LEDT
=
3
<<
10
,
/* Bit 11..10: Tx/Blink/On/Off */
PHY_L_LC_LEDG
=
3
<<
8
,
/* Bit 9..8: Giga/Blink/On/Off */
PHY_L_LC_LEDS
=
3
<<
6
,
/* Bit 7..6: 10-100/Blink/On/Off */
PHY_L_LC_LEDL
=
3
<<
4
,
/* Bit 5..4: Link/Blink/On/Off */
PHY_L_LC_LEDF
=
3
<<
2
,
/* Bit 3..2: Duplex/Blink/On/Off */
PHY_L_LC_PSTRECH
=
1
<<
1
,
/* Bit 1: Strech LED Pulses */
PHY_L_LC_FREQ
=
1
<<
0
,
/* Bit 0: 30/100 ms */
};
/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
enum
{
PHY_L_PC_TX_TCLK
=
1
<<
15
,
/* Bit 15: Enable TX_TCLK */
PHY_L_PC_ALT_NP
=
1
<<
13
,
/* Bit 14: Alternate Next Page */
PHY_L_PC_GMII_ALT
=
1
<<
12
,
/* Bit 13: Alternate GMII driver */
PHY_L_PC_TEN_CRS
=
1
<<
10
,
/* Bit 10: Extend CRS*/
};
/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
enum
{
PHY_L_CIM_ISOL
=
0xff
<<
8
,
/* Bit 15..8: Isolate Count */
PHY_L_CIM_FALSE_CAR
=
0xff
,
/* Bit 7..0: False Carrier Count */
};
/*
* Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
*/
enum
{
PHY_L_P_NO_PAUSE
=
0
<<
10
,
/* Bit 11..10: no Pause Mode */
PHY_L_P_SYM_MD
=
1
<<
10
,
/* Bit 11..10: symmetric Pause Mode */
PHY_L_P_ASYM_MD
=
2
<<
10
,
/* Bit 11..10: asymmetric Pause Mode */
PHY_L_P_BOTH_MD
=
3
<<
10
,
/* Bit 11..10: both Pause Mode */
};
/*
* National-Specific
*/
/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
enum
{
PHY_N_1000C_TEST
=
7
<<
13
,
/* Bit 15..13: Test Modes */
PHY_N_1000C_MSE
=
1
<<
12
,
/* Bit 12: Master/Slave Enable */
PHY_N_1000C_MSC
=
1
<<
11
,
/* Bit 11: M/S Configuration */
PHY_N_1000C_RD
=
1
<<
10
,
/* Bit 10: Repeater/DTE */
PHY_N_1000C_AFD
=
1
<<
9
,
/* Bit 9: Advertise Full Duplex */
PHY_N_1000C_AHD
=
1
<<
8
,
/* Bit 8: Advertise Half Duplex */
PHY_N_1000C_APC
=
1
<<
7
,
/* Bit 7: Asymmetric Pause Cap. */
};
/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
enum
{
PHY_N_1000S_MSF
=
1
<<
15
,
/* Bit 15: Master/Slave Fault */
PHY_N_1000S_MSR
=
1
<<
14
,
/* Bit 14: Master/Slave Result */
PHY_N_1000S_LRS
=
1
<<
13
,
/* Bit 13: Local Receiver Status */
PHY_N_1000S_RRS
=
1
<<
12
,
/* Bit 12: Remote Receiver Status*/
PHY_N_1000S_LP_FD
=
1
<<
11
,
/* Bit 11: Link Partner can FD */
PHY_N_1000S_LP_HD
=
1
<<
10
,
/* Bit 10: Link Partner can HD */
PHY_N_1000C_LP_APC
=
1
<<
9
,
/* Bit 9: LP Asym. Pause Cap. */
PHY_N_1000S_IEC
=
0xff
,
/* Bit 7..0: Idle Error Count */
};
/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
enum
{
PHY_N_ES_X_FD_CAP
=
1
<<
15
,
/* Bit 15: 1000Base-X FD capable */
PHY_N_ES_X_HD_CAP
=
1
<<
14
,
/* Bit 14: 1000Base-X HD capable */
PHY_N_ES_T_FD_CAP
=
1
<<
13
,
/* Bit 13: 1000Base-T FD capable */
PHY_N_ES_T_HD_CAP
=
1
<<
12
,
/* Bit 12: 1000Base-T HD capable */
};
/** Marvell-Specific */
/** Marvell-Specific */
enum
{
enum
{
PHY_M_AN_NXT_PG
=
1
<<
15
,
/* Request Next Page */
PHY_M_AN_NXT_PG
=
1
<<
15
,
/* Request Next Page */
...
@@ -1718,7 +1380,7 @@ enum {
...
@@ -1718,7 +1380,7 @@ enum {
PHY_M_PC_EN_DET_PLUS
=
3
<<
8
,
/* Energy Detect Plus (Mode 2) */
PHY_M_PC_EN_DET_PLUS
=
3
<<
8
,
/* Energy Detect Plus (Mode 2) */
};
};
#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK)
enum
{
enum
{
PHY_M_PC_MAN_MDI
=
0
,
/* 00 = Manual MDI configuration */
PHY_M_PC_MAN_MDI
=
0
,
/* 00 = Manual MDI configuration */
...
@@ -2105,7 +1767,7 @@ enum {
...
@@ -2105,7 +1767,7 @@ enum {
GM_GPSR_FC_RX_DIS
=
1
<<
2
,
/* Bit 2: Rx Flow-Control Mode Disabled */
GM_GPSR_FC_RX_DIS
=
1
<<
2
,
/* Bit 2: Rx Flow-Control Mode Disabled */
GM_GPSR_PROM_EN
=
1
<<
1
,
/* Bit 1: Promiscuous Mode Enabled */
GM_GPSR_PROM_EN
=
1
<<
1
,
/* Bit 1: Promiscuous Mode Enabled */
};
};
/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
enum
{
enum
{
GM_GPCR_PROM_ENA
=
1
<<
14
,
/* Bit 14: Enable Promiscuous Mode */
GM_GPCR_PROM_ENA
=
1
<<
14
,
/* Bit 14: Enable Promiscuous Mode */
...
@@ -2127,7 +1789,7 @@ enum {
...
@@ -2127,7 +1789,7 @@ enum {
#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
enum
{
enum
{
GM_TXCR_FORCE_JAM
=
1
<<
15
,
/* Bit 15: Force Jam / Flow-Control */
GM_TXCR_FORCE_JAM
=
1
<<
15
,
/* Bit 15: Force Jam / Flow-Control */
...
@@ -2138,7 +1800,7 @@ enum {
...
@@ -2138,7 +1800,7 @@ enum {
#define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK)
#define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK)
#define TX_COL_DEF 0x04
#define TX_COL_DEF 0x04
/* GM_RX_CTRL 16 bit r/w Receive Control Register */
/* GM_RX_CTRL 16 bit r/w Receive Control Register */
enum
{
enum
{
GM_RXCR_UCF_ENA
=
1
<<
15
,
/* Bit 15: Enable Unicast filtering */
GM_RXCR_UCF_ENA
=
1
<<
15
,
/* Bit 15: Enable Unicast filtering */
...
@@ -2146,7 +1808,7 @@ enum {
...
@@ -2146,7 +1808,7 @@ enum {
GM_RXCR_CRC_DIS
=
1
<<
13
,
/* Bit 13: Remove 4-byte CRC */
GM_RXCR_CRC_DIS
=
1
<<
13
,
/* Bit 13: Remove 4-byte CRC */
GM_RXCR_PASS_FC
=
1
<<
12
,
/* Bit 12: Pass FC packets to FIFO */
GM_RXCR_PASS_FC
=
1
<<
12
,
/* Bit 12: Pass FC packets to FIFO */
};
};
/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
enum
{
enum
{
GM_TXPA_JAMLEN_MSK
=
0x03
<<
14
,
/* Bit 15..14: Jam Length */
GM_TXPA_JAMLEN_MSK
=
0x03
<<
14
,
/* Bit 15..14: Jam Length */
...
@@ -2171,7 +1833,7 @@ enum {
...
@@ -2171,7 +1833,7 @@ enum {
GM_SMOD_JUMBO_ENA
=
1
<<
8
,
/* Bit 8: Enable Jumbo (Max. Frame Len) */
GM_SMOD_JUMBO_ENA
=
1
<<
8
,
/* Bit 8: Enable Jumbo (Max. Frame Len) */
GM_SMOD_IPG_MSK
=
0x1f
/* Bit 4..0: Inter-Packet Gap (IPG) */
GM_SMOD_IPG_MSK
=
0x1f
/* Bit 4..0: Inter-Packet Gap (IPG) */
};
};
#define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK)
#define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK)
#define DATA_BLIND_DEF 0x04
#define DATA_BLIND_DEF 0x04
...
@@ -2186,7 +1848,7 @@ enum {
...
@@ -2186,7 +1848,7 @@ enum {
GM_SMI_CT_RD_VAL
=
1
<<
4
,
/* Bit 4: Read Valid (Read completed) */
GM_SMI_CT_RD_VAL
=
1
<<
4
,
/* Bit 4: Read Valid (Read completed) */
GM_SMI_CT_BUSY
=
1
<<
3
,
/* Bit 3: Busy (Operation in progress) */
GM_SMI_CT_BUSY
=
1
<<
3
,
/* Bit 3: Busy (Operation in progress) */
};
};
#define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK)
#define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK)
#define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK)
#define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK)
...
@@ -2195,7 +1857,7 @@ enum {
...
@@ -2195,7 +1857,7 @@ enum {
GM_PAR_MIB_CLR
=
1
<<
5
,
/* Bit 5: Set MIB Clear Counter Mode */
GM_PAR_MIB_CLR
=
1
<<
5
,
/* Bit 5: Set MIB Clear Counter Mode */
GM_PAR_MIB_TST
=
1
<<
4
,
/* Bit 4: MIB Load Counter (Test Mode) */
GM_PAR_MIB_TST
=
1
<<
4
,
/* Bit 4: MIB Load Counter (Test Mode) */
};
};
/* Receive Frame Status Encoding */
/* Receive Frame Status Encoding */
enum
{
enum
{
GMR_FS_LEN
=
0xffff
<<
16
,
/* Bit 31..16: Rx Frame Length */
GMR_FS_LEN
=
0xffff
<<
16
,
/* Bit 31..16: Rx Frame Length */
...
@@ -2217,12 +1879,12 @@ enum {
...
@@ -2217,12 +1879,12 @@ enum {
/*
/*
* GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
* GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
*/
*/
GMR_FS_ANY_ERR
=
GMR_FS_CRC_ERR
|
GMR_FS_LONG_ERR
|
GMR_FS_ANY_ERR
=
GMR_FS_CRC_ERR
|
GMR_FS_LONG_ERR
|
GMR_FS_MII_ERR
|
GMR_FS_BAD_FC
|
GMR_FS_GOOD_FC
|
GMR_FS_MII_ERR
|
GMR_FS_BAD_FC
|
GMR_FS_GOOD_FC
|
GMR_FS_JABBER
,
GMR_FS_JABBER
,
/* Rx GMAC FIFO Flush Mask (default) */
/* Rx GMAC FIFO Flush Mask (default) */
RX_FF_FL_DEF_MSK
=
GMR_FS_CRC_ERR
|
GMR_FS_RX_FF_OV
|
GMR_FS_MII_ERR
|
RX_FF_FL_DEF_MSK
=
GMR_FS_CRC_ERR
|
GMR_FS_RX_FF_OV
|
GMR_FS_MII_ERR
|
GMR_FS_BAD_FC
|
GMR_FS_GOOD_FC
|
GMR_FS_UN_SIZE
|
GMR_FS_BAD_FC
|
GMR_FS_GOOD_FC
|
GMR_FS_UN_SIZE
|
GMR_FS_JABBER
,
GMR_FS_JABBER
,
};
};
...
@@ -2540,10 +2202,6 @@ enum {
...
@@ -2540,10 +2202,6 @@ enum {
};
};
/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
#define XM_PHY_ADDR_SZ 0x1f
/* Bit 4..0: PHY Address bits */
/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
enum
{
enum
{
XM_GP_ANIP
=
1
<<
6
,
/* Bit 6: (ro) Auto-Neg. in progress */
XM_GP_ANIP
=
1
<<
6
,
/* Bit 6: (ro) Auto-Neg. in progress */
...
@@ -2662,8 +2320,8 @@ enum {
...
@@ -2662,8 +2320,8 @@ enum {
};
};
#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
#define XM_DEF_MODE
(XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CA
A)
XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CS
A)
/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
enum
{
enum
{
...
@@ -2793,28 +2451,20 @@ struct skge_hw {
...
@@ -2793,28 +2451,20 @@ struct skge_hw {
u32
intr_mask
;
u32
intr_mask
;
struct
net_device
*
dev
[
2
];
struct
net_device
*
dev
[
2
];
u8
mac_cfg
;
u8
chip_id
;
u8
chip_id
;
u8
chip_rev
;
u8
phy_type
;
u8
phy_type
;
u8
pmd_type
;
u8
pmd_type
;
u16
phy_addr
;
u16
phy_addr
;
u8
ports
;
u32
ram_size
;
u32
ram_size
;
u32
ram_offset
;
u32
ram_offset
;
struct
tasklet_struct
ext_tasklet
;
struct
tasklet_struct
ext_tasklet
;
spinlock_t
phy_lock
;
spinlock_t
phy_lock
;
};
};
static
inline
int
isdualport
(
const
struct
skge_hw
*
hw
)
{
return
!
(
hw
->
mac_cfg
&
CFG_SNG_MAC
);
}
static
inline
u8
chip_rev
(
const
struct
skge_hw
*
hw
)
{
return
(
hw
->
mac_cfg
&
CFG_CHIP_R_MSK
)
>>
4
;
}
static
inline
int
iscopper
(
const
struct
skge_hw
*
hw
)
static
inline
int
iscopper
(
const
struct
skge_hw
*
hw
)
{
{
...
@@ -2827,7 +2477,7 @@ enum {
...
@@ -2827,7 +2477,7 @@ enum {
FLOW_MODE_REM_SEND
=
2
,
/* Symmetric or just remote */
FLOW_MODE_REM_SEND
=
2
,
/* Symmetric or just remote */
FLOW_MODE_SYMMETRIC
=
3
,
/* Both stations may send PAUSE */
FLOW_MODE_SYMMETRIC
=
3
,
/* Both stations may send PAUSE */
};
};
struct
skge_port
{
struct
skge_port
{
u32
msg_enable
;
u32
msg_enable
;
struct
skge_hw
*
hw
;
struct
skge_hw
*
hw
;
...
@@ -2853,8 +2503,8 @@ struct skge_port {
...
@@ -2853,8 +2503,8 @@ struct skge_port {
void
*
mem
;
/* PCI memory for rings */
void
*
mem
;
/* PCI memory for rings */
dma_addr_t
dma
;
dma_addr_t
dma
;
unsigned
long
mem_size
;
unsigned
long
mem_size
;
unsigned
int
rx_buf_size
;
struct
timer_list
link_check
;
struct
timer_list
led_blink
;
struct
timer_list
led_blink
;
};
};
...
@@ -2863,7 +2513,6 @@ struct skge_port {
...
@@ -2863,7 +2513,6 @@ struct skge_port {
static
inline
u32
skge_read32
(
const
struct
skge_hw
*
hw
,
int
reg
)
static
inline
u32
skge_read32
(
const
struct
skge_hw
*
hw
,
int
reg
)
{
{
return
readl
(
hw
->
regs
+
reg
);
return
readl
(
hw
->
regs
+
reg
);
}
}
static
inline
u16
skge_read16
(
const
struct
skge_hw
*
hw
,
int
reg
)
static
inline
u16
skge_read16
(
const
struct
skge_hw
*
hw
,
int
reg
)
...
@@ -2892,114 +2541,87 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val)
...
@@ -2892,114 +2541,87 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val)
}
}
/* MAC Related Registers inside the device. */
/* MAC Related Registers inside the device. */
#define SKGEMAC_REG(port,reg) (((port)<<7)+(reg))
#define SK_REG(port,reg) (((port)<<7)+(reg))
#define SK_XMAC_REG(port, reg) \
/* PCI config space can be accessed via memory mapped space */
#define SKGEPCI_REG(reg) ((reg)+ 0x380)
#define SKGEXM_REG(port, reg) \
((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
static
inline
u32
skge_xm_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
u32
xm_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
return
skge_read32
(
hw
,
SKGEXM_REG
(
port
,
reg
));
}
static
inline
u16
skge_xm_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
{
return
skge_read16
(
hw
,
SKGEXM_REG
(
port
,
reg
));
u32
v
;
v
=
skge_read16
(
hw
,
SK_XMAC_REG
(
port
,
reg
));
v
|=
(
u32
)
skge_read16
(
hw
,
SK_XMAC_REG
(
port
,
reg
+
2
))
<<
16
;
return
v
;
}
}
static
inline
u
8
skge_xm_read8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
u
16
xm_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
{
return
skge_read
8
(
hw
,
SKGEXM
_REG
(
port
,
reg
));
return
skge_read
16
(
hw
,
SK_XMAC
_REG
(
port
,
reg
));
}
}
static
inline
void
skge_
xm_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
static
inline
void
xm_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
{
{
skge_write32
(
hw
,
SKGEXM_REG
(
port
,
r
),
v
);
skge_write16
(
hw
,
SK_XMAC_REG
(
port
,
r
),
v
&
0xffff
);
skge_write16
(
hw
,
SK_XMAC_REG
(
port
,
r
+
2
),
v
>>
16
);
}
}
static
inline
void
skge_
xm_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
static
inline
void
xm_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
{
{
skge_write16
(
hw
,
SK
GEXM
_REG
(
port
,
r
),
v
);
skge_write16
(
hw
,
SK
_XMAC
_REG
(
port
,
r
),
v
);
}
}
static
inline
void
skge_xm_write8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u8
v
)
static
inline
void
xm_outhash
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
{
skge_write8
(
hw
,
SKGEXM_REG
(
port
,
r
),
v
);
}
static
inline
void
skge_xm_outhash
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
const
u8
*
hash
)
const
u8
*
hash
)
{
{
skge_xm_write16
(
hw
,
port
,
reg
,
xm_write16
(
hw
,
port
,
reg
,
(
u16
)
hash
[
0
]
|
((
u16
)
hash
[
1
]
<<
8
));
(
u16
)
hash
[
0
]
|
((
u16
)
hash
[
1
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
2
,
(
u16
)
hash
[
2
]
|
((
u16
)
hash
[
3
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
+
2
,
xm_write16
(
hw
,
port
,
reg
+
4
,
(
u16
)
hash
[
4
]
|
((
u16
)
hash
[
5
]
<<
8
));
(
u16
)
hash
[
2
]
|
((
u16
)
hash
[
3
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
6
,
(
u16
)
hash
[
6
]
|
((
u16
)
hash
[
7
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
+
4
,
(
u16
)
hash
[
4
]
|
((
u16
)
hash
[
5
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
+
6
,
(
u16
)
hash
[
6
]
|
((
u16
)
hash
[
7
]
<<
8
));
}
}
static
inline
void
skge_
xm_outaddr
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
static
inline
void
xm_outaddr
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
const
u8
*
addr
)
const
u8
*
addr
)
{
{
skge_xm_write16
(
hw
,
port
,
reg
,
xm_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
xm_write16
(
hw
,
port
,
reg
+
2
,
(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
,
xm_write16
(
hw
,
port
,
reg
+
4
,
(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
skge_xm_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
}
}
#define SK_GMAC_REG(port,reg) \
(BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
#define SKGEGMA_REG(port,reg) \
static
inline
u16
gma_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
((reg) + BASE_GMAC_1 + \
(port) * (BASE_GMAC_2-BASE_GMAC_1))
static
inline
u16
skge_gma_read16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
{
return
skge_read16
(
hw
,
SK
GEGMA
_REG
(
port
,
reg
));
return
skge_read16
(
hw
,
SK
_GMAC
_REG
(
port
,
reg
));
}
}
static
inline
u32
skge_
gma_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
u32
gma_read32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
{
{
return
(
u32
)
skge_read16
(
hw
,
SK
GEGMA
_REG
(
port
,
reg
))
return
(
u32
)
skge_read16
(
hw
,
SK
_GMAC
_REG
(
port
,
reg
))
|
((
u32
)
skge_read16
(
hw
,
SK
GEGMA
_REG
(
port
,
reg
+
4
))
<<
16
);
|
((
u32
)
skge_read16
(
hw
,
SK
_GMAC
_REG
(
port
,
reg
+
4
))
<<
16
);
}
}
static
inline
u8
skge_gma_read8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
reg
)
static
inline
void
gma_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
{
{
return
skge_read8
(
hw
,
SKGEGMA_REG
(
port
,
reg
)
);
skge_write16
(
hw
,
SK_GMAC_REG
(
port
,
r
),
v
);
}
}
static
inline
void
skge_gma_write16
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u16
v
)
static
inline
void
gma_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
{
{
skge_write16
(
hw
,
SKGEGMA_REG
(
port
,
r
),
v
);
skge_write16
(
hw
,
SK_GMAC_REG
(
port
,
r
),
(
u16
)
v
);
skge_write32
(
hw
,
SK_GMAC_REG
(
port
,
r
+
4
),
(
u16
)(
v
>>
16
));
}
}
static
inline
void
skge_gma_write32
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u32
v
)
static
inline
void
gma_write8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u8
v
)
{
{
skge_write16
(
hw
,
SKGEGMA_REG
(
port
,
r
),
(
u16
)
v
);
skge_write8
(
hw
,
SK_GMAC_REG
(
port
,
r
),
v
);
skge_write32
(
hw
,
SKGEGMA_REG
(
port
,
r
+
4
),
(
u16
)(
v
>>
16
));
}
}
static
inline
void
skge_gma_write8
(
const
struct
skge_hw
*
hw
,
int
port
,
int
r
,
u8
v
)
static
inline
void
gma_set_addr
(
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
{
skge_write8
(
hw
,
SKGEGMA_REG
(
port
,
r
),
v
);
}
static
inline
void
skge_gm_set_addr
(
struct
skge_hw
*
hw
,
int
port
,
int
reg
,
const
u8
*
addr
)
const
u8
*
addr
)
{
{
skge_gma_write16
(
hw
,
port
,
reg
,
gma_write16
(
hw
,
port
,
reg
,
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
(
u16
)
addr
[
0
]
|
((
u16
)
addr
[
1
]
<<
8
));
gma_write16
(
hw
,
port
,
reg
+
4
,(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
skge_gma_write16
(
hw
,
port
,
reg
+
4
,
gma_write16
(
hw
,
port
,
reg
+
8
,(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
(
u16
)
addr
[
2
]
|
((
u16
)
addr
[
3
]
<<
8
));
skge_gma_write16
(
hw
,
port
,
reg
+
8
,
(
u16
)
addr
[
4
]
|
((
u16
)
addr
[
5
]
<<
8
));
}
}
#endif
#endif
include/linux/etherdevice.h
浏览文件 @
245ac873
...
@@ -65,7 +65,7 @@ static inline int is_zero_ether_addr(const u8 *addr)
...
@@ -65,7 +65,7 @@ static inline int is_zero_ether_addr(const u8 *addr)
*/
*/
static
inline
int
is_multicast_ether_addr
(
const
u8
*
addr
)
static
inline
int
is_multicast_ether_addr
(
const
u8
*
addr
)
{
{
return
addr
[
0
]
&
0x01
;
return
((
addr
[
0
]
!=
0xff
)
&&
(
0x01
&
addr
[
0
]))
;
}
}
/**
/**
...
...
include/net/ieee80211.h
浏览文件 @
245ac873
...
@@ -625,17 +625,6 @@ enum ieee80211_state {
...
@@ -625,17 +625,6 @@ enum ieee80211_state {
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
extern
inline
int
is_multicast_ether_addr
(
const
u8
*
addr
)
{
return
((
addr
[
0
]
!=
0xff
)
&&
(
0x01
&
addr
[
0
]));
}
extern
inline
int
is_broadcast_ether_addr
(
const
u8
*
addr
)
{
return
((
addr
[
0
]
==
0xff
)
&&
(
addr
[
1
]
==
0xff
)
&&
(
addr
[
2
]
==
0xff
)
&&
\
(
addr
[
3
]
==
0xff
)
&&
(
addr
[
4
]
==
0xff
)
&&
(
addr
[
5
]
==
0xff
));
}
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_RESERVE_FCS (1<<0)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录