[07/10] net/atlantic: interrupt handling of macsec events

Message ID f9cc02c3c9a362a3631ba994ae4aba97e026c871.1554894242.git.igor.russkikh@aquantia.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers
Series add MACSEC hw offload to atlantic PMD |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Igor Russkikh April 10, 2019, 11:19 a.m. UTC
  From: Pavel Belous <pavel.belous@aquantia.com>

MACSEC should be configured only after link up event, thus we use
link interrupt to file an alarm for configuration.

FW also uses link interrupt line to indicate incoming events from
MACSEC. These may include key expiration, packet counter wrap, etc.
We pass these events to the upper layers.

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 drivers/net/atlantic/atl_ethdev.c | 66 ++++++++++++++++++++++++++-----
 drivers/net/atlantic/atl_ethdev.h |  2 +-
 2 files changed, 57 insertions(+), 11 deletions(-)
  

Patch

diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index 502ef5308b4d..4a6975dcf104 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -4,6 +4,7 @@ 
 
 #include <rte_string_fns.h>
 #include <rte_ethdev_pci.h>
+#include <rte_alarm.h>
 
 #include "atl_ethdev.h"
 #include "atl_common.h"
@@ -1089,13 +1090,20 @@  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)
 {
 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct atl_interrupt *intr =
-		ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 	struct rte_eth_link link, old;
 	int err = 0;
 
@@ -1122,8 +1130,6 @@  atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
 		return 0;
 	}
 
-	intr->flags &= ~ATL_FLAG_NEED_LINK_CONFIG;
-
 	link.link_status = ETH_LINK_UP;
 	link.link_duplex = ETH_LINK_FULL_DUPLEX;
 	link.link_speed = hw->aq_link_status.mbps;
@@ -1133,6 +1139,10 @@  atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
 	if (link.link_status == old.link_status)
 		return -1;
 
+	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;
 }
 
@@ -1210,8 +1220,9 @@  atl_dev_interrupt_get_status(struct rte_eth_dev *dev)
 	hw_atl_b0_hw_irq_read(hw, &cause);
 
 	atl_disable_intr(hw);
-	intr->flags = cause & BIT(ATL_IRQ_CAUSE_LINK) ?
-			ATL_FLAG_NEED_LINK_UPDATE : 0;
+
+	if (cause & BIT(ATL_IRQ_CAUSE_LINK))
+		intr->flags |= ATL_FLAG_NEED_LINK_UPDATE;
 
 	return 0;
 }
@@ -1276,15 +1287,50 @@  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 =
+		(struct atl_adapter *)dev->data->dev_private;
+	struct aq_hw_s *hw = &adapter->hw;
+
+	if (!(intr->flags & ATL_FLAG_NEED_LINK_UPDATE))
+		goto done;
 
-	if (intr->flags & ATL_FLAG_NEED_LINK_UPDATE) {
-		atl_dev_link_update(dev, 0);
-		intr->flags &= ~ATL_FLAG_NEED_LINK_UPDATE;
+	intr->flags &= ~ATL_FLAG_NEED_LINK_UPDATE;
+
+	/* Notify userapp if link status changed */
+	if (!atl_dev_link_update(dev, 0)) {
 		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_enable(intr_handle);
 
diff --git a/drivers/net/atlantic/atl_ethdev.h b/drivers/net/atlantic/atl_ethdev.h
index 1e29999b539c..cdb48e79472d 100644
--- a/drivers/net/atlantic/atl_ethdev.h
+++ b/drivers/net/atlantic/atl_ethdev.h
@@ -34,7 +34,7 @@ 
 	(&((struct atl_adapter *)adapter)->hw_cfg)
 
 #define ATL_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0)
-#define ATL_FLAG_NEED_LINK_CONFIG (uint32_t)(4 << 0)
+#define ATL_FLAG_MACSEC (uint32_t)(4 << 0)
 
 struct atl_interrupt {
 	uint32_t flags;