Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
10d1e8ca
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
10d1e8ca
编写于
7月 14, 2011
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
上级
cd0d7228
ff79c8ac
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
152 addition
and
99 deletion
+152
-99
drivers/net/sfc/Kconfig
drivers/net/sfc/Kconfig
+3
-4
drivers/net/sfc/efx.c
drivers/net/sfc/efx.c
+23
-37
drivers/net/sfc/enum.h
drivers/net/sfc/enum.h
+2
-1
drivers/net/sfc/ethtool.c
drivers/net/sfc/ethtool.c
+5
-22
drivers/net/sfc/falcon.c
drivers/net/sfc/falcon.c
+48
-3
drivers/net/sfc/filter.c
drivers/net/sfc/filter.c
+26
-19
drivers/net/sfc/net_driver.h
drivers/net/sfc/net_driver.h
+6
-5
drivers/net/sfc/siena.c
drivers/net/sfc/siena.c
+39
-8
未找到文件。
drivers/net/sfc/Kconfig
浏览文件 @
10d1e8ca
config SFC
config SFC
tristate "Solarflare S
olarstorm S
FC4000/SFC9000-family support"
tristate "Solarflare SFC4000/SFC9000-family support"
depends on PCI && INET
depends on PCI && INET
select MDIO
select MDIO
select CRC32
select CRC32
...
@@ -7,13 +7,12 @@ config SFC
...
@@ -7,13 +7,12 @@ config SFC
select I2C_ALGOBIT
select I2C_ALGOBIT
help
help
This driver supports 10-gigabit Ethernet cards based on
This driver supports 10-gigabit Ethernet cards based on
the Solarflare Communications Solarstorm SFC4000 and
the Solarflare SFC4000 and SFC9000-family controllers.
SFC9000-family controllers.
To compile this driver as a module, choose M here. The module
To compile this driver as a module, choose M here. The module
will be called sfc.
will be called sfc.
config SFC_MTD
config SFC_MTD
bool "Solarflare S
olarstorm S
FC4000/SFC9000-family MTD support"
bool "Solarflare SFC4000/SFC9000-family MTD support"
depends on SFC && MTD && !(SFC=y && MTD=m)
depends on SFC && MTD && !(SFC=y && MTD=m)
default y
default y
help
help
...
...
drivers/net/sfc/efx.c
浏览文件 @
10d1e8ca
...
@@ -229,8 +229,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
...
@@ -229,8 +229,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
struct
efx_nic
*
efx
=
channel
->
efx
;
struct
efx_nic
*
efx
=
channel
->
efx
;
int
spent
;
int
spent
;
if
(
unlikely
(
efx
->
reset_pending
!=
RESET_TYPE_NONE
||
if
(
unlikely
(
efx
->
reset_pending
||
!
channel
->
enabled
))
!
channel
->
enabled
))
return
0
;
return
0
;
spent
=
efx_nic_process_eventq
(
channel
,
budget
);
spent
=
efx_nic_process_eventq
(
channel
,
budget
);
...
@@ -1461,7 +1460,7 @@ static void efx_start_all(struct efx_nic *efx)
...
@@ -1461,7 +1460,7 @@ static void efx_start_all(struct efx_nic *efx)
* reset_pending [modified from an atomic context], we instead guarantee
* reset_pending [modified from an atomic context], we instead guarantee
* that efx_mcdi_mode_poll() isn't reverted erroneously */
* that efx_mcdi_mode_poll() isn't reverted erroneously */
efx_mcdi_mode_event
(
efx
);
efx_mcdi_mode_event
(
efx
);
if
(
efx
->
reset_pending
!=
RESET_TYPE_NONE
)
if
(
efx
->
reset_pending
)
efx_mcdi_mode_poll
(
efx
);
efx_mcdi_mode_poll
(
efx
);
/* Start the hardware monitor if there is one. Otherwise (we're link
/* Start the hardware monitor if there is one. Otherwise (we're link
...
@@ -2118,8 +2117,10 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
...
@@ -2118,8 +2117,10 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
goto
out
;
goto
out
;
}
}
/* Allow resets to be rescheduled. */
/* Clear flags for the scopes we covered. We assume the NIC and
efx
->
reset_pending
=
RESET_TYPE_NONE
;
* driver are now quiescent so that there is no race here.
*/
efx
->
reset_pending
&=
-
(
1
<<
(
method
+
1
));
/* Reinitialise bus-mastering, which may have been turned off before
/* Reinitialise bus-mastering, which may have been turned off before
* the reset was scheduled. This is still appropriate, even in the
* the reset was scheduled. This is still appropriate, even in the
...
@@ -2154,12 +2155,13 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
...
@@ -2154,12 +2155,13 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
static
void
efx_reset_work
(
struct
work_struct
*
data
)
static
void
efx_reset_work
(
struct
work_struct
*
data
)
{
{
struct
efx_nic
*
efx
=
container_of
(
data
,
struct
efx_nic
,
reset_work
);
struct
efx_nic
*
efx
=
container_of
(
data
,
struct
efx_nic
,
reset_work
);
unsigned
long
pending
=
ACCESS_ONCE
(
efx
->
reset_pending
);
if
(
efx
->
reset_pending
==
RESET_TYPE_NONE
)
if
(
!
pending
)
return
;
return
;
/* If we're not RUNNING then don't reset. Leave the reset_pending
/* If we're not RUNNING then don't reset. Leave the reset_pending
* flag set so that efx_pci_probe_main will be retried */
* flag
s
set so that efx_pci_probe_main will be retried */
if
(
efx
->
state
!=
STATE_RUNNING
)
{
if
(
efx
->
state
!=
STATE_RUNNING
)
{
netif_info
(
efx
,
drv
,
efx
->
net_dev
,
netif_info
(
efx
,
drv
,
efx
->
net_dev
,
"scheduled reset quenched. NIC not RUNNING
\n
"
);
"scheduled reset quenched. NIC not RUNNING
\n
"
);
...
@@ -2167,7 +2169,7 @@ static void efx_reset_work(struct work_struct *data)
...
@@ -2167,7 +2169,7 @@ static void efx_reset_work(struct work_struct *data)
}
}
rtnl_lock
();
rtnl_lock
();
(
void
)
efx_reset
(
efx
,
efx
->
reset_pending
);
(
void
)
efx_reset
(
efx
,
fls
(
pending
)
-
1
);
rtnl_unlock
();
rtnl_unlock
();
}
}
...
@@ -2175,40 +2177,24 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
...
@@ -2175,40 +2177,24 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
{
{
enum
reset_type
method
;
enum
reset_type
method
;
if
(
efx
->
reset_pending
!=
RESET_TYPE_NONE
)
{
netif_info
(
efx
,
drv
,
efx
->
net_dev
,
"quenching already scheduled reset
\n
"
);
return
;
}
switch
(
type
)
{
switch
(
type
)
{
case
RESET_TYPE_INVISIBLE
:
case
RESET_TYPE_INVISIBLE
:
case
RESET_TYPE_ALL
:
case
RESET_TYPE_ALL
:
case
RESET_TYPE_WORLD
:
case
RESET_TYPE_WORLD
:
case
RESET_TYPE_DISABLE
:
case
RESET_TYPE_DISABLE
:
method
=
type
;
method
=
type
;
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"scheduling %s reset
\n
"
,
RESET_TYPE
(
method
));
break
;
break
;
case
RESET_TYPE_RX_RECOVERY
:
case
RESET_TYPE_RX_DESC_FETCH
:
case
RESET_TYPE_TX_DESC_FETCH
:
case
RESET_TYPE_TX_SKIP
:
method
=
RESET_TYPE_INVISIBLE
;
break
;
case
RESET_TYPE_MC_FAILURE
:
default:
default:
method
=
RESET_TYPE_ALL
;
method
=
efx
->
type
->
map_reset_reason
(
type
);
break
;
}
if
(
method
!=
type
)
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"scheduling %s reset for %s
\n
"
,
"scheduling %s reset for %s
\n
"
,
RESET_TYPE
(
method
),
RESET_TYPE
(
type
));
RESET_TYPE
(
method
),
RESET_TYPE
(
type
));
else
break
;
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"scheduling %s reset
\n
"
,
}
RESET_TYPE
(
method
));
efx
->
reset_pending
=
method
;
set_bit
(
method
,
&
efx
->
reset_pending
)
;
/* efx_process_channel() will no longer read events once a
/* efx_process_channel() will no longer read events once a
* reset is scheduled. So switch back to poll'd MCDI completions. */
* reset is scheduled. So switch back to poll'd MCDI completions. */
...
@@ -2288,7 +2274,6 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type,
...
@@ -2288,7 +2274,6 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type,
efx
->
pci_dev
=
pci_dev
;
efx
->
pci_dev
=
pci_dev
;
efx
->
msg_enable
=
debug
;
efx
->
msg_enable
=
debug
;
efx
->
state
=
STATE_INIT
;
efx
->
state
=
STATE_INIT
;
efx
->
reset_pending
=
RESET_TYPE_NONE
;
strlcpy
(
efx
->
name
,
pci_name
(
pci_dev
),
sizeof
(
efx
->
name
));
strlcpy
(
efx
->
name
,
pci_name
(
pci_dev
),
sizeof
(
efx
->
name
));
efx
->
net_dev
=
net_dev
;
efx
->
net_dev
=
net_dev
;
...
@@ -2491,7 +2476,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
...
@@ -2491,7 +2476,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
goto
fail1
;
goto
fail1
;
netif_info
(
efx
,
probe
,
efx
->
net_dev
,
netif_info
(
efx
,
probe
,
efx
->
net_dev
,
"Solarflare
Communications
NIC detected
\n
"
);
"Solarflare NIC detected
\n
"
);
/* Set up basic I/O (BAR mappings etc) */
/* Set up basic I/O (BAR mappings etc) */
rc
=
efx_init_io
(
efx
);
rc
=
efx_init_io
(
efx
);
...
@@ -2510,7 +2495,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
...
@@ -2510,7 +2495,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
cancel_work_sync
(
&
efx
->
reset_work
);
cancel_work_sync
(
&
efx
->
reset_work
);
if
(
rc
==
0
)
{
if
(
rc
==
0
)
{
if
(
efx
->
reset_pending
!=
RESET_TYPE_NONE
)
{
if
(
efx
->
reset_pending
)
{
/* If there was a scheduled reset during
/* If there was a scheduled reset during
* probe, the NIC is probably hosed anyway */
* probe, the NIC is probably hosed anyway */
efx_pci_remove_main
(
efx
);
efx_pci_remove_main
(
efx
);
...
@@ -2521,11 +2506,12 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
...
@@ -2521,11 +2506,12 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
}
}
/* Retry if a recoverably reset event has been scheduled */
/* Retry if a recoverably reset event has been scheduled */
if
((
efx
->
reset_pending
!=
RESET_TYPE_INVISIBLE
)
&&
if
(
efx
->
reset_pending
&
(
efx
->
reset_pending
!=
RESET_TYPE_ALL
))
~
(
1
<<
RESET_TYPE_INVISIBLE
|
1
<<
RESET_TYPE_ALL
)
||
!
efx
->
reset_pending
)
goto
fail3
;
goto
fail3
;
efx
->
reset_pending
=
RESET_TYPE_NONE
;
efx
->
reset_pending
=
0
;
}
}
if
(
rc
)
{
if
(
rc
)
{
...
@@ -2609,7 +2595,7 @@ static int efx_pm_poweroff(struct device *dev)
...
@@ -2609,7 +2595,7 @@ static int efx_pm_poweroff(struct device *dev)
efx
->
type
->
fini
(
efx
);
efx
->
type
->
fini
(
efx
);
efx
->
reset_pending
=
RESET_TYPE_NONE
;
efx
->
reset_pending
=
0
;
pci_save_state
(
pci_dev
);
pci_save_state
(
pci_dev
);
return
pci_set_power_state
(
pci_dev
,
PCI_D3hot
);
return
pci_set_power_state
(
pci_dev
,
PCI_D3hot
);
...
...
drivers/net/sfc/enum.h
浏览文件 @
10d1e8ca
...
@@ -134,6 +134,8 @@ enum efx_loopback_mode {
...
@@ -134,6 +134,8 @@ enum efx_loopback_mode {
* other valuesspecify reasons, which efx_schedule_reset() will choose
* other valuesspecify reasons, which efx_schedule_reset() will choose
* a method for.
* a method for.
*
*
* Reset methods are numbered in order of increasing scope.
*
* @RESET_TYPE_INVISIBLE: don't reset the PHYs or interrupts
* @RESET_TYPE_INVISIBLE: don't reset the PHYs or interrupts
* @RESET_TYPE_ALL: reset everything but PCI core blocks
* @RESET_TYPE_ALL: reset everything but PCI core blocks
* @RESET_TYPE_WORLD: reset everything, save & restore PCI config
* @RESET_TYPE_WORLD: reset everything, save & restore PCI config
...
@@ -147,7 +149,6 @@ enum efx_loopback_mode {
...
@@ -147,7 +149,6 @@ enum efx_loopback_mode {
* @RESET_TYPE_MC_FAILURE: MC reboot/assertion
* @RESET_TYPE_MC_FAILURE: MC reboot/assertion
*/
*/
enum
reset_type
{
enum
reset_type
{
RESET_TYPE_NONE
=
-
1
,
RESET_TYPE_INVISIBLE
=
0
,
RESET_TYPE_INVISIBLE
=
0
,
RESET_TYPE_ALL
=
1
,
RESET_TYPE_ALL
=
1
,
RESET_TYPE_WORLD
=
2
,
RESET_TYPE_WORLD
=
2
,
...
...
drivers/net/sfc/ethtool.c
浏览文件 @
10d1e8ca
...
@@ -796,30 +796,13 @@ static int efx_ethtool_set_wol(struct net_device *net_dev,
...
@@ -796,30 +796,13 @@ static int efx_ethtool_set_wol(struct net_device *net_dev,
static
int
efx_ethtool_reset
(
struct
net_device
*
net_dev
,
u32
*
flags
)
static
int
efx_ethtool_reset
(
struct
net_device
*
net_dev
,
u32
*
flags
)
{
{
struct
efx_nic
*
efx
=
netdev_priv
(
net_dev
);
struct
efx_nic
*
efx
=
netdev_priv
(
net_dev
);
enum
reset_type
method
;
int
rc
;
enum
{
ETH_RESET_EFX_INVISIBLE
=
(
ETH_RESET_DMA
|
ETH_RESET_FILTER
|
ETH_RESET_OFFLOAD
|
ETH_RESET_MAC
)
};
/* Check for minimal reset flags */
if
((
*
flags
&
ETH_RESET_EFX_INVISIBLE
)
!=
ETH_RESET_EFX_INVISIBLE
)
return
-
EINVAL
;
*
flags
^=
ETH_RESET_EFX_INVISIBLE
;
method
=
RESET_TYPE_INVISIBLE
;
if
(
*
flags
&
ETH_RESET_PHY
)
{
*
flags
^=
ETH_RESET_PHY
;
method
=
RESET_TYPE_ALL
;
}
if
((
*
flags
&
efx
->
type
->
reset_world_flags
)
==
rc
=
efx
->
type
->
map_reset_flags
(
flags
);
efx
->
type
->
reset_world_flags
)
{
if
(
rc
<
0
)
*
flags
^=
efx
->
type
->
reset_world_flags
;
return
rc
;
method
=
RESET_TYPE_WORLD
;
}
return
efx_reset
(
efx
,
method
);
return
efx_reset
(
efx
,
rc
);
}
}
static
int
static
int
...
...
drivers/net/sfc/falcon.c
浏览文件 @
10d1e8ca
...
@@ -536,7 +536,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
...
@@ -536,7 +536,7 @@ void falcon_reconfigure_mac_wrapper(struct efx_nic *efx)
efx_oword_t
reg
;
efx_oword_t
reg
;
int
link_speed
,
isolate
;
int
link_speed
,
isolate
;
isolate
=
(
efx
->
reset_pending
!=
RESET_TYPE_NONE
);
isolate
=
!!
ACCESS_ONCE
(
efx
->
reset_pending
);
switch
(
link_state
->
speed
)
{
switch
(
link_state
->
speed
)
{
case
10000
:
link_speed
=
3
;
break
;
case
10000
:
link_speed
=
3
;
break
;
...
@@ -1051,6 +1051,49 @@ static int falcon_b0_test_registers(struct efx_nic *efx)
...
@@ -1051,6 +1051,49 @@ static int falcon_b0_test_registers(struct efx_nic *efx)
**************************************************************************
**************************************************************************
*/
*/
static
enum
reset_type
falcon_map_reset_reason
(
enum
reset_type
reason
)
{
switch
(
reason
)
{
case
RESET_TYPE_RX_RECOVERY
:
case
RESET_TYPE_RX_DESC_FETCH
:
case
RESET_TYPE_TX_DESC_FETCH
:
case
RESET_TYPE_TX_SKIP
:
/* These can occasionally occur due to hardware bugs.
* We try to reset without disrupting the link.
*/
return
RESET_TYPE_INVISIBLE
;
default:
return
RESET_TYPE_ALL
;
}
}
static
int
falcon_map_reset_flags
(
u32
*
flags
)
{
enum
{
FALCON_RESET_INVISIBLE
=
(
ETH_RESET_DMA
|
ETH_RESET_FILTER
|
ETH_RESET_OFFLOAD
|
ETH_RESET_MAC
),
FALCON_RESET_ALL
=
FALCON_RESET_INVISIBLE
|
ETH_RESET_PHY
,
FALCON_RESET_WORLD
=
FALCON_RESET_ALL
|
ETH_RESET_IRQ
,
};
if
((
*
flags
&
FALCON_RESET_WORLD
)
==
FALCON_RESET_WORLD
)
{
*
flags
&=
~
FALCON_RESET_WORLD
;
return
RESET_TYPE_WORLD
;
}
if
((
*
flags
&
FALCON_RESET_ALL
)
==
FALCON_RESET_ALL
)
{
*
flags
&=
~
FALCON_RESET_ALL
;
return
RESET_TYPE_ALL
;
}
if
((
*
flags
&
FALCON_RESET_INVISIBLE
)
==
FALCON_RESET_INVISIBLE
)
{
*
flags
&=
~
FALCON_RESET_INVISIBLE
;
return
RESET_TYPE_INVISIBLE
;
}
return
-
EINVAL
;
}
/* Resets NIC to known state. This routine must be called in process
/* Resets NIC to known state. This routine must be called in process
* context and is allowed to sleep. */
* context and is allowed to sleep. */
static
int
__falcon_reset_hw
(
struct
efx_nic
*
efx
,
enum
reset_type
method
)
static
int
__falcon_reset_hw
(
struct
efx_nic
*
efx
,
enum
reset_type
method
)
...
@@ -1709,6 +1752,8 @@ const struct efx_nic_type falcon_a1_nic_type = {
...
@@ -1709,6 +1752,8 @@ const struct efx_nic_type falcon_a1_nic_type = {
.
init
=
falcon_init_nic
,
.
init
=
falcon_init_nic
,
.
fini
=
efx_port_dummy_op_void
,
.
fini
=
efx_port_dummy_op_void
,
.
monitor
=
falcon_monitor
,
.
monitor
=
falcon_monitor
,
.
map_reset_reason
=
falcon_map_reset_reason
,
.
map_reset_flags
=
falcon_map_reset_flags
,
.
reset
=
falcon_reset_hw
,
.
reset
=
falcon_reset_hw
,
.
probe_port
=
falcon_probe_port
,
.
probe_port
=
falcon_probe_port
,
.
remove_port
=
falcon_remove_port
,
.
remove_port
=
falcon_remove_port
,
...
@@ -1741,7 +1786,6 @@ const struct efx_nic_type falcon_a1_nic_type = {
...
@@ -1741,7 +1786,6 @@ const struct efx_nic_type falcon_a1_nic_type = {
.
tx_dc_base
=
0x130000
,
.
tx_dc_base
=
0x130000
,
.
rx_dc_base
=
0x100000
,
.
rx_dc_base
=
0x100000
,
.
offload_features
=
NETIF_F_IP_CSUM
,
.
offload_features
=
NETIF_F_IP_CSUM
,
.
reset_world_flags
=
ETH_RESET_IRQ
,
};
};
const
struct
efx_nic_type
falcon_b0_nic_type
=
{
const
struct
efx_nic_type
falcon_b0_nic_type
=
{
...
@@ -1750,6 +1794,8 @@ const struct efx_nic_type falcon_b0_nic_type = {
...
@@ -1750,6 +1794,8 @@ const struct efx_nic_type falcon_b0_nic_type = {
.
init
=
falcon_init_nic
,
.
init
=
falcon_init_nic
,
.
fini
=
efx_port_dummy_op_void
,
.
fini
=
efx_port_dummy_op_void
,
.
monitor
=
falcon_monitor
,
.
monitor
=
falcon_monitor
,
.
map_reset_reason
=
falcon_map_reset_reason
,
.
map_reset_flags
=
falcon_map_reset_flags
,
.
reset
=
falcon_reset_hw
,
.
reset
=
falcon_reset_hw
,
.
probe_port
=
falcon_probe_port
,
.
probe_port
=
falcon_probe_port
,
.
remove_port
=
falcon_remove_port
,
.
remove_port
=
falcon_remove_port
,
...
@@ -1791,6 +1837,5 @@ const struct efx_nic_type falcon_b0_nic_type = {
...
@@ -1791,6 +1837,5 @@ const struct efx_nic_type falcon_b0_nic_type = {
.
tx_dc_base
=
0x130000
,
.
tx_dc_base
=
0x130000
,
.
rx_dc_base
=
0x100000
,
.
rx_dc_base
=
0x100000
,
.
offload_features
=
NETIF_F_IP_CSUM
|
NETIF_F_RXHASH
|
NETIF_F_NTUPLE
,
.
offload_features
=
NETIF_F_IP_CSUM
|
NETIF_F_RXHASH
|
NETIF_F_NTUPLE
,
.
reset_world_flags
=
ETH_RESET_IRQ
,
};
};
drivers/net/sfc/filter.c
浏览文件 @
10d1e8ca
...
@@ -335,28 +335,35 @@ static int efx_filter_search(struct efx_filter_table *table,
...
@@ -335,28 +335,35 @@ static int efx_filter_search(struct efx_filter_table *table,
bool
for_insert
,
int
*
depth_required
)
bool
for_insert
,
int
*
depth_required
)
{
{
unsigned
hash
,
incr
,
filter_idx
,
depth
,
depth_max
;
unsigned
hash
,
incr
,
filter_idx
,
depth
,
depth_max
;
struct
efx_filter_spec
*
cmp
;
hash
=
efx_filter_hash
(
key
);
hash
=
efx_filter_hash
(
key
);
incr
=
efx_filter_increment
(
key
);
incr
=
efx_filter_increment
(
key
);
depth_max
=
(
spec
->
priority
<=
EFX_FILTER_PRI_HINT
?
FILTER_CTL_SRCH_HINT_MAX
:
FILTER_CTL_SRCH_MAX
);
filter_idx
=
hash
&
(
table
->
size
-
1
);
depth
=
1
;
for
(
depth
=
1
,
filter_idx
=
hash
&
(
table
->
size
-
1
);
depth_max
=
(
for_insert
?
depth
<=
depth_max
&&
test_bit
(
filter_idx
,
table
->
used_bitmap
);
(
spec
->
priority
<=
EFX_FILTER_PRI_HINT
?
++
depth
)
{
FILTER_CTL_SRCH_HINT_MAX
:
FILTER_CTL_SRCH_MAX
)
:
cmp
=
&
table
->
spec
[
filter_idx
];
table
->
search_depth
[
spec
->
type
]);
if
(
efx_filter_equal
(
spec
,
cmp
))
goto
found
;
for
(;;)
{
/* Return success if entry is used and matches this spec
* or entry is unused and we are trying to insert.
*/
if
(
test_bit
(
filter_idx
,
table
->
used_bitmap
)
?
efx_filter_equal
(
spec
,
&
table
->
spec
[
filter_idx
])
:
for_insert
)
{
*
depth_required
=
depth
;
return
filter_idx
;
}
/* Return failure if we reached the maximum search depth */
if
(
depth
==
depth_max
)
return
for_insert
?
-
EBUSY
:
-
ENOENT
;
filter_idx
=
(
filter_idx
+
incr
)
&
(
table
->
size
-
1
);
filter_idx
=
(
filter_idx
+
incr
)
&
(
table
->
size
-
1
);
++
depth
;
}
}
if
(
!
for_insert
)
return
-
ENOENT
;
if
(
depth
>
depth_max
)
return
-
EBUSY
;
found:
*
depth_required
=
depth
;
return
filter_idx
;
}
}
/* Construct/deconstruct external filter IDs */
/* Construct/deconstruct external filter IDs */
...
@@ -650,11 +657,11 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
...
@@ -650,11 +657,11 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
return
-
EPROTONOSUPPORT
;
return
-
EPROTONOSUPPORT
;
/* RFS must validate the IP header length before calling us */
/* RFS must validate the IP header length before calling us */
EFX_BUG_ON_PARANOID
(
!
pskb_may_pull
(
skb
,
nhoff
+
sizeof
(
*
ip
)
));
EFX_BUG_ON_PARANOID
(
skb_headlen
(
skb
)
<
nhoff
+
sizeof
(
*
ip
));
ip
=
(
const
struct
iphdr
*
)(
skb
->
data
+
nhoff
);
ip
=
(
const
struct
iphdr
*
)(
skb
->
data
+
nhoff
);
if
(
ip_is_fragment
(
ip
))
if
(
ip_is_fragment
(
ip
))
return
-
EPROTONOSUPPORT
;
return
-
EPROTONOSUPPORT
;
EFX_BUG_ON_PARANOID
(
!
pskb_may_pull
(
skb
,
nhoff
+
4
*
ip
->
ihl
+
4
)
);
EFX_BUG_ON_PARANOID
(
skb_headlen
(
skb
)
<
nhoff
+
4
*
ip
->
ihl
+
4
);
ports
=
(
const
__be16
*
)(
skb
->
data
+
nhoff
+
4
*
ip
->
ihl
);
ports
=
(
const
__be16
*
)(
skb
->
data
+
nhoff
+
4
*
ip
->
ihl
);
efx_filter_init_rx
(
&
spec
,
EFX_FILTER_PRI_HINT
,
0
,
rxq_index
);
efx_filter_init_rx
(
&
spec
,
EFX_FILTER_PRI_HINT
,
0
,
rxq_index
);
...
...
drivers/net/sfc/net_driver.h
浏览文件 @
10d1e8ca
...
@@ -644,7 +644,7 @@ struct efx_filter_state;
...
@@ -644,7 +644,7 @@ struct efx_filter_state;
* @irq_rx_moderation: IRQ moderation time for RX event queues
* @irq_rx_moderation: IRQ moderation time for RX event queues
* @msg_enable: Log message enable flags
* @msg_enable: Log message enable flags
* @state: Device state flag. Serialised by the rtnl_lock.
* @state: Device state flag. Serialised by the rtnl_lock.
* @reset_pending:
Pending reset method (normally RESET_TYPE_NONE)
* @reset_pending:
Bitmask for pending resets
* @tx_queue: TX DMA queues
* @tx_queue: TX DMA queues
* @rx_queue: RX DMA queues
* @rx_queue: RX DMA queues
* @channel: Channels
* @channel: Channels
...
@@ -727,7 +727,7 @@ struct efx_nic {
...
@@ -727,7 +727,7 @@ struct efx_nic {
u32
msg_enable
;
u32
msg_enable
;
enum
nic_state
state
;
enum
nic_state
state
;
enum
reset_type
reset_pending
;
unsigned
long
reset_pending
;
struct
efx_channel
*
channel
[
EFX_MAX_CHANNELS
];
struct
efx_channel
*
channel
[
EFX_MAX_CHANNELS
];
char
channel_name
[
EFX_MAX_CHANNELS
][
IFNAMSIZ
+
6
];
char
channel_name
[
EFX_MAX_CHANNELS
][
IFNAMSIZ
+
6
];
...
@@ -827,6 +827,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
...
@@ -827,6 +827,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @init: Initialise the controller
* @init: Initialise the controller
* @fini: Shut down the controller
* @fini: Shut down the controller
* @monitor: Periodic function for polling link state and hardware monitor
* @monitor: Periodic function for polling link state and hardware monitor
* @map_reset_reason: Map ethtool reset reason to a reset method
* @map_reset_flags: Map ethtool reset flags to a reset method, if possible
* @reset: Reset the controller hardware and possibly the PHY. This will
* @reset: Reset the controller hardware and possibly the PHY. This will
* be called while the controller is uninitialised.
* be called while the controller is uninitialised.
* @probe_port: Probe the MAC and PHY
* @probe_port: Probe the MAC and PHY
...
@@ -864,8 +866,6 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
...
@@ -864,8 +866,6 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @rx_dc_base: Base address in SRAM of RX queue descriptor caches
* @rx_dc_base: Base address in SRAM of RX queue descriptor caches
* @offload_features: net_device feature flags for protocol offload
* @offload_features: net_device feature flags for protocol offload
* features implemented in hardware
* features implemented in hardware
* @reset_world_flags: Flags for additional components covered by
* reset method RESET_TYPE_WORLD
*/
*/
struct
efx_nic_type
{
struct
efx_nic_type
{
int
(
*
probe
)(
struct
efx_nic
*
efx
);
int
(
*
probe
)(
struct
efx_nic
*
efx
);
...
@@ -873,6 +873,8 @@ struct efx_nic_type {
...
@@ -873,6 +873,8 @@ struct efx_nic_type {
int
(
*
init
)(
struct
efx_nic
*
efx
);
int
(
*
init
)(
struct
efx_nic
*
efx
);
void
(
*
fini
)(
struct
efx_nic
*
efx
);
void
(
*
fini
)(
struct
efx_nic
*
efx
);
void
(
*
monitor
)(
struct
efx_nic
*
efx
);
void
(
*
monitor
)(
struct
efx_nic
*
efx
);
enum
reset_type
(
*
map_reset_reason
)(
enum
reset_type
reason
);
int
(
*
map_reset_flags
)(
u32
*
flags
);
int
(
*
reset
)(
struct
efx_nic
*
efx
,
enum
reset_type
method
);
int
(
*
reset
)(
struct
efx_nic
*
efx
,
enum
reset_type
method
);
int
(
*
probe_port
)(
struct
efx_nic
*
efx
);
int
(
*
probe_port
)(
struct
efx_nic
*
efx
);
void
(
*
remove_port
)(
struct
efx_nic
*
efx
);
void
(
*
remove_port
)(
struct
efx_nic
*
efx
);
...
@@ -907,7 +909,6 @@ struct efx_nic_type {
...
@@ -907,7 +909,6 @@ struct efx_nic_type {
unsigned
int
tx_dc_base
;
unsigned
int
tx_dc_base
;
unsigned
int
rx_dc_base
;
unsigned
int
rx_dc_base
;
u32
offload_features
;
u32
offload_features
;
u32
reset_world_flags
;
};
};
/**************************************************************************
/**************************************************************************
...
...
drivers/net/sfc/siena.c
浏览文件 @
10d1e8ca
...
@@ -177,6 +177,36 @@ static int siena_test_registers(struct efx_nic *efx)
...
@@ -177,6 +177,36 @@ static int siena_test_registers(struct efx_nic *efx)
**************************************************************************
**************************************************************************
*/
*/
static
enum
reset_type
siena_map_reset_reason
(
enum
reset_type
reason
)
{
return
RESET_TYPE_ALL
;
}
static
int
siena_map_reset_flags
(
u32
*
flags
)
{
enum
{
SIENA_RESET_PORT
=
(
ETH_RESET_DMA
|
ETH_RESET_FILTER
|
ETH_RESET_OFFLOAD
|
ETH_RESET_MAC
|
ETH_RESET_PHY
),
SIENA_RESET_MC
=
(
SIENA_RESET_PORT
|
ETH_RESET_MGMT
<<
ETH_RESET_SHARED_SHIFT
),
};
if
((
*
flags
&
SIENA_RESET_MC
)
==
SIENA_RESET_MC
)
{
*
flags
&=
~
SIENA_RESET_MC
;
return
RESET_TYPE_WORLD
;
}
if
((
*
flags
&
SIENA_RESET_PORT
)
==
SIENA_RESET_PORT
)
{
*
flags
&=
~
SIENA_RESET_PORT
;
return
RESET_TYPE_ALL
;
}
/* no invisible reset implemented */
return
-
EINVAL
;
}
static
int
siena_reset_hw
(
struct
efx_nic
*
efx
,
enum
reset_type
method
)
static
int
siena_reset_hw
(
struct
efx_nic
*
efx
,
enum
reset_type
method
)
{
{
int
rc
;
int
rc
;
...
@@ -390,14 +420,13 @@ static void siena_remove_nic(struct efx_nic *efx)
...
@@ -390,14 +420,13 @@ static void siena_remove_nic(struct efx_nic *efx)
efx
->
nic_data
=
NULL
;
efx
->
nic_data
=
NULL
;
}
}
#define STATS_GENERATION_INVALID ((
u
64)(-1))
#define STATS_GENERATION_INVALID ((
__force __le
64)(-1))
static
int
siena_try_update_nic_stats
(
struct
efx_nic
*
efx
)
static
int
siena_try_update_nic_stats
(
struct
efx_nic
*
efx
)
{
{
u
64
*
dma_stats
;
__le
64
*
dma_stats
;
struct
efx_mac_stats
*
mac_stats
;
struct
efx_mac_stats
*
mac_stats
;
u64
generation_start
;
__le64
generation_start
,
generation_end
;
u64
generation_end
;
mac_stats
=
&
efx
->
mac_stats
;
mac_stats
=
&
efx
->
mac_stats
;
dma_stats
=
efx
->
stats_buffer
.
addr
;
dma_stats
=
efx
->
stats_buffer
.
addr
;
...
@@ -408,7 +437,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
...
@@ -408,7 +437,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
rmb
();
rmb
();
#define MAC_STAT(M, D) \
#define MAC_STAT(M, D) \
mac_stats->M =
dma_stats[MC_CMD_MAC_ ## D]
mac_stats->M =
le64_to_cpu(dma_stats[MC_CMD_MAC_ ## D])
MAC_STAT
(
tx_bytes
,
TX_BYTES
);
MAC_STAT
(
tx_bytes
,
TX_BYTES
);
MAC_STAT
(
tx_bad_bytes
,
TX_BAD_BYTES
);
MAC_STAT
(
tx_bad_bytes
,
TX_BAD_BYTES
);
...
@@ -478,7 +507,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
...
@@ -478,7 +507,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
MAC_STAT
(
rx_internal_error
,
RX_INTERNAL_ERROR_PKTS
);
MAC_STAT
(
rx_internal_error
,
RX_INTERNAL_ERROR_PKTS
);
mac_stats
->
rx_good_lt64
=
0
;
mac_stats
->
rx_good_lt64
=
0
;
efx
->
n_rx_nodesc_drop_cnt
=
dma_stats
[
MC_CMD_MAC_RX_NODESC_DROPS
];
efx
->
n_rx_nodesc_drop_cnt
=
le64_to_cpu
(
dma_stats
[
MC_CMD_MAC_RX_NODESC_DROPS
]);
#undef MAC_STAT
#undef MAC_STAT
...
@@ -507,7 +537,7 @@ static void siena_update_nic_stats(struct efx_nic *efx)
...
@@ -507,7 +537,7 @@ static void siena_update_nic_stats(struct efx_nic *efx)
static
void
siena_start_nic_stats
(
struct
efx_nic
*
efx
)
static
void
siena_start_nic_stats
(
struct
efx_nic
*
efx
)
{
{
u64
*
dma_stats
=
(
u64
*
)
efx
->
stats_buffer
.
addr
;
__le64
*
dma_stats
=
efx
->
stats_buffer
.
addr
;
dma_stats
[
MC_CMD_MAC_GENERATION_END
]
=
STATS_GENERATION_INVALID
;
dma_stats
[
MC_CMD_MAC_GENERATION_END
]
=
STATS_GENERATION_INVALID
;
...
@@ -605,6 +635,8 @@ const struct efx_nic_type siena_a0_nic_type = {
...
@@ -605,6 +635,8 @@ const struct efx_nic_type siena_a0_nic_type = {
.
init
=
siena_init_nic
,
.
init
=
siena_init_nic
,
.
fini
=
efx_port_dummy_op_void
,
.
fini
=
efx_port_dummy_op_void
,
.
monitor
=
NULL
,
.
monitor
=
NULL
,
.
map_reset_reason
=
siena_map_reset_reason
,
.
map_reset_flags
=
siena_map_reset_flags
,
.
reset
=
siena_reset_hw
,
.
reset
=
siena_reset_hw
,
.
probe_port
=
siena_probe_port
,
.
probe_port
=
siena_probe_port
,
.
remove_port
=
siena_remove_port
,
.
remove_port
=
siena_remove_port
,
...
@@ -641,5 +673,4 @@ const struct efx_nic_type siena_a0_nic_type = {
...
@@ -641,5 +673,4 @@ const struct efx_nic_type siena_a0_nic_type = {
.
rx_dc_base
=
0x68000
,
.
rx_dc_base
=
0x68000
,
.
offload_features
=
(
NETIF_F_IP_CSUM
|
NETIF_F_IPV6_CSUM
|
.
offload_features
=
(
NETIF_F_IP_CSUM
|
NETIF_F_IPV6_CSUM
|
NETIF_F_RXHASH
|
NETIF_F_NTUPLE
),
NETIF_F_RXHASH
|
NETIF_F_NTUPLE
),
.
reset_world_flags
=
ETH_RESET_MGMT
<<
ETH_RESET_SHARED_SHIFT
,
};
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录