Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
16b237dc
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
16b237dc
编写于
7月 29, 2008
作者:
J
Jeff Garzik
提交者:
Jeff Garzik
7月 29, 2008
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-2.6.27' of
git://git.marvell.com/mv643xx_eth
into upstream-fixes
上级
80513675
ac0a2d0c
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
251 addition
and
122 deletion
+251
-122
arch/arm/mach-kirkwood/rd88f6281-setup.c
arch/arm/mach-kirkwood/rd88f6281-setup.c
+3
-0
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+3
-0
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+3
-0
arch/arm/mach-orion5x/wnr854t-setup.c
arch/arm/mach-orion5x/wnr854t-setup.c
+3
-0
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
+3
-0
drivers/net/mv643xx_eth.c
drivers/net/mv643xx_eth.c
+236
-122
未找到文件。
arch/arm/mach-kirkwood/rd88f6281-setup.c
浏览文件 @
16b237dc
...
...
@@ -18,6 +18,7 @@
#include <linux/timer.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
...
...
@@ -69,6 +70,8 @@ static struct platform_device rd88f6281_nand_flash = {
static
struct
mv643xx_eth_platform_data
rd88f6281_ge00_data
=
{
.
phy_addr
=
-
1
,
.
speed
=
SPEED_1000
,
.
duplex
=
DUPLEX_FULL
,
};
static
struct
mv_sata_platform_data
rd88f6281_sata_data
=
{
...
...
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
浏览文件 @
16b237dc
...
...
@@ -15,6 +15,7 @@
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/leds.h>
...
...
@@ -88,6 +89,8 @@ static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
static
struct
mv643xx_eth_platform_data
rd88f5181l_fxo_eth_data
=
{
.
phy_addr
=
-
1
,
.
speed
=
SPEED_1000
,
.
duplex
=
DUPLEX_FULL
,
};
static
void
__init
rd88f5181l_fxo_init
(
void
)
...
...
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
浏览文件 @
16b237dc
...
...
@@ -15,6 +15,7 @@
#include <linux/irq.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <linux/i2c.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
...
...
@@ -89,6 +90,8 @@ static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
static
struct
mv643xx_eth_platform_data
rd88f5181l_ge_eth_data
=
{
.
phy_addr
=
-
1
,
.
speed
=
SPEED_1000
,
.
duplex
=
DUPLEX_FULL
,
};
static
struct
i2c_board_info
__initdata
rd88f5181l_ge_i2c_rtc
=
{
...
...
arch/arm/mach-orion5x/wnr854t-setup.c
浏览文件 @
16b237dc
...
...
@@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
...
...
@@ -92,6 +93,8 @@ static struct platform_device wnr854t_nor_flash = {
static
struct
mv643xx_eth_platform_data
wnr854t_eth_data
=
{
.
phy_addr
=
-
1
,
.
speed
=
SPEED_1000
,
.
duplex
=
DUPLEX_FULL
,
};
static
void
__init
wnr854t_init
(
void
)
...
...
arch/arm/mach-orion5x/wrt350n-v2-setup.c
浏览文件 @
16b237dc
...
...
@@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
...
...
@@ -100,6 +101,8 @@ static struct platform_device wrt350n_v2_nor_flash = {
static
struct
mv643xx_eth_platform_data
wrt350n_v2_eth_data
=
{
.
phy_addr
=
-
1
,
.
speed
=
SPEED_1000
,
.
duplex
=
DUPLEX_FULL
,
};
static
void
__init
wrt350n_v2_init
(
void
)
...
...
drivers/net/mv643xx_eth.c
浏览文件 @
16b237dc
...
...
@@ -55,7 +55,7 @@
#include <asm/system.h>
static
char
mv643xx_eth_driver_name
[]
=
"mv643xx_eth"
;
static
char
mv643xx_eth_driver_version
[]
=
"1.
1
"
;
static
char
mv643xx_eth_driver_version
[]
=
"1.
2
"
;
#define MV643XX_ETH_CHECKSUM_OFFLOAD_TX
#define MV643XX_ETH_NAPI
...
...
@@ -90,12 +90,21 @@ static char mv643xx_eth_driver_version[] = "1.1";
#define PORT_SERIAL_CONTROL(p) (0x043c + ((p) << 10))
#define PORT_STATUS(p) (0x0444 + ((p) << 10))
#define TX_FIFO_EMPTY 0x00000400
#define TX_IN_PROGRESS 0x00000080
#define PORT_SPEED_MASK 0x00000030
#define PORT_SPEED_1000 0x00000010
#define PORT_SPEED_100 0x00000020
#define PORT_SPEED_10 0x00000000
#define FLOW_CONTROL_ENABLED 0x00000008
#define FULL_DUPLEX 0x00000004
#define LINK_UP 0x00000002
#define TXQ_COMMAND(p) (0x0448 + ((p) << 10))
#define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10))
#define TX_BW_RATE(p) (0x0450 + ((p) << 10))
#define TX_BW_MTU(p) (0x0458 + ((p) << 10))
#define TX_BW_BURST(p) (0x045c + ((p) << 10))
#define INT_CAUSE(p) (0x0460 + ((p) << 10))
#define INT_TX_END_0 0x00080000
#define INT_TX_END 0x07f80000
#define INT_RX 0x0007fbfc
#define INT_EXT 0x00000002
...
...
@@ -127,21 +136,21 @@ static char mv643xx_eth_driver_version[] = "1.1";
/*
* SDMA configuration register.
*/
#define RX_BURST_SIZE_
4_64BIT (2
<< 1)
#define RX_BURST_SIZE_
16_64BIT (4
<< 1)
#define BLM_RX_NO_SWAP (1 << 4)
#define BLM_TX_NO_SWAP (1 << 5)
#define TX_BURST_SIZE_
4_64BIT (2
<< 22)
#define TX_BURST_SIZE_
16_64BIT (4
<< 22)
#if defined(__BIG_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
RX_BURST_SIZE_
4
_64BIT | \
TX_BURST_SIZE_
4
_64BIT
RX_BURST_SIZE_
16
_64BIT | \
TX_BURST_SIZE_
16
_64BIT
#elif defined(__LITTLE_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
RX_BURST_SIZE_
4
_64BIT | \
RX_BURST_SIZE_
16
_64BIT | \
BLM_RX_NO_SWAP | \
BLM_TX_NO_SWAP | \
TX_BURST_SIZE_
4
_64BIT
TX_BURST_SIZE_
16
_64BIT
#else
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif
...
...
@@ -153,9 +162,7 @@ static char mv643xx_eth_driver_version[] = "1.1";
#define SET_MII_SPEED_TO_100 (1 << 24)
#define SET_GMII_SPEED_TO_1000 (1 << 23)
#define SET_FULL_DUPLEX_MODE (1 << 21)
#define MAX_RX_PACKET_1522BYTE (1 << 17)
#define MAX_RX_PACKET_9700BYTE (5 << 17)
#define MAX_RX_PACKET_MASK (7 << 17)
#define DISABLE_AUTO_NEG_SPEED_GMII (1 << 13)
#define DO_NOT_FORCE_LINK_FAIL (1 << 10)
#define SERIAL_PORT_CONTROL_RESERVED (1 << 9)
...
...
@@ -228,6 +235,8 @@ struct tx_desc {
#define GEN_IP_V4_CHECKSUM 0x00040000
#define GEN_TCP_UDP_CHECKSUM 0x00020000
#define UDP_FRAME 0x00010000
#define MAC_HDR_EXTRA_4_BYTES 0x00008000
#define MAC_HDR_EXTRA_8_BYTES 0x00000200
#define TX_IHL_SHIFT 11
...
...
@@ -404,6 +413,17 @@ static void rxq_disable(struct rx_queue *rxq)
udelay
(
10
);
}
static
void
txq_reset_hw_ptr
(
struct
tx_queue
*
txq
)
{
struct
mv643xx_eth_private
*
mp
=
txq_to_mp
(
txq
);
int
off
=
TXQ_CURRENT_DESC_PTR
(
mp
->
port_num
,
txq
->
index
);
u32
addr
;
addr
=
(
u32
)
txq
->
tx_desc_dma
;
addr
+=
txq
->
tx_curr_desc
*
sizeof
(
struct
tx_desc
);
wrl
(
mp
,
off
,
addr
);
}
static
void
txq_enable
(
struct
tx_queue
*
txq
)
{
struct
mv643xx_eth_private
*
mp
=
txq_to_mp
(
txq
);
...
...
@@ -614,6 +634,12 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
for
(
i
=
0
;
i
<
8
;
i
++
)
if
(
mp
->
txq_mask
&
(
1
<<
i
))
txq_reclaim
(
mp
->
txq
+
i
,
0
);
if
(
netif_carrier_ok
(
mp
->
dev
))
{
spin_lock
(
&
mp
->
lock
);
__txq_maybe_wake
(
mp
->
txq
+
mp
->
txq_primary
);
spin_unlock
(
&
mp
->
lock
);
}
}
#endif
...
...
@@ -706,6 +732,7 @@ static inline __be16 sum16_as_be(__sum16 sum)
static
void
txq_submit_skb
(
struct
tx_queue
*
txq
,
struct
sk_buff
*
skb
)
{
struct
mv643xx_eth_private
*
mp
=
txq_to_mp
(
txq
);
int
nr_frags
=
skb_shinfo
(
skb
)
->
nr_frags
;
int
tx_index
;
struct
tx_desc
*
desc
;
...
...
@@ -732,12 +759,36 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
desc
->
buf_ptr
=
dma_map_single
(
NULL
,
skb
->
data
,
length
,
DMA_TO_DEVICE
);
if
(
skb
->
ip_summed
==
CHECKSUM_PARTIAL
)
{
BUG_ON
(
skb
->
protocol
!=
htons
(
ETH_P_IP
));
int
mac_hdr_len
;
BUG_ON
(
skb
->
protocol
!=
htons
(
ETH_P_IP
)
&&
skb
->
protocol
!=
htons
(
ETH_P_8021Q
));
cmd_sts
|=
GEN_TCP_UDP_CHECKSUM
|
GEN_IP_V4_CHECKSUM
|
ip_hdr
(
skb
)
->
ihl
<<
TX_IHL_SHIFT
;
mac_hdr_len
=
(
void
*
)
ip_hdr
(
skb
)
-
(
void
*
)
skb
->
data
;
switch
(
mac_hdr_len
-
ETH_HLEN
)
{
case
0
:
break
;
case
4
:
cmd_sts
|=
MAC_HDR_EXTRA_4_BYTES
;
break
;
case
8
:
cmd_sts
|=
MAC_HDR_EXTRA_8_BYTES
;
break
;
case
12
:
cmd_sts
|=
MAC_HDR_EXTRA_4_BYTES
;
cmd_sts
|=
MAC_HDR_EXTRA_8_BYTES
;
break
;
default:
if
(
net_ratelimit
())
dev_printk
(
KERN_ERR
,
&
txq_to_mp
(
txq
)
->
dev
->
dev
,
"mac header length is %d?!
\n
"
,
mac_hdr_len
);
break
;
}
switch
(
ip_hdr
(
skb
)
->
protocol
)
{
case
IPPROTO_UDP
:
cmd_sts
|=
UDP_FRAME
;
...
...
@@ -759,6 +810,10 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
wmb
();
desc
->
cmd_sts
=
cmd_sts
;
/* clear TX_END interrupt status */
wrl
(
mp
,
INT_CAUSE
(
mp
->
port_num
),
~
(
INT_TX_END_0
<<
txq
->
index
));
rdl
(
mp
,
INT_CAUSE
(
mp
->
port_num
));
/* ensure all descriptors are written before poking hardware */
wmb
();
txq_enable
(
txq
);
...
...
@@ -1112,10 +1167,28 @@ static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *
static
int
mv643xx_eth_get_settings_phyless
(
struct
net_device
*
dev
,
struct
ethtool_cmd
*
cmd
)
{
struct
mv643xx_eth_private
*
mp
=
netdev_priv
(
dev
);
u32
port_status
;
port_status
=
rdl
(
mp
,
PORT_STATUS
(
mp
->
port_num
));
cmd
->
supported
=
SUPPORTED_MII
;
cmd
->
advertising
=
ADVERTISED_MII
;
cmd
->
speed
=
SPEED_1000
;
cmd
->
duplex
=
DUPLEX_FULL
;
switch
(
port_status
&
PORT_SPEED_MASK
)
{
case
PORT_SPEED_10
:
cmd
->
speed
=
SPEED_10
;
break
;
case
PORT_SPEED_100
:
cmd
->
speed
=
SPEED_100
;
break
;
case
PORT_SPEED_1000
:
cmd
->
speed
=
SPEED_1000
;
break
;
default:
cmd
->
speed
=
-
1
;
break
;
}
cmd
->
duplex
=
(
port_status
&
FULL_DUPLEX
)
?
DUPLEX_FULL
:
DUPLEX_HALF
;
cmd
->
port
=
PORT_MII
;
cmd
->
phy_address
=
0
;
cmd
->
transceiver
=
XCVR_INTERNAL
;
...
...
@@ -1539,8 +1612,11 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
tx_desc
=
(
struct
tx_desc
*
)
txq
->
tx_desc_area
;
for
(
i
=
0
;
i
<
txq
->
tx_ring_size
;
i
++
)
{
struct
tx_desc
*
txd
=
tx_desc
+
i
;
int
nexti
=
(
i
+
1
)
%
txq
->
tx_ring_size
;
tx_desc
[
i
].
next_desc_ptr
=
txq
->
tx_desc_dma
+
txd
->
cmd_sts
=
0
;
txd
->
next_desc_ptr
=
txq
->
tx_desc_dma
+
nexti
*
sizeof
(
struct
tx_desc
);
}
...
...
@@ -1577,8 +1653,11 @@ static void txq_reclaim(struct tx_queue *txq, int force)
desc
=
&
txq
->
tx_desc_area
[
tx_index
];
cmd_sts
=
desc
->
cmd_sts
;
if
(
!
force
&&
(
cmd_sts
&
BUFFER_OWNED_BY_DMA
))
break
;
if
(
cmd_sts
&
BUFFER_OWNED_BY_DMA
)
{
if
(
!
force
)
break
;
desc
->
cmd_sts
=
cmd_sts
&
~
BUFFER_OWNED_BY_DMA
;
}
txq
->
tx_used_desc
=
(
tx_index
+
1
)
%
txq
->
tx_ring_size
;
txq
->
tx_desc_count
--
;
...
...
@@ -1632,49 +1711,61 @@ static void txq_deinit(struct tx_queue *txq)
/* netdev ops and related ***************************************************/
static
void
update_pscr
(
struct
mv643xx_eth_private
*
mp
,
int
speed
,
int
duplex
)
static
void
handle_link_event
(
struct
mv643xx_eth_private
*
mp
)
{
u32
pscr_o
;
u32
pscr_n
;
pscr_o
=
rdl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
));
struct
net_device
*
dev
=
mp
->
dev
;
u32
port_status
;
int
speed
;
int
duplex
;
int
fc
;
port_status
=
rdl
(
mp
,
PORT_STATUS
(
mp
->
port_num
));
if
(
!
(
port_status
&
LINK_UP
))
{
if
(
netif_carrier_ok
(
dev
))
{
int
i
;
/* clear speed, duplex and rx buffer size fields */
pscr_n
=
pscr_o
&
~
(
SET_MII_SPEED_TO_100
|
SET_GMII_SPEED_TO_1000
|
SET_FULL_DUPLEX_MODE
|
MAX_RX_PACKET_MASK
);
printk
(
KERN_INFO
"%s: link down
\n
"
,
dev
->
name
);
if
(
speed
==
SPEED_1000
)
{
pscr_n
|=
SET_GMII_SPEED_TO_1000
|
MAX_RX_PACKET_9700BYTE
;
}
else
{
if
(
speed
==
SPEED_100
)
pscr_n
|=
SET_MII_SPEED_TO_100
;
pscr_n
|=
MAX_RX_PACKET_1522BYTE
;
}
netif_carrier_off
(
dev
);
netif_stop_queue
(
dev
);
if
(
duplex
==
DUPLEX_FULL
)
pscr_n
|=
SET_FULL_DUPLEX_MODE
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
struct
tx_queue
*
txq
=
mp
->
txq
+
i
;
if
(
pscr_n
!=
pscr_o
)
{
if
((
pscr_o
&
SERIAL_PORT_ENABLE
)
==
0
)
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr_n
);
else
{
int
i
;
if
(
mp
->
txq_mask
&
(
1
<<
i
))
{
txq_reclaim
(
txq
,
1
);
txq_reset_hw_ptr
(
txq
);
}
}
}
return
;
}
for
(
i
=
0
;
i
<
8
;
i
++
)
if
(
mp
->
txq_mask
&
(
1
<<
i
))
txq_disable
(
mp
->
txq
+
i
);
switch
(
port_status
&
PORT_SPEED_MASK
)
{
case
PORT_SPEED_10
:
speed
=
10
;
break
;
case
PORT_SPEED_100
:
speed
=
100
;
break
;
case
PORT_SPEED_1000
:
speed
=
1000
;
break
;
default:
speed
=
-
1
;
break
;
}
duplex
=
(
port_status
&
FULL_DUPLEX
)
?
1
:
0
;
fc
=
(
port_status
&
FLOW_CONTROL_ENABLED
)
?
1
:
0
;
pscr_o
&=
~
SERIAL_PORT_ENABLE
;
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr_o
);
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr_n
);
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr_n
);
printk
(
KERN_INFO
"%s: link up, %d Mb/s, %s duplex, "
"flow control %sabled
\n
"
,
dev
->
name
,
speed
,
duplex
?
"full"
:
"half"
,
fc
?
"en"
:
"dis"
);
for
(
i
=
0
;
i
<
8
;
i
++
)
if
(
mp
->
txq_mask
&
(
1
<<
i
))
txq_enable
(
mp
->
txq
+
i
);
}
if
(
!
netif_carrier_ok
(
dev
))
{
netif_carrier_on
(
dev
);
netif_wake_queue
(
dev
);
}
}
...
...
@@ -1684,7 +1775,6 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
struct
mv643xx_eth_private
*
mp
=
netdev_priv
(
dev
);
u32
int_cause
;
u32
int_cause_ext
;
u32
txq_active
;
int_cause
=
rdl
(
mp
,
INT_CAUSE
(
mp
->
port_num
))
&
(
INT_TX_END
|
INT_RX
|
INT_EXT
);
...
...
@@ -1698,30 +1788,8 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
wrl
(
mp
,
INT_CAUSE_EXT
(
mp
->
port_num
),
~
int_cause_ext
);
}
if
(
int_cause_ext
&
(
INT_EXT_PHY
|
INT_EXT_LINK
))
{
if
(
mp
->
phy_addr
==
-
1
||
mii_link_ok
(
&
mp
->
mii
))
{
int
i
;
if
(
mp
->
phy_addr
!=
-
1
)
{
struct
ethtool_cmd
cmd
;
mii_ethtool_gset
(
&
mp
->
mii
,
&
cmd
);
update_pscr
(
mp
,
cmd
.
speed
,
cmd
.
duplex
);
}
for
(
i
=
0
;
i
<
8
;
i
++
)
if
(
mp
->
txq_mask
&
(
1
<<
i
))
txq_enable
(
mp
->
txq
+
i
);
if
(
!
netif_carrier_ok
(
dev
))
{
netif_carrier_on
(
dev
);
__txq_maybe_wake
(
mp
->
txq
+
mp
->
txq_primary
);
}
}
else
if
(
netif_carrier_ok
(
dev
))
{
netif_stop_queue
(
dev
);
netif_carrier_off
(
dev
);
}
}
if
(
int_cause_ext
&
(
INT_EXT_PHY
|
INT_EXT_LINK
))
handle_link_event
(
mp
);
/*
* RxBuffer or RxError set for any of the 8 queues?
...
...
@@ -1743,8 +1811,6 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
}
#endif
txq_active
=
rdl
(
mp
,
TXQ_COMMAND
(
mp
->
port_num
));
/*
* TxBuffer or TxError set for any of the 8 queues?
*/
...
...
@@ -1754,6 +1820,16 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
for
(
i
=
0
;
i
<
8
;
i
++
)
if
(
mp
->
txq_mask
&
(
1
<<
i
))
txq_reclaim
(
mp
->
txq
+
i
,
0
);
/*
* Enough space again in the primary TX queue for a
* full packet?
*/
if
(
netif_carrier_ok
(
dev
))
{
spin_lock
(
&
mp
->
lock
);
__txq_maybe_wake
(
mp
->
txq
+
mp
->
txq_primary
);
spin_unlock
(
&
mp
->
lock
);
}
}
/*
...
...
@@ -1763,19 +1839,25 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
int
i
;
wrl
(
mp
,
INT_CAUSE
(
mp
->
port_num
),
~
(
int_cause
&
INT_TX_END
));
spin_lock
(
&
mp
->
lock
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
struct
tx_queue
*
txq
=
mp
->
txq
+
i
;
if
(
txq
->
tx_desc_count
&&
!
((
txq_active
>>
i
)
&
1
))
u32
hw_desc_ptr
;
u32
expected_ptr
;
if
((
int_cause
&
(
INT_TX_END_0
<<
i
))
==
0
)
continue
;
hw_desc_ptr
=
rdl
(
mp
,
TXQ_CURRENT_DESC_PTR
(
mp
->
port_num
,
i
));
expected_ptr
=
(
u32
)
txq
->
tx_desc_dma
+
txq
->
tx_curr_desc
*
sizeof
(
struct
tx_desc
);
if
(
hw_desc_ptr
!=
expected_ptr
)
txq_enable
(
txq
);
}
}
/*
* Enough space again in the primary TX queue for a full packet?
*/
if
(
int_cause_ext
&
INT_EXT_TX
)
{
struct
tx_queue
*
txq
=
mp
->
txq
+
mp
->
txq_primary
;
__txq_maybe_wake
(
txq
);
spin_unlock
(
&
mp
->
lock
);
}
return
IRQ_HANDLED
;
...
...
@@ -1785,14 +1867,14 @@ static void phy_reset(struct mv643xx_eth_private *mp)
{
unsigned
int
data
;
smi_reg_read
(
mp
,
mp
->
phy_addr
,
0
,
&
data
);
data
|=
0x8000
;
smi_reg_write
(
mp
,
mp
->
phy_addr
,
0
,
data
);
smi_reg_read
(
mp
,
mp
->
phy_addr
,
MII_BMCR
,
&
data
);
data
|=
BMCR_RESET
;
smi_reg_write
(
mp
,
mp
->
phy_addr
,
MII_BMCR
,
data
);
do
{
udelay
(
1
);
smi_reg_read
(
mp
,
mp
->
phy_addr
,
0
,
&
data
);
}
while
(
data
&
0x8000
);
smi_reg_read
(
mp
,
mp
->
phy_addr
,
MII_BMCR
,
&
data
);
}
while
(
data
&
BMCR_RESET
);
}
static
void
port_start
(
struct
mv643xx_eth_private
*
mp
)
...
...
@@ -1800,23 +1882,6 @@ static void port_start(struct mv643xx_eth_private *mp)
u32
pscr
;
int
i
;
/*
* Configure basic link parameters.
*/
pscr
=
rdl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
));
pscr
&=
~
(
SERIAL_PORT_ENABLE
|
FORCE_LINK_PASS
);
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr
);
pscr
|=
DISABLE_AUTO_NEG_FOR_FLOW_CTRL
|
DISABLE_AUTO_NEG_SPEED_GMII
|
DISABLE_AUTO_NEG_FOR_DUPLEX
|
DO_NOT_FORCE_LINK_FAIL
|
SERIAL_PORT_CONTROL_RESERVED
;
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr
);
pscr
|=
SERIAL_PORT_ENABLE
;
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr
);
wrl
(
mp
,
SDMA_CONFIG
(
mp
->
port_num
),
PORT_SDMA_CONFIG_DEFAULT_VALUE
);
/*
* Perform PHY reset, if there is a PHY.
*/
...
...
@@ -1828,22 +1893,32 @@ static void port_start(struct mv643xx_eth_private *mp)
mv643xx_eth_set_settings
(
mp
->
dev
,
&
cmd
);
}
/*
* Configure basic link parameters.
*/
pscr
=
rdl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
));
pscr
|=
SERIAL_PORT_ENABLE
;
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr
);
pscr
|=
DO_NOT_FORCE_LINK_FAIL
;
if
(
mp
->
phy_addr
==
-
1
)
pscr
|=
FORCE_LINK_PASS
;
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr
);
wrl
(
mp
,
SDMA_CONFIG
(
mp
->
port_num
),
PORT_SDMA_CONFIG_DEFAULT_VALUE
);
/*
* Configure TX path and queues.
*/
tx_set_rate
(
mp
,
1000000000
,
16777216
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
struct
tx_queue
*
txq
=
mp
->
txq
+
i
;
int
off
=
TXQ_CURRENT_DESC_PTR
(
mp
->
port_num
,
i
);
u32
addr
;
if
((
mp
->
txq_mask
&
(
1
<<
i
))
==
0
)
continue
;
addr
=
(
u32
)
txq
->
tx_desc_dma
;
addr
+=
txq
->
tx_curr_desc
*
sizeof
(
struct
tx_desc
);
wrl
(
mp
,
off
,
addr
);
txq_reset_hw_ptr
(
txq
);
txq_set_rate
(
txq
,
1000000000
,
16777216
);
txq_set_fixed_prio_mode
(
txq
);
}
...
...
@@ -1965,6 +2040,9 @@ static int mv643xx_eth_open(struct net_device *dev)
napi_enable
(
&
mp
->
napi
);
#endif
netif_carrier_off
(
dev
);
netif_stop_queue
(
dev
);
port_start
(
mp
);
set_rx_coal
(
mp
,
0
);
...
...
@@ -1999,8 +2077,14 @@ static void port_reset(struct mv643xx_eth_private *mp)
if
(
mp
->
txq_mask
&
(
1
<<
i
))
txq_disable
(
mp
->
txq
+
i
);
}
while
(
!
(
rdl
(
mp
,
PORT_STATUS
(
mp
->
port_num
))
&
TX_FIFO_EMPTY
))
while
(
1
)
{
u32
ps
=
rdl
(
mp
,
PORT_STATUS
(
mp
->
port_num
));
if
((
ps
&
(
TX_IN_PROGRESS
|
TX_FIFO_EMPTY
))
==
TX_FIFO_EMPTY
)
break
;
udelay
(
10
);
}
/* Reset the Enable bit in the Configuration Register */
data
=
rdl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
));
...
...
@@ -2202,7 +2286,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
int
ret
;
if
(
!
mv643xx_eth_version_printed
++
)
printk
(
KERN_NOTICE
"MV-643xx 10/100/1000 Ethernet Driver
\n
"
);
printk
(
KERN_NOTICE
"MV-643xx 10/100/1000 ethernet "
"driver version %s
\n
"
,
mv643xx_eth_driver_version
);
ret
=
-
EINVAL
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
...
...
@@ -2338,14 +2423,14 @@ static int phy_detect(struct mv643xx_eth_private *mp)
unsigned
int
data
;
unsigned
int
data2
;
smi_reg_read
(
mp
,
mp
->
phy_addr
,
0
,
&
data
);
smi_reg_write
(
mp
,
mp
->
phy_addr
,
0
,
data
^
0x1000
);
smi_reg_read
(
mp
,
mp
->
phy_addr
,
MII_BMCR
,
&
data
);
smi_reg_write
(
mp
,
mp
->
phy_addr
,
MII_BMCR
,
data
^
BMCR_ANENABLE
);
smi_reg_read
(
mp
,
mp
->
phy_addr
,
0
,
&
data2
);
if
(((
data
^
data2
)
&
0x1000
)
==
0
)
smi_reg_read
(
mp
,
mp
->
phy_addr
,
MII_BMCR
,
&
data2
);
if
(((
data
^
data2
)
&
BMCR_ANENABLE
)
==
0
)
return
-
ENODEV
;
smi_reg_write
(
mp
,
mp
->
phy_addr
,
0
,
data
);
smi_reg_write
(
mp
,
mp
->
phy_addr
,
MII_BMCR
,
data
);
return
0
;
}
...
...
@@ -2393,12 +2478,39 @@ static int phy_init(struct mv643xx_eth_private *mp,
cmd
.
duplex
=
pd
->
duplex
;
}
update_pscr
(
mp
,
cmd
.
speed
,
cmd
.
duplex
);
mv643xx_eth_set_settings
(
mp
->
dev
,
&
cmd
);
return
0
;
}
static
void
init_pscr
(
struct
mv643xx_eth_private
*
mp
,
int
speed
,
int
duplex
)
{
u32
pscr
;
pscr
=
rdl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
));
if
(
pscr
&
SERIAL_PORT_ENABLE
)
{
pscr
&=
~
SERIAL_PORT_ENABLE
;
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr
);
}
pscr
=
MAX_RX_PACKET_9700BYTE
|
SERIAL_PORT_CONTROL_RESERVED
;
if
(
mp
->
phy_addr
==
-
1
)
{
pscr
|=
DISABLE_AUTO_NEG_SPEED_GMII
;
if
(
speed
==
SPEED_1000
)
pscr
|=
SET_GMII_SPEED_TO_1000
;
else
if
(
speed
==
SPEED_100
)
pscr
|=
SET_MII_SPEED_TO_100
;
pscr
|=
DISABLE_AUTO_NEG_FOR_FLOW_CTRL
;
pscr
|=
DISABLE_AUTO_NEG_FOR_DUPLEX
;
if
(
duplex
==
DUPLEX_FULL
)
pscr
|=
SET_FULL_DUPLEX_MODE
;
}
wrl
(
mp
,
PORT_SERIAL_CONTROL
(
mp
->
port_num
),
pscr
);
}
static
int
mv643xx_eth_probe
(
struct
platform_device
*
pdev
)
{
struct
mv643xx_eth_platform_data
*
pd
;
...
...
@@ -2452,6 +2564,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
}
else
{
SET_ETHTOOL_OPS
(
dev
,
&
mv643xx_eth_ethtool_ops_phyless
);
}
init_pscr
(
mp
,
pd
->
speed
,
pd
->
duplex
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_IRQ
,
0
);
...
...
@@ -2478,6 +2591,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
* have to map the buffers to ISA memory which is only 16 MB
*/
dev
->
features
=
NETIF_F_SG
|
NETIF_F_IP_CSUM
;
dev
->
vlan_features
=
NETIF_F_SG
|
NETIF_F_IP_CSUM
;
#endif
SET_NETDEV_DEV
(
dev
,
&
pdev
->
dev
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录