#define HNS3_DEFAULT_PORT_CONF_QUEUES_NUM 1
#define HNS3_SERVICE_INTERVAL 1000000 /* us */
-#define HNS3_PORT_BASE_VLAN_DISABLE 0
-#define HNS3_PORT_BASE_VLAN_ENABLE 1
#define HNS3_INVLID_PVID 0xFFFF
#define HNS3_FILTER_TYPE_VF 0
hns3_restore_vlan_table(struct hns3_adapter *hns)
{
struct hns3_user_vlan_table *vlan_entry;
+ struct hns3_hw *hw = &hns->hw;
struct hns3_pf *pf = &hns->pf;
uint16_t vlan_id;
int ret = 0;
- if (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_ENABLE)
+ if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_ENABLE)
return hns3_vlan_pvid_configure(hns,
- pf->port_base_vlan_cfg.pvid, 1);
+ hw->port_base_vlan_cfg.pvid, 1);
LIST_FOREACH(vlan_entry, &pf->vlan_list, next) {
if (vlan_entry->hd_tbl_status) {
static int
hns3_vlan_filter_configure(struct hns3_adapter *hns, uint16_t vlan_id, int on)
{
- struct hns3_pf *pf = &hns->pf;
+ struct hns3_hw *hw = &hns->hw;
bool writen_to_tbl = false;
int ret = 0;
* vlan list. The vlan id in vlan list will be writen in vlan filter
* table until port base vlan disabled
*/
- if (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) {
+ if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) {
ret = hns3_set_port_vlan_filter(hns, vlan_id, on);
writen_to_tbl = true;
}
hns3_en_hw_strip_rxvtag(struct hns3_adapter *hns, bool enable)
{
struct hns3_rx_vtag_cfg rxvlan_cfg;
- struct hns3_pf *pf = &hns->pf;
struct hns3_hw *hw = &hns->hw;
int ret;
- if (pf->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) {
+ if (hw->port_base_vlan_cfg.state == HNS3_PORT_BASE_VLAN_DISABLE) {
rxvlan_cfg.strip_tag1_en = false;
rxvlan_cfg.strip_tag2_en = enable;
} else {
static void
hns3_store_port_base_vlan_info(struct hns3_adapter *hns, uint16_t pvid, int on)
{
- struct hns3_pf *pf = &hns->pf;
+ struct hns3_hw *hw = &hns->hw;
- pf->port_base_vlan_cfg.state = on ?
+ hw->port_base_vlan_cfg.state = on ?
HNS3_PORT_BASE_VLAN_ENABLE : HNS3_PORT_BASE_VLAN_DISABLE;
- pf->port_base_vlan_cfg.pvid = pvid;
+ hw->port_base_vlan_cfg.pvid = pvid;
}
static void
hns3_remove_all_vlan_table(struct hns3_adapter *hns)
{
struct hns3_hw *hw = &hns->hw;
- struct hns3_pf *pf = &hns->pf;
int ret;
hns3_rm_all_vlan_table(hns, true);
- if (pf->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID) {
+ if (hw->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID) {
ret = hns3_set_port_vlan_filter(hns,
- pf->port_base_vlan_cfg.pvid, 0);
+ hw->port_base_vlan_cfg.pvid, 0);
if (ret) {
hns3_err(hw, "Failed to remove all vlan table, ret =%d",
ret);
uint16_t port_base_vlan_state,
uint16_t new_pvid, uint16_t old_pvid)
{
- struct hns3_pf *pf = &hns->pf;
struct hns3_hw *hw = &hns->hw;
int ret = 0;
}
}
- if (new_pvid == pf->port_base_vlan_cfg.pvid)
+ if (new_pvid == hw->port_base_vlan_cfg.pvid)
hns3_add_all_vlan_table(hns);
return ret;
static int
hns3_vlan_pvid_configure(struct hns3_adapter *hns, uint16_t pvid, int on)
{
- struct hns3_pf *pf = &hns->pf;
struct hns3_hw *hw = &hns->hw;
uint16_t port_base_vlan_state;
uint16_t old_pvid;
int ret;
- if (on == 0 && pvid != pf->port_base_vlan_cfg.pvid) {
- if (pf->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID)
+ if (on == 0 && pvid != hw->port_base_vlan_cfg.pvid) {
+ if (hw->port_base_vlan_cfg.pvid != HNS3_INVLID_PVID)
hns3_warn(hw, "Invalid operation! As current pvid set "
"is %u, disable pvid %u is invalid",
- pf->port_base_vlan_cfg.pvid, pvid);
+ hw->port_base_vlan_cfg.pvid, pvid);
return 0;
}
if (pvid == HNS3_INVLID_PVID)
goto out;
- old_pvid = pf->port_base_vlan_cfg.pvid;
+ old_pvid = hw->port_base_vlan_cfg.pvid;
ret = hns3_update_vlan_filter_entries(hns, port_base_vlan_state, pvid,
old_pvid);
if (ret) {
static void
init_port_base_vlan_info(struct hns3_hw *hw)
{
- struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
- struct hns3_pf *pf = &hns->pf;
-
- pf->port_base_vlan_cfg.state = HNS3_PORT_BASE_VLAN_DISABLE;
- pf->port_base_vlan_cfg.pvid = HNS3_INVLID_PVID;
+ hw->port_base_vlan_cfg.state = HNS3_PORT_BASE_VLAN_DISABLE;
+ hw->port_base_vlan_cfg.pvid = HNS3_INVLID_PVID;
}
static int
uint16_t nb_fake_tx_queues; /* Number of fake TX queues. */
};
+#define HNS3_PORT_BASE_VLAN_DISABLE 0
+#define HNS3_PORT_BASE_VLAN_ENABLE 1
+struct hns3_port_base_vlan_config {
+ uint16_t state;
+ uint16_t pvid;
+};
+
/* Primary process maintains driver state in main thread.
*
* +---------------+
uint16_t tx_qnum_per_tc; /* TX queue number per TC */
uint32_t flag;
+
+ struct hns3_port_base_vlan_config port_base_vlan_cfg;
/*
* PMD setup and configuration is not thread safe. Since it is not
* performance sensitive, it is better to guarantee thread-safety
uint16_t vlan_id;
};
-struct hns3_port_base_vlan_config {
- uint16_t state;
- uint16_t pvid;
-};
-
/* Vlan tag configuration for RX direction */
struct hns3_rx_vtag_cfg {
uint8_t rx_vlan_offload_en; /* Whether enable rx vlan offload */
bool support_sfp_query;
struct hns3_vtag_cfg vtag_config;
- struct hns3_port_base_vlan_config port_base_vlan_cfg;
LIST_HEAD(vlan_tbl, hns3_user_vlan_table) vlan_list;
struct hns3_fdir_info fdir; /* flow director info */
static const uint32_t l2table[HNS3_L2TBL_NUM] = {
RTE_PTYPE_L2_ETHER,
- RTE_PTYPE_L2_ETHER_VLAN,
RTE_PTYPE_L2_ETHER_QINQ,
- 0
+ RTE_PTYPE_L2_ETHER_VLAN,
+ RTE_PTYPE_L2_ETHER_VLAN
};
static const uint32_t l3table[HNS3_L3TBL_NUM] = {
}
}
+static inline void
+hns3_rxd_to_vlan_tci(struct rte_eth_dev *dev, struct rte_mbuf *mb,
+ uint32_t l234_info, const struct hns3_desc *rxd)
+{
+#define HNS3_STRP_STATUS_NUM 0x4
+
+#define HNS3_NO_STRP_VLAN_VLD 0x0
+#define HNS3_INNER_STRP_VLAN_VLD 0x1
+#define HNS3_OUTER_STRP_VLAN_VLD 0x2
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = &hns->hw;
+ uint32_t strip_status;
+ uint32_t report_mode;
+
+ /*
+ * Since HW limitation, the vlan tag will always be inserted into RX
+ * descriptor when strip the tag from packet, driver needs to determine
+ * reporting which tag to mbuf according to the PVID configuration
+ * and vlan striped status.
+ */
+ static const uint32_t report_type[][HNS3_STRP_STATUS_NUM] = {
+ {
+ HNS3_NO_STRP_VLAN_VLD,
+ HNS3_OUTER_STRP_VLAN_VLD,
+ HNS3_INNER_STRP_VLAN_VLD,
+ HNS3_OUTER_STRP_VLAN_VLD
+ },
+ {
+ HNS3_NO_STRP_VLAN_VLD,
+ HNS3_NO_STRP_VLAN_VLD,
+ HNS3_NO_STRP_VLAN_VLD,
+ HNS3_INNER_STRP_VLAN_VLD
+ }
+ };
+ strip_status = hns3_get_field(l234_info, HNS3_RXD_STRP_TAGP_M,
+ HNS3_RXD_STRP_TAGP_S);
+ report_mode = report_type[hw->port_base_vlan_cfg.state][strip_status];
+ switch (report_mode) {
+ case HNS3_NO_STRP_VLAN_VLD:
+ mb->vlan_tci = 0;
+ return;
+ case HNS3_INNER_STRP_VLAN_VLD:
+ mb->ol_flags |= PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED;
+ mb->vlan_tci = rte_le_to_cpu_16(rxd->rx.vlan_tag);
+ return;
+ case HNS3_OUTER_STRP_VLAN_VLD:
+ mb->ol_flags |= PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED;
+ mb->vlan_tci = rte_le_to_cpu_16(rxd->rx.ot_vlan_tag);
+ return;
+ }
+}
+
uint16_t
hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
{
hns3_rx_set_cksum_flag(first_seg,
first_seg->packet_type,
cksum_err);
+ hns3_rxd_to_vlan_tci(dev, first_seg, l234_info, &rxd);
- first_seg->vlan_tci = rte_le_to_cpu_16(rxd.rx.vlan_tag);
- first_seg->vlan_tci_outer =
- rte_le_to_cpu_16(rxd.rx.ot_vlan_tag);
rx_pkts[nb_rx++] = first_seg;
first_seg = NULL;
continue;