Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
45993653
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
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看板
提交
45993653
编写于
1月 19, 2011
作者:
U
Uwe Kleine-König
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
net/fec: reorder functions a bit allows removing forward declarations
Signed-off-by:
N
Uwe Kleine-König
<
u.kleine-koenig@pengutronix.de
>
上级
db8880bc
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
174 addition
and
179 deletion
+174
-179
drivers/net/fec.c
drivers/net/fec.c
+174
-179
未找到文件。
drivers/net/fec.c
浏览文件 @
45993653
...
...
@@ -205,13 +205,6 @@ struct fec_enet_private {
struct
completion
mdio_done
;
};
static
irqreturn_t
fec_enet_interrupt
(
int
irq
,
void
*
dev_id
);
static
void
fec_enet_tx
(
struct
net_device
*
ndev
);
static
void
fec_enet_rx
(
struct
net_device
*
ndev
);
static
int
fec_enet_close
(
struct
net_device
*
ndev
);
static
void
fec_restart
(
struct
net_device
*
ndev
,
int
duplex
);
static
void
fec_stop
(
struct
net_device
*
ndev
);
/* FEC MII MMFR bits definition */
#define FEC_MMFR_ST (1 << 30)
#define FEC_MMFR_OP_READ (2 << 28)
...
...
@@ -335,53 +328,159 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return
NETDEV_TX_OK
;
}
/* This function is called to start or restart the FEC during a link
* change. This only happens when switching between half and full
* duplex.
*/
static
void
fec_
timeout
(
struct
net_device
*
ndev
)
fec_
restart
(
struct
net_device
*
ndev
,
int
duplex
)
{
struct
fec_enet_private
*
fep
=
netdev_priv
(
ndev
);
const
struct
platform_device_id
*
id_entry
=
platform_get_device_id
(
fep
->
pdev
);
int
i
;
u32
val
,
temp_mac
[
2
];
ndev
->
stats
.
tx_errors
++
;
/* Whack a reset. We should wait for this. */
writel
(
1
,
fep
->
hwp
+
FEC_ECNTRL
);
udelay
(
10
);
fec_restart
(
ndev
,
fep
->
full_duplex
);
netif_wake_queue
(
ndev
);
}
/*
* enet-mac reset will reset mac address registers too,
* so need to reconfigure it.
*/
if
(
id_entry
->
driver_data
&
FEC_QUIRK_ENET_MAC
)
{
memcpy
(
&
temp_mac
,
ndev
->
dev_addr
,
ETH_ALEN
);
writel
(
cpu_to_be32
(
temp_mac
[
0
]),
fep
->
hwp
+
FEC_ADDR_LOW
);
writel
(
cpu_to_be32
(
temp_mac
[
1
]),
fep
->
hwp
+
FEC_ADDR_HIGH
);
}
static
irqreturn_t
fec_enet_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
net_device
*
ndev
=
dev_id
;
struct
fec_enet_private
*
fep
=
netdev_priv
(
ndev
);
uint
int_events
;
irqreturn_t
ret
=
IRQ_NONE
;
/* Clear any outstanding interrupt. */
writel
(
0xffc00000
,
fep
->
hwp
+
FEC_IEVENT
);
do
{
int_events
=
readl
(
fep
->
hwp
+
FEC_IEVENT
);
writel
(
int_events
,
fep
->
hwp
+
FEC_IEVENT
);
/* Reset all multicast. */
writel
(
0
,
fep
->
hwp
+
FEC_GRP_HASH_TABLE_HIGH
);
writel
(
0
,
fep
->
hwp
+
FEC_GRP_HASH_TABLE_LOW
);
#ifndef CONFIG_M5272
writel
(
0
,
fep
->
hwp
+
FEC_HASH_TABLE_HIGH
);
writel
(
0
,
fep
->
hwp
+
FEC_HASH_TABLE_LOW
);
#endif
if
(
int_events
&
FEC_ENET_RXF
)
{
ret
=
IRQ_HANDLED
;
fec_enet_rx
(
ndev
);
}
/* Set maximum receive buffer size. */
writel
(
PKT_MAXBLR_SIZE
,
fep
->
hwp
+
FEC_R_BUFF_SIZE
);
/* Transmit OK, or non-fatal error. Update the buffer
* descriptors. FEC handles all errors, we just discover
* them as part of the transmit process.
*/
if
(
int_events
&
FEC_ENET_TXF
)
{
ret
=
IRQ_HANDLED
;
fec_enet_tx
(
ndev
);
/* Set receive and transmit descriptor base. */
writel
(
fep
->
bd_dma
,
fep
->
hwp
+
FEC_R_DES_START
);
writel
((
unsigned
long
)
fep
->
bd_dma
+
sizeof
(
struct
bufdesc
)
*
RX_RING_SIZE
,
fep
->
hwp
+
FEC_X_DES_START
);
fep
->
dirty_tx
=
fep
->
cur_tx
=
fep
->
tx_bd_base
;
fep
->
cur_rx
=
fep
->
rx_bd_base
;
/* Reset SKB transmit buffers. */
fep
->
skb_cur
=
fep
->
skb_dirty
=
0
;
for
(
i
=
0
;
i
<=
TX_RING_MOD_MASK
;
i
++
)
{
if
(
fep
->
tx_skbuff
[
i
])
{
dev_kfree_skb_any
(
fep
->
tx_skbuff
[
i
]);
fep
->
tx_skbuff
[
i
]
=
NULL
;
}
}
if
(
int_events
&
FEC_ENET_MII
)
{
ret
=
IRQ_HANDLED
;
complete
(
&
fep
->
mdio_done
);
/* Enable MII mode */
if
(
duplex
)
{
/* MII enable / FD enable */
writel
(
OPT_FRAME_SIZE
|
0x04
,
fep
->
hwp
+
FEC_R_CNTRL
);
writel
(
0x04
,
fep
->
hwp
+
FEC_X_CNTRL
);
}
else
{
/* MII enable / No Rcv on Xmit */
writel
(
OPT_FRAME_SIZE
|
0x06
,
fep
->
hwp
+
FEC_R_CNTRL
);
writel
(
0x0
,
fep
->
hwp
+
FEC_X_CNTRL
);
}
fep
->
full_duplex
=
duplex
;
/* Set MII speed */
writel
(
fep
->
phy_speed
,
fep
->
hwp
+
FEC_MII_SPEED
);
/*
* The phy interface and speed need to get configured
* differently on enet-mac.
*/
if
(
id_entry
->
driver_data
&
FEC_QUIRK_ENET_MAC
)
{
val
=
readl
(
fep
->
hwp
+
FEC_R_CNTRL
);
/* MII or RMII */
if
(
fep
->
phy_interface
==
PHY_INTERFACE_MODE_RMII
)
val
|=
(
1
<<
8
);
else
val
&=
~
(
1
<<
8
);
/* 10M or 100M */
if
(
fep
->
phy_dev
&&
fep
->
phy_dev
->
speed
==
SPEED_100
)
val
&=
~
(
1
<<
9
);
else
val
|=
(
1
<<
9
);
writel
(
val
,
fep
->
hwp
+
FEC_R_CNTRL
);
}
else
{
#ifdef FEC_MIIGSK_ENR
if
(
fep
->
phy_interface
==
PHY_INTERFACE_MODE_RMII
)
{
/* disable the gasket and wait */
writel
(
0
,
fep
->
hwp
+
FEC_MIIGSK_ENR
);
while
(
readl
(
fep
->
hwp
+
FEC_MIIGSK_ENR
)
&
4
)
udelay
(
1
);
/*
* configure the gasket:
* RMII, 50 MHz, no loopback, no echo
*/
writel
(
1
,
fep
->
hwp
+
FEC_MIIGSK_CFGR
);
/* re-enable the gasket */
writel
(
2
,
fep
->
hwp
+
FEC_MIIGSK_ENR
);
}
}
while
(
int_events
);
#endif
}
return
ret
;
/* And last, enable the transmit and receive processing */
writel
(
2
,
fep
->
hwp
+
FEC_ECNTRL
);
writel
(
0
,
fep
->
hwp
+
FEC_R_DES_ACTIVE
);
/* Enable interrupts we wish to service */
writel
(
FEC_DEFAULT_IMASK
,
fep
->
hwp
+
FEC_IMASK
);
}
static
void
fec_stop
(
struct
net_device
*
ndev
)
{
struct
fec_enet_private
*
fep
=
netdev_priv
(
ndev
);
/* We cannot expect a graceful transmit stop without link !!! */
if
(
fep
->
link
)
{
writel
(
1
,
fep
->
hwp
+
FEC_X_CNTRL
);
/* Graceful transmit stop */
udelay
(
10
);
if
(
!
(
readl
(
fep
->
hwp
+
FEC_IEVENT
)
&
FEC_ENET_GRA
))
printk
(
"fec_stop : Graceful transmit stop did not complete !
\n
"
);
}
/* Whack a reset. We should wait for this. */
writel
(
1
,
fep
->
hwp
+
FEC_ECNTRL
);
udelay
(
10
);
writel
(
fep
->
phy_speed
,
fep
->
hwp
+
FEC_MII_SPEED
);
writel
(
FEC_DEFAULT_IMASK
,
fep
->
hwp
+
FEC_IMASK
);
}
static
void
fec_timeout
(
struct
net_device
*
ndev
)
{
struct
fec_enet_private
*
fep
=
netdev_priv
(
ndev
);
ndev
->
stats
.
tx_errors
++
;
fec_restart
(
ndev
,
fep
->
full_duplex
);
netif_wake_queue
(
ndev
);
}
static
void
fec_enet_tx
(
struct
net_device
*
ndev
)
{
...
...
@@ -576,6 +675,43 @@ fec_enet_rx(struct net_device *ndev)
spin_unlock
(
&
fep
->
hw_lock
);
}
static
irqreturn_t
fec_enet_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
net_device
*
ndev
=
dev_id
;
struct
fec_enet_private
*
fep
=
netdev_priv
(
ndev
);
uint
int_events
;
irqreturn_t
ret
=
IRQ_NONE
;
do
{
int_events
=
readl
(
fep
->
hwp
+
FEC_IEVENT
);
writel
(
int_events
,
fep
->
hwp
+
FEC_IEVENT
);
if
(
int_events
&
FEC_ENET_RXF
)
{
ret
=
IRQ_HANDLED
;
fec_enet_rx
(
ndev
);
}
/* Transmit OK, or non-fatal error. Update the buffer
* descriptors. FEC handles all errors, we just discover
* them as part of the transmit process.
*/
if
(
int_events
&
FEC_ENET_TXF
)
{
ret
=
IRQ_HANDLED
;
fec_enet_tx
(
ndev
);
}
if
(
int_events
&
FEC_ENET_MII
)
{
ret
=
IRQ_HANDLED
;
complete
(
&
fep
->
mdio_done
);
}
}
while
(
int_events
);
return
ret
;
}
/* ------------------------------------------------------------------------- */
static
void
__inline__
fec_get_mac
(
struct
net_device
*
ndev
)
{
...
...
@@ -1217,147 +1353,6 @@ static int fec_enet_init(struct net_device *ndev)
return
0
;
}
/* This function is called to start or restart the FEC during a link
* change. This only happens when switching between half and full
* duplex.
*/
static
void
fec_restart
(
struct
net_device
*
ndev
,
int
duplex
)
{
struct
fec_enet_private
*
fep
=
netdev_priv
(
ndev
);
const
struct
platform_device_id
*
id_entry
=
platform_get_device_id
(
fep
->
pdev
);
int
i
;
u32
val
,
temp_mac
[
2
];
/* Whack a reset. We should wait for this. */
writel
(
1
,
fep
->
hwp
+
FEC_ECNTRL
);
udelay
(
10
);
/*
* enet-mac reset will reset mac address registers too,
* so need to reconfigure it.
*/
if
(
id_entry
->
driver_data
&
FEC_QUIRK_ENET_MAC
)
{
memcpy
(
&
temp_mac
,
ndev
->
dev_addr
,
ETH_ALEN
);
writel
(
cpu_to_be32
(
temp_mac
[
0
]),
fep
->
hwp
+
FEC_ADDR_LOW
);
writel
(
cpu_to_be32
(
temp_mac
[
1
]),
fep
->
hwp
+
FEC_ADDR_HIGH
);
}
/* Clear any outstanding interrupt. */
writel
(
0xffc00000
,
fep
->
hwp
+
FEC_IEVENT
);
/* Reset all multicast. */
writel
(
0
,
fep
->
hwp
+
FEC_GRP_HASH_TABLE_HIGH
);
writel
(
0
,
fep
->
hwp
+
FEC_GRP_HASH_TABLE_LOW
);
#ifndef CONFIG_M5272
writel
(
0
,
fep
->
hwp
+
FEC_HASH_TABLE_HIGH
);
writel
(
0
,
fep
->
hwp
+
FEC_HASH_TABLE_LOW
);
#endif
/* Set maximum receive buffer size. */
writel
(
PKT_MAXBLR_SIZE
,
fep
->
hwp
+
FEC_R_BUFF_SIZE
);
/* Set receive and transmit descriptor base. */
writel
(
fep
->
bd_dma
,
fep
->
hwp
+
FEC_R_DES_START
);
writel
((
unsigned
long
)
fep
->
bd_dma
+
sizeof
(
struct
bufdesc
)
*
RX_RING_SIZE
,
fep
->
hwp
+
FEC_X_DES_START
);
fep
->
dirty_tx
=
fep
->
cur_tx
=
fep
->
tx_bd_base
;
fep
->
cur_rx
=
fep
->
rx_bd_base
;
/* Reset SKB transmit buffers. */
fep
->
skb_cur
=
fep
->
skb_dirty
=
0
;
for
(
i
=
0
;
i
<=
TX_RING_MOD_MASK
;
i
++
)
{
if
(
fep
->
tx_skbuff
[
i
])
{
dev_kfree_skb_any
(
fep
->
tx_skbuff
[
i
]);
fep
->
tx_skbuff
[
i
]
=
NULL
;
}
}
/* Enable MII mode */
if
(
duplex
)
{
/* MII enable / FD enable */
writel
(
OPT_FRAME_SIZE
|
0x04
,
fep
->
hwp
+
FEC_R_CNTRL
);
writel
(
0x04
,
fep
->
hwp
+
FEC_X_CNTRL
);
}
else
{
/* MII enable / No Rcv on Xmit */
writel
(
OPT_FRAME_SIZE
|
0x06
,
fep
->
hwp
+
FEC_R_CNTRL
);
writel
(
0x0
,
fep
->
hwp
+
FEC_X_CNTRL
);
}
fep
->
full_duplex
=
duplex
;
/* Set MII speed */
writel
(
fep
->
phy_speed
,
fep
->
hwp
+
FEC_MII_SPEED
);
/*
* The phy interface and speed need to get configured
* differently on enet-mac.
*/
if
(
id_entry
->
driver_data
&
FEC_QUIRK_ENET_MAC
)
{
val
=
readl
(
fep
->
hwp
+
FEC_R_CNTRL
);
/* MII or RMII */
if
(
fep
->
phy_interface
==
PHY_INTERFACE_MODE_RMII
)
val
|=
(
1
<<
8
);
else
val
&=
~
(
1
<<
8
);
/* 10M or 100M */
if
(
fep
->
phy_dev
&&
fep
->
phy_dev
->
speed
==
SPEED_100
)
val
&=
~
(
1
<<
9
);
else
val
|=
(
1
<<
9
);
writel
(
val
,
fep
->
hwp
+
FEC_R_CNTRL
);
}
else
{
#ifdef FEC_MIIGSK_ENR
if
(
fep
->
phy_interface
==
PHY_INTERFACE_MODE_RMII
)
{
/* disable the gasket and wait */
writel
(
0
,
fep
->
hwp
+
FEC_MIIGSK_ENR
);
while
(
readl
(
fep
->
hwp
+
FEC_MIIGSK_ENR
)
&
4
)
udelay
(
1
);
/*
* configure the gasket:
* RMII, 50 MHz, no loopback, no echo
*/
writel
(
1
,
fep
->
hwp
+
FEC_MIIGSK_CFGR
);
/* re-enable the gasket */
writel
(
2
,
fep
->
hwp
+
FEC_MIIGSK_ENR
);
}
#endif
}
/* And last, enable the transmit and receive processing */
writel
(
2
,
fep
->
hwp
+
FEC_ECNTRL
);
writel
(
0
,
fep
->
hwp
+
FEC_R_DES_ACTIVE
);
/* Enable interrupts we wish to service */
writel
(
FEC_DEFAULT_IMASK
,
fep
->
hwp
+
FEC_IMASK
);
}
static
void
fec_stop
(
struct
net_device
*
ndev
)
{
struct
fec_enet_private
*
fep
=
netdev_priv
(
ndev
);
/* We cannot expect a graceful transmit stop without link !!! */
if
(
fep
->
link
)
{
writel
(
1
,
fep
->
hwp
+
FEC_X_CNTRL
);
/* Graceful transmit stop */
udelay
(
10
);
if
(
!
(
readl
(
fep
->
hwp
+
FEC_IEVENT
)
&
FEC_ENET_GRA
))
printk
(
"fec_stop : Graceful transmit stop did not complete !
\n
"
);
}
/* Whack a reset. We should wait for this. */
writel
(
1
,
fep
->
hwp
+
FEC_ECNTRL
);
udelay
(
10
);
writel
(
fep
->
phy_speed
,
fep
->
hwp
+
FEC_MII_SPEED
);
writel
(
FEC_DEFAULT_IMASK
,
fep
->
hwp
+
FEC_IMASK
);
}
static
int
__devinit
fec_probe
(
struct
platform_device
*
pdev
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录