Skip to content

Commit

Permalink
Merge branch 'sfc-remove-nic_data-usage-in-common-code'
Browse files Browse the repository at this point in the history
Edward Cree says:

====================
sfc: remove nic_data usage in common code

efx->nic_data should only be used from NIC-specific code (i.e. nic_type
 functions and things they call), in files like ef10[_sriov].c and
 siena.c.  This series refactors several nic_data usages from common
 code (mainly in mcdi_filters.c) into nic_type functions, in preparation
 for the upcoming ef100 driver which will use those functions but have
 its own struct layout for efx->nic_data distinct from ef10's.
After this series, one nic_data usage (in ptp.c) remains; it wasn't
 clear to me how to fix it, and ef100 devices don't yet have PTP support
 (so the initial ef100 driver will not call that code).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 11, 2020
2 parents a90f704 + 9b46132 commit 9b1b31d
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 186 deletions.
214 changes: 132 additions & 82 deletions drivers/net/ethernet/sfc/ef10.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ static int efx_ef10_probe(struct efx_nic *efx)

efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;

nic_data->vport_id = EVB_PORT_ID_ASSIGNED;
efx->vport_id = EVB_PORT_ID_ASSIGNED;

/* In case we're recovering from a crash (kexec), we want to
* cancel any outstanding request by the previous user of this
Expand Down Expand Up @@ -1281,13 +1281,13 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
nic_data->must_check_datapath_caps = false;
}

if (nic_data->must_realloc_vis) {
if (efx->must_realloc_vis) {
/* We cannot let the number of VIs change now */
rc = efx_ef10_alloc_vis(efx, nic_data->n_allocated_vis,
nic_data->n_allocated_vis);
if (rc)
return rc;
nic_data->must_realloc_vis = false;
efx->must_realloc_vis = false;
}

if (nic_data->must_restore_piobufs && nic_data->n_piobufs) {
Expand Down Expand Up @@ -1326,16 +1326,15 @@ static void efx_ef10_table_reset_mc_allocations(struct efx_nic *efx)
#endif

/* All our allocations have been reset */
nic_data->must_realloc_vis = true;
nic_data->must_restore_rss_contexts = true;
nic_data->must_restore_filters = true;
efx->must_realloc_vis = true;
efx_mcdi_filter_table_reset_mc_allocations(efx);
nic_data->must_restore_piobufs = true;
efx_ef10_forget_old_piobufs(efx);
efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;

/* Driver-created vswitches and vports must be re-created */
nic_data->must_probe_vswitching = true;
nic_data->vport_id = EVB_PORT_ID_ASSIGNED;
efx->vport_id = EVB_PORT_ID_ASSIGNED;
#ifdef CONFIG_SFC_SRIOV
if (nic_data->vf)
for (i = 0; i < efx->vf_count; i++)
Expand Down Expand Up @@ -2389,6 +2388,86 @@ static void efx_ef10_tx_write(struct efx_tx_queue *tx_queue)
}
}

static int efx_ef10_probe_multicast_chaining(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
unsigned int enabled, implemented;
bool want_workaround_26807;
int rc;

rc = efx_mcdi_get_workarounds(efx, &implemented, &enabled);
if (rc == -ENOSYS) {
/* GET_WORKAROUNDS was implemented before this workaround,
* thus it must be unavailable in this firmware.
*/
nic_data->workaround_26807 = false;
return 0;
}
if (rc)
return rc;
want_workaround_26807 =
implemented & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807;
nic_data->workaround_26807 =
!!(enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807);

if (want_workaround_26807 && !nic_data->workaround_26807) {
unsigned int flags;

rc = efx_mcdi_set_workaround(efx,
MC_CMD_WORKAROUND_BUG26807,
true, &flags);
if (!rc) {
if (flags &
1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN) {
netif_info(efx, drv, efx->net_dev,
"other functions on NIC have been reset\n");

/* With MCFW v4.6.x and earlier, the
* boot count will have incremented,
* so re-read the warm_boot_count
* value now to ensure this function
* doesn't think it has changed next
* time it checks.
*/
rc = efx_ef10_get_warm_boot_count(efx);
if (rc >= 0) {
nic_data->warm_boot_count = rc;
rc = 0;
}
}
nic_data->workaround_26807 = true;
} else if (rc == -EPERM) {
rc = 0;
}
}
return rc;
}

