aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2012-02-05 10:24:40 -0500
committerDavid S. Miller <davem@davemloft.net>2012-02-05 22:42:00 -0500
commit3238a9be4d7ad95c741bcfe6c147406eeef62d95 (patch)
treecfb3a9f8ca9117fb8adc8f413415262a00c8bb20 /drivers
parent94bf91baf3a16ec274de3cd913be3033c029f853 (diff)
cnic: Add FCoE parity error recovery
When bnx2x returns error on FCoE SPQ messages, generate an error completion to bnx2fc immediately to speed up error recovery. This will eliminate length timeouts and spped up the reset of the device. Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c38
-rw-r--r--drivers/net/ethernet/broadcom/cnic_defs.h3
2 files changed, 36 insertions, 5 deletions
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index dd3a0a232ea0..7381460142e6 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -1,6 +1,6 @@
1/* cnic.c: Broadcom CNIC core network driver. 1/* cnic.c: Broadcom CNIC core network driver.
2 * 2 *
3 * Copyright (c) 2006-2011 Broadcom Corporation 3 * Copyright (c) 2006-2012 Broadcom Corporation
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -2521,12 +2521,35 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe)
2521 u32 cid; 2521 u32 cid;
2522 u32 opcode = KWQE_OPCODE(kwqe->kwqe_op_flag); 2522 u32 opcode = KWQE_OPCODE(kwqe->kwqe_op_flag);
2523 u32 layer_code = kwqe->kwqe_op_flag & KWQE_LAYER_MASK; 2523 u32 layer_code = kwqe->kwqe_op_flag & KWQE_LAYER_MASK;
2524 u32 kcqe_op;
2524 int ulp_type; 2525 int ulp_type;
2525 2526
2526 cid = kwqe->kwqe_info0; 2527 cid = kwqe->kwqe_info0;
2527 memset(&kcqe, 0, sizeof(kcqe)); 2528 memset(&kcqe, 0, sizeof(kcqe));
2528 2529
2529 if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_ISCSI) { 2530 if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_FCOE) {
2531 u32 l5_cid = 0;
2532
2533 ulp_type = CNIC_ULP_FCOE;
2534 if (opcode == FCOE_KWQE_OPCODE_DISABLE_CONN) {
2535 struct fcoe_kwqe_conn_enable_disable *req;
2536
2537 req = (struct fcoe_kwqe_conn_enable_disable *) kwqe;
2538 kcqe_op = FCOE_KCQE_OPCODE_DISABLE_CONN;
2539 cid = req->context_id;
2540 l5_cid = req->conn_id;
2541 } else if (opcode == FCOE_KWQE_OPCODE_DESTROY) {
2542 kcqe_op = FCOE_KCQE_OPCODE_DESTROY_FUNC;
2543 } else {
2544 return;
2545 }
2546 kcqe.kcqe_op_flag = kcqe_op << KCQE_FLAGS_OPCODE_SHIFT;
2547 kcqe.kcqe_op_flag |= KCQE_FLAGS_LAYER_MASK_L5_FCOE;
2548 kcqe.kcqe_info1 = FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR;
2549 kcqe.kcqe_info2 = cid;
2550 kcqe.kcqe_info0 = l5_cid;
2551
2552 } else if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_ISCSI) {
2530 ulp_type = CNIC_ULP_ISCSI; 2553 ulp_type = CNIC_ULP_ISCSI;
2531 if (opcode == ISCSI_KWQE_OPCODE_UPDATE_CONN) 2554 if (opcode == ISCSI_KWQE_OPCODE_UPDATE_CONN)
2532 cid = kwqe->kwqe_info1; 2555 cid = kwqe->kwqe_info1;
@@ -2539,7 +2562,6 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe)
2539 2562
2540 } else if (layer_code == KWQE_FLAGS_LAYER_MASK_L4) { 2563 } else if (layer_code == KWQE_FLAGS_LAYER_MASK_L4) {
2541 struct l4_kcq *l4kcqe = (struct l4_kcq *) &kcqe; 2564 struct l4_kcq *l4kcqe = (struct l4_kcq *) &kcqe;
2542 u32 kcqe_op;
2543 2565
2544 ulp_type = CNIC_ULP_L4; 2566 ulp_type = CNIC_ULP_L4;
2545 if (opcode == L4_KWQE_OPCODE_VALUE_CONNECT1) 2567 if (opcode == L4_KWQE_OPCODE_VALUE_CONNECT1)
@@ -2686,9 +2708,17 @@ static int cnic_submit_bnx2x_fcoe_kwqes(struct cnic_dev *dev,
2686 opcode); 2708 opcode);
2687 break; 2709 break;
2688 } 2710 }
2689 if (ret < 0) 2711 if (ret < 0) {
2690 netdev_err(dev->netdev, "KWQE(0x%x) failed\n", 2712 netdev_err(dev->netdev, "KWQE(0x%x) failed\n",
2691 opcode); 2713 opcode);
2714
2715 /* Possibly bnx2x parity error, send completion
2716 * to ulp drivers with error code to speed up
2717 * cleanup and reset recovery.
2718 */
2719 if (ret == -EIO || ret == -EAGAIN)
2720 cnic_bnx2x_kwqe_err(dev, kwqe);
2721 }
2692 i += work; 2722 i += work;
2693 } 2723 }
2694 return 0; 2724 return 0;
diff --git a/drivers/net/ethernet/broadcom/cnic_defs.h b/drivers/net/ethernet/broadcom/cnic_defs.h
index 86936f6b6dbc..7271f14bda3b 100644
--- a/drivers/net/ethernet/broadcom/cnic_defs.h
+++ b/drivers/net/ethernet/broadcom/cnic_defs.h
@@ -1,7 +1,7 @@
1 1
2/* cnic.c: Broadcom CNIC core network driver. 2/* cnic.c: Broadcom CNIC core network driver.
3 * 3 *
4 * Copyright (c) 2006-2009 Broadcom Corporation 4 * Copyright (c) 2006-2012 Broadcom Corporation
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -69,6 +69,7 @@
69 69
70#define FCOE_KCQE_COMPLETION_STATUS_ERROR (0x1) 70#define FCOE_KCQE_COMPLETION_STATUS_ERROR (0x1)
71#define FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE (0x3) 71#define FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE (0x3)
72#define FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR (0x5)
72 73
73/* KCQ (kernel completion queue) response op codes */ 74/* KCQ (kernel completion queue) response op codes */
74#define L4_KCQE_OPCODE_VALUE_CLOSE_COMP (53) 75#define L4_KCQE_OPCODE_VALUE_CLOSE_COMP (53)