Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
10d1e8ca
Commit
10d1e8ca
authored
Jul 14, 2011
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
parents
cd0d7228
ff79c8ac
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
152 additions
and
99 deletions
+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
No files found.
drivers/net/sfc/Kconfig
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
,
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment