From 08f87f769b595151be1afeff53e144f543faa614 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 06 Dec 2023 09:51:13 +0000
Subject: [PATCH] add dts config

---
 kernel/drivers/scsi/qedf/qedf_fip.c |  113 +++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/kernel/drivers/scsi/qedf/qedf_fip.c b/kernel/drivers/scsi/qedf/qedf_fip.c
index 3fd3af7..ad6a56c 100644
--- a/kernel/drivers/scsi/qedf/qedf_fip.c
+++ b/kernel/drivers/scsi/qedf/qedf_fip.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  *  QLogic FCoE Offload Driver
  *  Copyright (c) 2016-2018 Cavium Inc.
- *
- *  This software is available under the terms of the GNU General Public License
- *  (GPL) Version 2, available from the file COPYING in the main directory of
- *  this source tree.
  */
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
@@ -19,17 +16,19 @@
 {
 	struct sk_buff *skb;
 	char *eth_fr;
-	int fr_len;
 	struct fip_vlan *vlan;
 #define MY_FIP_ALL_FCF_MACS        ((__u8[6]) { 1, 0x10, 0x18, 1, 0, 2 })
 	static u8 my_fcoe_all_fcfs[ETH_ALEN] = MY_FIP_ALL_FCF_MACS;
 	unsigned long flags = 0;
+	int rc;
 
 	skb = dev_alloc_skb(sizeof(struct fip_vlan));
-	if (!skb)
+	if (!skb) {
+		QEDF_ERR(&qedf->dbg_ctx,
+			 "Failed to allocate skb.\n");
 		return;
+	}
 
-	fr_len = sizeof(*vlan);
 	eth_fr = (char *)skb->data;
 	vlan = (struct fip_vlan *)eth_fr;
 
@@ -68,7 +67,13 @@
 	}
 
 	set_bit(QED_LL2_XMIT_FLAGS_FIP_DISCOVERY, &flags);
-	qed_ops->ll2->start_xmit(qedf->cdev, skb, flags);
+	rc = qed_ops->ll2->start_xmit(qedf->cdev, skb, flags);
+	if (rc) {
+		QEDF_ERR(&qedf->dbg_ctx, "start_xmit failed rc = %d.\n", rc);
+		kfree_skb(skb);
+		return;
+	}
+
 }
 
 static void qedf_fcoe_process_vlan_resp(struct qedf_ctx *qedf,
@@ -95,6 +100,12 @@
 		rlen -= dlen;
 	}
 
+	if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN) {
+		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
+			  "Dropping VLAN response as link is down.\n");
+		return;
+	}
+
 	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "VLAN response, "
 		   "vid=0x%x.\n", vid);
 
@@ -114,6 +125,7 @@
 	struct fip_header *fiph;
 	u16 op, vlan_tci = 0;
 	u8 sub;
+	int rc = -1;
 
 	if (!test_bit(QEDF_LL2_STARTED, &qedf->flags)) {
 		QEDF_WARN(&(qedf->dbg_ctx), "LL2 not started\n");
@@ -142,8 +154,15 @@
 		print_hex_dump(KERN_WARNING, "fip ", DUMP_PREFIX_OFFSET, 16, 1,
 		    skb->data, skb->len, false);
 
-	qed_ops->ll2->start_xmit(qedf->cdev, skb, 0);
+	rc = qed_ops->ll2->start_xmit(qedf->cdev, skb, 0);
+	if (rc) {
+		QEDF_ERR(&qedf->dbg_ctx, "start_xmit failed rc = %d.\n", rc);
+		kfree_skb(skb);
+		return;
+	}
 }
+
+static u8 fcoe_all_enode[ETH_ALEN] = FIP_ALL_ENODE_MACS;
 
 /* Process incoming FIP frames. */
 void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb)
@@ -157,19 +176,36 @@
 	size_t rlen, dlen;
 	u16 op;
 	u8 sub;
-	bool do_reset = false;
+	bool fcf_valid = false;
+	/* Default is to handle CVL regardless of fabric id descriptor */
+	bool fabric_id_valid = true;
+	bool fc_wwpn_valid = false;
+	u64 switch_name;
+	u16 vlan = 0;
 
 	eth_hdr = (struct ethhdr *)skb_mac_header(skb);
 	fiph = (struct fip_header *) ((void *)skb->data + 2 * ETH_ALEN + 2);
 	op = ntohs(fiph->fip_op);
 	sub = fiph->fip_subcode;
 
