Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51d1f98a authored by Ajit Khaparde's avatar Ajit Khaparde Committed by David S. Miller
Browse files

be2net: Interpret and log new data that's added to the port misconfigure async event



>From FW version 11.0. onwards, the PORT_MISCONFIG event generated by the FW
will carry more information about the event in the "data_word1"
and "data_word2" fields. This patch adds support in the driver to parse the
new information and log it accordingly. This patch also changes some of the
messages that are being logged currently.

Signed-off-by: default avatarSuresh Reddy <suresh.reddy@broadcom.com>
Signed-off-by: default avatarVenkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Signed-off-by: default avatarAjit Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 62219066
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -115,6 +115,8 @@
#define	RSS_INDIR_TABLE_LEN	128
#define RSS_HASH_KEY_LEN	40

#define BE_UNKNOWN_PHY_STATE	0xFF

struct be_dma_mem {
	void *va;
	dma_addr_t dma;
@@ -390,7 +392,7 @@ enum vf_state {
#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD		BIT(7)
#define BE_FLAGS_VXLAN_OFFLOADS			BIT(8)
#define BE_FLAGS_SETUP_DONE			BIT(9)
#define BE_FLAGS_EVT_INCOMPATIBLE_SFP		BIT(10)
#define BE_FLAGS_PHY_MISCONFIGURED		BIT(10)
#define BE_FLAGS_ERR_DETECTION_SCHEDULED	BIT(11)
#define BE_FLAGS_OS2BMC				BIT(12)

@@ -603,6 +605,7 @@ struct be_adapter {
	u32 bmc_filt_mask;
	u32 fat_dump_len;
	u16 serial_num[CNTL_SERIAL_NUM_WORDS];
	u8 phy_state; /* state of sfp optics (functional, faulted, etc.,) */
};

#define be_physfn(adapter)		(!adapter->virtfn)
+61 −21
Original line number Diff line number Diff line
@@ -19,19 +19,25 @@
#include "be.h"
#include "be_cmds.h"

static char *be_port_misconfig_evt_desc[] = {
	"A valid SFP module detected",
	"Optics faulted/ incorrectly installed/ not installed.",
	"Optics of two types installed.",
	"Incompatible optics.",
	"Unknown port SFP status"
char *be_misconfig_evt_port_state[] = {
	"Physical Link is functional",
	"Optics faulted/incorrectly installed/not installed - Reseat optics. If issue not resolved, replace.",
	"Optics of two types installed – Remove one optic or install matching pair of optics.",
	"Incompatible optics – Replace with compatible optics for card to function.",
	"Unqualified optics – Replace with Avago optics for Warranty and Technical Support.",
	"Uncertified optics – Replace with Avago-certified optics to enable link operation."
};

static char *be_port_misconfig_remedy_desc[] = {
	"",
	"Reseat optics. If issue not resolved, replace",
	"Remove one optic or install matching pair of optics",
	"Replace with compatible optics for card to function",
static char *be_port_misconfig_evt_severity[] = {
	"KERN_WARN",
	"KERN_INFO",
	"KERN_ERR",
	"KERN_WARN"
};

static char *phy_state_oper_desc[] = {
	"Link is non-operational",
	"Link is operational",
	""
};

@@ -297,22 +303,56 @@ static void be_async_port_misconfig_event_process(struct be_adapter *adapter,
{
	struct be_async_event_misconfig_port *evt =
			(struct be_async_event_misconfig_port *)compl;
	u32 sfp_mismatch_evt = le32_to_cpu(evt->event_data_word1);
	u32 sfp_misconfig_evt_word1 = le32_to_cpu(evt->event_data_word1);
	u32 sfp_misconfig_evt_word2 = le32_to_cpu(evt->event_data_word2);
	u8 phy_oper_state = PHY_STATE_OPER_MSG_NONE;
	struct device *dev = &adapter->pdev->dev;
	u8 port_misconfig_evt;
	u8 msg_severity = DEFAULT_MSG_SEVERITY;
	u8 phy_state_info;
	u8 new_phy_state;

	new_phy_state =
		(sfp_misconfig_evt_word1 >> (adapter->hba_port_num * 8)) & 0xff;

	if (new_phy_state == adapter->phy_state)
		return;

	adapter->phy_state = new_phy_state;

	port_misconfig_evt =
		((sfp_mismatch_evt >> (adapter->hba_port_num * 8)) & 0xff);
	/* for older fw that doesn't populate link effect data */
	if (!sfp_misconfig_evt_word2)
		goto log_message;

	phy_state_info =
		(sfp_misconfig_evt_word2 >> (adapter->hba_port_num * 8)) & 0xff;

	if (phy_state_info & PHY_STATE_INFO_VALID) {
		msg_severity = (phy_state_info & PHY_STATE_MSG_SEVERITY) >> 1;

		if (be_phy_unqualified(new_phy_state))
			phy_oper_state = (phy_state_info & PHY_STATE_OPER);
	}

log_message:
	/* Log an error message that would allow a user to determine
	 * whether the SFPs have an issue
	 */
	dev_info(dev, "Port %c: %s %s", adapter->port_name,
		 be_port_misconfig_evt_desc[port_misconfig_evt],
		 be_port_misconfig_remedy_desc[port_misconfig_evt]);

	if (port_misconfig_evt == INCOMPATIBLE_SFP)
		adapter->flags |= BE_FLAGS_EVT_INCOMPATIBLE_SFP;
	if (be_phy_state_unknown(new_phy_state))
		dev_printk(be_port_misconfig_evt_severity[msg_severity], dev,
			   "Port %c: Unrecognized Optics state: 0x%x. %s",
			   adapter->port_name,
			   new_phy_state,
			   phy_state_oper_desc[phy_oper_state]);
	else
		dev_printk(be_port_misconfig_evt_severity[msg_severity], dev,
			   "Port %c: %s %s",
			   adapter->port_name,
			   be_misconfig_evt_port_state[new_phy_state],
			   phy_state_oper_desc[phy_oper_state]);

	/* Log Vendor name and part no. if a misconfigured SFP is detected */
	if (be_phy_misconfigured(new_phy_state))
		adapter->flags |= BE_FLAGS_PHY_MISCONFIGURED;
}

/* Grp5 CoS Priority evt */
+44 −1
Original line number Diff line number Diff line
@@ -176,10 +176,53 @@ struct be_async_event_qnq {
	u32 flags;
} __packed;

#define INCOMPATIBLE_SFP		0x3
enum {
	BE_PHY_FUNCTIONAL	= 0,
	BE_PHY_NOT_PRESENT	= 1,
	BE_PHY_DIFF_MEDIA	= 2,
	BE_PHY_INCOMPATIBLE	= 3,
	BE_PHY_UNQUALIFIED	= 4,
	BE_PHY_UNCERTIFIED	= 5
};

#define PHY_STATE_MSG_SEVERITY		0x6
#define PHY_STATE_OPER			0x1
#define PHY_STATE_INFO_VALID		0x80
#define	PHY_STATE_OPER_MSG_NONE		0x2
#define DEFAULT_MSG_SEVERITY		0x1

#define be_phy_state_unknown(phy_state) (phy_state > BE_PHY_UNCERTIFIED)
#define be_phy_unqualified(phy_state)				\
			(phy_state == BE_PHY_UNQUALIFIED ||	\
			 phy_state == BE_PHY_UNCERTIFIED)
#define be_phy_misconfigured(phy_state)				\
			(phy_state == BE_PHY_INCOMPATIBLE ||	\
			 phy_state == BE_PHY_UNQUALIFIED ||	\
			 phy_state == BE_PHY_UNCERTIFIED)

extern  char *be_misconfig_evt_port_state[];

/* async event indicating misconfigured port */
struct be_async_event_misconfig_port {
 /* DATA_WORD1:
  * phy state of port 0: bits 7 - 0
  * phy state of port 1: bits 15 - 8
  * phy state of port 2: bits 23 - 16
  * phy state of port 3: bits 31 - 24
  */
	u32 event_data_word1;
 /* DATA_WORD2:
  * phy state info of port 0: bits 7 - 0
  * phy state info of port 1: bits 15 - 8
  * phy state info of port 2: bits 23 - 16
  * phy state info of port 3: bits 31 - 24
  *
  * PHY STATE INFO:
  * Link operability	 :bit 0
  * Message severity	 :bit 2 - 1
  * Rsvd			 :bits 6 - 3
  * phy state info valid	 :bit 7
  */
	u32 event_data_word2;
	u32 rsvd0;
	u32 flags;
+7 −4
Original line number Diff line number Diff line
@@ -4089,6 +4089,7 @@ static void be_setup_init(struct be_adapter *adapter)
	adapter->if_handle = -1;
	adapter->be3_native = false;
	adapter->if_flags = 0;
	adapter->phy_state = BE_UNKNOWN_PHY_STATE;
	if (be_physfn(adapter))
		adapter->cmd_privileges = MAX_PRIVILEGES;
	else
@@ -4961,11 +4962,13 @@ static void be_log_sfp_info(struct be_adapter *adapter)
	status = be_cmd_query_sfp_info(adapter);
	if (!status) {
		dev_err(&adapter->pdev->dev,
			"Unqualified SFP+ detected on %c from %s part no: %s",
			adapter->port_name, adapter->phy.vendor_name,
			"Port %c: %s Vendor: %s part no: %s",
			adapter->port_name,
			be_misconfig_evt_port_state[adapter->phy_state],
			adapter->phy.vendor_name,
			adapter->phy.vendor_pn);
	}
	adapter->flags &= ~BE_FLAGS_EVT_INCOMPATIBLE_SFP;
	adapter->flags &= ~BE_FLAGS_PHY_MISCONFIGURED;
}

static void be_worker(struct work_struct *work)
@@ -5009,7 +5012,7 @@ static void be_worker(struct work_struct *work)
	if (!skyhawk_chip(adapter))
		be_eqd_update(adapter, false);

	if (adapter->flags & BE_FLAGS_EVT_INCOMPATIBLE_SFP)
	if (adapter->flags & BE_FLAGS_PHY_MISCONFIGURED)
		be_log_sfp_info(adapter);

reschedule: