diff options
Diffstat (limited to 'drivers/net/ethernet/sfc/ef10.c')
-rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 70 |
1 files changed, 51 insertions, 19 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 5cc786aec7c4..dcd6be14a430 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -233,7 +233,7 @@ static int efx_ef10_get_vf_index(struct efx_nic *efx) static int efx_ef10_init_datapath_caps(struct efx_nic *efx) { - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V2_OUT_LEN); + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V3_OUT_LEN); struct efx_ef10_nic_data *nic_data = efx->nic_data; size_t outlen; int rc; @@ -277,6 +277,35 @@ static int efx_ef10_init_datapath_caps(struct efx_nic *efx) return -ENODEV; } + if (outlen >= MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) { + u8 vi_window_mode = MCDI_BYTE(outbuf, + GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE); + + switch (vi_window_mode) { + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K: + efx->vi_stride = 8192; + break; + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K: + efx->vi_stride = 16384; + break; + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K: + efx->vi_stride = 65536; + break; + default: + netif_err(efx, probe, efx->net_dev, + "Unrecognised VI window mode %d\n", + vi_window_mode); + return -EIO; + } + netif_dbg(efx, probe, efx->net_dev, "vi_stride = %u\n", + efx->vi_stride); + } else { + /* keep default VI stride */ + netif_dbg(efx, probe, efx->net_dev, + "firmware did not report VI window mode, assuming vi_stride = %u\n", + efx->vi_stride); + } + return 0; } @@ -609,17 +638,6 @@ static int efx_ef10_probe(struct efx_nic *efx) struct efx_ef10_nic_data *nic_data; int i, rc; - /* We can have one VI for each 8K region. 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_PAGE_SIZE * EFX_TXQ_TYPES)); - efx->max_tx_channels = efx->max_channels; - if (WARN_ON(efx->max_channels == 0)) - return -EIO; - nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); if (!nic_data) return -ENOMEM; @@ -691,6 +709,20 @@ static int efx_ef10_probe(struct efx_nic *efx) if (rc < 0) goto fail5; + /* We can have one VI for each vi_stride-byte region. + * 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_tx_channels = efx->max_channels; + if (WARN_ON(efx->max_channels == 0)) { + rc = -EIO; + goto fail5; + } + efx->rx_packet_len_offset = ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE; @@ -927,7 +959,7 @@ static int efx_ef10_link_piobufs(struct efx_nic *efx) } else { tx_queue->piobuf = nic_data->pio_write_base + - index * EFX_VI_PAGE_SIZE + offset; + index * efx->vi_stride + offset; tx_queue->piobuf_offset = offset; netif_dbg(efx, probe, efx->net_dev, "linked VI %u to PIO buffer %u offset %x addr %p\n", @@ -1273,19 +1305,19 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx) * for writing PIO buffers through. * * The UC mapping contains (channel_vis - 1) complete VIs and the - * first half of the next VI. Then the WC mapping begins with - * the second half of this last VI. + * first 4K of the next VI. Then the WC mapping begins with + * the remainder of this last VI. */ - uc_mem_map_size = PAGE_ALIGN((channel_vis - 1) * EFX_VI_PAGE_SIZE + + uc_mem_map_size = PAGE_ALIGN((channel_vis - 1) * efx->vi_stride + ER_DZ_TX_PIOBUF); if (nic_data->n_piobufs) { /* pio_write_vi_base rounds down to give the number of complete * VIs inside the UC mapping. */ - pio_write_vi_base = uc_mem_map_size / EFX_VI_PAGE_SIZE; + pio_write_vi_base = uc_mem_map_size / efx->vi_stride; wc_mem_map_size = (PAGE_ALIGN((pio_write_vi_base + nic_data->n_piobufs) * - EFX_VI_PAGE_SIZE) - + efx->vi_stride) - uc_mem_map_size); max_vis = pio_write_vi_base + nic_data->n_piobufs; } else { @@ -1357,7 +1389,7 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx) nic_data->pio_write_vi_base = pio_write_vi_base; nic_data->pio_write_base = nic_data->wc_membase + - (pio_write_vi_base * EFX_VI_PAGE_SIZE + ER_DZ_TX_PIOBUF - + (pio_write_vi_base * efx->vi_stride + ER_DZ_TX_PIOBUF - uc_mem_map_size); rc = efx_ef10_link_piobufs(efx); |