static int efx_ef10_filter_table_probe(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
int rc = efx_ef10_probe_multicast_chaining(efx);
struct efx_mcdi_filter_vlan *vlan;

if (rc)
return rc;
rc = efx_mcdi_filter_table_probe(efx, nic_data->workaround_26807);

if (rc)
return rc;

list_for_each_entry(vlan, &nic_data->vlan_list, list) {
rc = efx_mcdi_filter_add_vlan(efx, vlan->vid);
if (rc)
goto fail_add_vlan;
}
return 0;

fail_add_vlan:
efx_mcdi_filter_table_remove(efx);
return rc;
}

/* This creates an entry in the RX descriptor queue */
static inline void
efx_ef10_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
Expand Down Expand Up @@ -2464,75 +2543,14 @@ static int efx_ef10_ev_init(struct efx_channel *channel)
{
struct efx_nic *efx = channel->efx;
struct efx_ef10_nic_data *nic_data;
unsigned int enabled, implemented;
bool use_v2, cut_thru;
int rc;

nic_data = efx->nic_data;
use_v2 = nic_data->datapath_caps2 &
1 << MC_CMD_GET_CAPABILITIES_V2_OUT_INIT_EVQ_V2_LBN;
cut_thru = !(nic_data->datapath_caps &
1 << MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN);
rc = efx_mcdi_ev_init(channel, cut_thru, use_v2);

/* IRQ return is ignored */
if (channel->channel || rc)
return rc;

/* Successfully created event queue on channel 0 */
rc = efx_mcdi_get_workarounds(efx, &implemented, &enabled);
if (rc == -ENOSYS) {
/* GET_WORKAROUNDS was implemented before this workaround,
* thus it must be unavailable in this firmware.
*/
nic_data->workaround_26807 = false;
rc = 0;
} else if (rc) {
goto fail;
} else {
nic_data->workaround_26807 =
!!(enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807);

if (implemented & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807 &&
!nic_data->workaround_26807) {
unsigned int flags;

rc = efx_mcdi_set_workaround(efx,
MC_CMD_WORKAROUND_BUG26807,
true, &flags);

if (!rc) {
if (flags &
1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN) {
netif_info(efx, drv, efx->net_dev,
"other functions on NIC have been reset\n");

/* With MCFW v4.6.x and earlier, the
* boot count will have incremented,
* so re-read the warm_boot_count
* value now to ensure this function
* doesn't think it has changed next
* time it checks.
*/
rc = efx_ef10_get_warm_boot_count(efx);
if (rc >= 0) {
nic_data->warm_boot_count = rc;
rc = 0;
}
}
nic_data->workaround_26807 = true;
} else if (rc == -EPERM) {
rc = 0;
}
}
}

if (!rc)
return 0;

fail:
efx_mcdi_ev_fini(channel);
return rc;
return efx_mcdi_ev_init(channel, cut_thru, use_v2);
}

