Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
acb96956
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看板
提交
acb96956
编写于
5月 25, 2005
作者:
提交者:
Jeff Garzik
5月 25, 2005
浏览文件
操作
浏览文件
下载
差异文件
Automatic merge of /spare/repo/netdev-2.6 branch forcedeth
上级
ee03a68c
22c6d143
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
86 addition
and
17 deletion
+86
-17
drivers/net/forcedeth.c
drivers/net/forcedeth.c
+86
-17
未找到文件。
drivers/net/forcedeth.c
浏览文件 @
acb96956
...
...
@@ -81,6 +81,7 @@
* cause DMA to kfree'd memory.
* 0.31: 14 Nov 2004: ethtool support for getting/setting link
* capabilities.
* 0.32: 16 Apr 2005: RX_ERROR4 handling added.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
...
...
@@ -92,7 +93,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
#define FORCEDETH_VERSION "0.3
1
"
#define FORCEDETH_VERSION "0.3
2
"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
...
...
@@ -109,6 +110,7 @@
#include <linux/mii.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/if_vlan.h>
#include <asm/irq.h>
#include <asm/io.h>
...
...
@@ -1013,6 +1015,59 @@ static void nv_tx_timeout(struct net_device *dev)
spin_unlock_irq
(
&
np
->
lock
);
}
/*
* Called when the nic notices a mismatch between the actual data len on the
* wire and the len indicated in the 802 header
*/
static
int
nv_getlen
(
struct
net_device
*
dev
,
void
*
packet
,
int
datalen
)
{
int
hdrlen
;
/* length of the 802 header */
int
protolen
;
/* length as stored in the proto field */
/* 1) calculate len according to header */
if
(
((
struct
vlan_ethhdr
*
)
packet
)
->
h_vlan_proto
==
__constant_htons
(
ETH_P_8021Q
))
{
protolen
=
ntohs
(
((
struct
vlan_ethhdr
*
)
packet
)
->
h_vlan_encapsulated_proto
);
hdrlen
=
VLAN_HLEN
;
}
else
{
protolen
=
ntohs
(
((
struct
ethhdr
*
)
packet
)
->
h_proto
);
hdrlen
=
ETH_HLEN
;
}
dprintk
(
KERN_DEBUG
"%s: nv_getlen: datalen %d, protolen %d, hdrlen %d
\n
"
,
dev
->
name
,
datalen
,
protolen
,
hdrlen
);
if
(
protolen
>
ETH_DATA_LEN
)
return
datalen
;
/* Value in proto field not a len, no checks possible */
protolen
+=
hdrlen
;
/* consistency checks: */
if
(
datalen
>
ETH_ZLEN
)
{
if
(
datalen
>=
protolen
)
{
/* more data on wire than in 802 header, trim of
* additional data.
*/
dprintk
(
KERN_DEBUG
"%s: nv_getlen: accepting %d bytes.
\n
"
,
dev
->
name
,
protolen
);
return
protolen
;
}
else
{
/* less data on wire than mentioned in header.
* Discard the packet.
*/
dprintk
(
KERN_DEBUG
"%s: nv_getlen: discarding long packet.
\n
"
,
dev
->
name
);
return
-
1
;
}
}
else
{
/* short packet. Accept only if 802 values are also short */
if
(
protolen
>
ETH_ZLEN
)
{
dprintk
(
KERN_DEBUG
"%s: nv_getlen: discarding short packet.
\n
"
,
dev
->
name
);
return
-
1
;
}
dprintk
(
KERN_DEBUG
"%s: nv_getlen: accepting %d bytes.
\n
"
,
dev
->
name
,
datalen
);
return
datalen
;
}
}
static
void
nv_rx_process
(
struct
net_device
*
dev
)
{
struct
fe_priv
*
np
=
get_nvpriv
(
dev
);
...
...
@@ -1064,7 +1119,7 @@ static void nv_rx_process(struct net_device *dev)
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
if
(
Flags
&
(
NV_RX_ERROR1
|
NV_RX_ERROR2
|
NV_RX_ERROR3
|
NV_RX_ERROR4
))
{
if
(
Flags
&
(
NV_RX_ERROR1
|
NV_RX_ERROR2
|
NV_RX_ERROR3
))
{
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
...
...
@@ -1078,22 +1133,24 @@ static void nv_rx_process(struct net_device *dev)
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
if
(
Flags
&
NV_RX_ERROR
)
{
/* framing errors are soft errors, the rest is fatal. */
if
(
Flags
&
NV_RX_ERROR4
)
{
len
=
nv_getlen
(
dev
,
np
->
rx_skbuff
[
i
]
->
data
,
len
);
if
(
len
<
0
)
{
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
}
/* framing errors are soft errors. */
if
(
Flags
&
NV_RX_FRAMINGERR
)
{
if
(
Flags
&
NV_RX_SUBSTRACT1
)
{
len
--
;
}
}
else
{
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
}
}
else
{
if
(
!
(
Flags
&
NV_RX2_DESCRIPTORVALID
))
goto
next_pkt
;
if
(
Flags
&
(
NV_RX2_ERROR1
|
NV_RX2_ERROR2
|
NV_RX2_ERROR3
|
NV_RX2_ERROR4
))
{
if
(
Flags
&
(
NV_RX2_ERROR1
|
NV_RX2_ERROR2
|
NV_RX2_ERROR3
))
{
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
...
...
@@ -1107,16 +1164,18 @@ static void nv_rx_process(struct net_device *dev)
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
if
(
Flags
&
NV_RX2_ERROR
)
{
/* framing errors are soft errors, the rest is fatal. */
if
(
Flags
&
NV_RX2_ERROR4
)
{
len
=
nv_getlen
(
dev
,
np
->
rx_skbuff
[
i
]
->
data
,
len
);
if
(
len
<
0
)
{
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
}
/* framing errors are soft errors */
if
(
Flags
&
NV_RX2_FRAMINGERR
)
{
if
(
Flags
&
NV_RX2_SUBSTRACT1
)
{
len
--
;
}
}
else
{
np
->
stats
.
rx_errors
++
;
goto
next_pkt
;
}
}
Flags
&=
NV_RX2_CHECKSUMMASK
;
if
(
Flags
==
NV_RX2_CHECKSUMOK1
||
...
...
@@ -1480,6 +1539,13 @@ static void nv_do_nic_poll(unsigned long data)
enable_irq
(
dev
->
irq
);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
static
void
nv_poll_controller
(
struct
net_device
*
dev
)
{
nv_do_nic_poll
((
unsigned
long
)
dev
);
}
#endif
static
void
nv_get_drvinfo
(
struct
net_device
*
dev
,
struct
ethtool_drvinfo
*
info
)
{
struct
fe_priv
*
np
=
get_nvpriv
(
dev
);
...
...
@@ -1962,6 +2028,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev
->
get_stats
=
nv_get_stats
;
dev
->
change_mtu
=
nv_change_mtu
;
dev
->
set_multicast_list
=
nv_set_multicast
;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev
->
poll_controller
=
nv_poll_controller
;
#endif
SET_ETHTOOL_OPS
(
dev
,
&
ops
);
dev
->
tx_timeout
=
nv_tx_timeout
;
dev
->
watchdog_timeo
=
NV_WATCHDOG_TIMEO
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录