Skip to content

Commit

Permalink
Merge branch 'sfc-prerequisites-for-EF100-driver-part-1'
Browse files Browse the repository at this point in the history
Edward Cree says:

====================
sfc: prerequisites for EF100 driver, part 1

This continues the work started by Alex Maftei <[email protected]>
 in the series "sfc: code refactoring", "sfc: more code refactoring",
 "sfc: even more code refactoring" and "sfc: refactor mcdi filtering
 code", to prepare for a new driver which will share much of the code
 to support the new EF100 family of Solarflare/Xilinx NICs.
After this series, there will be approximately two more of these
 'prerequisites' series, followed by the sfc_ef100 driver itself.

v2: fix reverse xmas tree in patch 5.  (Left the cases in patches 7,
 9 and 14 alone as those are all in pure movement of existing code.)
====================

Reviewed-by: Jakub Kicinski <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jun 30, 2020
2 parents 5f035af + 4d9c0a2 commit 17af2c4
Show file tree
Hide file tree
Showing 24 changed files with 8,671 additions and 1,711 deletions.
34 changes: 29 additions & 5 deletions drivers/net/ethernet/sfc/bitfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,10 @@ typedef union efx_oword {
field7, value7, \
field8, value8, \
field9, value9, \
field10, value10) \
field10, value10, \
field11, value11, \
field12, value12, \
field13, value13) \
(EFX_INSERT_FIELD_NATIVE((min), (max), field1, (value1)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field2, (value2)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field3, (value3)) | \
Expand All @@ -292,7 +295,10 @@ typedef union efx_oword {
EFX_INSERT_FIELD_NATIVE((min), (max), field7, (value7)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field8, (value8)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field9, (value9)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field10, (value10)))
EFX_INSERT_FIELD_NATIVE((min), (max), field10, (value10)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field11, (value11)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field12, (value12)) | \
EFX_INSERT_FIELD_NATIVE((min), (max), field13, (value13)))