static void efx_ef10_handle_rx_wrong_queue(struct efx_rx_queue *rx_queue,
Expand Down Expand Up @@ -3100,16 +3118,15 @@ void efx_ef10_handle_drain_event(struct efx_nic *efx)

static int efx_ef10_fini_dmaq(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
struct efx_channel *channel;
int pending;

/* If the MC has just rebooted, the TX/RX queues will have already been
* torn down, but efx->active_queues needs to be set to zero.
*/
if (nic_data->must_realloc_vis) {
if (efx->must_realloc_vis) {
atomic_set(&efx->active_queues, 0);
return 0;
}
Expand Down Expand Up @@ -3158,22 +3175,22 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
efx_mcdi_filter_table_remove(efx);
up_write(&efx->filter_sem);

rc = efx_ef10_vadaptor_free(efx, nic_data->vport_id);
rc = efx_ef10_vadaptor_free(efx, efx->vport_id);
if (rc)
goto restore_filters;

ether_addr_copy(mac_old, nic_data->vport_mac);
rc = efx_ef10_vport_del_mac(efx, nic_data->vport_id,
rc = efx_ef10_vport_del_mac(efx, efx->vport_id,
nic_data->vport_mac);
if (rc)
goto restore_vadaptor;

rc = efx_ef10_vport_add_mac(efx, nic_data->vport_id,
rc = efx_ef10_vport_add_mac(efx, efx->vport_id,
efx->net_dev->dev_addr);
if (!rc) {
ether_addr_copy(nic_data->vport_mac, efx->net_dev->dev_addr);
} else {
rc2 = efx_ef10_vport_add_mac(efx, nic_data->vport_id, mac_old);
rc2 = efx_ef10_vport_add_mac(efx, efx->vport_id, mac_old);
if (rc2) {
/* Failed to add original MAC, so clear vport_mac */
eth_zero_addr(nic_data->vport_mac);
Expand All @@ -3182,12 +3199,12 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
}

restore_vadaptor:
rc2 = efx_ef10_vadaptor_alloc(efx, nic_data->vport_id);
rc2 = efx_ef10_vadaptor_alloc(efx, efx->vport_id);
if (rc2)
goto reset_nic;
restore_filters:
down_write(&efx->filter_sem);
rc2 = efx_mcdi_filter_table_probe(efx);
rc2 = efx_ef10_filter_table_probe(efx);
up_write(&efx->filter_sem);
if (rc2)
goto reset_nic;
Expand Down Expand Up @@ -3225,11 +3242,11 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
ether_addr_copy(MCDI_PTR(inbuf, VADAPTOR_SET_MAC_IN_MACADDR),
efx->net_dev->dev_addr);
MCDI_SET_DWORD(inbuf, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID,
nic_data->vport_id);
efx->vport_id);
rc = efx_mcdi_rpc_quiet(efx, MC_CMD_VADAPTOR_SET_MAC, inbuf,
sizeof(inbuf), NULL, 0, NULL);

efx_mcdi_filter_table_probe(efx);
efx_ef10_filter_table_probe(efx);
up_write(&efx->filter_sem);
mutex_unlock(&efx->mac_lock);

Expand Down Expand Up @@ -3961,6 +3978,35 @@ static int efx_ef10_udp_tnl_del_port(struct efx_nic *efx,
return rc;
}

/* EF10 may have multiple datapath firmware variants within a
* single version. Report which variants are running.
*/
static size_t efx_ef10_print_additional_fwver(struct efx_nic *efx, char *buf,
size_t len)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;

return scnprintf(buf, len, " rx%x tx%x",
nic_data->rx_dpcpu_fw_id,
nic_data->tx_dpcpu_fw_id);
}

static unsigned int ef10_check_caps(const struct efx_nic *efx,
u8 flag,
u32 offset)
{
const struct efx_ef10_nic_data *nic_data = efx->nic_data;

switch (offset) {
case(MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS1_OFST):
return nic_data->datapath_caps & BIT_ULL(flag);
case(MC_CMD_GET_CAPABILITIES_V4_OUT_FLAGS2_OFST):
return nic_data->datapath_caps2 & BIT_ULL(flag);
default:
return 0;
}
}

#define EF10_OFFLOAD_FEATURES \
(NETIF_F_IP_CSUM | \
NETIF_F_HW_VLAN_CTAG_FILTER | \
Expand Down Expand Up @@ -4027,7 +4073,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.ev_process = efx_ef10_ev_process,
.ev_read_ack = efx_ef10_ev_read_ack,
.ev_test_generate = efx_ef10_ev_test_generate,
.filter_table_probe = efx_mcdi_filter_table_probe,
.filter_table_probe = efx_ef10_filter_table_probe,
.filter_table_restore = efx_mcdi_filter_table_restore,
.filter_table_remove = efx_mcdi_filter_table_remove,
.filter_update_rx_scatter = efx_mcdi_update_rx_scatter,
Expand Down Expand Up @@ -4073,6 +4119,8 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
1 << HWTSTAMP_FILTER_ALL,
.rx_hash_key_size = 40,
.check_caps = ef10_check_caps,
.print_additional_fwver = efx_ef10_print_additional_fwver,
};

const struct efx_nic_type efx_hunt_a0_nic_type = {
Expand Down Expand Up @@ -4139,7 +4187,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.ev_process = efx_ef10_ev_process,
.ev_read_ack = efx_ef10_ev_read_ack,
.ev_test_generate = efx_ef10_ev_test_generate,
.filter_table_probe = efx_mcdi_filter_table_probe,
.filter_table_probe = efx_ef10_filter_table_probe,
.filter_table_restore = efx_mcdi_filter_table_restore,
.filter_table_remove = efx_mcdi_filter_table_remove,
.filter_update_rx_scatter = efx_mcdi_update_rx_scatter,
Expand Down Expand Up @@ -4208,4 +4256,6 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
1 << HWTSTAMP_FILTER_ALL,
.rx_hash_key_size = 40,
.check_caps = ef10_check_caps,
.print_additional_fwver = efx_ef10_print_additional_fwver,
};
Loading

0 comments on commit 9b1b31d

Please sign in to comment.