DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1] net/axgbe: vlan support enabling in axgbe
@ 2020-03-31  8:08 ssardar
  0 siblings, 0 replies; only message in thread
From: ssardar @ 2020-03-31  8:08 UTC (permalink / raw)
  To: dev; +Cc: Ravi1.Kumar

From: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>

adding APIs axgbe_enable_rx_vlan_stripping,
axgbe_disable_rx_vlan_stripping, axgbe_enable_rx_vlan_filtering,
axgbe_disable_rx_vlan_filtering, axgbe_update_vlan_hash_table,
axgbe_vlan_filter_set, axgbe_vlan_tpid_set, axgbe_vlan_offload_set

Signed-off-by: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
---
 doc/guides/nics/features/axgbe.ini |   1 +
 drivers/net/axgbe/axgbe_common.h   |  29 +++++
 drivers/net/axgbe/axgbe_dev.c      | 171 +++++++++++++++++++++++++++--
 drivers/net/axgbe/axgbe_ethdev.c   | 169 +++++++++++++++++++++++++++-
 drivers/net/axgbe/axgbe_ethdev.h   |  16 +++
 drivers/net/axgbe/axgbe_rxtx.c     |   6 +
 6 files changed, 381 insertions(+), 11 deletions(-)

diff --git a/doc/guides/nics/features/axgbe.ini b/doc/guides/nics/features/axgbe.ini
index 0becaa097..b7b4dd992 100644
--- a/doc/guides/nics/features/axgbe.ini
+++ b/doc/guides/nics/features/axgbe.ini
@@ -11,6 +11,7 @@ Scattered Rx         = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 RSS hash             = Y
+VLAN                 = Y
 CRC offload          = Y
 L3 checksum offload  = Y
 L4 checksum offload  = Y
diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h
index f48117180..4cf966d79 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -257,6 +257,7 @@
 #define MAC_HWF0R			0x011c
 #define MAC_HWF1R			0x0120
 #define MAC_HWF2R			0x0124
+#define MAC_HWF3R			0x0128
 #define MAC_MDIOSCAR			0x0200
 #define MAC_MDIOSCCDR			0x0204
 #define MAC_MDIOISR			0x0214
@@ -282,6 +283,18 @@
 #define MAC_TXSNR			0x0d30
 #define MAC_TXSSR			0x0d34
 
+/*VLAN control bit mask*/
+#define AXGBE_VLNCTRL_MASK		0x0000FFFF
+#define VLAN_PRIO_MASK			0xe000 /* Priority Code Point */
+#define VLAN_PRIO_SHIFT			13
+#define VLAN_CFI_MASK			0x1000 /* Canonical Format Indicator */
+#define VLAN_TAG_PRESENT		VLAN_CFI_MASK
+#define VLAN_VID_MASK			0x0fff /* VLAN Identifier */
+#define VLAN_N_VID			4096
+#define VLAN_TABLE_SIZE			64
+#define VLAN_TABLE_BIT(vlan_id)	((unsigned long)1 << ((vlan_id) & 0x3F))
+#define VLAN_TABLE_IDX(vlan_id)	((vlan_id) >> 6)
+
 #define MAC_QTFCR_INC			4
 #define MAC_MACA_INC			4
 #define MAC_HTR_INC			4
@@ -359,6 +372,10 @@
 #define MAC_HWF2R_TXCHCNT_WIDTH		4
 #define MAC_HWF2R_TXQCNT_INDEX		6
 #define MAC_HWF2R_TXQCNT_WIDTH		4
+#define MAC_HWF3R_CBTISEL_INDEX		4
+#define MAC_HWF3R_CBTISEL_WIDTH		1
+#define MAC_HWF3R_NRVF_INDEX		0
+#define MAC_HWF3R_NRVF_WIDTH		3
 #define MAC_IER_TSIE_INDEX		12
 #define MAC_IER_TSIE_WIDTH		1
 #define MAC_ISR_MMCRXIS_INDEX		9
@@ -513,6 +530,8 @@
 #define MAC_VLANIR_VLTI_WIDTH		1
 #define MAC_VLANIR_CSVL_INDEX		19
 #define MAC_VLANIR_CSVL_WIDTH		1