#define EFX_INSERT_FIELDS64(...) \
cpu_to_le64(EFX_INSERT_FIELDS_NATIVE(__VA_ARGS__))
Expand Down Expand Up @@ -334,7 +340,13 @@ typedef union efx_oword {
#endif

/* Populate an octword field with various numbers of arguments */
#define EFX_POPULATE_OWORD_10 EFX_POPULATE_OWORD
#define EFX_POPULATE_OWORD_13 EFX_POPULATE_OWORD
#define EFX_POPULATE_OWORD_12(oword, ...) \
EFX_POPULATE_OWORD_13(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_OWORD_11(oword, ...) \
EFX_POPULATE_OWORD_12(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_OWORD_10(oword, ...) \
EFX_POPULATE_OWORD_11(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_OWORD_9(oword, ...) \
EFX_POPULATE_OWORD_10(oword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_OWORD_8(oword, ...) \
Expand Down Expand Up @@ -363,7 +375,13 @@ typedef union efx_oword {
EFX_DWORD_3, 0xffffffff)

/* Populate a quadword field with various numbers of arguments */
#define EFX_POPULATE_QWORD_10 EFX_POPULATE_QWORD
#define EFX_POPULATE_QWORD_13 EFX_POPULATE_QWORD
#define EFX_POPULATE_QWORD_12(qword, ...) \
EFX_POPULATE_QWORD_13(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_QWORD_11(qword, ...) \
EFX_POPULATE_QWORD_12(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_QWORD_10(qword, ...) \
EFX_POPULATE_QWORD_11(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_QWORD_9(qword, ...) \
EFX_POPULATE_QWORD_10(qword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_QWORD_8(qword, ...) \
Expand All @@ -390,7 +408,13 @@ typedef union efx_oword {
EFX_DWORD_1, 0xffffffff)

/* Populate a dword field with various numbers of arguments */
#define EFX_POPULATE_DWORD_10 EFX_POPULATE_DWORD
#define EFX_POPULATE_DWORD_13 EFX_POPULATE_DWORD
#define EFX_POPULATE_DWORD_12(dword, ...) \
EFX_POPULATE_DWORD_13(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_DWORD_11(dword, ...) \
EFX_POPULATE_DWORD_12(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_DWORD_10(dword, ...) \
EFX_POPULATE_DWORD_11(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_DWORD_9(dword, ...) \
EFX_POPULATE_DWORD_10(dword, EFX_DUMMY_FIELD, 0, __VA_ARGS__)
#define EFX_POPULATE_DWORD_8(dword, ...) \
Expand Down
100 changes: 50 additions & 50 deletions drivers/net/ethernet/sfc/ef10.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,10 +601,14 @@ static int efx_ef10_probe(struct efx_nic *efx)
* However, until we use TX option descriptors we need two TX queues
* per channel.
*/
efx->max_channels = min_t(unsigned int,
EFX_MAX_CHANNELS,
efx_ef10_mem_map_size(efx) /
(efx->vi_stride * EFX_TXQ_TYPES));
efx->max_vis = efx_ef10_mem_map_size(efx) / efx->vi_stride;
if (!efx->max_vis) {
netif_err(efx, drv, efx->net_dev, "error determining max VIs\n");
rc = -EIO;
goto fail5;
}
efx->max_channels = min_t(unsigned int, EFX_MAX_CHANNELS,
efx->max_vis / EFX_TXQ_TYPES);
efx->max_tx_channels = efx->max_channels;
if (WARN_ON(efx->max_channels == 0)) {
rc = -EIO;
Expand Down Expand Up @@ -1129,6 +1133,12 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
((efx->n_tx_channels + efx->n_extra_tx_channels) *
EFX_TXQ_TYPES) +
efx->n_xdp_channels * efx->xdp_tx_per_channel);
if (efx->max_vis && efx->max_vis < channel_vis) {
netif_dbg(efx, drv, efx->net_dev,
"Reducing channel VIs from %u to %u\n",
channel_vis, efx->max_vis);
channel_vis = efx->max_vis;
}

#ifdef EFX_USE_PIO
/* Try to allocate PIO buffers if wanted and if the full
Expand Down Expand Up @@ -1269,6 +1279,14 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
return 0;
}

static void efx_ef10_fini_nic(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;

kfree(nic_data->mc_stats);
nic_data->mc_stats = NULL;
}

static int efx_ef10_init_nic(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
Expand All @@ -1290,6 +1308,11 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
efx->must_realloc_vis = false;
}

nic_data->mc_stats = kmalloc(efx->num_mac_stats * sizeof(__le64),
GFP_KERNEL);
if (!nic_data->mc_stats)
return -ENOMEM;

if (nic_data->must_restore_piobufs && nic_data->n_piobufs) {
rc = efx_ef10_alloc_piobufs(efx, nic_data->n_piobufs);
if (rc == 0) {
Expand Down Expand Up @@ -1410,8 +1433,6 @@ static int efx_ef10_reset(struct efx_nic *efx, enum reset_type reset_type)
{ NULL, 64, 8 * MC_CMD_MAC_ ## mcdi_name }
#define EF10_OTHER_STAT(ext_name) \
[EF10_STAT_ ## ext_name] = { #ext_name, 0, 0 }
#define GENERIC_SW_STAT(ext_name) \
[GENERIC_STAT_ ## ext_name] = { #ext_name, 0, 0 }

static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
EF10_DMA_STAT(port_tx_bytes, TX_BYTES),
Expand Down Expand Up @@ -1455,8 +1476,8 @@ static const struct efx_hw_stat_desc efx_ef10_stat_desc[EF10_STAT_COUNT] = {
EF10_DMA_STAT(port_rx_align_error, RX_ALIGN_ERROR_PKTS),
EF10_DMA_STAT(port_rx_length_error, RX_LENGTH_ERROR_PKTS),
EF10_DMA_STAT(port_rx_nodesc_drops, RX_NODESC_DROPS),
GENERIC_SW_STAT(rx_nodesc_trunc),
GENERIC_SW_STAT(rx_noskb_drops),
EFX_GENERIC_SW_STAT(rx_nodesc_trunc),
EFX_GENERIC_SW_STAT(rx_noskb_drops),
EF10_DMA_STAT(port_rx_pm_trunc_bb_overflow, PM_TRUNC_BB_OVERFLOW),
EF10_DMA_STAT(port_rx_pm_discard_bb_overflow, PM_DISCARD_BB_OVERFLOW),
EF10_DMA_STAT(port_rx_pm_trunc_vfifo_full, PM_TRUNC_VFIFO_FULL),
Expand Down Expand Up @@ -1765,55 +1786,42 @@ static size_t efx_ef10_update_stats_common(struct efx_nic *efx, u64 *full_stats,
return stats_count;
}

static int efx_ef10_try_update_nic_stats_pf(struct efx_nic *efx)
static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
struct rtnl_link_stats64 *core_stats)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
DECLARE_BITMAP(mask, EF10_STAT_COUNT);
__le64 generation_start, generation_end;
u64 *stats = nic_data->stats;
__le64 *dma_stats;

efx_ef10_get_stat_mask(efx, mask);

dma_stats = efx->stats_buffer.addr;

generation_end = dma_stats[efx->num_mac_stats - 1];
if (generation_end == EFX_MC_STATS_GENERATION_INVALID)
return 0;
rmb();
efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask,
stats, efx->stats_buffer.addr, false);
rmb();
generation_start = dma_stats[MC_CMD_MAC_GENERATION_START];
if (generation_end != generation_start)
return -EAGAIN;
efx_nic_copy_stats(efx, nic_data->mc_stats);
efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT,
mask, stats, nic_data->mc_stats, false);

/* Update derived statistics */
efx_nic_fix_nodesc_drop_stat(efx,
&stats[EF10_STAT_port_rx_nodesc_drops]);
/* MC Firmware reads RX_BYTES and RX_GOOD_BYTES from the MAC.
* It then calculates RX_BAD_BYTES and DMAs it to us with RX_BYTES.
* We report these as port_rx_ stats. We are not given RX_GOOD_BYTES.
* Here we calculate port_rx_good_bytes.
*/
stats[EF10_STAT_port_rx_good_bytes] =
stats[EF10_STAT_port_rx_bytes] -
stats[EF10_STAT_port_rx_bytes_minus_good_bytes];

/* The asynchronous reads used to calculate RX_BAD_BYTES in
* MC Firmware are done such that we should not see an increase in
* RX_BAD_BYTES when a good packet has arrived. Unfortunately this
* does mean that the stat can decrease at times. Here we do not
* update the stat unless it has increased or has gone to zero
* (In the case of the NIC rebooting).
* Please see Bug 33781 for a discussion of why things work this way.
*/
efx_update_diff_stat(&stats[EF10_STAT_port_rx_bad_bytes],
stats[EF10_STAT_port_rx_bytes_minus_good_bytes]);
efx_update_sw_stats(efx, stats);
return 0;
}


static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
struct rtnl_link_stats64 *core_stats)
{
int retry;

/* If we're unlucky enough to read statistics during the DMA, wait
* up to 10ms for it to finish (typically takes <500us)
*/
for (retry = 0; retry < 100; ++retry) {
if (efx_ef10_try_update_nic_stats_pf(efx) == 0)
break;
udelay(100);
}

return efx_ef10_update_stats_common(efx, full_stats, core_stats);
}
Expand Down Expand Up @@ -3109,14 +3117,6 @@ static void efx_ef10_ev_test_generate(struct efx_channel *channel)
netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
}

void efx_ef10_handle_drain_event(struct efx_nic *efx)
{
if (atomic_dec_and_test(&efx->active_queues))
wake_up(&efx->flush_wq);

WARN_ON(atomic_read(&efx->active_queues) < 0);
}

static int efx_ef10_fini_dmaq(struct efx_nic *efx)
{
struct efx_tx_queue *tx_queue;
Expand Down Expand Up @@ -4023,7 +4023,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.remove = efx_ef10_remove,
.dimension_resources = efx_ef10_dimension_resources,
.init = efx_ef10_init_nic,
.fini = efx_port_dummy_op_void,
.fini = efx_ef10_fini_nic,
.map_reset_reason = efx_ef10_map_reset_reason,
.map_reset_flags = efx_ef10_map_reset_flags,
.reset = efx_ef10_reset,
Expand Down Expand Up @@ -4132,7 +4132,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.remove = efx_ef10_remove,
.dimension_resources = efx_ef10_dimension_resources,
.init = efx_ef10_init_nic,
.fini = efx_port_dummy_op_void,
.fini = efx_ef10_fini_nic,
.map_reset_reason = efx_ef10_map_reset_reason,
.map_reset_flags = efx_ef10_map_reset_flags,
.reset = efx_ef10_reset,
Expand Down
Loading

0 comments on commit 17af2c4

Please sign in to comment.