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: Suresh Reddy <suresh.reddy@broadcom.com>
Signed-off-by: Venkat Duvvuru <venkatkumar.duvvuru@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Ajit Khaparde 2016-02-10 22:45:54 +05:30 committed by David S. Miller
parent 6221906694
commit 51d1f98a13
4 changed files with 115 additions and 26 deletions

View File

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

View File

@ -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;
port_misconfig_evt =
((sfp_mismatch_evt >> (adapter->hba_port_num * 8)) & 0xff);
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;
/* 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 (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]);
if (port_misconfig_evt == INCOMPATIBLE_SFP)
adapter->flags |= BE_FLAGS_EVT_INCOMPATIBLE_SFP;
/* 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 */

View File

@ -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;

View File

@ -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: