#define ETH_I40E_VF_MSG_CFG "vf_msg_cfg"
#define I40E_CLEAR_PXE_WAIT_MS 200
+#define I40E_VSI_TSR_QINQ_STRIP 0x4010
+#define I40E_VSI_TSR(_i) (0x00050800 + ((_i) * 4))
/* Maximun number of capability elements */
#define I40E_MAX_CAP_ELE_NUM 128
.rx_queue_intr_enable = i40e_dev_rx_queue_intr_enable,
.rx_queue_intr_disable = i40e_dev_rx_queue_intr_disable,
.rx_queue_release = i40e_dev_rx_queue_release,
- .rx_queue_count = i40e_dev_rx_queue_count,
- .rx_descriptor_done = i40e_dev_rx_descriptor_done,
- .rx_descriptor_status = i40e_dev_rx_descriptor_status,
- .tx_descriptor_status = i40e_dev_tx_descriptor_status,
.tx_queue_setup = i40e_dev_tx_queue_setup,
.tx_queue_release = i40e_dev_tx_queue_release,
.dev_led_on = i40e_dev_led_on,
PMD_INIT_FUNC_TRACE();
dev->dev_ops = &i40e_eth_dev_ops;
+ dev->rx_queue_count = i40e_dev_rx_queue_count;
+ dev->rx_descriptor_done = i40e_dev_rx_descriptor_done;
+ dev->rx_descriptor_status = i40e_dev_rx_descriptor_status;
+ dev->tx_descriptor_status = i40e_dev_tx_descriptor_status;
dev->rx_pkt_burst = i40e_recv_pkts;
dev->tx_pkt_burst = i40e_xmit_pkts;
dev->tx_pkt_prepare = i40e_prep_pkts;
if (fdir_info->hash_table)
rte_hash_free(fdir_info->hash_table);
if (fdir_info->fdir_flow_pool.bitmap)
- rte_bitmap_free(fdir_info->fdir_flow_pool.bitmap);
+ rte_free(fdir_info->fdir_flow_pool.bitmap);
if (fdir_info->fdir_flow_pool.pool)
rte_free(fdir_info->fdir_flow_pool.pool);
if (fdir_info->fdir_filter_array)
link->link_speed = ETH_SPEED_NUM_40G;
break;
default:
- link->link_speed = ETH_SPEED_NUM_NONE;
+ if (link->link_status)
+ link->link_speed = ETH_SPEED_NUM_UNKNOWN;
+ else
+ link->link_speed = ETH_SPEED_NUM_NONE;
break;
}
}
return ret;
}
+static void
+i40e_stat_update_48_in_64(struct i40e_hw *hw, uint32_t hireg,
+ uint32_t loreg, bool offset_loaded, uint64_t *offset,
+ uint64_t *stat, uint64_t *prev_stat)
+{
+ i40e_stat_update_48(hw, hireg, loreg, offset_loaded, offset, stat);
+ /* enlarge the limitation when statistics counters overflowed */
+ if (offset_loaded) {
+ if (I40E_RXTX_BYTES_L_48_BIT(*prev_stat) > *stat)
+ *stat += (uint64_t)1 << I40E_48_BIT_WIDTH;
+ *stat += I40E_RXTX_BYTES_H_16_BIT(*prev_stat);
+ }
+ *prev_stat = *stat;
+}
+
/* Get all the statistics of a VSI */
void
i40e_update_vsi_stats(struct i40e_vsi *vsi)
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
int idx = rte_le_to_cpu_16(vsi->info.stat_counter_idx);
- i40e_stat_update_48(hw, I40E_GLV_GORCH(idx), I40E_GLV_GORCL(idx),
- vsi->offset_loaded, &oes->rx_bytes,
- &nes->rx_bytes);
+ i40e_stat_update_48_in_64(hw, I40E_GLV_GORCH(idx), I40E_GLV_GORCL(idx),
+ vsi->offset_loaded, &oes->rx_bytes,
+ &nes->rx_bytes, &vsi->prev_rx_bytes);
i40e_stat_update_48(hw, I40E_GLV_UPRCH(idx), I40E_GLV_UPRCL(idx),
vsi->offset_loaded, &oes->rx_unicast,
&nes->rx_unicast);
i40e_stat_update_32(hw, I40E_GLV_RUPP(idx), vsi->offset_loaded,
&oes->rx_unknown_protocol,
&nes->rx_unknown_protocol);
- i40e_stat_update_48(hw, I40E_GLV_GOTCH(idx), I40E_GLV_GOTCL(idx),
- vsi->offset_loaded, &oes->tx_bytes,
- &nes->tx_bytes);
+ i40e_stat_update_48_in_64(hw, I40E_GLV_GOTCH(idx), I40E_GLV_GOTCL(idx),
+ vsi->offset_loaded, &oes->tx_bytes,
+ &nes->tx_bytes, &vsi->prev_tx_bytes);
i40e_stat_update_48(hw, I40E_GLV_UPTCH(idx), I40E_GLV_UPTCL(idx),
vsi->offset_loaded, &oes->tx_unicast,
&nes->tx_unicast);
struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */
/* Get rx/tx bytes of internal transfer packets */
- i40e_stat_update_48(hw, I40E_GLV_GORCH(hw->port),
- I40E_GLV_GORCL(hw->port),
- pf->offset_loaded,
- &pf->internal_stats_offset.rx_bytes,
- &pf->internal_stats.rx_bytes);
-
- i40e_stat_update_48(hw, I40E_GLV_GOTCH(hw->port),
- I40E_GLV_GOTCL(hw->port),
- pf->offset_loaded,
- &pf->internal_stats_offset.tx_bytes,
- &pf->internal_stats.tx_bytes);
+ i40e_stat_update_48_in_64(hw, I40E_GLV_GORCH(hw->port),
+ I40E_GLV_GORCL(hw->port),
+ pf->offset_loaded,
+ &pf->internal_stats_offset.rx_bytes,
+ &pf->internal_stats.rx_bytes,
+ &pf->internal_prev_rx_bytes);
+ i40e_stat_update_48_in_64(hw, I40E_GLV_GOTCH(hw->port),
+ I40E_GLV_GOTCL(hw->port),
+ pf->offset_loaded,
+ &pf->internal_stats_offset.tx_bytes,
+ &pf->internal_stats.tx_bytes,
+ &pf->internal_prev_tx_bytes);
/* Get total internal rx packet count */
i40e_stat_update_48(hw, I40E_GLV_UPRCH(hw->port),
I40E_GLV_UPRCL(hw->port),
pf->internal_stats.rx_broadcast) * RTE_ETHER_CRC_LEN;
/* Get statistics of struct i40e_eth_stats */
- i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port),
- I40E_GLPRT_GORCL(hw->port),
- pf->offset_loaded, &os->eth.rx_bytes,
- &ns->eth.rx_bytes);
+ i40e_stat_update_48_in_64(hw, I40E_GLPRT_GORCH(hw->port),
+ I40E_GLPRT_GORCL(hw->port),
+ pf->offset_loaded, &os->eth.rx_bytes,
+ &ns->eth.rx_bytes, &pf->prev_rx_bytes);
i40e_stat_update_48(hw, I40E_GLPRT_UPRCH(hw->port),
I40E_GLPRT_UPRCL(hw->port),
pf->offset_loaded, &os->eth.rx_unicast,
pf->offset_loaded,
&os->eth.rx_unknown_protocol,
&ns->eth.rx_unknown_protocol);
- i40e_stat_update_48(hw, I40E_GLPRT_GOTCH(hw->port),
- I40E_GLPRT_GOTCL(hw->port),
- pf->offset_loaded, &os->eth.tx_bytes,
- &ns->eth.tx_bytes);
+ i40e_stat_update_48_in_64(hw, I40E_GLPRT_GOTCH(hw->port),
+ I40E_GLPRT_GOTCL(hw->port),
+ pf->offset_loaded, &os->eth.tx_bytes,
+ &ns->eth.tx_bytes, &pf->prev_tx_bytes);
i40e_stat_update_48(hw, I40E_GLPRT_UPTCH(hw->port),
I40E_GLPRT_UPTCL(hw->port),
pf->offset_loaded, &os->eth.tx_unicast,
return ret;
}
+/* Configure outer vlan stripping on or off in QinQ mode */
+static int
+i40e_vsi_config_outer_vlan_stripping(struct i40e_vsi *vsi, bool on)
+{
+ struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+ int ret = I40E_SUCCESS;
+ uint32_t reg;
+
+ if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) {
+ PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum");
+ return -EINVAL;
+ }
+
+ /* Configure for outer VLAN RX stripping */
+ reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id));
+
+ if (on)
+ reg |= I40E_VSI_TSR_QINQ_STRIP;
+ else
+ reg &= ~I40E_VSI_TSR_QINQ_STRIP;
+
+ ret = i40e_aq_debug_write_register(hw,
+ I40E_VSI_TSR(vsi->vsi_id),
+ reg, NULL);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]",
+ vsi->vsi_id);
+ return I40E_ERR_CONFIG;
+ }
+
+ return ret;
+}
+
static int
i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
i40e_vsi_config_double_vlan(vsi, FALSE);
}
+ if (mask & ETH_QINQ_STRIP_MASK) {
+ /* Enable or disable outer VLAN stripping */
+ if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP)
+ i40e_vsi_config_outer_vlan_stripping(vsi, TRUE);
+ else
+ i40e_vsi_config_outer_vlan_stripping(vsi, FALSE);
+ }
+
return 0;
}
/* Apply vlan offload setting */
mask = ETH_VLAN_STRIP_MASK |
+ ETH_QINQ_STRIP_MASK |
ETH_VLAN_FILTER_MASK |
ETH_VLAN_EXTEND_MASK;
ret = i40e_vlan_offload_set(dev, mask);
case i40e_aqc_opc_get_link_status:
ret = i40e_dev_link_update(dev, 0);
if (!ret)
- _rte_eth_dev_callback_process(dev,
+ rte_eth_dev_callback_process(dev,
RTE_ETH_EVENT_INTR_LSC, NULL);
break;
default:
}
}
-#define I40E_VSI_TSR(_i) (0x00050800 + ((_i) * 4))
#define I40E_VSI_TSR_QINQ_CONFIG 0xc030
#define I40E_VSI_L2TAGSTXVALID(_i) (0x00042800 + ((_i) * 4))
#define I40E_VSI_L2TAGSTXVALID_QINQ 0xab