mirror of https://gitee.com/openkylin/linux.git
sfc: commonise miscellaneous efx functions
Various left-over bits and pieces from efx.c that are needed by ef100. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2c6c1e3cfd
commit
2d73515a1c
|
@ -593,109 +593,6 @@ int efx_net_stop(struct net_device *net_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Context: netif_tx_lock held, BHs disabled. */
|
||||
static void efx_watchdog(struct net_device *net_dev, unsigned int txqueue)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
netif_err(efx, tx_err, efx->net_dev,
|
||||
"TX stuck with port_enabled=%d: resetting channels\n",
|
||||
efx->port_enabled);
|
||||
|
||||
efx_schedule_reset(efx, RESET_TYPE_TX_WATCHDOG);
|
||||
}
|
||||
|
||||
static int efx_set_mac_address(struct net_device *net_dev, void *data)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
struct sockaddr *addr = data;
|
||||
u8 *new_addr = addr->sa_data;
|
||||
u8 old_addr[6];
|
||||
int rc;
|
||||
|
||||
if (!is_valid_ether_addr(new_addr)) {
|
||||
netif_err(efx, drv, efx->net_dev,
|
||||
"invalid ethernet MAC address requested: %pM\n",
|
||||
new_addr);
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
/* save old address */
|
||||
ether_addr_copy(old_addr, net_dev->dev_addr);
|
||||
ether_addr_copy(net_dev->dev_addr, new_addr);
|
||||
if (efx->type->set_mac_address) {
|
||||
rc = efx->type->set_mac_address(efx);
|
||||
if (rc) {
|
||||
ether_addr_copy(net_dev->dev_addr, old_addr);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reconfigure the MAC */
|
||||
mutex_lock(&efx->mac_lock);
|
||||
efx_mac_reconfigure(efx);
|
||||
mutex_unlock(&efx->mac_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Context: netif_addr_lock held, BHs disabled. */
|
||||
static void efx_set_rx_mode(struct net_device *net_dev)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
if (efx->port_enabled)
|
||||
queue_work(efx->workqueue, &efx->mac_work);
|
||||
/* Otherwise efx_start_port() will do this */
|
||||
}
|
||||
|
||||
static int efx_set_features(struct net_device *net_dev, netdev_features_t data)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
int rc;
|
||||
|
||||
/* If disabling RX n-tuple filtering, clear existing filters */
|
||||
if (net_dev->features & ~data & NETIF_F_NTUPLE) {
|
||||
rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* If Rx VLAN filter is changed, update filters via mac_reconfigure.
|
||||
* If rx-fcs is changed, mac_reconfigure updates that too.
|
||||
*/
|
||||
if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
|
||||
NETIF_F_RXFCS)) {
|
||||
/* efx_set_rx_mode() will schedule MAC work to update filters
|
||||
* when a new features are finally set in net_dev.
|
||||
*/
|
||||
efx_set_rx_mode(net_dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efx_get_phys_port_id(struct net_device *net_dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
if (efx->type->get_phys_port_id)
|
||||
return efx->type->get_phys_port_id(efx, ppid);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int efx_get_phys_port_name(struct net_device *net_dev,
|
||||
char *name, size_t len)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
if (snprintf(name, len, "p%u", efx->port_num) >= len)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efx_vlan_rx_add_vid(struct net_device *net_dev, __be16 proto, u16 vid)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
|
|
@ -36,13 +36,6 @@ static inline void efx_rx_flush_packet(struct efx_channel *channel)
|
|||
__efx_rx_packet(channel);
|
||||
}
|
||||
|
||||
#define EFX_MAX_DMAQ_SIZE 4096UL
|
||||
#define EFX_DEFAULT_DMAQ_SIZE 1024UL
|
||||
#define EFX_MIN_DMAQ_SIZE 512UL
|
||||
|
||||
#define EFX_MAX_EVQ_SIZE 16384UL
|
||||
#define EFX_MIN_EVQ_SIZE 512UL
|
||||
|
||||
/* Maximum number of TCP segments we support for soft-TSO */
|
||||
#define EFX_TSO_MAX_SEGS 100
|
||||
|
||||
|
@ -166,10 +159,6 @@ 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);
|
||||
|
||||
/* Dummy PHY ops for PHY drivers */
|
||||
int efx_port_dummy_op_int(struct efx_nic *efx);
|
||||
void efx_port_dummy_op_void(struct efx_nic *efx);
|
||||
|
||||
/* Update the generic software stats in the passed stats array */
|
||||
void efx_update_sw_stats(struct efx_nic *efx, u64 *stats);
|
||||
|
||||
|
@ -196,21 +185,6 @@ static inline unsigned int efx_vf_size(struct efx_nic *efx)
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline void efx_schedule_channel(struct efx_channel *channel)
|
||||
{
|
||||
netif_vdbg(channel->efx, intr, channel->efx->net_dev,
|
||||
"channel %d scheduling NAPI poll on CPU%d\n",
|
||||
channel->channel, raw_smp_processor_id());
|
||||
|
||||
napi_schedule(&channel->napi_str);
|
||||
}
|
||||
|
||||
static inline void efx_schedule_channel_irq(struct efx_channel *channel)
|
||||
{
|
||||
channel->event_test_cpu = raw_smp_processor_id();
|
||||
efx_schedule_channel(channel);
|
||||
}
|
||||
|
||||
static inline void efx_device_detach_sync(struct efx_nic *efx)
|
||||
{
|
||||
struct net_device *dev = efx->net_dev;
|
||||
|
|
|
@ -162,6 +162,76 @@ static void efx_mac_work(struct work_struct *data)
|
|||
mutex_unlock(&efx->mac_lock);
|
||||
}
|
||||
|
||||
int efx_set_mac_address(struct net_device *net_dev, void *data)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
struct sockaddr *addr = data;
|
||||
u8 *new_addr = addr->sa_data;
|
||||
u8 old_addr[6];
|
||||
int rc;
|
||||
|
||||
if (!is_valid_ether_addr(new_addr)) {
|
||||
netif_err(efx, drv, efx->net_dev,
|
||||
"invalid ethernet MAC address requested: %pM\n",
|
||||
new_addr);
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
/* save old address */
|
||||
ether_addr_copy(old_addr, net_dev->dev_addr);
|
||||
ether_addr_copy(net_dev->dev_addr, new_addr);
|
||||
if (efx->type->set_mac_address) {
|
||||
rc = efx->type->set_mac_address(efx);
|
||||
if (rc) {
|
||||
ether_addr_copy(net_dev->dev_addr, old_addr);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reconfigure the MAC */
|
||||
mutex_lock(&efx->mac_lock);
|
||||
efx_mac_reconfigure(efx);
|
||||
mutex_unlock(&efx->mac_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Context: netif_addr_lock held, BHs disabled. */
|
||||
void efx_set_rx_mode(struct net_device *net_dev)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
if (efx->port_enabled)
|
||||
queue_work(efx->workqueue, &efx->mac_work);
|
||||
/* Otherwise efx_start_port() will do this */
|
||||
}
|
||||
|
||||
int efx_set_features(struct net_device *net_dev, netdev_features_t data)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
int rc;
|
||||
|
||||
/* If disabling RX n-tuple filtering, clear existing filters */
|
||||
if (net_dev->features & ~data & NETIF_F_NTUPLE) {
|
||||
rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* If Rx VLAN filter is changed, update filters via mac_reconfigure.
|
||||
* If rx-fcs is changed, mac_reconfigure updates that too.
|
||||
*/
|
||||
if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
|
||||
NETIF_F_RXFCS)) {
|
||||
/* efx_set_rx_mode() will schedule MAC work to update filters
|
||||
* when a new features are finally set in net_dev.
|
||||
*/
|
||||
efx_set_rx_mode(net_dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This ensures that the kernel is kept informed (via
|
||||
* netif_carrier_on/off) of the link status, and also maintains the
|
||||
* link status's stop on the port's TX queue.
|
||||
|
@ -650,6 +720,18 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
|
|||
efx->type->fini(efx);
|
||||
}
|
||||
|
||||
/* Context: netif_tx_lock held, BHs disabled. */
|
||||
void efx_watchdog(struct net_device *net_dev, unsigned int txqueue)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
netif_err(efx, tx_err, efx->net_dev,
|
||||
"TX stuck with port_enabled=%d: resetting channels\n",
|
||||
efx->port_enabled);
|
||||
|
||||
efx_schedule_reset(efx, RESET_TYPE_TX_WATCHDOG);
|
||||
}
|
||||
|
||||
/* This function will always ensure that the locks acquired in
|
||||
* efx_reset_down() are released. A failure return code indicates
|
||||
* that we were unable to reinitialise the hardware, and the
|
||||
|
@ -1221,3 +1303,23 @@ const struct pci_error_handlers efx_err_handlers = {
|
|||
.slot_reset = efx_io_slot_reset,
|
||||
.resume = efx_io_resume,
|
||||
};
|
||||
|
||||
int efx_get_phys_port_id(struct net_device *net_dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
if (efx->type->get_phys_port_id)
|
||||
return efx->type->get_phys_port_id(efx, ppid);
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int efx_get_phys_port_name(struct net_device *net_dev, char *name, size_t len)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
if (snprintf(name, len, "p%u", efx->port_num) >= len)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,13 @@ int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev,
|
|||
struct net_device *net_dev);
|
||||
void efx_fini_struct(struct efx_nic *efx);
|
||||
|
||||
#define EFX_MAX_DMAQ_SIZE 4096UL
|
||||
#define EFX_DEFAULT_DMAQ_SIZE 1024UL
|
||||
#define EFX_MIN_DMAQ_SIZE 512UL
|
||||
|
||||
#define EFX_MAX_EVQ_SIZE 16384UL
|
||||
#define EFX_MIN_EVQ_SIZE 512UL
|
||||
|
||||
void efx_link_clear_advertising(struct efx_nic *efx);
|
||||
void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
|
||||
|
||||
|
@ -46,10 +53,15 @@ int efx_reconfigure_port(struct efx_nic *efx);
|
|||
|
||||
int efx_try_recovery(struct efx_nic *efx);
|
||||
void efx_reset_down(struct efx_nic *efx, enum reset_type method);
|
||||
void efx_watchdog(struct net_device *net_dev, unsigned int txqueue);
|
||||
int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok);
|
||||
int efx_reset(struct efx_nic *efx, enum reset_type method);
|
||||
void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
|
||||
|
||||
/* Dummy PHY ops for PHY drivers */
|
||||
int efx_port_dummy_op_int(struct efx_nic *efx);
|
||||
void efx_port_dummy_op_void(struct efx_nic *efx);
|
||||
|
||||
static inline int efx_check_disabled(struct efx_nic *efx)
|
||||
{
|
||||
if (efx->state == STATE_DISABLED || efx->state == STATE_RECOVERY) {
|
||||
|
@ -60,6 +72,21 @@ static inline int efx_check_disabled(struct efx_nic *efx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void efx_schedule_channel(struct efx_channel *channel)
|
||||
{
|
||||
netif_vdbg(channel->efx, intr, channel->efx->net_dev,
|
||||
"channel %d scheduling NAPI poll on CPU%d\n",
|
||||
channel->channel, raw_smp_processor_id());
|
||||
|
||||
napi_schedule(&channel->napi_str);
|
||||
}
|
||||
|
||||
static inline void efx_schedule_channel_irq(struct efx_channel *channel)
|
||||
{
|
||||
channel->event_test_cpu = raw_smp_processor_id();
|
||||
efx_schedule_channel(channel);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SFC_MCDI_LOGGING
|
||||
void efx_init_mcdi_logging(struct efx_nic *efx);
|
||||
void efx_fini_mcdi_logging(struct efx_nic *efx);
|
||||
|
@ -69,9 +96,18 @@ static inline void efx_fini_mcdi_logging(struct efx_nic *efx) {}
|
|||
#endif
|
||||
|
||||
void efx_mac_reconfigure(struct efx_nic *efx);
|
||||
int efx_set_mac_address(struct net_device *net_dev, void *data);
|
||||
void efx_set_rx_mode(struct net_device *net_dev);
|
||||
int efx_set_features(struct net_device *net_dev, netdev_features_t data);
|
||||
void efx_link_status_changed(struct efx_nic *efx);
|
||||
unsigned int efx_xdp_max_mtu(struct efx_nic *efx);
|
||||
int efx_change_mtu(struct net_device *net_dev, int new_mtu);
|
||||
|
||||
extern const struct pci_error_handlers efx_err_handlers;
|
||||
|
||||
int efx_get_phys_port_id(struct net_device *net_dev,
|
||||
struct netdev_phys_item_id *ppid);
|
||||
|
||||
int efx_get_phys_port_name(struct net_device *net_dev,
|
||||
char *name, size_t len);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue