|
|
@@ -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);
|