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
nexedi
linux
Commits
30088a25
Commit
30088a25
authored
Jan 29, 2012
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-davem' of
git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
parents
c45a3dfb
db339569
Changes
30
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
3108 additions
and
2137 deletions
+3108
-2137
drivers/net/ethernet/sfc/Kconfig
drivers/net/ethernet/sfc/Kconfig
+10
-3
drivers/net/ethernet/sfc/Makefile
drivers/net/ethernet/sfc/Makefile
+1
-1
drivers/net/ethernet/sfc/bitfield.h
drivers/net/ethernet/sfc/bitfield.h
+9
-9
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx.c
+83
-115
drivers/net/ethernet/sfc/efx.h
drivers/net/ethernet/sfc/efx.h
+8
-2
drivers/net/ethernet/sfc/ethtool.c
drivers/net/ethernet/sfc/ethtool.c
+64
-74
drivers/net/ethernet/sfc/falcon.c
drivers/net/ethernet/sfc/falcon.c
+20
-22
drivers/net/ethernet/sfc/falcon_boards.c
drivers/net/ethernet/sfc/falcon_boards.c
+6
-6
drivers/net/ethernet/sfc/falcon_xmac.c
drivers/net/ethernet/sfc/falcon_xmac.c
+4
-11
drivers/net/ethernet/sfc/mac.h
drivers/net/ethernet/sfc/mac.h
+0
-21
drivers/net/ethernet/sfc/mcdi.c
drivers/net/ethernet/sfc/mcdi.c
+48
-67
drivers/net/ethernet/sfc/mcdi.h
drivers/net/ethernet/sfc/mcdi.h
+33
-1
drivers/net/ethernet/sfc/mcdi_mac.c
drivers/net/ethernet/sfc/mcdi_mac.c
+22
-39
drivers/net/ethernet/sfc/mcdi_mon.c
drivers/net/ethernet/sfc/mcdi_mon.c
+415
-0
drivers/net/ethernet/sfc/mcdi_pcol.h
drivers/net/ethernet/sfc/mcdi_pcol.h
+2085
-1457
drivers/net/ethernet/sfc/mcdi_phy.c
drivers/net/ethernet/sfc/mcdi_phy.c
+18
-18
drivers/net/ethernet/sfc/mdio_10g.c
drivers/net/ethernet/sfc/mdio_10g.c
+1
-1
drivers/net/ethernet/sfc/mtd.c
drivers/net/ethernet/sfc/mtd.c
+7
-7
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/net_driver.h
+85
-104
drivers/net/ethernet/sfc/nic.c
drivers/net/ethernet/sfc/nic.c
+32
-37
drivers/net/ethernet/sfc/nic.h
drivers/net/ethernet/sfc/nic.h
+17
-3
drivers/net/ethernet/sfc/qt202x_phy.c
drivers/net/ethernet/sfc/qt202x_phy.c
+3
-3
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/sfc/rx.c
+61
-58
drivers/net/ethernet/sfc/selftest.c
drivers/net/ethernet/sfc/selftest.c
+54
-56
drivers/net/ethernet/sfc/selftest.h
drivers/net/ethernet/sfc/selftest.h
+0
-1
drivers/net/ethernet/sfc/siena.c
drivers/net/ethernet/sfc/siena.c
+18
-15
drivers/net/ethernet/sfc/spi.h
drivers/net/ethernet/sfc/spi.h
+1
-1
drivers/net/ethernet/sfc/tenxpress.c
drivers/net/ethernet/sfc/tenxpress.c
+1
-1
drivers/net/ethernet/sfc/tx.c
drivers/net/ethernet/sfc/tx.c
+1
-3
drivers/net/ethernet/sfc/txc43128_phy.c
drivers/net/ethernet/sfc/txc43128_phy.c
+1
-1
No files found.
drivers/net/ethernet/sfc/Kconfig
View file @
30088a25
...
...
@@ -16,6 +16,13 @@ config SFC_MTD
depends on SFC && MTD && !(SFC=y && MTD=m)
default y
---help---
This exposes the on-board flash memory as MTD devices (e.g.
/dev/mtd1). This makes it possible to upload new firmware
to the NIC.
This exposes the on-board flash and/or EEPROM as MTD devices
(e.g. /dev/mtd1). This is required to update the firmware or
the boot configuration under Linux.
config SFC_MCDI_MON
bool "Solarflare SFC9000-family hwmon support"
depends on SFC && HWMON && !(SFC=y && HWMON=m)
default y
----help---
This exposes the on-board firmware-managed sensors as a
hardware monitor device.
drivers/net/ethernet/sfc/Makefile
View file @
30088a25
...
...
@@ -2,7 +2,7 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \
falcon_xmac.o mcdi_mac.o
\
selftest.o ethtool.o qt202x_phy.o mdio_10g.o
\
tenxpress.o txc43128_phy.o falcon_boards.o
\
mcdi.o mcdi_phy.o
mcdi.o mcdi_phy.o
mcdi_mon.o
sfc-$(CONFIG_SFC_MTD)
+=
mtd.o
obj-$(CONFIG_SFC)
+=
sfc.o
drivers/net/ethernet/sfc/bitfield.h
View file @
30088a25
...
...
@@ -448,40 +448,40 @@ typedef union efx_oword {
EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low))
#define EFX_SET_OWORD64(oword, low, high, value) do { \
(oword).u64[0] = (((oword).u64[0]
\
(oword).u64[0] = (((oword).u64[0] \
& ~EFX_INPLACE_MASK64(0, 63, low, high)) \
| EFX_INSERT64(0, 63, low, high, value)); \
(oword).u64[1] = (((oword).u64[1]
\
(oword).u64[1] = (((oword).u64[1] \
& ~EFX_INPLACE_MASK64(64, 127, low, high)) \
| EFX_INSERT64(64, 127, low, high, value)); \
} while (0)
#define EFX_SET_QWORD64(qword, low, high, value) do { \
(qword).u64[0] = (((qword).u64[0]
\
(qword).u64[0] = (((qword).u64[0] \
& ~EFX_INPLACE_MASK64(0, 63, low, high)) \
| EFX_INSERT64(0, 63, low, high, value)); \
} while (0)
#define EFX_SET_OWORD32(oword, low, high, value) do { \
(oword).u32[0] = (((oword).u32[0]
\
(oword).u32[0] = (((oword).u32[0] \
& ~EFX_INPLACE_MASK32(0, 31, low, high)) \
| EFX_INSERT32(0, 31, low, high, value)); \
(oword).u32[1] = (((oword).u32[1]
\
(oword).u32[1] = (((oword).u32[1] \
& ~EFX_INPLACE_MASK32(32, 63, low, high)) \
| EFX_INSERT32(32, 63, low, high, value)); \
(oword).u32[2] = (((oword).u32[2]
\
(oword).u32[2] = (((oword).u32[2] \
& ~EFX_INPLACE_MASK32(64, 95, low, high)) \
| EFX_INSERT32(64, 95, low, high, value)); \
(oword).u32[3] = (((oword).u32[3]
\
(oword).u32[3] = (((oword).u32[3] \
& ~EFX_INPLACE_MASK32(96, 127, low, high)) \
| EFX_INSERT32(96, 127, low, high, value)); \
} while (0)
#define EFX_SET_QWORD32(qword, low, high, value) do { \
(qword).u32[0] = (((qword).u32[0]
\
(qword).u32[0] = (((qword).u32[0] \
& ~EFX_INPLACE_MASK32(0, 31, low, high)) \
| EFX_INSERT32(0, 31, low, high, value)); \
(qword).u32[1] = (((qword).u32[1]
\
(qword).u32[1] = (((qword).u32[1] \
& ~EFX_INPLACE_MASK32(32, 63, low, high)) \
| EFX_INSERT32(32, 63, low, high, value)); \
} while (0)
...
...
drivers/net/ethernet/sfc/efx.c
View file @
30088a25
...
...
@@ -38,15 +38,15 @@
/* Loopback mode names (see LOOPBACK_MODE()) */
const
unsigned
int
efx_loopback_mode_max
=
LOOPBACK_MAX
;
const
char
*
efx_loopback_mode_names
[]
=
{
const
char
*
const
efx_loopback_mode_names
[]
=
{
[
LOOPBACK_NONE
]
=
"NONE"
,
[
LOOPBACK_DATA
]
=
"DATAPATH"
,
[
LOOPBACK_GMAC
]
=
"GMAC"
,
[
LOOPBACK_XGMII
]
=
"XGMII"
,
[
LOOPBACK_XGXS
]
=
"XGXS"
,
[
LOOPBACK_XAUI
]
=
"XAUI"
,
[
LOOPBACK_GMII
]
=
"GMII"
,
[
LOOPBACK_SGMII
]
=
"SGMII"
,
[
LOOPBACK_XAUI
]
=
"XAUI"
,
[
LOOPBACK_GMII
]
=
"GMII"
,
[
LOOPBACK_SGMII
]
=
"SGMII"
,
[
LOOPBACK_XGBR
]
=
"XGBR"
,
[
LOOPBACK_XFI
]
=
"XFI"
,
[
LOOPBACK_XAUI_FAR
]
=
"XAUI_FAR"
,
...
...
@@ -55,21 +55,21 @@ const char *efx_loopback_mode_names[] = {
[
LOOPBACK_XFI_FAR
]
=
"XFI_FAR"
,
[
LOOPBACK_GPHY
]
=
"GPHY"
,
[
LOOPBACK_PHYXS
]
=
"PHYXS"
,
[
LOOPBACK_PCS
]
=
"PCS"
,
[
LOOPBACK_PMAPMD
]
=
"PMA/PMD"
,
[
LOOPBACK_PCS
]
=
"PCS"
,
[
LOOPBACK_PMAPMD
]
=
"PMA/PMD"
,
[
LOOPBACK_XPORT
]
=
"XPORT"
,
[
LOOPBACK_XGMII_WS
]
=
"XGMII_WS"
,
[
LOOPBACK_XAUI_WS
]
=
"XAUI_WS"
,
[
LOOPBACK_XAUI_WS
]
=
"XAUI_WS"
,
[
LOOPBACK_XAUI_WS_FAR
]
=
"XAUI_WS_FAR"
,
[
LOOPBACK_XAUI_WS_NEAR
]
=
"XAUI_WS_NEAR"
,
[
LOOPBACK_GMII_WS
]
=
"GMII_WS"
,
[
LOOPBACK_GMII_WS
]
=
"GMII_WS"
,
[
LOOPBACK_XFI_WS
]
=
"XFI_WS"
,
[
LOOPBACK_XFI_WS_FAR
]
=
"XFI_WS_FAR"
,
[
LOOPBACK_PHYXS_WS
]
=
"PHYXS_WS"
,
[
LOOPBACK_PHYXS_WS
]
=
"PHYXS_WS"
,
};
const
unsigned
int
efx_reset_type_max
=
RESET_TYPE_MAX
;
const
char
*
efx_reset_type_names
[]
=
{
const
char
*
const
efx_reset_type_names
[]
=
{
[
RESET_TYPE_INVISIBLE
]
=
"INVISIBLE"
,
[
RESET_TYPE_ALL
]
=
"ALL"
,
[
RESET_TYPE_WORLD
]
=
"WORLD"
,
...
...
@@ -122,15 +122,6 @@ static int napi_weight = 64;
*/
static
unsigned
int
efx_monitor_interval
=
1
*
HZ
;
/* This controls whether or not the driver will initialise devices
* with invalid MAC addresses stored in the EEPROM or flash. If true,
* such devices will be initialised with a random locally-generated
* MAC address. This allows for loading the sfc_mtd driver to
* reprogram the flash, even if the flash contents (including the MAC
* address) have previously been erased.
*/
static
unsigned
int
allow_bad_hwaddr
;
/* Initial interrupt moderation settings. They can be modified after
* module load with ethtool.
*
...
...
@@ -162,7 +153,7 @@ static unsigned int interrupt_mode;
* interrupt handling.
*
* Cards without MSI-X will only target one CPU via legacy or MSI interrupt.
* The default (0) means to assign an interrupt to each
package (level II cache)
* The default (0) means to assign an interrupt to each
core.
*/
static
unsigned
int
rss_cpus
;
module_param
(
rss_cpus
,
uint
,
0444
);
...
...
@@ -238,8 +229,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget)
/* Deliver last RX packet. */
if
(
channel
->
rx_pkt
)
{
__efx_rx_packet
(
channel
,
channel
->
rx_pkt
,
channel
->
rx_pkt_csummed
);
__efx_rx_packet
(
channel
,
channel
->
rx_pkt
);
channel
->
rx_pkt
=
NULL
;
}
...
...
@@ -373,7 +363,7 @@ static int efx_probe_eventq(struct efx_channel *channel)
struct
efx_nic
*
efx
=
channel
->
efx
;
unsigned
long
entries
;
netif_dbg
(
channel
->
efx
,
probe
,
channel
->
efx
->
net_dev
,
netif_dbg
(
efx
,
probe
,
efx
->
net_dev
,
"chan %d create event queue
\n
"
,
channel
->
channel
);
/* Build an event queue with room for one event per tx and rx buffer,
...
...
@@ -807,16 +797,14 @@ void efx_link_status_changed(struct efx_nic *efx)
}
/* Status message for kernel log */
if
(
link_state
->
up
)
{
if
(
link_state
->
up
)
netif_info
(
efx
,
link
,
efx
->
net_dev
,
"link up at %uMbps %s-duplex (MTU %d)%s
\n
"
,
link_state
->
speed
,
link_state
->
fd
?
"full"
:
"half"
,
efx
->
net_dev
->
mtu
,
(
efx
->
promiscuous
?
" [PROMISC]"
:
""
));
}
else
{
else
netif_info
(
efx
,
link
,
efx
->
net_dev
,
"link down
\n
"
);
}
}
void
efx_link_set_advertising
(
struct
efx_nic
*
efx
,
u32
advertising
)
...
...
@@ -863,11 +851,9 @@ int __efx_reconfigure_port(struct efx_nic *efx)
WARN_ON
(
!
mutex_is_locked
(
&
efx
->
mac_lock
));
/* Serialise the promiscuous flag with efx_set_multicast_list. */
if
(
efx_dev_registered
(
efx
))
{
netif_addr_lock_bh
(
efx
->
net_dev
);
netif_addr_unlock_bh
(
efx
->
net_dev
);
}
/* Serialise the promiscuous flag with efx_set_rx_mode. */
netif_addr_lock_bh
(
efx
->
net_dev
);
netif_addr_unlock_bh
(
efx
->
net_dev
);
/* Disable PHY transmit in mac level loopbacks */
phy_mode
=
efx
->
phy_mode
;
...
...
@@ -907,16 +893,13 @@ static void efx_mac_work(struct work_struct *data)
struct
efx_nic
*
efx
=
container_of
(
data
,
struct
efx_nic
,
mac_work
);
mutex_lock
(
&
efx
->
mac_lock
);
if
(
efx
->
port_enabled
)
{
efx
->
type
->
push_multicast_hash
(
efx
);
efx
->
mac_op
->
reconfigure
(
efx
);
}
if
(
efx
->
port_enabled
)
efx
->
type
->
reconfigure_mac
(
efx
);
mutex_unlock
(
&
efx
->
mac_lock
);
}
static
int
efx_probe_port
(
struct
efx_nic
*
efx
)
{
unsigned
char
*
perm_addr
;
int
rc
;
netif_dbg
(
efx
,
probe
,
efx
->
net_dev
,
"create port
\n
"
);
...
...
@@ -929,28 +912,10 @@ static int efx_probe_port(struct efx_nic *efx)
if
(
rc
)
return
rc
;
/* Sanity check MAC address */
perm_addr
=
efx
->
net_dev
->
perm_addr
;
if
(
is_valid_ether_addr
(
perm_addr
))
{
memcpy
(
efx
->
net_dev
->
dev_addr
,
perm_addr
,
ETH_ALEN
);
}
else
{
netif_err
(
efx
,
probe
,
efx
->
net_dev
,
"invalid MAC address %pM
\n
"
,
perm_addr
);
if
(
!
allow_bad_hwaddr
)
{
rc
=
-
EINVAL
;
goto
err
;
}
random_ether_addr
(
efx
->
net_dev
->
dev_addr
);
netif_info
(
efx
,
probe
,
efx
->
net_dev
,
"using locally-generated MAC %pM
\n
"
,
efx
->
net_dev
->
dev_addr
);
}
/* Initialise MAC address to permanent address */
memcpy
(
efx
->
net_dev
->
dev_addr
,
efx
->
net_dev
->
perm_addr
,
ETH_ALEN
);
return
0
;
err:
efx
->
type
->
remove_port
(
efx
);
return
rc
;
}
static
int
efx_init_port
(
struct
efx_nic
*
efx
)
...
...
@@ -969,7 +934,7 @@ static int efx_init_port(struct efx_nic *efx)
/* Reconfigure the MAC before creating dma queues (required for
* Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */
efx
->
mac_op
->
reconfigure
(
efx
);
efx
->
type
->
reconfigure_mac
(
efx
);
/* Ensure the PHY advertises the correct flow control settings */
rc
=
efx
->
phy_op
->
reconfigure
(
efx
);
...
...
@@ -996,8 +961,7 @@ static void efx_start_port(struct efx_nic *efx)
/* efx_mac_work() might have been scheduled after efx_stop_port(),
* and then cancelled by efx_flush_all() */
efx
->
type
->
push_multicast_hash
(
efx
);
efx
->
mac_op
->
reconfigure
(
efx
);
efx
->
type
->
reconfigure_mac
(
efx
);
mutex_unlock
(
&
efx
->
mac_lock
);
}
...
...
@@ -1012,10 +976,8 @@ static void efx_stop_port(struct efx_nic *efx)
mutex_unlock
(
&
efx
->
mac_lock
);
/* Serialise against efx_set_multicast_list() */
if
(
efx_dev_registered
(
efx
))
{
netif_addr_lock_bh
(
efx
->
net_dev
);
netif_addr_unlock_bh
(
efx
->
net_dev
);
}
netif_addr_lock_bh
(
efx
->
net_dev
);
netif_addr_unlock_bh
(
efx
->
net_dev
);
}
static
void
efx_fini_port
(
struct
efx_nic
*
efx
)
...
...
@@ -1069,9 +1031,11 @@ static int efx_init_io(struct efx_nic *efx)
* masks event though they reject 46 bit masks.
*/
while
(
dma_mask
>
0x7fffffffUL
)
{
if
(
pci_dma_supported
(
pci_dev
,
dma_mask
)
&&
((
rc
=
pci_set_dma_mask
(
pci_dev
,
dma_mask
))
==
0
))
break
;
if
(
pci_dma_supported
(
pci_dev
,
dma_mask
))
{
rc
=
pci_set_dma_mask
(
pci_dev
,
dma_mask
);
if
(
rc
==
0
)
break
;
}
dma_mask
>>=
1
;
}
if
(
rc
)
{
...
...
@@ -1144,18 +1108,16 @@ static void efx_fini_io(struct efx_nic *efx)
pci_disable_device
(
efx
->
pci_dev
);
}
/* Get number of channels wanted. Each channel will have its own IRQ,
* 1 RX queue and/or 2 TX queues. */
static
int
efx_wanted_channels
(
void
)
static
int
efx_wanted_parallelism
(
void
)
{
cpumask_var_t
core
_mask
;
cpumask_var_t
thread
_mask
;
int
count
;
int
cpu
;
if
(
rss_cpus
)
return
rss_cpus
;
if
(
unlikely
(
!
zalloc_cpumask_var
(
&
core
_mask
,
GFP_KERNEL
)))
{
if
(
unlikely
(
!
zalloc_cpumask_var
(
&
thread
_mask
,
GFP_KERNEL
)))
{
printk
(
KERN_WARNING
"sfc: RSS disabled due to allocation failure
\n
"
);
return
1
;
...
...
@@ -1163,14 +1125,14 @@ static int efx_wanted_channels(void)
count
=
0
;
for_each_online_cpu
(
cpu
)
{
if
(
!
cpumask_test_cpu
(
cpu
,
core
_mask
))
{
if
(
!
cpumask_test_cpu
(
cpu
,
thread
_mask
))
{
++
count
;
cpumask_or
(
core_mask
,
core
_mask
,
topology_
core
_cpumask
(
cpu
));
cpumask_or
(
thread_mask
,
thread
_mask
,
topology_
thread
_cpumask
(
cpu
));
}
}
free_cpumask_var
(
core
_mask
);
free_cpumask_var
(
thread
_mask
);
return
count
;
}
...
...
@@ -1209,7 +1171,7 @@ static int efx_probe_interrupts(struct efx_nic *efx)
struct
msix_entry
xentries
[
EFX_MAX_CHANNELS
];
int
n_channels
;
n_channels
=
efx_wanted_
channels
();
n_channels
=
efx_wanted_
parallelism
();
if
(
separate_tx_channels
)
n_channels
*=
2
;
n_channels
=
min
(
n_channels
,
max_channels
);
...
...
@@ -1425,14 +1387,14 @@ static void efx_start_all(struct efx_nic *efx)
return
;
if
((
efx
->
state
!=
STATE_RUNNING
)
&&
(
efx
->
state
!=
STATE_INIT
))
return
;
if
(
efx_dev_registered
(
efx
)
&&
!
netif_running
(
efx
->
net_dev
))
if
(
!
netif_running
(
efx
->
net_dev
))
return
;
/* Mark the port as enabled so port reconfigurations can start, then
* restart the transmit interface early so the watchdog timer stops */
efx_start_port
(
efx
);
if
(
efx_dev_registered
(
efx
)
&&
netif_device_present
(
efx
->
net_dev
))
if
(
netif_device_present
(
efx
->
net_dev
))
netif_tx_wake_all_queues
(
efx
->
net_dev
);
efx_for_each_channel
(
channel
,
efx
)
...
...
@@ -1523,11 +1485,9 @@ static void efx_stop_all(struct efx_nic *efx)
/* Stop the kernel transmit interface late, so the watchdog
* timer isn't ticking over the flush */
if
(
efx_dev_registered
(
efx
))
{
netif_tx_stop_all_queues
(
efx
->
net_dev
);
netif_tx_lock_bh
(
efx
->
net_dev
);
netif_tx_unlock_bh
(
efx
->
net_dev
);
}
netif_tx_stop_all_queues
(
efx
->
net_dev
);
netif_tx_lock_bh
(
efx
->
net_dev
);
netif_tx_unlock_bh
(
efx
->
net_dev
);
}
static
void
efx_remove_all
(
struct
efx_nic
*
efx
)
...
...
@@ -1544,13 +1504,13 @@ static void efx_remove_all(struct efx_nic *efx)
*
**************************************************************************/
static
unsigned
int
irq_mod_ticks
(
unsigned
int
usecs
,
unsigned
int
resolution
)
static
unsigned
int
irq_mod_ticks
(
unsigned
int
usecs
,
unsigned
int
quantum_ns
)
{
if
(
usecs
==
0
)
return
0
;
if
(
usecs
<
resolution
)
if
(
usecs
*
1000
<
quantum_ns
)
return
1
;
/* never round down to 0 */
return
usecs
/
resolution
;
return
usecs
*
1000
/
quantum_ns
;
}
/* Set interrupt moderation parameters */
...
...
@@ -1559,14 +1519,20 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
bool
rx_may_override_tx
)
{
struct
efx_channel
*
channel
;
unsigned
tx_ticks
=
irq_mod_ticks
(
tx_usecs
,
EFX_IRQ_MOD_RESOLUTION
);
unsigned
rx_ticks
=
irq_mod_ticks
(
rx_usecs
,
EFX_IRQ_MOD_RESOLUTION
);
unsigned
int
irq_mod_max
=
DIV_ROUND_UP
(
efx
->
type
->
timer_period_max
*
efx
->
timer_quantum_ns
,
1000
);
unsigned
int
tx_ticks
;
unsigned
int
rx_ticks
;
EFX_ASSERT_RESET_SERIALISED
(
efx
);
if
(
tx_
ticks
>
EFX_IRQ_MOD_MAX
||
rx_ticks
>
EFX_IRQ_MOD_MAX
)
if
(
tx_
usecs
>
irq_mod_max
||
rx_usecs
>
irq_mod_max
)
return
-
EINVAL
;
tx_ticks
=
irq_mod_ticks
(
tx_usecs
,
efx
->
timer_quantum_ns
);
rx_ticks
=
irq_mod_ticks
(
rx_usecs
,
efx
->
timer_quantum_ns
);
if
(
tx_ticks
!=
rx_ticks
&&
efx
->
tx_channel_offset
==
0
&&
!
rx_may_override_tx
)
{
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"Channels are shared. "
...
...
@@ -1589,8 +1555,14 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
void
efx_get_irq_moderation
(
struct
efx_nic
*
efx
,
unsigned
int
*
tx_usecs
,
unsigned
int
*
rx_usecs
,
bool
*
rx_adaptive
)
{
/* We must round up when converting ticks to microseconds
* because we round down when converting the other way.
*/
*
rx_adaptive
=
efx
->
irq_rx_adaptive
;
*
rx_usecs
=
efx
->
irq_rx_moderation
*
EFX_IRQ_MOD_RESOLUTION
;
*
rx_usecs
=
DIV_ROUND_UP
(
efx
->
irq_rx_moderation
*
efx
->
timer_quantum_ns
,
1000
);
/* If channels are shared between RX and TX, so is IRQ
* moderation. Otherwise, IRQ moderation is the same for all
...
...
@@ -1599,9 +1571,10 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
if
(
efx
->
tx_channel_offset
==
0
)
*
tx_usecs
=
*
rx_usecs
;
else
*
tx_usecs
=
*
tx_usecs
=
DIV_ROUND_UP
(
efx
->
channel
[
efx
->
tx_channel_offset
]
->
irq_moderation
*
EFX_IRQ_MOD_RESOLUTION
;
efx
->
timer_quantum_ns
,
1000
);
}
/**************************************************************************
...
...
@@ -1765,14 +1738,15 @@ static int efx_net_stop(struct net_device *net_dev)
}
/* Context: process, dev_base_lock or RTNL held, non-blocking. */
static
struct
rtnl_link_stats64
*
efx_net_stats
(
struct
net_device
*
net_dev
,
struct
rtnl_link_stats64
*
stats
)
static
struct
rtnl_link_stats64
*
efx_net_stats
(
struct
net_device
*
net_dev
,
struct
rtnl_link_stats64
*
stats
)
{
struct
efx_nic
*
efx
=
netdev_priv
(
net_dev
);
struct
efx_mac_stats
*
mac_stats
=
&
efx
->
mac_stats
;
spin_lock_bh
(
&
efx
->
stats_lock
);
efx
->
type
->
update_stats
(
efx
);
spin_unlock_bh
(
&
efx
->
stats_lock
);
stats
->
rx_packets
=
mac_stats
->
rx_packets
;
stats
->
tx_packets
=
mac_stats
->
tx_packets
;
...
...
@@ -1796,6 +1770,8 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc
stats
->
tx_errors
=
(
stats
->
tx_window_errors
+
mac_stats
->
tx_bad
);
spin_unlock_bh
(
&
efx
->
stats_lock
);
return
stats
;
}
...
...
@@ -1816,7 +1792,6 @@ static void efx_watchdog(struct net_device *net_dev)
static
int
efx_change_mtu
(
struct
net_device
*
net_dev
,
int
new_mtu
)
{
struct
efx_nic
*
efx
=
netdev_priv
(
net_dev
);
int
rc
=
0
;
EFX_ASSERT_RESET_SERIALISED
(
efx
);
...
...
@@ -1833,13 +1808,13 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
/* Reconfigure the MAC before enabling the dma queues so that
* the RX buffers don't overflow */
net_dev
->
mtu
=
new_mtu
;
efx
->
mac_op
->
reconfigure
(
efx
);
efx
->
type
->
reconfigure_mac
(
efx
);
mutex_unlock
(
&
efx
->
mac_lock
);
efx_init_channels
(
efx
);
efx_start_all
(
efx
);
return
rc
;
return
0
;
}
static
int
efx_set_mac_address
(
struct
net_device
*
net_dev
,
void
*
data
)
...
...
@@ -1861,14 +1836,14 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
/* Reconfigure the MAC */
mutex_lock
(
&
efx
->
mac_lock
);
efx
->
mac_op
->
reconfigure
(
efx
);
efx
->
type
->
reconfigure_mac
(
efx
);
mutex_unlock
(
&
efx
->
mac_lock
);
return
0
;
}
/* Context: netif_addr_lock held, BHs disabled. */
static
void
efx_set_
multicast_list
(
struct
net_device
*
net_dev
)
static
void
efx_set_
rx_mode
(
struct
net_device
*
net_dev
)
{
struct
efx_nic
*
efx
=
netdev_priv
(
net_dev
);
struct
netdev_hw_addr
*
ha
;
...
...
@@ -1922,7 +1897,7 @@ static const struct net_device_ops efx_netdev_ops = {
.
ndo_do_ioctl
=
efx_ioctl
,
.
ndo_change_mtu
=
efx_change_mtu
,
.
ndo_set_mac_address
=
efx_set_mac_address
,
.
ndo_set_rx_mode
=
efx_set_
multicast_list
,
.
ndo_set_rx_mode
=
efx_set_
rx_mode
,
.
ndo_set_features
=
efx_set_features
,
#ifdef CONFIG_NET_POLL_CONTROLLER
.
ndo_poll_controller
=
efx_netpoll
,
...
...
@@ -1975,10 +1950,6 @@ static int efx_register_netdev(struct efx_nic *efx)
net_dev
->
netdev_ops
=
&
efx_netdev_ops
;
SET_ETHTOOL_OPS
(
net_dev
,
&
efx_ethtool_ops
);
/* Clear MAC statistics */
efx
->
mac_op
->
update_stats
(
efx
);
memset
(
&
efx
->
mac_stats
,
0
,
sizeof
(
efx
->
mac_stats
));
rtnl_lock
();
rc
=
dev_alloc_name
(
net_dev
,
net_dev
->
name
);
...
...
@@ -1997,7 +1968,7 @@ static int efx_register_netdev(struct efx_nic *efx)
}
/* Always start with carrier off; PHY events will detect the link */
netif_carrier_off
(
efx
->
net_dev
);
netif_carrier_off
(
net_dev
);
rtnl_unlock
();
...
...
@@ -2038,11 +2009,9 @@ static void efx_unregister_netdev(struct efx_nic *efx)
efx_release_tx_buffers
(
tx_queue
);
}
if
(
efx_dev_registered
(
efx
))
{
strlcpy
(
efx
->
name
,
pci_name
(
efx
->
pci_dev
),
sizeof
(
efx
->
name
));
device_remove_file
(
&
efx
->
pci_dev
->
dev
,
&
dev_attr_phy_type
);
unregister_netdev
(
efx
->
net_dev
);
}
strlcpy
(
efx
->
name
,
pci_name
(
efx
->
pci_dev
),
sizeof
(
efx
->
name
));
device_remove_file
(
&
efx
->
pci_dev
->
dev
,
&
dev_attr_phy_type
);
unregister_netdev
(
efx
->
net_dev
);
}
/**************************************************************************
...
...
@@ -2095,7 +2064,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
"could not restore PHY settings
\n
"
);
}
efx
->
mac_op
->
reconfigure
(
efx
);
efx
->
type
->
reconfigure_mac
(
efx
);
efx_init_channels
(
efx
);
efx_restore_filters
(
efx
);
...
...
@@ -2300,7 +2269,6 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type,
efx
->
net_dev
=
net_dev
;
spin_lock_init
(
&
efx
->
stats_lock
);
mutex_init
(
&
efx
->
mac_lock
);
efx
->
mac_op
=
type
->
default_mac_ops
;
efx
->
phy_op
=
&
efx_dummy_phy_operations
;
efx
->
mdio
.
dev
=
net_dev
;
INIT_WORK
(
&
efx
->
mac_work
,
efx_mac_work
);
...
...
@@ -2459,7 +2427,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
/* NIC initialisation
*
* This is called at module load (or hotplug insertion,
* theoretically). It sets up PCI mappings,
tests and
resets the NIC,
* theoretically). It sets up PCI mappings, resets the NIC,
* sets up and registers the network devices with the kernel and hooks
* the interrupt service routine. It does not prepare the device for
* transmission; this is left to the first time one of the network
...
...
@@ -2658,7 +2626,7 @@ static int efx_pm_suspend(struct device *dev)
return
rc
;
}
static
struct
dev_pm_ops
efx_pm_ops
=
{
static
const
struct
dev_pm_ops
efx_pm_ops
=
{
.
suspend
=
efx_pm_suspend
,
.
resume
=
efx_pm_resume
,
.
freeze
=
efx_pm_freeze
,
...
...
drivers/net/ethernet/sfc/efx.h
View file @
30088a25
...
...
@@ -40,9 +40,9 @@ extern void efx_rx_strategy(struct efx_channel *channel);
extern
void
efx_fast_push_rx_descriptors
(
struct
efx_rx_queue
*
rx_queue
);
extern
void
efx_rx_slow_fill
(
unsigned
long
context
);
extern
void
__efx_rx_packet
(
struct
efx_channel
*
channel
,
struct
efx_rx_buffer
*
rx_buf
,
bool
checksummed
);
struct
efx_rx_buffer
*
rx_buf
);
extern
void
efx_rx_packet
(
struct
efx_rx_queue
*
rx_queue
,
unsigned
int
index
,
unsigned
int
len
,
bool
checksummed
,
bool
discard
);
unsigned
int
len
,
u16
flags
);
extern
void
efx_schedule_slow_fill
(
struct
efx_rx_queue
*
rx_queue
);
#define EFX_MAX_DMAQ_SIZE 4096UL
...
...
@@ -145,6 +145,12 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
napi_schedule
(
&
channel
->
napi_str
);
}
static
inline
void
efx_schedule_channel_irq
(
struct
efx_channel
*
channel
)
{
channel
->
last_irq_cpu
=
raw_smp_processor_id
();
efx_schedule_channel
(
channel
);
}
extern
void
efx_link_status_changed
(
struct
efx_nic
*
efx
);
extern
void
efx_link_set_advertising
(
struct
efx_nic
*
efx
,
u32
);
extern
void
efx_link_set_wanted_fc
(
struct
efx_nic
*
efx
,
u8
);
...
...
drivers/net/ethernet/sfc/ethtool.c
View file @
30088a25
...
...
@@ -52,11 +52,6 @@ static u64 efx_get_uint_stat(void *field)
return
*
(
unsigned
int
*
)
field
;
}
static
u64
efx_get_ulong_stat
(
void
*
field
)
{
return
*
(
unsigned
long
*
)
field
;
}
static
u64
efx_get_u64_stat
(
void
*
field
)
{
return
*
(
u64
*
)
field
;
...
...
@@ -67,12 +62,8 @@ static u64 efx_get_atomic_stat(void *field)
return
atomic_read
((
atomic_t
*
)
field
);
}
#define EFX_ETHTOOL_ULONG_MAC_STAT(field) \
EFX_ETHTOOL_STAT(field, mac_stats, field, \
unsigned long, efx_get_ulong_stat)
#define EFX_ETHTOOL_U64_MAC_STAT(field) \
EFX_ETHTOOL_STAT(field, mac_stats, field,
\
EFX_ETHTOOL_STAT(field, mac_stats, field, \
u64, efx_get_u64_stat)
#define EFX_ETHTOOL_UINT_NIC_STAT(name) \
...
...
@@ -91,36 +82,36 @@ static u64 efx_get_atomic_stat(void *field)
EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \
unsigned int, efx_get_uint_stat)
static
struct
efx_ethtool_stat
efx_ethtool_stats
[]
=
{
static
const
struct
efx_ethtool_stat
efx_ethtool_stats
[]
=
{
EFX_ETHTOOL_U64_MAC_STAT
(
tx_bytes
),
EFX_ETHTOOL_U64_MAC_STAT
(
tx_good_bytes
),
EFX_ETHTOOL_U64_MAC_STAT
(
tx_bad_bytes
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_packets
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_bad
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_pause
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_control
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_unicast
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_multicast
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_broadcast
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_lt64
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_64
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_65_to_127
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_128_to_255
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_256_to_511
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_512_to_1023
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_1024_to_15xx
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_15xx_to_jumbo
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_gtjumbo
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_collision
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_single_collision
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_multiple_collision
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_excessive_collision
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_deferred
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_late_collision
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_excessive_deferred
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_non_tcpudp
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_mac_src_error
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
tx_ip_src_error
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_packets
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_bad
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_pause
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_control
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_unicast
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_multicast
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_broadcast
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_lt64
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_64
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_65_to_127
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_128_to_255
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_256_to_511
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_512_to_1023
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_1024_to_15xx
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_15xx_to_jumbo
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_gtjumbo
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_collision
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_single_collision
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_multiple_collision
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_excessive_collision
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_deferred
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_late_collision
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_excessive_deferred
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_non_tcpudp
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_mac_src_error
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
tx_ip_src_error
),
EFX_ETHTOOL_UINT_TXQ_STAT
(
tso_bursts
),
EFX_ETHTOOL_UINT_TXQ_STAT
(
tso_long_headers
),
EFX_ETHTOOL_UINT_TXQ_STAT
(
tso_packets
),
...
...
@@ -128,34 +119,34 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
EFX_ETHTOOL_U64_MAC_STAT
(
rx_bytes
),
EFX_ETHTOOL_U64_MAC_STAT
(
rx_good_bytes
),
EFX_ETHTOOL_U64_MAC_STAT
(
rx_bad_bytes
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_packets
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_good
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_bad
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_pause
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_control
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_unicast
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_multicast
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_broadcast
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_lt64
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_64
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_65_to_127
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_128_to_255
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_256_to_511
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_512_to_1023
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_1024_to_15xx
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_15xx_to_jumbo
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_gtjumbo
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_bad_lt64
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_bad_64_to_15xx
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_bad_15xx_to_jumbo
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_bad_gtjumbo
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_overflow
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_missed
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_false_carrier
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_symbol_error
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_align_error
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_length_error
),
EFX_ETHTOOL_U
LONG
_MAC_STAT
(
rx_internal_error
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_packets
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_good
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_bad
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_pause
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_control
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_unicast
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_multicast
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_broadcast
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_lt64
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_64
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_65_to_127
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_128_to_255
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_256_to_511
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_512_to_1023
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_1024_to_15xx
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_15xx_to_jumbo
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_gtjumbo
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_bad_lt64
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_bad_64_to_15xx
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_bad_15xx_to_jumbo
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_bad_gtjumbo
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_overflow
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_missed
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_false_carrier
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_symbol_error
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_align_error
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_length_error
),
EFX_ETHTOOL_U
64
_MAC_STAT
(
rx_internal_error
),
EFX_ETHTOOL_UINT_NIC_STAT
(
rx_nodesc_drop_cnt
),
EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT
(
rx_reset
),
EFX_ETHTOOL_UINT_CHANNEL_STAT
(
rx_tobe_disc
),
...
...
@@ -404,10 +395,6 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
&
tests
->
eventq_int
[
channel
->
channel
],
EFX_CHANNEL_NAME
(
channel
),
"eventq.int"
,
NULL
);
efx_fill_test
(
n
++
,
strings
,
data
,
&
tests
->
eventq_poll
[
channel
->
channel
],
EFX_CHANNEL_NAME
(
channel
),
"eventq.poll"
,
NULL
);
}
efx_fill_test
(
n
++
,
strings
,
data
,
&
tests
->
registers
,
...
...
@@ -486,16 +473,17 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
{
struct
efx_nic
*
efx
=
netdev_priv
(
net_dev
);
struct
efx_mac_stats
*
mac_stats
=
&
efx
->
mac_stats
;
struct
efx_ethtool_stat
*
stat
;
const
struct
efx_ethtool_stat
*
stat
;
struct
efx_channel
*
channel
;
struct
efx_tx_queue
*
tx_queue
;
struct
rtnl_link_stats64
temp
;
int
i
;
EFX_BUG_ON_PARANOID
(
stats
->
n_stats
!=
EFX_ETHTOOL_NUM_STATS
);
spin_lock_bh
(
&
efx
->
stats_lock
);
/* Update MAC and NIC statistics */
dev_get_stats
(
net_dev
,
&
temp
);
efx
->
type
->
update_stats
(
efx
);
/* Fill detailed statistics buffer */
for
(
i
=
0
;
i
<
EFX_ETHTOOL_NUM_STATS
;
i
++
)
{
...
...
@@ -525,6 +513,8 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
break
;
}
}
spin_unlock_bh
(
&
efx
->
stats_lock
);
}
static
void
efx_ethtool_self_test
(
struct
net_device
*
net_dev
,
...
...
@@ -747,7 +737,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
/* Recover by resetting the EM block */
falcon_stop_nic_stats
(
efx
);
falcon_drain_tx_fifo
(
efx
);
efx
->
mac_op
->
reconfigure
(
efx
);
falcon_reconfigure_xmac
(
efx
);
falcon_start_nic_stats
(
efx
);
}
else
{
/* Schedule a reset to recover */
...
...
@@ -772,7 +762,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
/* Reconfigure the MAC. The PHY *may* generate a link state change event
* if the user just changed the advertised capabilities, but there's no
* harm doing this twice */
efx
->
mac_op
->
reconfigure
(
efx
);
efx
->
type
->
reconfigure_mac
(
efx
);
out:
mutex_unlock
(
&
efx
->
mac_lock
);
...
...
drivers/net/ethernet/sfc/falcon.c
View file @
30088a25
...
...
@@ -19,7 +19,6 @@
#include "net_driver.h"
#include "bitfield.h"
#include "efx.h"
#include "mac.h"
#include "spi.h"
#include "nic.h"
#include "regs.h"
...
...
@@ -89,7 +88,7 @@ static int falcon_getscl(void *data)
return
EFX_OWORD_FIELD
(
reg
,
FRF_AB_GPIO0_IN
);
}
static
struct
i2c_algo_bit_data
falcon_i2c_bit_operations
=
{
static
const
struct
i2c_algo_bit_data
falcon_i2c_bit_operations
=
{
.
setsda
=
falcon_setsda
,
.
setscl
=
falcon_setscl
,
.
getsda
=
falcon_getsda
,
...
...
@@ -104,8 +103,6 @@ static void falcon_push_irq_moderation(struct efx_channel *channel)
efx_dword_t
timer_cmd
;
struct
efx_nic
*
efx
=
channel
->
efx
;
BUILD_BUG_ON
(
EFX_IRQ_MOD_MAX
>
(
1
<<
FRF_AB_TC_TIMER_VAL_WIDTH
));
/* Set timer register */
if
(
channel
->
irq_moderation
)
{
EFX_POPULATE_DWORD_2
(
timer_cmd
,
...
...
@@ -177,27 +174,24 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
"IRQ %d on CPU %d status "
EFX_OWORD_FMT
"
\n
"
,
irq
,
raw_smp_processor_id
(),
EFX_OWORD_VAL
(
*
int_ker
));
/* Check to see if we have a serious error condition */
syserr
=
EFX_OWORD_FIELD
(
*
int_ker
,
FSF_AZ_NET_IVEC_FATAL_INT
);
if
(
unlikely
(
syserr
))
return
efx_nic_fatal_interrupt
(
efx
);
/* Determine interrupting queues, clear interrupt status
* register and acknowledge the device interrupt.
*/
BUILD_BUG_ON
(
FSF_AZ_NET_IVEC_INT_Q_WIDTH
>
EFX_MAX_CHANNELS
);
queues
=
EFX_OWORD_FIELD
(
*
int_ker
,
FSF_AZ_NET_IVEC_INT_Q
);
/* Check to see if we have a serious error condition */
if
(
queues
&
(
1U
<<
efx
->
fatal_irq_level
))
{
syserr
=
EFX_OWORD_FIELD
(
*
int_ker
,
FSF_AZ_NET_IVEC_FATAL_INT
);
if
(
unlikely
(
syserr
))
return
efx_nic_fatal_interrupt
(
efx
);
}
EFX_ZERO_OWORD
(
*
int_ker
);
wmb
();
/* Ensure the vector is cleared before interrupt ack */
falcon_irq_ack_a1
(
efx
);
if
(
queues
&
1
)
efx_schedule_channel
(
efx_get_channel
(
efx
,
0
));
efx_schedule_channel
_irq
(
efx_get_channel
(
efx
,
0
));
if
(
queues
&
2
)
efx_schedule_channel
(
efx_get_channel
(
efx
,
1
));
efx_schedule_channel
_irq
(
efx_get_channel
(
efx
,
1
));
return
IRQ_HANDLED
;
}
/**************************************************************************
...
...
@@ -613,7 +607,7 @@ static void falcon_stats_complete(struct efx_nic *efx)
nic_data
->
stats_pending
=
false
;
if
(
*
nic_data
->
stats_dma_done
==
FALCON_STATS_DONE
)
{
rmb
();
/* read the done flag before the stats */
efx
->
mac_op
->
update_stats
(
efx
);
falcon_update_stats_xmac
(
efx
);
}
else
{
netif_err
(
efx
,
hw
,
efx
->
net_dev
,
"timed out waiting for statistics
\n
"
);
...
...
@@ -670,7 +664,7 @@ static int falcon_reconfigure_port(struct efx_nic *efx)
falcon_reset_macs
(
efx
);
efx
->
phy_op
->
reconfigure
(
efx
);
rc
=
efx
->
mac_op
->
reconfigure
(
efx
);
rc
=
falcon_reconfigure_xmac
(
efx
);
BUG_ON
(
rc
);
falcon_start_nic_stats
(
efx
);
...
...
@@ -1218,7 +1212,7 @@ static void falcon_monitor(struct efx_nic *efx)
falcon_deconfigure_mac_wrapper
(
efx
);
falcon_reset_macs
(
efx
);
rc
=
efx
->
mac_op
->
reconfigure
(
efx
);
rc
=
falcon_reconfigure_xmac
(
efx
);
BUG_ON
(
rc
);
falcon_start_nic_stats
(
efx
);
...
...
@@ -1472,6 +1466,8 @@ static int falcon_probe_nic(struct efx_nic *efx)
goto
fail5
;
}
efx
->
timer_quantum_ns
=
4968
;
/* 621 cycles */
/* Initialise I2C adapter */
board
=
falcon_board
(
efx
);
board
->
i2c_adap
.
owner
=
THIS_MODULE
;
...
...
@@ -1676,7 +1672,7 @@ static void falcon_update_nic_stats(struct efx_nic *efx)
*
nic_data
->
stats_dma_done
==
FALCON_STATS_DONE
)
{
nic_data
->
stats_pending
=
false
;
rmb
();
/* read the done flag before the stats */
efx
->
mac_op
->
update_stats
(
efx
);
falcon_update_stats_xmac
(
efx
);
}
}
...
...
@@ -1767,13 +1763,13 @@ const struct efx_nic_type falcon_a1_nic_type = {
.
stop_stats
=
falcon_stop_nic_stats
,
.
set_id_led
=
falcon_set_id_led
,
.
push_irq_moderation
=
falcon_push_irq_moderation
,
.
push_multicast_hash
=
falcon_push_multicast_hash
,
.
reconfigure_port
=
falcon_reconfigure_port
,
.
reconfigure_mac
=
falcon_reconfigure_xmac
,
.
check_mac_fault
=
falcon_xmac_check_fault
,
.
get_wol
=
falcon_get_wol
,
.
set_wol
=
falcon_set_wol
,
.
resume_wol
=
efx_port_dummy_op_void
,
.
test_nvram
=
falcon_test_nvram
,
.
default_mac_ops
=
&
falcon_xmac_operations
,
.
revision
=
EFX_REV_FALCON_A1
,
.
mem_map_size
=
0x20000
,
...
...
@@ -1786,6 +1782,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
.
rx_buffer_padding
=
0x24
,
.
max_interrupt_mode
=
EFX_INT_MODE_MSI
,
.
phys_addr_channels
=
4
,
.
timer_period_max
=
1
<<
FRF_AB_TC_TIMER_VAL_WIDTH
,
.
tx_dc_base
=
0x130000
,
.
rx_dc_base
=
0x100000
,
.
offload_features
=
NETIF_F_IP_CSUM
,
...
...
@@ -1809,14 +1806,14 @@ const struct efx_nic_type falcon_b0_nic_type = {
.
stop_stats
=
falcon_stop_nic_stats
,
.
set_id_led
=
falcon_set_id_led
,
.
push_irq_moderation
=
falcon_push_irq_moderation
,
.
push_multicast_hash
=
falcon_push_multicast_hash
,
.
reconfigure_port
=
falcon_reconfigure_port
,
.
reconfigure_mac
=
falcon_reconfigure_xmac
,
.
check_mac_fault
=
falcon_xmac_check_fault
,
.
get_wol
=
falcon_get_wol
,
.
set_wol
=
falcon_set_wol
,
.
resume_wol
=
efx_port_dummy_op_void
,
.
test_registers
=
falcon_b0_test_registers
,
.
test_nvram
=
falcon_test_nvram
,
.
default_mac_ops
=
&
falcon_xmac_operations
,
.
revision
=
EFX_REV_FALCON_B0
,
/* Map everything up to and including the RSS indirection
...
...
@@ -1837,6 +1834,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
.
phys_addr_channels
=
32
,
/* Hardware limit is 64, but the legacy
* interrupt handler only supports 32
* channels */
.
timer_period_max
=
1
<<
FRF_AB_TC_TIMER_VAL_WIDTH
,
.
tx_dc_base
=
0x130000
,
.
rx_dc_base
=
0x100000
,
.
offload_features
=
NETIF_F_IP_CSUM
|
NETIF_F_RXHASH
|
NETIF_F_NTUPLE
,
...
...
drivers/net/ethernet/sfc/falcon_boards.c
View file @
30088a25
...
...
@@ -87,7 +87,7 @@ static const u8 falcon_lm87_common_regs[] = {
0
};
static
int
efx_init_lm87
(
struct
efx_nic
*
efx
,
struct
i2c_board_info
*
info
,
static
int
efx_init_lm87
(
struct
efx_nic
*
efx
,
const
struct
i2c_board_info
*
info
,
const
u8
*
reg_values
)
{
struct
falcon_board
*
board
=
falcon_board
(
efx
);
...
...
@@ -179,7 +179,7 @@ static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
#else
/* !CONFIG_SENSORS_LM87 */
static
inline
int
efx_init_lm87
(
struct
efx_nic
*
efx
,
struct
i2c_board_info
*
info
,
efx_init_lm87
(
struct
efx_nic
*
efx
,
const
struct
i2c_board_info
*
info
,
const
u8
*
reg_values
)
{
return
0
;
...
...
@@ -442,7 +442,7 @@ static int sfe4001_check_hw(struct efx_nic *efx)
return
(
status
<
0
)
?
-
EIO
:
-
ERANGE
;
}
static
struct
i2c_board_info
sfe4001_hwmon_info
=
{
static
const
struct
i2c_board_info
sfe4001_hwmon_info
=
{
I2C_BOARD_INFO
(
"max6647"
,
0x4e
),
};
...
...
@@ -522,7 +522,7 @@ static const u8 sfe4002_lm87_regs[] = {
0
};
static
struct
i2c_board_info
sfe4002_hwmon_info
=
{
static
const
struct
i2c_board_info
sfe4002_hwmon_info
=
{
I2C_BOARD_INFO
(
"lm87"
,
0x2e
),
.
platform_data
=
&
sfe4002_lm87_channel
,
};
...
...
@@ -591,7 +591,7 @@ static const u8 sfn4112f_lm87_regs[] = {
0
};
static
struct
i2c_board_info
sfn4112f_hwmon_info
=
{
static
const
struct
i2c_board_info
sfn4112f_hwmon_info
=
{
I2C_BOARD_INFO
(
"lm87"
,
0x2e
),
.
platform_data
=
&
sfn4112f_lm87_channel
,
};
...
...
@@ -653,7 +653,7 @@ static const u8 sfe4003_lm87_regs[] = {
0
};
static
struct
i2c_board_info
sfe4003_hwmon_info
=
{
static
const
struct
i2c_board_info
sfe4003_hwmon_info
=
{
I2C_BOARD_INFO
(
"lm87"
,
0x2e
),
.
platform_data
=
&
sfe4003_lm87_channel
,
};
...
...
drivers/net/ethernet/sfc/falcon_xmac.c
View file @
30088a25
...
...
@@ -14,7 +14,6 @@
#include "nic.h"
#include "regs.h"
#include "io.h"
#include "mac.h"
#include "mdio_10g.h"
#include "workarounds.h"
...
...
@@ -139,7 +138,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx)
return
(
efx
->
loopback_mode
==
LOOPBACK_XGMII
||
falcon_xgxs_link_ok
(
efx
))
&&
(
!
(
efx
->
mdio
.
mmds
&
(
1
<<
MDIO_MMD_PHYXS
))
||
LOOPBACK_INTERNAL
(
efx
)
||
LOOPBACK_INTERNAL
(
efx
)
||
efx_mdio_phyxgxs_lane_sync
(
efx
));
}
...
...
@@ -270,12 +269,12 @@ static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries)
return
mac_up
;
}
static
bool
falcon_xmac_check_fault
(
struct
efx_nic
*
efx
)
bool
falcon_xmac_check_fault
(
struct
efx_nic
*
efx
)
{
return
!
falcon_xmac_link_ok_retry
(
efx
,
5
);
}
static
int
falcon_reconfigure_xmac
(
struct
efx_nic
*
efx
)
int
falcon_reconfigure_xmac
(
struct
efx_nic
*
efx
)
{
struct
falcon_nic_data
*
nic_data
=
efx
->
nic_data
;
...
...
@@ -290,7 +289,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx)
return
0
;
}
static
void
falcon_update_stats_xmac
(
struct
efx_nic
*
efx
)
void
falcon_update_stats_xmac
(
struct
efx_nic
*
efx
)
{
struct
efx_mac_stats
*
mac_stats
=
&
efx
->
mac_stats
;
...
...
@@ -361,9 +360,3 @@ void falcon_poll_xmac(struct efx_nic *efx)
nic_data
->
xmac_poll_required
=
!
falcon_xmac_link_ok_retry
(
efx
,
1
);
falcon_ack_status_intr
(
efx
);
}
const
struct
efx_mac_operations
falcon_xmac_operations
=
{
.
reconfigure
=
falcon_reconfigure_xmac
,
.
update_stats
=
falcon_update_stats_xmac
,
.
check_fault
=
falcon_xmac_check_fault
,
};
drivers/net/ethernet/sfc/mac.h
deleted
100644 → 0
View file @
c45a3dfb
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2005-2006 Fen Systems Ltd.
* Copyright 2006-2009 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#ifndef EFX_MAC_H
#define EFX_MAC_H
#include "net_driver.h"
extern
const
struct
efx_mac_operations
falcon_xmac_operations
;
extern
const
struct
efx_mac_operations
efx_mcdi_mac_operations
;
extern
int
efx_mcdi_mac_stats
(
struct
efx_nic
*
efx
,
dma_addr_t
dma_addr
,
u32
dma_len
,
int
enable
,
int
clear
);
#endif
drivers/net/ethernet/sfc/mcdi.c
View file @
30088a25
...
...
@@ -22,22 +22,22 @@
**************************************************************************
*/
/* Software-defined structure to the shared-memory */
#define CMD_NOTIFY_PORT0 0
#define CMD_NOTIFY_PORT1 4
#define CMD_PDU_PORT0 0x008
#define CMD_PDU_PORT1 0x108
#define REBOOT_FLAG_PORT0 0x3f8
#define REBOOT_FLAG_PORT1 0x3fc
#define MCDI_RPC_TIMEOUT 10
/*seconds */
#define MCDI_PDU(efx) \
(efx_port_num(efx) ?
CMD_PDU_PORT1 : CMD_PDU_PORT0
)
(efx_port_num(efx) ?
MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST
)
#define MCDI_DOORBELL(efx) \
(efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0)
#define MCDI_REBOOT_FLAG(efx) \
(efx_port_num(efx) ? REBOOT_FLAG_PORT1 : REBOOT_FLAG_PORT0)
(efx_port_num(efx) ? MC_SMEM_P1_DOORBELL_OFST : MC_SMEM_P0_DOORBELL_OFST)
#define MCDI_STATUS(efx) \
(efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST)
/* A reboot/assertion causes the MCDI status word to be set after the
* command word is set or a REBOOT event is sent. If we notice a reboot
* via these mechanisms then wait 10ms for the status word to be set. */
#define MCDI_STATUS_DELAY_US 100
#define MCDI_STATUS_DELAY_COUNT 100
#define MCDI_STATUS_SLEEP_MS \
(MCDI_STATUS_DELAY_US * MCDI_STATUS_DELAY_COUNT / 1000)
#define SEQ_MASK \
EFX_MASK32(EFX_WIDTH(MCDI_HEADER_SEQ))
...
...
@@ -77,7 +77,7 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
u32
xflags
,
seqno
;
BUG_ON
(
atomic_read
(
&
mcdi
->
state
)
==
MCDI_STATE_QUIESCENT
);
BUG_ON
(
inlen
&
3
||
inlen
>=
0x100
);
BUG_ON
(
inlen
&
3
||
inlen
>=
MC_SMEM_PDU_LEN
);
seqno
=
mcdi
->
seqno
&
SEQ_MASK
;
xflags
=
0
;
...
...
@@ -111,7 +111,7 @@ static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)
int
i
;
BUG_ON
(
atomic_read
(
&
mcdi
->
state
)
==
MCDI_STATE_QUIESCENT
);
BUG_ON
(
outlen
&
3
||
outlen
>=
0x100
);
BUG_ON
(
outlen
&
3
||
outlen
>=
MC_SMEM_PDU_LEN
);
for
(
i
=
0
;
i
<
outlen
;
i
+=
4
)
*
((
__le32
*
)(
outbuf
+
i
))
=
_efx_readd
(
efx
,
pdu
+
4
+
i
);
...
...
@@ -210,7 +210,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
/* Test and clear MC-rebooted flag for this port/function */
int
efx_mcdi_poll_reboot
(
struct
efx_nic
*
efx
)
{
unsigned
int
addr
=
FR_CZ_MC_TREG_SMEM
+
MCDI_
REBOOT_FLAG
(
efx
);
unsigned
int
addr
=
FR_CZ_MC_TREG_SMEM
+
MCDI_
STATUS
(
efx
);
efx_dword_t
reg
;
uint32_t
value
;
...
...
@@ -384,6 +384,11 @@ int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
netif_dbg
(
efx
,
hw
,
efx
->
net_dev
,
"MC command 0x%x inlen %d failed rc=%d
\n
"
,
cmd
,
(
int
)
inlen
,
-
rc
);
if
(
rc
==
-
EIO
||
rc
==
-
EINTR
)
{
msleep
(
MCDI_STATUS_SLEEP_MS
);
efx_mcdi_poll_reboot
(
efx
);
}
}
efx_mcdi_release
(
mcdi
);
...
...
@@ -465,10 +470,20 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc)
mcdi
->
resplen
=
0
;
++
mcdi
->
credits
;
}
}
else
}
else
{
int
count
;
/* Nobody was waiting for an MCDI request, so trigger a reset */
efx_schedule_reset
(
efx
,
RESET_TYPE_MC_FAILURE
);
/* Consume the status word since efx_mcdi_rpc_finish() won't */
for
(
count
=
0
;
count
<
MCDI_STATUS_DELAY_COUNT
;
++
count
)
{
if
(
efx_mcdi_poll_reboot
(
efx
))
break
;
udelay
(
MCDI_STATUS_DELAY_US
);
}
}
spin_unlock
(
&
mcdi
->
iface_lock
);
}
...
...
@@ -502,49 +517,6 @@ static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
efx_link_status_changed
(
efx
);
}
static
const
char
*
sensor_names
[]
=
{
[
MC_CMD_SENSOR_CONTROLLER_TEMP
]
=
"Controller temp. sensor"
,
[
MC_CMD_SENSOR_PHY_COMMON_TEMP
]
=
"PHY shared temp. sensor"
,
[
MC_CMD_SENSOR_CONTROLLER_COOLING
]
=
"Controller cooling"
,
[
MC_CMD_SENSOR_PHY0_TEMP
]
=
"PHY 0 temp. sensor"
,
[
MC_CMD_SENSOR_PHY0_COOLING
]
=
"PHY 0 cooling"
,
[
MC_CMD_SENSOR_PHY1_TEMP
]
=
"PHY 1 temp. sensor"
,
[
MC_CMD_SENSOR_PHY1_COOLING
]
=
"PHY 1 cooling"
,
[
MC_CMD_SENSOR_IN_1V0
]
=
"1.0V supply sensor"
,
[
MC_CMD_SENSOR_IN_1V2
]
=
"1.2V supply sensor"
,
[
MC_CMD_SENSOR_IN_1V8
]
=
"1.8V supply sensor"
,
[
MC_CMD_SENSOR_IN_2V5
]
=
"2.5V supply sensor"
,
[
MC_CMD_SENSOR_IN_3V3
]
=
"3.3V supply sensor"
,
[
MC_CMD_SENSOR_IN_12V0
]
=
"12V supply sensor"
};
static
const
char
*
sensor_status_names
[]
=
{
[
MC_CMD_SENSOR_STATE_OK
]
=
"OK"
,
[
MC_CMD_SENSOR_STATE_WARNING
]
=
"Warning"
,
[
MC_CMD_SENSOR_STATE_FATAL
]
=
"Fatal"
,
[
MC_CMD_SENSOR_STATE_BROKEN
]
=
"Device failure"
,
};
static
void
efx_mcdi_sensor_event
(
struct
efx_nic
*
efx
,
efx_qword_t
*
ev
)
{
unsigned
int
monitor
,
state
,
value
;
const
char
*
name
,
*
state_txt
;
monitor
=
EFX_QWORD_FIELD
(
*
ev
,
MCDI_EVENT_SENSOREVT_MONITOR
);
state
=
EFX_QWORD_FIELD
(
*
ev
,
MCDI_EVENT_SENSOREVT_STATE
);
value
=
EFX_QWORD_FIELD
(
*
ev
,
MCDI_EVENT_SENSOREVT_VALUE
);
/* Deal gracefully with the board having more drivers than we
* know about, but do not expect new sensor states. */
name
=
(
monitor
>=
ARRAY_SIZE
(
sensor_names
))
?
"No sensor name available"
:
sensor_names
[
monitor
];
EFX_BUG_ON_PARANOID
(
state
>=
ARRAY_SIZE
(
sensor_status_names
));
state_txt
=
sensor_status_names
[
state
];
netif_err
(
efx
,
hw
,
efx
->
net_dev
,
"Sensor %d (%s) reports condition '%s' for raw value %d
\n
"
,
monitor
,
name
,
state_txt
,
value
);
}
/* Called from falcon_process_eventq for MCDI events */
void
efx_mcdi_process_event
(
struct
efx_channel
*
channel
,
efx_qword_t
*
event
)
...
...
@@ -604,7 +576,7 @@ void efx_mcdi_process_event(struct efx_channel *channel,
void
efx_mcdi_print_fwver
(
struct
efx_nic
*
efx
,
char
*
buf
,
size_t
len
)
{
u8
outbuf
[
ALIGN
(
MC_CMD_GET_VERSION_
V1_
OUT_LEN
,
4
)];
u8
outbuf
[
ALIGN
(
MC_CMD_GET_VERSION_OUT_LEN
,
4
)];
size_t
outlength
;
const
__le16
*
ver_words
;
int
rc
;
...
...
@@ -616,7 +588,7 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len)
if
(
rc
)
goto
fail
;
if
(
outlength
<
MC_CMD_GET_VERSION_
V1_
OUT_LEN
)
{
if
(
outlength
<
MC_CMD_GET_VERSION_OUT_LEN
)
{
rc
=
-
EIO
;
goto
fail
;
}
...
...
@@ -663,9 +635,9 @@ int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
}
int
efx_mcdi_get_board_cfg
(
struct
efx_nic
*
efx
,
u8
*
mac_address
,
u16
*
fw_subtype_list
)
u16
*
fw_subtype_list
,
u32
*
capabilities
)
{
uint8_t
outbuf
[
MC_CMD_GET_BOARD_CFG_OUT_LEN
];
uint8_t
outbuf
[
MC_CMD_GET_BOARD_CFG_OUT_LEN
MIN
];
size_t
outlen
;
int
port_num
=
efx_port_num
(
efx
);
int
offset
;
...
...
@@ -678,7 +650,7 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
if
(
rc
)
goto
fail
;
if
(
outlen
<
MC_CMD_GET_BOARD_CFG_OUT_LEN
)
{
if
(
outlen
<
MC_CMD_GET_BOARD_CFG_OUT_LEN
MIN
)
{
rc
=
-
EIO
;
goto
fail
;
}
...
...
@@ -691,7 +663,16 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
if
(
fw_subtype_list
)
memcpy
(
fw_subtype_list
,
outbuf
+
MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST
,
MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN
);
MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM
*
sizeof
(
fw_subtype_list
[
0
]));
if
(
capabilities
)
{
if
(
port_num
)
*
capabilities
=
MCDI_DWORD
(
outbuf
,
GET_BOARD_CFG_OUT_CAPABILITIES_PORT1
);
else
*
capabilities
=
MCDI_DWORD
(
outbuf
,
GET_BOARD_CFG_OUT_CAPABILITIES_PORT0
);
}
return
0
;
...
...
@@ -779,7 +760,7 @@ int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
*
size_out
=
MCDI_DWORD
(
outbuf
,
NVRAM_INFO_OUT_SIZE
);
*
erase_size_out
=
MCDI_DWORD
(
outbuf
,
NVRAM_INFO_OUT_ERASESIZE
);
*
protected_out
=
!!
(
MCDI_DWORD
(
outbuf
,
NVRAM_INFO_OUT_FLAGS
)
&
(
1
<<
MC_CMD_NVRAM_PROTECTED_LBN
));
(
1
<<
MC_CMD_NVRAM_
INFO_OUT_
PROTECTED_LBN
));
return
0
;
fail:
...
...
@@ -1060,7 +1041,7 @@ void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
int
efx_mcdi_reset_port
(
struct
efx_nic
*
efx
)
{
int
rc
=
efx_mcdi_rpc
(
efx
,
MC_CMD_
PORT
_RESET
,
NULL
,
0
,
NULL
,
0
,
NULL
);
int
rc
=
efx_mcdi_rpc
(
efx
,
MC_CMD_
ENTITY
_RESET
,
NULL
,
0
,
NULL
,
0
,
NULL
);
if
(
rc
)
netif_err
(
efx
,
hw
,
efx
->
net_dev
,
"%s: failed rc=%d
\n
"
,
__func__
,
rc
);
...
...
drivers/net/ethernet/sfc/mcdi.h
View file @
30088a25
...
...
@@ -56,6 +56,15 @@ struct efx_mcdi_iface {
size_t
resplen
;
};
struct
efx_mcdi_mon
{
struct
efx_buffer
dma_buf
;
struct
mutex
update_lock
;
unsigned
long
last_update
;
struct
device
*
device
;
struct
efx_mcdi_mon_attribute
*
attrs
;
unsigned
int
n_attrs
;
};
extern
void
efx_mcdi_init
(
struct
efx_nic
*
efx
);
extern
int
efx_mcdi_rpc
(
struct
efx_nic
*
efx
,
unsigned
cmd
,
const
u8
*
inbuf
,
...
...
@@ -68,6 +77,7 @@ extern void efx_mcdi_mode_event(struct efx_nic *efx);
extern
void
efx_mcdi_process_event
(
struct
efx_channel
*
channel
,
efx_qword_t
*
event
);
extern
void
efx_mcdi_sensor_event
(
struct
efx_nic
*
efx
,
efx_qword_t
*
ev
);
#define MCDI_PTR2(_buf, _ofst) \
(((u8 *)_buf) + _ofst)
...
...
@@ -83,6 +93,10 @@ extern void efx_mcdi_process_event(struct efx_channel *channel,
#define MCDI_PTR(_buf, _ofst) \
MCDI_PTR2(_buf, MC_CMD_ ## _ofst ## _OFST)
#define MCDI_ARRAY_PTR(_buf, _field, _type, _index) \
MCDI_PTR2(_buf, \
MC_CMD_ ## _field ## _OFST + \
(_index) * MC_CMD_ ## _type ## _TYPEDEF_LEN)
#define MCDI_SET_DWORD(_buf, _ofst, _value) \
MCDI_SET_DWORD2(_buf, MC_CMD_ ## _ofst ## _OFST, _value)
#define MCDI_DWORD(_buf, _ofst) \
...
...
@@ -92,12 +106,18 @@ extern void efx_mcdi_process_event(struct efx_channel *channel,
#define MCDI_EVENT_FIELD(_ev, _field) \
EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
#define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2) \
EFX_DWORD_FIELD( \
*((efx_dword_t *) \
(MCDI_ARRAY_PTR(_buf, _field1, _type, _index) + \
(MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _OFST & ~3))), \
MC_CMD_ ## _type ## _TYPEDEF_ ## _field2)
extern
void
efx_mcdi_print_fwver
(
struct
efx_nic
*
efx
,
char
*
buf
,
size_t
len
);
extern
int
efx_mcdi_drv_attach
(
struct
efx_nic
*
efx
,
bool
driver_operating
,
bool
*
was_attached_out
);
extern
int
efx_mcdi_get_board_cfg
(
struct
efx_nic
*
efx
,
u8
*
mac_address
,
u16
*
fw_subtype_list
);
u16
*
fw_subtype_list
,
u32
*
capabilities
);
extern
int
efx_mcdi_log_ctrl
(
struct
efx_nic
*
efx
,
bool
evq
,
bool
uart
,
u32
dest_evq
);
extern
int
efx_mcdi_nvram_types
(
struct
efx_nic
*
efx
,
u32
*
nvram_types_out
);
...
...
@@ -126,5 +146,17 @@ extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx,
extern
int
efx_mcdi_wol_filter_get_magic
(
struct
efx_nic
*
efx
,
int
*
id_out
);
extern
int
efx_mcdi_wol_filter_remove
(
struct
efx_nic
*
efx
,
int
id
);
extern
int
efx_mcdi_wol_filter_reset
(
struct
efx_nic
*
efx
);
extern
int
efx_mcdi_mac_stats
(
struct
efx_nic
*
efx
,
dma_addr_t
dma_addr
,
u32
dma_len
,
int
enable
,
int
clear
);
extern
int
efx_mcdi_mac_reconfigure
(
struct
efx_nic
*
efx
);
extern
bool
efx_mcdi_mac_check_fault
(
struct
efx_nic
*
efx
);
#ifdef CONFIG_SFC_MCDI_MON
extern
int
efx_mcdi_mon_probe
(
struct
efx_nic
*
efx
);
extern
void
efx_mcdi_mon_remove
(
struct
efx_nic
*
efx
);
#else
static
inline
int
efx_mcdi_mon_probe
(
struct
efx_nic
*
efx
)
{
return
0
;
}
static
inline
void
efx_mcdi_mon_remove
(
struct
efx_nic
*
efx
)
{}
#endif
#endif
/* EFX_MCDI_H */
drivers/net/ethernet/sfc/mcdi_mac.c
View file @
30088a25
...
...
@@ -9,7 +9,6 @@
#include "net_driver.h"
#include "efx.h"
#include "mac.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
...
...
@@ -52,7 +51,7 @@ static int efx_mcdi_set_mac(struct efx_nic *efx)
NULL
,
0
,
NULL
);
}
static
int
efx_mcdi_get_mac_faults
(
struct
efx_nic
*
efx
,
u32
*
faults
)
bool
efx_mcdi_mac_check_fault
(
struct
efx_nic
*
efx
)
{
u8
outbuf
[
MC_CMD_GET_LINK_OUT_LEN
];
size_t
outlength
;
...
...
@@ -62,16 +61,13 @@ static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults)
rc
=
efx_mcdi_rpc
(
efx
,
MC_CMD_GET_LINK
,
NULL
,
0
,
outbuf
,
sizeof
(
outbuf
),
&
outlength
);
if
(
rc
)
goto
fail
;
*
faults
=
MCDI_DWORD
(
outbuf
,
GET_LINK_OUT_MAC_FAULT
)
;
return
0
;
if
(
rc
)
{
netif_err
(
efx
,
hw
,
efx
->
net_dev
,
"%s: failed rc=%d
\n
"
,
__func__
,
rc
);
return
true
;
}
fail:
netif_err
(
efx
,
hw
,
efx
->
net_dev
,
"%s: failed rc=%d
\n
"
,
__func__
,
rc
);
return
rc
;
return
MCDI_DWORD
(
outbuf
,
GET_LINK_OUT_MAC_FAULT
)
!=
0
;
}
int
efx_mcdi_mac_stats
(
struct
efx_nic
*
efx
,
dma_addr_t
dma_addr
,
...
...
@@ -84,7 +80,7 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
u32
addr_hi
;
u32
addr_lo
;
BUILD_BUG_ON
(
MC_CMD_MAC_STATS_OUT_LEN
!=
0
);
BUILD_BUG_ON
(
MC_CMD_MAC_STATS_OUT_
DMA_
LEN
!=
0
);
addr_lo
=
((
u64
)
dma_addr
)
>>
0
;
addr_hi
=
((
u64
)
dma_addr
)
>>
32
;
...
...
@@ -93,13 +89,13 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
MCDI_SET_DWORD
(
inbuf
,
MAC_STATS_IN_DMA_ADDR_HI
,
addr_hi
);
cmd_ptr
=
(
efx_dword_t
*
)
MCDI_PTR
(
inbuf
,
MAC_STATS_IN_CMD
);
EFX_POPULATE_DWORD_7
(
*
cmd_ptr
,
MC_CMD_MAC_STATS_
CMD
_DMA
,
!!
enable
,
MC_CMD_MAC_STATS_
CMD
_CLEAR
,
clear
,
MC_CMD_MAC_STATS_
CMD
_PERIODIC_CHANGE
,
1
,
MC_CMD_MAC_STATS_
CMD
_PERIODIC_ENABLE
,
!!
enable
,
MC_CMD_MAC_STATS_
CMD
_PERIODIC_CLEAR
,
0
,
MC_CMD_MAC_STATS_
CMD
_PERIODIC_NOEVENT
,
1
,
MC_CMD_MAC_STATS_
CMD
_PERIOD_MS
,
period
);
MC_CMD_MAC_STATS_
IN
_DMA
,
!!
enable
,
MC_CMD_MAC_STATS_
IN
_CLEAR
,
clear
,
MC_CMD_MAC_STATS_
IN
_PERIODIC_CHANGE
,
1
,
MC_CMD_MAC_STATS_
IN
_PERIODIC_ENABLE
,
!!
enable
,
MC_CMD_MAC_STATS_
IN
_PERIODIC_CLEAR
,
0
,
MC_CMD_MAC_STATS_
IN
_PERIODIC_NOEVENT
,
1
,
MC_CMD_MAC_STATS_
IN
_PERIOD_MS
,
period
);
MCDI_SET_DWORD
(
inbuf
,
MAC_STATS_IN_DMA_LEN
,
dma_len
);
rc
=
efx_mcdi_rpc
(
efx
,
MC_CMD_MAC_STATS
,
inbuf
,
sizeof
(
inbuf
),
...
...
@@ -115,31 +111,18 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
return
rc
;
}
static
int
efx_mcdi_mac_reconfigure
(
struct
efx_nic
*
efx
)
int
efx_mcdi_mac_reconfigure
(
struct
efx_nic
*
efx
)
{
int
rc
;
WARN_ON
(
!
mutex_is_locked
(
&
efx
->
mac_lock
));
rc
=
efx_mcdi_set_mac
(
efx
);
if
(
rc
!=
0
)
return
rc
;
/* Restore the multicast hash registers. */
efx
->
type
->
push_multicast_hash
(
efx
);
return
0
;
}
static
bool
efx_mcdi_mac_check_fault
(
struct
efx_nic
*
efx
)
{
u32
faults
;
int
rc
=
efx_mcdi_get_mac_faults
(
efx
,
&
faults
);
return
(
rc
!=
0
)
||
(
faults
!=
0
);
return
efx_mcdi_rpc
(
efx
,
MC_CMD_SET_MCAST_HASH
,
efx
->
multicast_hash
.
byte
,
sizeof
(
efx
->
multicast_hash
),
NULL
,
0
,
NULL
);
}
const
struct
efx_mac_operations
efx_mcdi_mac_operations
=
{
.
reconfigure
=
efx_mcdi_mac_reconfigure
,
.
update_stats
=
efx_port_dummy_op_void
,
.
check_fault
=
efx_mcdi_mac_check_fault
,
};
drivers/net/ethernet/sfc/mcdi_mon.c
0 → 100644
View file @
30088a25
/****************************************************************************
* Driver for Solarflare Solarstorm network controllers and boards
* Copyright 2011 Solarflare Communications Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation, incorporated herein by reference.
*/
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/hwmon.h>
#include <linux/stat.h>
#include "net_driver.h"
#include "mcdi.h"
#include "mcdi_pcol.h"
#include "nic.h"
enum
efx_hwmon_type
{
EFX_HWMON_UNKNOWN
,
EFX_HWMON_TEMP
,
/* temperature */
EFX_HWMON_COOL
,
/* cooling device, probably a heatsink */
EFX_HWMON_IN
/* input voltage */
};
static
const
struct
{
const
char
*
label
;
enum
efx_hwmon_type
hwmon_type
;
int
port
;
}
efx_mcdi_sensor_type
[
MC_CMD_SENSOR_ENTRY_MAXNUM
]
=
{
#define SENSOR(name, label, hwmon_type, port) \
[MC_CMD_SENSOR_##name] = { label, hwmon_type, port }
SENSOR
(
CONTROLLER_TEMP
,
"Controller temp."
,
EFX_HWMON_TEMP
,
-
1
),
SENSOR
(
PHY_COMMON_TEMP
,
"PHY temp."
,
EFX_HWMON_TEMP
,
-
1
),
SENSOR
(
CONTROLLER_COOLING
,
"Controller cooling"
,
EFX_HWMON_COOL
,
-
1
),
SENSOR
(
PHY0_TEMP
,
"PHY temp."
,
EFX_HWMON_TEMP
,
0
),
SENSOR
(
PHY0_COOLING
,
"PHY cooling"
,
EFX_HWMON_COOL
,
0
),
SENSOR
(
PHY1_TEMP
,
"PHY temp."
,
EFX_HWMON_TEMP
,
1
),
SENSOR
(
PHY1_COOLING
,
"PHY cooling"
,
EFX_HWMON_COOL
,
1
),
SENSOR
(
IN_1V0
,
"1.0V supply"
,
EFX_HWMON_IN
,
-
1
),
SENSOR
(
IN_1V2
,
"1.2V supply"
,
EFX_HWMON_IN
,
-
1
),
SENSOR
(
IN_1V8
,
"1.8V supply"
,
EFX_HWMON_IN
,
-
1
),
SENSOR
(
IN_2V5
,
"2.5V supply"
,
EFX_HWMON_IN
,
-
1
),
SENSOR
(
IN_3V3
,
"3.3V supply"
,
EFX_HWMON_IN
,
-
1
),
SENSOR
(
IN_12V0
,
"12.0V supply"
,
EFX_HWMON_IN
,
-
1
),
SENSOR
(
IN_1V2A
,
"1.2V analogue supply"
,
EFX_HWMON_IN
,
-
1
),
SENSOR
(
IN_VREF
,
"ref. voltage"
,
EFX_HWMON_IN
,
-
1
),
#undef SENSOR
};
static
const
char
*
const
sensor_status_names
[]
=
{
[
MC_CMD_SENSOR_STATE_OK
]
=
"OK"
,
[
MC_CMD_SENSOR_STATE_WARNING
]
=
"Warning"
,
[
MC_CMD_SENSOR_STATE_FATAL
]
=
"Fatal"
,
[
MC_CMD_SENSOR_STATE_BROKEN
]
=
"Device failure"
,
};
void
efx_mcdi_sensor_event
(
struct
efx_nic
*
efx
,
efx_qword_t
*
ev
)
{
unsigned
int
type
,
state
,
value
;
const
char
*
name
=
NULL
,
*
state_txt
;
type
=
EFX_QWORD_FIELD
(
*
ev
,
MCDI_EVENT_SENSOREVT_MONITOR
);
state
=
EFX_QWORD_FIELD
(
*
ev
,
MCDI_EVENT_SENSOREVT_STATE
);
value
=
EFX_QWORD_FIELD
(
*
ev
,
MCDI_EVENT_SENSOREVT_VALUE
);
/* Deal gracefully with the board having more drivers than we
* know about, but do not expect new sensor states. */
if
(
type
<
ARRAY_SIZE
(
efx_mcdi_sensor_type
))
name
=
efx_mcdi_sensor_type
[
type
].
label
;
if
(
!
name
)
name
=
"No sensor name available"
;
EFX_BUG_ON_PARANOID
(
state
>=
ARRAY_SIZE
(
sensor_status_names
));
state_txt
=
sensor_status_names
[
state
];
netif_err
(
efx
,
hw
,
efx
->
net_dev
,
"Sensor %d (%s) reports condition '%s' for raw value %d
\n
"
,
type
,
name
,
state_txt
,
value
);
}
#ifdef CONFIG_SFC_MCDI_MON
struct
efx_mcdi_mon_attribute
{
struct
device_attribute
dev_attr
;
unsigned
int
index
;
unsigned
int
type
;
unsigned
int
limit_value
;
char
name
[
12
];
};
static
int
efx_mcdi_mon_update
(
struct
efx_nic
*
efx
)
{
struct
efx_mcdi_mon
*
hwmon
=
efx_mcdi_mon
(
efx
);
u8
inbuf
[
MC_CMD_READ_SENSORS_IN_LEN
];
int
rc
;
MCDI_SET_DWORD
(
inbuf
,
READ_SENSORS_IN_DMA_ADDR_LO
,
hwmon
->
dma_buf
.
dma_addr
&
0xffffffff
);
MCDI_SET_DWORD
(
inbuf
,
READ_SENSORS_IN_DMA_ADDR_HI
,
(
u64
)
hwmon
->
dma_buf
.
dma_addr
>>
32
);
rc
=
efx_mcdi_rpc
(
efx
,
MC_CMD_READ_SENSORS
,
inbuf
,
sizeof
(
inbuf
),
NULL
,
0
,
NULL
);
if
(
rc
==
0
)
hwmon
->
last_update
=
jiffies
;
return
rc
;
}
static
ssize_t
efx_mcdi_mon_show_name
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
return
sprintf
(
buf
,
"%s
\n
"
,
KBUILD_MODNAME
);
}
static
int
efx_mcdi_mon_get_entry
(
struct
device
*
dev
,
unsigned
int
index
,
efx_dword_t
*
entry
)
{
struct
efx_nic
*
efx
=
dev_get_drvdata
(
dev
);
struct
efx_mcdi_mon
*
hwmon
=
efx_mcdi_mon
(
efx
);
int
rc
;
BUILD_BUG_ON
(
MC_CMD_READ_SENSORS_OUT_LEN
!=
0
);
mutex_lock
(
&
hwmon
->
update_lock
);
/* Use cached value if last update was < 1 s ago */
if
(
time_before
(
jiffies
,
hwmon
->
last_update
+
HZ
))
rc
=
0
;
else
rc
=
efx_mcdi_mon_update
(
efx
);
/* Copy out the requested entry */
*
entry
=
((
efx_dword_t
*
)
hwmon
->
dma_buf
.
addr
)[
index
];
mutex_unlock
(
&
hwmon
->
update_lock
);
return
rc
;
}
static
ssize_t
efx_mcdi_mon_show_value
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
efx_mcdi_mon_attribute
*
mon_attr
=
container_of
(
attr
,
struct
efx_mcdi_mon_attribute
,
dev_attr
);
efx_dword_t
entry
;
unsigned
int
value
;
int
rc
;
rc
=
efx_mcdi_mon_get_entry
(
dev
,
mon_attr
->
index
,
&
entry
);
if
(
rc
)
return
rc
;
value
=
EFX_DWORD_FIELD
(
entry
,
MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE
);
/* Convert temperature from degrees to milli-degrees Celsius */
if
(
efx_mcdi_sensor_type
[
mon_attr
->
type
].
hwmon_type
==
EFX_HWMON_TEMP
)
value
*=
1000
;
return
sprintf
(
buf
,
"%u
\n
"
,
value
);
}
static
ssize_t
efx_mcdi_mon_show_limit
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
efx_mcdi_mon_attribute
*
mon_attr
=
container_of
(
attr
,
struct
efx_mcdi_mon_attribute
,
dev_attr
);
unsigned
int
value
;
value
=
mon_attr
->
limit_value
;
/* Convert temperature from degrees to milli-degrees Celsius */
if
(
efx_mcdi_sensor_type
[
mon_attr
->
type
].
hwmon_type
==
EFX_HWMON_TEMP
)
value
*=
1000
;
return
sprintf
(
buf
,
"%u
\n
"
,
value
);
}
static
ssize_t
efx_mcdi_mon_show_alarm
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
efx_mcdi_mon_attribute
*
mon_attr
=
container_of
(
attr
,
struct
efx_mcdi_mon_attribute
,
dev_attr
);
efx_dword_t
entry
;
int
state
;
int
rc
;
rc
=
efx_mcdi_mon_get_entry
(
dev
,
mon_attr
->
index
,
&
entry
);
if
(
rc
)
return
rc
;
state
=
EFX_DWORD_FIELD
(
entry
,
MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE
);
return
sprintf
(
buf
,
"%d
\n
"
,
state
!=
MC_CMD_SENSOR_STATE_OK
);
}
static
ssize_t
efx_mcdi_mon_show_label
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
efx_mcdi_mon_attribute
*
mon_attr
=
container_of
(
attr
,
struct
efx_mcdi_mon_attribute
,
dev_attr
);
return
sprintf
(
buf
,
"%s
\n
"
,
efx_mcdi_sensor_type
[
mon_attr
->
type
].
label
);
}
static
int
efx_mcdi_mon_add_attr
(
struct
efx_nic
*
efx
,
const
char
*
name
,
ssize_t
(
*
reader
)(
struct
device
*
,
struct
device_attribute
*
,
char
*
),
unsigned
int
index
,
unsigned
int
type
,
unsigned
int
limit_value
)
{
struct
efx_mcdi_mon
*
hwmon
=
efx_mcdi_mon
(
efx
);
struct
efx_mcdi_mon_attribute
*
attr
=
&
hwmon
->
attrs
[
hwmon
->
n_attrs
];
int
rc
;
strlcpy
(
attr
->
name
,
name
,
sizeof
(
attr
->
name
));
attr
->
index
=
index
;
attr
->
type
=
type
;
attr
->
limit_value
=
limit_value
;
attr
->
dev_attr
.
attr
.
name
=
attr
->
name
;
attr
->
dev_attr
.
attr
.
mode
=
S_IRUGO
;
attr
->
dev_attr
.
show
=
reader
;
rc
=
device_create_file
(
&
efx
->
pci_dev
->
dev
,
&
attr
->
dev_attr
);
if
(
rc
==
0
)
++
hwmon
->
n_attrs
;
return
rc
;
}
int
efx_mcdi_mon_probe
(
struct
efx_nic
*
efx
)
{
struct
efx_mcdi_mon
*
hwmon
=
efx_mcdi_mon
(
efx
);
unsigned
int
n_attrs
,
n_temp
=
0
,
n_cool
=
0
,
n_in
=
0
;
u8
outbuf
[
MC_CMD_SENSOR_INFO_OUT_LENMAX
];
size_t
outlen
;
char
name
[
12
];
u32
mask
;
int
rc
,
i
,
type
;
BUILD_BUG_ON
(
MC_CMD_SENSOR_INFO_IN_LEN
!=
0
);
rc
=
efx_mcdi_rpc
(
efx
,
MC_CMD_SENSOR_INFO
,
NULL
,
0
,
outbuf
,
sizeof
(
outbuf
),
&
outlen
);
if
(
rc
)
return
rc
;
if
(
outlen
<
MC_CMD_SENSOR_INFO_OUT_LENMIN
)
return
-
EIO
;
/* Find out which sensors are present. Don't create a device
* if there are none.
*/
mask
=
MCDI_DWORD
(
outbuf
,
SENSOR_INFO_OUT_MASK
);
if
(
mask
==
0
)
return
0
;
/* Check again for short response */
if
(
outlen
<
MC_CMD_SENSOR_INFO_OUT_LEN
(
hweight32
(
mask
)))
return
-
EIO
;
rc
=
efx_nic_alloc_buffer
(
efx
,
&
hwmon
->
dma_buf
,
4
*
MC_CMD_SENSOR_ENTRY_MAXNUM
);
if
(
rc
)
return
rc
;
mutex_init
(
&
hwmon
->
update_lock
);
efx_mcdi_mon_update
(
efx
);
/* Allocate space for the maximum possible number of
* attributes for this set of sensors: name of the driver plus
* value, min, max, crit, alarm and label for each sensor.
*/
n_attrs
=
1
+
6
*
hweight32
(
mask
);
hwmon
->
attrs
=
kcalloc
(
n_attrs
,
sizeof
(
*
hwmon
->
attrs
),
GFP_KERNEL
);
if
(
!
hwmon
->
attrs
)
{
rc
=
-
ENOMEM
;
goto
fail
;
}
hwmon
->
device
=
hwmon_device_register
(
&
efx
->
pci_dev
->
dev
);
if
(
IS_ERR
(
hwmon
->
device
))
{
rc
=
PTR_ERR
(
hwmon
->
device
);
goto
fail
;
}
rc
=
efx_mcdi_mon_add_attr
(
efx
,
"name"
,
efx_mcdi_mon_show_name
,
0
,
0
,
0
);
if
(
rc
)
goto
fail
;
for
(
i
=
0
,
type
=
-
1
;
;
i
++
)
{
const
char
*
hwmon_prefix
;
unsigned
hwmon_index
;
u16
min1
,
max1
,
min2
,
max2
;
/* Find next sensor type or exit if there is none */
type
++
;
while
(
!
(
mask
&
(
1
<<
type
)))
{
type
++
;
if
(
type
==
32
)
return
0
;
}
/* Skip sensors specific to a different port */
if
(
efx_mcdi_sensor_type
[
type
].
hwmon_type
!=
EFX_HWMON_UNKNOWN
&&
efx_mcdi_sensor_type
[
type
].
port
>=
0
&&
efx_mcdi_sensor_type
[
type
].
port
!=
efx_port_num
(
efx
))
continue
;
switch
(
efx_mcdi_sensor_type
[
type
].
hwmon_type
)
{
case
EFX_HWMON_TEMP
:
hwmon_prefix
=
"temp"
;
hwmon_index
=
++
n_temp
;
/* 1-based */
break
;
case
EFX_HWMON_COOL
:
/* This is likely to be a heatsink, but there
* is no convention for representing cooling
* devices other than fans.
*/
hwmon_prefix
=
"fan"
;
hwmon_index
=
++
n_cool
;
/* 1-based */
break
;
default:
hwmon_prefix
=
"in"
;
hwmon_index
=
n_in
++
;
/* 0-based */
break
;
}
min1
=
MCDI_ARRAY_FIELD
(
outbuf
,
SENSOR_ENTRY
,
SENSOR_INFO_ENTRY
,
i
,
MIN1
);
max1
=
MCDI_ARRAY_FIELD
(
outbuf
,
SENSOR_ENTRY
,
SENSOR_INFO_ENTRY
,
i
,
MAX1
);
min2
=
MCDI_ARRAY_FIELD
(
outbuf
,
SENSOR_ENTRY
,
SENSOR_INFO_ENTRY
,
i
,
MIN2
);
max2
=
MCDI_ARRAY_FIELD
(
outbuf
,
SENSOR_ENTRY
,
SENSOR_INFO_ENTRY
,
i
,
MAX2
);
if
(
min1
!=
max1
)
{
snprintf
(
name
,
sizeof
(
name
),
"%s%u_input"
,
hwmon_prefix
,
hwmon_index
);
rc
=
efx_mcdi_mon_add_attr
(
efx
,
name
,
efx_mcdi_mon_show_value
,
i
,
type
,
0
);
if
(
rc
)
goto
fail
;
snprintf
(
name
,
sizeof
(
name
),
"%s%u_min"
,
hwmon_prefix
,
hwmon_index
);
rc
=
efx_mcdi_mon_add_attr
(
efx
,
name
,
efx_mcdi_mon_show_limit
,
i
,
type
,
min1
);
if
(
rc
)
goto
fail
;
snprintf
(
name
,
sizeof
(
name
),
"%s%u_max"
,
hwmon_prefix
,
hwmon_index
);
rc
=
efx_mcdi_mon_add_attr
(
efx
,
name
,
efx_mcdi_mon_show_limit
,
i
,
type
,
max1
);
if
(
rc
)
goto
fail
;
if
(
min2
!=
max2
)
{
/* Assume max2 is critical value.
* But we have no good way to expose min2.
*/
snprintf
(
name
,
sizeof
(
name
),
"%s%u_crit"
,
hwmon_prefix
,
hwmon_index
);
rc
=
efx_mcdi_mon_add_attr
(
efx
,
name
,
efx_mcdi_mon_show_limit
,
i
,
type
,
max2
);
if
(
rc
)
goto
fail
;
}
}
snprintf
(
name
,
sizeof
(
name
),
"%s%u_alarm"
,
hwmon_prefix
,
hwmon_index
);
rc
=
efx_mcdi_mon_add_attr
(
efx
,
name
,
efx_mcdi_mon_show_alarm
,
i
,
type
,
0
);
if
(
rc
)
goto
fail
;
if
(
efx_mcdi_sensor_type
[
type
].
label
)
{
snprintf
(
name
,
sizeof
(
name
),
"%s%u_label"
,
hwmon_prefix
,
hwmon_index
);
rc
=
efx_mcdi_mon_add_attr
(
efx
,
name
,
efx_mcdi_mon_show_label
,
i
,
type
,
0
);
if
(
rc
)
goto
fail
;
}
}
fail:
efx_mcdi_mon_remove
(
efx
);
return
rc
;
}
void
efx_mcdi_mon_remove
(
struct
efx_nic
*
efx
)
{
struct
siena_nic_data
*
nic_data
=
efx
->
nic_data
;
struct
efx_mcdi_mon
*
hwmon
=
&
nic_data
->
hwmon
;
unsigned
int
i
;
for
(
i
=
0
;
i
<
hwmon
->
n_attrs
;
i
++
)
device_remove_file
(
&
efx
->
pci_dev
->
dev
,
&
hwmon
->
attrs
[
i
].
dev_attr
);
kfree
(
hwmon
->
attrs
);
if
(
hwmon
->
device
)
hwmon_device_unregister
(
hwmon
->
device
);
efx_nic_free_buffer
(
efx
,
&
hwmon
->
dma_buf
);
}
#endif
/* CONFIG_SFC_MCDI_MON */
drivers/net/ethernet/sfc/mcdi_pcol.h
View file @
30088a25
This source diff could not be displayed because it is too large. You can
view the blob
instead.
drivers/net/ethernet/sfc/mcdi_phy.c
View file @
30088a25
...
...
@@ -116,7 +116,7 @@ static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
goto
fail
;
}
*
loopback_modes
=
MCDI_QWORD
(
outbuf
,
GET_LOOPBACK_MODES_SUGGESTED
);
*
loopback_modes
=
MCDI_QWORD
(
outbuf
,
GET_LOOPBACK_MODES_
OUT_
SUGGESTED
);
return
0
;
...
...
@@ -264,22 +264,22 @@ static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
/* TODO: Advertise the capabilities supported by this PHY */
supported
=
0
;
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_TXDIS_LBN
))
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
TXDIS_LBN
))
supported
|=
PHY_MODE_TX_DISABLED
;
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_LOWPOWER_LBN
))
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
LOWPOWER_LBN
))
supported
|=
PHY_MODE_LOW_POWER
;
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_POWEROFF_LBN
))
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
POWEROFF_LBN
))
supported
|=
PHY_MODE_OFF
;
mode
=
efx
->
phy_mode
&
supported
;
flags
=
0
;
if
(
mode
&
PHY_MODE_TX_DISABLED
)
flags
|=
(
1
<<
MC_CMD_SET_LINK_TXDIS_LBN
);
flags
|=
(
1
<<
MC_CMD_SET_LINK_
IN_
TXDIS_LBN
);
if
(
mode
&
PHY_MODE_LOW_POWER
)
flags
|=
(
1
<<
MC_CMD_SET_LINK_LOWPOWER_LBN
);
flags
|=
(
1
<<
MC_CMD_SET_LINK_
IN_
LOWPOWER_LBN
);
if
(
mode
&
PHY_MODE_OFF
)
flags
|=
(
1
<<
MC_CMD_SET_LINK_POWEROFF_LBN
);
flags
|=
(
1
<<
MC_CMD_SET_LINK_
IN_
POWEROFF_LBN
);
return
flags
;
}
...
...
@@ -436,8 +436,8 @@ void efx_mcdi_phy_decode_link(struct efx_nic *efx,
break
;
}
link_state
->
up
=
!!
(
flags
&
(
1
<<
MC_CMD_GET_LINK_LINK_UP_LBN
));
link_state
->
fd
=
!!
(
flags
&
(
1
<<
MC_CMD_GET_LINK_FULL_DUPLEX_LBN
));
link_state
->
up
=
!!
(
flags
&
(
1
<<
MC_CMD_GET_LINK_
OUT_
LINK_UP_LBN
));
link_state
->
fd
=
!!
(
flags
&
(
1
<<
MC_CMD_GET_LINK_
OUT_
FULL_DUPLEX_LBN
));
link_state
->
speed
=
speed
;
}
...
...
@@ -592,7 +592,7 @@ static int efx_mcdi_phy_test_alive(struct efx_nic *efx)
if
(
outlen
<
MC_CMD_GET_PHY_STATE_OUT_LEN
)
return
-
EIO
;
if
(
MCDI_DWORD
(
outbuf
,
GET_PHY_STATE_STATE
)
!=
MC_CMD_PHY_STATE_OK
)
if
(
MCDI_DWORD
(
outbuf
,
GET_PHY_STATE_
OUT_
STATE
)
!=
MC_CMD_PHY_STATE_OK
)
return
-
EINVAL
;
return
0
;
...
...
@@ -680,7 +680,7 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results,
u32
mode
;
int
rc
;
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_BIST_LBN
))
{
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
BIST_LBN
))
{
rc
=
efx_mcdi_bist
(
efx
,
MC_CMD_PHY_BIST
,
results
);
if
(
rc
<
0
)
return
rc
;
...
...
@@ -691,15 +691,15 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results,
/* If we support both LONG and SHORT, then run each in response to
* break or not. Otherwise, run the one we support */
mode
=
0
;
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN
))
{
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
BIST_CABLE_SHORT_LBN
))
{
if
((
flags
&
ETH_TEST_FL_OFFLINE
)
&&
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN
)))
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
BIST_CABLE_LONG_LBN
)))
mode
=
MC_CMD_PHY_BIST_CABLE_LONG
;
else
mode
=
MC_CMD_PHY_BIST_CABLE_SHORT
;
}
else
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN
))
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
BIST_CABLE_LONG_LBN
))
mode
=
MC_CMD_PHY_BIST_CABLE_LONG
;
if
(
mode
!=
0
)
{
...
...
@@ -717,14 +717,14 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
{
struct
efx_mcdi_phy_data
*
phy_cfg
=
efx
->
phy_data
;
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_BIST_LBN
))
{
if
(
phy_cfg
->
flags
&
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
BIST_LBN
))
{
if
(
index
==
0
)
return
"bist"
;
--
index
;
}
if
(
phy_cfg
->
flags
&
((
1
<<
MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN
)
|
(
1
<<
MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN
)))
{
if
(
phy_cfg
->
flags
&
((
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
BIST_CABLE_SHORT_LBN
)
|
(
1
<<
MC_CMD_GET_PHY_CFG_
OUT_
BIST_CABLE_LONG_LBN
)))
{
if
(
index
==
0
)
return
"cable"
;
--
index
;
...
...
@@ -741,7 +741,7 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
const
struct
efx_phy_operations
efx_mcdi_phy_ops
=
{
.
probe
=
efx_mcdi_phy_probe
,
.
init
=
efx_port_dummy_op_int
,
.
init
=
efx_port_dummy_op_int
,
.
reconfigure
=
efx_mcdi_phy_reconfigure
,
.
poll
=
efx_mcdi_phy_poll
,
.
fini
=
efx_port_dummy_op_void
,
...
...
drivers/net/ethernet/sfc/mdio_10g.c
View file @
30088a25
...
...
@@ -228,7 +228,7 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
/**
* efx_mdio_set_settings - Set (some of) the PHY settings over MDIO.
* @efx: Efx NIC
* @ecmd:
New settings
* @ecmd: New settings
*/
int
efx_mdio_set_settings
(
struct
efx_nic
*
efx
,
struct
ethtool_cmd
*
ecmd
)
{
...
...
drivers/net/ethernet/sfc/mtd.c
View file @
30088a25
...
...
@@ -10,6 +10,7 @@
#include <linux/bitops.h>
#include <linux/module.h>
#undef DEBUG
/* <linux/mtd/mtd.h> has its own use for DEBUG */
#include <linux/mtd/mtd.h>
#include <linux/delay.h>
#include <linux/slab.h>
...
...
@@ -382,7 +383,7 @@ static int falcon_mtd_sync(struct mtd_info *mtd)
return
rc
;
}
static
struct
efx_mtd_ops
falcon_mtd_ops
=
{
static
const
struct
efx_mtd_ops
falcon_mtd_ops
=
{
.
read
=
falcon_mtd_read
,
.
erase
=
falcon_mtd_erase
,
.
write
=
falcon_mtd_write
,
...
...
@@ -560,7 +561,7 @@ static int siena_mtd_sync(struct mtd_info *mtd)
return
rc
;
}
static
struct
efx_mtd_ops
siena_mtd_ops
=
{
static
const
struct
efx_mtd_ops
siena_mtd_ops
=
{
.
read
=
siena_mtd_read
,
.
erase
=
siena_mtd_erase
,
.
write
=
siena_mtd_write
,
...
...
@@ -572,7 +573,7 @@ struct siena_nvram_type_info {
const
char
*
name
;
};
static
struct
siena_nvram_type_info
siena_nvram_types
[]
=
{
static
const
struct
siena_nvram_type_info
siena_nvram_types
[]
=
{
[
MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO
]
=
{
0
,
"sfc_dummy_phy"
},
[
MC_CMD_NVRAM_TYPE_MC_FW
]
=
{
0
,
"sfc_mcfw"
},
[
MC_CMD_NVRAM_TYPE_MC_FW_BACKUP
]
=
{
0
,
"sfc_mcfw_backup"
},
...
...
@@ -593,7 +594,7 @@ static int siena_mtd_probe_partition(struct efx_nic *efx,
unsigned
int
type
)
{
struct
efx_mtd_partition
*
part
=
&
efx_mtd
->
part
[
part_id
];
struct
siena_nvram_type_info
*
info
;
const
struct
siena_nvram_type_info
*
info
;
size_t
size
,
erase_size
;
bool
protected
;
int
rc
;
...
...
@@ -627,11 +628,10 @@ static int siena_mtd_get_fw_subtypes(struct efx_nic *efx,
struct
efx_mtd
*
efx_mtd
)
{
struct
efx_mtd_partition
*
part
;
uint16_t
fw_subtype_list
[
MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN
/
sizeof
(
uint16_t
)];
uint16_t
fw_subtype_list
[
MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM
];
int
rc
;
rc
=
efx_mcdi_get_board_cfg
(
efx
,
NULL
,
fw_subtype_list
);
rc
=
efx_mcdi_get_board_cfg
(
efx
,
NULL
,
fw_subtype_list
,
NULL
);
if
(
rc
)
return
rc
;
...
...
drivers/net/ethernet/sfc/net_driver.h
View file @
30088a25
...
...
@@ -13,10 +13,6 @@
#ifndef EFX_NET_DRIVER_H
#define EFX_NET_DRIVER_H
#if defined(EFX_ENABLE_DEBUG) && !defined(DEBUG)
#define DEBUG
#endif
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
...
...
@@ -42,7 +38,7 @@
#define EFX_DRIVER_VERSION "3.1"
#ifdef
EFX_ENABLE_
DEBUG
#ifdef DEBUG
#define EFX_BUG_ON_PARANOID(x) BUG_ON(x)
#define EFX_WARN_ON_PARANOID(x) WARN_ON(x)
#else
...
...
@@ -209,12 +205,12 @@ struct efx_tx_queue {
/**
* struct efx_rx_buffer - An Efx RX data buffer
* @dma_addr: DMA base address of the buffer
* @skb: The associated socket buffer
, if any
.
*
If both this and page are %NULL,
the buffer slot is currently free.
* @page: The associated page buffer
, if any
.
*
If both this and skb are %NULL,
the buffer slot is currently free.
* @skb: The associated socket buffer
. Valid iff !(@flags & %EFX_RX_BUF_PAGE)
.
*
Will be %NULL if
the buffer slot is currently free.
* @page: The associated page buffer
. Valif iff @flags & %EFX_RX_BUF_PAGE
.
*
Will be %NULL if
the buffer slot is currently free.
* @len: Buffer length, in bytes.
* @
is_page: Indicates if @page is valid. If false, @skb is valid
.
* @
flags: Flags for buffer and packet state
.
*/
struct
efx_rx_buffer
{
dma_addr_t
dma_addr
;
...
...
@@ -223,8 +219,11 @@ struct efx_rx_buffer {
struct
page
*
page
;
}
u
;
unsigned
int
len
;
bool
is_page
;
u16
flags
;
};
#define EFX_RX_BUF_PAGE 0x0001
#define EFX_RX_PKT_CSUMMED 0x0002
#define EFX_RX_PKT_DISCARD 0x0004
/**
* struct efx_rx_page_state - Page-based rx buffer state
...
...
@@ -329,6 +328,7 @@ enum efx_rx_alloc_method {
* @eventq_mask: Event queue pointer mask
* @eventq_read_ptr: Event queue read pointer
* @last_eventq_read_ptr: Last event queue read pointer value.
* @last_irq_cpu: Last CPU to handle interrupt for this channel
* @irq_count: Number of IRQs since last adaptive moderation decision
* @irq_mod_score: IRQ moderation score
* @rx_alloc_level: Watermark based heuristic counter for pushing descriptors
...
...
@@ -359,6 +359,7 @@ struct efx_channel {
unsigned
int
eventq_read_ptr
;
unsigned
int
last_eventq_read_ptr
;
int
last_irq_cpu
;
unsigned
int
irq_count
;
unsigned
int
irq_mod_score
;
#ifdef CONFIG_RFS_ACCEL
...
...
@@ -380,7 +381,6 @@ struct efx_channel {
* access with prefetches.
*/
struct
efx_rx_buffer
*
rx_pkt
;
bool
rx_pkt_csummed
;
struct
efx_rx_queue
rx_queue
;
struct
efx_tx_queue
tx_queue
[
EFX_TXQ_TYPES
];
...
...
@@ -395,12 +395,12 @@ enum efx_led_mode {
#define STRING_TABLE_LOOKUP(val, member) \
((val) < member ## _max) ? member ## _names[val] : "(invalid)"
extern
const
char
*
efx_loopback_mode_names
[];
extern
const
char
*
const
efx_loopback_mode_names
[];
extern
const
unsigned
int
efx_loopback_mode_max
;
#define LOOPBACK_MODE(efx) \
STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode)
extern
const
char
*
efx_reset_type_names
[];
extern
const
char
*
const
efx_reset_type_names
[];
extern
const
unsigned
int
efx_reset_type_max
;
#define RESET_TYPE(type) \
STRING_TABLE_LOOKUP(type, efx_reset_type)
...
...
@@ -473,18 +473,6 @@ static inline bool efx_link_state_equal(const struct efx_link_state *left,
left
->
fc
==
right
->
fc
&&
left
->
speed
==
right
->
speed
;
}
/**
* struct efx_mac_operations - Efx MAC operations table
* @reconfigure: Reconfigure MAC. Serialised by the mac_lock
* @update_stats: Update statistics
* @check_fault: Check fault state. True if fault present.
*/
struct
efx_mac_operations
{
int
(
*
reconfigure
)
(
struct
efx_nic
*
efx
);
void
(
*
update_stats
)
(
struct
efx_nic
*
efx
);
bool
(
*
check_fault
)(
struct
efx_nic
*
efx
);
};
/**
* struct efx_phy_operations - Efx PHY operations table
* @probe: Probe PHY and initialise efx->mdio.mode_support, efx->mdio.mmds,
...
...
@@ -552,64 +540,64 @@ struct efx_mac_stats {
u64
tx_bytes
;
u64
tx_good_bytes
;
u64
tx_bad_bytes
;
u
nsigned
long
tx_packets
;
u
nsigned
long
tx_bad
;
u
nsigned
long
tx_pause
;
u
nsigned
long
tx_control
;
u
nsigned
long
tx_unicast
;
u
nsigned
long
tx_multicast
;
u
nsigned
long
tx_broadcast
;
u
nsigned
long
tx_lt64
;
u
nsigned
long
tx_64
;
u
nsigned
long
tx_65_to_127
;
u
nsigned
long
tx_128_to_255
;
u
nsigned
long
tx_256_to_511
;
u
nsigned
long
tx_512_to_1023
;
u
nsigned
long
tx_1024_to_15xx
;
u
nsigned
long
tx_15xx_to_jumbo
;
u
nsigned
long
tx_gtjumbo
;
u
nsigned
long
tx_collision
;
u
nsigned
long
tx_single_collision
;
u
nsigned
long
tx_multiple_collision
;
u
nsigned
long
tx_excessive_collision
;
u
nsigned
long
tx_deferred
;
u
nsigned
long
tx_late_collision
;
u
nsigned
long
tx_excessive_deferred
;
u
nsigned
long
tx_non_tcpudp
;
u
nsigned
long
tx_mac_src_error
;
u
nsigned
long
tx_ip_src_error
;
u
64
tx_packets
;
u
64
tx_bad
;
u
64
tx_pause
;
u
64
tx_control
;
u
64
tx_unicast
;
u
64
tx_multicast
;
u
64
tx_broadcast
;
u
64
tx_lt64
;
u
64
tx_64
;
u
64
tx_65_to_127
;
u
64
tx_128_to_255
;
u
64
tx_256_to_511
;
u
64
tx_512_to_1023
;
u
64
tx_1024_to_15xx
;
u
64
tx_15xx_to_jumbo
;
u
64
tx_gtjumbo
;
u
64
tx_collision
;
u
64
tx_single_collision
;
u
64
tx_multiple_collision
;
u
64
tx_excessive_collision
;
u
64
tx_deferred
;
u
64
tx_late_collision
;
u
64
tx_excessive_deferred
;
u
64
tx_non_tcpudp
;
u
64
tx_mac_src_error
;
u
64
tx_ip_src_error
;
u64
rx_bytes
;
u64
rx_good_bytes
;
u64
rx_bad_bytes
;
u
nsigned
long
rx_packets
;
u
nsigned
long
rx_good
;
u
nsigned
long
rx_bad
;
u
nsigned
long
rx_pause
;
u
nsigned
long
rx_control
;
u
nsigned
long
rx_unicast
;
u
nsigned
long
rx_multicast
;
u
nsigned
long
rx_broadcast
;
u
nsigned
long
rx_lt64
;
u
nsigned
long
rx_64
;
u
nsigned
long
rx_65_to_127
;
u
nsigned
long
rx_128_to_255
;
u
nsigned
long
rx_256_to_511
;
u
nsigned
long
rx_512_to_1023
;
u
nsigned
long
rx_1024_to_15xx
;
u
nsigned
long
rx_15xx_to_jumbo
;
u
nsigned
long
rx_gtjumbo
;
u
nsigned
long
rx_bad_lt64
;
u
nsigned
long
rx_bad_64_to_15xx
;
u
nsigned
long
rx_bad_15xx_to_jumbo
;
u
nsigned
long
rx_bad_gtjumbo
;
u
nsigned
long
rx_overflow
;
u
nsigned
long
rx_missed
;
u
nsigned
long
rx_false_carrier
;
u
nsigned
long
rx_symbol_error
;
u
nsigned
long
rx_align_error
;
u
nsigned
long
rx_length_error
;
u
nsigned
long
rx_internal_error
;
u
nsigned
long
rx_good_lt64
;
u
64
rx_packets
;
u
64
rx_good
;
u
64
rx_bad
;
u
64
rx_pause
;
u
64
rx_control
;
u
64
rx_unicast
;
u
64
rx_multicast
;
u
64
rx_broadcast
;
u
64
rx_lt64
;
u
64
rx_64
;
u
64
rx_65_to_127
;
u
64
rx_128_to_255
;
u
64
rx_256_to_511
;
u
64
rx_512_to_1023
;
u
64
rx_1024_to_15xx
;
u
64
rx_15xx_to_jumbo
;
u
64
rx_gtjumbo
;
u
64
rx_bad_lt64
;
u
64
rx_bad_64_to_15xx
;
u
64
rx_bad_15xx_to_jumbo
;
u
64
rx_bad_gtjumbo
;
u
64
rx_overflow
;
u
64
rx_missed
;
u
64
rx_false_carrier
;
u
64
rx_symbol_error
;
u
64
rx_align_error
;
u
64
rx_length_error
;
u
64
rx_internal_error
;
u
64
rx_good_lt64
;
};
/* Number of bits used in a multicast filter hash address */
...
...
@@ -640,6 +628,7 @@ struct efx_filter_state;
* @membase_phys: Memory BAR value as physical address
* @membase: Memory BAR value
* @interrupt_mode: Interrupt mode
* @timer_quantum_ns: Interrupt timer quantum, in nanoseconds
* @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
* @irq_rx_moderation: IRQ moderation time for RX event queues
* @msg_enable: Log message enable flags
...
...
@@ -663,7 +652,7 @@ struct efx_filter_state;
* @int_error_expire: Time at which error count will be expired
* @irq_status: Interrupt status buffer
* @irq_zero_count: Number of legacy IRQs seen with queue flags == 0
* @
fatal_irq_level: IRQ level (bit number) used for serious errors
* @
irq_level: IRQ level/index for IRQs not triggered by an event queue
* @mtd_list: List of MTDs attached to the NIC
* @nic_data: Hardware dependent state
* @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
...
...
@@ -676,7 +665,6 @@ struct efx_filter_state;
* @port_initialized: Port initialized?
* @net_dev: Operating system network device. Consider holding the rtnl lock
* @stats_buffer: DMA buffer for statistics
* @mac_op: MAC interface
* @phy_type: PHY type
* @phy_op: PHY interface
* @phy_data: PHY private data (including PHY-specific stats)
...
...
@@ -695,15 +683,15 @@ struct efx_filter_state;
* @loopback_selftest: Offline self-test private state
* @monitor_work: Hardware monitor workitem
* @biu_lock: BIU (bus interface unit) lock
* @last_irq_cpu: Last CPU to handle interrupt.
* This register is written with the SMP processor ID whenever an
* interrupt is handled. It is used by efx_nic_test_interrupt()
* to verify that an interrupt has occurred.
* @last_irq_cpu: Last CPU to handle a possible test interrupt. This
* field is used by efx_test_interrupts() to verify that an
* interrupt has occurred.
* @n_rx_nodesc_drop_cnt: RX no descriptor drop count
* @mac_stats: MAC statistics. These include all statistics the MACs
* can provide. Generic code converts these into a standard
* &struct net_device_stats.
* @stats_lock: Statistics update lock. Serialises statistics fetches
* and access to @mac_stats.
*
* This is stored in the private area of the &struct net_device.
*/
...
...
@@ -722,6 +710,7 @@ struct efx_nic {
void
__iomem
*
membase
;
enum
efx_int_mode
interrupt_mode
;
unsigned
int
timer_quantum_ns
;
bool
irq_rx_adaptive
;
unsigned
int
irq_rx_moderation
;
u32
msg_enable
;
...
...
@@ -749,7 +738,7 @@ struct efx_nic {
struct
efx_buffer
irq_status
;
unsigned
irq_zero_count
;
unsigned
fatal_
irq_level
;
unsigned
irq_level
;
#ifdef CONFIG_SFC_MTD
struct
list_head
mtd_list
;
...
...
@@ -766,8 +755,6 @@ struct efx_nic {
struct
efx_buffer
stats_buffer
;
const
struct
efx_mac_operations
*
mac_op
;
unsigned
int
phy_type
;
const
struct
efx_phy_operations
*
phy_op
;
void
*
phy_data
;
...
...
@@ -795,7 +782,7 @@ struct efx_nic {
struct
delayed_work
monitor_work
____cacheline_aligned_in_smp
;
spinlock_t
biu_lock
;
volatile
signed
int
last_irq_cpu
;
int
last_irq_cpu
;
unsigned
n_rx_nodesc_drop_cnt
;
struct
efx_mac_stats
mac_stats
;
spinlock_t
stats_lock
;
...
...
@@ -806,15 +793,6 @@ static inline int efx_dev_registered(struct efx_nic *efx)
return
efx
->
net_dev
->
reg_state
==
NETREG_REGISTERED
;
}
/* Net device name, for inclusion in log messages if it has been registered.
* Use efx->name not efx->net_dev->name so that races with (un)registration
* are harmless.
*/
static
inline
const
char
*
efx_dev_name
(
struct
efx_nic
*
efx
)
{
return
efx_dev_registered
(
efx
)
?
efx
->
name
:
""
;
}
static
inline
unsigned
int
efx_port_num
(
struct
efx_nic
*
efx
)
{
return
efx
->
net_dev
->
dev_id
;
...
...
@@ -840,14 +818,15 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @stop_stats: Stop the regular fetching of statistics
* @set_id_led: Set state of identifying LED or revert to automatic function
* @push_irq_moderation: Apply interrupt moderation value
* @push_multicast_hash: Apply multicast hash table
* @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY
* @reconfigure_mac: Push MAC address, MTU, flow control and filter settings
* to the hardware. Serialised by the mac_lock.
* @check_mac_fault: Check MAC fault state. True if fault present.
* @get_wol: Get WoL configuration from driver state
* @set_wol: Push WoL configuration to the NIC
* @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume)
* @test_registers: Test read/write functionality of control registers
* @test_nvram: Test validity of NVRAM contents
* @default_mac_ops: efx_mac_operations to set at startup
* @revision: Hardware architecture revision
* @mem_map_size: Memory BAR mapped size
* @txd_ptr_tbl_base: TX descriptor ring base address
...
...
@@ -862,6 +841,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* from &enum efx_init_mode.
* @phys_addr_channels: Number of channels with physically addressed
* descriptors
* @timer_period_max: Maximum period of interrupt timer (in ticks)
* @tx_dc_base: Base address in SRAM of TX queue descriptor caches
* @rx_dc_base: Base address in SRAM of RX queue descriptor caches
* @offload_features: net_device feature flags for protocol offload
...
...
@@ -885,14 +865,14 @@ struct efx_nic_type {
void
(
*
stop_stats
)(
struct
efx_nic
*
efx
);
void
(
*
set_id_led
)(
struct
efx_nic
*
efx
,
enum
efx_led_mode
mode
);
void
(
*
push_irq_moderation
)(
struct
efx_channel
*
channel
);
void
(
*
push_multicast_hash
)(
struct
efx_nic
*
efx
);
int
(
*
reconfigure_port
)(
struct
efx_nic
*
efx
);
int
(
*
reconfigure_mac
)(
struct
efx_nic
*
efx
);
bool
(
*
check_mac_fault
)(
struct
efx_nic
*
efx
);
void
(
*
get_wol
)(
struct
efx_nic
*
efx
,
struct
ethtool_wolinfo
*
wol
);
int
(
*
set_wol
)(
struct
efx_nic
*
efx
,
u32
type
);
void
(
*
resume_wol
)(
struct
efx_nic
*
efx
);
int
(
*
test_registers
)(
struct
efx_nic
*
efx
);
int
(
*
test_nvram
)(
struct
efx_nic
*
efx
);
const
struct
efx_mac_operations
*
default_mac_ops
;
int
revision
;
unsigned
int
mem_map_size
;
...
...
@@ -906,6 +886,7 @@ struct efx_nic_type {
unsigned
int
rx_buffer_padding
;
unsigned
int
max_interrupt_mode
;
unsigned
int
phys_addr_channels
;
unsigned
int
timer_period_max
;
unsigned
int
tx_dc_base
;
unsigned
int
rx_dc_base
;
netdev_features_t
offload_features
;
...
...
drivers/net/ethernet/sfc/nic.c
View file @
30088a25
...
...
@@ -726,11 +726,9 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
tx_queue
=
efx_channel_get_tx_queue
(
channel
,
tx_ev_q_label
%
EFX_TXQ_TYPES
);
if
(
efx_dev_registered
(
efx
))
netif_tx_lock
(
efx
->
net_dev
);
netif_tx_lock
(
efx
->
net_dev
);
efx_notify_tx_desc
(
tx_queue
);
if
(
efx_dev_registered
(
efx
))
netif_tx_unlock
(
efx
->
net_dev
);
netif_tx_unlock
(
efx
->
net_dev
);
}
else
if
(
EFX_QWORD_FIELD
(
*
event
,
FSF_AZ_TX_EV_PKT_ERR
)
&&
EFX_WORKAROUND_10727
(
efx
))
{
efx_schedule_reset
(
efx
,
RESET_TYPE_TX_DESC_FETCH
);
...
...
@@ -745,10 +743,8 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
}
/* Detect errors included in the rx_evt_pkt_ok bit. */
static
void
efx_handle_rx_not_ok
(
struct
efx_rx_queue
*
rx_queue
,
const
efx_qword_t
*
event
,
bool
*
rx_ev_pkt_ok
,
bool
*
discard
)
static
u16
efx_handle_rx_not_ok
(
struct
efx_rx_queue
*
rx_queue
,
const
efx_qword_t
*
event
)
{
struct
efx_channel
*
channel
=
efx_rx_queue_channel
(
rx_queue
);
struct
efx_nic
*
efx
=
rx_queue
->
efx
;
...
...
@@ -793,15 +789,11 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
++
channel
->
n_rx_tcp_udp_chksum_err
;
}
/* The frame must be discarded if any of these are true. */
*
discard
=
(
rx_ev_eth_crc_err
|
rx_ev_frm_trunc
|
rx_ev_drib_nib
|
rx_ev_tobe_disc
|
rx_ev_pause_frm
);
/* TOBE_DISC is expected on unicast mismatches; don't print out an
* error message. FRM_TRUNC indicates RXDP dropped the packet due
* to a FIFO overflow.
*/
#ifdef
EFX_ENABLE_
DEBUG
#ifdef DEBUG
if
(
rx_ev_other_err
&&
net_ratelimit
())
{
netif_dbg
(
efx
,
rx_err
,
efx
->
net_dev
,
" RX queue %d unexpected RX event "
...
...
@@ -819,6 +811,11 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
rx_ev_pause_frm
?
" [PAUSE]"
:
""
);
}
#endif
/* The frame must be discarded if any of these are true. */
return
(
rx_ev_eth_crc_err
|
rx_ev_frm_trunc
|
rx_ev_drib_nib
|
rx_ev_tobe_disc
|
rx_ev_pause_frm
)
?
EFX_RX_PKT_DISCARD
:
0
;
}
/* Handle receive events that are not in-order. */
...
...
@@ -851,7 +848,8 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
unsigned
int
rx_ev_desc_ptr
,
rx_ev_byte_cnt
;
unsigned
int
rx_ev_hdr_type
,
rx_ev_mcast_pkt
;
unsigned
expected_ptr
;
bool
rx_ev_pkt_ok
,
discard
=
false
,
checksummed
;
bool
rx_ev_pkt_ok
;
u16
flags
;
struct
efx_rx_queue
*
rx_queue
;
/* Basic packet information */
...
...
@@ -874,12 +872,11 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
/* If packet is marked as OK and packet type is TCP/IP or
* UDP/IP, then we can rely on the hardware checksum.
*/
checksummed
=
rx_ev_hdr_type
==
FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP
||
rx_ev_hdr_type
==
FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP
;
flags
=
(
rx_ev_hdr_type
==
FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP
||
rx_ev_hdr_type
==
FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP
)
?
EFX_RX_PKT_CSUMMED
:
0
;
}
else
{
efx_handle_rx_not_ok
(
rx_queue
,
event
,
&
rx_ev_pkt_ok
,
&
discard
);
checksummed
=
false
;
flags
=
efx_handle_rx_not_ok
(
rx_queue
,
event
);
}
/* Detect multicast packets that didn't match the filter */
...
...
@@ -890,15 +887,14 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
if
(
unlikely
(
!
rx_ev_mcast_hash_match
))
{
++
channel
->
n_rx_mcast_mismatch
;
discard
=
true
;
flags
|=
EFX_RX_PKT_DISCARD
;
}
}
channel
->
irq_mod_score
+=
2
;
/* Handle received packet */
efx_rx_packet
(
rx_queue
,
rx_ev_desc_ptr
,
rx_ev_byte_cnt
,
checksummed
,
discard
);
efx_rx_packet
(
rx_queue
,
rx_ev_desc_ptr
,
rx_ev_byte_cnt
,
flags
);
}
static
void
...
...
@@ -1311,7 +1307,7 @@ static inline void efx_nic_interrupts(struct efx_nic *efx,
efx_oword_t
int_en_reg_ker
;
EFX_POPULATE_OWORD_3
(
int_en_reg_ker
,
FRF_AZ_KER_INT_LEVE_SEL
,
efx
->
fatal_
irq_level
,
FRF_AZ_KER_INT_LEVE_SEL
,
efx
->
irq_level
,
FRF_AZ_KER_INT_KER
,
force
,
FRF_AZ_DRV_INT_EN_KER
,
enabled
);
efx_writeo
(
efx
,
&
int_en_reg_ker
,
FR_AZ_INT_EN_KER
);
...
...
@@ -1427,11 +1423,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
efx_readd
(
efx
,
&
reg
,
FR_BZ_INT_ISR0
);
queues
=
EFX_EXTRACT_DWORD
(
reg
,
0
,
31
);
/*
Check to see if we have a serious error condition
*/
if
(
queues
&
(
1U
<<
efx
->
fatal_
irq_level
))
{
/*
Handle non-event-queue sources
*/
if
(
queues
&
(
1U
<<
efx
->
irq_level
))
{
syserr
=
EFX_OWORD_FIELD
(
*
int_ker
,
FSF_AZ_NET_IVEC_FATAL_INT
);
if
(
unlikely
(
syserr
))
return
efx_nic_fatal_interrupt
(
efx
);
efx
->
last_irq_cpu
=
raw_smp_processor_id
();
}
if
(
queues
!=
0
)
{
...
...
@@ -1441,7 +1438,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
/* Schedule processing of any interrupting queues */
efx_for_each_channel
(
channel
,
efx
)
{
if
(
queues
&
1
)
efx_schedule_channel
(
channel
);
efx_schedule_channel
_irq
(
channel
);
queues
>>=
1
;
}
result
=
IRQ_HANDLED
;
...
...
@@ -1458,18 +1455,16 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
efx_for_each_channel
(
channel
,
efx
)
{
event
=
efx_event
(
channel
,
channel
->
eventq_read_ptr
);
if
(
efx_event_present
(
event
))
efx_schedule_channel
(
channel
);
efx_schedule_channel
_irq
(
channel
);
else
efx_nic_eventq_read_ack
(
channel
);
}
}
if
(
result
==
IRQ_HANDLED
)
{
efx
->
last_irq_cpu
=
raw_smp_processor_id
();
if
(
result
==
IRQ_HANDLED
)
netif_vdbg
(
efx
,
intr
,
efx
->
net_dev
,
"IRQ %d on CPU %d status "
EFX_DWORD_FMT
"
\n
"
,
irq
,
raw_smp_processor_id
(),
EFX_DWORD_VAL
(
reg
));
}
return
result
;
}
...
...
@@ -1488,20 +1483,20 @@ static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
efx_oword_t
*
int_ker
=
efx
->
irq_status
.
addr
;
int
syserr
;
efx
->
last_irq_cpu
=
raw_smp_processor_id
();
netif_vdbg
(
efx
,
intr
,
efx
->
net_dev
,
"IRQ %d on CPU %d status "
EFX_OWORD_FMT
"
\n
"
,
irq
,
raw_smp_processor_id
(),
EFX_OWORD_VAL
(
*
int_ker
));
/*
Check to see if we have a serious error condition
*/
if
(
channel
->
channel
==
efx
->
fatal_
irq_level
)
{
/*
Handle non-event-queue sources
*/
if
(
channel
->
channel
==
efx
->
irq_level
)
{
syserr
=
EFX_OWORD_FIELD
(
*
int_ker
,
FSF_AZ_NET_IVEC_FATAL_INT
);
if
(
unlikely
(
syserr
))
return
efx_nic_fatal_interrupt
(
efx
);
efx
->
last_irq_cpu
=
raw_smp_processor_id
();
}
/* Schedule processing of the channel */
efx_schedule_channel
(
channel
);
efx_schedule_channel
_irq
(
channel
);
return
IRQ_HANDLED
;
}
...
...
@@ -1640,10 +1635,10 @@ void efx_nic_init_common(struct efx_nic *efx)
if
(
EFX_WORKAROUND_17213
(
efx
)
&&
!
EFX_INT_MODE_USE_MSI
(
efx
))
/* Use an interrupt level unused by event queues */
efx
->
fatal_
irq_level
=
0x1f
;
efx
->
irq_level
=
0x1f
;
else
/* Use a valid MSI-X vector */
efx
->
fatal_
irq_level
=
0
;
efx
->
irq_level
=
0
;
/* Enable all the genuinely fatal interrupts. (They are still
* masked by the overall interrupt mask, controlled by
...
...
@@ -1837,7 +1832,7 @@ struct efx_nic_reg_table {
REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev, \
step, rows \
}
#define REGISTER_TABLE(name, min_rev, max_rev)
\
#define REGISTER_TABLE(name, min_rev, max_rev) \
REGISTER_TABLE_DIMENSIONS( \
name, FR_ ## min_rev ## max_rev ## _ ## name, \
min_rev, max_rev, \
...
...
drivers/net/ethernet/sfc/nic.h
View file @
30088a25
...
...
@@ -144,12 +144,26 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx)
* struct siena_nic_data - Siena NIC state
* @mcdi: Management-Controller-to-Driver Interface
* @wol_filter_id: Wake-on-LAN packet filter id
* @hwmon: Hardware monitor state
*/
struct
siena_nic_data
{
struct
efx_mcdi_iface
mcdi
;
int
wol_filter_id
;
#ifdef CONFIG_SFC_MCDI_MON
struct
efx_mcdi_mon
hwmon
;
#endif
};
#ifdef CONFIG_SFC_MCDI_MON
static
inline
struct
efx_mcdi_mon
*
efx_mcdi_mon
(
struct
efx_nic
*
efx
)
{
struct
siena_nic_data
*
nic_data
;
EFX_BUG_ON_PARANOID
(
efx_nic_rev
(
efx
)
<
EFX_REV_SIENA_A0
);
nic_data
=
efx
->
nic_data
;
return
&
nic_data
->
hwmon
;
}
#endif
extern
const
struct
efx_nic_type
falcon_a1_nic_type
;
extern
const
struct
efx_nic_type
falcon_b0_nic_type
;
extern
const
struct
efx_nic_type
siena_a0_nic_type
;
...
...
@@ -189,6 +203,9 @@ extern bool efx_nic_event_present(struct efx_channel *channel);
/* MAC/PHY */
extern
void
falcon_drain_tx_fifo
(
struct
efx_nic
*
efx
);
extern
void
falcon_reconfigure_mac_wrapper
(
struct
efx_nic
*
efx
);
extern
bool
falcon_xmac_check_fault
(
struct
efx_nic
*
efx
);
extern
int
falcon_reconfigure_xmac
(
struct
efx_nic
*
efx
);
extern
void
falcon_update_stats_xmac
(
struct
efx_nic
*
efx
);
/* Interrupts and test events */
extern
int
efx_nic_init_interrupt
(
struct
efx_nic
*
efx
);
...
...
@@ -202,9 +219,6 @@ extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx);
extern
irqreturn_t
falcon_legacy_interrupt_a1
(
int
irq
,
void
*
dev_id
);
extern
void
falcon_irq_ack_a1
(
struct
efx_nic
*
efx
);
#define EFX_IRQ_MOD_RESOLUTION 5
#define EFX_IRQ_MOD_MAX 0x1000
/* Global Resources */
extern
int
efx_nic_flush_queues
(
struct
efx_nic
*
efx
);
extern
void
falcon_start_nic_stats
(
struct
efx_nic
*
efx
);
...
...
drivers/net/ethernet/sfc/qt202x_phy.c
View file @
30088a25
...
...
@@ -47,7 +47,7 @@
#define PMA_PMD_FTX_STATIC_LBN 13
#define PMA_PMD_VEND1_REG 0xc001
#define PMA_PMD_VEND1_LBTXD_LBN 15
#define PCS_VEND1_REG
0xc000
#define PCS_VEND1_REG 0xc000
#define PCS_VEND1_LBTXD_LBN 5
void
falcon_qt202x_set_led
(
struct
efx_nic
*
p
,
int
led
,
int
mode
)
...
...
@@ -453,9 +453,9 @@ const struct efx_phy_operations falcon_qt202x_phy_ops = {
.
probe
=
qt202x_phy_probe
,
.
init
=
qt202x_phy_init
,
.
reconfigure
=
qt202x_phy_reconfigure
,
.
poll
=
qt202x_phy_poll
,
.
poll
=
qt202x_phy_poll
,
.
fini
=
efx_port_dummy_op_void
,
.
remove
=
qt202x_phy_remove
,
.
remove
=
qt202x_phy_remove
,
.
get_settings
=
qt202x_phy_get_settings
,
.
set_settings
=
efx_mdio_set_settings
,
.
test_alive
=
efx_mdio_test_alive
,
...
...
drivers/net/ethernet/sfc/rx.c
View file @
30088a25
...
...
@@ -98,8 +98,8 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx,
/* Offset is always within one page, so we don't need to consider
* the page order.
*/
return
((
(
__force
unsigned
long
)
buf
->
dma_addr
&
(
PAGE_SIZE
-
1
))
+
efx
->
type
->
rx_buffer_hash_size
)
;
return
((
__force
unsigned
long
)
buf
->
dma_addr
&
(
PAGE_SIZE
-
1
))
+
efx
->
type
->
rx_buffer_hash_size
;
}
static
inline
unsigned
int
efx_rx_buf_size
(
struct
efx_nic
*
efx
)
{
...
...
@@ -108,11 +108,10 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
static
u8
*
efx_rx_buf_eh
(
struct
efx_nic
*
efx
,
struct
efx_rx_buffer
*
buf
)
{
if
(
buf
->
is_page
)
if
(
buf
->
flags
&
EFX_RX_BUF_PAGE
)
return
page_address
(
buf
->
u
.
page
)
+
efx_rx_buf_offset
(
efx
,
buf
);
else
return
((
u8
*
)
buf
->
u
.
skb
->
data
+
efx
->
type
->
rx_buffer_hash_size
);
return
(
u8
*
)
buf
->
u
.
skb
->
data
+
efx
->
type
->
rx_buffer_hash_size
;
}
static
inline
u32
efx_rx_buf_hash
(
const
u8
*
eh
)
...
...
@@ -122,10 +121,10 @@ static inline u32 efx_rx_buf_hash(const u8 *eh)
return
__le32_to_cpup
((
const
__le32
*
)(
eh
-
4
));
#else
const
u8
*
data
=
eh
-
4
;
return
(
(
u32
)
data
[
0
]
|
(
u32
)
data
[
1
]
<<
8
|
(
u32
)
data
[
2
]
<<
16
|
(
u32
)
data
[
3
]
<<
24
)
;
return
(
u32
)
data
[
0
]
|
(
u32
)
data
[
1
]
<<
8
|
(
u32
)
data
[
2
]
<<
16
|
(
u32
)
data
[
3
]
<<
24
;
#endif
}
...
...
@@ -159,7 +158,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue)
/* Adjust the SKB for padding and checksum */
skb_reserve
(
skb
,
NET_IP_ALIGN
);
rx_buf
->
len
=
skb_len
-
NET_IP_ALIGN
;
rx_buf
->
is_page
=
false
;
rx_buf
->
flags
=
0
;
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
rx_buf
->
dma_addr
=
pci_map_single
(
efx
->
pci_dev
,
...
...
@@ -228,7 +227,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
rx_buf
->
dma_addr
=
dma_addr
+
EFX_PAGE_IP_ALIGN
;
rx_buf
->
u
.
page
=
page
;
rx_buf
->
len
=
efx
->
rx_buffer_len
-
EFX_PAGE_IP_ALIGN
;
rx_buf
->
is_page
=
true
;
rx_buf
->
flags
=
EFX_RX_BUF_PAGE
;
++
rx_queue
->
added_count
;
++
rx_queue
->
alloc_page_count
;
++
state
->
refcnt
;
...
...
@@ -249,7 +248,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
static
void
efx_unmap_rx_buffer
(
struct
efx_nic
*
efx
,
struct
efx_rx_buffer
*
rx_buf
)
{
if
(
rx_buf
->
is_page
&&
rx_buf
->
u
.
page
)
{
if
(
(
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
&&
rx_buf
->
u
.
page
)
{
struct
efx_rx_page_state
*
state
;
state
=
page_address
(
rx_buf
->
u
.
page
);
...
...
@@ -259,7 +258,7 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
efx_rx_buf_size
(
efx
),
PCI_DMA_FROMDEVICE
);
}
}
else
if
(
!
rx_buf
->
is_page
&&
rx_buf
->
u
.
skb
)
{
}
else
if
(
!
(
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
&&
rx_buf
->
u
.
skb
)
{
pci_unmap_single
(
efx
->
pci_dev
,
rx_buf
->
dma_addr
,
rx_buf
->
len
,
PCI_DMA_FROMDEVICE
);
}
...
...
@@ -268,10 +267,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
static
void
efx_free_rx_buffer
(
struct
efx_nic
*
efx
,
struct
efx_rx_buffer
*
rx_buf
)
{
if
(
rx_buf
->
is_page
&&
rx_buf
->
u
.
page
)
{
if
(
(
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
&&
rx_buf
->
u
.
page
)
{
__free_pages
(
rx_buf
->
u
.
page
,
efx
->
rx_buffer_order
);
rx_buf
->
u
.
page
=
NULL
;
}
else
if
(
!
rx_buf
->
is_page
&&
rx_buf
->
u
.
skb
)
{
}
else
if
(
!
(
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
&&
rx_buf
->
u
.
skb
)
{
dev_kfree_skb_any
(
rx_buf
->
u
.
skb
);
rx_buf
->
u
.
skb
=
NULL
;
}
...
...
@@ -311,7 +310,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
new_buf
->
dma_addr
=
rx_buf
->
dma_addr
^
(
PAGE_SIZE
>>
1
);
new_buf
->
u
.
page
=
rx_buf
->
u
.
page
;
new_buf
->
len
=
rx_buf
->
len
;
new_buf
->
is_page
=
true
;
new_buf
->
flags
=
EFX_RX_BUF_PAGE
;
++
rx_queue
->
added_count
;
}
...
...
@@ -325,7 +324,10 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
struct
efx_rx_buffer
*
new_buf
;
unsigned
index
;
if
(
rx_buf
->
is_page
&&
efx
->
rx_buffer_len
<=
EFX_RX_HALF_PAGE
&&
rx_buf
->
flags
&=
EFX_RX_BUF_PAGE
;
if
((
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
&&
efx
->
rx_buffer_len
<=
EFX_RX_HALF_PAGE
&&
page_count
(
rx_buf
->
u
.
page
)
==
1
)
efx_resurrect_rx_buffer
(
rx_queue
,
rx_buf
);
...
...
@@ -412,8 +414,7 @@ void efx_rx_slow_fill(unsigned long context)
static
void
efx_rx_packet__check_len
(
struct
efx_rx_queue
*
rx_queue
,
struct
efx_rx_buffer
*
rx_buf
,
int
len
,
bool
*
discard
,
bool
*
leak_packet
)
int
len
,
bool
*
leak_packet
)
{
struct
efx_nic
*
efx
=
rx_queue
->
efx
;
unsigned
max_len
=
rx_buf
->
len
-
efx
->
type
->
rx_buffer_padding
;
...
...
@@ -424,7 +425,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
/* The packet must be discarded, but this is only a fatal error
* if the caller indicated it was
*/
*
discard
=
true
;
rx_buf
->
flags
|=
EFX_RX_PKT_DISCARD
;
if
((
len
>
rx_buf
->
len
)
&&
EFX_WORKAROUND_8071
(
efx
))
{
if
(
net_ratelimit
())
...
...
@@ -437,7 +438,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
* data at the end of the skb will be trashed. So
* we have no choice but to leak the fragment.
*/
*
leak_packet
=
!
rx_buf
->
is_page
;
*
leak_packet
=
!
(
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
;
efx_schedule_reset
(
efx
,
RESET_TYPE_RX_RECOVERY
);
}
else
{
if
(
net_ratelimit
())
...
...
@@ -457,13 +458,13 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
*/
static
void
efx_rx_packet_gro
(
struct
efx_channel
*
channel
,
struct
efx_rx_buffer
*
rx_buf
,
const
u8
*
eh
,
bool
checksummed
)
const
u8
*
eh
)
{
struct
napi_struct
*
napi
=
&
channel
->
napi_str
;
gro_result_t
gro_result
;
/* Pass the skb/page into the GRO engine */
if
(
rx_buf
->
is_page
)
{
if
(
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
{
struct
efx_nic
*
efx
=
channel
->
efx
;
struct
page
*
page
=
rx_buf
->
u
.
page
;
struct
sk_buff
*
skb
;
...
...
@@ -485,8 +486,8 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
skb
->
len
=
rx_buf
->
len
;
skb
->
data_len
=
rx_buf
->
len
;
skb
->
truesize
+=
rx_buf
->
len
;
skb
->
ip_summed
=
checksummed
?
CHECKSUM_UNNECESSARY
:
CHECKSUM_NONE
;
skb
->
ip_summed
=
((
rx_buf
->
flags
&
EFX_RX_PKT_CSUMMED
)
?
CHECKSUM_UNNECESSARY
:
CHECKSUM_NONE
)
;
skb_record_rx_queue
(
skb
,
channel
->
channel
);
...
...
@@ -494,7 +495,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
}
else
{
struct
sk_buff
*
skb
=
rx_buf
->
u
.
skb
;
EFX_BUG_ON_PARANOID
(
!
checksummed
);
EFX_BUG_ON_PARANOID
(
!
(
rx_buf
->
flags
&
EFX_RX_PKT_CSUMMED
)
);
rx_buf
->
u
.
skb
=
NULL
;
gro_result
=
napi_gro_receive
(
napi
,
skb
);
...
...
@@ -509,7 +510,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
}
void
efx_rx_packet
(
struct
efx_rx_queue
*
rx_queue
,
unsigned
int
index
,
unsigned
int
len
,
bool
checksummed
,
bool
discard
)
unsigned
int
len
,
u16
flags
)
{
struct
efx_nic
*
efx
=
rx_queue
->
efx
;
struct
efx_channel
*
channel
=
efx_rx_queue_channel
(
rx_queue
);
...
...
@@ -517,6 +518,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
bool
leak_packet
=
false
;
rx_buf
=
efx_rx_buffer
(
rx_queue
,
index
);
rx_buf
->
flags
|=
flags
;
/* This allows the refill path to post another buffer.
* EFX_RXD_HEAD_ROOM ensures that the slot we are using
...
...
@@ -525,18 +527,17 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
rx_queue
->
removed_count
++
;
/* Validate the length encoded in the event vs the descriptor pushed */
efx_rx_packet__check_len
(
rx_queue
,
rx_buf
,
len
,
&
discard
,
&
leak_packet
);
efx_rx_packet__check_len
(
rx_queue
,
rx_buf
,
len
,
&
leak_packet
);
netif_vdbg
(
efx
,
rx_status
,
efx
->
net_dev
,
"RX queue %d received id %x at %llx+%x %s%s
\n
"
,
efx_rx_queue_index
(
rx_queue
),
index
,
(
unsigned
long
long
)
rx_buf
->
dma_addr
,
len
,
(
checksummed
?
" [SUMMED]"
:
""
)
,
(
discard
?
" [DISCARD]"
:
""
)
);
(
rx_buf
->
flags
&
EFX_RX_PKT_CSUMMED
)
?
" [SUMMED]"
:
""
,
(
rx_buf
->
flags
&
EFX_RX_PKT_DISCARD
)
?
" [DISCARD]"
:
""
);
/* Discard packet, if instructed to do so */
if
(
unlikely
(
discard
))
{
if
(
unlikely
(
rx_buf
->
flags
&
EFX_RX_PKT_DISCARD
))
{
if
(
unlikely
(
leak_packet
))
channel
->
n_skbuff_leaks
++
;
else
...
...
@@ -563,18 +564,33 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
rx_buf
->
len
=
len
-
efx
->
type
->
rx_buffer_hash_size
;
out:
if
(
channel
->
rx_pkt
)
__efx_rx_packet
(
channel
,
channel
->
rx_pkt
,
channel
->
rx_pkt_csummed
);
__efx_rx_packet
(
channel
,
channel
->
rx_pkt
);
channel
->
rx_pkt
=
rx_buf
;
channel
->
rx_pkt_csummed
=
checksummed
;
}
static
void
efx_rx_deliver
(
struct
efx_channel
*
channel
,
struct
efx_rx_buffer
*
rx_buf
)
{
struct
sk_buff
*
skb
;
/* We now own the SKB */
skb
=
rx_buf
->
u
.
skb
;
rx_buf
->
u
.
skb
=
NULL
;
/* Set the SKB flags */
skb_checksum_none_assert
(
skb
);
/* Pass the packet up */
netif_receive_skb
(
skb
);
/* Update allocation strategy method */
channel
->
rx_alloc_level
+=
RX_ALLOC_FACTOR_SKB
;
}
/* Handle a received packet. Second half: Touches packet payload. */
void
__efx_rx_packet
(
struct
efx_channel
*
channel
,
struct
efx_rx_buffer
*
rx_buf
,
bool
checksummed
)
void
__efx_rx_packet
(
struct
efx_channel
*
channel
,
struct
efx_rx_buffer
*
rx_buf
)
{
struct
efx_nic
*
efx
=
channel
->
efx
;
struct
sk_buff
*
skb
;
u8
*
eh
=
efx_rx_buf_eh
(
efx
,
rx_buf
);
/* If we're in loopback test, then pass the packet directly to the
...
...
@@ -586,8 +602,8 @@ void __efx_rx_packet(struct efx_channel *channel,
return
;
}
if
(
!
rx_buf
->
is_page
)
{
skb
=
rx_buf
->
u
.
skb
;
if
(
!
(
rx_buf
->
flags
&
EFX_RX_BUF_PAGE
)
)
{
s
truct
sk_buff
*
s
kb
=
rx_buf
->
u
.
skb
;
prefetch
(
skb_shinfo
(
skb
));
...
...
@@ -605,25 +621,12 @@ void __efx_rx_packet(struct efx_channel *channel,
}
if
(
unlikely
(
!
(
efx
->
net_dev
->
features
&
NETIF_F_RXCSUM
)))
checksummed
=
false
;
if
(
likely
(
checksummed
||
rx_buf
->
is_page
))
{
efx_rx_packet_gro
(
channel
,
rx_buf
,
eh
,
checksummed
);
return
;
}
/* We now own the SKB */
skb
=
rx_buf
->
u
.
skb
;
rx_buf
->
u
.
skb
=
NULL
;
rx_buf
->
flags
&=
~
EFX_RX_PKT_CSUMMED
;
/* Set the SKB flags */
skb_checksum_none_assert
(
skb
);
/* Pass the packet up */
netif_receive_skb
(
skb
);
/* Update allocation strategy method */
channel
->
rx_alloc_level
+=
RX_ALLOC_FACTOR_SKB
;
if
(
likely
(
rx_buf
->
flags
&
(
EFX_RX_BUF_PAGE
|
EFX_RX_PKT_CSUMMED
)))
efx_rx_packet_gro
(
channel
,
rx_buf
,
eh
);
else
efx_rx_deliver
(
channel
,
rx_buf
);
}
void
efx_rx_strategy
(
struct
efx_channel
*
channel
)
...
...
drivers/net/ethernet/sfc/selftest.c
View file @
30088a25
...
...
@@ -19,7 +19,6 @@
#include <linux/udp.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <asm/io.h>
#include "net_driver.h"
#include "efx.h"
#include "nic.h"
...
...
@@ -50,7 +49,7 @@ static const char payload_msg[] =
/* Interrupt mode names */
static
const
unsigned
int
efx_interrupt_mode_max
=
EFX_INT_MODE_MAX
;
static
const
char
*
efx_interrupt_mode_names
[]
=
{
static
const
char
*
const
efx_interrupt_mode_names
[]
=
{
[
EFX_INT_MODE_MSIX
]
=
"MSI-X"
,
[
EFX_INT_MODE_MSI
]
=
"MSI"
,
[
EFX_INT_MODE_LEGACY
]
=
"legacy"
,
...
...
@@ -131,6 +130,8 @@ static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
static
int
efx_test_interrupts
(
struct
efx_nic
*
efx
,
struct
efx_self_tests
*
tests
)
{
int
cpu
;
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"testing interrupts
\n
"
);
tests
->
interrupt
=
-
1
;
...
...
@@ -143,7 +144,8 @@ static int efx_test_interrupts(struct efx_nic *efx,
/* Wait for arrival of test interrupt. */
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"waiting for test interrupt
\n
"
);
schedule_timeout_uninterruptible
(
HZ
/
10
);
if
(
efx
->
last_irq_cpu
>=
0
)
cpu
=
ACCESS_ONCE
(
efx
->
last_irq_cpu
);
if
(
cpu
>=
0
)
goto
success
;
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"timed out waiting for interrupt
\n
"
);
...
...
@@ -151,8 +153,7 @@ static int efx_test_interrupts(struct efx_nic *efx,
success:
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"%s test interrupt seen on CPU%d
\n
"
,
INT_MODE
(
efx
),
efx
->
last_irq_cpu
);
INT_MODE
(
efx
),
cpu
);
tests
->
interrupt
=
1
;
return
0
;
}
...
...
@@ -162,56 +163,57 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
struct
efx_self_tests
*
tests
)
{
struct
efx_nic
*
efx
=
channel
->
efx
;
unsigned
int
read_ptr
,
count
;
tests
->
eventq_dma
[
channel
->
channel
]
=
-
1
;
tests
->
eventq_int
[
channel
->
channel
]
=
-
1
;
tests
->
eventq_poll
[
channel
->
channel
]
=
-
1
;
unsigned
int
read_ptr
;
bool
napi_ran
,
dma_seen
,
int_seen
;
read_ptr
=
channel
->
eventq_read_ptr
;
channel
->
efx
->
last_irq_cpu
=
-
1
;
channel
->
last_irq_cpu
=
-
1
;
smp_wmb
();
efx_nic_generate_test_event
(
channel
);
/* Wait for arrival of interrupt */
count
=
0
;
do
{
schedule_timeout_uninterruptible
(
HZ
/
100
);
if
(
ACCESS_ONCE
(
channel
->
eventq_read_ptr
)
!=
read_ptr
)
goto
eventq_ok
;
}
while
(
++
count
<
2
);
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"channel %d timed out waiting for event queue
\n
"
,
channel
->
channel
);
/* See if interrupt arrived */
if
(
channel
->
efx
->
last_irq_cpu
>=
0
)
{
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"channel %d saw interrupt on CPU%d "
"during event queue test
\n
"
,
channel
->
channel
,
raw_smp_processor_id
());
tests
->
eventq_int
[
channel
->
channel
]
=
1
;
/* Wait for arrival of interrupt. NAPI processing may or may
* not complete in time, but we can cope in any case.
*/
msleep
(
10
);
napi_disable
(
&
channel
->
napi_str
);
if
(
channel
->
eventq_read_ptr
!=
read_ptr
)
{
napi_ran
=
true
;
dma_seen
=
true
;
int_seen
=
true
;
}
else
{
napi_ran
=
false
;
dma_seen
=
efx_nic_event_present
(
channel
);
int_seen
=
ACCESS_ONCE
(
channel
->
last_irq_cpu
)
>=
0
;
}
napi_enable
(
&
channel
->
napi_str
);
efx_nic_eventq_read_ack
(
channel
);
tests
->
eventq_dma
[
channel
->
channel
]
=
dma_seen
?
1
:
-
1
;
tests
->
eventq_int
[
channel
->
channel
]
=
int_seen
?
1
:
-
1
;
/* Check to see if event was received even if interrupt wasn't */
if
(
efx_nic_event_present
(
channel
))
{
if
(
dma_seen
&&
int_seen
)
{
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"channel %d event queue passed (with%s NAPI)
\n
"
,
channel
->
channel
,
napi_ran
?
""
:
"out"
);
return
0
;
}
else
{
/* Report failure and whether either interrupt or DMA worked */
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"channel %d event was generated, but "
"failed to trigger an interrupt
\n
"
,
channel
->
channel
);
tests
->
eventq_dma
[
channel
->
channel
]
=
1
;
"channel %d timed out waiting for event queue
\n
"
,
channel
->
channel
);
if
(
int_seen
)
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"channel %d saw interrupt "
"during event queue test
\n
"
,
channel
->
channel
);
if
(
dma_seen
)
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"channel %d event was generated, but "
"failed to trigger an interrupt
\n
"
,
channel
->
channel
);
return
-
ETIMEDOUT
;
}
return
-
ETIMEDOUT
;
eventq_ok:
netif_dbg
(
efx
,
drv
,
efx
->
net_dev
,
"channel %d event queue passed
\n
"
,
channel
->
channel
);
tests
->
eventq_dma
[
channel
->
channel
]
=
1
;
tests
->
eventq_int
[
channel
->
channel
]
=
1
;
tests
->
eventq_poll
[
channel
->
channel
]
=
1
;
return
0
;
}
static
int
efx_test_phy
(
struct
efx_nic
*
efx
,
struct
efx_self_tests
*
tests
,
...
...
@@ -316,7 +318,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx,
return
;
err:
#ifdef
EFX_ENABLE_
DEBUG
#ifdef DEBUG
if
(
atomic_read
(
&
state
->
rx_bad
)
==
0
)
{
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
"received packet:
\n
"
);
print_hex_dump
(
KERN_ERR
,
""
,
DUMP_PREFIX_OFFSET
,
0x10
,
1
,
...
...
@@ -395,11 +397,9 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
* interrupt handler. */
smp_wmb
();
if
(
efx_dev_registered
(
efx
))
netif_tx_lock_bh
(
efx
->
net_dev
);
netif_tx_lock_bh
(
efx
->
net_dev
);
rc
=
efx_enqueue_skb
(
tx_queue
,
skb
);
if
(
efx_dev_registered
(
efx
))
netif_tx_unlock_bh
(
efx
->
net_dev
);
netif_tx_unlock_bh
(
efx
->
net_dev
);
if
(
rc
!=
NETDEV_TX_OK
)
{
netif_err
(
efx
,
drv
,
efx
->
net_dev
,
...
...
@@ -440,20 +440,18 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue,
int
tx_done
=
0
,
rx_good
,
rx_bad
;
int
i
,
rc
=
0
;
if
(
efx_dev_registered
(
efx
))
netif_tx_lock_bh
(
efx
->
net_dev
);
netif_tx_lock_bh
(
efx
->
net_dev
);
/* Count the number of tx completions, and decrement the refcnt. Any
* skbs not already completed will be free'd when the queue is flushed */
for
(
i
=
0
;
i
<
state
->
packet_count
;
i
++
)
{
for
(
i
=
0
;
i
<
state
->
packet_count
;
i
++
)
{
skb
=
state
->
skbs
[
i
];
if
(
skb
&&
!
skb_shared
(
skb
))
++
tx_done
;
dev_kfree_skb_any
(
skb
);
}
if
(
efx_dev_registered
(
efx
))
netif_tx_unlock_bh
(
efx
->
net_dev
);
netif_tx_unlock_bh
(
efx
->
net_dev
);
/* Check TX completion and received packet counts */
rx_good
=
atomic_read
(
&
state
->
rx_good
);
...
...
@@ -570,7 +568,7 @@ static int efx_wait_for_link(struct efx_nic *efx)
mutex_lock
(
&
efx
->
mac_lock
);
link_up
=
link_state
->
up
;
if
(
link_up
)
link_up
=
!
efx
->
mac_op
->
check
_fault
(
efx
);
link_up
=
!
efx
->
type
->
check_mac
_fault
(
efx
);
mutex_unlock
(
&
efx
->
mac_lock
);
if
(
link_up
)
{
...
...
drivers/net/ethernet/sfc/selftest.h
View file @
30088a25
...
...
@@ -37,7 +37,6 @@ struct efx_self_tests {
int
interrupt
;
int
eventq_dma
[
EFX_MAX_CHANNELS
];
int
eventq_int
[
EFX_MAX_CHANNELS
];
int
eventq_poll
[
EFX_MAX_CHANNELS
];
/* offline tests */
int
registers
;
int
phy_ext
[
EFX_MAX_PHY_TESTS
];
...
...
drivers/net/ethernet/sfc/siena.c
View file @
30088a25
...
...
@@ -18,7 +18,6 @@
#include "bitfield.h"
#include "efx.h"
#include "nic.h"
#include "mac.h"
#include "spi.h"
#include "regs.h"
#include "io.h"
...
...
@@ -36,8 +35,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel)
{
efx_dword_t
timer_cmd
;
BUILD_BUG_ON
(
EFX_IRQ_MOD_MAX
>
(
1
<<
FRF_CZ_TC_TIMER_VAL_WIDTH
));
if
(
channel
->
irq_moderation
)
EFX_POPULATE_DWORD_2
(
timer_cmd
,
FRF_CZ_TC_TIMER_MODE
,
...
...
@@ -53,15 +50,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel)
channel
->
channel
);
}
static
void
siena_push_multicast_hash
(
struct
efx_nic
*
efx
)
{
WARN_ON
(
!
mutex_is_locked
(
&
efx
->
mac_lock
));
efx_mcdi_rpc
(
efx
,
MC_CMD_SET_MCAST_HASH
,
efx
->
multicast_hash
.
byte
,
sizeof
(
efx
->
multicast_hash
),
NULL
,
0
,
NULL
);
}
static
int
siena_mdio_write
(
struct
net_device
*
net_dev
,
int
prtad
,
int
devad
,
u16
addr
,
u16
value
)
{
...
...
@@ -226,7 +214,15 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method)
static
int
siena_probe_nvconfig
(
struct
efx_nic
*
efx
)
{
return
efx_mcdi_get_board_cfg
(
efx
,
efx
->
net_dev
->
perm_addr
,
NULL
);
u32
caps
=
0
;
int
rc
;
rc
=
efx_mcdi_get_board_cfg
(
efx
,
efx
->
net_dev
->
perm_addr
,
NULL
,
&
caps
);
efx
->
timer_quantum_ns
=
(
caps
&
(
1
<<
MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN
))
?
3072
:
6144
;
/* 768 cycles */
return
rc
;
}
static
int
siena_probe_nic
(
struct
efx_nic
*
efx
)
...
...
@@ -304,6 +300,10 @@ static int siena_probe_nic(struct efx_nic *efx)
goto
fail5
;
}
rc
=
efx_mcdi_mon_probe
(
efx
);
if
(
rc
)
goto
fail5
;
return
0
;
fail5:
...
...
@@ -391,6 +391,8 @@ static int siena_init_nic(struct efx_nic *efx)
static
void
siena_remove_nic
(
struct
efx_nic
*
efx
)
{
efx_mcdi_mon_remove
(
efx
);
efx_nic_free_buffer
(
efx
,
&
efx
->
irq_status
);
siena_reset_hw
(
efx
,
RESET_TYPE_ALL
);
...
...
@@ -630,14 +632,14 @@ const struct efx_nic_type siena_a0_nic_type = {
.
stop_stats
=
siena_stop_nic_stats
,
.
set_id_led
=
efx_mcdi_set_id_led
,
.
push_irq_moderation
=
siena_push_irq_moderation
,
.
push_multicast_hash
=
siena_push_multicast_hash
,
.
reconfigure_mac
=
efx_mcdi_mac_reconfigure
,
.
check_mac_fault
=
efx_mcdi_mac_check_fault
,
.
reconfigure_port
=
efx_mcdi_phy_reconfigure
,
.
get_wol
=
siena_get_wol
,
.
set_wol
=
siena_set_wol
,
.
resume_wol
=
siena_init_wol
,
.
test_registers
=
siena_test_registers
,
.
test_nvram
=
efx_mcdi_nvram_test_all
,
.
default_mac_ops
=
&
efx_mcdi_mac_operations
,
.
revision
=
EFX_REV_SIENA_A0
,
.
mem_map_size
=
(
FR_CZ_MC_TREG_SMEM
+
...
...
@@ -654,6 +656,7 @@ const struct efx_nic_type siena_a0_nic_type = {
.
phys_addr_channels
=
32
,
/* Hardware limit is 64, but the legacy
* interrupt handler only supports 32
* channels */
.
timer_period_max
=
1
<<
FRF_CZ_TC_TIMER_VAL_WIDTH
,
.
tx_dc_base
=
0x88000
,
.
rx_dc_base
=
0x68000
,
.
offload_features
=
(
NETIF_F_IP_CSUM
|
NETIF_F_IPV6_CSUM
|
...
...
drivers/net/ethernet/sfc/spi.h
View file @
30088a25
...
...
@@ -68,7 +68,7 @@ static inline bool efx_spi_present(const struct efx_spi_device *spi)
int
falcon_spi_cmd
(
struct
efx_nic
*
efx
,
const
struct
efx_spi_device
*
spi
,
unsigned
int
command
,
int
address
,
const
void
*
in
,
void
*
out
,
size_t
len
);
int
address
,
const
void
*
in
,
void
*
out
,
size_t
len
);
int
falcon_spi_wait_write
(
struct
efx_nic
*
efx
,
const
struct
efx_spi_device
*
spi
);
int
falcon_spi_read
(
struct
efx_nic
*
efx
,
...
...
drivers/net/ethernet/sfc/tenxpress.c
View file @
30088a25
...
...
@@ -121,7 +121,7 @@
#define GPHY_XCONTROL_REG 49152
#define GPHY_ISOLATE_LBN 10
#define GPHY_ISOLATE_WIDTH 1
#define GPHY_DUPLEX_LBN
8
#define GPHY_DUPLEX_LBN 8
#define GPHY_DUPLEX_WIDTH 1
#define GPHY_LOOPBACK_NEAR_LBN 14
#define GPHY_LOOPBACK_NEAR_WIDTH 1
...
...
drivers/net/ethernet/sfc/tx.c
View file @
30088a25
...
...
@@ -446,10 +446,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
likely
(
efx
->
port_enabled
)
&&
likely
(
netif_device_present
(
efx
->
net_dev
)))
{
fill_level
=
tx_queue
->
insert_count
-
tx_queue
->
read_count
;
if
(
fill_level
<
EFX_TXQ_THRESHOLD
(
efx
))
{
EFX_BUG_ON_PARANOID
(
!
efx_dev_registered
(
efx
));
if
(
fill_level
<
EFX_TXQ_THRESHOLD
(
efx
))
netif_tx_wake_queue
(
tx_queue
->
core_txq
);
}
}
/* Check whether the hardware queue is now empty */
...
...
drivers/net/ethernet/sfc/txc43128_phy.c
View file @
30088a25
...
...
@@ -512,7 +512,7 @@ static bool txc43128_phy_poll(struct efx_nic *efx)
return
efx
->
link_state
.
up
!=
was_up
;
}
static
const
char
*
txc43128_test_names
[]
=
{
static
const
char
*
const
txc43128_test_names
[]
=
{
"bist"
};
...
...
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