From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from dpdk.org (dpdk.org [92.243.14.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 92F36A04DB;
	Tue,  1 Dec 2020 15:18:11 +0100 (CET)
Received: from [92.243.14.124] (localhost [127.0.0.1])
	by dpdk.org (Postfix) with ESMTP id E5AD0C996;
	Tue,  1 Dec 2020 15:18:09 +0100 (CET)
Received: from NAM12-DM6-obe.outbound.protection.outlook.com
 (mail-dm6nam12on2050.outbound.protection.outlook.com [40.107.243.50])
 by dpdk.org (Postfix) with ESMTP id 48E86C988
 for <dev@dpdk.org>; Tue,  1 Dec 2020 15:18:06 +0100 (CET)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=S4t6B7suWgWnYogloc4CFNhGOtyLeU+UaAAQRey3kuZaPQD9zP/9X4Ghya0VLvSu8iNEzF7Cx3oTrweDgZKuwafHHaH4+1vRGxhkVq0B1roVG2JF4xqlle0tBtC0aMi0eZ3vAVr3uRwN122vXpwBaUX9tdcNDrCUWs0lObUvX/fBMu23wnvsu7ZBOhSAGeuQ7nB7iTY/b85uR4sa1B8a7MpI/d9BVe3VHon/Rsg4tUhP8Ib4njH64yit3f/VOggVmavB4KyoypMNEdrhdUOUmSLsLuaLnvIpbWj7NyZl220JcqUQy2XbwsrbipKrAXSKHCijXeNyGTXpOPLMUlM+bw==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=TEAQO62vP/4Iww9l7jif3/73Ngkx3TeMJy/akpIc/yU=;
 b=bvR9gf/KTqeo5cTJN4ss1FpmeSZdCdVLfJm9WPN+xw3giX2R2MGo+iAs/KmxmOxocWDwGu/dSeFa6l2G57skUWJFngev08r4TMr0HWRX9rGXulRDkfGj7qyMGgkBpjuTeii65Hld1/wKtwxybSI7cqFAPjDwr6jVoh7lEN7w4ZqROW/zOg3VtQElEZ3okX8vidDnksFzZ4FnVKMu4I6ipwDqrkAfyoTjEwkd8D5e9H1/OXCOsE+7S3bD/a9irGBSr3SGm6txiyKsoidSAtBRWH7C9AbRnOhnS1mUDT/fUdswcF/kuMvQdEMdsm9v7/4gL6VME+6A09NMS+/230Dg0A==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
 smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass
 header.d=amd.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=amdcloud.onmicrosoft.com; s=selector2-amdcloud-onmicrosoft-com;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=TEAQO62vP/4Iww9l7jif3/73Ngkx3TeMJy/akpIc/yU=;
 b=1VjrQr0SF3AOjoAO+2QAneMoBJvhq3NPfjtxkXVhLEVF3ro4wRJFEcTPCjrYWA2xuAz78AEH5fa01ajDfqaVIy0ZDyu9GELYmDPkP7z7llUJJrQZzvI+M3U24MSJSFZAG9vKmPhfdm1wISIzMtBUaI1e3fencG2fAzsFJGkA4W8=
Received: from BYAPR12MB2821.namprd12.prod.outlook.com (2603:10b6:a03:9b::30)
 by BY5PR12MB3713.namprd12.prod.outlook.com (2603:10b6:a03:1a6::22)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3632.17; Tue, 1 Dec
 2020 14:18:02 +0000
Received: from BYAPR12MB2821.namprd12.prod.outlook.com
 ([fe80::c9e:efb6:8cd1:5a6d]) by BYAPR12MB2821.namprd12.prod.outlook.com
 ([fe80::c9e:efb6:8cd1:5a6d%4]) with mapi id 15.20.3611.031; Tue, 1 Dec 2020
 14:18:02 +0000
From: "Somalapuram, Amaranath" <Amaranath.Somalapuram@amd.com>
To: "Nandibasappa, Girish" <Girish.Nandibasappa@amd.com>, "dev@dpdk.org"
 <dev@dpdk.org>, Ferruh Yigit <ferruh.yigit@intel.com>
Thread-Topic: [PATCH v2] net/axgbe: enabling VLAN support in axgbe
Thread-Index: AQHWx9kujJ6Fm2EkcEmCyytqIie6sqniSaUg
Date: Tue, 1 Dec 2020 14:18:02 +0000
Message-ID: <BYAPR12MB2821D14DCFE4045542A3DD3AF8F40@BYAPR12MB2821.namprd12.prod.outlook.com>
References: <20201201115719.50637-1-gnandiba@amd.com>
In-Reply-To: <20201201115719.50637-1-gnandiba@amd.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
msip_labels: MSIP_Label_76546daa-41b6-470c-bb85-f6f40f044d7f_ActionId=ee1f48d1-6ace-488b-aefa-00a7a0e65d3a;
 MSIP_Label_76546daa-41b6-470c-bb85-f6f40f044d7f_ContentBits=0;
 MSIP_Label_76546daa-41b6-470c-bb85-f6f40f044d7f_Enabled=true;
 MSIP_Label_76546daa-41b6-470c-bb85-f6f40f044d7f_Method=Standard;
 MSIP_Label_76546daa-41b6-470c-bb85-f6f40f044d7f_Name=Internal
 Use Only - Unrestricted;
 MSIP_Label_76546daa-41b6-470c-bb85-f6f40f044d7f_SetDate=2020-12-01T14:17:19Z;
 MSIP_Label_76546daa-41b6-470c-bb85-f6f40f044d7f_SiteId=3dd8961f-e488-4e60-8e11-a82d994e183d;
authentication-results: amd.com; dkim=none (message not signed)
 header.d=none;amd.com; dmarc=none action=none header.from=amd.com;
x-originating-ip: [49.37.163.149]
x-ms-publictraffictype: Email
x-ms-office365-filtering-ht: Tenant
x-ms-office365-filtering-correlation-id: d326bf12-7d58-4566-05e5-08d89603ea03
x-ms-traffictypediagnostic: BY5PR12MB3713:
x-ms-exchange-transport-forked: True
x-microsoft-antispam-prvs: <BY5PR12MB3713B1AB91BC432546872F85F8F40@BY5PR12MB3713.namprd12.prod.outlook.com>
x-ms-oob-tlc-oobclassifiers: OLM:17;
x-ms-exchange-senderadcheck: 1
x-microsoft-antispam: BCL:0;
x-microsoft-antispam-message-info: 23RpSmOdFWhikaNcaWdDa+ly9q9tjRL3vJCOp5vs5NdCLS+pxRPOEZfAhStUDN3ZHQYH+QDva6upCtP5yhr46+XatIBR95mvBix07hPJuulc+NkVSorBEOj0cgs5t+Xl+uQODsUNA67L6KuFsqBjc9k4n9rlLNkp9KQC+jA7EgWLNQOtIVwqsLkpNRxzetCcLDr8R/y7XRkc5o3e+tixm/UOTAQiJuvyShPvWYyOrm5jMJj583e/6nTJXA7AZIyDYZbob+dsAipVL2F6U9zppqDAi9zkAARP7U/pDGAXH09nInG3lE/E3+MKO/KQHwt4umJjRjHvxhT89javmY0hZA==
x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:BYAPR12MB2821.namprd12.prod.outlook.com; PTR:; CAT:NONE;
 SFS:(4636009)(39860400002)(366004)(376002)(346002)(396003)(136003)(8936002)(33656002)(30864003)(55016002)(76116006)(66946007)(9686003)(5660300002)(64756008)(66446008)(2906002)(52536014)(66476007)(71200400001)(66556008)(83380400001)(186003)(26005)(6506007)(53546011)(8676002)(86362001)(110136005)(7696005)(478600001)(316002)(579004);
 DIR:OUT; SFP:1101; 
x-ms-exchange-antispam-messagedata: =?us-ascii?Q?C23hzIFthqBsifeZ/EDv6fDzqScB9Ke9WWvh9ICE2eaiIhdNOgzwMS/lPV8b?=
 =?us-ascii?Q?nheGUDKbhkUvpMiRuuTULl9HQIZmfX0uVbXv5vx97+YwPJK0MqCYku7dHu//?=
 =?us-ascii?Q?SbNB/H8/Y0vYnsce8rDYHnuAfcGRfRhK+w2ieMzXA5hP4+zw7VzXyUmenHBk?=
 =?us-ascii?Q?8pIbj9LdQlQDLMdR0HVlbD1ESXOx7MSRwUi59XgaQIuW5bRcNNOGPYDPprEK?=
 =?us-ascii?Q?lzY9QqNEgTOYfzNCySdibu/wbpf1aqswmNnV2JacSw1VfBYnWgcPxsdBJhDi?=
 =?us-ascii?Q?JFR8+NG8LJBeubhKw1YkNgPo0ptjMFNviLLxIxIzwR4GHqdbcNh5eWP8OMd4?=
 =?us-ascii?Q?6yld4IRBuaeMvBJxa62Sw1W+y6RfvVuldoiplsx/SrlS23wgf36sWuCosklF?=
 =?us-ascii?Q?n4Q9eSMP5++biZyZblnASGuAHVFbCMCHYK2blfHUjLNB4VaYBAvCIzb27HZ2?=
 =?us-ascii?Q?+ciE/KVAv03Ia7wohD+zbvc/457+GAxbAHkRm46R1KqGEn/9nTstYTHz6PKg?=
 =?us-ascii?Q?d7HUmqETovK3GskAU2FPjowePhmSE20HEABoNYlWP1LojZAzFOrabP/9cX73?=
 =?us-ascii?Q?cXqvLYuJ+VCiTlNnNyGDVGNNFBqE9eIowRCwEAeV96jsRMcaHKyZCb21LWn4?=
 =?us-ascii?Q?PlDoxBrhTwG6v5WZ6wcGBfwK1vBvErw41gCKGzy0ZetPJyL+qj/1xqbzJxcS?=
 =?us-ascii?Q?7k1a7OjutEibWl5MtG+qEi+p2FUIiqN0yz+15b/jJWrk5OUtuhrLFkz5wNAm?=
 =?us-ascii?Q?hLWJ2m3O2L8yqFtoBh+NdqHWcsGFbPOfo6vDtD+RwKXcr/BNZrvp+xchQcoy?=
 =?us-ascii?Q?WtAiy5B2c/wvdFnfZeJKO9u+qHQe4HQqczDM9HWPjacPFE8a5iN0f0Xj8ufY?=
 =?us-ascii?Q?qnneAUEGfo/T0RE8AsdjH8nZlQWSkTMRyXz9kj90m17N2YOKNkmqO3n/L29A?=
 =?us-ascii?Q?hekYKSPve2ZmOlWCoGA1gC6toG7LxWCko5UfoyoFJHw=3D?=
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-OriginatorOrg: amd.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: BYAPR12MB2821.namprd12.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: d326bf12-7d58-4566-05e5-08d89603ea03
X-MS-Exchange-CrossTenant-originalarrivaltime: 01 Dec 2020 14:18:02.7390 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: 142XNEmBm3u7Mlcdgl6qrNBdsVDqY/zgA+CipzBPBYX6cLruHhlj+U+cOmNTBYxH9K6P0u1lItjZq0zgIohoNg==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR12MB3713
Subject: Re: [dpdk-dev] [PATCH v2] net/axgbe: enabling VLAN support in axgbe
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

[AMD Official Use Only - Internal Distribution Only]

-----Original Message-----
From: Nandibasappa, Girish <Girish.Nandibasappa@amd.com>
Sent: Tuesday, December 1, 2020 5:27 PM
To: dev@dpdk.org
Cc: Somalapuram, Amaranath <Amaranath.Somalapuram@amd.com>
Subject: [PATCH v2] net/axgbe: enabling VLAN support in axgbe

From: gnandiba <girish.nandibasappa@amd.com>

Added VLAN support for AMD XGBE driver

adding below APIs for axgbe
- axgbe_enable_rx_vlan_stripping: to enable vlan header stipping
- axgbe_disable_rx_vlan_stripping: to disable vlan header stipping
- axgbe_enable_rx_vlan_filtering: to enable vlan filter mode
- axgbe_disable_rx_vlan_filtering: to disable vlan filter mode
- axgbe_update_vlan_hash_table: crc calculation and hash table update based=
 on vlan values post filter enable
- axgbe_vlan_filter_set: setting of active vlan out of max 4K values before=
 doing hash update of same
- axgbe_vlan_tpid_set: setting of default tpid values
- axgbe_vlan_offload_set: a top layer function to call stip/filter etc base=
d on mask values

Signed-off-by: gnandiba <girish.nandibasappa@amd.com>
---
 doc/guides/nics/features/axgbe.ini |   1 +
 drivers/net/axgbe/axgbe_common.h   |  30 +++++
 drivers/net/axgbe/axgbe_dev.c      | 171 +++++++++++++++++++++++++++--
 drivers/net/axgbe/axgbe_ethdev.c   | 170 +++++++++++++++++++++++++++-
 drivers/net/axgbe/axgbe_ethdev.h   |  16 +++
 drivers/net/axgbe/axgbe_rxtx.c     |  70 +++++++++++-
 6 files changed, 442 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/features/axgbe.ini b/doc/guides/nics/features/=
axgbe.ini
index 34df0d1ee..4da9e6263 100644
--- a/doc/guides/nics/features/axgbe.ini
+++ b/doc/guides/nics/features/axgbe.ini
@@ -13,6 +13,7 @@ Allmulticast mode    =3D Y
 RSS hash             =3D Y
 RSS key update       =3D Y
 RSS reta update      =3D Y
+VLAN filter          =3D Y
 CRC offload          =3D Y
 L3 checksum offload  =3D Y
 L4 checksum offload  =3D Y
diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_com=
mon.h
index fb97f0b5b..91404ca01 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -259,6 +259,7 @@
 #define MAC_HWF0R0x011c
 #define MAC_HWF1R0x0120
 #define MAC_HWF2R0x0124
+#define MAC_HWF3R0x0128
 #define MAC_MDIOSCAR0x0200
 #define MAC_MDIOSCCDR0x0204
 #define MAC_MDIOISR0x0214
@@ -284,6 +285,19 @@
 #define MAC_TXSNR0x0d30
 #define MAC_TXSSR0x0d34

+/*VLAN control bit mask*/
+#define AXGBE_VLNCTRL_MASK0x0000FFFF
+#define VLAN_PRIO_MASK0xe000 /* Priority Code Point */
+#define VLAN_PRIO_SHIFT13
+#define VLAN_CFI_MASK0x1000 /* Canonical Format Indicator */
+#define VLAN_TAG_PRESENTVLAN_CFI_MASK
+#define VLAN_VID_MASK0x0fff /* VLAN Identifier */
+#define VLAN_N_VID4096
+#define VLAN_TABLE_SIZE64
+#define VLAN_TABLE_BIT(vlan_id)(1UL << ((vlan_id) & 0x3F))
+#define VLAN_TABLE_IDX(vlan_id)((vlan_id) >> 6)
+#define RX_CVLAN_TAG_PRESENT                   9
+
 #define MAC_QTFCR_INC4
 #define MAC_MACA_INC4
 #define MAC_HTR_INC4
@@ -361,6 +375,10 @@
 #define MAC_HWF2R_TXCHCNT_WIDTH4
 #define MAC_HWF2R_TXQCNT_INDEX6
 #define MAC_HWF2R_TXQCNT_WIDTH4
+#define MAC_HWF3R_CBTISEL_INDEX4
+#define MAC_HWF3R_CBTISEL_WIDTH1
+#define MAC_HWF3R_NRVF_INDEX0
+#define MAC_HWF3R_NRVF_WIDTH3
 #define MAC_IER_TSIE_INDEX12
 #define MAC_IER_TSIE_WIDTH1
 #define MAC_ISR_MMCRXIS_INDEX9
@@ -519,6 +537,8 @@
 #define MAC_VLANIR_VLTI_WIDTH1
 #define MAC_VLANIR_CSVL_INDEX19
 #define MAC_VLANIR_CSVL_WIDTH1
+#define MAC_VLANIR_VLC_INDEX16
+#define MAC_VLANIR_VLC_WIDTH2
 #define MAC_VLANTR_DOVLTC_INDEX20
 #define MAC_VLANTR_DOVLTC_WIDTH1
 #define MAC_VLANTR_ERSVLM_INDEX19
@@ -529,12 +549,18 @@
 #define MAC_VLANTR_ETV_WIDTH1
 #define MAC_VLANTR_EVLS_INDEX21
 #define MAC_VLANTR_EVLS_WIDTH2
+#define MAC_VLANTR_EIVLS_INDEX21
+#define MAC_VLANTR_EIVLS_WIDTH2
 #define MAC_VLANTR_EVLRXS_INDEX24
 #define MAC_VLANTR_EVLRXS_WIDTH1
+#define MAC_VLANTR_EIVLRXS_INDEX31
+#define MAC_VLANTR_EIVLRXS_WIDTH1
 #define MAC_VLANTR_VL_INDEX0
 #define MAC_VLANTR_VL_WIDTH16
 #define MAC_VLANTR_VTHM_INDEX25
 #define MAC_VLANTR_VTHM_WIDTH1
+#define MAC_VLANTR_EDVLP_INDEX26
+#define MAC_VLANTR_EDVLP_WIDTH1
 #define MAC_VLANTR_VTIM_INDEX17
 #define MAC_VLANTR_VTIM_WIDTH1
 #define MAC_VR_DEVID_INDEX8
@@ -543,6 +569,10 @@
 #define MAC_VR_SNPSVER_WIDTH8
 #define MAC_VR_USERVER_INDEX16
 #define MAC_VR_USERVER_WIDTH8
+#define MAC_VLANIR_VLT_INDEX0
+#define MAC_VLANIR_VLT_WIDTH16
+#define MAC_VLANTR_ERIVLT_INDEX27
+#define MAC_VLANTR_ERIVLT_WIDTH1


 /* MMC register offsets */
diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c =
index af62eae3b..786288a7b 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 =3D (x >> 16) | (x << 16);
+x =3D (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+x =3D (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+x =3D (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+x =3D (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+return x;
+}
+
+/*MSB set bit from 32 to 1*/
+static int get_lastbit_set(int x)
+{
+int r =3D 32;
+
+if (!x)
+return 0;
+if (!(x & 0xffff0000)) {
+x <<=3D 16;
+r -=3D 16;
+}
+if (!(x & 0xff000000)) {
+x <<=3D 8;
+r -=3D 8;
+}
+if (!(x & 0xf0000000)) {
+x <<=3D 4;
+r -=3D 4;
+}
+if (!(x & 0xc0000000)) {
+x <<=3D 2;
+r -=3D 2;
+}
+if (!(x & 0x80000000)) {
+x <<=3D 1;
+r -=3D 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 =3D 0xedb88320;  /* CRCPOLY_LE */
+u32 crc =3D ~0;
+u32 temp =3D 0;
+unsigned char *data =3D (unsigned char *)&vid_le;
+unsigned char data_byte =3D 0;
+int i, bits;
+
+bits =3D get_lastbit_set(VLAN_VID_MASK);
+for (i =3D 0; i < bits; i++) {
+if ((i % 8) =3D=3D 0)
+data_byte =3D data[i / 8];
+
+temp =3D ((crc & 1) ^ data_byte) & 1;
+crc >>=3D 1;
+data_byte >>=3D 1;
+
+if (temp)
+crc ^=3D poly;
+}
+return crc;
+}
+
+static int axgbe_update_vlan_hash_table(struct axgbe_port *pdata) {
+u32 crc =3D 0;
+u16 vid;
+__le16 vid_le =3D 0;
+u16 vlan_hash_table =3D 0;
+unsigned int reg =3D 0;
+unsigned long vid_idx, vid_valid;
+
+/* Generate the VLAN Hash Table value */
+for (vid =3D 0; vid < VLAN_N_VID; vid++) {
+vid_idx =3D VLAN_TABLE_IDX(vid);
+vid_valid =3D pdata->active_vlans[vid_idx];
+vid_valid =3D (unsigned long)vid_valid >> (vid - (64 * vid_idx));
+if (vid_valid & 1)
+PMD_DRV_LOG(DEBUG,
+    "vid:%d pdata->active_vlans[%ld]=3D0x%lx\n",
+    vid, vid_idx, pdata->active_vlans[vid_idx]);
+else
+continue;
+
+vid_le =3D rte_cpu_to_le_16(vid);
+crc =3D bitrev32(~axgbe_vid_crc32_le(vid_le)) >> 28;
+vlan_hash_table |=3D (1 << crc);
+PMD_DRV_LOG(DEBUG, "crc =3D %d vlan_hash_table =3D 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 =3D AXGMAC_IOREAD(pdata, MAC_VLANHTR);
+PMD_DRV_LOG(DEBUG, "vlan_hash_table reg val =3D 0x%x\n", reg);
+return 0;
+}
+
 static int __axgbe_exit(struct axgbe_port *pdata)  {
 unsigned int count =3D 2000;
@@ -1009,16 +1163,6 @@ static void axgbe_enable_mtl_interrupts(struct axgbe=
_port *pdata)
 }
 }

-static uint32_t bitrev32(uint32_t x)
-{
-x =3D (x >> 16) | (x << 16);
-x =3D (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
-x =3D (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
-x =3D (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
-x =3D (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
-return x;
-}
-
 static uint32_t crc32_le(uint32_t crc, uint8_t *p, uint32_t len)  {
 int i;
@@ -1218,4 +1362,11 @@ void axgbe_init_function_ptrs_dev(struct axgbe_hw_if=
 *hw_if)
 /* For FLOW ctrl */
 hw_if->config_tx_flow_control =3D axgbe_config_tx_flow_control;
 hw_if->config_rx_flow_control =3D axgbe_config_rx_flow_control;
+
+/*vlan*/
+hw_if->enable_rx_vlan_stripping =3D axgbe_enable_rx_vlan_stripping;
+hw_if->disable_rx_vlan_stripping =3D axgbe_disable_rx_vlan_stripping;
+hw_if->enable_rx_vlan_filtering =3D axgbe_enable_rx_vlan_filtering;
+hw_if->disable_rx_vlan_filtering =3D axgbe_disable_rx_vlan_filtering;
+hw_if->update_vlan_hash_table =3D axgbe_update_vlan_hash_table;
 }
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_eth=
dev.c
index cfe6aba73..760426029 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -109,6 +109,11 @@ axgbe_set_tstamp_time(struct axgbe_port *pdata, unsign=
ed int sec,  static void  axgbe_update_tstamp_addend(struct axgbe_port *pda=
ta,
 unsigned int addend);
+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];
@@ -250,6 +255,9 @@ static const struct eth_dev_ops axgbe_eth_dev_ops =3D {
 .txq_info_get                 =3D axgbe_txq_info_get,
 .dev_supported_ptypes_get     =3D axgbe_dev_supported_ptypes_get,
 .mtu_set=3D axgb_mtu_set,
+.vlan_filter_set      =3D axgbe_vlan_filter_set,
+.vlan_tpid_set        =3D axgbe_vlan_tpid_set,
+.vlan_offload_set     =3D axgbe_vlan_offload_set,
 .timesync_enable              =3D axgbe_timesync_enable,
 .timesync_disable             =3D axgbe_timesync_disable,
 .timesync_read_rx_timestamp   =3D axgbe_timesync_read_rx_timestamp,
@@ -1163,6 +1171,9 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rt=
e_eth_dev_info *dev_info)
 dev_info->speed_capa =3D  ETH_LINK_SPEED_10G;

 dev_info->rx_offload_capa =3D
+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  |
@@ -1171,6 +1182,8 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rt=
e_eth_dev_info *dev_info)
 DEV_RX_OFFLOAD_KEEP_CRC;

 dev_info->tx_offload_capa =3D
+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;
@@ -1756,14 +1769,163 @@ axgbe_timesync_read_tx_timestamp(struct rte_eth_de=
v *dev,
 return 0;
 }

+static int
+axgbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on) {
+struct axgbe_port *pdata =3D dev->data->dev_private;
+unsigned long vid_bit, vid_idx;
+
+vid_bit =3D VLAN_TABLE_BIT(vid);
+vid_idx =3D VLAN_TABLE_IDX(vid);
+
+if (on) {
+PMD_DRV_LOG(DEBUG, "Set VLAN vid=3D%d for device =3D %s\n",
+    vid, pdata->eth_dev->device->name);
+pdata->active_vlans[vid_idx] |=3D vid_bit;
+} else {
+PMD_DRV_LOG(DEBUG, "Reset VLAN vid=3D%d for device =3D %s\n",
+    vid, pdata->eth_dev->device->name);
+pdata->active_vlans[vid_idx] &=3D ~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 =3D dev->data->dev_private;
+uint32_t reg =3D 0;
+uint32_t qinq =3D 0;
+
+qinq =3D AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
+PMD_DRV_LOG(DEBUG, "EDVLP: qinq =3D 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 !=3D 0x8100 && tpid !=3D 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 =3D AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, ERIVLT);
+PMD_DRV_LOG(DEBUG, "bit ERIVLT =3D 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 =3D AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, ERIVLT);
+PMD_DRV_LOG(DEBUG, "bit ERIVLT =3D 0x%x\n", reg);
+
+AXGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 1);
+reg =3D AXGMAC_IOREAD_BITS(pdata, MAC_VLANIR, CSVL);
+PMD_DRV_LOG(DEBUG, "bit CSVL =3D 0x%x\n", reg);
+} else {
+if (tpid !=3D 0x8100 && tpid !=3D 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 =3D 0;
+
+AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EDVLP, 1);
+qinq =3D AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
+PMD_DRV_LOG(DEBUG, "vlan double tag enabled EDVLP:qinq=3D0x%x\n", qinq);
+}
+
+static void axgbe_vlan_extend_disable(struct axgbe_port *pdata) {
+int qinq =3D 0;
+
+AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EDVLP, 0);
+qinq =3D AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
+PMD_DRV_LOG(DEBUG, "vlan double tag disable EDVLP:qinq=3D0x%x\n", qinq);
+}
+
+static int
+axgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask) {
+struct rte_eth_rxmode *rxmode =3D &dev->data->dev_conf.rxmode;
+struct axgbe_port *pdata =3D dev->data->dev_private;
+
+/* Indicate that VLAN Tx CTAGs come from context descriptors */
+AXGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 0);
+AXGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, VLTI, 1);
+
+if (mask & ETH_VLAN_STRIP_MASK) {
+if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
+PMD_DRV_LOG(DEBUG, "Strip ON for device =3D %s\n",
+    pdata->eth_dev->device->name);
+pdata->hw_if.enable_rx_vlan_stripping(pdata);
+} else {
+PMD_DRV_LOG(DEBUG, "Strip OFF for device =3D %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 =3D %s\n",
+    pdata->eth_dev->device->name);
+pdata->hw_if.enable_rx_vlan_filtering(pdata);
+} else {
+PMD_DRV_LOG(DEBUG, "Filter OFF for device =3D %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 =3D &pdata->hw_feat;

 mac_hfr0 =3D AXGMAC_IOREAD(pdata, MAC_HWF0R);
 mac_hfr1 =3D AXGMAC_IOREAD(pdata, MAC_HWF1R);
 mac_hfr2 =3D AXGMAC_IOREAD(pdata, MAC_HWF2R);
+mac_hfr3 =3D AXGMAC_IOREAD(pdata, MAC_HWF3R);

 memset(hw_feat, 0, sizeof(*hw_feat));

@@ -1814,6 +1976,12 @@ static void axgbe_get_all_hw_features(struct axgbe_p=
ort *pdata)
 hw_feat->aux_snap_num =3D AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R,
 AUXSNAPNUM);

+/* Hardware feature register 3 */
+hw_feat->tx_q_vlan_tag_ins  =3D AXGMAC_GET_BITS(mac_hfr3,
+      MAC_HWF3R, CBTISEL);
+hw_feat->no_of_vlan_extn    =3D 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_eth=
dev.h
index 35a847646..1481fd9ff 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -299,6 +299,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 *);
 };

@@ -433,6 +440,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 {
@@ -654,6 +667,9 @@ struct axgbe_port {
 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];
+
 /* For IEEE1588 PTP */
 struct rte_timecounter systime_tc;
 struct rte_timecounter tx_tstamp;
diff --git a/drivers/net/axgbe/axgbe_rxtx.c b/drivers/net/axgbe/axgbe_rxtx.=
c index 032e3cebc..71e3cffc5 100644
--- a/drivers/net/axgbe/axgbe_rxtx.c
+++ b/drivers/net/axgbe/axgbe_rxtx.c
@@ -209,9 +209,10 @@ axgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_p=
kts,
 volatile union axgbe_rx_desc *desc;
 uint64_t old_dirty =3D rxq->dirty;
 struct rte_mbuf *mbuf, *tmbuf;
-unsigned int err;
+unsigned int err, etlt;
 uint32_t error_status;
 uint16_t idx, pidx, pkt_len;
+uint64_t offloads;

 idx =3D AXGBE_GET_DESC_IDX(rxq, rxq->cur);
 while (nb_rx < nb_pkts) {
@@ -276,6 +277,26 @@ axgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_p=
kts,
 /* Get the RSS hash */
 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, RSV))
 mbuf->hash.rss =3D rte_le_to_cpu_32(desc->write.desc1);
+etlt =3D AXGMAC_GET_BITS_LE(desc->write.desc3,
+RX_NORMAL_DESC3, ETLT);
+offloads =3D rxq->pdata->eth_dev->data->dev_conf.rxmode.offloads;
+if (!err || !etlt) {
+if (etlt =3D=3D RX_CVLAN_TAG_PRESENT) {
+mbuf->ol_flags |=3D PKT_RX_VLAN;
+mbuf->vlan_tci =3D
+AXGMAC_GET_BITS_LE(desc->write.desc0,
+RX_NORMAL_DESC0, OVT);
+if (offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+mbuf->ol_flags |=3D PKT_RX_VLAN_STRIPPED;
+else
+mbuf->ol_flags &=3D ~PKT_RX_VLAN_STRIPPED;
+} else {
+mbuf->ol_flags &=3D
+~(PKT_RX_VLAN
+| PKT_RX_VLAN_STRIPPED);
+mbuf->vlan_tci =3D 0;
+}
+}
 /* Indicate if a Context Descriptor is next */
 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, CDA))
 mbuf->ol_flags |=3D PKT_RX_IEEE1588_PTP @@ -324,9 +345,10 @@ uint16_t eth_=
axgbe_recv_scattered_pkts(void *rx_queue,
 uint64_t old_dirty =3D rxq->dirty;
 struct rte_mbuf *first_seg =3D NULL;
 struct rte_mbuf *mbuf, *tmbuf;
-unsigned int err;
+unsigned int err, etlt;
 uint32_t error_status;
 uint16_t idx, pidx, data_len =3D 0, pkt_len =3D 0;
+uint64_t offloads;

 idx =3D AXGBE_GET_DESC_IDX(rxq, rxq->cur);
 while (nb_rx < nb_pkts) {
@@ -399,7 +421,25 @@ uint16_t eth_axgbe_recv_scattered_pkts(void *rx_queue,
 /* Get the RSS hash */
 if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, RSV))
 mbuf->hash.rss =3D rte_le_to_cpu_32(desc->write.desc1);
-
+etlt =3D AXGMAC_GET_BITS_LE(desc->write.desc3,
+RX_NORMAL_DESC3, ETLT);
+offloads =3D rxq->pdata->eth_dev->data->dev_conf.rxmode.offloads;
+if (!err || !etlt) {
+if (etlt =3D=3D RX_CVLAN_TAG_PRESENT) {
+mbuf->ol_flags |=3D PKT_RX_VLAN;
+mbuf->vlan_tci =3D
+AXGMAC_GET_BITS_LE(desc->write.desc0,
+RX_NORMAL_DESC0, OVT);
+if (offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+mbuf->ol_flags |=3D PKT_RX_VLAN_STRIPPED;
+else
+mbuf->ol_flags &=3D ~PKT_RX_VLAN_STRIPPED;
+} else {
+mbuf->ol_flags &=3D
+~(PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED);
+mbuf->vlan_tci =3D 0;
+}
+}
 /* Mbuf populate */
 mbuf->data_off =3D RTE_PKTMBUF_HEADROOM;
 mbuf->data_len =3D data_len;
@@ -492,6 +532,7 @@ int axgbe_dev_tx_queue_setup(struct rte_eth_dev *dev, u=
int16_t queue_idx,
 struct axgbe_tx_queue *txq;
 unsigned int tsize;
 const struct rte_memzone *tz;
+uint64_t offloads;

 tx_desc =3D nb_desc;
 pdata =3D dev->data->dev_private;
@@ -511,7 +552,8 @@ int axgbe_dev_tx_queue_setup(struct rte_eth_dev *dev, u=
int16_t queue_idx,
 if (!txq)
 return -ENOMEM;
 txq->pdata =3D pdata;
-
+offloads =3D tx_conf->offloads |
+txq->pdata->eth_dev->data->dev_conf.txmode.offloads;
 txq->nb_desc =3D tx_desc;
 txq->free_thresh =3D tx_conf->tx_free_thresh ?
 tx_conf->tx_free_thresh : AXGBE_TX_FREE_THRESH; @@ -523,7 +565,7 @@ int ax=
gbe_dev_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 if (txq->nb_desc % txq->free_thresh !=3D 0)
 txq->vector_disable =3D 1;

-if (tx_conf->offloads !=3D 0)
+if (offloads !=3D 0)
 txq->vector_disable =3D 1;

 /* Allocate TX ring hardware descriptors */ @@ -745,10 +787,28 @@ static i=
nt axgbe_xmit_hw(struct axgbe_tx_queue *txq,
 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, CIC, 0x1);
 rte_wmb();

+if (mbuf->ol_flags & (PKT_TX_VLAN_PKT | PKT_TX_QINQ_PKT)) {
+/* Mark it as a CONTEXT descriptor */
+AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
+  CTXT, 1);
+/* Set the VLAN tag */
+AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
+  VT, mbuf->vlan_tci);
+/* Indicate this descriptor contains the VLAN tag */
+AXGMAC_SET_BITS_LE(desc->desc3, TX_CONTEXT_DESC3,
+  VLTV, 1);
+AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR,
+TX_NORMAL_DESC2_VLAN_INSERT);
+} else {
+AXGMAC_SET_BITS_LE(desc->desc2, TX_NORMAL_DESC2, VTIR, 0x0);
+}
+rte_wmb();
+
 /* Set OWN bit */
 AXGMAC_SET_BITS_LE(desc->desc3, TX_NORMAL_DESC3, OWN, 1);
 rte_wmb();

+
 /* Save mbuf */
 txq->sw_ring[idx] =3D mbuf;
 /* Update current index*/
--
2.25.1

For series,
Acked-by: Somalapuram Amaranath <asomalap@amd.com>