-	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, "FIP frame received: "
-	    "skb=%p fiph=%p source=%pM op=%x sub=%x", skb, fiph,
-	    eth_hdr->h_source, op, sub);
+	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_LL2,
+		  "FIP frame received: skb=%p fiph=%p source=%pM destn=%pM op=%x sub=%x vlan=%04x",
+		  skb, fiph, eth_hdr->h_source, eth_hdr->h_dest, op,
+		  sub, vlan);
 	if (qedf_dump_frames)
 		print_hex_dump(KERN_WARNING, "fip ", DUMP_PREFIX_OFFSET, 16, 1,
 		    skb->data, skb->len, false);
+
+	if (!ether_addr_equal(eth_hdr->h_dest, qedf->mac) &&
+	    !ether_addr_equal(eth_hdr->h_dest, fcoe_all_enode) &&
+		!ether_addr_equal(eth_hdr->h_dest, qedf->data_src_addr)) {
+		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_LL2,
+			  "Dropping FIP type 0x%x pkt due to destination MAC mismatch dest_mac=%pM ctlr.dest_addr=%pM data_src_addr=%pM.\n",
+			  op, eth_hdr->h_dest, qedf->mac,
+			  qedf->data_src_addr);
+		kfree_skb(skb);
+		return;
+	}
 
 	/* Handle FIP VLAN resp in the driver */
 	if (op == FIP_OP_VLAN && sub == FIP_SC_VL_NOTE) {
@@ -199,25 +235,42 @@
 			switch (desc->fip_dtype) {
 			case FIP_DT_MAC:
 				mp = (struct fip_mac_desc *)desc;
-				QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
-				    "fd_mac=%pM\n", mp->fd_mac);
+				QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
+					  "Switch fd_mac=%pM.\n", mp->fd_mac);
 				if (ether_addr_equal(mp->fd_mac,
 				    qedf->ctlr.sel_fcf->fcf_mac))
-					do_reset = true;
+					fcf_valid = true;
 				break;
 			case FIP_DT_NAME:
 				wp = (struct fip_wwn_desc *)desc;
-				QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
-				    "fc_wwpn=%016llx.\n",
-				    get_unaligned_be64(&wp->fd_wwn));
+				switch_name = get_unaligned_be64(&wp->fd_wwn);
+				QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
+					  "Switch fd_wwn=%016llx fcf_switch_name=%016llx.\n",
+					  switch_name,
+					  qedf->ctlr.sel_fcf->switch_name);
+				if (switch_name ==
+				    qedf->ctlr.sel_fcf->switch_name)
+					fc_wwpn_valid = true;
 				break;
 			case FIP_DT_VN_ID:
+				fabric_id_valid = false;
 				vp = (struct fip_vn_desc *)desc;
-				QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
-				    "fd_fc_id=%x.\n", ntoh24(vp->fd_fc_id));
-				if (ntoh24(vp->fd_fc_id) ==
-				    qedf->lport->port_id)
-					do_reset = true;
+
+				QEDF_ERR(&qedf->dbg_ctx,
+					 "CVL vx_port fd_fc_id=0x%x fd_mac=%pM fd_wwpn=%016llx.\n",
+					 ntoh24(vp->fd_fc_id), vp->fd_mac,
+					 get_unaligned_be64(&vp->fd_wwpn));
+				/* Check for vx_port wwpn OR Check vx_port
+				 * fabric ID OR Check vx_port MAC
+				 */
+				if ((get_unaligned_be64(&vp->fd_wwpn) ==
+					qedf->wwpn) ||
+				   (ntoh24(vp->fd_fc_id) ==
+					qedf->lport->port_id) ||
+				   (ether_addr_equal(vp->fd_mac,
+					qedf->data_src_addr))) {
+					fabric_id_valid = true;
+				}
 				break;
 			default:
 				/* Ignore anything else */
@@ -227,13 +280,11 @@
 			rlen -= dlen;
 		}
 
-		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
-		    "do_reset=%d.\n", do_reset);
-		if (do_reset) {
-			fcoe_ctlr_link_down(&qedf->ctlr);
-			qedf_wait_for_upload(qedf);
-			fcoe_ctlr_link_up(&qedf->ctlr);
-		}
+		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
+			  "fcf_valid=%d fabric_id_valid=%d fc_wwpn_valid=%d.\n",
+			  fcf_valid, fabric_id_valid, fc_wwpn_valid);
+		if (fcf_valid && fabric_id_valid && fc_wwpn_valid)
+			qedf_ctx_soft_reset(qedf->lport);
 		kfree_skb(skb);
 	} else {
 		/* Everything else is handled by libfcoe */

--
Gitblit v1.6.2