DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure.
@ 2019-10-25 17:53 Pavel Belous
  2019-10-25 17:53 ` [dpdk-dev] [RFC v2 1/7] security: MACSEC infrastructure data declarations Pavel Belous
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:53 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

This RFC suggest possible API to implement generic MACSEC HW
offload in DPDK infrastructure.

Right now two PMDs implementing MACSEC hw offload via private
API: ixgbe (Intel) and atlantic (Aquantia).

During that private API discussion it was decided to go further
with well defined public API, based most probably on rte_security
infrastructure.

Here is that previous discussion:

http://inbox.dpdk.org/dev/20190416101145.nVecHKp3w14Ptd_hne-DqHhKyzbre88PwNI-OAowXJM@z/

Declaring macsec API via rte_security gives a good data-centric view on parameters
and operations macsec supports. Old, pure functional API (basically ixbe only API)
presented function calls with big argument lists which is hard to extend and analyse.

However, I'd like to note rte_security has to be used via explicitly created
mempools - this hardens abit the usage.
It also may be hard to extend the structures in the ABI compatible way.

One of the problems with MACSEC is that internally implementation and hardware
support could be either very simple, doing only endpoint encryption with a single
TX SC (Secure Connection), or quite complex, capable to do flexible filtering
and SC matching based on mac, vlan, ethertype and other.

Different macsec hardware supports some custom features and from our experience
users would like to configure these as well. Therefore there will probably be
needed a number of PMD specific macsec operators support.

Examples include: custom in-the-clear tag (matched by vlan id or mask),
configurable internal logic to allow both secure and unsecure traffic,
bypass filters on specific ethertypes.
To support such extensions, suggest use rte_security_macsec_op enum with
vendor specific operation codes.

In context of rte_security, MACSEC operations should normally be based on
security session create and update calls.

Session create is used to setup overall session. Thats equivalent of old
`macsec enable` operation.

Session update is used to update security connections and associations.
Here xform->op contains the required operation: rx/tx session/association
add/update/removal.

This RFC contains:
- patch 1-2 is rte_security data structures declaration and documentation
- patches 3-5 MACSEC implementation for atlantic (Aquantia) driver, using
  new rte_security interface.
- patches 6-7 is a draft on how testpmd based invocations of rte_security
  API will look like

To be done/decide:
- add missing documentation and comments to all the structures
- full testpmd macsec API adoption
- ixgbe api adoptation
- decide on how to declare SA (Security Associations) auto rollover and
  some other important features.
- interrupt event callback detalization of possible macsec events.
  Notice that it is not a part of rte_security, but a part of rte_ethdev.
- add ability to retrieve MACSEC statistics per individual SC/SA.

Pavel Belous (7):
  security: MACSEC infrastructure data declarations
  security: Update rte_security documentation
  net/atlantic: Add helper functions for PHY access
  net/atlantic: add MACSEC internal HW data declaration and functions
  net/atlantic: implementation of the MACSEC using rte_security
    interface
  app/testpmd: macsec on/off commands using rte_security interface
  app/testpmd: macsec adding RX/TX SC using rte_security interface

 app/test-pmd/Makefile                              |    1 +
 app/test-pmd/cmdline.c                             |   20 +-
 app/test-pmd/macsec.c                              |  138 ++
 app/test-pmd/macsec.h                              |   14 +
 app/test-pmd/meson.build                           |    3 +-
 doc/guides/prog_guide/rte_security.rst             |    4 -
 drivers/net/atlantic/Makefile                      |    5 +-
 drivers/net/atlantic/atl_ethdev.c                  |  316 +---
 drivers/net/atlantic/atl_sec.c                     |  615 ++++++++
 drivers/net/atlantic/atl_sec.h                     |  124 ++
 drivers/net/atlantic/hw_atl/hw_atl_utils.h         |  116 +-
 drivers/net/atlantic/macsec/MSS_Egress_registers.h | 1498 ++++++++++++++++++
 .../net/atlantic/macsec/MSS_Ingress_registers.h    | 1135 ++++++++++++++
 drivers/net/atlantic/macsec/macsec_api.c           | 1612 ++++++++++++++++++++
 drivers/net/atlantic/macsec/macsec_api.h           |  111 ++
 drivers/net/atlantic/macsec/macsec_struct.h        |  269 ++++
 drivers/net/atlantic/macsec/mdio.c                 |  328 ++++
 drivers/net/atlantic/macsec/mdio.h                 |   19 +
 drivers/net/atlantic/meson.build                   |    6 +-
 drivers/net/atlantic/rte_pmd_atlantic.c            |  102 --
 drivers/net/atlantic/rte_pmd_atlantic.h            |  144 --
 drivers/net/atlantic/rte_pmd_atlantic_version.map  |   16 -
 lib/librte_security/rte_security.h                 |  143 +-
 23 files changed, 6080 insertions(+), 659 deletions(-)
 create mode 100644 app/test-pmd/macsec.c
 create mode 100644 app/test-pmd/macsec.h
 create mode 100644 drivers/net/atlantic/atl_sec.c
 create mode 100644 drivers/net/atlantic/atl_sec.h
 create mode 100644 drivers/net/atlantic/macsec/MSS_Egress_registers.h
 create mode 100644 drivers/net/atlantic/macsec/MSS_Ingress_registers.h
 create mode 100644 drivers/net/atlantic/macsec/macsec_api.c
 create mode 100644 drivers/net/atlantic/macsec/macsec_api.h
 create mode 100644 drivers/net/atlantic/macsec/macsec_struct.h
 create mode 100644 drivers/net/atlantic/macsec/mdio.c
 create mode 100644 drivers/net/atlantic/macsec/mdio.h
 delete mode 100644 drivers/net/atlantic/rte_pmd_atlantic.c
 delete mode 100644 drivers/net/atlantic/rte_pmd_atlantic.h
 delete mode 100644 drivers/net/atlantic/rte_pmd_atlantic_version.map

-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [RFC v2 1/7] security: MACSEC infrastructure data declarations
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
@ 2019-10-25 17:53 ` Pavel Belous
  2019-10-25 17:53 ` [dpdk-dev] [RFC v2 2/7] security: Update rte_security documentation Pavel Belous
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:53 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

This patch extends rte_security framework to support MACSEC operations.

Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
---
 lib/librte_security/rte_security.h | 143 +++++++++++++++++++++++++++++++++++--
 1 file changed, 138 insertions(+), 5 deletions(-)

diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
index aaafdfc..201319f 100644
--- a/lib/librte_security/rte_security.h
+++ b/lib/librte_security/rte_security.h
@@ -29,6 +29,7 @@ extern "C" {
 #include <rte_mbuf.h>
 #include <rte_memory.h>
 #include <rte_mempool.h>
+#include <rte_ether.h>
 
 /** IPSec protocol mode */
 enum rte_security_ipsec_sa_mode {
@@ -215,11 +216,109 @@ struct rte_security_ipsec_xform {
 };
 
 /**
+ * MACSEC global configuration parameters
+ *
+ */
+struct rte_security_macsec_param {
+	uint8_t enabled;
+	uint32_t ingress_pn_threshold;
+	uint32_t egress_pn_threshold;
+	uint8_t interrupts_enabled;
+	/**< List of bypassed ethertypes */
+	uint32_t ctl_ether_types[8];
+};
+
+/**
+ * MACSEC SC (Secure Connection) parameters
+ *
+ */
+struct rte_security_macsec_txsc_param {
+	struct rte_ether_addr s_mac;
+	/**< local side mac address */
+	struct rte_ether_addr d_mac;
+	/**< remote side mac address */
+	uint64_t sci;
+	uint32_t tci;
+	uint32_t sa_num;
+	uint8_t encrypt;
+	uint8_t protect;
+	uint8_t key_len;
+	uint8_t auto_rollover_enabled;
+
+	uint32_t index;
+	uint32_t curr_an;
+};
+
+struct rte_security_macsec_rxsc_param {
+	struct rte_ether_addr s_mac;
+	struct rte_ether_addr d_mac;
+	uint64_t sci;
+	uint32_t tci;
+	uint32_t sa_num;
+	/**< remote side mac address */
+	uint8_t replay_protection;
+	/**< replay protection */
+	uint32_t anti_replay_window;
+	/**< anti replay window */
+	uint16_t port_ident;
+	/**< remote side port identifier */
+	uint8_t auto_rollover_enabled;
+	uint8_t validate_frames;
+
+	uint32_t index;
+};
+
+struct rte_security_macsec_sa_param {
+	uint8_t sa_idx;
+	uint8_t an;
+	uint32_t packet_number;
+	uint8_t key_len;
+	uint8_t key[32];
+};
+
+struct rte_security_macsec_capabilities {
+        /** Extended Packet Numbers (XPN)
+         *
+         * * 1: Extended (64 bit) packet numbers supported
+         * * 0: Extended (64 bit) packet numbers not supported
+         */
+        uint32_t xpn : 1;
+};
+
+/**
+ * Available operations over MACSEC instance
+ */
+enum rte_security_macsec_op {
+	RTE_SECURITY_MACSEC_OP_CONFIG = 0,
+
+	RTE_SECURITY_MACSEC_OP_ADD_TXSC,
+	RTE_SECURITY_MACSEC_OP_DEL_TXSC,
+	RTE_SECURITY_MACSEC_OP_UPD_TXSC,
+
+	RTE_SECURITY_MACSEC_OP_ADD_RXSC,
+	RTE_SECURITY_MACSEC_OP_DEL_RXSC,
+	RTE_SECURITY_MACSEC_OP_UPD_RXSC,
+
+	RTE_SECURITY_MACSEC_OP_ADD_TXSA,
+	RTE_SECURITY_MACSEC_OP_DEL_TXSA,
+	RTE_SECURITY_MACSEC_OP_UPD_TXSA,
+
+	RTE_SECURITY_MACSEC_OP_ADD_RXSA,
+	RTE_SECURITY_MACSEC_OP_DEL_RXSA,
+	RTE_SECURITY_MACSEC_OP_UPD_RXSA,
+};
+
+/**
  * MACsec security session configuration
  */
 struct rte_security_macsec_xform {
-	/** To be Filled */
-	int dummy;
+	enum rte_security_macsec_op op;
+	union {
+		struct rte_security_macsec_param config_options;
+		struct rte_security_macsec_txsc_param txsc_options;
+		struct rte_security_macsec_rxsc_param rxsc_options;
+		struct rte_security_macsec_sa_param sa_options;
+	};
 };
 
 /**
@@ -495,7 +594,42 @@ rte_security_attach_session(struct rte_crypto_op *op,
 }
 
 struct rte_security_macsec_stats {
-	uint64_t reserved;
+	/* Ingress Counters */
+	uint64_t in_ctl_pkts;
+	uint64_t in_tagged_miss_pkts;
+	uint64_t in_untagged_miss_pkts;
+	uint64_t in_notag_pkts;
+	uint64_t in_untagged_pkts;
+	uint64_t in_bad_tag_pkts;
+	uint64_t in_no_sci_pkts;
+	uint64_t in_unknown_sci_pkts;
+
+	/* Egress Counters */
+	uint64_t out_ctl_pkts;
+	uint64_t out_unknown_sa_pkts;
+	uint64_t out_untagged_pkts;
+	uint64_t out_too_long;
+
+	/* Ingress SA Counters */
+	uint64_t in_untagged_hit_pkts;
+	uint64_t in_not_using_sa;
+	uint64_t in_unused_sa;
+	uint64_t in_not_valid_pkts;
+	uint64_t in_invalid_pkts;
+	uint64_t in_ok_pkts;
+	uint64_t in_unchecked_pkts;
+	uint64_t in_validated_octets;
+	uint64_t in_decrypted_octets;
+	/* Egress SC Counters */
+	uint64_t out_sc_protected_pkts;
+	uint64_t out_sc_encrypted_pkts;
+	uint64_t out_sc_protected_octets;
+	uint64_t out_sc_encrypted_octets;
+	/* Egress SA Counters */
+	uint64_t out_sa_hit_drop_redirect;
+	uint64_t out_sa_protected2_pkts;
+	uint64_t out_sa_protected_pkts;
+	uint64_t out_sa_encrypted_pkts;
 };
 
 struct rte_security_ipsec_stats {
@@ -566,8 +700,7 @@ struct rte_security_capability {
 		} ipsec;
 		/**< IPsec capability */
 		struct {
-			/* To be Filled */
-			int dummy;
+			struct rte_security_macsec_capabilities caps;
 		} macsec;
 		/**< MACsec capability */
 		struct {
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [RFC v2 2/7] security: Update rte_security documentation
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
  2019-10-25 17:53 ` [dpdk-dev] [RFC v2 1/7] security: MACSEC infrastructure data declarations Pavel Belous
@ 2019-10-25 17:53 ` Pavel Belous
  2019-10-25 17:53 ` [dpdk-dev] [RFC v2 3/7] net/atlantic: Add helper functions for PHY access Pavel Belous
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:53 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
---
 doc/guides/prog_guide/rte_security.rst | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/doc/guides/prog_guide/rte_security.rst b/doc/guides/prog_guide/rte_security.rst
index 7d0734a..4b9b186 100644
--- a/doc/guides/prog_guide/rte_security.rst
+++ b/doc/guides/prog_guide/rte_security.rst
@@ -533,10 +533,6 @@ The ``rte_security_session_protocol`` is defined as
         /**< PDCP Protocol */
     };
 
-Currently the library defines configuration parameters for IPsec and PDCP only.
-For other protocols like MACSec, structures and enums are defined as place holders
-which will be updated in the future.
-
 IPsec related configuration parameters are defined in ``rte_security_ipsec_xform``
 
 .. code-block:: c
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [RFC v2 3/7] net/atlantic: Add helper functions for PHY access
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
  2019-10-25 17:53 ` [dpdk-dev] [RFC v2 1/7] security: MACSEC infrastructure data declarations Pavel Belous
  2019-10-25 17:53 ` [dpdk-dev] [RFC v2 2/7] security: Update rte_security documentation Pavel Belous
@ 2019-10-25 17:53 ` Pavel Belous
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 4/7] net/atlantic: add MACSEC internal HW data declaration and functions Pavel Belous
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:53 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

Aquantia AQC107/AQC108 ethernet controllers includes MAC and PHY part.
Some network features, like MACSec, are configured directly in the PHY part.

This patch adds helper functions for accessing PHY part via internal MDIO interface.

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
---
 drivers/net/atlantic/Makefile      |   2 +
 drivers/net/atlantic/macsec/mdio.c | 328 +++++++++++++++++++++++++++++++++++++
 drivers/net/atlantic/macsec/mdio.h |  19 +++
 drivers/net/atlantic/meson.build   |   1 +
 4 files changed, 350 insertions(+)
 create mode 100644 drivers/net/atlantic/macsec/mdio.c
 create mode 100644 drivers/net/atlantic/macsec/mdio.h

diff --git a/drivers/net/atlantic/Makefile b/drivers/net/atlantic/Makefile
index fc12e6a..6340588 100644
--- a/drivers/net/atlantic/Makefile
+++ b/drivers/net/atlantic/Makefile
@@ -21,6 +21,7 @@ LDLIBS += -lrte_ethdev -lrte_net
 LDLIBS += -lrte_bus_pci
 
 VPATH += $(SRCDIR)/hw_atl
+VPATH += $(SRCDIR)/macsec
 
 #
 # all source are stored in SRCS-y
@@ -33,5 +34,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_llh.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_utils_fw2x.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_b0.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += rte_pmd_atlantic.c
+SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += mdio.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/atlantic/macsec/mdio.c b/drivers/net/atlantic/macsec/mdio.c
new file mode 100644
index 0000000..a662f58
--- /dev/null
+++ b/drivers/net/atlantic/macsec/mdio.c
@@ -0,0 +1,328 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Aquantia Corporation
+ */
+
+#include "errno.h"
+#include "../atl_hw_regs.h"
+#include "../atl_logs.h"
+#include "../hw_atl/hw_atl_llh.h"
+#include "../hw_atl/hw_atl_b0.h"
+#include "../hw_atl/hw_atl_b0_internal.h"
+#include "mdio.h"
+
+static inline uint32_t macValRead(uint32_t reg, uint32_t msk, uint32_t shift)
+{
+    return (reg & msk) >> shift;
+}
+
+static inline void macValWrite(uint32_t* reg, uint32_t msk, uint32_t shift, uint32_t val)
+{
+    *reg = (*reg & ~msk) | (val << shift);
+}
+
+static inline uint32_t macBitRead(uint32_t reg, uint32_t msk)
+{
+    return reg & msk;
+}
+
+static inline uint32_t regGlobalMdioInterface1Get(void *hw)
+{
+    return aq_hw_read_reg(hw, 0x280);
+}
+
+static inline void valGlobalMdioInterface1MdioClockEnableSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x00004000, 14, val);
+}
+
+static inline void regGlobalMdioInterface1Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x280, val);
+}
+
+static inline void valGlobalMdioInterface4MdioAddressSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x0000FFFF, 0, val);
+}
+
+static inline void regGlobalMdioInterface4Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x28C, val);
+}
+
+static inline void valGlobalMdioInterface2MdioExecuteOperationSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x00008000, 15, val);
+}
+
+static inline void valGlobalMdioInterface2MdioOpModeSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x00003000, 12, val);
+}
+
+static inline void valGlobalMdioInterface2MdioPhyAddressSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x000003FF, 0, val);
+}
+
+static inline void regGlobalMdioInterface2Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x284, val);
+}
+
+static inline uint32_t regGlobalMdioInterface2Get(void *hw)
+{
+    return aq_hw_read_reg(hw, 0x284);
+}
+
+static inline void valGlobalMdioInterface3MdioWriteDataSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x0000FFFF, 0, val);
+}
+
+static inline void regGlobalMdioInterface3Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x288, val);
+}
+
+static inline uint32_t regGlobalMdioInterface5Get(void *hw)
+{
+    return aq_hw_read_reg(hw, 0x290);
+}
+
+static inline uint32_t valGlobalMdioInterface5MdioReadDataGet(uint32_t reg)
+{
+    return macValRead(reg, 0x0000FFFF, 0);
+}
+
+static inline uint32_t bitGlobalMdioInterface2MdioBusyGet(uint32_t reg)
+{
+    return macBitRead(reg, 0x80000000);
+}
+
+
+/* Operation Mode for MDIO */
+#define MDIO_OP_NO 0 /* No Op */
+#define MDIO_OP_READ 1 /* Read Op */
+#define MDIO_OP_WRITE 2 /* Write Op */
+#define MDIO_OP_ADDR 3 /* Address Op */
+
+#define MDIO_COMMAND_TIMEOUT 100
+#define MDIO_SEMAPHORE_TIMEOUT_MS 30 /* msec. */
+
+
+/* 32 bits command + 32 bits preamble = 64 */
+#define MDIO_ONE_CMD_CLOCK_TICKS     64
+/* Wait 10 MDIO transactions */
+#define TIMEOUT_BUSY_WAIT_COUNT     ((MIPS_COUNT_HZ * MDIO_ONE_CMD_CLOCK_TICKS / MDIO_HZ) * 10)
+
+static int mdio_phy_addr = (0 << 5);
+
+
+static inline unsigned int mMdioBusyCheck(void *hw)
+{
+    return bitGlobalMdioInterface2MdioBusyGet(regGlobalMdioInterface2Get(hw));
+}
+
+static int mBusyWait(struct aq_hw_s *hw)
+{
+    unsigned i = 0;
+
+    for (i = 1000U; mMdioBusyCheck(hw) && i; i--){};
+
+    if (i == 0) {
+	PMD_DRV_LOG(ERR, "Mdio busy!!");
+	return 1;
+    }
+
+    return 0;
+}
+
+
+static inline void mSendPhyAddress(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr)
+{
+    uint32_t reg;
+
+    /* Set MDIO Address (0x28c) */
+    reg = 0;
+    valGlobalMdioInterface4MdioAddressSet(&reg, addr);
+    regGlobalMdioInterface4Set(hw, reg);
+
+    /* Set MDIO Address Operation and PHY Address (0x284) */
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_ADDR);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, mdio_phy_addr | mmd);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static void mSendDummyWriteCmd(struct aq_hw_s *hw)
+{
+    uint32_t reg;
+
+    // Set data (0x288)
+    reg = 0;
+    valGlobalMdioInterface3MdioWriteDataSet(&reg, 0);
+    regGlobalMdioInterface3Set(hw, reg);
+
+    // Write operation (0x284)
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_WRITE);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, 0);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static inline void mSendReadCmd(struct aq_hw_s *hw, unsigned int mmd)
+{
+    uint32_t reg;
+
+    // Execute Read Operation (0x284)
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_READ);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, mdio_phy_addr | mmd);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static inline void mSendWriteCmd(struct aq_hw_s *hw, unsigned int mmd)
+{
+    uint32_t reg;
+
+    // Execute Read Operation (0x284)
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_WRITE);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, mdio_phy_addr | mmd);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static inline unsigned short int mReadData(struct aq_hw_s *hw)
+{
+    // Register 0x290
+    return valGlobalMdioInterface5MdioReadDataGet(regGlobalMdioInterface5Get(hw));
+}
+
+static inline void mWriteData(struct aq_hw_s *hw, unsigned short int val)
+{
+    uint32_t reg;
+
+    // Register 0x288
+    reg = 0;
+    valGlobalMdioInterface3MdioWriteDataSet(&reg, val);
+    regGlobalMdioInterface3Set(hw, reg);
+}
+
+
+static int __mdioRead(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int* data)
+{
+    int ret = -1;
+
+    /* Execute Address Operation */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendPhyAddress(hw, mmd, addr);
+
+    /* Dummy write transaction */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendDummyWriteCmd(hw);
+
+    /* Read command */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendReadCmd(hw, mmd);
+
+    /* Read MDIO Data */
+    if (mBusyWait(hw))
+        goto _exit;
+    *data = mReadData(hw);
+
+    ret = 0;
+
+_exit:
+    return ret;
+}
+
+static
+int __mdioWrite(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int data)
+{
+    int ret = -1;
+
+    /* Execute Address Operation */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendPhyAddress(hw, mmd, addr);
+
+    /* Dummy write transaction */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendDummyWriteCmd(hw);
+
+    /* Write command */
+    if (mBusyWait(hw))
+        goto _exit;
+    mWriteData(hw, data);
+    mSendWriteCmd(hw, mmd);
+
+    /* Expect completion of the operation */
+    if (mBusyWait(hw))
+        goto _exit;
+
+    ret = 0;
+
+_exit:
+    return ret;
+}
+
+int mdioRead(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int* data)
+{
+    uint32_t reg;
+    int ret;
+
+    // Send Dummy Transaction
+    if (mBusyWait(hw))
+        return -1;
+    mSendDummyWriteCmd(hw);
+
+    // Enable MDIO Clock (active low) (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 0);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    ret = __mdioRead(hw, mmd, addr, data);
+
+    // Disable MDIO Clock (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 1);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    return ret;
+}
+
+int mdioWrite(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int data)
+{
+    uint32_t reg;
+    int ret;
+
+    // Send Dummy Transaction
+    if (mBusyWait(hw))
+        return -1;
+    mSendDummyWriteCmd(hw);
+
+    // Enable MDIO Clock (active low) (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 0);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    ret = __mdioWrite(hw, mmd, addr, data);
+
+    // Disable MDIO Clock (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 1);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    return ret;
+}
+
+
diff --git a/drivers/net/atlantic/macsec/mdio.h b/drivers/net/atlantic/macsec/mdio.h
new file mode 100644
index 0000000..907f04f
--- /dev/null
+++ b/drivers/net/atlantic/macsec/mdio.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Aquantia Corporation
+ */
+
+#ifndef __MDIO_HH__
+#define __MDIO_HH__
+
+
+#include "../atl_types.h"
+#include "../hw_atl/hw_atl_utils.h"
+
+
+#define MMD_GLOBAL 0x1E
+
+
+int mdioRead(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int* data);
+int mdioWrite(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int data);
+
+#endif
diff --git a/drivers/net/atlantic/meson.build b/drivers/net/atlantic/meson.build
index 919d741..d1c66f4 100644
--- a/drivers/net/atlantic/meson.build
+++ b/drivers/net/atlantic/meson.build
@@ -12,4 +12,5 @@ sources = files(
 	'hw_atl/hw_atl_utils_fw2x.c',
 	'hw_atl/hw_atl_utils.c',
 	'rte_pmd_atlantic.c',
+	'macsec/mdio.c',
 )
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [RFC v2 4/7] net/atlantic: add MACSEC internal HW data declaration and functions
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
                   ` (2 preceding siblings ...)
  2019-10-25 17:53 ` [dpdk-dev] [RFC v2 3/7] net/atlantic: Add helper functions for PHY access Pavel Belous
@ 2019-10-25 17:54 ` Pavel Belous
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 5/7] net/atlantic: implementation of the MACSEC using rte_security interface Pavel Belous
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:54 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

MACSEC configuration is done by configuring multiple tables of MACSEC block:

- Ingress Pre-Security Classification table
- Ingress SC/SA/SAK lookup tables
- Ingress Post-Security Classification table
- Egress Packet Classifier table
- Egress Control Filter table
- Egress SC/SA/SAK lookup tables
- Ingress/Egress SC/SA/Common counters tables
- Some additional tables and spare registers

Each entry of the tables is distributed across a set of PHY registers.

This patch adds declarations for internal MACSEC HW structures
and helper functions (HAL) for accessing these tables inside MACSEC block.

This HAL was automatically generated based on the RTL design of the MACSEC
block.

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 drivers/net/atlantic/Makefile                      |    1 +
 drivers/net/atlantic/macsec/MSS_Egress_registers.h | 1498 ++++++++++++++++++
 .../net/atlantic/macsec/MSS_Ingress_registers.h    | 1135 ++++++++++++++
 drivers/net/atlantic/macsec/macsec_api.c           | 1612 ++++++++++++++++++++
 drivers/net/atlantic/macsec/macsec_api.h           |  111 ++
 drivers/net/atlantic/macsec/macsec_struct.h        |  269 ++++
 drivers/net/atlantic/meson.build                   |    1 +
 7 files changed, 4627 insertions(+)
 create mode 100644 drivers/net/atlantic/macsec/MSS_Egress_registers.h
 create mode 100644 drivers/net/atlantic/macsec/MSS_Ingress_registers.h
 create mode 100644 drivers/net/atlantic/macsec/macsec_api.c
 create mode 100644 drivers/net/atlantic/macsec/macsec_api.h
 create mode 100644 drivers/net/atlantic/macsec/macsec_struct.h

diff --git a/drivers/net/atlantic/Makefile b/drivers/net/atlantic/Makefile
index 6340588..966676b 100644
--- a/drivers/net/atlantic/Makefile
+++ b/drivers/net/atlantic/Makefile
@@ -35,5 +35,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_utils_fw2x.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_b0.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += rte_pmd_atlantic.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += mdio.c
+SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += macsec_api.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/atlantic/macsec/MSS_Egress_registers.h b/drivers/net/atlantic/macsec/MSS_Egress_registers.h
new file mode 100644
index 0000000..ccbb20f
--- /dev/null
+++ b/drivers/net/atlantic/macsec/MSS_Egress_registers.h
@@ -0,0 +1,1498 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) */
+/* Copyright (C) 2014-2019 aQuantia Corporation. */
+
+#ifndef MSS_EGRESS_REGS_HEADER
+#define MSS_EGRESS_REGS_HEADER
+
+
+#define mssEgressVersionStatusRegister_ADDR 0x00005000
+#define mssEgressControlRegister_ADDR 0x00005002
+#define mssEgressPrescaleControlRegister_ADDR 0x00005004
+#define mssEgressVlanTpid_0Register_ADDR 0x00005008
+#define mssEgressVlanTpid_1Register_ADDR 0x0000500A
+#define mssEgressVlanControlRegister_ADDR 0x0000500C
+#define mssEgressPnControlRegister_ADDR 0x0000500E
+#define mssEgressMtuSizeControlRegister_ADDR 0x00005010
+#define mssEgressGcmDataInput_0ControlRegister_ADDR 0x00005012
+#define mssEgressGcmDataInput_1ControlRegister_ADDR 0x00005014
+#define mssEgressGcmDataInput_2ControlRegister_ADDR 0x00005016
+#define mssEgressGcmDataInput_3ControlRegister_ADDR 0x00005018
+#define mssEgressGcmKey_0ControlRegister_ADDR 0x0000501A
+#define mssEgressGcmKey_0ControlRegister_word_REF(word) (0x0000501A
+#define mssEgressGcmKey_1ControlRegister_ADDR 0x0000501C
+#define mssEgressGcmKey_2ControlRegister_ADDR 0x0000501E
+#define mssEgressGcmKey_3ControlRegister_ADDR 0x00005020
+#define mssEgressGcmInitialVector_0ControlRegister_ADDR 0x00005022
+#define mssEgressGcmInitialVector_1ControlRegister_ADDR 0x00005024
+#define mssEgressGcmInitialVector_2ControlRegister_ADDR 0x00005026
+#define mssEgressGcmInitialVector_3ControlRegister_ADDR 0x00005028
+#define mssEgressGcmHashInput_0ControlRegister_ADDR 0x0000502A
+#define mssEgressGcmHashInput_1ControlRegister_ADDR 0x0000502C
+#define mssEgressGcmHashInput_2ControlRegister_ADDR 0x0000502E
+#define mssEgressGcmHashInput_3ControlRegister_ADDR 0x00005030
+#define mssEgressGcmDataOut_0StatusRegister_ADDR 0x00005032
+#define mssEgressGcmDataOut_1StatusRegister_ADDR 0x00005034
+#define mssEgressGcmDataOut_2StatusRegister_ADDR 0x00005036
+#define mssEgressGcmDataOut_3StatusRegister_ADDR 0x00005038
+#define mssEgressGcmHashOut_0StatusRegister_ADDR 0x0000503A
+#define mssEgressGcmHashOut_1StatusRegister_ADDR 0x0000503C
+#define mssEgressGcmHashOut_2StatusRegister_ADDR 0x0000503E
+#define mssEgressGcmHashOut_3StatusRegister_ADDR 0x00005040
+#define mssEgressBufferDebugStatusRegister_ADDR 0x00005042
+#define mssEgressPacketFormatDebugStatusRegister_ADDR 0x00005044
+#define mssEgressGcmMultLengthADebugStatusRegister_ADDR 0x00005046
+#define mssEgressGcmMultLengthCDebugStatusRegister_ADDR 0x0000504A
+#define mssEgressGcmMultDataCountDebugStatusRegister_ADDR 0x0000504E
+#define mssEgressGcmCounterIncrmentDebugStatusRegister_ADDR 0x00005050
+#define mssEgressGcmBusyDebugStatusRegister_ADDR 0x00005052
+#define mssEgressSpareControlRegister_ADDR 0x00005054
+#define mssEgressInterruptStatusRegister_ADDR 0x0000505C
+#define mssEgressInterruptMaskRegister_ADDR 0x0000505E
+#define mssEgressSaExpiredStatusRegister_ADDR 0x00005060
+#define mssEgressSaThresholdExpiredStatusRegister_ADDR 0x00005062
+#define mssEgressEccInterruptStatusRegister_ADDR 0x00005064
+#define mssEgressEgprcLutEccError_1AddressStatusRegister_ADDR 0x00005066
+#define mssEgressEgprcLutEccError_2AddressStatusRegister_ADDR 0x00005068
+#define mssEgressEgprctlfLutEccErrorAddressStatusRegister_ADDR 0x0000506A
+#define mssEgressEgpfmtLutEccErrorAddressStatusRegister_ADDR 0x0000506C
+#define mssEgressEgmibEccErrorAddressStatusRegister_ADDR 0x0000506E
+#define mssEgressEccControlRegister_ADDR 0x00005070
+#define mssEgressDebugControlRegister_ADDR 0x00005072
+#define mssEgressDebugStatusRegister_ADDR 0x00005074
+#define mssEgressLutAddressControlRegister_ADDR 0x00005080
+#define mssEgressLutControlRegister_ADDR 0x00005081
+#define mssEgressLutDataControlRegister_ADDR 0x000050A0
+
+struct mssEgressVersionStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressID:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressVersion:8;
+			unsigned int mssEgressRevision:8;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSoftReset:1;
+			unsigned int mssEgressDropKayPacket:1;
+			unsigned int mssEgressDropEgprcLutMiss:1;
+			unsigned int mssEgressGcmStart:1;
+			unsigned int mssEgresssGcmTestMode:1;
+			unsigned int mssEgressUnmatchedUseSc_0:1;
+			unsigned int mssEgressDropInvalidSa_scPackets:1;
+			unsigned int mssEgressExplicitSectagReportShortLength:1;
+			unsigned int mssEgressExternalClassificationEnable:1;
+			unsigned int mssEgressIcvLsb_8BytesEnable:1;
+			unsigned int mssEgressHighPriority:1;
+			unsigned int mssEgressClearCounter:1;
+			unsigned int mssEgressClearGlobalTime:1;
+			unsigned int mssEgressEthertypeExplicitSectagLsb:3;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEthertypeExplicitSectagMsb:13;
+			unsigned int reserved0:3;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressPrescaleControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressPrescaleConfigurationLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressPrescaleConfigurationMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressVlanTpid_0Register_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressVlanStagTpid:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressVlanTpid_1Register_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressVlanQtagTpid:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressVlanControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressVlanUpMapTable:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressVlanUpMapTableMSW:8;
+			unsigned int mssEgressVlanUpDefault:3;
+			unsigned int mssEgressVlanStagUpParseEnable:1;
+			unsigned int mssEgressVlanQtagUpParseEnable:1;
+			unsigned int mssEgressVlanQinqParseEnable:1;
+			unsigned int mssEgressVlanStagParseEnable:1;
+			unsigned int mssEgressVlanQtagParseEnable:1;
+		} bits_1;
+	unsigned short word_1;
+	};
+};
+
+struct mssEgressPnControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaPnThresholdLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaPnThresholdMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressMtuSizeControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressControlledPacketMtuSize:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressUncontrolledPacketMtuSize:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataInput_0ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_0LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_0MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataInput_1ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_1LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataInput_2ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_2LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_2MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataInput_3ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_3LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataInput_3MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmKey_0ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_0LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_0MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmKey_1ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_1LSW:16;
+		} bits_0;
+	unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmKey_2ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_2LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_2MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmKey_3ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_3LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmKey_3MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmInitialVector_0ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_0LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_0MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmInitialVector_1ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_1LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmInitialVector_2ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_2LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_2MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmInitialVector_3ControlRegister_t
+{
+	 union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_3LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmInitialVector_3MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashInput_0ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_0LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_0MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashInput_1ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_1LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashInput_2ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_2LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_2MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashInput_3ControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_3LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashInput_3MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataOut_0StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_0LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_0MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataOut_1StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_1LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataOut_2StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_2LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_2MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmDataOut_3StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_3LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmDataOut_3MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashOut_0StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_0LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_0MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashOut_1StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_1LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashOut_2StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_2LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_2MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmHashOut_3StatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_3LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmHashOut_3MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressBufferDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEofInsertionDebug:4;
+			unsigned int mssEgressRemovalDebug:4;
+			unsigned int mssEgressRemovalS_wDebug:6;
+			unsigned int reserved0:2;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssEgressPacketFormatDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressPacketFormatDebug:8;
+			unsigned int mssEgressSectagInsertionDebug:6;
+			unsigned int mssEgressPadInsertionDebugLsb:2;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressPadInsertionDebugMsb:4;
+			unsigned int mssEgressSectagRemovalDebug:6;
+			unsigned int reserved0:6;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmMultLengthADebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthADebug_0:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthADebug_1:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthADebug_2:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthADebug_3:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+};
+
+struct mssEgressGcmMultLengthCDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthCDebug_0:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthCDebug_1:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthCDebug_2:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultLengthCDebug_3:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+};
+
+struct mssEgressGcmMultDataCountDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmMultDataCountDebug:2;
+			unsigned int reserved0:14;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssEgressGcmCounterIncrmentDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmCounterIncrementDebugLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressGcmCounterIncrementDebugMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressGcmBusyDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressDatapathBusy:1;
+			unsigned int mssEgressPacketFormatBusy:1;
+			unsigned int mssEgressAesCounterBusy:1;
+			unsigned int mssEgressPostGcmBufferBusy:1;
+			unsigned int mssEgressGcmBufferBusy:1;
+			unsigned int mssEgressLookupBusy:1;
+			unsigned int reserved0:10;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssEgressSpareControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_1LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_2LSW:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_2MSW:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_3LSW:16;
+		} bits_4;
+		unsigned int word_4;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_3MSW:16;
+		} bits_5;
+		unsigned int word_5;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_4LSW:16;
+		} bits_6;
+		unsigned int word_6;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSpareConfiguration_4MSW:16;
+		} bits_7;
+		unsigned int word_7;
+	};
+};
+
+struct mssEgressInterruptStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressMasterInterrupt:1;
+			unsigned int mssEgressSaExpiredInterrupt:1;
+			unsigned int mssEgressSaThresholdExpiredInterrupt:1;
+			unsigned int mssEgressMibSaturationInterrupt:1;
+			unsigned int mssEgressEccErrorInterrupt:1;
+			unsigned int reserved0:11;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressInterruptMaskRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressMasterInterruptEnable:1;
+			unsigned int mssEgressSaExpiredInterruptEnable:1;
+			unsigned int mssEgressSaExpiredThresholdInterruptEnable:1;
+			unsigned int mssEgressMibSaturationInterruptEnable:1;
+			unsigned int mssEgressEccErrorInterruptEnable:1;
+			unsigned int reserved0:11;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressSaExpiredStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaExpiredLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaExpiredMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressSaThresholdExpiredStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaThresholdExpiredLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaThresholdExpiredMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressEccInterruptStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaEccErrorInterruptLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressSaEccErrorInterruptMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressEgprcLutEccError_1AddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgprcLutEccError_1AddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgprcLutEccError_1AddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressEgprcLutEccError_2AddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgprcLutEccError_2AddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgprcLutEccError_2AddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressEgprctlfLutEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgprctlfLutEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgprctlfLutEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressEgpfmtLutEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgpfmtLutEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgpfmtLutEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressEgmibEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgmibEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEgmibEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssEgressEccControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressEccEnable:1;
+			unsigned int mssEgressFastPnNumberEnable:1;
+			unsigned int reserved0:14;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssEgressDebugControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressDebugBusSelect:2;
+			unsigned int reserved0:14;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssEgressDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressClassificationLutDebug:12;
+			unsigned int mssEgressMacControlFilterDebugLsb:4;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressMacControlFilterDebugMsb:7;
+			unsigned int mssEgressSectagProcessingLutDebug:8;
+			unsigned int reserved0:1;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLookupDebugLSW:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLookupDebugMSW:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressDatapathDebug:6;
+			unsigned int reserved0:10;
+		} bits_4;
+		unsigned int word_4;
+	};
+};
+
+struct mssEgressLutAddressControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutAddress:9;
+			unsigned int reserved0:3;
+			unsigned int mssEgressLutSelect:4;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssEgressLutControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:14;
+			unsigned int mssEgressLutRead:1;
+			unsigned int mssEgressLutWrite:1;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssEgressLutDataControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_0:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_1:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_2:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_3:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_4:16;
+		} bits_4;
+		unsigned int word_4;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_5:16;
+		} bits_5;
+		unsigned int word_5;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_6:16;
+		} bits_6;
+		unsigned int word_6;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_7:16;
+		} bits_7;
+		unsigned int word_7;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_8:16;
+		} bits_8;
+		unsigned int word_8;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_9:16;
+		} bits_9;
+		unsigned int word_9;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_10:16;
+		} bits_10;
+		unsigned short word_10;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_11:16;
+		} bits_11;
+		unsigned short word_11;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_12:16;
+		} bits_12;
+		unsigned short word_12;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_13:16;
+		} bits_13;
+		unsigned short word_13;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_14:16;
+		} bits_14;
+		unsigned short word_14;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_15:16;
+		} bits_15;
+		unsigned short word_15;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_16:16;
+		} bits_16;
+		unsigned short word_16;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_17:16;
+		} bits_17;
+		unsigned short word_17;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_18:16;
+		} bits_18;
+		unsigned short word_18;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_19:16;
+		} bits_19;
+		unsigned short word_19;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_20:16;
+		} bits_20;
+		unsigned int word_20;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_21:16;
+		} bits_21;
+		unsigned int word_21;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_22:16;
+		} bits_22;
+		unsigned int word_22;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_23:16;
+		} bits_23;
+		unsigned int word_23;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_24:16;
+		} bits_24;
+		unsigned int word_24;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_25:16;
+		} bits_25;
+		unsigned int word_25;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_26:16;
+		} bits_26;
+		unsigned int word_26;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssEgressLutData_27:16;
+		} bits_27;
+		unsigned int word_27;
+	};
+};
+
+#endif /* MSS_EGRESS_REGS_HEADER */
diff --git a/drivers/net/atlantic/macsec/MSS_Ingress_registers.h b/drivers/net/atlantic/macsec/MSS_Ingress_registers.h
new file mode 100644
index 0000000..ec5adb3
--- /dev/null
+++ b/drivers/net/atlantic/macsec/MSS_Ingress_registers.h
@@ -0,0 +1,1135 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) */
+/* Copyright (C) 2014-2019 aQuantia Corporation. */
+
+#ifndef MSS_INGRESS_REGS_HEADER
+#define MSS_INGRESS_REGS_HEADER
+
+#define mssIngressVersionStatusRegister_ADDR 0x00008000
+#define mssIngressPrescaleControlRegister_ADDR 0x00008004
+#define mssIngressVlanTpid_0Register_ADDR 0x00008006
+#define mssIngressVlanTpid_1Register_ADDR 0x00008008
+#define mssIngressVlanControlRegister_ADDR 0x0000800A
+#define mssIngressMtuSizeControlRegister_ADDR 0x0000800C
+#define mssIngressControlRegister_ADDR 0x0000800E
+#define mssIngressSaControlRegister_ADDR 0x00008010
+#define mssIngressDebugStatusRegister_ADDR 0x00008012
+#define mssIngressBusyStatusRegister_ADDR 0x00008022
+#define mssIngressSpareControlRegister_ADDR 0x00008024
+#define mssIngressSciDefaultControlRegister_ADDR 0x0000802A
+#define mssIngressInterruptStatusRegister_ADDR 0x0000802E
+#define mssIngressInterruptMaskRegister_ADDR 0x00008030
+#define mssIngressSaIcvErrorStatusRegister_ADDR 0x00008032
+#define mssIngressSaReplayErrorStatusRegister_ADDR 0x00008034
+#define mssIngressSaExpiredStatusRegister_ADDR 0x00008036
+#define mssIngressSaThresholdExpiredStatusRegister_ADDR 0x00008038
+#define mssIngressEccInterruptStatusRegister_ADDR 0x0000803A
+#define mssIngressIgprcLutEccError_1AddressStatusRegister_ADDR 0x0000803C
+#define mssIngressIgprcLutEccError_2AddressStatusRegister_ADDR 0x0000803E
+#define mssIngressIgctlfLutEccErrorAddressStatusRegister_ADDR 0x00008040
+#define mssIngressIgpfmtLutEccErrorAddressStatusRegister_ADDR 0x00008042
+#define mssIngressIgpopLutEccErrorAddressStatusRegister_ADDR 0x00008044
+#define mssIngressIgpoctlfLutEccErrorAddressStatusRegister_ADDR 0x00008046
+#define mssIngressIgpocLutEccError_1AddressStatusRegister_ADDR 0x00008048
+#define mssIngressIgpocLutEccError_2AddressStatusRegister_ADDR 0x0000804A
+#define mssIngressIgmibEccErrorAddressStatusRegister_ADDR 0x0000804C
+#define mssIngressEccControlRegister_ADDR 0x0000804E
+#define mssIngressDebugControlRegister_ADDR 0x00008050
+#define mssIngressAdditionalDebugStatusRegister_ADDR 0x00008052
+#define mssIngressLutAddressControlRegister_ADDR 0x00008080
+#define mssIngressLutControlRegister_ADDR 0x00008081
+#define mssIngressLutDataControlRegister_ADDR 0x000080A0
+
+struct mssIngressVersionStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressID:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressVersion:8;
+			unsigned int mssIngressRevision:8;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressPrescaleControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressPrescaleConfigurationLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressPrescaleConfigurationMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressVlanTpid_0Register_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressVlanStag:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressVlanTpid_1Register_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressVlanQtag:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressVlanControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressVlanUpMapTableLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressVlanUpMapTableMSW:8;
+			unsigned int mssIngressVlanUpDefault:3;
+			unsigned int mssIngressVlanStagUpParseEnable:1;
+			unsigned int mssIngressVlanQtagUpParseEnable:1;
+			unsigned int mssIngressVlanQinqParseEnable:1;
+			unsigned int mssIngressVlanStagParseEnable:1;
+			unsigned int mssIngressVlanQtagParseEnable:1;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressMtuSizeControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressControlledPacketMtuSize:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressUncontrolledPacketMtuSize:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSoftReset:1;
+			unsigned int mssIngressOperationPointToPoint:1;
+			unsigned int mssIngressCreateSci:1;
+			unsigned int mssIngressMaskShortLengthError:1;
+			unsigned int mssIngressDropKayPacket:1;
+			unsigned int mssIngressDropIgprcMiss:1;
+			unsigned int mssIngressCheckIcv:1;
+			unsigned int mssIngressClearGlobalTime:1;
+			unsigned int mssIngressClearCount:1;
+			unsigned int mssIngressHighPriority:1;
+			unsigned int mssIngressRemoveSectag:1;
+			unsigned int mssIngressGlobalValidateFrames:2;
+			unsigned int mssIngressIcvLsb_8BytesEnable:1;
+			unsigned int reserved0:2;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressSaControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaThresholdLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaThresholdMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpfmtStateMachine:4;
+			unsigned int mssIngressIgpfmtBufferDepth:4;
+			unsigned int mssIngressIgpfmtPadInsertionStateMachine:4;
+			unsigned int mssIngressIgpfmtPadInsertionBufferDepth:2;
+			unsigned int reserved0:2;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpopStateMachine:4;
+			unsigned int mssIngressIgpopBufferDepth:5;
+			unsigned int mssIngressIgpfmtSectagRemovalStateMachine:2;
+			unsigned int mssIngressIgpfmtSectagRemovalBufferDepth:3;
+			unsigned int mssIngressIgpfmtLastBytesRemovalStateMachine:2;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpfmtLastBytesRemovalBufferDepth:2;
+			unsigned int reserved0:14;
+		} bits_3;
+		unsigned int word_3;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmCounterLSW:16;
+		} bits_4;
+		unsigned int word_4;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmCounterMSW:16;
+		} bits_5;
+		unsigned int word_5;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGmcMultBufferDepth:2;
+			unsigned int reserved0:14;
+		} bits_6;
+		unsigned int word_6;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_7;
+		unsigned int word_7;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthA_0:16;
+		} bits_8;
+		unsigned int word_8;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthA_1:16;
+		} bits_9;
+		unsigned int word_9;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthA_2:16;
+		} bits_10;
+		unsigned short word_10;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthA_3:16;
+		} bits_11;
+		unsigned short word_11;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthC_0:16;
+		} bits_12;
+		unsigned short word_12;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthC_1:16;
+		} bits_13;
+		unsigned short word_13;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthC_2:16;
+		} bits_14;
+		unsigned short word_14;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressGcmMultLengthC_3:16;
+		} bits_15;
+		unsigned short word_15;
+	};
+};
+
+struct mssIngressBusyStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressDataPathBusy:1;
+			unsigned int mssIngressIgpfmtBusy:1;
+			unsigned int mssIngressAesCounterBusy:1;
+			unsigned int mssIngressIgpopBusy:1;
+			unsigned int mssIngressGcmBufferBusy:1;
+			unsigned int mssIngressIgprcBusy:1;
+			unsigned int mssIngressIgpocBusy:1;
+			unsigned int reserved0:9;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssIngressSpareControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSpareControl_1LSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSpareControl_1MSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSpareControl_2LSW:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSpareControl_2MSW:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSpareControl_3LSW:16;
+		} bits_4;
+		unsigned int word_4;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSpareControl_3MSW:16;
+		} bits_5;
+		unsigned int word_5;
+	};
+};
+
+struct mssIngressSciDefaultControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSciDefault_0:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSciDefault_1:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSciDefault_2:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSciDefault_3:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+};
+
+struct mssIngressInterruptStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssMasterIngressInterrupt:1;
+			unsigned int mssIngressSaExpiredInterrupt:1;
+			unsigned int mssIngressSaThresholdExpiredInterrupt:1;
+			unsigned int mssIngressIcvErrorInterrupt:1;
+			unsigned int mssIngressReplayErrorInterrupt:1;
+			unsigned int mssIngressMibSaturationInterrupt:1;
+			unsigned int mssIngressEccErrorInterrupt:1;
+			unsigned int mssIngressTciE_cErrorInterrupt:1;
+			unsigned int mssIngressIgpocMissInterrupt:1;
+			unsigned int reserved0:7;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressInterruptMaskRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressMasterInterruptEnable:1;
+			unsigned int mssIngressSaExpiredInterruptEnable:1;
+			unsigned int mssIngressSaThresholdExpiredInterruptEnable:1;
+			unsigned int mssIngressIcvErrorInterruptEnable:1;
+			unsigned int mssIngressReplayErrorInterruptEnable:1;
+			unsigned int mssIngressMibSaturationInterruptEnable:1;
+			unsigned int mssIngressEccErrorInterruptEnable:1;
+			unsigned int mssIngressTciE_cErrorInterruptEnable:1;
+			unsigned int mssIngressIgpocMissInterruptEnable:1;
+			unsigned int reserved0:7;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressSaIcvErrorStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaIcvErrorLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaIcvErrorMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressSaReplayErrorStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaReplayErrorLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaReplayErrorMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressSaExpiredStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaExpiredLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaExpiredMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressSaThresholdExpiredStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaThresholdExpiredLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaThresholdExpiredMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressEccInterruptStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaEccErrorInterruptLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressSaEccErrorInterruptMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgprcLutEccError_1AddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgprcLutEccError_1AddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgprcLutEccError_1AddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgprcLutEccError_2AddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgprcLutEccError_2AddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgprcLutEccError_2AddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgctlfLutEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgctlfLutEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgctlfLutEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgpfmtLutEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpfmtLutEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpfmtLutEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgpopLutEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpopLutEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpopLutEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgpoctlfLutEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpoctlfLutEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpoctlfLutEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgpocLutEccError_1AddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpocLutEccError_1AddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpocLutEccError_1AddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgpocLutEccError_2AddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpocLutEccError_2AddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpocLutEccError_2AddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressIgmibEccErrorAddressStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgmibEccErrorAddressLSW:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgmibEccErrorAddressMSW:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+};
+
+struct mssIngressEccControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressEccEnable:1;
+			unsigned int reserved0:15;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssIngressDebugControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressDebugBusSelect:2;
+			unsigned int reserved0:14;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssIngressAdditionalDebugStatusRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpoctlfLutDebug:11;
+			unsigned int mssIngressIgpocDebugLsb:5;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpocDebugMsb:15;
+			unsigned int reserved0:1;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpocLutDebug:14;
+			unsigned int mssIngressIgpopDebugLsb:2;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgpopDebugMsb:6;
+			unsigned int mssIngressDataPathDebug:10;
+		} bits_3;
+		unsigned int word_3;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgprctlfLutDebug:11;
+			unsigned int mssIngressIgprcLutDebugLsb:5;
+		} bits_4;
+		unsigned int word_4;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressIgprcLutDebugMsb:8;
+			unsigned int reserved0:8;
+		} bits_5;
+		unsigned int word_5;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLookupDebug:12;
+			unsigned int mssIngressProcessingDebugLsb:4;
+		} bits_6;
+		unsigned int word_6;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressProcessingDebugMsb:7;
+			unsigned int reserved0:9;
+		} bits_7;
+		unsigned int word_7;
+	};
+};
+
+struct mssIngressLutAddressControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutAddress:9;
+			unsigned int reserved0:3;
+			unsigned int mssIngressLutSelect:4;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssIngressLutControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int reserved0:14;
+			unsigned int mssIngressLutRead:1;
+			unsigned int mssIngressLutWrite:1;
+		} bits_0;
+		unsigned short word_0;
+	};
+};
+
+struct mssIngressLutDataControlRegister_t
+{
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_0:16;
+		} bits_0;
+		unsigned short word_0;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_1:16;
+		} bits_1;
+		unsigned short word_1;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_2:16;
+		} bits_2;
+		unsigned int word_2;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_3:16;
+		} bits_3;
+		unsigned int word_3;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_4:16;
+		} bits_4;
+		unsigned int word_4;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_5:16;
+		} bits_5;
+		unsigned int word_5;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_6:16;
+		} bits_6;
+		unsigned int word_6;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_7:16;
+		} bits_7;
+		unsigned int word_7;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_8:16;
+		} bits_8;
+		unsigned int word_8;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_9:16;
+		} bits_9;
+		unsigned int word_9;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_10:16;
+		} bits_10;
+		unsigned short word_10;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_11:16;
+		} bits_11;
+		unsigned short word_11;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_12:16;
+		} bits_12;
+		unsigned short word_12;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_13:16;
+		} bits_13;
+		unsigned short word_13;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_14:16;
+		} bits_14;
+		unsigned short word_14;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_15:16;
+		} bits_15;
+		unsigned short word_15;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_16:16;
+		} bits_16;
+		unsigned short word_16;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_17:16;
+		} bits_17;
+		unsigned short word_17;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_18:16;
+		} bits_18;
+		unsigned short word_18;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_19:16;
+		} bits_19;
+		unsigned short word_19;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_20:16;
+		} bits_20;
+		unsigned int word_20;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_21:16;
+		} bits_21;
+		unsigned int word_21;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_22:16;
+		} bits_22;
+		unsigned int word_22;
+	};
+	union
+	{
+		struct
+		{
+			unsigned int mssIngressLutData_23:16;
+		} bits_23;
+		unsigned int word_23;
+	};
+};
+
+#endif /* MSS_INGRESS_REGS_HEADER */
diff --git a/drivers/net/atlantic/macsec/macsec_api.c b/drivers/net/atlantic/macsec/macsec_api.c
new file mode 100644
index 0000000..2003821
--- /dev/null
+++ b/drivers/net/atlantic/macsec/macsec_api.c
@@ -0,0 +1,1612 @@
+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
+/* Copyright (C) 2014-2019 aQuantia Corporation. */
+
+#include "macsec_api.h"
+#include "MSS_Ingress_registers.h"
+#include "MSS_Egress_registers.h"
+#include "mdio.h"
+
+#include "errno.h"
+
+static
+int SetRawSECIngressRecordVal(struct aq_hw_s *hw, uint16_t* packedRecVal, uint8_t numWords, uint8_t tableID, uint16_t tableIndex)
+{
+    struct mssIngressLutAddressControlRegister_t tableSelReg;
+    struct mssIngressLutControlRegister_t readWriteReg;
+
+    unsigned int i;
+
+    for (i = 0; i < numWords; i += 2)
+    {
+        mdioWrite(hw, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i, packedRecVal[i]);
+        mdioWrite(hw, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i + 1, packedRecVal[i + 1]);
+    }
+
+    for (i = numWords; i < 24; i += 2)
+    {
+        mdioWrite(hw, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i, 0);
+        mdioWrite(hw, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i + 1, 0);
+    }
+
+    tableSelReg.bits_0.mssIngressLutSelect = tableID;
+    tableSelReg.bits_0.mssIngressLutAddress = tableIndex;
+
+    readWriteReg.bits_0.mssIngressLutRead = 0;
+    readWriteReg.bits_0.mssIngressLutWrite = 1;
+
+    mdioWrite(hw, MMD_GLOBAL, mssIngressLutAddressControlRegister_ADDR, tableSelReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssIngressLutControlRegister_ADDR, readWriteReg.word_0);
+
+    return 0;
+}
+
+static
+int GetRawSECIngressRecordVal(struct aq_hw_s *hw, uint16_t* packedRecVal, uint8_t numWords, uint8_t tableID, uint16_t tableIndex)
+{
+    struct mssIngressLutAddressControlRegister_t tableSelReg;
+    struct mssIngressLutControlRegister_t readWriteReg;
+
+    unsigned int i;
+
+    tableSelReg.bits_0.mssIngressLutSelect = tableID;
+    tableSelReg.bits_0.mssIngressLutAddress = tableIndex;
+
+    readWriteReg.bits_0.mssIngressLutRead = 1;
+    readWriteReg.bits_0.mssIngressLutWrite = 0;
+
+    mdioWrite(hw, MMD_GLOBAL, mssIngressLutAddressControlRegister_ADDR, tableSelReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssIngressLutControlRegister_ADDR, readWriteReg.word_0);
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * numWords);
+
+    for (i = 0; i < numWords; i += 2)
+    {
+        mdioRead(hw, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i, &packedRecVal[i]);
+        mdioRead(hw, MMD_GLOBAL, mssIngressLutDataControlRegister_ADDR + i + 1, &packedRecVal[i + 1]);
+    }
+
+    return 0;
+}
+
+static
+int SetRawSECEgressRecordVal(struct aq_hw_s *hw, uint16_t* packedRecVal, uint8_t numWords, uint8_t tableID, uint16_t tableIndex)
+{
+    struct mssEgressLutAddressControlRegister_t tableSelReg;
+    struct mssEgressLutControlRegister_t readWriteReg;
+
+    unsigned int i;
+
+    for (i = 0; i < numWords; i += 2)
+    {
+        mdioWrite(hw, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i, packedRecVal[i]);
+        mdioWrite(hw, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i + 1, packedRecVal[i + 1]);
+    }
+
+    for (i = numWords; i < 28; i += 2)
+    {
+        mdioWrite(hw, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i, 0);
+        mdioWrite(hw, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i + 1, 0);
+    }
+
+    tableSelReg.bits_0.mssEgressLutSelect = tableID;
+    tableSelReg.bits_0.mssEgressLutAddress = tableIndex;
+
+    readWriteReg.bits_0.mssEgressLutRead = 0;
+    readWriteReg.bits_0.mssEgressLutWrite = 1;
+
+    mdioWrite(hw, MMD_GLOBAL, mssEgressLutAddressControlRegister_ADDR, tableSelReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssEgressLutControlRegister_ADDR, readWriteReg.word_0);
+
+    return 0;
+}
+
+static
+int GetRawSECEgressRecordVal(struct aq_hw_s *hw, uint16_t* packedRecVal, uint8_t numWords, uint8_t tableID, uint16_t tableIndex)
+{
+    struct mssEgressLutAddressControlRegister_t tableSelReg;
+    struct mssEgressLutControlRegister_t readWriteReg;
+
+    unsigned int i;
+
+    tableSelReg.bits_0.mssEgressLutSelect = tableID;
+    tableSelReg.bits_0.mssEgressLutAddress = tableIndex;
+
+    readWriteReg.bits_0.mssEgressLutRead = 1;
+    readWriteReg.bits_0.mssEgressLutWrite = 0;
+
+    mdioWrite(hw, MMD_GLOBAL, mssEgressLutAddressControlRegister_ADDR, tableSelReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssEgressLutControlRegister_ADDR, readWriteReg.word_0);
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * numWords);
+
+    for (i = 0; i < numWords; i += 2)
+    {
+        mdioRead(hw, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i, &packedRecVal[i]);
+        mdioRead(hw, MMD_GLOBAL, mssEgressLutDataControlRegister_ADDR + i + 1, &packedRecVal[i + 1]);
+    }
+
+    return 0;
+}
+
+int AQ_API_SetIngressPreCTLFRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPreCTLFRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[6];
+
+    if (tableIndex >= NUMROWS_INGRESSPRECTLFRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 6);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->sa_da[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->sa_da[0] >> 16) & 0xFFFF) << 0);
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->sa_da[1] >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->eth_type >> 0) & 0xFFFF) << 0);
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->match_mask >> 0) & 0xFFFF) << 0);
+    packedRecVal[5] = (packedRecVal[5] & 0xFFF0) | (((rec->match_type >> 0) & 0xF) << 0);
+    packedRecVal[5] = (packedRecVal[5] & 0xFFEF) | (((rec->action >> 0) & 0x1) << 4);
+
+    SetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetIngressPreCTLFRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPreCTLFRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[6];
+
+    if (tableIndex >= NUMROWS_INGRESSPRECTLFRECORD)
+        return -EINVAL;
+
+    if ((tableIndex % 2) > 0)
+    {
+        GetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex - 1);
+    }
+
+    memset(rec, 0, sizeof(AQ_API_SEC_IngressPreCTLFRecord));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_INGRESSPRECTLFRECORD + tableIndex);
+
+    rec->sa_da[0] = (rec->sa_da[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->sa_da[0] = (rec->sa_da[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->sa_da[1] = (rec->sa_da[1] & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+
+    rec->eth_type = (rec->eth_type & 0xFFFF0000) | (((packedRecVal[3] >> 0) & 0xFFFF) << 0);
+
+    rec->match_mask = (rec->match_mask & 0xFFFF0000) | (((packedRecVal[4] >> 0) & 0xFFFF) << 0);
+
+    rec->match_type = (rec->match_type & 0xFFFFFFF0) | (((packedRecVal[5] >> 0) & 0xF) << 0);
+
+    rec->action = (rec->action & 0xFFFFFFFE) | (((packedRecVal[5] >> 4) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetIngressPreClassRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPreClassRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[20];
+
+    if (tableIndex >= NUMROWS_INGRESSPRECLASSRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 20);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->sci[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->sci[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->sci[1] >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->sci[1] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFF00) | (((rec->tci >> 0) & 0xFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x00FF) | (((rec->encr_offset >> 0) & 0xFF) << 8);
+
+    packedRecVal[5] = (packedRecVal[5] & 0x0000) | (((rec->eth_type >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0x0000) | (((rec->snap[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[7] = (packedRecVal[7] & 0x0000) | (((rec->snap[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[8] = (packedRecVal[8] & 0xFF00) | (((rec->snap[1] >> 0) & 0xFF) << 0);
+
+    packedRecVal[8] = (packedRecVal[8] & 0x00FF) | (((rec->llc >> 0) & 0xFF) << 8);
+    packedRecVal[9] = (packedRecVal[9] & 0x0000) | (((rec->llc >> 8) & 0xFFFF) << 0);
+
+    packedRecVal[10] = (packedRecVal[10] & 0x0000) | (((rec->mac_sa[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[11] = (packedRecVal[11] & 0x0000) | (((rec->mac_sa[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[12] = (packedRecVal[12] & 0x0000) | (((rec->mac_sa[1] >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[13] = (packedRecVal[13] & 0x0000) | (((rec->mac_da[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[14] = (packedRecVal[14] & 0x0000) | (((rec->mac_da[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[15] = (packedRecVal[15] & 0x0000) | (((rec->mac_da[1] >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[16] = (packedRecVal[16] & 0xFFFE) | (((rec->lpbk_packet >> 0) & 0x1) << 0);
+
+    packedRecVal[16] = (packedRecVal[16] & 0xFFF9) | (((rec->an_mask >> 0) & 0x3) << 1);
+
+    packedRecVal[16] = (packedRecVal[16] & 0xFE07) | (((rec->tci_mask >> 0) & 0x3F) << 3);
+
+    packedRecVal[16] = (packedRecVal[16] & 0x01FF) | (((rec->sci_mask >> 0) & 0x7F) << 9);
+    packedRecVal[17] = (packedRecVal[17] & 0xFFFE) | (((rec->sci_mask >> 7) & 0x1) << 0);
+
+    packedRecVal[17] = (packedRecVal[17] & 0xFFF9) | (((rec->eth_type_mask >> 0) & 0x3) << 1);
+
+    packedRecVal[17] = (packedRecVal[17] & 0xFF07) | (((rec->snap_mask >> 0) & 0x1F) << 3);
+
+    packedRecVal[17] = (packedRecVal[17] & 0xF8FF) | (((rec->llc_mask >> 0) & 0x7) << 8);
+
+    packedRecVal[17] = (packedRecVal[17] & 0xF7FF) | (((rec->_802_2_encapsulate >> 0) & 0x1) << 11);
+
+    packedRecVal[17] = (packedRecVal[17] & 0x0FFF) | (((rec->sa_mask >> 0) & 0xF) << 12);
+    packedRecVal[18] = (packedRecVal[18] & 0xFFFC) | (((rec->sa_mask >> 4) & 0x3) << 0);
+
+    packedRecVal[18] = (packedRecVal[18] & 0xFF03) | (((rec->da_mask >> 0) & 0x3F) << 2);
+
+    packedRecVal[18] = (packedRecVal[18] & 0xFEFF) | (((rec->lpbk_mask >> 0) & 0x1) << 8);
+
+    packedRecVal[18] = (packedRecVal[18] & 0xC1FF) | (((rec->sc_idx >> 0) & 0x1F) << 9);
+
+    packedRecVal[18] = (packedRecVal[18] & 0xBFFF) | (((rec->proc_dest >> 0) & 0x1) << 14);
+
+    packedRecVal[18] = (packedRecVal[18] & 0x7FFF) | (((rec->action >> 0) & 0x1) << 15);
+    packedRecVal[19] = (packedRecVal[19] & 0xFFFE) | (((rec->action >> 1) & 0x1) << 0);
+
+    packedRecVal[19] = (packedRecVal[19] & 0xFFFD) | (((rec->ctrl_unctrl >> 0) & 0x1) << 1);
+
+    packedRecVal[19] = (packedRecVal[19] & 0xFFFB) | (((rec->sci_from_table >> 0) & 0x1) << 2);
+
+    packedRecVal[19] = (packedRecVal[19] & 0xFF87) | (((rec->reserved >> 0) & 0xF) << 3);
+
+    packedRecVal[19] = (packedRecVal[19] & 0xFF7F) | (((rec->valid >> 0) & 0x1) << 7);
+
+    SetRawSECIngressRecordVal(hw, packedRecVal, 20, 1, ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetIngressPreClassRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPreClassRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[20];
+
+    if (tableIndex >= NUMROWS_INGRESSPRECLASSRECORD)
+        return -EINVAL;
+
+    if ((tableIndex % 2) > 0)
+    {
+        GetRawSECIngressRecordVal(hw, packedRecVal, 20, 1, 
+            ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex - 1);
+    }
+
+    memset(rec, 0, sizeof(AQ_API_SEC_IngressPreClassRecord));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 20, 1, ROWOFFSET_INGRESSPRECLASSRECORD + tableIndex);
+
+    rec->sci[0] = (rec->sci[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->sci[0] = (rec->sci[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->sci[1] = (rec->sci[1] & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+    rec->sci[1] = (rec->sci[1] & 0x0000FFFF) | (((packedRecVal[3] >> 0) & 0xFFFF) << 16);
+
+    rec->tci = (rec->tci & 0xFFFFFF00) | (((packedRecVal[4] >> 0) & 0xFF) << 0);
+
+    rec->encr_offset = (rec->encr_offset & 0xFFFFFF00) | (((packedRecVal[4] >> 8) & 0xFF) << 0);
+
+    rec->eth_type = (rec->eth_type & 0xFFFF0000) | (((packedRecVal[5] >> 0) & 0xFFFF) << 0);
+
+    rec->snap[0] = (rec->snap[0] & 0xFFFF0000) | (((packedRecVal[6] >> 0) & 0xFFFF) << 0);
+    rec->snap[0] = (rec->snap[0] & 0x0000FFFF) | (((packedRecVal[7] >> 0) & 0xFFFF) << 16);
+
+    rec->snap[1] = (rec->snap[1] & 0xFFFFFF00) | (((packedRecVal[8] >> 0) & 0xFF) << 0);
+
+    rec->llc = (rec->llc & 0xFFFFFF00) | (((packedRecVal[8] >> 8) & 0xFF) << 0);
+    rec->llc = (rec->llc & 0xFF0000FF) | (((packedRecVal[9] >> 0) & 0xFFFF) << 8);
+
+    rec->mac_sa[0] = (rec->mac_sa[0] & 0xFFFF0000) | (((packedRecVal[10] >> 0) & 0xFFFF) << 0);
+    rec->mac_sa[0] = (rec->mac_sa[0] & 0x0000FFFF) | (((packedRecVal[11] >> 0) & 0xFFFF) << 16);
+
+    rec->mac_sa[1] = (rec->mac_sa[1] & 0xFFFF0000) | (((packedRecVal[12] >> 0) & 0xFFFF) << 0);
+
+    rec->mac_da[0] = (rec->mac_da[0] & 0xFFFF0000) | (((packedRecVal[13] >> 0) & 0xFFFF) << 0);
+    rec->mac_da[0] = (rec->mac_da[0] & 0x0000FFFF) | (((packedRecVal[14] >> 0) & 0xFFFF) << 16);
+
+    rec->mac_da[1] = (rec->mac_da[1] & 0xFFFF0000) | (((packedRecVal[15] >> 0) & 0xFFFF) << 0);
+
+    rec->lpbk_packet = (rec->lpbk_packet & 0xFFFFFFFE) | (((packedRecVal[16] >> 0) & 0x1) << 0);
+
+    rec->an_mask = (rec->an_mask & 0xFFFFFFFC) | (((packedRecVal[16] >> 1) & 0x3) << 0);
+
+    rec->tci_mask = (rec->tci_mask & 0xFFFFFFC0) | (((packedRecVal[16] >> 3) & 0x3F) << 0);
+
+    rec->sci_mask = (rec->sci_mask & 0xFFFFFF80) | (((packedRecVal[16] >> 9) & 0x7F) << 0);
+    rec->sci_mask = (rec->sci_mask & 0xFFFFFF7F) | (((packedRecVal[17] >> 0) & 0x1) << 7);
+
+    rec->eth_type_mask = (rec->eth_type_mask & 0xFFFFFFFC) | (((packedRecVal[17] >> 1) & 0x3) << 0);
+
+    rec->snap_mask = (rec->snap_mask & 0xFFFFFFE0) | (((packedRecVal[17] >> 3) & 0x1F) << 0);
+
+    rec->llc_mask = (rec->llc_mask & 0xFFFFFFF8) | (((packedRecVal[17] >> 8) & 0x7) << 0);
+
+    rec->_802_2_encapsulate = (rec->_802_2_encapsulate & 0xFFFFFFFE) | (((packedRecVal[17] >> 11) & 0x1) << 0);
+
+    rec->sa_mask = (rec->sa_mask & 0xFFFFFFF0) | (((packedRecVal[17] >> 12) & 0xF) << 0);
+    rec->sa_mask = (rec->sa_mask & 0xFFFFFFCF) | (((packedRecVal[18] >> 0) & 0x3) << 4);
+
+    rec->da_mask = (rec->da_mask & 0xFFFFFFC0) | (((packedRecVal[18] >> 2) & 0x3F) << 0);
+
+    rec->lpbk_mask = (rec->lpbk_mask & 0xFFFFFFFE) | (((packedRecVal[18] >> 8) & 0x1) << 0);
+
+    rec->sc_idx = (rec->sc_idx & 0xFFFFFFE0) | (((packedRecVal[18] >> 9) & 0x1F) << 0);
+
+    rec->proc_dest = (rec->proc_dest & 0xFFFFFFFE) | (((packedRecVal[18] >> 14) & 0x1) << 0);
+
+    rec->action = (rec->action & 0xFFFFFFFE) | (((packedRecVal[18] >> 15) & 0x1) << 0);
+    rec->action = (rec->action & 0xFFFFFFFD) | (((packedRecVal[19] >> 0) & 0x1) << 1);
+
+    rec->ctrl_unctrl = (rec->ctrl_unctrl & 0xFFFFFFFE) | (((packedRecVal[19] >> 1) & 0x1) << 0);
+
+    rec->sci_from_table = (rec->sci_from_table & 0xFFFFFFFE) | (((packedRecVal[19] >> 2) & 0x1) << 0);
+
+    rec->reserved = (rec->reserved & 0xFFFFFFF0) | (((packedRecVal[19] >> 3) & 0xF) << 0);
+
+    rec->valid = (rec->valid & 0xFFFFFFFE) | (((packedRecVal[19] >> 7) & 0x1) << 0);
+
+    return 0;
+}
+
+
+int AQ_API_SetIngressSCRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressSCRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_INGRESSSCRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 8);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->stop_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->stop_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->start_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->start_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFFFC) | (((rec->validate_frames >> 0) & 0x3) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFFFB) | (((rec->replay_protect >> 0) & 0x1) << 2);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x0007) | (((rec->anti_replay_window >> 0) & 0x1FFF) << 3);
+    packedRecVal[5] = (packedRecVal[5] & 0x0000) | (((rec->anti_replay_window >> 13) & 0xFFFF) << 0);
+    packedRecVal[6] = (packedRecVal[6] & 0xFFF8) | (((rec->anti_replay_window >> 29) & 0x7) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFF7) | (((rec->receiving >> 0) & 0x1) << 3);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFEF) | (((rec->fresh >> 0) & 0x1) << 4);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFDF) | (((rec->an_rol >> 0) & 0x1) << 5);
+
+    packedRecVal[6] = (packedRecVal[6] & 0x003F) | (((rec->reserved >> 0) & 0x3FF) << 6);
+    packedRecVal[7] = (packedRecVal[7] & 0x8000) | (((rec->reserved >> 10) & 0x7FFF) << 0);
+
+    packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
+
+    SetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSCRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetIngressSCRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressSCRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_INGRESSSCRECORD)
+        return -EINVAL;
+
+    memset(rec, 0, sizeof(AQ_API_SEC_IngressSCRecord));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSCRECORD + tableIndex);
+
+    rec->stop_time = (rec->stop_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->stop_time = (rec->stop_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->start_time = (rec->start_time & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+    rec->start_time = (rec->start_time & 0x0000FFFF) | (((packedRecVal[3] >> 0) & 0xFFFF) << 16);
+
+    rec->validate_frames = (rec->validate_frames & 0xFFFFFFFC) | (((packedRecVal[4] >> 0) & 0x3) << 0);
+
+    rec->replay_protect = (rec->replay_protect & 0xFFFFFFFE) | (((packedRecVal[4] >> 2) & 0x1) << 0);
+
+    rec->anti_replay_window = (rec->anti_replay_window & 0xFFFFE000) | (((packedRecVal[4] >> 3) & 0x1FFF) << 0);
+    rec->anti_replay_window = (rec->anti_replay_window & 0xE0001FFF) | (((packedRecVal[5] >> 0) & 0xFFFF) << 13);
+    rec->anti_replay_window = (rec->anti_replay_window & 0x1FFFFFFF) | (((packedRecVal[6] >> 0) & 0x7) << 29);
+
+    rec->receiving = (rec->receiving & 0xFFFFFFFE) | (((packedRecVal[6] >> 3) & 0x1) << 0);
+
+    rec->fresh = (rec->fresh & 0xFFFFFFFE) | (((packedRecVal[6] >> 4) & 0x1) << 0);
+
+    rec->an_rol = (rec->an_rol & 0xFFFFFFFE) | (((packedRecVal[6] >> 5) & 0x1) << 0);
+
+    rec->reserved = (rec->reserved & 0xFFFFFC00) | (((packedRecVal[6] >> 6) & 0x3FF) << 0);
+    rec->reserved = (rec->reserved & 0xFE0003FF) | (((packedRecVal[7] >> 0) & 0x7FFF) << 10);
+
+    rec->valid = (rec->valid & 0xFFFFFFFE) | (((packedRecVal[7] >> 15) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetIngressSARecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressSARecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_INGRESSSARECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 8);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->stop_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->stop_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->start_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->start_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->next_pn >> 0) & 0xFFFF) << 0);
+    packedRecVal[5] = (packedRecVal[5] & 0x0000) | (((rec->next_pn >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFFE) | (((rec->sat_nextpn >> 0) & 0x1) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFFD) | (((rec->in_use >> 0) & 0x1) << 1);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFFB) | (((rec->fresh >> 0) & 0x1) << 2);
+
+    packedRecVal[6] = (packedRecVal[6] & 0x0007) | (((rec->reserved >> 0) & 0x1FFF) << 3);
+    packedRecVal[7] = (packedRecVal[7] & 0x8000) | (((rec->reserved >> 13) & 0x7FFF) << 0);
+
+    packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
+
+    SetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSARECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetIngressSARecord(struct aq_hw_s *hw, AQ_API_SEC_IngressSARecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_INGRESSSARECORD)
+        return -EINVAL;
+
+    memset(rec, 0, sizeof(AQ_API_SEC_IngressSARecord));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 8, 3, ROWOFFSET_INGRESSSARECORD + tableIndex);
+
+    rec->stop_time = (rec->stop_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->stop_time = (rec->stop_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->start_time = (rec->start_time & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+    rec->start_time = (rec->start_time & 0x0000FFFF) | (((packedRecVal[3] >> 0) & 0xFFFF) << 16);
+
+    rec->next_pn = (rec->next_pn & 0xFFFF0000) | (((packedRecVal[4] >> 0) & 0xFFFF) << 0);
+    rec->next_pn = (rec->next_pn & 0x0000FFFF) | (((packedRecVal[5] >> 0) & 0xFFFF) << 16);
+
+    rec->sat_nextpn = (rec->sat_nextpn & 0xFFFFFFFE) | (((packedRecVal[6] >> 0) & 0x1) << 0);
+
+    rec->in_use = (rec->in_use & 0xFFFFFFFE) | (((packedRecVal[6] >> 1) & 0x1) << 0);
+
+    rec->fresh = (rec->fresh & 0xFFFFFFFE) | (((packedRecVal[6] >> 2) & 0x1) << 0);
+
+    rec->reserved = (rec->reserved & 0xFFFFE000) | (((packedRecVal[6] >> 3) & 0x1FFF) << 0);
+    rec->reserved = (rec->reserved & 0xF0001FFF) | (((packedRecVal[7] >> 0) & 0x7FFF) << 13);
+
+    rec->valid = (rec->valid & 0xFFFFFFFE) | (((packedRecVal[7] >> 15) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetIngressSAKeyRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressSAKeyRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[18];
+
+    if (tableIndex >= NUMROWS_INGRESSSAKEYRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 18);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->key[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->key[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->key[1] >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->key[1] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->key[2] >> 0) & 0xFFFF) << 0);
+    packedRecVal[5] = (packedRecVal[5] & 0x0000) | (((rec->key[2] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0x0000) | (((rec->key[3] >> 0) & 0xFFFF) << 0);
+    packedRecVal[7] = (packedRecVal[7] & 0x0000) | (((rec->key[3] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[8] = (packedRecVal[8] & 0x0000) | (((rec->key[4] >> 0) & 0xFFFF) << 0);
+    packedRecVal[9] = (packedRecVal[9] & 0x0000) | (((rec->key[4] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[10] = (packedRecVal[10] & 0x0000) | (((rec->key[5] >> 0) & 0xFFFF) << 0);
+    packedRecVal[11] = (packedRecVal[11] & 0x0000) | (((rec->key[5] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[12] = (packedRecVal[12] & 0x0000) | (((rec->key[6] >> 0) & 0xFFFF) << 0);
+    packedRecVal[13] = (packedRecVal[13] & 0x0000) | (((rec->key[6] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[14] = (packedRecVal[14] & 0x0000) | (((rec->key[7] >> 0) & 0xFFFF) << 0);
+    packedRecVal[15] = (packedRecVal[15] & 0x0000) | (((rec->key[7] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[16] = (packedRecVal[16] & 0xFFFC) | (((rec->key_len >> 0) & 0x3) << 0);
+
+    SetRawSECIngressRecordVal(hw, packedRecVal, 18, 2, ROWOFFSET_INGRESSSAKEYRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetIngressSAKeyRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressSAKeyRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[18];
+
+    if (tableIndex >= NUMROWS_INGRESSSAKEYRECORD)
+        return -EINVAL;
+
+    memset(rec, 0, sizeof(AQ_API_SEC_IngressSAKeyRecord));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 18, 2, ROWOFFSET_INGRESSSAKEYRECORD + tableIndex);
+
+    rec->key[0] = (rec->key[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->key[0] = (rec->key[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->key[1] = (rec->key[1] & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+    rec->key[1] = (rec->key[1] & 0x0000FFFF) | (((packedRecVal[3] >> 0) & 0xFFFF) << 16);
+
+    rec->key[2] = (rec->key[2] & 0xFFFF0000) | (((packedRecVal[4] >> 0) & 0xFFFF) << 0);
+    rec->key[2] = (rec->key[2] & 0x0000FFFF) | (((packedRecVal[5] >> 0) & 0xFFFF) << 16);
+
+    rec->key[3] = (rec->key[3] & 0xFFFF0000) | (((packedRecVal[6] >> 0) & 0xFFFF) << 0);
+    rec->key[3] = (rec->key[3] & 0x0000FFFF) | (((packedRecVal[7] >> 0) & 0xFFFF) << 16);
+
+    rec->key[4] = (rec->key[4] & 0xFFFF0000) | (((packedRecVal[8] >> 0) & 0xFFFF) << 0);
+    rec->key[4] = (rec->key[4] & 0x0000FFFF) | (((packedRecVal[9] >> 0) & 0xFFFF) << 16);
+
+    rec->key[5] = (rec->key[5] & 0xFFFF0000) | (((packedRecVal[10] >> 0) & 0xFFFF) << 0);
+    rec->key[5] = (rec->key[5] & 0x0000FFFF) | (((packedRecVal[11] >> 0) & 0xFFFF) << 16);
+
+    rec->key[6] = (rec->key[6] & 0xFFFF0000) | (((packedRecVal[12] >> 0) & 0xFFFF) << 0);
+    rec->key[6] = (rec->key[6] & 0x0000FFFF) | (((packedRecVal[13] >> 0) & 0xFFFF) << 16);
+
+    rec->key[7] = (rec->key[7] & 0xFFFF0000) | (((packedRecVal[14] >> 0) & 0xFFFF) << 0);
+    rec->key[7] = (rec->key[7] & 0x0000FFFF) | (((packedRecVal[15] >> 0) & 0xFFFF) << 16);
+
+    rec->key_len = (rec->key_len & 0xFFFFFFFC) | (((packedRecVal[16] >> 0) & 0x3) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetIngressPostClassRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPostClassRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_INGRESSPOSTCLASSRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 8);
+
+    packedRecVal[0] = (packedRecVal[0] & 0xFF00) | (((rec->byte0 >> 0) & 0xFF) << 0);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x00FF) | (((rec->byte1 >> 0) & 0xFF) << 8);
+
+    packedRecVal[1] = (packedRecVal[1] & 0xFF00) | (((rec->byte2 >> 0) & 0xFF) << 0);
+
+    packedRecVal[1] = (packedRecVal[1] & 0x00FF) | (((rec->byte3 >> 0) & 0xFF) << 8);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->eth_type >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[3] = (packedRecVal[3] & 0xFFFE) | (((rec->eth_type_valid >> 0) & 0x1) << 0);
+
+    packedRecVal[3] = (packedRecVal[3] & 0xE001) | (((rec->vlan_id >> 0) & 0xFFF) << 1);
+
+    packedRecVal[3] = (packedRecVal[3] & 0x1FFF) | (((rec->vlan_up >> 0) & 0x7) << 13);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFFFE) | (((rec->vlan_valid >> 0) & 0x1) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFFC1) | (((rec->sai >> 0) & 0x1F) << 1);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFFBF) | (((rec->sai_hit >> 0) & 0x1) << 6);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xF87F) | (((rec->eth_type_mask >> 0) & 0xF) << 7);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x07FF) | (((rec->byte3_location >> 0) & 0x1F) << 11);
+    packedRecVal[5] = (packedRecVal[5] & 0xFFFE) | (((rec->byte3_location >> 5) & 0x1) << 0);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFF9) | (((rec->byte3_mask >> 0) & 0x3) << 1);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFE07) | (((rec->byte2_location >> 0) & 0x3F) << 3);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xF9FF) | (((rec->byte2_mask >> 0) & 0x3) << 9);
+
+    packedRecVal[5] = (packedRecVal[5] & 0x07FF) | (((rec->byte1_location >> 0) & 0x1F) << 11);
+    packedRecVal[6] = (packedRecVal[6] & 0xFFFE) | (((rec->byte1_location >> 5) & 0x1) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFF9) | (((rec->byte1_mask >> 0) & 0x3) << 1);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFE07) | (((rec->byte0_location >> 0) & 0x3F) << 3);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xF9FF) | (((rec->byte0_mask >> 0) & 0x3) << 9);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xE7FF) | (((rec->eth_type_valid_mask >> 0) & 0x3) << 11);
+
+    packedRecVal[6] = (packedRecVal[6] & 0x1FFF) | (((rec->vlan_id_mask >> 0) & 0x7) << 13);
+    packedRecVal[7] = (packedRecVal[7] & 0xFFFE) | (((rec->vlan_id_mask >> 3) & 0x1) << 0);
+
+    packedRecVal[7] = (packedRecVal[7] & 0xFFF9) | (((rec->vlan_up_mask >> 0) & 0x3) << 1);
+
+    packedRecVal[7] = (packedRecVal[7] & 0xFFE7) | (((rec->vlan_valid_mask >> 0) & 0x3) << 3);
+
+    packedRecVal[7] = (packedRecVal[7] & 0xFF9F) | (((rec->sai_mask >> 0) & 0x3) << 5);
+
+    packedRecVal[7] = (packedRecVal[7] & 0xFE7F) | (((rec->sai_hit_mask >> 0) & 0x3) << 7);
+
+    packedRecVal[7] = (packedRecVal[7] & 0xFDFF) | (((rec->firstlevel_actions >> 0) & 0x1) << 9);
+
+    packedRecVal[7] = (packedRecVal[7] & 0xFBFF) | (((rec->secondlevel_actions >> 0) & 0x1) << 10);
+
+    packedRecVal[7] = (packedRecVal[7] & 0x87FF) | (((rec->reserved >> 0) & 0xF) << 11);
+
+    packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
+
+    SetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetIngressPostClassRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPostClassRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_INGRESSPOSTCLASSRECORD)
+        return -EINVAL;
+
+    if ((tableIndex % 2) > 0)
+    {
+        GetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex - 1);
+    }
+
+    memset(rec, 0, sizeof(AQ_API_SEC_IngressPostClassRecord));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 8, 4, ROWOFFSET_INGRESSPOSTCLASSRECORD + tableIndex);
+
+    rec->byte0 = (rec->byte0 & 0xFFFFFF00) | (((packedRecVal[0] >> 0) & 0xFF) << 0);
+
+    rec->byte1 = (rec->byte1 & 0xFFFFFF00) | (((packedRecVal[0] >> 8) & 0xFF) << 0);
+
+    rec->byte2 = (rec->byte2 & 0xFFFFFF00) | (((packedRecVal[1] >> 0) & 0xFF) << 0);
+
+    rec->byte3 = (rec->byte3 & 0xFFFFFF00) | (((packedRecVal[1] >> 8) & 0xFF) << 0);
+
+    rec->eth_type = (rec->eth_type & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+
+    rec->eth_type_valid = (rec->eth_type_valid & 0xFFFFFFFE) | (((packedRecVal[3] >> 0) & 0x1) << 0);
+
+    rec->vlan_id = (rec->vlan_id & 0xFFFFF000) | (((packedRecVal[3] >> 1) & 0xFFF) << 0);
+
+    rec->vlan_up = (rec->vlan_up & 0xFFFFFFF8) | (((packedRecVal[3] >> 13) & 0x7) << 0);
+
+    rec->vlan_valid = (rec->vlan_valid & 0xFFFFFFFE) | (((packedRecVal[4] >> 0) & 0x1) << 0);
+
+    rec->sai = (rec->sai & 0xFFFFFFE0) | (((packedRecVal[4] >> 1) & 0x1F) << 0);
+
+    rec->sai_hit = (rec->sai_hit & 0xFFFFFFFE) | (((packedRecVal[4] >> 6) & 0x1) << 0);
+
+    rec->eth_type_mask = (rec->eth_type_mask & 0xFFFFFFF0) | (((packedRecVal[4] >> 7) & 0xF) << 0);
+
+    rec->byte3_location = (rec->byte3_location & 0xFFFFFFE0) | (((packedRecVal[4] >> 11) & 0x1F) << 0);
+    rec->byte3_location = (rec->byte3_location & 0xFFFFFFDF) | (((packedRecVal[5] >> 0) & 0x1) << 5);
+
+    rec->byte3_mask = (rec->byte3_mask & 0xFFFFFFFC) | (((packedRecVal[5] >> 1) & 0x3) << 0);
+
+    rec->byte2_location = (rec->byte2_location & 0xFFFFFFC0) | (((packedRecVal[5] >> 3) & 0x3F) << 0);
+
+    rec->byte2_mask = (rec->byte2_mask & 0xFFFFFFFC) | (((packedRecVal[5] >> 9) & 0x3) << 0);
+
+    rec->byte1_location = (rec->byte1_location & 0xFFFFFFE0) | (((packedRecVal[5] >> 11) & 0x1F) << 0);
+    rec->byte1_location = (rec->byte1_location & 0xFFFFFFDF) | (((packedRecVal[6] >> 0) & 0x1) << 5);
+
+    rec->byte1_mask = (rec->byte1_mask & 0xFFFFFFFC) | (((packedRecVal[6] >> 1) & 0x3) << 0);
+
+    rec->byte0_location = (rec->byte0_location & 0xFFFFFFC0) | (((packedRecVal[6] >> 3) & 0x3F) << 0);
+
+    rec->byte0_mask = (rec->byte0_mask & 0xFFFFFFFC) | (((packedRecVal[6] >> 9) & 0x3) << 0);
+
+    rec->eth_type_valid_mask = (rec->eth_type_valid_mask & 0xFFFFFFFC) | (((packedRecVal[6] >> 11) & 0x3) << 0);
+
+    rec->vlan_id_mask = (rec->vlan_id_mask & 0xFFFFFFF8) | (((packedRecVal[6] >> 13) & 0x7) << 0);
+    rec->vlan_id_mask = (rec->vlan_id_mask & 0xFFFFFFF7) | (((packedRecVal[7] >> 0) & 0x1) << 3);
+
+    rec->vlan_up_mask = (rec->vlan_up_mask & 0xFFFFFFFC) | (((packedRecVal[7] >> 1) & 0x3) << 0);
+
+    rec->vlan_valid_mask = (rec->vlan_valid_mask & 0xFFFFFFFC) | (((packedRecVal[7] >> 3) & 0x3) << 0);
+
+    rec->sai_mask = (rec->sai_mask & 0xFFFFFFFC) | (((packedRecVal[7] >> 5) & 0x3) << 0);
+
+    rec->sai_hit_mask = (rec->sai_hit_mask & 0xFFFFFFFC) | (((packedRecVal[7] >> 7) & 0x3) << 0);
+
+    rec->firstlevel_actions = (rec->firstlevel_actions & 0xFFFFFFFE) | (((packedRecVal[7] >> 9) & 0x1) << 0);
+
+    rec->secondlevel_actions = (rec->secondlevel_actions & 0xFFFFFFFE) | (((packedRecVal[7] >> 10) & 0x1) << 0);
+
+    rec->reserved = (rec->reserved & 0xFFFFFFF0) | (((packedRecVal[7] >> 11) & 0xF) << 0);
+
+    rec->valid = (rec->valid & 0xFFFFFFFE) | (((packedRecVal[7] >> 15) & 0x1) << 0);
+
+    return 0;
+}
+
+
+int AQ_API_SetIngressPostCTLFRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPostCTLFRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[6];
+
+    if (tableIndex >= NUMROWS_INGRESSPOSTCTLFRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 6);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->sa_da[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->sa_da[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->sa_da[1] >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->eth_type >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->match_mask >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFF0) | (((rec->match_type >> 0) & 0xF) << 0);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFEF) | (((rec->action >> 0) & 0x1) << 4);
+
+    SetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetIngressPostCTLFRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPostCTLFRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[6];
+
+    if (tableIndex >= NUMROWS_INGRESSPOSTCTLFRECORD)
+        return -EINVAL;
+
+    if ((tableIndex % 2) > 0)
+    {
+        GetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex - 1);
+    }
+
+    memset(rec, 0, sizeof(AQ_API_SEC_IngressPostCTLFRecord));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 6, 5, ROWOFFSET_INGRESSPOSTCTLFRECORD + tableIndex);
+
+    rec->sa_da[0] = (rec->sa_da[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->sa_da[0] = (rec->sa_da[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->sa_da[1] = (rec->sa_da[1] & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+
+    rec->eth_type = (rec->eth_type & 0xFFFF0000) | (((packedRecVal[3] >> 0) & 0xFFFF) << 0);
+
+    rec->match_mask = (rec->match_mask & 0xFFFF0000) | (((packedRecVal[4] >> 0) & 0xFFFF) << 0);
+
+    rec->match_type = (rec->match_type & 0xFFFFFFF0) | (((packedRecVal[5] >> 0) & 0xF) << 0);
+
+    rec->action = (rec->action & 0xFFFFFFFE) | (((packedRecVal[5] >> 4) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetEgressCTLFRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressCTLFRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[6];
+
+    if (tableIndex >= NUMROWS_EGRESSCTLFRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 6);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->sa_da[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->sa_da[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->sa_da[1] >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->eth_type >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->match_mask >> 0) & 0xFFFF) << 0);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFF0) | (((rec->match_type >> 0) & 0xF) << 0);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFEF) | (((rec->action >> 0) & 0x1) << 4);
+
+    SetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetEgressCTLFRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressCTLFRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[6];
+
+    if (tableIndex >= NUMROWS_EGRESSCTLFRECORD)
+        return -EINVAL;
+
+    if ((tableIndex % 2) > 0)
+    {
+        GetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex - 1);
+    }
+
+    memset(rec, 0, sizeof(AQ_API_SEC_EgressCTLFRecord));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 6, 0, ROWOFFSET_EGRESSCTLFRECORD + tableIndex);
+
+    rec->sa_da[0] = (rec->sa_da[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->sa_da[0] = (rec->sa_da[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->sa_da[1] = (rec->sa_da[1] & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+
+    rec->eth_type = (rec->eth_type & 0xFFFF0000) | (((packedRecVal[3] >> 0) & 0xFFFF) << 0);
+
+    rec->match_mask = (rec->match_mask & 0xFFFF0000) | (((packedRecVal[4] >> 0) & 0xFFFF) << 0);
+
+    rec->match_type = (rec->match_type & 0xFFFFFFF0) | (((packedRecVal[5] >> 0) & 0xF) << 0);
+
+    rec->action = (rec->action & 0xFFFFFFFE) | (((packedRecVal[5] >> 4) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetEgressClassRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressClassRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[28];
+
+    if (tableIndex >= NUMROWS_EGRESSCLASSRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 28);
+
+    packedRecVal[0] = (packedRecVal[0] & 0xF000) | (((rec->vlan_id >> 0) & 0xFFF) << 0);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x8FFF) | (((rec->vlan_up >> 0) & 0x7) << 12);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x7FFF) | (((rec->vlan_valid >> 0) & 0x1) << 15);
+
+    packedRecVal[1] = (packedRecVal[1] & 0xFF00) | (((rec->byte3 >> 0) & 0xFF) << 0);
+
+    packedRecVal[1] = (packedRecVal[1] & 0x00FF) | (((rec->byte2 >> 0) & 0xFF) << 8);
+
+    packedRecVal[2] = (packedRecVal[2] & 0xFF00) | (((rec->byte1 >> 0) & 0xFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x00FF) | (((rec->byte0 >> 0) & 0xFF) << 8);
+
+    packedRecVal[3] = (packedRecVal[3] & 0xFF00) | (((rec->tci >> 0) & 0xFF) << 0);
+
+    packedRecVal[3] = (packedRecVal[3] & 0x00FF) | (((rec->sci[0] >> 0) & 0xFF) << 8);
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->sci[0] >> 8) & 0xFFFF) << 0);
+    packedRecVal[5] = (packedRecVal[5] & 0xFF00) | (((rec->sci[0] >> 24) & 0xFF) << 0);
+
+    packedRecVal[5] = (packedRecVal[5] & 0x00FF) | (((rec->sci[1] >> 0) & 0xFF) << 8);
+    packedRecVal[6] = (packedRecVal[6] & 0x0000) | (((rec->sci[1] >> 8) & 0xFFFF) << 0);
+    packedRecVal[7] = (packedRecVal[7] & 0xFF00) | (((rec->sci[1] >> 24) & 0xFF) << 0);
+
+    packedRecVal[7] = (packedRecVal[7] & 0x00FF) | (((rec->eth_type >> 0) & 0xFF) << 8);
+    packedRecVal[8] = (packedRecVal[8] & 0xFF00) | (((rec->eth_type >> 8) & 0xFF) << 0);
+
+    packedRecVal[8] = (packedRecVal[8] & 0x00FF) | (((rec->snap[0] >> 0) & 0xFF) << 8);
+    packedRecVal[9] = (packedRecVal[9] & 0x0000) | (((rec->snap[0] >> 8) & 0xFFFF) << 0);
+    packedRecVal[10] = (packedRecVal[10] & 0xFF00) | (((rec->snap[0] >> 24) & 0xFF) << 0);
+
+    packedRecVal[10] = (packedRecVal[10] & 0x00FF) | (((rec->snap[1] >> 0) & 0xFF) << 8);
+
+    packedRecVal[11] = (packedRecVal[11] & 0x0000) | (((rec->llc >> 0) & 0xFFFF) << 0);
+    packedRecVal[12] = (packedRecVal[12] & 0xFF00) | (((rec->llc >> 16) & 0xFF) << 0);
+
+    packedRecVal[12] = (packedRecVal[12] & 0x00FF) | (((rec->mac_sa[0] >> 0) & 0xFF) << 8);
+    packedRecVal[13] = (packedRecVal[13] & 0x0000) | (((rec->mac_sa[0] >> 8) & 0xFFFF) << 0);
+    packedRecVal[14] = (packedRecVal[14] & 0xFF00) | (((rec->mac_sa[0] >> 24) & 0xFF) << 0);
+
+    packedRecVal[14] = (packedRecVal[14] & 0x00FF) | (((rec->mac_sa[1] >> 0) & 0xFF) << 8);
+    packedRecVal[15] = (packedRecVal[15] & 0xFF00) | (((rec->mac_sa[1] >> 8) & 0xFF) << 0);
+
+    packedRecVal[15] = (packedRecVal[15] & 0x00FF) | (((rec->mac_da[0] >> 0) & 0xFF) << 8);
+    packedRecVal[16] = (packedRecVal[16] & 0x0000) | (((rec->mac_da[0] >> 8) & 0xFFFF) << 0);
+    packedRecVal[17] = (packedRecVal[17] & 0xFF00) | (((rec->mac_da[0] >> 24) & 0xFF) << 0);
+
+    packedRecVal[17] = (packedRecVal[17] & 0x00FF) | (((rec->mac_da[1] >> 0) & 0xFF) << 8);
+    packedRecVal[18] = (packedRecVal[18] & 0xFF00) | (((rec->mac_da[1] >> 8) & 0xFF) << 0);
+
+    packedRecVal[18] = (packedRecVal[18] & 0x00FF) | (((rec->pn >> 0) & 0xFF) << 8);
+    packedRecVal[19] = (packedRecVal[19] & 0x0000) | (((rec->pn >> 8) & 0xFFFF) << 0);
+    packedRecVal[20] = (packedRecVal[20] & 0xFF00) | (((rec->pn >> 24) & 0xFF) << 0);
+
+    packedRecVal[20] = (packedRecVal[20] & 0xC0FF) | (((rec->byte3_location >> 0) & 0x3F) << 8);
+
+    packedRecVal[20] = (packedRecVal[20] & 0xBFFF) | (((rec->byte3_mask >> 0) & 0x1) << 14);
+
+    packedRecVal[20] = (packedRecVal[20] & 0x7FFF) | (((rec->byte2_location >> 0) & 0x1) << 15);
+    packedRecVal[21] = (packedRecVal[21] & 0xFFE0) | (((rec->byte2_location >> 1) & 0x1F) << 0);
+
+    packedRecVal[21] = (packedRecVal[21] & 0xFFDF) | (((rec->byte2_mask >> 0) & 0x1) << 5);
+
+    packedRecVal[21] = (packedRecVal[21] & 0xF03F) | (((rec->byte1_location >> 0) & 0x3F) << 6);
+
+    packedRecVal[21] = (packedRecVal[21] & 0xEFFF) | (((rec->byte1_mask >> 0) & 0x1) << 12);
+
+    packedRecVal[21] = (packedRecVal[21] & 0x1FFF) | (((rec->byte0_location >> 0) & 0x7) << 13);
+    packedRecVal[22] = (packedRecVal[22] & 0xFFF8) | (((rec->byte0_location >> 3) & 0x7) << 0);
+
+    packedRecVal[22] = (packedRecVal[22] & 0xFFF7) | (((rec->byte0_mask >> 0) & 0x1) << 3);
+
+    packedRecVal[22] = (packedRecVal[22] & 0xFFCF) | (((rec->vlan_id_mask >> 0) & 0x3) << 4);
+
+    packedRecVal[22] = (packedRecVal[22] & 0xFFBF) | (((rec->vlan_up_mask >> 0) & 0x1) << 6);
+
+    packedRecVal[22] = (packedRecVal[22] & 0xFF7F) | (((rec->vlan_valid_mask >> 0) & 0x1) << 7);
+
+    packedRecVal[22] = (packedRecVal[22] & 0x00FF) | (((rec->tci_mask >> 0) & 0xFF) << 8);
+
+    packedRecVal[23] = (packedRecVal[23] & 0xFF00) | (((rec->sci_mask >> 0) & 0xFF) << 0);
+
+    packedRecVal[23] = (packedRecVal[23] & 0xFCFF) | (((rec->eth_type_mask >> 0) & 0x3) << 8);
+
+    packedRecVal[23] = (packedRecVal[23] & 0x83FF) | (((rec->snap_mask >> 0) & 0x1F) << 10);
+
+    packedRecVal[23] = (packedRecVal[23] & 0x7FFF) | (((rec->llc_mask >> 0) & 0x1) << 15);
+    packedRecVal[24] = (packedRecVal[24] & 0xFFFC) | (((rec->llc_mask >> 1) & 0x3) << 0);
+
+    packedRecVal[24] = (packedRecVal[24] & 0xFF03) | (((rec->sa_mask >> 0) & 0x3F) << 2);
+
+    packedRecVal[24] = (packedRecVal[24] & 0xC0FF) | (((rec->da_mask >> 0) & 0x3F) << 8);
+
+    packedRecVal[24] = (packedRecVal[24] & 0x3FFF) | (((rec->pn_mask >> 0) & 0x3) << 14);
+    packedRecVal[25] = (packedRecVal[25] & 0xFFFC) | (((rec->pn_mask >> 2) & 0x3) << 0);
+
+    packedRecVal[25] = (packedRecVal[25] & 0xFFFB) | (((rec->eight02dot2 >> 0) & 0x1) << 2);
+
+    packedRecVal[25] = (packedRecVal[25] & 0xFFF7) | (((rec->tci_sc >> 0) & 0x1) << 3);
+
+    packedRecVal[25] = (packedRecVal[25] & 0xFFEF) | (((rec->tci_87543 >> 0) & 0x1) << 4);
+
+    packedRecVal[25] = (packedRecVal[25] & 0xFFDF) | (((rec->exp_sectag_en >> 0) & 0x1) << 5);
+
+    packedRecVal[25] = (packedRecVal[25] & 0xF83F) | (((rec->sc_idx >> 0) & 0x1F) << 6);
+
+    packedRecVal[25] = (packedRecVal[25] & 0xE7FF) | (((rec->sc_sa >> 0) & 0x3) << 11);
+
+    packedRecVal[25] = (packedRecVal[25] & 0xDFFF) | (((rec->debug >> 0) & 0x1) << 13);
+
+    packedRecVal[25] = (packedRecVal[25] & 0x3FFF) | (((rec->action >> 0) & 0x3) << 14);
+
+    packedRecVal[26] = (packedRecVal[26] & 0xFFF7) | (((rec->valid >> 0) & 0x1) << 3);
+
+    SetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetEgressClassRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressClassRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[28];
+
+    if (tableIndex >= NUMROWS_EGRESSCLASSRECORD)
+        return -EINVAL;
+
+    if ((tableIndex % 2) > 0) {
+        GetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex - 1);
+    }
+
+    memset(rec, 0, sizeof(AQ_API_SEC_EgressClassRecord));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 28, 1, ROWOFFSET_EGRESSCLASSRECORD + tableIndex);
+
+    rec->vlan_id = (rec->vlan_id & 0xFFFFF000) | (((packedRecVal[0] >> 0) & 0xFFF) << 0);
+
+    rec->vlan_up = (rec->vlan_up & 0xFFFFFFF8) | (((packedRecVal[0] >> 12) & 0x7) << 0);
+
+    rec->vlan_valid = (rec->vlan_valid & 0xFFFFFFFE) | (((packedRecVal[0] >> 15) & 0x1) << 0);
+
+    rec->byte3 = (rec->byte3 & 0xFFFFFF00) | (((packedRecVal[1] >> 0) & 0xFF) << 0);
+
+    rec->byte2 = (rec->byte2 & 0xFFFFFF00) | (((packedRecVal[1] >> 8) & 0xFF) << 0);
+
+    rec->byte1 = (rec->byte1 & 0xFFFFFF00) | (((packedRecVal[2] >> 0) & 0xFF) << 0);
+
+    rec->byte0 = (rec->byte0 & 0xFFFFFF00) | (((packedRecVal[2] >> 8) & 0xFF) << 0);
+
+    rec->tci = (rec->tci & 0xFFFFFF00) | (((packedRecVal[3] >> 0) & 0xFF) << 0);
+
+    rec->sci[0] = (rec->sci[0] & 0xFFFFFF00) | (((packedRecVal[3] >> 8) & 0xFF) << 0);
+    rec->sci[0] = (rec->sci[0] & 0xFF0000FF) | (((packedRecVal[4] >> 0) & 0xFFFF) << 8);
+    rec->sci[0] = (rec->sci[0] & 0x00FFFFFF) | (((packedRecVal[5] >> 0) & 0xFF) << 24);
+
+    rec->sci[1] = (rec->sci[1] & 0xFFFFFF00) | (((packedRecVal[5] >> 8) & 0xFF) << 0);
+    rec->sci[1] = (rec->sci[1] & 0xFF0000FF) | (((packedRecVal[6] >> 0) & 0xFFFF) << 8);
+    rec->sci[1] = (rec->sci[1] & 0x00FFFFFF) | (((packedRecVal[7] >> 0) & 0xFF) << 24);
+
+    rec->eth_type = (rec->eth_type & 0xFFFFFF00) | (((packedRecVal[7] >> 8) & 0xFF) << 0);
+    rec->eth_type = (rec->eth_type & 0xFFFF00FF) | (((packedRecVal[8] >> 0) & 0xFF) << 8);
+
+    rec->snap[0] = (rec->snap[0] & 0xFFFFFF00) | (((packedRecVal[8] >> 8) & 0xFF) << 0);
+    rec->snap[0] = (rec->snap[0] & 0xFF0000FF) | (((packedRecVal[9] >> 0) & 0xFFFF) << 8);
+    rec->snap[0] = (rec->snap[0] & 0x00FFFFFF) | (((packedRecVal[10] >> 0) & 0xFF) << 24);
+
+    rec->snap[1] = (rec->snap[1] & 0xFFFFFF00) | (((packedRecVal[10] >> 8) & 0xFF) << 0);
+
+    rec->llc = (rec->llc & 0xFFFF0000) | (((packedRecVal[11] >> 0) & 0xFFFF) << 0);
+    rec->llc = (rec->llc & 0xFF00FFFF) | (((packedRecVal[12] >> 0) & 0xFF) << 16);
+
+    rec->mac_sa[0] = (rec->mac_sa[0] & 0xFFFFFF00) | (((packedRecVal[12] >> 8) & 0xFF) << 0);
+    rec->mac_sa[0] = (rec->mac_sa[0] & 0xFF0000FF) | (((packedRecVal[13] >> 0) & 0xFFFF) << 8);
+    rec->mac_sa[0] = (rec->mac_sa[0] & 0x00FFFFFF) | (((packedRecVal[14] >> 0) & 0xFF) << 24);
+
+    rec->mac_sa[1] = (rec->mac_sa[1] & 0xFFFFFF00) | (((packedRecVal[14] >> 8) & 0xFF) << 0);
+    rec->mac_sa[1] = (rec->mac_sa[1] & 0xFFFF00FF) | (((packedRecVal[15] >> 0) & 0xFF) << 8);
+
+    rec->mac_da[0] = (rec->mac_da[0] & 0xFFFFFF00) | (((packedRecVal[15] >> 8) & 0xFF) << 0);
+    rec->mac_da[0] = (rec->mac_da[0] & 0xFF0000FF) | (((packedRecVal[16] >> 0) & 0xFFFF) << 8);
+    rec->mac_da[0] = (rec->mac_da[0] & 0x00FFFFFF) | (((packedRecVal[17] >> 0) & 0xFF) << 24);
+
+    rec->mac_da[1] = (rec->mac_da[1] & 0xFFFFFF00) | (((packedRecVal[17] >> 8) & 0xFF) << 0);
+    rec->mac_da[1] = (rec->mac_da[1] & 0xFFFF00FF) | (((packedRecVal[18] >> 0) & 0xFF) << 8);
+
+    rec->pn = (rec->pn & 0xFFFFFF00) | (((packedRecVal[18] >> 8) & 0xFF) << 0);
+    rec->pn = (rec->pn & 0xFF0000FF) | (((packedRecVal[19] >> 0) & 0xFFFF) << 8);
+    rec->pn = (rec->pn & 0x00FFFFFF) | (((packedRecVal[20] >> 0) & 0xFF) << 24);
+
+    rec->byte3_location = (rec->byte3_location & 0xFFFFFFC0) | (((packedRecVal[20] >> 8) & 0x3F) << 0);
+
+    rec->byte3_mask = (rec->byte3_mask & 0xFFFFFFFE) | (((packedRecVal[20] >> 14) & 0x1) << 0);
+
+    rec->byte2_location = (rec->byte2_location & 0xFFFFFFFE) | (((packedRecVal[20] >> 15) & 0x1) << 0);
+    rec->byte2_location = (rec->byte2_location & 0xFFFFFFC1) | (((packedRecVal[21] >> 0) & 0x1F) << 1);
+
+    rec->byte2_mask = (rec->byte2_mask & 0xFFFFFFFE) | (((packedRecVal[21] >> 5) & 0x1) << 0);
+
+    rec->byte1_location = (rec->byte1_location & 0xFFFFFFC0) | (((packedRecVal[21] >> 6) & 0x3F) << 0);
+
+    rec->byte1_mask = (rec->byte1_mask & 0xFFFFFFFE) | (((packedRecVal[21] >> 12) & 0x1) << 0);
+
+    rec->byte0_location = (rec->byte0_location & 0xFFFFFFF8) | (((packedRecVal[21] >> 13) & 0x7) << 0);
+    rec->byte0_location = (rec->byte0_location & 0xFFFFFFC7) | (((packedRecVal[22] >> 0) & 0x7) << 3);
+
+    rec->byte0_mask = (rec->byte0_mask & 0xFFFFFFFE) | (((packedRecVal[22] >> 3) & 0x1) << 0);
+
+    rec->vlan_id_mask = (rec->vlan_id_mask & 0xFFFFFFFC) | (((packedRecVal[22] >> 4) & 0x3) << 0);
+
+    rec->vlan_up_mask = (rec->vlan_up_mask & 0xFFFFFFFE) | (((packedRecVal[22] >> 6) & 0x1) << 0);
+
+    rec->vlan_valid_mask = (rec->vlan_valid_mask & 0xFFFFFFFE) | (((packedRecVal[22] >> 7) & 0x1) << 0);
+
+    rec->tci_mask = (rec->tci_mask & 0xFFFFFF00) | (((packedRecVal[22] >> 8) & 0xFF) << 0);
+
+    rec->sci_mask = (rec->sci_mask & 0xFFFFFF00) | (((packedRecVal[23] >> 0) & 0xFF) << 0);
+
+    rec->eth_type_mask = (rec->eth_type_mask & 0xFFFFFFFC) | (((packedRecVal[23] >> 8) & 0x3) << 0);
+
+    rec->snap_mask = (rec->snap_mask & 0xFFFFFFE0) | (((packedRecVal[23] >> 10) & 0x1F) << 0);
+
+    rec->llc_mask = (rec->llc_mask & 0xFFFFFFFE) | (((packedRecVal[23] >> 15) & 0x1) << 0);
+    rec->llc_mask = (rec->llc_mask & 0xFFFFFFF9) | (((packedRecVal[24] >> 0) & 0x3) << 1);
+
+    rec->sa_mask = (rec->sa_mask & 0xFFFFFFC0) | (((packedRecVal[24] >> 2) & 0x3F) << 0);
+
+    rec->da_mask = (rec->da_mask & 0xFFFFFFC0) | (((packedRecVal[24] >> 8) & 0x3F) << 0);
+
+    rec->pn_mask = (rec->pn_mask & 0xFFFFFFFC) | (((packedRecVal[24] >> 14) & 0x3) << 0);
+    rec->pn_mask = (rec->pn_mask & 0xFFFFFFF3) | (((packedRecVal[25] >> 0) & 0x3) << 2);
+
+    rec->eight02dot2 = (rec->eight02dot2 & 0xFFFFFFFE) | (((packedRecVal[25] >> 2) & 0x1) << 0);
+
+    rec->tci_sc = (rec->tci_sc & 0xFFFFFFFE) | (((packedRecVal[25] >> 3) & 0x1) << 0);
+
+    rec->tci_87543 = (rec->tci_87543 & 0xFFFFFFFE) | (((packedRecVal[25] >> 4) & 0x1) << 0);
+
+    rec->exp_sectag_en = (rec->exp_sectag_en & 0xFFFFFFFE) | (((packedRecVal[25] >> 5) & 0x1) << 0);
+
+    rec->sc_idx = (rec->sc_idx & 0xFFFFFFE0) | (((packedRecVal[25] >> 6) & 0x1F) << 0);
+
+    rec->sc_sa = (rec->sc_sa & 0xFFFFFFFC) | (((packedRecVal[25] >> 11) & 0x3) << 0);
+
+    rec->debug = (rec->debug & 0xFFFFFFFE) | (((packedRecVal[25] >> 13) & 0x1) << 0);
+
+    rec->action = (rec->action & 0xFFFFFFFC) | (((packedRecVal[25] >> 14) & 0x3) << 0);
+
+    rec->valid = (rec->valid & 0xFFFFFFFE) | (((packedRecVal[26] >> 3) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetEgressSCRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressSCRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_EGRESSSCRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 8);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->start_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->start_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->stop_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->stop_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFFFC) | (((rec->curr_an >> 0) & 0x3) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFFFB) | (((rec->an_roll >> 0) & 0x1) << 2);
+
+    packedRecVal[4] = (packedRecVal[4] & 0xFE07) | (((rec->tci >> 0) & 0x3F) << 3);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x01FF) | (((rec->enc_off >> 0) & 0x7F) << 9);
+    packedRecVal[5] = (packedRecVal[5] & 0xFFFE) | (((rec->enc_off >> 7) & 0x1) << 0);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFFD) | (((rec->protect >> 0) & 0x1) << 1);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFFB) | (((rec->recv >> 0) & 0x1) << 2);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFF7) | (((rec->fresh >> 0) & 0x1) << 3);
+
+    packedRecVal[5] = (packedRecVal[5] & 0xFFCF) | (((rec->sak_len >> 0) & 0x3) << 4);
+
+    packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
+
+    SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSCRECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetEgressSCRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressSCRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_EGRESSSCRECORD)
+        return -EINVAL;
+
+    memset(rec, 0, sizeof(AQ_API_SEC_EgressSCRecord));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSCRECORD + tableIndex);
+
+    rec->start_time = (rec->start_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->start_time = (rec->start_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->stop_time = (rec->stop_time & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+    rec->stop_time = (rec->stop_time & 0x0000FFFF) | (((packedRecVal[3] >> 0) & 0xFFFF) << 16);
+
+    rec->curr_an = (rec->curr_an & 0xFFFFFFFC) | (((packedRecVal[4] >> 0) & 0x3) << 0);
+
+    rec->an_roll = (rec->an_roll & 0xFFFFFFFE) | (((packedRecVal[4] >> 2) & 0x1) << 0);
+
+    rec->tci = (rec->tci & 0xFFFFFFC0) | (((packedRecVal[4] >> 3) & 0x3F) << 0);
+
+    rec->enc_off = (rec->enc_off & 0xFFFFFF80) | (((packedRecVal[4] >> 9) & 0x7F) << 0);
+    rec->enc_off = (rec->enc_off & 0xFFFFFF7F) | (((packedRecVal[5] >> 0) & 0x1) << 7);
+
+    rec->protect = (rec->protect & 0xFFFFFFFE) | (((packedRecVal[5] >> 1) & 0x1) << 0);
+
+    rec->recv = (rec->recv & 0xFFFFFFFE) | (((packedRecVal[5] >> 2) & 0x1) << 0);
+
+    rec->fresh = (rec->fresh & 0xFFFFFFFE) | (((packedRecVal[5] >> 3) & 0x1) << 0);
+
+    rec->sak_len = (rec->sak_len & 0xFFFFFFFC) | (((packedRecVal[5] >> 4) & 0x3) << 0);
+
+    rec->valid = (rec->valid & 0xFFFFFFFE) | (((packedRecVal[7] >> 15) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetEgressSARecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressSARecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_EGRESSSARECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 8);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->start_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->start_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->stop_time >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->stop_time >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->next_pn >> 0) & 0xFFFF) << 0);
+    packedRecVal[5] = (packedRecVal[5] & 0x0000) | (((rec->next_pn >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFFE) | (((rec->sat_pn >> 0) & 0x1) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0xFFFD) | (((rec->fresh >> 0) & 0x1) << 1);
+
+    packedRecVal[7] = (packedRecVal[7] & 0x7FFF) | (((rec->valid >> 0) & 0x1) << 15);
+
+    SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSARECORD + tableIndex);
+
+    return 0;
+}
+
+int AQ_API_GetEgressSARecord(struct aq_hw_s *hw, AQ_API_SEC_EgressSARecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[8];
+
+    if (tableIndex >= NUMROWS_EGRESSSARECORD)
+        return -EINVAL;
+
+    memset(rec, 0, sizeof(AQ_API_SEC_EgressSARecord));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSARECORD + tableIndex);
+
+    rec->start_time = (rec->start_time & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->start_time = (rec->start_time & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->stop_time = (rec->stop_time & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+    rec->stop_time = (rec->stop_time & 0x0000FFFF) | (((packedRecVal[3] >> 0) & 0xFFFF) << 16);
+
+    rec->next_pn = (rec->next_pn & 0xFFFF0000) | (((packedRecVal[4] >> 0) & 0xFFFF) << 0);
+    rec->next_pn = (rec->next_pn & 0x0000FFFF) | (((packedRecVal[5] >> 0) & 0xFFFF) << 16);
+
+    rec->sat_pn = (rec->sat_pn & 0xFFFFFFFE) | (((packedRecVal[6] >> 0) & 0x1) << 0);
+
+    rec->fresh = (rec->fresh & 0xFFFFFFFE) | (((packedRecVal[6] >> 1) & 0x1) << 0);
+
+    rec->valid = (rec->valid & 0xFFFFFFFE) | (((packedRecVal[7] >> 15) & 0x1) << 0);
+
+    return 0;
+}
+
+int AQ_API_SetEgressSAKeyRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressSAKeyRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[16];
+
+    if (tableIndex >= NUMROWS_EGRESSSAKEYRECORD)
+        return -EINVAL;
+
+    memset(packedRecVal, 0, sizeof(uint16_t) * 16);
+
+    packedRecVal[0] = (packedRecVal[0] & 0x0000) | (((rec->key[0] >> 0) & 0xFFFF) << 0);
+    packedRecVal[1] = (packedRecVal[1] & 0x0000) | (((rec->key[0] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[2] = (packedRecVal[2] & 0x0000) | (((rec->key[1] >> 0) & 0xFFFF) << 0);
+    packedRecVal[3] = (packedRecVal[3] & 0x0000) | (((rec->key[1] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[4] = (packedRecVal[4] & 0x0000) | (((rec->key[2] >> 0) & 0xFFFF) << 0);
+    packedRecVal[5] = (packedRecVal[5] & 0x0000) | (((rec->key[2] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[6] = (packedRecVal[6] & 0x0000) | (((rec->key[3] >> 0) & 0xFFFF) << 0);
+    packedRecVal[7] = (packedRecVal[7] & 0x0000) | (((rec->key[3] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[8] = (packedRecVal[8] & 0x0000) | (((rec->key[4] >> 0) & 0xFFFF) << 0);
+    packedRecVal[9] = (packedRecVal[9] & 0x0000) | (((rec->key[4] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[10] = (packedRecVal[10] & 0x0000) | (((rec->key[5] >> 0) & 0xFFFF) << 0);
+    packedRecVal[11] = (packedRecVal[11] & 0x0000) | (((rec->key[5] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[12] = (packedRecVal[12] & 0x0000) | (((rec->key[6] >> 0) & 0xFFFF) << 0);
+    packedRecVal[13] = (packedRecVal[13] & 0x0000) | (((rec->key[6] >> 16) & 0xFFFF) << 0);
+
+    packedRecVal[14] = (packedRecVal[14] & 0x0000) | (((rec->key[7] >> 0) & 0xFFFF) << 0);
+    packedRecVal[15] = (packedRecVal[15] & 0x0000) | (((rec->key[7] >> 16) & 0xFFFF) << 0);
+
+    SetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex);
+    SetRawSECEgressRecordVal(hw, packedRecVal + 8, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex - 32);
+
+    return 0;
+}
+
+int AQ_API_GetEgressSAKeyRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressSAKeyRecord* rec, uint16_t tableIndex)
+{
+    uint16_t packedRecVal[16];
+
+    if (tableIndex >= NUMROWS_EGRESSSAKEYRECORD)
+        return -EINVAL;
+
+    memset(rec, 0, sizeof(AQ_API_SEC_EgressSAKeyRecord));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex);
+    GetRawSECEgressRecordVal(hw, packedRecVal + 8, 8, 2, ROWOFFSET_EGRESSSAKEYRECORD + tableIndex - 32);
+
+    rec->key[0] = (rec->key[0] & 0xFFFF0000) | (((packedRecVal[0] >> 0) & 0xFFFF) << 0);
+    rec->key[0] = (rec->key[0] & 0x0000FFFF) | (((packedRecVal[1] >> 0) & 0xFFFF) << 16);
+
+    rec->key[1] = (rec->key[1] & 0xFFFF0000) | (((packedRecVal[2] >> 0) & 0xFFFF) << 0);
+    rec->key[1] = (rec->key[1] & 0x0000FFFF) | (((packedRecVal[3] >> 0) & 0xFFFF) << 16);
+
+    rec->key[2] = (rec->key[2] & 0xFFFF0000) | (((packedRecVal[4] >> 0) & 0xFFFF) << 0);
+    rec->key[2] = (rec->key[2] & 0x0000FFFF) | (((packedRecVal[5] >> 0) & 0xFFFF) << 16);
+
+    rec->key[3] = (rec->key[3] & 0xFFFF0000) | (((packedRecVal[6] >> 0) & 0xFFFF) << 0);
+    rec->key[3] = (rec->key[3] & 0x0000FFFF) | (((packedRecVal[7] >> 0) & 0xFFFF) << 16);
+
+    rec->key[4] = (rec->key[4] & 0xFFFF0000) | (((packedRecVal[8] >> 0) & 0xFFFF) << 0);
+    rec->key[4] = (rec->key[4] & 0x0000FFFF) | (((packedRecVal[9] >> 0) & 0xFFFF) << 16);
+
+    rec->key[5] = (rec->key[5] & 0xFFFF0000) | (((packedRecVal[10] >> 0) & 0xFFFF) << 0);
+    rec->key[5] = (rec->key[5] & 0x0000FFFF) | (((packedRecVal[11] >> 0) & 0xFFFF) << 16);
+
+    rec->key[6] = (rec->key[6] & 0xFFFF0000) | (((packedRecVal[12] >> 0) & 0xFFFF) << 0);
+    rec->key[6] = (rec->key[6] & 0x0000FFFF) | (((packedRecVal[13] >> 0) & 0xFFFF) << 16);
+
+    rec->key[7] = (rec->key[7] & 0xFFFF0000) | (((packedRecVal[14] >> 0) & 0xFFFF) << 0);
+    rec->key[7] = (rec->key[7] & 0x0000FFFF) | (((packedRecVal[15] >> 0) & 0xFFFF) << 16);
+
+    return 0;
+}
+
+int AQ_API_GetEgressSCCounters(struct aq_hw_s *hw, AQ_API_SEC_EgressSCCounters* counters, uint16_t SCIndex)
+{
+    uint16_t packedRecVal[4];
+
+    if (SCIndex >= NUMROWS_EGRESSSCRECORD)
+        return -EINVAL;
+
+    memset(counters, 0, sizeof(AQ_API_SEC_EgressSCCounters));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 4);
+    counters->sc_protected_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sc_protected_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 5);
+    counters->sc_encrypted_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sc_encrypted_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 6);
+    counters->sc_protected_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sc_protected_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SCIndex * 8 + 7);
+    counters->sc_encrypted_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sc_encrypted_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    return 0;
+}
+
+int AQ_API_GetEgressSACounters(struct aq_hw_s *hw, AQ_API_SEC_EgressSACounters* counters, uint16_t SAIndex)
+{
+    uint16_t packedRecVal[4];
+
+    if (SAIndex >= NUMROWS_EGRESSSARECORD)
+        return -EINVAL;
+
+    memset(counters, 0, sizeof(AQ_API_SEC_EgressSACounters));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 0);
+    counters->sa_hit_drop_redirect[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sa_hit_drop_redirect[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 1);
+    counters->sa_protected2_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sa_protected2_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 2);
+    counters->sa_protected_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sa_protected_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, SAIndex * 8 + 3);
+    counters->sa_encrypted_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->sa_encrypted_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    return 0;
+}
+
+int AQ_API_GetEgressCommonCounters(struct aq_hw_s *hw, AQ_API_SEC_EgressCommonCounters* counters)
+{
+    uint16_t packedRecVal[4];
+
+    memset(counters, 0, sizeof(AQ_API_SEC_EgressCommonCounters));
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 0);
+    counters->ctl_pkt[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ctl_pkt[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 1);
+    counters->unknown_sa_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unknown_sa_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 2);
+    counters->untagged_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->untagged_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 3);
+    counters->too_long[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->too_long[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 4);
+    counters->ecc_error_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ecc_error_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECEgressRecordVal(hw, packedRecVal, 4, 3, 256 + 5);
+    counters->unctrl_hit_drop_redir[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unctrl_hit_drop_redir[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    return 0;
+}
+
+int AQ_API_ClearEgressCounters(struct aq_hw_s *hw)
+{
+    struct mssEgressControlRegister_t controlReg;
+
+    memset(&controlReg, 0, sizeof(struct mssEgressControlRegister_t));
+
+    mdioRead(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR, &controlReg.word_0);
+    mdioRead(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, &controlReg.word_1);
+
+    controlReg.bits_0.mssEgressClearCounter = 0;
+
+    mdioWrite(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
+
+    controlReg.bits_0.mssEgressClearCounter = 1;
+
+    mdioWrite(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4, controlReg.word_1);
+
+    controlReg.bits_0.mssEgressClearCounter = 0;
+
+    mdioWrite(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR, controlReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssEgressControlRegister_ADDR + 4,  controlReg.word_1);
+
+    return 0;
+}
+
+int AQ_API_GetIngressSACounters(struct aq_hw_s *hw, AQ_API_SEC_IngressSACounters* counters, uint16_t SAIndex)
+{
+    uint16_t packedRecVal[4];
+
+    if (SAIndex >= NUMROWS_INGRESSSARECORD)
+        return -EINVAL;
+
+    memset(counters, 0, sizeof(AQ_API_SEC_IngressSACounters));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 0);
+    counters->untagged_hit_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->untagged_hit_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 1);
+    counters->ctrl_hit_drop_redir_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ctrl_hit_drop_redir_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 2);
+    counters->not_using_sa[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->not_using_sa[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 3);
+    counters->unused_sa[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unused_sa[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 4);
+    counters->not_valid_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->not_valid_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 5);
+    counters->invalid_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->invalid_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 6);
+    counters->ok_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ok_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 7);
+    counters->late_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->late_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 8);
+    counters->delayed_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->delayed_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 9);
+    counters->unchecked_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unchecked_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 10);
+    counters->validated_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->validated_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, SAIndex * 12 + 11);
+    counters->decrypted_octets[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->decrypted_octets[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    return 0;
+}
+
+int AQ_API_GetIngressCommonCounters(struct aq_hw_s *hw, AQ_API_SEC_IngressCommonCounters* counters)
+{
+    uint16_t packedRecVal[4];
+
+    memset(counters, 0, sizeof(AQ_API_SEC_IngressCommonCounters));
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 0);
+    counters->ctl_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ctl_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 1);
+    counters->tagged_miss_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->tagged_miss_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 2);
+    counters->untagged_miss_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->untagged_miss_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 3);
+    counters->notag_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->notag_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 4);
+    counters->untagged_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->untagged_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 5);
+    counters->bad_tag_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->bad_tag_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 6);
+    counters->no_sci_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->no_sci_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 7);
+    counters->unknown_sci_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unknown_sci_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 8);
+    counters->ctrl_prt_pass_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ctrl_prt_pass_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 9);
+    counters->unctrl_prt_pass_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unctrl_prt_pass_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 10);
+    counters->ctrl_prt_fail_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ctrl_prt_fail_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 11);
+    counters->unctrl_prt_fail_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unctrl_prt_fail_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 12);
+    counters->too_long_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->too_long_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 13);
+    counters->igpoc_ctl_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->igpoc_ctl_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 14);
+    counters->ecc_error_pkts[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->ecc_error_pkts[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    GetRawSECIngressRecordVal(hw, packedRecVal, 4, 6, 385 + 15);
+    counters->unctrl_hit_drop_redir[0] = packedRecVal[0] | (packedRecVal[1] << 16);
+    counters->unctrl_hit_drop_redir[1] = packedRecVal[2] | (packedRecVal[3] << 16);
+
+    return 0;
+}
+
+int AQ_API_ClearIngressCounters(struct aq_hw_s *hw)
+{
+    struct mssIngressControlRegister_t controlReg;
+
+    memset(&controlReg, 0, sizeof(struct mssIngressControlRegister_t));
+
+    mdioRead(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR, &controlReg.word_0);
+    mdioRead(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR +4, &controlReg.word_1);
+
+    controlReg.bits_0.mssIngressClearCount = 0;
+
+    mdioWrite(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
+
+    controlReg.bits_0.mssIngressClearCount = 1;
+
+    mdioWrite(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
+
+    controlReg.bits_0.mssIngressClearCount = 0;
+
+    mdioWrite(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR, controlReg.word_0);
+    mdioWrite(hw, MMD_GLOBAL, mssIngressControlRegister_ADDR + 4, controlReg.word_1);
+
+    return 0;
+}
+
+
diff --git a/drivers/net/atlantic/macsec/macsec_api.h b/drivers/net/atlantic/macsec/macsec_api.h
new file mode 100644
index 0000000..653c29c
--- /dev/null
+++ b/drivers/net/atlantic/macsec/macsec_api.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) */
+/* Copyright (C) 2014-2019 aQuantia Corporation. */
+
+#ifndef __MACSEC_API_H__
+#define __MACSEC_API_H__
+
+#include "../atl_types.h"
+#include "macsec_struct.h"
+
+
+#define NUMROWS_INGRESSPRECTLFRECORD 24
+#define ROWOFFSET_INGRESSPRECTLFRECORD 0
+
+#define NUMROWS_INGRESSPRECLASSRECORD 48
+#define ROWOFFSET_INGRESSPRECLASSRECORD 0
+
+#define NUMROWS_INGRESSPOSTCLASSRECORD 48
+#define ROWOFFSET_INGRESSPOSTCLASSRECORD 0
+
+#define NUMROWS_INGRESSSCRECORD 32
+#define ROWOFFSET_INGRESSSCRECORD 0
+ 
+#define NUMROWS_INGRESSSARECORD 32
+#define ROWOFFSET_INGRESSSARECORD 32
+
+#define NUMROWS_INGRESSSAKEYRECORD 32
+#define ROWOFFSET_INGRESSSAKEYRECORD 0
+
+#define NUMROWS_INGRESSPOSTCTLFRECORD 24
+#define ROWOFFSET_INGRESSPOSTCTLFRECORD 0
+
+#define NUMROWS_EGRESSCTLFRECORD 24
+#define ROWOFFSET_EGRESSCTLFRECORD 0
+
+#define NUMROWS_EGRESSCLASSRECORD 48
+#define ROWOFFSET_EGRESSCLASSRECORD 0
+
+#define NUMROWS_EGRESSSCRECORD 32
+#define ROWOFFSET_EGRESSSCRECORD 0
+
+#define NUMROWS_EGRESSSARECORD 32
+#define ROWOFFSET_EGRESSSARECORD 32
+
+#define NUMROWS_EGRESSSAKEYRECORD 32
+#define ROWOFFSET_EGRESSSAKEYRECORD 96
+
+int AQ_API_GetEgressCTLFRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressCTLFRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetEgressCTLFRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressCTLFRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetEgressClassRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressClassRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetEgressClassRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressClassRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetEgressSCRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressSCRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetEgressSCRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressSCRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetEgressSARecord(struct aq_hw_s *hw, AQ_API_SEC_EgressSARecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetEgressSARecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressSARecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetEgressSAKeyRecord(struct aq_hw_s *hw, AQ_API_SEC_EgressSAKeyRecord* rec, uint16_t tableIndex); 
+
+int AQ_API_SetEgressSAKeyRecord(struct aq_hw_s *hw, const AQ_API_SEC_EgressSAKeyRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetIngressPreCTLFRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPreCTLFRecord* rec, uint16_t);
+
+int AQ_API_SetIngressPreCTLFRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPreCTLFRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetIngressPreClassRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPreClassRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetIngressPreClassRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPreClassRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetIngressSCRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressSCRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetIngressSCRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressSCRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetIngressSARecord(struct aq_hw_s *hw, AQ_API_SEC_IngressSARecord* rec, uint16_t);
+
+int AQ_API_SetIngressSARecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressSARecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetIngressSAKeyRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressSAKeyRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetIngressSAKeyRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressSAKeyRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetIngressPostClassRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPostClassRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetIngressPostClassRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPostClassRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetIngressPostCTLFRecord(struct aq_hw_s *hw, AQ_API_SEC_IngressPostCTLFRecord* rec, uint16_t tableIndex);
+
+int AQ_API_SetIngressPostCTLFRecord(struct aq_hw_s *hw, const AQ_API_SEC_IngressPostCTLFRecord* rec, uint16_t tableIndex);
+
+int AQ_API_GetEgressSCCounters(struct aq_hw_s *hw, AQ_API_SEC_EgressSCCounters* counters, uint16_t SCIndex);
+
+int AQ_API_GetEgressSACounters(struct aq_hw_s *hw, AQ_API_SEC_EgressSACounters* counters, uint16_t SAindex);
+
+int AQ_API_GetEgressCommonCounters(struct aq_hw_s *hw, AQ_API_SEC_EgressCommonCounters* counters);
+
+int AQ_API_ClearEgressCounters(struct aq_hw_s *hw);
+
+int AQ_API_GetIngressSACounters(struct aq_hw_s *hw, AQ_API_SEC_IngressSACounters* counters, uint16_t SAindex);
+
+int AQ_API_GetIngressCommonCounters(struct aq_hw_s *hw, AQ_API_SEC_IngressCommonCounters* counters);
+int AQ_API_ClearIngressCounters(struct aq_hw_s *hw);
+
+
+
+
+#endif /* __MACSEC_API_H__ */
diff --git a/drivers/net/atlantic/macsec/macsec_struct.h b/drivers/net/atlantic/macsec/macsec_struct.h
new file mode 100644
index 0000000..b408fdf
--- /dev/null
+++ b/drivers/net/atlantic/macsec/macsec_struct.h
@@ -0,0 +1,269 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) */
+/* Copyright (C) 2014-2019 aQuantia Corporation. */
+
+#ifndef _MACSEC_STRUCT_H_
+#define _MACSEC_STRUCT_H_
+
+typedef struct
+{
+	uint32_t sa_da[2];
+	uint32_t eth_type;
+	uint32_t match_mask;
+	uint32_t match_type;
+	uint32_t action;
+} AQ_API_SEC_EgressCTLFRecord;
+
+typedef struct
+{
+	uint32_t vlan_id;
+	uint32_t vlan_up;
+	uint32_t vlan_valid;
+	uint32_t byte3;
+	uint32_t byte2;
+	uint32_t byte1;
+	uint32_t byte0;
+	uint32_t tci;
+	uint32_t sci[2];
+	uint32_t eth_type;
+	uint32_t snap[2];
+	uint32_t llc;
+	uint32_t mac_sa[2];
+	uint32_t mac_da[2];
+	uint32_t pn;
+	uint32_t byte3_location;
+	uint32_t byte3_mask;
+	uint32_t byte2_location;
+	uint32_t byte2_mask;
+	uint32_t byte1_location;
+	uint32_t byte1_mask;
+	uint32_t byte0_location;
+	uint32_t byte0_mask;
+	uint32_t vlan_id_mask;
+	uint32_t vlan_up_mask;
+	uint32_t vlan_valid_mask;
+	uint32_t tci_mask;
+	uint32_t sci_mask;
+	uint32_t eth_type_mask;
+	uint32_t snap_mask;
+	uint32_t llc_mask;
+	uint32_t sa_mask;
+	uint32_t da_mask;
+	uint32_t pn_mask;
+	uint32_t eight02dot2;
+	uint32_t tci_sc;
+	uint32_t tci_87543;
+	uint32_t exp_sectag_en;
+	uint32_t sc_idx;
+	uint32_t sc_sa;
+	uint32_t debug;
+	uint32_t action;
+	uint32_t valid;
+} AQ_API_SEC_EgressClassRecord;
+
+typedef struct
+{
+	uint32_t start_time;
+	uint32_t stop_time;
+	uint32_t curr_an;
+	uint32_t an_roll;
+	uint32_t tci;
+	uint32_t enc_off;
+	uint32_t protect;
+	uint32_t recv;
+	uint32_t fresh;
+	uint32_t sak_len;
+	uint32_t valid;
+} AQ_API_SEC_EgressSCRecord;
+
+typedef struct
+{
+	uint32_t start_time;
+	uint32_t stop_time;
+	uint32_t next_pn;
+	uint32_t sat_pn;
+	uint32_t fresh;
+	uint32_t valid;
+} AQ_API_SEC_EgressSARecord;
+
+typedef struct
+{
+	uint32_t key[8];
+} AQ_API_SEC_EgressSAKeyRecord;
+
+typedef struct
+{
+	uint32_t sa_da[2];
+	uint32_t eth_type;
+	uint32_t match_mask;
+	uint32_t match_type;
+	uint32_t action;
+} AQ_API_SEC_IngressPreCTLFRecord;
+
+typedef struct
+{
+	uint32_t sci[2];
+	uint32_t tci;
+	uint32_t encr_offset;
+	uint32_t eth_type;
+	uint32_t snap[2];
+	uint32_t llc;
+	uint32_t mac_sa[2];
+	uint32_t mac_da[2];
+	uint32_t lpbk_packet;
+	uint32_t an_mask;
+	uint32_t tci_mask;
+	uint32_t sci_mask;
+	uint32_t eth_type_mask;
+	uint32_t snap_mask;
+	uint32_t llc_mask;
+	uint32_t _802_2_encapsulate;
+	uint32_t sa_mask;
+	uint32_t da_mask;
+	uint32_t lpbk_mask;
+	uint32_t sc_idx;
+	uint32_t proc_dest;
+	uint32_t action;
+	uint32_t ctrl_unctrl;
+	uint32_t sci_from_table;
+	uint32_t reserved;
+	uint32_t valid;
+} AQ_API_SEC_IngressPreClassRecord;
+
+typedef struct
+{
+	uint32_t stop_time;
+	uint32_t start_time;
+	uint32_t validate_frames;
+	uint32_t replay_protect;
+	uint32_t anti_replay_window;
+	uint32_t receiving;
+	uint32_t fresh;
+	uint32_t an_rol;
+	uint32_t reserved;
+	uint32_t valid;
+} AQ_API_SEC_IngressSCRecord;
+
+typedef struct
+{
+	uint32_t stop_time;
+	uint32_t start_time;
+	uint32_t next_pn;
+	uint32_t sat_nextpn;
+	uint32_t in_use;
+	uint32_t fresh;
+	uint32_t reserved;
+	uint32_t valid;
+} AQ_API_SEC_IngressSARecord;
+
+typedef struct
+{
+	uint32_t key[8];
+	uint32_t key_len;
+} AQ_API_SEC_IngressSAKeyRecord;
+
+typedef struct
+{
+	uint32_t byte0;
+	uint32_t byte1;
+	uint32_t byte2;
+	uint32_t byte3;
+	uint32_t eth_type;
+	uint32_t eth_type_valid;
+	uint32_t vlan_id;
+	uint32_t vlan_up;
+	uint32_t vlan_valid;
+	uint32_t sai;
+	uint32_t sai_hit;
+	uint32_t eth_type_mask;
+	uint32_t byte3_location;
+	uint32_t byte3_mask;
+	uint32_t byte2_location;
+	uint32_t byte2_mask;
+	uint32_t byte1_location;
+	uint32_t byte1_mask;
+	uint32_t byte0_location;
+	uint32_t byte0_mask;
+	uint32_t eth_type_valid_mask;
+	uint32_t vlan_id_mask;
+	uint32_t vlan_up_mask;
+	uint32_t vlan_valid_mask;
+	uint32_t sai_mask;
+	uint32_t sai_hit_mask;
+	uint32_t firstlevel_actions;
+	uint32_t secondlevel_actions;
+	uint32_t reserved;
+	uint32_t valid;
+} AQ_API_SEC_IngressPostClassRecord;
+
+typedef struct
+{
+	uint32_t sa_da[2];
+	uint32_t eth_type;
+	uint32_t match_mask;
+	uint32_t match_type;
+	uint32_t action;
+} AQ_API_SEC_IngressPostCTLFRecord;
+
+typedef struct
+{
+	uint32_t sc_protected_pkts[2];
+	uint32_t sc_encrypted_pkts[2];
+	uint32_t sc_protected_octets[2];
+	uint32_t sc_encrypted_octets[2];
+} AQ_API_SEC_EgressSCCounters;
+
+typedef struct
+{
+	uint32_t sa_hit_drop_redirect[2];
+	uint32_t sa_protected2_pkts[2];
+	uint32_t sa_protected_pkts[2];
+	uint32_t sa_encrypted_pkts[2];
+} AQ_API_SEC_EgressSACounters;
+
+typedef struct
+{
+	uint32_t ctl_pkt[2];
+	uint32_t unknown_sa_pkts[2];
+	uint32_t untagged_pkts[2];
+	uint32_t too_long[2];
+	uint32_t ecc_error_pkts[2];
+	uint32_t unctrl_hit_drop_redir[2];
+} AQ_API_SEC_EgressCommonCounters;
+
+typedef struct
+{
+	uint32_t untagged_hit_pkts[2];
+	uint32_t ctrl_hit_drop_redir_pkts[2];
+	uint32_t not_using_sa[2];
+	uint32_t unused_sa[2];
+	uint32_t not_valid_pkts[2];
+	uint32_t invalid_pkts[2];
+	uint32_t ok_pkts[2];
+	uint32_t late_pkts[2];
+	uint32_t delayed_pkts[2];
+	uint32_t unchecked_pkts[2];
+	uint32_t validated_octets[2];
+	uint32_t decrypted_octets[2];
+} AQ_API_SEC_IngressSACounters;
+
+typedef struct
+{
+	uint32_t ctl_pkts[2];
+	uint32_t tagged_miss_pkts[2];
+	uint32_t untagged_miss_pkts[2];
+	uint32_t notag_pkts[2];
+	uint32_t untagged_pkts[2];
+	uint32_t bad_tag_pkts[2];
+	uint32_t no_sci_pkts[2];
+	uint32_t unknown_sci_pkts[2];
+	uint32_t ctrl_prt_pass_pkts[2];
+	uint32_t unctrl_prt_pass_pkts[2];
+	uint32_t ctrl_prt_fail_pkts[2];
+	uint32_t unctrl_prt_fail_pkts[2];
+	uint32_t too_long_pkts[2];
+	uint32_t igpoc_ctl_pkts[2];
+	uint32_t ecc_error_pkts[2];
+	uint32_t unctrl_hit_drop_redir[2];
+} AQ_API_SEC_IngressCommonCounters;
+
+#endif
diff --git a/drivers/net/atlantic/meson.build b/drivers/net/atlantic/meson.build
index d1c66f4..139cdec 100644
--- a/drivers/net/atlantic/meson.build
+++ b/drivers/net/atlantic/meson.build
@@ -13,4 +13,5 @@ sources = files(
 	'hw_atl/hw_atl_utils.c',
 	'rte_pmd_atlantic.c',
 	'macsec/mdio.c',
+	'macsec/macsec_api.c',
 )
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [RFC v2 5/7] net/atlantic: implementation of the MACSEC using rte_security interface
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
                   ` (3 preceding siblings ...)
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 4/7] net/atlantic: add MACSEC internal HW data declaration and functions Pavel Belous
@ 2019-10-25 17:54 ` Pavel Belous
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands " Pavel Belous
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:54 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
---
 drivers/net/atlantic/Makefile                     |   2 +-
 drivers/net/atlantic/atl_ethdev.c                 | 316 ++---------
 drivers/net/atlantic/atl_sec.c                    | 615 ++++++++++++++++++++++
 drivers/net/atlantic/atl_sec.h                    | 124 +++++
 drivers/net/atlantic/hw_atl/hw_atl_utils.h        | 116 +---
 drivers/net/atlantic/meson.build                  |   4 +-
 drivers/net/atlantic/rte_pmd_atlantic.c           | 102 ----
 drivers/net/atlantic/rte_pmd_atlantic.h           | 144 -----
 drivers/net/atlantic/rte_pmd_atlantic_version.map |  16 -
 9 files changed, 802 insertions(+), 637 deletions(-)
 create mode 100644 drivers/net/atlantic/atl_sec.c
 create mode 100644 drivers/net/atlantic/atl_sec.h
 delete mode 100644 drivers/net/atlantic/rte_pmd_atlantic.c
 delete mode 100644 drivers/net/atlantic/rte_pmd_atlantic.h
 delete mode 100644 drivers/net/atlantic/rte_pmd_atlantic_version.map

diff --git a/drivers/net/atlantic/Makefile b/drivers/net/atlantic/Makefile
index 966676b..7aef5a1 100644
--- a/drivers/net/atlantic/Makefile
+++ b/drivers/net/atlantic/Makefile
@@ -33,8 +33,8 @@ SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_utils.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_llh.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_utils_fw2x.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_b0.c
-SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += rte_pmd_atlantic.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += mdio.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += macsec_api.c
+SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += atl_sec.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index b2b3bd3..13b017d 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -13,6 +13,8 @@
 #include "hw_atl/hw_atl_llh.h"
 #include "hw_atl/hw_atl_b0.h"
 #include "hw_atl/hw_atl_b0_internal.h"
+#include "atl_sec.h"
+
 
 static int eth_atl_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_atl_dev_uninit(struct rte_eth_dev *eth_dev);
@@ -119,6 +121,7 @@ static int eth_atl_pci_remove(struct rte_pci_device *pci_dev);
 
 static int atl_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static int atl_macsec_ctx_create(struct rte_eth_dev *dev);
 
 int atl_logtype_init;
 int atl_logtype_driver;
@@ -204,7 +207,7 @@ enum atl_xstats_type {
 
 #define ATL_MACSEC_XSTATS_FIELD(name) { \
 	#name, \
-	offsetof(struct macsec_stats, name), \
+	offsetof(struct atl_macsec_stats, name), \
 	XSTATS_TYPE_MACSEC \
 }
 
@@ -238,13 +241,19 @@ static struct atl_xstats_tbl_s atl_xstats_tbl[] = {
 	ATL_MACSEC_XSTATS_FIELD(in_bad_tag_pkts),
 	ATL_MACSEC_XSTATS_FIELD(in_no_sci_pkts),
 	ATL_MACSEC_XSTATS_FIELD(in_unknown_sci_pkts),
+
+	ATL_MACSEC_XSTATS_FIELD(in_ecc_error_pkts),
+	ATL_MACSEC_XSTATS_FIELD(in_unctrl_hit_drop_redir),
 	/* Ingress SA Counters */
 	ATL_MACSEC_XSTATS_FIELD(in_untagged_hit_pkts),
+	ATL_MACSEC_XSTATS_FIELD(in_ctrl_hit_drop_redir_pkts),
 	ATL_MACSEC_XSTATS_FIELD(in_not_using_sa),
 	ATL_MACSEC_XSTATS_FIELD(in_unused_sa),
 	ATL_MACSEC_XSTATS_FIELD(in_not_valid_pkts),
 	ATL_MACSEC_XSTATS_FIELD(in_invalid_pkts),
 	ATL_MACSEC_XSTATS_FIELD(in_ok_pkts),
+	ATL_MACSEC_XSTATS_FIELD(in_late_pkts),
+	ATL_MACSEC_XSTATS_FIELD(in_delayed_pkts),
 	ATL_MACSEC_XSTATS_FIELD(in_unchecked_pkts),
 	ATL_MACSEC_XSTATS_FIELD(in_validated_octets),
 	ATL_MACSEC_XSTATS_FIELD(in_decrypted_octets),
@@ -409,6 +418,12 @@ eth_atl_dev_init(struct rte_eth_dev *eth_dev)
 
 	pthread_mutex_init(&hw->mbox_mutex, NULL);
 
+#ifdef RTE_LIBRTE_SECURITY
+	/* Initialize security_ctx only for primary process*/
+	if (atl_macsec_ctx_create(eth_dev))
+		return -ENOMEM;
+#endif
+
 	/* disable interrupt */
 	atl_disable_intr(hw);
 
@@ -473,6 +488,10 @@ eth_atl_dev_uninit(struct rte_eth_dev *eth_dev)
 	rte_free(eth_dev->data->mac_addrs);
 	eth_dev->data->mac_addrs = NULL;
 
+#ifdef RTE_LIBRTE_SECURITY
+	rte_free(eth_dev->security_ctx);
+#endif
+
 	pthread_mutex_destroy(&hw->mbox_mutex);
 
 	return 0;
@@ -746,208 +765,6 @@ atl_dev_reset(struct rte_eth_dev *dev)
 }
 
 static int
-atl_dev_configure_macsec(struct rte_eth_dev *dev)
-{
-	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct aq_hw_cfg_s *cf = ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
-	struct aq_macsec_config *aqcfg = &cf->aq_macsec;
-	struct macsec_msg_fw_request msg_macsec;
-	struct macsec_msg_fw_response response;
-
-	if (!aqcfg->common.macsec_enabled ||
-	    hw->aq_fw_ops->send_macsec_req == NULL)
-		return 0;
-
-	memset(&msg_macsec, 0, sizeof(msg_macsec));
-
-	/* Creating set of sc/sa structures from parameters provided by DPDK */
-
-	/* Configure macsec */
-	msg_macsec.msg_type = macsec_cfg_msg;
-	msg_macsec.cfg.enabled = aqcfg->common.macsec_enabled;
-	msg_macsec.cfg.interrupts_enabled = 1;
-
-	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
-
-	if (response.result)
-		return -1;
-
-	memset(&msg_macsec, 0, sizeof(msg_macsec));
-
-	/* Configure TX SC */
-
-	msg_macsec.msg_type = macsec_add_tx_sc_msg;
-	msg_macsec.txsc.index = 0; /* TXSC always one (??) */
-	msg_macsec.txsc.protect = aqcfg->common.encryption_enabled;
-
-	/* MAC addr for TX */
-	msg_macsec.txsc.mac_sa[0] = rte_bswap32(aqcfg->txsc.mac[1]);
-	msg_macsec.txsc.mac_sa[1] = rte_bswap32(aqcfg->txsc.mac[0]);
-	msg_macsec.txsc.sa_mask = 0x3f;
-
-	msg_macsec.txsc.da_mask = 0;
-	msg_macsec.txsc.tci = 0x0B;
-	msg_macsec.txsc.curr_an = 0; /* SA index which currently used */
-
-	/*
-	 * Creating SCI (Secure Channel Identifier).
-	 * SCI constructed from Source MAC and Port identifier
-	 */
-	uint32_t sci_hi_part = (msg_macsec.txsc.mac_sa[1] << 16) |
-			       (msg_macsec.txsc.mac_sa[0] >> 16);
-	uint32_t sci_low_part = (msg_macsec.txsc.mac_sa[0] << 16);
-
-	uint32_t port_identifier = 1;
-
-	msg_macsec.txsc.sci[1] = sci_hi_part;
-	msg_macsec.txsc.sci[0] = sci_low_part | port_identifier;
-
-	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
-
-	if (response.result)
-		return -1;
-
-	memset(&msg_macsec, 0, sizeof(msg_macsec));
-
-	/* Configure RX SC */
-
-	msg_macsec.msg_type = macsec_add_rx_sc_msg;
-	msg_macsec.rxsc.index = aqcfg->rxsc.pi;
-	msg_macsec.rxsc.replay_protect =
-		aqcfg->common.replay_protection_enabled;
-	msg_macsec.rxsc.anti_replay_window = 0;
-
-	/* MAC addr for RX */
-	msg_macsec.rxsc.mac_da[0] = rte_bswap32(aqcfg->rxsc.mac[1]);
-	msg_macsec.rxsc.mac_da[1] = rte_bswap32(aqcfg->rxsc.mac[0]);
-	msg_macsec.rxsc.da_mask = 0;//0x3f;
-
-	msg_macsec.rxsc.sa_mask = 0;
-
-	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
-
-	if (response.result)
-		return -1;
-
-	memset(&msg_macsec, 0, sizeof(msg_macsec));
-
-	/* Configure RX SC */
-
-	msg_macsec.msg_type = macsec_add_tx_sa_msg;
-	msg_macsec.txsa.index = aqcfg->txsa.idx;
-	msg_macsec.txsa.next_pn = aqcfg->txsa.pn;
-
-	msg_macsec.txsa.key[0] = rte_bswap32(aqcfg->txsa.key[3]);
-	msg_macsec.txsa.key[1] = rte_bswap32(aqcfg->txsa.key[2]);
-	msg_macsec.txsa.key[2] = rte_bswap32(aqcfg->txsa.key[1]);
-	msg_macsec.txsa.key[3] = rte_bswap32(aqcfg->txsa.key[0]);
-
-	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
-
-	if (response.result)
-		return -1;
-
-	memset(&msg_macsec, 0, sizeof(msg_macsec));
-
-	/* Configure RX SA */
-
-	msg_macsec.msg_type = macsec_add_rx_sa_msg;
-	msg_macsec.rxsa.index = aqcfg->rxsa.idx;
-	msg_macsec.rxsa.next_pn = aqcfg->rxsa.pn;
-
-	msg_macsec.rxsa.key[0] = rte_bswap32(aqcfg->rxsa.key[3]);
-	msg_macsec.rxsa.key[1] = rte_bswap32(aqcfg->rxsa.key[2]);
-	msg_macsec.rxsa.key[2] = rte_bswap32(aqcfg->rxsa.key[1]);
-	msg_macsec.rxsa.key[3] = rte_bswap32(aqcfg->rxsa.key[0]);
-
-	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
-
-	if (response.result)
-		return -1;
-
-	return 0;
-}
-
-int atl_macsec_enable(struct rte_eth_dev *dev,
-		      uint8_t encr, uint8_t repl_prot)
-{
-	struct aq_hw_cfg_s *cfg =
-		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
-
-	cfg->aq_macsec.common.macsec_enabled = 1;
-	cfg->aq_macsec.common.encryption_enabled = encr;
-	cfg->aq_macsec.common.replay_protection_enabled = repl_prot;
-
-	return 0;
-}
-
-int atl_macsec_disable(struct rte_eth_dev *dev)
-{
-	struct aq_hw_cfg_s *cfg =
-		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
-
-	cfg->aq_macsec.common.macsec_enabled = 0;
-
-	return 0;
-}
-
-int atl_macsec_config_txsc(struct rte_eth_dev *dev, uint8_t *mac)
-{
-	struct aq_hw_cfg_s *cfg =
-		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
-
-	memset(&cfg->aq_macsec.txsc.mac, 0, sizeof(cfg->aq_macsec.txsc.mac));
-	memcpy((uint8_t *)&cfg->aq_macsec.txsc.mac + 2, mac,
-		RTE_ETHER_ADDR_LEN);
-
-	return 0;
-}
-
-int atl_macsec_config_rxsc(struct rte_eth_dev *dev,
-			   uint8_t *mac, uint16_t pi)
-{
-	struct aq_hw_cfg_s *cfg =
-		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
-
-	memset(&cfg->aq_macsec.rxsc.mac, 0, sizeof(cfg->aq_macsec.rxsc.mac));
-	memcpy((uint8_t *)&cfg->aq_macsec.rxsc.mac + 2, mac,
-		RTE_ETHER_ADDR_LEN);
-	cfg->aq_macsec.rxsc.pi = pi;
-
-	return 0;
-}
-
-int atl_macsec_select_txsa(struct rte_eth_dev *dev,
-			   uint8_t idx, uint8_t an,
-			   uint32_t pn, uint8_t *key)
-{
-	struct aq_hw_cfg_s *cfg =
-		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
-
-	cfg->aq_macsec.txsa.idx = idx;
-	cfg->aq_macsec.txsa.pn = pn;
-	cfg->aq_macsec.txsa.an = an;
-
-	memcpy(&cfg->aq_macsec.txsa.key, key, 16);
-	return 0;
-}
-
-int atl_macsec_select_rxsa(struct rte_eth_dev *dev,
-			   uint8_t idx, uint8_t an,
-			   uint32_t pn, uint8_t *key)
-{
-	struct aq_hw_cfg_s *cfg =
-		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
-
-	cfg->aq_macsec.rxsa.idx = idx;
-	cfg->aq_macsec.rxsa.pn = pn;
-	cfg->aq_macsec.rxsa.an = an;
-
-	memcpy(&cfg->aq_macsec.rxsa.key, key, 16);
-	return 0;
-}
-
-static int
 atl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
@@ -1040,9 +857,8 @@ atl_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
 {
 	struct atl_adapter *adapter = dev->data->dev_private;
 	struct aq_hw_s *hw = &adapter->hw;
-	struct get_stats req = { 0 };
-	struct macsec_msg_fw_request msg = { 0 };
-	struct macsec_msg_fw_response resp = { 0 };
+	struct atl_macsec_stats ms_stats;
+	struct atl_get_stats_param req = { 0 };;
 	int err = -1;
 	unsigned int i;
 	unsigned int count = atl_dev_xstats_get_count(dev);
@@ -1050,16 +866,7 @@ atl_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
 	if (!stats)
 		return count;
 
-	if (hw->aq_fw_ops->send_macsec_req != NULL) {
-		req.ingress_sa_index = 0xff;
-		req.egress_sc_index = 0xff;
-		req.egress_sa_index = 0xff;
-
-		msg.msg_type = macsec_get_stats_msg;
-		msg.stats = req;
-
-		err = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
-	}
+	err = atl_macsec_send_stats_req(dev, &req, &ms_stats);	
 
 	for (i = 0; i < n && i < count; i++) {
 		stats[i].id = i;
@@ -1072,7 +879,7 @@ atl_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
 		case XSTATS_TYPE_MACSEC:
 			if (!err) {
 				stats[i].value =
-					*(u64 *)((uint8_t *)&resp.stats +
+					*(u64 *)((uint8_t *)&ms_stats +
 					atl_xstats_tbl[i].offset);
 			}
 			break;
@@ -1171,15 +978,6 @@ atl_dev_supported_ptypes_get(struct rte_eth_dev *dev)
 	return NULL;
 }
 
-static void
-atl_dev_delayed_handler(void *param)
-{
-	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
-
-	atl_dev_configure_macsec(dev);
-}
-
-
 /* return 0 means link status changed, -1 means not changed */
 static int
 atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
@@ -1230,10 +1028,6 @@ atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
 		hw_atl_b0_set_fc(hw, fc, 0U);
 	}
 
-	if (rte_eal_alarm_set(1000 * 1000,
-			      atl_dev_delayed_handler, (void *)dev) < 0)
-		PMD_DRV_LOG(ERR, "rte_eal_alarm_set fail");
-
 	return 0;
 }
 
@@ -1386,8 +1180,6 @@ atl_dev_interrupt_action(struct rte_eth_dev *dev,
 {
 	struct atl_interrupt *intr =
 		ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
-	struct atl_adapter *adapter = dev->data->dev_private;
-	struct aq_hw_s *hw = &adapter->hw;
 
 	if (!(intr->flags & ATL_FLAG_NEED_LINK_UPDATE))
 		goto done;
@@ -1399,39 +1191,12 @@ atl_dev_interrupt_action(struct rte_eth_dev *dev,
 		atl_dev_link_status_print(dev);
 		_rte_eth_dev_callback_process(dev,
 			RTE_ETH_EVENT_INTR_LSC, NULL);
-	} else {
-		if (hw->aq_fw_ops->send_macsec_req == NULL)
-			goto done;
-
-		/* Check macsec Keys expired */
-		struct get_stats req = { 0 };
-		struct macsec_msg_fw_request msg = { 0 };
-		struct macsec_msg_fw_response resp = { 0 };
-
-		req.ingress_sa_index = 0x0;
-		req.egress_sc_index = 0x0;
-		req.egress_sa_index = 0x0;
-		msg.msg_type = macsec_get_stats_msg;
-		msg.stats = req;
-
-		int err = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
-		if (err) {
-			PMD_DRV_LOG(ERR, "send_macsec_req fail");
-			goto done;
-		}
-		if (resp.stats.egress_threshold_expired ||
-		    resp.stats.ingress_threshold_expired ||
-		    resp.stats.egress_expired ||
-		    resp.stats.ingress_expired) {
-			PMD_DRV_LOG(INFO, "RTE_ETH_EVENT_MACSEC");
-			_rte_eth_dev_callback_process(dev,
-				RTE_ETH_EVENT_MACSEC, NULL);
-		}
 	}
-done:
+
 	atl_enable_intr(dev);
 	rte_intr_ack(intr_handle);
 
+done:
 	return 0;
 }
 
@@ -1911,6 +1676,35 @@ atl_rss_hash_conf_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static struct rte_security_ops atl_security_ops = {
+	.session_create = atl_macsec_create_session,
+	.session_update = atl_macsec_update_session,
+	.session_get_size = atl_macsec_session_get_size,
+	.session_stats_get = atl_macsec_session_stats_get,
+	.session_destroy = atl_macsec_destroy_session,
+	.set_pkt_metadata = NULL,
+	.capabilities_get = atl_macsec_capabilities_get,
+};
+
+static int
+atl_macsec_ctx_create(struct rte_eth_dev *dev)
+{
+	struct rte_security_ctx *ctx = NULL;
+
+	ctx = rte_malloc("rte_security_instances_ops",
+				sizeof(struct rte_security_ctx), 0);
+	if (ctx) {
+		ctx->device = (void *)dev;
+		ctx->ops = &atl_security_ops;
+		ctx->sess_cnt = 0;
+		dev->security_ctx = ctx;
+	} else {
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+
 static bool
 is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
 {
diff --git a/drivers/net/atlantic/atl_sec.c b/drivers/net/atlantic/atl_sec.c
new file mode 100644
index 0000000..8702408
--- /dev/null
+++ b/drivers/net/atlantic/atl_sec.c
@@ -0,0 +1,615 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Aquantia Corporation
+ */
+
+#include <rte_ethdev_driver.h>
+
+
+#include "atl_logs.h"
+
+#include "atl_sec.h"
+#include "atl_ethdev.h"
+
+#include "macsec/MSS_Egress_registers.h"
+#include "macsec/MSS_Ingress_registers.h"
+#include "macsec/mdio.h"
+#include "macsec/macsec_api.h"
+
+
+#define STATS_2x32_TO_64(stat_field) \
+        (((uint64_t)stat_field[1] << 32) | stat_field[0])
+
+static void ether_addr_to_mac(uint32_t mac[2], struct rte_ether_addr *emac)
+{
+	uint32_t tmp[2] = {0};
+
+	memcpy(((uint8_t*)tmp) + 2, emac->addr_bytes, RTE_ETHER_ADDR_LEN);
+
+	mac[0] = rte_bswap32(tmp[1]);
+	mac[1] = rte_bswap32(tmp[0]);
+}
+
+static int atl_macsec_configure(struct rte_eth_dev *dev,
+				struct rte_security_session *sess __rte_unused,
+				struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw;
+
+	struct macsec_msg_fw_request msg = { 0 };
+	struct macsec_msg_fw_response resp = { 0 };
+	int ret = -1;
+	struct rte_security_macsec_param *conf = &xform->config_options;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	if (hw->aq_fw_ops->send_macsec_req != NULL) {
+		struct macsec_cfg cfg = { 0 };
+
+		cfg.enabled = conf->enabled;
+		cfg.egress_threshold = conf->egress_pn_threshold;
+		cfg.ingress_threshold = conf->ingress_pn_threshold;
+		cfg.interrupts_enabled = conf->interrupts_enabled;
+
+		msg.msg_type = macsec_cfg_msg;
+		msg.cfg = cfg;
+
+		ret = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
+	}
+
+
+	if (conf->enabled) {
+		int index = 0;
+		int num_ctl_ether_types = 0;
+
+		/* Init Ethertype bypass filters */
+		for (index = 0; index < 8; index++) {
+			if (conf->ctl_ether_types[index] != 0) {
+				AQ_API_SEC_EgressCTLFRecord egressCTLFRecord = {0};
+				egressCTLFRecord.eth_type = conf->ctl_ether_types[index];
+				egressCTLFRecord.match_type = 4; /* Match eth_type only */
+				egressCTLFRecord.match_mask = 0xf; /* match for eth_type */
+				egressCTLFRecord.action = 0; /* Bypass remaining MACSEC modules */
+				AQ_API_SetEgressCTLFRecord(hw, &egressCTLFRecord, NUMROWS_EGRESSCTLFRECORD - num_ctl_ether_types - 1);
+
+				AQ_API_SEC_IngressPreCTLFRecord ingressPreCTLFRecord = {0};
+				ingressPreCTLFRecord.eth_type = conf->ctl_ether_types[index];
+				ingressPreCTLFRecord.match_type = 4; /* Match eth_type only */
+				ingressPreCTLFRecord.match_mask = 0xf; /* match for eth_type */
+				ingressPreCTLFRecord.action = 0;
+				AQ_API_SetIngressPreCTLFRecord(hw, &ingressPreCTLFRecord, NUMROWS_INGRESSPRECTLFRECORD - num_ctl_ether_types - 1);
+
+				num_ctl_ether_types++;
+			}
+		}
+	}
+
+	return ret;
+}
+
+int atl_macsec_send_stats_req(struct rte_eth_dev *dev,
+			 struct atl_get_stats_param *param,
+			 struct atl_macsec_stats *stats)
+{
+        struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct get_stats req = { 0 };
+	struct macsec_msg_fw_request msg = { 0 };
+	struct macsec_msg_fw_response resp = { 0 };
+	int ret = -1;
+
+	memset(stats, 0, sizeof(*stats));
+
+	if (hw->aq_fw_ops->send_macsec_req != NULL) {
+		req.ingress_sa_index = param->ingress_sa_index;
+		req.egress_sc_index = param->egress_sc_index;
+		req.egress_sa_index = param->egress_sa_index;
+
+		msg.msg_type = macsec_get_stats_msg;
+		msg.stats = req;
+
+		ret = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
+
+		memcpy(stats, &resp.stats, sizeof(*stats));
+	}
+
+	return ret;
+}
+
+static void atl_rotate_keys(uint32_t (*key)[8], int key_len)
+{
+	uint32_t tmp[8] = {0};
+
+	memcpy(&tmp, key, sizeof(tmp));
+	memset(*key, 0, sizeof(*key));
+
+	if (key_len == 16) {
+		(*key)[0] = tmp[3];
+		(*key)[1] = tmp[2];
+		(*key)[2] = tmp[1];
+		(*key)[3] = tmp[0];
+	} else if (key_len == 32) {
+		(*key)[0] = tmp[7];
+		(*key)[1] = tmp[6];
+		(*key)[2] = tmp[5];
+		(*key)[3] = tmp[4];
+		(*key)[4] = tmp[3];
+		(*key)[5] = tmp[2];
+		(*key)[6] = tmp[1];
+		(*key)[7] = tmp[0];
+	} else {
+		printf("Rotate_keys: invalid key_len\n");
+	}
+
+}
+
+static int atl_macsec_set_rx_sa(struct rte_eth_dev *dev,
+				struct rte_security_session *sess __rte_unused,
+				struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw;
+	struct rte_security_macsec_sa_param* param = &xform->sa_options;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	AQ_API_SEC_IngressSARecord matchSARecord = {0};
+	matchSARecord.valid = 1;
+	matchSARecord.fresh = 1;
+	matchSARecord.next_pn = param->packet_number;
+
+	AQ_API_SetIngressSARecord(hw, &matchSARecord, param->an);
+
+	AQ_API_SEC_IngressSAKeyRecord matchKeyRecord = {0};
+	memcpy(&matchKeyRecord.key, &param->key, sizeof(matchKeyRecord.key));
+
+	switch (param->key_len) {
+	case 16:
+		matchKeyRecord.key_len = 0;
+		break;
+	case 24:
+		matchKeyRecord.key_len = 1;
+		break;
+	case 32:
+		matchKeyRecord.key_len = 2;
+		break;
+	default:
+		return -1;
+	}
+
+	atl_rotate_keys(&matchKeyRecord.key, param->key_len);
+
+	return AQ_API_SetIngressSAKeyRecord(hw, &matchKeyRecord, param->an);
+}
+
+static int atl_macsec_delete_rx_sa(struct rte_eth_dev *dev,
+			    struct rte_security_session *sess __rte_unused,
+			    struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw;
+	struct rte_security_macsec_sa_param* param = &xform->sa_options;
+	uint16_t sa_index = param->sa_idx;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	AQ_API_SEC_IngressSARecord blankIngressSARecord = {0};
+	AQ_API_SetIngressSARecord(hw, &blankIngressSARecord, sa_index);
+
+	AQ_API_SEC_IngressSAKeyRecord blankIngressKeyRecord = {0};
+	AQ_API_SetIngressSAKeyRecord(hw, &blankIngressKeyRecord, sa_index);
+	return 0;
+}
+
+static int atl_macsec_set_tx_sa(struct rte_eth_dev *dev, 
+				struct rte_security_session *sess __rte_unused,
+				struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw;
+	struct rte_security_macsec_sa_param* param = &xform->sa_options;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	AQ_API_SEC_EgressSARecord matchSARecord = {0};
+	matchSARecord.valid = 1;
+	matchSARecord.fresh = 1;
+	matchSARecord.next_pn = param->packet_number;
+
+	AQ_API_SetEgressSARecord(hw, &matchSARecord, param->an);
+
+	AQ_API_SEC_EgressSAKeyRecord matchKeyRecord = {0};
+	memcpy(&matchKeyRecord.key, &param->key, sizeof(matchKeyRecord.key));
+
+	atl_rotate_keys(&matchKeyRecord.key, param->key_len);
+
+	return AQ_API_SetEgressSAKeyRecord(hw, &matchKeyRecord, param->an);
+}
+
+static int atl_macsec_delete_tx_sa(struct rte_eth_dev *dev,
+			    struct rte_security_session *sess __rte_unused,
+			    struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw;
+	struct rte_security_macsec_sa_param* param = &xform->sa_options;
+	uint16_t sa_index = param->sa_idx;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	AQ_API_SEC_EgressSARecord blankEgressSARecord = {0};
+	AQ_API_SetEgressSARecord(hw, &blankEgressSARecord, sa_index);
+
+	AQ_API_SEC_EgressSAKeyRecord blankEgressKeyRecord = {0};
+	AQ_API_SetEgressSAKeyRecord(hw, &blankEgressKeyRecord, sa_index);
+	return 0;
+}
+
+static int atl_macsec_get_idx_by_sa_num(int sa_num, int sc_index, int an)
+{
+	if (sa_num == 1) {
+		return an; //SA index
+	} else if (sa_num == 2) {
+		return (sc_index << 1) | an; //SC index
+	} else { //sa_num = 4
+		return (sc_index << 2) | an; //SC index
+	}
+}
+
+static int atl_macsec_set_rx_sc(struct rte_eth_dev *dev,
+				struct rte_security_session *sess __rte_unused,
+				struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw;
+	int err = 0;
+	struct rte_security_macsec_rxsc_param* param = &xform->rxsc_options;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	AQ_API_SEC_IngressPreClassRecord matchIngressPreClassRecord = {0};
+
+	matchIngressPreClassRecord.sci[0] = param->sci & 0xffffffff;
+	matchIngressPreClassRecord.sci[1] = param->sci >> 32;
+
+	matchIngressPreClassRecord.tci = param->tci;
+
+	ether_addr_to_mac(matchIngressPreClassRecord.mac_sa, &param->s_mac);
+	ether_addr_to_mac(matchIngressPreClassRecord.mac_da, &param->d_mac);
+
+	matchIngressPreClassRecord.sa_mask = 0x3f;
+	matchIngressPreClassRecord.da_mask = 0x3f;
+
+	matchIngressPreClassRecord.sci_mask = 0xff;
+
+	matchIngressPreClassRecord.valid = 1;
+
+	matchIngressPreClassRecord.eth_type = 0x88e5; //match all MACSEC ethertype packets
+	matchIngressPreClassRecord.eth_type_mask = 0x3;
+	matchIngressPreClassRecord.action = 0x0; //forward for decryption
+
+	matchIngressPreClassRecord.sc_idx = atl_macsec_get_idx_by_sa_num(param->sa_num, param->index, 0);
+	// Num SA per SC: # 0: 4SA, 2: 2SA, 3: 1SA
+	switch (param->sa_num) {
+	case 4:
+		matchIngressPreClassRecord.an_mask = 0;
+		break;
+	case 2:
+		matchIngressPreClassRecord.an_mask = 2;
+		break;
+	case 1:
+		matchIngressPreClassRecord.an_mask = 3;
+		break;
+	default:
+		break;
+	}
+
+	err = AQ_API_SetIngressPreClassRecord(hw, &matchIngressPreClassRecord, param->index);
+
+	
+	AQ_API_SEC_IngressSCRecord matchSCRecord = {0};
+
+	matchSCRecord.validate_frames = param->validate_frames;
+	matchSCRecord.an_rol = param->auto_rollover_enabled;
+	matchSCRecord.replay_protect = param->replay_protection;
+	matchSCRecord.anti_replay_window = param->anti_replay_window;
+	matchSCRecord.valid = 1;
+	matchSCRecord.fresh = 1;
+
+	err = AQ_API_SetIngressSCRecord(hw, &matchSCRecord, param->index);
+	return err;
+}
+
+static int atl_macsec_delete_rx_sc(struct rte_eth_dev *dev,
+			    struct rte_security_session *sess __rte_unused,
+			    struct rte_security_macsec_xform *xform)
+{
+	struct rte_security_macsec_rxsc_param* param = &xform->rxsc_options;
+	uint16_t sc_index = param->index;
+	struct aq_hw_s *hw;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	AQ_API_SEC_IngressSCRecord blankSCRecord = {0};
+	return AQ_API_SetIngressSCRecord(hw, &blankSCRecord, sc_index);
+}
+
+static int atl_macsec_set_tx_sc(struct rte_eth_dev *dev,
+				struct rte_security_session *sess __rte_unused,
+				struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw;
+	struct rte_security_macsec_txsc_param *param = &xform->txsc_options;
+
+	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	AQ_API_SEC_EgressClassRecord matchEgressClassRecord = {0};
+
+/* SA/SC lookup */
+	ether_addr_to_mac(matchEgressClassRecord.mac_sa, &param->s_mac);
+	ether_addr_to_mac(matchEgressClassRecord.mac_da, &param->d_mac);
+
+	matchEgressClassRecord.sci[0] = param->sci & 0xffffffff;
+	matchEgressClassRecord.sci[1] = param->sci >> 32;
+	matchEgressClassRecord.sci_mask = 0xff;
+
+	matchEgressClassRecord.sa_mask = 0x3f; 
+	matchEgressClassRecord.da_mask = 0x3f;
+
+	matchEgressClassRecord.action = 0; //forward to SA/SC table
+	matchEgressClassRecord.valid = 1;
+
+	matchEgressClassRecord.sc_idx = param->index;
+
+	switch (param->sa_num) {
+	case 4:
+		matchEgressClassRecord.sc_sa = 0;
+		break;
+	case 2:
+		matchEgressClassRecord.sc_sa = 2;
+		break;
+	case 1:
+		matchEgressClassRecord.sc_sa = 3;
+		break;
+	default:
+		break;
+	}
+
+	AQ_API_SetEgressClassRecord(hw, &matchEgressClassRecord, param->index);
+
+	AQ_API_SEC_EgressSCRecord matchSCRecord = {0};
+
+	matchSCRecord.protect = param->protect;
+	matchSCRecord.tci = param->tci;
+	matchSCRecord.an_roll = param->auto_rollover_enabled;
+
+	switch (param->key_len) {
+	case 16:
+		matchSCRecord.sak_len = 0;
+		break;
+	case 24:
+		matchSCRecord.sak_len = 1;
+		break;
+	case 32:
+		matchSCRecord.sak_len = 2;
+		break;
+	default:
+		return -1;
+	}
+
+	/* Current Associacion Number (according to doc: Not used when there is only one SA per SC) */
+	matchSCRecord.curr_an = param->curr_an;
+
+	matchSCRecord.valid = 1;
+	matchSCRecord.fresh = 1;
+	return AQ_API_SetEgressSCRecord(hw, &matchSCRecord, param->index);
+}
+
+static int atl_macsec_delete_tx_sc(struct rte_eth_dev *dev,
+				   struct rte_security_session *sess __rte_unused,
+				   struct rte_security_macsec_xform *xform)
+{
+	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct rte_security_macsec_txsc_param *param = &xform->txsc_options;
+	AQ_API_SEC_EgressSCRecord blankSCRecord = {0};
+
+	return AQ_API_SetEgressSCRecord(hw, &blankSCRecord, param->index);
+}
+
+/* MACSEC op jump table */
+typedef struct {
+	int op;
+	int (*func)(struct rte_eth_dev *dev, struct rte_security_session *sess, struct rte_security_macsec_xform *xform);
+} macsec_op_jump_tbl_entry;
+
+static const macsec_op_jump_tbl_entry macsec_op_jmp_tbl[] = {
+	{ RTE_SECURITY_MACSEC_OP_CONFIG, atl_macsec_configure },
+	{ RTE_SECURITY_MACSEC_OP_ADD_TXSC, atl_macsec_set_tx_sc },
+	{ RTE_SECURITY_MACSEC_OP_DEL_TXSC, atl_macsec_delete_tx_sc },
+	{ RTE_SECURITY_MACSEC_OP_UPD_TXSC, atl_macsec_set_tx_sc },
+
+	{ RTE_SECURITY_MACSEC_OP_ADD_RXSC, atl_macsec_set_rx_sc },
+	{ RTE_SECURITY_MACSEC_OP_DEL_RXSC, atl_macsec_delete_rx_sc },
+	{ RTE_SECURITY_MACSEC_OP_UPD_RXSC, atl_macsec_set_rx_sc },
+
+	{ RTE_SECURITY_MACSEC_OP_ADD_TXSA, atl_macsec_set_tx_sa },
+	{ RTE_SECURITY_MACSEC_OP_DEL_TXSA, atl_macsec_delete_tx_sa },
+	{ RTE_SECURITY_MACSEC_OP_UPD_TXSA, atl_macsec_set_tx_sa },
+
+	{ RTE_SECURITY_MACSEC_OP_ADD_RXSA, atl_macsec_set_rx_sa },
+	{ RTE_SECURITY_MACSEC_OP_DEL_RXSA, atl_macsec_delete_rx_sa },
+	{ RTE_SECURITY_MACSEC_OP_UPD_RXSA, atl_macsec_set_rx_sa },
+};
+
+int
+atl_macsec_create_session(void *device,
+				struct rte_security_session_conf *conf,
+				struct rte_security_session *session,
+				struct rte_mempool *mp)
+{
+	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
+	struct atl_macsec_session *macsec_session = NULL;
+
+	if (conf->protocol != RTE_SECURITY_PROTOCOL_MACSEC) {
+		PMD_DRV_LOG(ERR, "Unsupported security protocol\n");
+		return -ENOTSUP;
+	}
+
+	/* For create_session only CONFIG OP is supported */
+	if (conf->macsec.op != RTE_SECURITY_MACSEC_OP_CONFIG) {
+		PMD_DRV_LOG(ERR, "Unsupported OP for create_session\n");
+		return -ENOTSUP;
+	}
+
+	if (rte_mempool_get(mp, (void **)&macsec_session)) {
+		PMD_DRV_LOG(ERR, "Cannot get object from ic_session mempool\n");
+		return -ENOMEM;
+	}
+
+
+	macsec_session->dev = eth_dev;
+
+	set_sec_session_private_data(session, macsec_session);
+
+	return 0;
+}
+
+int
+atl_macsec_update_session(void *device,
+			  struct rte_security_session *sess,
+			  struct rte_security_session_conf *conf)
+{
+	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
+	struct rte_security_macsec_xform *xform = &conf->macsec;
+
+	if (xform->op > RTE_DIM(macsec_op_jmp_tbl))
+		return -ENOTSUP;
+
+	return macsec_op_jmp_tbl[xform->op].func(eth_dev, sess, xform);
+}
+
+unsigned int
+atl_macsec_session_get_size(void *device __rte_unused)
+{
+	return sizeof(struct atl_macsec_session);
+}
+
+int
+atl_macsec_destroy_session(void *device,
+			   struct rte_security_session *sess)
+{
+	struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
+	struct atl_macsec_session *macsec_session =
+		(struct atl_macsec_session*) get_sec_session_private_data(sess);
+	struct rte_mempool *mp = rte_mempool_from_obj(macsec_session);
+
+	if (eth_dev != macsec_session->dev) {
+		PMD_DRV_LOG(ERR, "Session not bound to this device\n");
+		return -ENODEV;
+	}
+
+	set_sec_session_private_data(sess, NULL);
+	rte_mempool_put(mp, (void *)macsec_session);
+
+	return 0;
+}
+
+int
+atl_macsec_session_stats_get(void *device,
+			     struct rte_security_session *sess __rte_unused,
+			     struct rte_security_stats *stats)
+{
+	struct rte_eth_dev *dev = (struct rte_eth_dev *)device;
+	struct atl_macsec_stats macsec_stats = { 0 };
+	struct atl_get_stats_param param = { 0 };
+	struct rte_security_macsec_stats *result_stats = &stats->macsec;
+	int err = 0;
+
+	dev = dev;
+
+	memset(result_stats, 0, sizeof(struct rte_security_macsec_stats));
+
+	err = atl_macsec_send_stats_req(dev, &param, &macsec_stats);
+
+	if (err)
+		return err;
+
+
+	result_stats->in_ctl_pkts = macsec_stats.in_ctl_pkts;
+	result_stats->in_tagged_miss_pkts = macsec_stats.in_tagged_miss_pkts;
+	result_stats->in_untagged_miss_pkts = macsec_stats.in_untagged_miss_pkts;
+	result_stats->in_notag_pkts = macsec_stats.in_notag_pkts;
+	result_stats->in_untagged_pkts = macsec_stats.in_untagged_pkts;
+	result_stats->in_bad_tag_pkts = macsec_stats.in_bad_tag_pkts;
+	result_stats->in_no_sci_pkts = macsec_stats.in_no_sci_pkts;
+	result_stats->in_unknown_sci_pkts = macsec_stats.in_unknown_sci_pkts;
+
+	result_stats->out_ctl_pkts = macsec_stats.out_ctl_pkts;
+	result_stats->out_unknown_sa_pkts = macsec_stats.out_unknown_sa_pkts;
+	result_stats->out_untagged_pkts = macsec_stats.out_untagged_pkts;
+	result_stats->out_too_long = macsec_stats.out_too_long;
+
+	result_stats->in_untagged_hit_pkts = macsec_stats.in_untagged_hit_pkts;
+	result_stats->in_not_using_sa = macsec_stats.in_not_using_sa;
+	result_stats->in_unused_sa = macsec_stats.in_unused_sa;
+	result_stats->in_not_valid_pkts = macsec_stats.in_not_valid_pkts;
+	result_stats->in_invalid_pkts = macsec_stats.in_invalid_pkts;
+	result_stats->in_ok_pkts = macsec_stats.in_ok_pkts;
+	result_stats->in_unchecked_pkts = macsec_stats.in_unchecked_pkts;
+	result_stats->in_validated_octets = macsec_stats.in_validated_octets;
+	result_stats->in_decrypted_octets = macsec_stats.in_decrypted_octets;
+	result_stats->out_sc_protected_pkts = macsec_stats.out_sc_protected_pkts;
+	result_stats->out_sc_encrypted_pkts = macsec_stats.out_sc_encrypted_pkts;
+	result_stats->out_sc_protected_octets = macsec_stats.out_sc_protected_octets;
+	result_stats->out_sc_encrypted_octets = macsec_stats.out_sc_encrypted_octets;
+	result_stats->out_sa_hit_drop_redirect = macsec_stats.out_sa_hit_drop_redirect;
+	result_stats->out_sa_protected2_pkts = macsec_stats.out_sa_protected2_pkts;
+	result_stats->out_sa_protected_pkts = macsec_stats.out_sa_protected_pkts;
+	result_stats->out_sa_encrypted_pkts = macsec_stats.out_sa_encrypted_pkts;
+
+	return err;
+}
+
+const struct rte_security_capability *
+atl_macsec_capabilities_get(void *device)
+{
+	struct rte_eth_dev *dev = (struct rte_eth_dev *)device;
+	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	static const struct rte_cryptodev_capabilities
+	aes_gcm_gmac_crypto_capabilities[] = {
+		{       /* AES GMAC (128-bit) */
+			.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+			{.sym = {
+				.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+				{.auth = {
+					.algo = RTE_CRYPTO_AUTH_AES_GMAC,
+					.block_size = 16,
+					.key_size = {
+						.min = 16,
+						.max = 16,
+						.increment = 0
+					},
+				}, }
+			}, }
+		},
+	};
+
+	static const struct rte_security_capability
+	alt_security_capabilities[] = {
+		{
+			.action = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL,
+			.protocol = RTE_SECURITY_PROTOCOL_MACSEC,
+			{.macsec = {
+				.caps = {
+					.xpn = 0, /* Extended Packet Numbers (64 bit) not supported */
+				},
+			} },
+			.crypto_capabilities = aes_gcm_gmac_crypto_capabilities,
+			.ol_flags = 0
+		},
+		{
+			.action = RTE_SECURITY_ACTION_TYPE_NONE
+		}
+	};
+
+/* No MACSEC support for AQC100 devices */
+	if ((hw->caps_lo & BIT(CAPS_LO_MACSEC)) == 0)
+		return NULL;
+
+	return alt_security_capabilities;
+}
+
diff --git a/drivers/net/atlantic/atl_sec.h b/drivers/net/atlantic/atl_sec.h
new file mode 100644
index 0000000..1d8651d
--- /dev/null
+++ b/drivers/net/atlantic/atl_sec.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Aquantia Corporation
+ */
+
+/**
+ * @file rte_pmd_atlantic.h
+ * atlantic PMD specific functions.
+ *
+ **/
+
+#ifndef _ATL_SEC_H_
+#define _ATL_SEC_H_
+
+#include <rte_security.h>
+#include <rte_security_driver.h>
+#include <rte_cryptodev.h>
+#include <rte_tailq.h>
+
+#include <rte_ethdev_driver.h>
+
+struct atl_get_stats_param {
+        uint8_t version_only;
+        uint8_t ingress_sa_index;
+        uint8_t egress_sa_index;
+        uint8_t egress_sc_index;
+};
+
+struct atl_macsec_stats {
+    /* Retrieve Atlantic MACSEC FW version*/
+    uint32_t api_version;
+    /* Ingress Common Counters */
+    uint64_t in_ctl_pkts;
+    uint64_t in_tagged_miss_pkts;
+    uint64_t in_untagged_miss_pkts;
+    uint64_t in_notag_pkts;
+    uint64_t in_untagged_pkts;
+    uint64_t in_bad_tag_pkts;
+    uint64_t in_no_sci_pkts;
+    uint64_t in_unknown_sci_pkts;
+    uint64_t in_ctrl_prt_pass_pkts;
+    uint64_t in_unctrl_prt_pass_pkts;
+    uint64_t in_ctrl_prt_fail_pkts;
+    uint64_t in_unctrl_prt_fail_pkts;
+    uint64_t in_too_long_pkts;
+    uint64_t in_igpoc_ctl_pkts;
+    uint64_t in_ecc_error_pkts;
+    uint64_t in_unctrl_hit_drop_redir;
+
+    /* Egress Common Counters */
+    uint64_t out_ctl_pkts;
+    uint64_t out_unknown_sa_pkts;
+    uint64_t out_untagged_pkts;
+    uint64_t out_too_long;
+    uint64_t out_ecc_error_pkts;
+    uint64_t out_unctrl_hit_drop_redir;
+
+    /* Ingress SA Counters */
+    uint64_t in_untagged_hit_pkts;
+    uint64_t in_ctrl_hit_drop_redir_pkts;
+    uint64_t in_not_using_sa;
+    uint64_t in_unused_sa;
+    uint64_t in_not_valid_pkts;
+    uint64_t in_invalid_pkts;
+    uint64_t in_ok_pkts;
+    uint64_t in_late_pkts;
+    uint64_t in_delayed_pkts;
+    uint64_t in_unchecked_pkts;
+    uint64_t in_validated_octets;
+    uint64_t in_decrypted_octets;
+
+    /* Egress SA Counters */
+    uint64_t out_sa_hit_drop_redirect;
+    uint64_t out_sa_protected2_pkts;
+    uint64_t out_sa_protected_pkts;
+    uint64_t out_sa_encrypted_pkts;
+
+    /* Egress SC Counters */
+    uint64_t out_sc_protected_pkts;
+    uint64_t out_sc_encrypted_pkts;
+    uint64_t out_sc_protected_octets;
+    uint64_t out_sc_encrypted_octets;
+
+    /* SA Counters expiration info */
+    uint32_t egress_threshold_expired;
+    uint32_t ingress_threshold_expired;
+    uint32_t egress_expired;
+    uint32_t ingress_expired;
+} __attribute__((__packed__));
+
+int atl_macsec_send_stats_req(struct rte_eth_dev *dev,
+			      struct atl_get_stats_param *param,
+			      struct atl_macsec_stats *stats);
+
+struct atl_macsec_session {
+	unsigned int session_id;
+	struct rte_eth_dev *dev;
+};
+
+TAILQ_HEAD(atl_macsec_sessions_list, atl_macsec_session);
+
+struct atl_macsec {
+	struct atl_macsec_sessions_list sessions_list;
+};
+
+int atl_macsec_create_session(void *device,
+				struct rte_security_session_conf *conf,
+				struct rte_security_session *session,
+				struct rte_mempool *mp);
+
+int atl_macsec_update_session(void *device,
+				struct rte_security_session *sess,
+				struct rte_security_session_conf *conf);
+
+unsigned int atl_macsec_session_get_size(void *device);
+
+int atl_macsec_destroy_session(void *device, struct rte_security_session *sess);
+
+int atl_macsec_session_stats_get(void *device,
+				 struct rte_security_session *sess,
+				 struct rte_security_stats *stats);
+
+const struct rte_security_capability *atl_macsec_capabilities_get(void *device);
+
+#endif /* _ATL_SEC_H_ */
diff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/atlantic/hw_atl/hw_atl_utils.h
index 81caffa..af4dd82 100644
--- a/drivers/net/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils.h
@@ -11,6 +11,8 @@
 #define BIT(x)  (1UL << (x))
 #define HW_ATL_FLUSH() { (void)aq_hw_read_reg(self, 0x10); }
 
+#include "../atl_sec.h"
+
 /* Hardware tx descriptor */
 struct hw_atl_txd_s {
 	u64 buf_addr;
@@ -360,51 +362,6 @@ struct macsec_cfg {
 	uint32_t interrupts_enabled;
 } __attribute__((__packed__));
 
-struct add_rx_sc {
-	uint32_t index;
-	uint32_t pi; /* Port identifier */
-	uint32_t sci[2]; /* Secure Channel identifier */
-	uint32_t sci_mask; /* 1: enable comparison of SCI, 0: don't care */
-	uint32_t tci;
-	uint32_t tci_mask;
-	uint32_t mac_sa[2];
-	uint32_t sa_mask; /* 0: ignore mac_sa */
-	uint32_t mac_da[2];
-	uint32_t da_mask; /* 0: ignore mac_da */
-	uint32_t validate_frames; /* 0: strict, 1:check, 2:disabled */
-	uint32_t replay_protect; /* 1: enabled, 0:disabled */
-	uint32_t anti_replay_window; /* default 0 */
-	/* 1: auto_rollover enabled (when SA next_pn is saturated */
-	uint32_t an_rol;
-} __attribute__((__packed__));
-
-struct add_tx_sc {
-	uint32_t index;
-	uint32_t pi; /* Port identifier */
-	uint32_t sci[2]; /* Secure Channel identifier */
-	uint32_t sci_mask; /* 1: enable comparison of SCI, 0: don't care */
-	uint32_t tci; /* TCI value, used if packet is not explicitly tagged */
-	uint32_t tci_mask;
-	uint32_t mac_sa[2];
-	uint32_t sa_mask; /* 0: ignore mac_sa */
-	uint32_t mac_da[2];
-	uint32_t da_mask; /* 0: ignore mac_da */
-	uint32_t protect;
-	uint32_t curr_an; /* SA index which currently used */
-} __attribute__((__packed__));
-
-struct add_rx_sa {
-	uint32_t index;
-	uint32_t next_pn;
-	uint32_t key[4]; /* 128 bit key */
-} __attribute__((__packed__));
-
-struct add_tx_sa {
-	uint32_t index;
-	uint32_t next_pn;
-	uint32_t key[4]; /* 128 bit key */
-} __attribute__((__packed__));
-
 struct get_stats {
 	uint32_t version_only;
 	uint32_t ingress_sa_index;
@@ -412,84 +369,19 @@ struct get_stats {
 	uint32_t egress_sc_index;
 } __attribute__((__packed__));
 
-struct macsec_stats {
-	uint32_t api_version;
-	/* Ingress Common Counters */
-	uint64_t in_ctl_pkts;
-	uint64_t in_tagged_miss_pkts;
-	uint64_t in_untagged_miss_pkts;
-	uint64_t in_notag_pkts;
-	uint64_t in_untagged_pkts;
-	uint64_t in_bad_tag_pkts;
-	uint64_t in_no_sci_pkts;
-	uint64_t in_unknown_sci_pkts;
-	uint64_t in_ctrl_prt_pass_pkts;
-	uint64_t in_unctrl_prt_pass_pkts;
-	uint64_t in_ctrl_prt_fail_pkts;
-	uint64_t in_unctrl_prt_fail_pkts;
-	uint64_t in_too_long_pkts;
-	uint64_t in_igpoc_ctl_pkts;
-	uint64_t in_ecc_error_pkts;
-	uint64_t in_unctrl_hit_drop_redir;
-
-	/* Egress Common Counters */
-	uint64_t out_ctl_pkts;
-	uint64_t out_unknown_sa_pkts;
-	uint64_t out_untagged_pkts;
-	uint64_t out_too_long;
-	uint64_t out_ecc_error_pkts;
-	uint64_t out_unctrl_hit_drop_redir;
-
-	/* Ingress SA Counters */
-	uint64_t in_untagged_hit_pkts;
-	uint64_t in_ctrl_hit_drop_redir_pkts;
-	uint64_t in_not_using_sa;
-	uint64_t in_unused_sa;
-	uint64_t in_not_valid_pkts;
-	uint64_t in_invalid_pkts;
-	uint64_t in_ok_pkts;
-	uint64_t in_late_pkts;
-	uint64_t in_delayed_pkts;
-	uint64_t in_unchecked_pkts;
-	uint64_t in_validated_octets;
-	uint64_t in_decrypted_octets;
-
-	/* Egress SA Counters */
-	uint64_t out_sa_hit_drop_redirect;
-	uint64_t out_sa_protected2_pkts;
-	uint64_t out_sa_protected_pkts;
-	uint64_t out_sa_encrypted_pkts;
-
-	/* Egress SC Counters */
-	uint64_t out_sc_protected_pkts;
-	uint64_t out_sc_encrypted_pkts;
-	uint64_t out_sc_protected_octets;
-	uint64_t out_sc_encrypted_octets;
-
-	/* SA Counters expiration info */
-	uint32_t egress_threshold_expired;
-	uint32_t ingress_threshold_expired;
-	uint32_t egress_expired;
-	uint32_t ingress_expired;
-} __attribute__((__packed__));
-
 struct macsec_msg_fw_request {
-	uint32_t offset; /* not used */
+	uint32_t msg_id; /* not used */
 	uint32_t msg_type;
 
 	union {
 		struct macsec_cfg cfg;
-		struct add_rx_sc rxsc;
-		struct add_tx_sc txsc;
-		struct add_rx_sa rxsa;
-		struct add_tx_sa txsa;
 		struct get_stats stats;
 	};
 } __attribute__((__packed__));
 
 struct macsec_msg_fw_response {
 	uint32_t result;
-	struct macsec_stats stats;
+	struct atl_macsec_stats stats;
 } __attribute__((__packed__));
 
 #define HAL_ATLANTIC_UTILS_CHIP_MIPS         0x00000001U
diff --git a/drivers/net/atlantic/meson.build b/drivers/net/atlantic/meson.build
index 139cdec..986c6d6 100644
--- a/drivers/net/atlantic/meson.build
+++ b/drivers/net/atlantic/meson.build
@@ -7,11 +7,13 @@ sources = files(
 	'atl_rxtx.c',
 	'atl_ethdev.c',
 	'atl_hw_regs.c',
+	'atl_sec.c',
 	'hw_atl/hw_atl_b0.c',
 	'hw_atl/hw_atl_llh.c',
 	'hw_atl/hw_atl_utils_fw2x.c',
 	'hw_atl/hw_atl_utils.c',
-	'rte_pmd_atlantic.c',
 	'macsec/mdio.c',
 	'macsec/macsec_api.c',
 )
+
+deps += ['security']
diff --git a/drivers/net/atlantic/rte_pmd_atlantic.c b/drivers/net/atlantic/rte_pmd_atlantic.c
deleted file mode 100644
index 2962f5c..0000000
--- a/drivers/net/atlantic/rte_pmd_atlantic.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Aquantia Corporation
- */
-
-#include <rte_ethdev_driver.h>
-
-#include "rte_pmd_atlantic.h"
-#include "atl_ethdev.h"
-
-
-int
-rte_pmd_atl_macsec_enable(uint16_t port,
-			  uint8_t encr, uint8_t repl_prot)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
-
-	dev = &rte_eth_devices[port];
-
-	if (!is_atlantic_supported(dev))
-		return -ENOTSUP;
-
-	return atl_macsec_enable(dev, encr, repl_prot);
-}
-
-int
-rte_pmd_atl_macsec_disable(uint16_t port)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
-
-	dev = &rte_eth_devices[port];
-
-	if (!is_atlantic_supported(dev))
-		return -ENOTSUP;
-
-	return atl_macsec_disable(dev);
-}
-
-int
-rte_pmd_atl_macsec_config_txsc(uint16_t port, uint8_t *mac)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
-
-	dev = &rte_eth_devices[port];
-
-	if (!is_atlantic_supported(dev))
-		return -ENOTSUP;
-
-	return atl_macsec_config_txsc(dev, mac);
-}
-
-int
-rte_pmd_atl_macsec_config_rxsc(uint16_t port, uint8_t *mac, uint16_t pi)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
-
-	dev = &rte_eth_devices[port];
-
-	if (!is_atlantic_supported(dev))
-		return -ENOTSUP;
-
-	return atl_macsec_config_rxsc(dev, mac, pi);
-}
-
-int
-rte_pmd_atl_macsec_select_txsa(uint16_t port, uint8_t idx, uint8_t an,
-				 uint32_t pn, uint8_t *key)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
-
-	dev = &rte_eth_devices[port];
-
-	if (!is_atlantic_supported(dev))
-		return -ENOTSUP;
-
-	return atl_macsec_select_txsa(dev, idx, an, pn, key);
-}
-
-int
-rte_pmd_atl_macsec_select_rxsa(uint16_t port, uint8_t idx, uint8_t an,
-				 uint32_t pn, uint8_t *key)
-{
-	struct rte_eth_dev *dev;
-
-	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
-
-	dev = &rte_eth_devices[port];
-
-	if (!is_atlantic_supported(dev))
-		return -ENOTSUP;
-
-	return atl_macsec_select_rxsa(dev, idx, an, pn, key);
-}
diff --git a/drivers/net/atlantic/rte_pmd_atlantic.h b/drivers/net/atlantic/rte_pmd_atlantic.h
deleted file mode 100644
index c020856..0000000
--- a/drivers/net/atlantic/rte_pmd_atlantic.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Aquantia Corporation
- */
-
-/**
- * @file rte_pmd_atlantic.h
- * atlantic PMD specific functions.
- *
- **/
-
-#ifndef _PMD_ATLANTIC_H_
-#define _PMD_ATLANTIC_H_
-
-#include <rte_ethdev_driver.h>
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
- * Enable MACsec offload.
- *
- * @param port
- *   The port identifier of the Ethernet device.
- * @param encr
- *    1 - Enable encryption (encrypt and add integrity signature).
- *    0 - Disable encryption (only add integrity signature).
- * @param repl_prot
- *    1 - Enable replay protection.
- *    0 - Disable replay protection.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port* invalid.
- *   - (-ENOTSUP) if hardware doesn't support this feature.
- */
-__rte_experimental
-int rte_pmd_atl_macsec_enable(uint16_t port, uint8_t encr, uint8_t repl_prot);
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
- * Disable MACsec offload.
- *
- * @param port
- *   The port identifier of the Ethernet device.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port* invalid.
- *   - (-ENOTSUP) if hardware doesn't support this feature.
- */
-__rte_experimental
-int rte_pmd_atl_macsec_disable(uint16_t port);
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
- * Configure Tx SC (Secure Connection).
- *
- * @param port
- *   The port identifier of the Ethernet device.
- * @param mac
- *   The MAC address on the local side.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port* invalid.
- *   - (-ENOTSUP) if hardware doesn't support this feature.
- */
-__rte_experimental
-int rte_pmd_atl_macsec_config_txsc(uint16_t port, uint8_t *mac);
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
- * Configure Rx SC (Secure Connection).
- *
- * @param port
- *   The port identifier of the Ethernet device.
- * @param mac
- *   The MAC address on the remote side.
- * @param pi
- *   The PI (port identifier) on the remote side.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port* invalid.
- *   - (-ENOTSUP) if hardware doesn't support this feature.
- */
-__rte_experimental
-int rte_pmd_atl_macsec_config_rxsc(uint16_t port, uint8_t *mac, uint16_t pi);
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
- * Enable Tx SA (Secure Association).
- *
- * @param port
- *   The port identifier of the Ethernet device.
- * @param idx
- *   The SA to be enabled (0 or 1).
- * @param an
- *   The association number on the local side.
- * @param pn
- *   The packet number on the local side.
- * @param key
- *   The key on the local side.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port* invalid.
- *   - (-ENOTSUP) if hardware doesn't support this feature.
- *   - (-EINVAL) if bad parameter.
- */
-__rte_experimental
-int rte_pmd_atl_macsec_select_txsa(uint16_t port, uint8_t idx, uint8_t an,
-				   uint32_t pn, uint8_t *key);
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
- *
- * Enable Rx SA (Secure Association).
- *
- * @param port
- *   The port identifier of the Ethernet device.
- * @param idx
- *   The SA to be enabled (0 or 1)
- * @param an
- *   The association number on the remote side.
- * @param pn
- *   The packet number on the remote side.
- * @param key
- *   The key on the remote side.
- * @return
- *   - (0) if successful.
- *   - (-ENODEV) if *port* invalid.
- *   - (-ENOTSUP) if hardware doesn't support this feature.
- *   - (-EINVAL) if bad parameter.
- */
-__rte_experimental
-int rte_pmd_atl_macsec_select_rxsa(uint16_t port, uint8_t idx, uint8_t an,
-				   uint32_t pn, uint8_t *key);
-
-#endif /* _PMD_ATLANTIC_H_ */
diff --git a/drivers/net/atlantic/rte_pmd_atlantic_version.map b/drivers/net/atlantic/rte_pmd_atlantic_version.map
deleted file mode 100644
index b16faa9..0000000
--- a/drivers/net/atlantic/rte_pmd_atlantic_version.map
+++ /dev/null
@@ -1,16 +0,0 @@
-DPDK_18.11 {
-
-	local: *;
-};
-
-EXPERIMENTAL {
-	global:
-
-	rte_pmd_atl_macsec_enable;
-	rte_pmd_atl_macsec_disable;
-	rte_pmd_atl_macsec_config_txsc;
-	rte_pmd_atl_macsec_config_rxsc;
-	rte_pmd_atl_macsec_select_txsa;
-	rte_pmd_atl_macsec_select_rxsa;
-};
-
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands using rte_security interface
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
                   ` (4 preceding siblings ...)
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 5/7] net/atlantic: implementation of the MACSEC using rte_security interface Pavel Belous
@ 2019-10-25 17:54 ` Pavel Belous
  2019-10-25 19:01   ` Stephen Hemminger
  2019-10-25 19:02   ` Stephen Hemminger
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 7/7] app/testpmd: macsec adding RX/TX SC " Pavel Belous
  2020-01-27 11:25 ` [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Akhil Goyal
  7 siblings, 2 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:54 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

Here we create/get security mempool, get sec_ctx, and then
request session creation with macsec specific session configuration.

encrypt and replay_protection parameters are really not a global macsec
attributes, they are related to tx and rx security connection properties.

But we keep testpmd commands structure the same for now and will redesign
it in later commits.

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 app/test-pmd/Makefile    |  1 +
 app/test-pmd/cmdline.c   |  9 ++----
 app/test-pmd/macsec.c    | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/macsec.h    | 12 +++++++
 app/test-pmd/meson.build |  3 +-
 5 files changed, 100 insertions(+), 7 deletions(-)
 create mode 100644 app/test-pmd/macsec.c
 create mode 100644 app/test-pmd/macsec.h

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index d5258ea..14cd7f0 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -37,6 +37,7 @@ SRCS-y += noisy_vnf.c
 SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
 SRCS-$(CONFIG_RTE_LIBRTE_BPF) += bpf_cmd.c
 SRCS-y += util.c
+SRCS-y += macsec.c
 
 ifeq ($(CONFIG_RTE_LIBRTE_PMD_SOFTNIC), y)
 SRCS-y += softnicfwd.c
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ffc8b70..10f48f8 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -75,6 +75,7 @@
 #include "cmdline_mtr.h"
 #include "cmdline_tm.h"
 #include "bpf_cmd.h"
+#include "macsec.h"
 
 static struct cmdline *testpmd_cl;
 
@@ -14124,9 +14125,7 @@ cmd_set_macsec_offload_on_parsed(
 		return;
 
 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-#ifdef RTE_LIBRTE_IXGBE_PMD
-		ret = rte_pmd_ixgbe_macsec_enable(port_id, en, rp);
-#endif
+		ret = set_macsec_on_off(port_id, 1, en, rp);
 	}
 	RTE_SET_USED(en);
 	RTE_SET_USED(rp);
@@ -14221,9 +14220,7 @@ cmd_set_macsec_offload_off_parsed(
 		return;
 
 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MACSEC_INSERT) {
-#ifdef RTE_LIBRTE_IXGBE_PMD
-		ret = rte_pmd_ixgbe_macsec_disable(port_id);
-#endif
+		ret = set_macsec_on_off(port_id, 0, 0, 0);
 	}
 	switch (ret) {
 	case 0:
diff --git a/app/test-pmd/macsec.c b/app/test-pmd/macsec.c
new file mode 100644
index 0000000..fc7976d
--- /dev/null
+++ b/app/test-pmd/macsec.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2016 Intel Corporation.
+ * Copyright(c) 2014 6WIND S.A.
+ */
+
+#include <rte_ethdev.h>
+#include <rte_flow.h>
+#include <rte_security.h>
+#include "macsec.h"
+
+#define TESTPMD_MEMPOOL_NAME "testpmd_security_pool"
+
+struct macsec_params {
+	struct rte_mempool *mp;
+	struct rte_security_session *session;
+	int replay_protection_enabled;
+	int encryption_enabled;
+};
+
+static struct macsec_params macsec_param;
+
+static struct rte_mempool *get_security_pool(struct rte_security_ctx *ctx)
+{
+	struct rte_mempool *mp = rte_mempool_lookup(TESTPMD_MEMPOOL_NAME);
+
+	if (!mp) {
+		unsigned int ssize = rte_security_session_get_size(ctx);
+
+		if (ssize) {
+			mp = rte_mempool_create("testpmd_security_pool",
+				1, /* One sesion */
+				ssize,
+				0, 0, NULL, NULL, NULL, NULL,
+				SOCKET_ID_ANY, 0);
+		}
+	}
+
+	return mp;
+}
+
+int set_macsec_on_off(portid_t port_id, int on, int en, int rp)
+{
+	struct rte_security_session_conf macsec_conf;
+	struct rte_security_ctx *ctx;
+	struct rte_mempool *mp;
+	int err = 0;
+
+	ctx = rte_eth_dev_get_sec_ctx(port_id);
+
+	if (!ctx) {
+		err = -ENOTSUP;
+		goto done;
+	}
+
+	mp = get_security_pool(ctx);
+
+	macsec_conf.action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
+	macsec_conf.protocol = RTE_SECURITY_PROTOCOL_MACSEC;
+	macsec_conf.macsec.op = RTE_SECURITY_MACSEC_OP_CONFIG;
+
+	if (on) {
+		macsec_param.session = rte_security_session_create(ctx, &macsec_conf, mp);
+
+		if (!macsec_param.session) {
+			err = -ENOTSUP;
+			goto done;
+		}
+
+		macsec_param.replay_protection_enabled = rp;
+		macsec_param.encryption_enabled = en;
+	} else {
+		if (macsec_param.session) {
+			err = rte_security_session_destroy(ctx, macsec_param.session);
+		} else {
+			err = -ENOTSUP;
+		}
+	}
+
+done:
+	return err;
+}
+
diff --git a/app/test-pmd/macsec.h b/app/test-pmd/macsec.h
new file mode 100644
index 0000000..42a534f
--- /dev/null
+++ b/app/test-pmd/macsec.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef _TESTPMD_MACSEC_H_
+#define _TESTPMD_MACSEC_H_
+
+#include "testpmd.h"
+
+int set_macsec_on_off(portid_t port_id, int on, int en, int rp);
+
+#endif
diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
index 6006c60..755bab2 100644
--- a/app/test-pmd/meson.build
+++ b/app/test-pmd/meson.build
@@ -22,7 +22,8 @@ sources = files('cmdline.c',
 	'rxonly.c',
 	'testpmd.c',
 	'txonly.c',
-	'util.c')
+	'util.c',
+	'macsec.c')
 
 deps += ['ethdev', 'gro', 'gso', 'cmdline', 'metrics', 'meter', 'bus_pci']
 if dpdk_conf.has('RTE_LIBRTE_PDUMP')
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [RFC v2 7/7] app/testpmd: macsec adding RX/TX SC using rte_security interface
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
                   ` (5 preceding siblings ...)
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands " Pavel Belous
@ 2019-10-25 17:54 ` Pavel Belous
  2020-01-27 11:25 ` [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Akhil Goyal
  7 siblings, 0 replies; 11+ messages in thread
From: Pavel Belous @ 2019-10-25 17:54 UTC (permalink / raw)
  To: dev
  Cc: Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri, Pavel Belous, Pavel Belous

From: Pavel Belous <Pavel.Belous@aquantia.com>

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 app/test-pmd/cmdline.c | 11 +++++-----
 app/test-pmd/macsec.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/macsec.h  |  2 ++
 3 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 10f48f8..a1f895c 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -14304,13 +14304,12 @@ cmd_set_macsec_sc_parsed(
 	int ret = -ENOTSUP;
 	int is_tx = (strcmp(res->tx_rx, "tx") == 0) ? 1 : 0;
 
-#ifdef RTE_LIBRTE_IXGBE_PMD
 	ret = is_tx ?
-		rte_pmd_ixgbe_macsec_config_txsc(res->port_id,
-				res->mac.addr_bytes) :
-		rte_pmd_ixgbe_macsec_config_rxsc(res->port_id,
-				res->mac.addr_bytes, res->pi);
-#endif
+		config_macsec_txsc(res->port_id,
+                                res->mac) :
+	        config_macsec_rxsc(res->port_id,
+                                res->mac, res->pi);
+
 	RTE_SET_USED(is_tx);
 
 	switch (ret) {
diff --git a/app/test-pmd/macsec.c b/app/test-pmd/macsec.c
index fc7976d..ffba467 100644
--- a/app/test-pmd/macsec.c
+++ b/app/test-pmd/macsec.c
@@ -80,3 +80,59 @@ int set_macsec_on_off(portid_t port_id, int on, int en, int rp)
 	return err;
 }
 
+int config_macsec_txsc(portid_t port_id, struct rte_ether_addr mac)
+{
+	struct rte_security_session_conf macsec_conf;
+	struct rte_security_ctx *ctx;
+	int err = 0;
+
+	ctx = rte_eth_dev_get_sec_ctx(port_id);
+
+	if (!ctx) {
+		err = -ENOTSUP;
+		goto done;
+	}
+
+	macsec_conf.action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
+	macsec_conf.protocol = RTE_SECURITY_PROTOCOL_MACSEC;
+
+	macsec_conf.macsec.op = RTE_SECURITY_MACSEC_OP_ADD_TXSC;
+
+	rte_memcpy(&macsec_conf.macsec.txsc_options.s_mac, mac.addr_bytes, sizeof(struct rte_ether_addr));
+	macsec_conf.macsec.txsc_options.encrypt = macsec_param.encryption_enabled;
+	macsec_conf.macsec.txsc_options.protect = 1;
+
+	err = rte_security_session_update(ctx, macsec_param.session, &macsec_conf);
+
+done:
+	return err;
+}
+
+int config_macsec_rxsc(portid_t port_id, struct rte_ether_addr mac, uint16_t pi)
+{
+	struct rte_security_session_conf macsec_conf;
+	struct rte_security_ctx *ctx;
+	int err = 0;
+
+	ctx = rte_eth_dev_get_sec_ctx(port_id);
+	if (!ctx) {
+		err = -ENOTSUP;
+		goto done;
+	}
+
+	macsec_conf.action_type = RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL;
+	macsec_conf.protocol = RTE_SECURITY_PROTOCOL_MACSEC;
+	macsec_conf.macsec.op = RTE_SECURITY_MACSEC_OP_ADD_RXSC;
+
+	rte_memcpy(&macsec_conf.macsec.txsc_options.s_mac, mac.addr_bytes, sizeof(struct rte_ether_addr));
+	macsec_conf.macsec.rxsc_options.anti_replay_window = 0;
+	macsec_conf.macsec.rxsc_options.replay_protection = macsec_param.replay_protection_enabled;
+	macsec_conf.macsec.rxsc_options.auto_rollover_enabled = true;
+	macsec_conf.macsec.rxsc_options.port_ident = pi;
+
+	err = rte_security_session_update(ctx, macsec_param.session, &macsec_conf);
+
+done:
+	return err;
+}
+
diff --git a/app/test-pmd/macsec.h b/app/test-pmd/macsec.h
index 42a534f..e155937 100644
--- a/app/test-pmd/macsec.h
+++ b/app/test-pmd/macsec.h
@@ -8,5 +8,7 @@
 #include "testpmd.h"
 
 int set_macsec_on_off(portid_t port_id, int on, int en, int rp);
+int config_macsec_txsc(portid_t port_id, struct rte_ether_addr mac);
+int config_macsec_rxsc(portid_t port_id, struct rte_ether_addr mac, uint16_t pi);
 
 #endif
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands using rte_security interface
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands " Pavel Belous
@ 2019-10-25 19:01   ` Stephen Hemminger
  2019-10-25 19:02   ` Stephen Hemminger
  1 sibling, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2019-10-25 19:01 UTC (permalink / raw)
  To: Pavel Belous
  Cc: dev, Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri

On Fri, 25 Oct 2019 17:54:08 +0000
Pavel Belous <Pavel.Belous@aquantia.com> wrote:

> +static struct rte_mempool *get_security_pool(struct rte_security_ctx *ctx)
> +{
> +	struct rte_mempool *mp = rte_mempool_lookup(TESTPMD_MEMPOOL_NAME);
> +
> +	if (!mp) {
> +		unsigned int ssize = rte_security_session_get_size(ctx);
> +
> +		if (ssize) {
> +			mp = rte_mempool_create("testpmd_security_pool",
> +				1, /* One sesion */

spelling "session"

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands using rte_security interface
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands " Pavel Belous
  2019-10-25 19:01   ` Stephen Hemminger
@ 2019-10-25 19:02   ` Stephen Hemminger
  1 sibling, 0 replies; 11+ messages in thread
From: Stephen Hemminger @ 2019-10-25 19:02 UTC (permalink / raw)
  To: Pavel Belous
  Cc: dev, Ferruh Yigit, Akhil Goyal, John McNamara, Declan Doherty,
	Konstantin Ananyev, Thomas Monjalon, Igor Russkikh,
	Fenilkumar Patel, Hitesh K Maisheri

On Fri, 25 Oct 2019 17:54:08 +0000
Pavel Belous <Pavel.Belous@aquantia.com> wrote:

> +int set_macsec_on_off(portid_t port_id, int on, int en, int rp)
> +{
> +	struct rte_security_session_conf macsec_conf;
> +	struct rte_security_ctx *ctx;
> +	struct rte_mempool *mp;
> +	int err = 0;
> +
> +	ctx = rte_eth_dev_get_sec_ctx(port_id);
> +
> +	if (!ctx) {

blank line between assignment and the if() statement is not necessary.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure.
  2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
                   ` (6 preceding siblings ...)
  2019-10-25 17:54 ` [dpdk-dev] [RFC v2 7/7] app/testpmd: macsec adding RX/TX SC " Pavel Belous
@ 2020-01-27 11:25 ` Akhil Goyal
  7 siblings, 0 replies; 11+ messages in thread
From: Akhil Goyal @ 2020-01-27 11:25 UTC (permalink / raw)
  To: Pavel Belous, dev
  Cc: Ferruh Yigit, John McNamara, Declan Doherty, Konstantin Ananyev,
	Thomas Monjalon, Igor Russkikh, Fenilkumar Patel,
	Hitesh K Maisheri

Hi Pavel,

> From: Pavel Belous <Pavel.Belous@aquantia.com>
> 
> This RFC suggest possible API to implement generic MACSEC HW
> offload in DPDK infrastructure.
> 
> Right now two PMDs implementing MACSEC hw offload via private
> API: ixgbe (Intel) and atlantic (Aquantia).
> 
> During that private API discussion it was decided to go further
> with well defined public API, based most probably on rte_security
> infrastructure.
> 
> Here is that previous discussion:
> 
> http://inbox.dpdk.org/dev/20190416101145.nVecHKp3w14Ptd_hne-DqHhKyzbre88PwNI-OAowXJM@z/
> 
> Declaring macsec API via rte_security gives a good data-centric view on
> parameters
> and operations macsec supports. Old, pure functional API (basically ixbe only API)
> presented function calls with big argument lists which is hard to extend and
> analyse.
> 
> However, I'd like to note rte_security has to be used via explicitly created
> mempools - this hardens abit the usage.
> It also may be hard to extend the structures in the ABI compatible way.
> 
> One of the problems with MACSEC is that internally implementation and
> hardware
> support could be either very simple, doing only endpoint encryption with a single
> TX SC (Secure Connection), or quite complex, capable to do flexible filtering
> and SC matching based on mac, vlan, ethertype and other.
> 
> Different macsec hardware supports some custom features and from our
> experience
> users would like to configure these as well. Therefore there will probably be
> needed a number of PMD specific macsec operators support.
> 
> Examples include: custom in-the-clear tag (matched by vlan id or mask),
> configurable internal logic to allow both secure and unsecure traffic,
> bypass filters on specific ethertypes.
> To support such extensions, suggest use rte_security_macsec_op enum with
> vendor specific operation codes.
> 
> In context of rte_security, MACSEC operations should normally be based on
> security session create and update calls.
> 
> Session create is used to setup overall session. Thats equivalent of old
> `macsec enable` operation.
> 
> Session update is used to update security connections and associations.
> Here xform->op contains the required operation: rx/tx session/association
> add/update/removal.
> 

The patches look good from rte_security perspective. You can send the formal
Patches for 20.05 window.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-01-27 11:25 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
2019-10-25 17:53 ` [dpdk-dev] [RFC v2 1/7] security: MACSEC infrastructure data declarations Pavel Belous
2019-10-25 17:53 ` [dpdk-dev] [RFC v2 2/7] security: Update rte_security documentation Pavel Belous
2019-10-25 17:53 ` [dpdk-dev] [RFC v2 3/7] net/atlantic: Add helper functions for PHY access Pavel Belous
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 4/7] net/atlantic: add MACSEC internal HW data declaration and functions Pavel Belous
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 5/7] net/atlantic: implementation of the MACSEC using rte_security interface Pavel Belous
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands " Pavel Belous
2019-10-25 19:01   ` Stephen Hemminger
2019-10-25 19:02   ` Stephen Hemminger
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 7/7] app/testpmd: macsec adding RX/TX SC " Pavel Belous
2020-01-27 11:25 ` [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Akhil Goyal

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).