|
@@ -19,6 +19,22 @@
|
|
|
#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"
|
|
|
+};
|
|
|
+
|
|
|
+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 struct be_cmd_priv_map cmd_priv_map[] = {
|
|
|
{
|
|
|
OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
|
|
@@ -249,6 +265,29 @@ static void be_async_link_state_process(struct be_adapter *adapter,
|
|
|
evt->port_link_status & LINK_STATUS_MASK);
|
|
|
}
|
|
|
|
|
|
+static void be_async_port_misconfig_event_process(struct be_adapter *adapter,
|
|
|
+ struct be_mcc_compl *compl)
|
|
|
+{
|
|
|
+ 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);
|
|
|
+ struct device *dev = &adapter->pdev->dev;
|
|
|
+ u8 port_misconfig_evt;
|
|
|
+
|
|
|
+ port_misconfig_evt =
|
|
|
+ ((sfp_mismatch_evt >> (adapter->hba_port_num * 8)) & 0xff);
|
|
|
+
|
|
|
+ /* 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;
|
|
|
+}
|
|
|
+
|
|
|
/* Grp5 CoS Priority evt */
|
|
|
static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
|
|
|
struct be_mcc_compl *compl)
|
|
@@ -334,6 +373,16 @@ static void be_async_dbg_evt_process(struct be_adapter *adapter,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void be_async_sliport_evt_process(struct be_adapter *adapter,
|
|
|
+ struct be_mcc_compl *cmp)
|
|
|
+{
|
|
|
+ u8 event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
|
|
|
+ ASYNC_EVENT_TYPE_MASK;
|
|
|
+
|
|
|
+ if (event_type == ASYNC_EVENT_PORT_MISCONFIG)
|
|
|
+ be_async_port_misconfig_event_process(adapter, cmp);
|
|
|
+}
|
|
|
+
|
|
|
static inline bool is_link_state_evt(u32 flags)
|
|
|
{
|
|
|
return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
|
|
@@ -352,6 +401,12 @@ static inline bool is_dbg_evt(u32 flags)
|
|
|
ASYNC_EVENT_CODE_QNQ;
|
|
|
}
|
|
|
|
|
|
+static inline bool is_sliport_evt(u32 flags)
|
|
|
+{
|
|
|
+ return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
|
|
|
+ ASYNC_EVENT_CODE_SLIPORT;
|
|
|
+}
|
|
|
+
|
|
|
static void be_mcc_event_process(struct be_adapter *adapter,
|
|
|
struct be_mcc_compl *compl)
|
|
|
{
|
|
@@ -361,6 +416,8 @@ static void be_mcc_event_process(struct be_adapter *adapter,
|
|
|
be_async_grp5_evt_process(adapter, compl);
|
|
|
else if (is_dbg_evt(compl->flags))
|
|
|
be_async_dbg_evt_process(adapter, compl);
|
|
|
+ else if (is_sliport_evt(compl->flags))
|
|
|
+ be_async_sliport_evt_process(adapter, compl);
|
|
|
}
|
|
|
|
|
|
static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
|
|
@@ -1171,9 +1228,15 @@ static int be_cmd_mccq_ext_create(struct be_adapter *adapter,
|
|
|
ctxt, 1);
|
|
|
}
|
|
|
|
|
|
- /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
|
|
|
- req->async_event_bitmap[0] = cpu_to_le32(0x00000022);
|
|
|
- req->async_event_bitmap[0] |= cpu_to_le32(1 << ASYNC_EVENT_CODE_QNQ);
|
|
|
+ /* Subscribe to Link State, Sliport Event and Group 5 Events
|
|
|
+ * (bits 1, 5 and 17 set)
|
|
|
+ */
|
|
|
+ req->async_event_bitmap[0] =
|
|
|
+ cpu_to_le32(BIT(ASYNC_EVENT_CODE_LINK_STATE) |
|
|
|
+ BIT(ASYNC_EVENT_CODE_GRP_5) |
|
|
|
+ BIT(ASYNC_EVENT_CODE_QNQ) |
|
|
|
+ BIT(ASYNC_EVENT_CODE_SLIPORT));
|
|
|
+
|
|
|
be_dws_cpu_to_le(ctxt, sizeof(req->context));
|
|
|
|
|
|
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
|
|
@@ -2344,6 +2407,24 @@ int be_cmd_query_cable_type(struct be_adapter *adapter)
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+int be_cmd_query_sfp_info(struct be_adapter *adapter)
|
|
|
+{
|
|
|
+ u8 page_data[PAGE_DATA_LEN];
|
|
|
+ int status;
|
|
|
+
|
|
|
+ status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
|
|
|
+ page_data);
|
|
|
+ if (!status) {
|
|
|
+ strlcpy(adapter->phy.vendor_name, page_data +
|
|
|
+ SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);
|
|
|
+ strlcpy(adapter->phy.vendor_pn,
|
|
|
+ page_data + SFP_VENDOR_PN_OFFSET,
|
|
|
+ SFP_VENDOR_NAME_LEN - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
|
|
|
{
|
|
|
struct lancer_cmd_req_delete_object *req;
|
|
@@ -3437,42 +3518,34 @@ err:
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
-int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name)
|
|
|
+int be_cmd_query_port_name(struct be_adapter *adapter)
|
|
|
{
|
|
|
- struct be_mcc_wrb *wrb;
|
|
|
struct be_cmd_req_get_port_name *req;
|
|
|
+ struct be_mcc_wrb *wrb;
|
|
|
int status;
|
|
|
|
|
|
- if (!lancer_chip(adapter)) {
|
|
|
- *port_name = adapter->hba_port_num + '0';
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- spin_lock_bh(&adapter->mcc_lock);
|
|
|
-
|
|
|
- wrb = wrb_from_mccq(adapter);
|
|
|
- if (!wrb) {
|
|
|
- status = -EBUSY;
|
|
|
- goto err;
|
|
|
- }
|
|
|
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
|
|
|
+ return -1;
|
|
|
|
|
|
+ wrb = wrb_from_mbox(adapter);
|
|
|
req = embedded_payload(wrb);
|
|
|
|
|
|
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
|
|
OPCODE_COMMON_GET_PORT_NAME, sizeof(*req), wrb,
|
|
|
NULL);
|
|
|
- req->hdr.version = 1;
|
|
|
+ if (!BEx_chip(adapter))
|
|
|
+ req->hdr.version = 1;
|
|
|
|
|
|
- status = be_mcc_notify_wait(adapter);
|
|
|
+ status = be_mbox_notify_wait(adapter);
|
|
|
if (!status) {
|
|
|
struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb);
|
|
|
|
|
|
- *port_name = resp->port_name[adapter->hba_port_num];
|
|
|
+ adapter->port_name = resp->port_name[adapter->hba_port_num];
|
|
|
} else {
|
|
|
- *port_name = adapter->hba_port_num + '0';
|
|
|
+ adapter->port_name = adapter->hba_port_num + '0';
|
|
|
}
|
|
|
-err:
|
|
|
- spin_unlock_bh(&adapter->mcc_lock);
|
|
|
+
|
|
|
+ mutex_unlock(&adapter->mbox_lock);
|
|
|
return status;
|
|
|
}
|
|
|
|