aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorVasundhara Volam <vasundhara.volam@emulex.com>2015-02-06 08:18:42 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-08 01:50:59 -0500
commit21252377bb2b9f038b4c9d829f69cafca4a4c1c7 (patch)
tree27d1abe0d5d04ac2070fbba7c45044493a98b2f4 /drivers/net/ethernet
parentf66b7cfd95a5e13ca8bc4854252cd027f3d7fe86 (diff)
be2net: process port misconfig async event
This patch adds support for processing the port misconfigure async event generated by the FW. This event is generated typically when an optical module is incorrectly installed or is faulty. This patch also moves the port_name field to the adapter struct for logging the event. As the be_cmd_query_port_name() call is now moved to be_get_config(), it is modified to use the mailbox instead of MCCQ Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h6
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c119
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h16
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c28
4 files changed, 139 insertions, 30 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 98716e1c7615..27de37aa90af 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -368,6 +368,7 @@ enum vf_state {
368#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD BIT(7) 368#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD BIT(7)
369#define BE_FLAGS_VXLAN_OFFLOADS BIT(8) 369#define BE_FLAGS_VXLAN_OFFLOADS BIT(8)
370#define BE_FLAGS_SETUP_DONE BIT(9) 370#define BE_FLAGS_SETUP_DONE BIT(9)
371#define BE_FLAGS_EVT_INCOMPATIBLE_SFP BIT(10)
371 372
372#define BE_UC_PMAC_COUNT 30 373#define BE_UC_PMAC_COUNT 30
373#define BE_VF_UC_PMAC_COUNT 2 374#define BE_VF_UC_PMAC_COUNT 2
@@ -377,6 +378,8 @@ enum vf_state {
377#define LANCER_DELETE_FW_DUMP 0x2 378#define LANCER_DELETE_FW_DUMP 0x2
378 379
379struct phy_info { 380struct phy_info {
381/* From SFF-8472 spec */
382#define SFP_VENDOR_NAME_LEN 17
380 u8 transceiver; 383 u8 transceiver;
381 u8 autoneg; 384 u8 autoneg;
382 u8 fc_autoneg; 385 u8 fc_autoneg;
@@ -390,6 +393,8 @@ struct phy_info {
390 u32 advertising; 393 u32 advertising;
391 u32 supported; 394 u32 supported;
392 u8 cable_type; 395 u8 cable_type;
396 u8 vendor_name[SFP_VENDOR_NAME_LEN];
397 u8 vendor_pn[SFP_VENDOR_NAME_LEN];
393}; 398};
394 399
395struct be_resources { 400struct be_resources {
@@ -478,6 +483,7 @@ struct be_adapter {
478 bool hw_error; 483 bool hw_error;
479 484
480 u32 port_num; 485 u32 port_num;
486 char port_name;
481 u8 mc_type; 487 u8 mc_type;
482 u32 function_mode; 488 u32 function_mode;
483 u32 function_caps; 489 u32 function_caps;
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index ceae6235e707..36916cfa70f9 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -19,6 +19,22 @@
19#include "be.h" 19#include "be.h"
20#include "be_cmds.h" 20#include "be_cmds.h"
21 21
22static char *be_port_misconfig_evt_desc[] = {
23 "A valid SFP module detected",
24 "Optics faulted/ incorrectly installed/ not installed.",
25 "Optics of two types installed.",
26 "Incompatible optics.",
27 "Unknown port SFP status"
28};
29
30static char *be_port_misconfig_remedy_desc[] = {
31 "",
32 "Reseat optics. If issue not resolved, replace",
33 "Remove one optic or install matching pair of optics",
34 "Replace with compatible optics for card to function",
35 ""
36};
37
22static struct be_cmd_priv_map cmd_priv_map[] = { 38static struct be_cmd_priv_map cmd_priv_map[] = {
23 { 39 {
24 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG, 40 OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
@@ -249,6 +265,29 @@ static void be_async_link_state_process(struct be_adapter *adapter,
249 evt->port_link_status & LINK_STATUS_MASK); 265 evt->port_link_status & LINK_STATUS_MASK);
250} 266}
251 267
268static void be_async_port_misconfig_event_process(struct be_adapter *adapter,
269 struct be_mcc_compl *compl)
270{
271 struct be_async_event_misconfig_port *evt =
272 (struct be_async_event_misconfig_port *)compl;
273 u32 sfp_mismatch_evt = le32_to_cpu(evt->event_data_word1);
274 struct device *dev = &adapter->pdev->dev;
275 u8 port_misconfig_evt;
276
277 port_misconfig_evt =
278 ((sfp_mismatch_evt >> (adapter->hba_port_num * 8)) & 0xff);
279
280 /* Log an error message that would allow a user to determine
281 * whether the SFPs have an issue
282 */
283 dev_info(dev, "Port %c: %s %s", adapter->port_name,
284 be_port_misconfig_evt_desc[port_misconfig_evt],
285 be_port_misconfig_remedy_desc[port_misconfig_evt]);
286
287 if (port_misconfig_evt == INCOMPATIBLE_SFP)
288 adapter->flags |= BE_FLAGS_EVT_INCOMPATIBLE_SFP;
289}
290
252/* Grp5 CoS Priority evt */ 291/* Grp5 CoS Priority evt */
253static void be_async_grp5_cos_priority_process(struct be_adapter *adapter, 292static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
254 struct be_mcc_compl *compl) 293 struct be_mcc_compl *compl)
@@ -334,6 +373,16 @@ static void be_async_dbg_evt_process(struct be_adapter *adapter,
334 } 373 }
335} 374}
336 375
376static void be_async_sliport_evt_process(struct be_adapter *adapter,
377 struct be_mcc_compl *cmp)
378{
379 u8 event_type = (cmp->flags >> ASYNC_EVENT_TYPE_SHIFT) &
380 ASYNC_EVENT_TYPE_MASK;
381
382 if (event_type == ASYNC_EVENT_PORT_MISCONFIG)
383 be_async_port_misconfig_event_process(adapter, cmp);
384}
385
337static inline bool is_link_state_evt(u32 flags) 386static inline bool is_link_state_evt(u32 flags)
338{ 387{
339 return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) == 388 return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
@@ -352,6 +401,12 @@ static inline bool is_dbg_evt(u32 flags)
352 ASYNC_EVENT_CODE_QNQ; 401 ASYNC_EVENT_CODE_QNQ;
353} 402}
354 403
404static inline bool is_sliport_evt(u32 flags)
405{
406 return ((flags >> ASYNC_EVENT_CODE_SHIFT) & ASYNC_EVENT_CODE_MASK) ==
407 ASYNC_EVENT_CODE_SLIPORT;
408}
409
355static void be_mcc_event_process(struct be_adapter *adapter, 410static void be_mcc_event_process(struct be_adapter *adapter,
356 struct be_mcc_compl *compl) 411 struct be_mcc_compl *compl)
357{ 412{
@@ -361,6 +416,8 @@ static void be_mcc_event_process(struct be_adapter *adapter,
361 be_async_grp5_evt_process(adapter, compl); 416 be_async_grp5_evt_process(adapter, compl);
362 else if (is_dbg_evt(compl->flags)) 417 else if (is_dbg_evt(compl->flags))
363 be_async_dbg_evt_process(adapter, compl); 418 be_async_dbg_evt_process(adapter, compl);
419 else if (is_sliport_evt(compl->flags))
420 be_async_sliport_evt_process(adapter, compl);
364} 421}
365 422
366static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) 423static 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,
1171 ctxt, 1); 1228 ctxt, 1);
1172 } 1229 }
1173 1230
1174 /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ 1231 /* Subscribe to Link State, Sliport Event and Group 5 Events
1175 req->async_event_bitmap[0] = cpu_to_le32(0x00000022); 1232 * (bits 1, 5 and 17 set)
1176 req->async_event_bitmap[0] |= cpu_to_le32(1 << ASYNC_EVENT_CODE_QNQ); 1233 */
1234 req->async_event_bitmap[0] =
1235 cpu_to_le32(BIT(ASYNC_EVENT_CODE_LINK_STATE) |
1236 BIT(ASYNC_EVENT_CODE_GRP_5) |
1237 BIT(ASYNC_EVENT_CODE_QNQ) |
1238 BIT(ASYNC_EVENT_CODE_SLIPORT));
1239
1177 be_dws_cpu_to_le(ctxt, sizeof(req->context)); 1240 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1178 1241
1179 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); 1242 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)
2344 return status; 2407 return status;
2345} 2408}
2346 2409
2410int be_cmd_query_sfp_info(struct be_adapter *adapter)
2411{
2412 u8 page_data[PAGE_DATA_LEN];
2413 int status;
2414
2415 status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
2416 page_data);
2417 if (!status) {
2418 strlcpy(adapter->phy.vendor_name, page_data +
2419 SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1);
2420 strlcpy(adapter->phy.vendor_pn,
2421 page_data + SFP_VENDOR_PN_OFFSET,
2422 SFP_VENDOR_NAME_LEN - 1);
2423 }
2424
2425 return status;
2426}
2427
2347int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name) 2428int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name)
2348{ 2429{
2349 struct lancer_cmd_req_delete_object *req; 2430 struct lancer_cmd_req_delete_object *req;
@@ -3437,42 +3518,34 @@ err:
3437 return status; 3518 return status;
3438} 3519}
3439 3520
3440int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name) 3521int be_cmd_query_port_name(struct be_adapter *adapter)
3441{ 3522{
3442 struct be_mcc_wrb *wrb;
3443 struct be_cmd_req_get_port_name *req; 3523 struct be_cmd_req_get_port_name *req;
3524 struct be_mcc_wrb *wrb;
3444 int status; 3525 int status;
3445 3526
3446 if (!lancer_chip(adapter)) { 3527 if (mutex_lock_interruptible(&adapter->mbox_lock))
3447 *port_name = adapter->hba_port_num + '0'; 3528 return -1;
3448 return 0;
3449 }
3450
3451 spin_lock_bh(&adapter->mcc_lock);
3452
3453 wrb = wrb_from_mccq(adapter);
3454 if (!wrb) {
3455 status = -EBUSY;
3456 goto err;
3457 }
3458 3529
3530 wrb = wrb_from_mbox(adapter);
3459 req = embedded_payload(wrb); 3531 req = embedded_payload(wrb);
3460 3532
3461 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 3533 be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
3462 OPCODE_COMMON_GET_PORT_NAME, sizeof(*req), wrb, 3534 OPCODE_COMMON_GET_PORT_NAME, sizeof(*req), wrb,
3463 NULL); 3535 NULL);
3464 req->hdr.version = 1; 3536 if (!BEx_chip(adapter))
3537 req->hdr.version = 1;
3465 3538
3466 status = be_mcc_notify_wait(adapter); 3539 status = be_mbox_notify_wait(adapter);
3467 if (!status) { 3540 if (!status) {
3468 struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb); 3541 struct be_cmd_resp_get_port_name *resp = embedded_payload(wrb);
3469 3542
3470 *port_name = resp->port_name[adapter->hba_port_num]; 3543 adapter->port_name = resp->port_name[adapter->hba_port_num];
3471 } else { 3544 } else {
3472 *port_name = adapter->hba_port_num + '0'; 3545 adapter->port_name = adapter->hba_port_num + '0';
3473 } 3546 }
3474err: 3547
3475 spin_unlock_bh(&adapter->mcc_lock); 3548 mutex_unlock(&adapter->mbox_lock);
3476 return status; 3549 return status;
3477} 3550}
3478 3551
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index cf9d87086546..db761e8e42a3 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -102,6 +102,8 @@ struct be_mcc_compl {
102#define ASYNC_EVENT_PVID_STATE 0x3 102#define ASYNC_EVENT_PVID_STATE 0x3
103#define ASYNC_EVENT_CODE_QNQ 0x6 103#define ASYNC_EVENT_CODE_QNQ 0x6
104#define ASYNC_DEBUG_EVENT_TYPE_QNQ 1 104#define ASYNC_DEBUG_EVENT_TYPE_QNQ 1
105#define ASYNC_EVENT_CODE_SLIPORT 0x11
106#define ASYNC_EVENT_PORT_MISCONFIG 0x9
105 107
106enum { 108enum {
107 LINK_DOWN = 0x0, 109 LINK_DOWN = 0x0,
@@ -169,6 +171,15 @@ struct be_async_event_qnq {
169 u32 flags; 171 u32 flags;
170} __packed; 172} __packed;
171 173
174#define INCOMPATIBLE_SFP 0x3
175/* async event indicating misconfigured port */
176struct be_async_event_misconfig_port {
177 u32 event_data_word1;
178 u32 event_data_word2;
179 u32 rsvd0;
180 u32 flags;
181} __packed;
182
172struct be_mcc_mailbox { 183struct be_mcc_mailbox {
173 struct be_mcc_wrb wrb; 184 struct be_mcc_wrb wrb;
174 struct be_mcc_compl compl; 185 struct be_mcc_compl compl;
@@ -1028,6 +1039,8 @@ enum {
1028#define SFP_PLUS_SFF_8472_COMP 0x5E 1039#define SFP_PLUS_SFF_8472_COMP 0x5E
1029#define SFP_PLUS_CABLE_TYPE_OFFSET 0x8 1040#define SFP_PLUS_CABLE_TYPE_OFFSET 0x8
1030#define SFP_PLUS_COPPER_CABLE 0x4 1041#define SFP_PLUS_COPPER_CABLE 0x4
1042#define SFP_VENDOR_NAME_OFFSET 0x14
1043#define SFP_VENDOR_PN_OFFSET 0x28
1031 1044
1032#define PAGE_DATA_LEN 256 1045#define PAGE_DATA_LEN 256
1033struct be_cmd_resp_port_type { 1046struct be_cmd_resp_port_type {
@@ -2259,6 +2272,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num,
2259int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, 2272int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
2260 u8 page_num, u8 *data); 2273 u8 page_num, u8 *data);
2261int be_cmd_query_cable_type(struct be_adapter *adapter); 2274int be_cmd_query_cable_type(struct be_adapter *adapter);
2275int be_cmd_query_sfp_info(struct be_adapter *adapter);
2262int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, 2276int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
2263 u32 flash_oper, u32 flash_opcode, u32 img_offset, 2277 u32 flash_oper, u32 flash_opcode, u32 img_offset,
2264 u32 buf_size); 2278 u32 buf_size);
@@ -2326,7 +2340,7 @@ int lancer_initiate_dump(struct be_adapter *adapter);
2326int lancer_delete_dump(struct be_adapter *adapter); 2340int lancer_delete_dump(struct be_adapter *adapter);
2327bool dump_present(struct be_adapter *adapter); 2341bool dump_present(struct be_adapter *adapter);
2328int lancer_test_and_set_rdy_state(struct be_adapter *adapter); 2342int lancer_test_and_set_rdy_state(struct be_adapter *adapter);
2329int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name); 2343int be_cmd_query_port_name(struct be_adapter *adapter);
2330int be_cmd_get_func_config(struct be_adapter *adapter, 2344int be_cmd_get_func_config(struct be_adapter *adapter,
2331 struct be_resources *res); 2345 struct be_resources *res);
2332int be_cmd_get_profile_config(struct be_adapter *adapter, 2346int be_cmd_get_profile_config(struct be_adapter *adapter,
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 617038fa92f0..195d357e2f3f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3682,7 +3682,9 @@ static int be_get_config(struct be_adapter *adapter)
3682 if (status) 3682 if (status)
3683 return status; 3683 return status;
3684 3684
3685 if (be_physfn(adapter)) { 3685 be_cmd_query_port_name(adapter);
3686
3687 if (be_physfn(adapter)) {
3686 status = be_cmd_get_active_profile(adapter, &profile_id); 3688 status = be_cmd_get_active_profile(adapter, &profile_id);
3687 if (!status) 3689 if (!status)
3688 dev_info(&adapter->pdev->dev, 3690 dev_info(&adapter->pdev->dev,
@@ -5052,6 +5054,20 @@ static void be_func_recovery_task(struct work_struct *work)
5052 msecs_to_jiffies(1000)); 5054 msecs_to_jiffies(1000));
5053} 5055}
5054 5056
5057static void be_log_sfp_info(struct be_adapter *adapter)
5058{
5059 int status;
5060
5061 status = be_cmd_query_sfp_info(adapter);
5062 if (!status) {
5063 dev_err(&adapter->pdev->dev,
5064 "Unqualified SFP+ detected on %c from %s part no: %s",
5065 adapter->port_name, adapter->phy.vendor_name,
5066 adapter->phy.vendor_pn);
5067 }
5068 adapter->flags &= ~BE_FLAGS_EVT_INCOMPATIBLE_SFP;
5069}
5070
5055static void be_worker(struct work_struct *work) 5071static void be_worker(struct work_struct *work)
5056{ 5072{
5057 struct be_adapter *adapter = 5073 struct be_adapter *adapter =
@@ -5090,6 +5106,9 @@ static void be_worker(struct work_struct *work)
5090 5106
5091 be_eqd_update(adapter); 5107 be_eqd_update(adapter);
5092 5108
5109 if (adapter->flags & BE_FLAGS_EVT_INCOMPATIBLE_SFP)
5110 be_log_sfp_info(adapter);
5111
5093reschedule: 5112reschedule:
5094 adapter->work_counter++; 5113 adapter->work_counter++;
5095 schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); 5114 schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
@@ -5158,10 +5177,9 @@ static inline char *nic_name(struct pci_dev *pdev)
5158 5177
5159static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) 5178static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
5160{ 5179{
5161 int status = 0;
5162 struct be_adapter *adapter; 5180 struct be_adapter *adapter;
5163 struct net_device *netdev; 5181 struct net_device *netdev;
5164 char port_name; 5182 int status = 0;
5165 5183
5166 dev_info(&pdev->dev, "%s version is %s\n", DRV_NAME, DRV_VER); 5184 dev_info(&pdev->dev, "%s version is %s\n", DRV_NAME, DRV_VER);
5167 5185
@@ -5255,10 +5273,8 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
5255 schedule_delayed_work(&adapter->func_recovery_work, 5273 schedule_delayed_work(&adapter->func_recovery_work,
5256 msecs_to_jiffies(1000)); 5274 msecs_to_jiffies(1000));
5257 5275
5258 be_cmd_query_port_name(adapter, &port_name);
5259
5260 dev_info(&pdev->dev, "%s: %s %s port %c\n", nic_name(pdev), 5276 dev_info(&pdev->dev, "%s: %s %s port %c\n", nic_name(pdev),
5261 func_name(adapter), mc_name(adapter), port_name); 5277 func_name(adapter), mc_name(adapter), adapter->port_name);
5262 5278
5263 return 0; 5279 return 0;
5264 5280