[][Add macsec HW offload backport from kernel 5.18]

[Description]
Add macsec HW offload backport from kernel 5.18.

[Release-log]
N/A

Change-Id: I5b143fe620ec4bcae4075d1d85db5e41c8d48717
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5981730
diff --git a/target/linux/mediatek/patches-5.4/999-1771-07-v5.18-net-macsec-support-multicast-broadcast-when-offloading.patch b/target/linux/mediatek/patches-5.4/999-1771-07-v5.18-net-macsec-support-multicast-broadcast-when-offloading.patch
new file mode 100644
index 0000000..2f17478
--- /dev/null
+++ b/target/linux/mediatek/patches-5.4/999-1771-07-v5.18-net-macsec-support-multicast-broadcast-when-offloading.patch
@@ -0,0 +1,105 @@
+From f428011b90ec0de7429886f753b7c3293392761c Mon Sep 17 00:00:00 2001
+From: Mark Starovoytov <mstarovoitov@marvell.com>
+Date: Wed, 25 Mar 2020 15:52:36 +0300
+Subject: net: macsec: support multicast/broadcast when offloading
+
+The idea is simple. If the frame is an exact match for the controlled port
+(based on DA comparison), then we simply divert this skb to matching port.
+
+Multicast/broadcast messages are delivered to all ports.
+
+Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com>
+Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/macsec.c | 51 ++++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 38 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 146a7881a20ac..c7ad7c6f1d1ec 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -1006,22 +1006,53 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
+ {
+ 	/* Deliver to the uncontrolled port by default */
+ 	enum rx_handler_result ret = RX_HANDLER_PASS;
++	struct ethhdr *hdr = eth_hdr(skb);
+ 	struct macsec_rxh_data *rxd;
+ 	struct macsec_dev *macsec;
+ 
+ 	rcu_read_lock();
+ 	rxd = macsec_data_rcu(skb->dev);
+ 
+-	/* 10.6 If the management control validateFrames is not
+-	 * Strict, frames without a SecTAG are received, counted, and
+-	 * delivered to the Controlled Port
+-	 */
+ 	list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
+ 		struct sk_buff *nskb;
+ 		struct pcpu_secy_stats *secy_stats = this_cpu_ptr(macsec->stats);
++		struct net_device *ndev = macsec->secy.netdev;
+ 
+-		if (!macsec_is_offloaded(macsec) &&
+-		    macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
++		/* If h/w offloading is enabled, HW decodes frames and strips
++		 * the SecTAG, so we have to deduce which port to deliver to.
++		 */
++		if (macsec_is_offloaded(macsec) && netif_running(ndev)) {
++			if (ether_addr_equal_64bits(hdr->h_dest,
++						    ndev->dev_addr)) {
++				/* exact match, divert skb to this port */
++				skb->dev = ndev;
++				skb->pkt_type = PACKET_HOST;
++				ret = RX_HANDLER_ANOTHER;
++				goto out;
++			} else if (is_multicast_ether_addr_64bits(
++					   hdr->h_dest)) {
++				/* multicast frame, deliver on this port too */
++				nskb = skb_clone(skb, GFP_ATOMIC);
++				if (!nskb)
++					break;
++
++				nskb->dev = ndev;
++				if (ether_addr_equal_64bits(hdr->h_dest,
++							    ndev->broadcast))
++					nskb->pkt_type = PACKET_BROADCAST;
++				else
++					nskb->pkt_type = PACKET_MULTICAST;
++
++				netif_rx(nskb);
++			}
++			continue;
++		}
++
++		/* 10.6 If the management control validateFrames is not
++		 * Strict, frames without a SecTAG are received, counted, and
++		 * delivered to the Controlled Port
++		 */
++		if (macsec->secy.validate_frames == MACSEC_VALIDATE_STRICT) {
+ 			u64_stats_update_begin(&secy_stats->syncp);
+ 			secy_stats->stats.InPktsNoTag++;
+ 			u64_stats_update_end(&secy_stats->syncp);
+@@ -1033,19 +1064,13 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)
+ 		if (!nskb)
+ 			break;
+ 
+-		nskb->dev = macsec->secy.netdev;
++		nskb->dev = ndev;
+ 
+ 		if (netif_rx(nskb) == NET_RX_SUCCESS) {
+ 			u64_stats_update_begin(&secy_stats->syncp);
+ 			secy_stats->stats.InPktsUntagged++;
+ 			u64_stats_update_end(&secy_stats->syncp);
+ 		}
+-
+-		if (netif_running(macsec->secy.netdev) &&
+-		    macsec_is_offloaded(macsec)) {
+-			ret = RX_HANDLER_EXACT;
+-			goto out;
+-		}
+ 	}
+ 
+ out:
+-- 
+cgit 1.2.3-1.el7
+