+#define MAC_VLANIR_VLC_INDEX		16
+#define MAC_VLANIR_VLC_WIDTH		2
 #define MAC_VLANTR_DOVLTC_INDEX		20
 #define MAC_VLANTR_DOVLTC_WIDTH		1
 #define MAC_VLANTR_ERSVLM_INDEX		19
@@ -523,12 +542,18 @@
 #define MAC_VLANTR_ETV_WIDTH		1
 #define MAC_VLANTR_EVLS_INDEX		21
 #define MAC_VLANTR_EVLS_WIDTH		2
+#define MAC_VLANTR_EIVLS_INDEX		21
+#define MAC_VLANTR_EIVLS_WIDTH		2
 #define MAC_VLANTR_EVLRXS_INDEX		24
 #define MAC_VLANTR_EVLRXS_WIDTH		1
+#define MAC_VLANTR_EIVLRXS_INDEX	31
+#define MAC_VLANTR_EIVLRXS_WIDTH	1
 #define MAC_VLANTR_VL_INDEX		0
 #define MAC_VLANTR_VL_WIDTH		16
 #define MAC_VLANTR_VTHM_INDEX		25
 #define MAC_VLANTR_VTHM_WIDTH		1
+#define MAC_VLANTR_EDVLP_INDEX		26
+#define MAC_VLANTR_EDVLP_WIDTH		1
 #define MAC_VLANTR_VTIM_INDEX		17
 #define MAC_VLANTR_VTIM_WIDTH		1
 #define MAC_VR_DEVID_INDEX		8
@@ -537,6 +562,10 @@
 #define MAC_VR_SNPSVER_WIDTH		8
 #define MAC_VR_USERVER_INDEX		16
 #define MAC_VR_USERVER_WIDTH		8
+#define MAC_VLANIR_VLT_INDEX		0
+#define MAC_VLANIR_VLT_WIDTH		16
+#define MAC_VLANTR_ERIVLT_INDEX		27
+#define MAC_VLANTR_ERIVLT_WIDTH		1
 
 /* MMC register offsets */
 #define MMC_CR				0x0800
diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index 5f0f19592..79b913c74 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -8,6 +8,46 @@
 #include "axgbe_phy.h"
 #include "axgbe_rxtx.h"
 
+static uint32_t bitrev32(uint32_t x)
+{
+	x = (x >> 16) | (x << 16);
+	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+	return x;
+}
+
+/*MSB set bit from 32 to 1*/
+static int get_lastbit_set(int x)
+{
+	int r = 32;
+
+	if (!x)
+		return 0;
+	if (!(x & 0xffff0000)) {
+		x <<= 16;
+		r -= 16;
+	}
+	if (!(x & 0xff000000)) {
+		x <<= 8;
+		r -= 8;
+	}
+	if (!(x & 0xf0000000)) {
+		x <<= 4;
+		r -= 4;
+	}
+	if (!(x & 0xc0000000)) {
+		x <<= 2;
+		r -= 2;
+	}
+	if (!(x & 0x80000000)) {
+		x <<= 1;
+		r -= 1;
+	}
+	return r;
+}
+
 static inline unsigned int axgbe_get_max_frame(struct axgbe_port *pdata)
 {
 	return pdata->eth_dev->data->mtu + RTE_ETHER_HDR_LEN +
@@ -407,6 +447,120 @@ static void axgbe_config_flow_control_threshold(struct axgbe_port *pdata)
 	}
 }
 
+static int axgbe_enable_rx_vlan_stripping(struct axgbe_port *pdata)
+{
+	/* Put the VLAN tag in the Rx descriptor */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLRXS, 1);
+
+	/* Don't check the VLAN type */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, DOVLTC, 1);
+
+	/* Check only C-TAG (0x8100) packets */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERSVLM, 0);
+
+	/* Don't consider an S-TAG (0x88A8) packet as a VLAN packet */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ESVL, 0);
+
+	/* Enable VLAN tag stripping */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0x3);
+	return 0;
+}
+
+static int axgbe_disable_rx_vlan_stripping(struct axgbe_port *pdata)
+{
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0);
+	return 0;
+}
+
+static int axgbe_enable_rx_vlan_filtering(struct axgbe_port *pdata)
+{
+	/* Enable VLAN filtering */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 1);
+
+	/* Enable VLAN Hash Table filtering */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTHM, 1);
+
+	/* Disable VLAN tag inverse matching */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VTIM, 0);
+
+	/* Only filter on the lower 12-bits of the VLAN tag */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ETV, 1);
+
+	/* In order for the VLAN Hash Table filtering to be effective,
+	 * the VLAN tag identifier in the VLAN Tag Register must not
+	 * be zero.  Set the VLAN tag identifier to "1" to enable the
+	 * VLAN Hash Table filtering.  This implies that a VLAN tag of
+	 * 1 will always pass filtering.
+	 */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, VL, 1);
+	return 0;
+}
+
+static int axgbe_disable_rx_vlan_filtering(struct axgbe_port *pdata)
+{
+	/* Disable VLAN filtering */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, VTFE, 0);
+	return 0;
+}
+
+static u32 axgbe_vid_crc32_le(__le16 vid_le)
+{
+	u32 poly = 0xedb88320;  /* CRCPOLY_LE */
+	u32 crc = ~0;
+	u32 temp = 0;
+	unsigned char *data = (unsigned char *)&vid_le;
+	unsigned char data_byte = 0;
+	int i, bits;
+
+	bits = get_lastbit_set(VLAN_VID_MASK);
+	for (i = 0; i < bits; i++) {
+		if ((i % 8) == 0)
+			data_byte = data[i / 8];
+
+		temp = ((crc & 1) ^ data_byte) & 1;
+		crc >>= 1;
+		data_byte >>= 1;
+
+		if (temp)
+			crc ^= poly;
+	}
+	return crc;
+}
+
+static int axgbe_update_vlan_hash_table(struct axgbe_port *pdata)
+{
+	u32 crc = 0;
+	u16 vid;
+	__le16 vid_le = 0;
+	u16 vlan_hash_table = 0;
+	unsigned int reg = 0;
+	unsigned long vid_idx, vid_valid;
+
+	/* Generate the VLAN Hash Table value */
+	for (vid = 0; vid < VLAN_N_VID; vid++) {
+		vid_idx = VLAN_TABLE_IDX(vid);
+		vid_valid = pdata->active_vlans[vid_idx];
+		vid_valid = (unsigned long)vid_valid >> (vid - (64 * vid_idx));
+		if (vid_valid & 1)
+			PMD_DRV_LOG(DEBUG,
+				    "vid:%d pdata->active_vlans[%ld]=0x%lx\n",
+				    vid, vid_idx, pdata->active_vlans[vid_idx]);
+		else
+			continue;
+
+		vid_le = rte_cpu_to_le_16(vid);
+		crc = bitrev32(~axgbe_vid_crc32_le(vid_le)) >> 28;
+		vlan_hash_table |= (1 << crc);
+		PMD_DRV_LOG(DEBUG, "crc = %d vlan_hash_table = 0x%x\n",
+			    crc, vlan_hash_table);
+	}
+	/* Set the VLAN Hash Table filtering register */
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANHTR, VLHT, vlan_hash_table);
+	reg = AXGMAC_IOREAD(pdata, MAC_VLANHTR);
+	PMD_DRV_LOG(DEBUG, "vlan_hash_table reg val = 0x%x\n", reg);
+	return 0;
+}
+
 static int __axgbe_exit(struct axgbe_port *pdata)
 {
 	unsigned int count = 2000;
@@ -1008,16 +1162,6 @@ static void axgbe_enable_mtl_interrupts(struct axgbe_port *pdata)
 	}
 }
 
-static uint32_t bitrev32(uint32_t x)
-{
-	x = (x >> 16) | (x << 16);
-	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
-	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
-	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
-	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
-	return x;
-}
-
 static uint32_t crc32_le(uint32_t crc, uint8_t *p, uint32_t len)
 {
 	int i;
@@ -1217,4 +1361,11 @@ void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if)
 	/* For FLOW ctrl */
 	hw_if->config_tx_flow_control = axgbe_config_tx_flow_control;
 	hw_if->config_rx_flow_control = axgbe_config_rx_flow_control;
+
+	/*vlan*/
+	hw_if->enable_rx_vlan_stripping = axgbe_enable_rx_vlan_stripping;
+	hw_if->disable_rx_vlan_stripping = axgbe_disable_rx_vlan_stripping;
+	hw_if->enable_rx_vlan_filtering = axgbe_enable_rx_vlan_filtering;
+	hw_if->disable_rx_vlan_filtering = axgbe_disable_rx_vlan_filtering;
+	hw_if->update_vlan_hash_table = axgbe_update_vlan_hash_table;
 }
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index 867058845..f50827d07 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -73,6 +73,14 @@ static void axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 static void axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
 	struct rte_eth_txq_info *qinfo);
 const uint32_t *axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev);
+static int
+axgbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on);
+static int
+axgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+		    enum rte_vlan_type vlan_type,
+		    uint16_t tpid);
+static int
+axgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 
 struct axgbe_xstats {
 	char name[RTE_ETH_XSTATS_NAME_SIZE];
@@ -214,6 +222,9 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = {
 	.dev_supported_ptypes_get     = axgbe_dev_supported_ptypes_get,
 	.rx_descriptor_status         = axgbe_dev_rx_descriptor_status,
 	.tx_descriptor_status         = axgbe_dev_tx_descriptor_status,
+	.vlan_filter_set      = axgbe_vlan_filter_set,
+	.vlan_tpid_set        = axgbe_vlan_tpid_set,
+	.vlan_offload_set     = axgbe_vlan_offload_set,
 };
 
 static int axgbe_phy_reset(struct axgbe_port *pdata)
@@ -995,6 +1006,9 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->speed_capa =  ETH_LINK_SPEED_10G;
 
 	dev_info->rx_offload_capa =
+		DEV_RX_OFFLOAD_VLAN_STRIP |
+		DEV_RX_OFFLOAD_VLAN_FILTER |
+		DEV_RX_OFFLOAD_VLAN_EXTEND |
 		DEV_RX_OFFLOAD_IPV4_CKSUM |
 		DEV_RX_OFFLOAD_UDP_CKSUM  |
 		DEV_RX_OFFLOAD_TCP_CKSUM  |
@@ -1003,6 +1017,8 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		DEV_RX_OFFLOAD_KEEP_CRC;
 
 	dev_info->tx_offload_capa =
+		DEV_TX_OFFLOAD_VLAN_INSERT |
+		DEV_TX_OFFLOAD_QINQ_INSERT |
 		DEV_TX_OFFLOAD_IPV4_CKSUM  |
 		DEV_TX_OFFLOAD_UDP_CKSUM   |
 		DEV_TX_OFFLOAD_TCP_CKSUM;
@@ -1255,14 +1271,159 @@ axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
+static int
+axgbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	unsigned long vid_bit, vid_idx;
+
+	vid_bit = VLAN_TABLE_BIT(vid);
+	vid_idx = VLAN_TABLE_IDX(vid);
+
+	if (on) {
+		PMD_DRV_LOG(DEBUG, "Set VLAN vid=%d for device = %s\n",
+			    vid, pdata->eth_dev->device->name);
+		pdata->active_vlans[vid_idx] |= vid_bit;
+	} else {
+		PMD_DRV_LOG(DEBUG, "Reset VLAN vid=%d for device = %s\n",
+			    vid, pdata->eth_dev->device->name);
+		pdata->active_vlans[vid_idx] &= ~vid_bit;
+	}
+	pdata->hw_if.update_vlan_hash_table(pdata);
+	return 0;
+}
+
+static int
+axgbe_vlan_tpid_set(struct rte_eth_dev *dev,
+		    enum rte_vlan_type vlan_type,
+		    uint16_t tpid)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	uint32_t reg = 0;
+	uint32_t qinq = 0;
+
+	qinq = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
+	PMD_DRV_LOG(DEBUG, "EDVLP: qinq = 0x%x\n", qinq);
+
+	switch (vlan_type) {
+	case ETH_VLAN_TYPE_INNER:
+		PMD_DRV_LOG(DEBUG, "ETH_VLAN_TYPE_INNER\n");
+		if (qinq) {
+			if (tpid != 0x8100 && tpid != 0x88a8)
+				PMD_DRV_LOG(ERR,
+					    "tag supported 0x8100/0x88A8\n");
+			PMD_DRV_LOG(DEBUG, "qinq with inner tag\n");
+
+			/*Enable Inner VLAN Tag */
+			AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERIVLT, 1);
+			reg = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, ERIVLT);
+			PMD_DRV_LOG(DEBUG, "bit ERIVLT = 0x%x\n", reg);
+
+		} else {
+			PMD_DRV_LOG(ERR,
+				    "Inner type not supported in single tag\n");
+		}
+		break;
+	case ETH_VLAN_TYPE_OUTER:
+		PMD_DRV_LOG(DEBUG, "ETH_VLAN_TYPE_OUTER\n");
+		if (qinq) {
+			PMD_DRV_LOG(DEBUG, "double tagging is enabled\n");
+			/*Enable outer VLAN tag*/
+			AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERIVLT, 0);
+			reg = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, ERIVLT);
+			PMD_DRV_LOG(DEBUG, "bit ERIVLT = 0x%x\n", reg);
+
+			AXGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 1);
+			reg = AXGMAC_IOREAD_BITS(pdata, MAC_VLANIR, CSVL);
+			PMD_DRV_LOG(DEBUG, "bit CSVL = 0x%x\n", reg);
+		} else {
+			if (tpid != 0x8100 && tpid != 0x88a8)
+				PMD_DRV_LOG(ERR,
+					    "tag supported 0x8100/0x88A8\n");
+		}
+		break;
+	case ETH_VLAN_TYPE_MAX:
+		PMD_DRV_LOG(ERR, "ETH_VLAN_TYPE_MAX\n");
+		break;
+	case ETH_VLAN_TYPE_UNKNOWN:
+		PMD_DRV_LOG(ERR, "ETH_VLAN_TYPE_UNKNOWN\n");
+		break;
+	}
+	return 0;
+}
+
+static void axgbe_vlan_extend_enable(struct axgbe_port *pdata)
+{
+	int qinq = 0;
+
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EDVLP, 1);
+	qinq = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
+	PMD_DRV_LOG(DEBUG, "vlan double tag enabled EDVLP:qinq=0x%x\n", qinq);
+}
+
+static void axgbe_vlan_extend_disable(struct axgbe_port *pdata)
+{
+	int qinq = 0;
+
+	AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EDVLP, 0);
+	qinq = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
+	PMD_DRV_LOG(DEBUG, "vlan double tag disable EDVLP:qinq=0x%x\n", qinq);
+}
+
+static int
+axgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+	struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+	struct axgbe_port *pdata = dev->data->dev_private;
+
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
+			PMD_DRV_LOG(DEBUG, "Strip ON for device = %s\n",
+				    pdata->eth_dev->device->name);
+			pdata->hw_if.enable_rx_vlan_stripping(pdata);
+		} else {
+			PMD_DRV_LOG(DEBUG, "Strip OFF for device = %s\n",
+				    pdata->eth_dev->device->name);
+			pdata->hw_if.disable_rx_vlan_stripping(pdata);
+		}
+	}
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
+			PMD_DRV_LOG(DEBUG, "Filter ON for device = %s\n",
+				    pdata->eth_dev->device->name);
+			pdata->hw_if.enable_rx_vlan_filtering(pdata);
+		} else {
+			PMD_DRV_LOG(DEBUG, "Filter OFF for device = %s\n",
+				    pdata->eth_dev->device->name);
+			pdata->hw_if.disable_rx_vlan_filtering(pdata);
+		}
+	}
+	if (mask & ETH_VLAN_EXTEND_MASK) {
+		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND) {
+			PMD_DRV_LOG(DEBUG, "enabling vlan extended mode\n");
+			axgbe_vlan_extend_enable(pdata);
+			/* Set global registers with default ethertype*/
+			axgbe_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
+					    RTE_ETHER_TYPE_VLAN);
+			axgbe_vlan_tpid_set(dev, ETH_VLAN_TYPE_INNER,
+					    RTE_ETHER_TYPE_VLAN);
+		} else {
+			PMD_DRV_LOG(DEBUG, "disabling vlan extended mode\n");
+			axgbe_vlan_extend_disable(pdata);
+		}
+	}
+	return 0;
+}
+
 static void axgbe_get_all_hw_features(struct axgbe_port *pdata)
 {
-	unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
+	unsigned int mac_hfr0, mac_hfr1, mac_hfr2, mac_hfr3;
 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
 
 	mac_hfr0 = AXGMAC_IOREAD(pdata, MAC_HWF0R);
 	mac_hfr1 = AXGMAC_IOREAD(pdata, MAC_HWF1R);
 	mac_hfr2 = AXGMAC_IOREAD(pdata, MAC_HWF2R);
+	mac_hfr3 = AXGMAC_IOREAD(pdata, MAC_HWF3R);
 
 	memset(hw_feat, 0, sizeof(*hw_feat));
 
@@ -1313,6 +1474,12 @@ static void axgbe_get_all_hw_features(struct axgbe_port *pdata)
 	hw_feat->aux_snap_num = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R,
 						AUXSNAPNUM);
 
+	/* Hardware feature register 3 */
+	hw_feat->tx_q_vlan_tag_ins  = AXGMAC_GET_BITS(mac_hfr3,
+						      MAC_HWF3R, CBTISEL);
+	hw_feat->no_of_vlan_extn    = AXGMAC_GET_BITS(mac_hfr3,
+						      MAC_HWF3R, NRVF);
+
 	/* Translate the Hash Table size into actual number */
 	switch (hw_feat->hash_table_size) {
 	case 0:
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index f10ec4a40..5840a313c 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -291,6 +291,13 @@ struct axgbe_hw_if {
 	int (*config_tx_flow_control)(struct axgbe_port *);
 	int (*config_rx_flow_control)(struct axgbe_port *);
 
+	/* vlan */
+	int (*enable_rx_vlan_stripping)(struct axgbe_port *);
+	int (*disable_rx_vlan_stripping)(struct axgbe_port *);
+	int (*enable_rx_vlan_filtering)(struct axgbe_port *);
+	int (*disable_rx_vlan_filtering)(struct axgbe_port *);
+	int (*update_vlan_hash_table)(struct axgbe_port *);
+
 	int (*exit)(struct axgbe_port *);
 };
 
@@ -425,6 +432,12 @@ struct axgbe_hw_features {
 	unsigned int tx_ch_cnt;		/* Number of DMA Transmit Channels */
 	unsigned int pps_out_num;	/* Number of PPS outputs */
 	unsigned int aux_snap_num;	/* Number of Aux snapshot inputs */
+
+	/* HW Feature Register3 */
+	unsigned int tx_q_vlan_tag_ins; /* Queue/Channel based VLAN tag */
+					/* insertion on Tx Enable */
+	unsigned int no_of_vlan_extn;   /* Number of Extended VLAN Tag */
+					/* Filters Enabled */
 };
 
 struct axgbe_version_data {
@@ -644,6 +657,9 @@ struct axgbe_port {
 	unsigned int hash_table_count;
 	unsigned int uc_hash_mac_addr;
 	unsigned int uc_hash_table[AXGBE_MAC_HASH_TABLE_SIZE];
+
+	/* Filtering support */
+	unsigned long active_vlans[VLAN_TABLE_SIZE];
 };
 
 void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if);
diff --git a/drivers/net/axgbe/axgbe_rxtx.c b/drivers/net/axgbe/axgbe_rxtx.c
index 30c467db7..798156822 100644
--- a/drivers/net/axgbe/axgbe_rxtx.c
+++ b/drivers/net/axgbe/axgbe_rxtx.c
@@ -739,6 +739,12 @@ static int axgbe_xmit_hw(struct axgbe_tx_queue *txq,
 	AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN, 1);
 	rte_wmb();
 
+	if (mbuf->ol_flags & (PKT_TX_VLAN_PKT | PKT_TX_QINQ_PKT))
+		AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR, 0x2);
+	else
+		AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR, 0x0);
+	rte_wmb();
+
 	/* Save mbuf */
 	txq->sw_ring[idx] = mbuf;
 	/* Update current index*/
-- 
2.17.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-03-31  8:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-31  8:08 [dpdk-dev] [PATCH v1] net/axgbe: vlan support enabling in axgbe ssardar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).