aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBarak Witkowski <barak@broadcom.com>2012-06-25 21:31:19 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-27 04:20:13 -0400
commit2e499d3cc13365a87815266dda59904dcb8c8d6c (patch)
treeb9f0e8b8a4356d8beb112cf76b0b97789eb335c3
parent747cf6ed3dbf6200af761f5384893c3b621a484c (diff)
bnx2x, bnx2fc, bnx2i, cnic: Add statistics support and FCoE capabilities advertisement
1. When FCoE offload driver is registered, copy its capabilities to the chip scratchpad. 2. Copy FCoE/iSCSI MAC addresses in aligned manner to chip scratchpad. 3. Add FCoE/iSCSI statistics collection support Signed-off-by: Barak Witkowski <barak@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h120
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c41
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h168
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c11
-rw-r--r--drivers/net/ethernet/broadcom/cnic_if.h9
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc.h4
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c44
-rw-r--r--drivers/scsi/bnx2i/57xx_iscsi_hsi.h16
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h58
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c35
-rw-r--r--drivers/scsi/bnx2i/bnx2i_init.c40
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c11
13 files changed, 420 insertions, 139 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 7211cb07426e..362d16f1d256 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -51,6 +51,7 @@
51 51
52#include "bnx2x_reg.h" 52#include "bnx2x_reg.h"
53#include "bnx2x_fw_defs.h" 53#include "bnx2x_fw_defs.h"
54#include "bnx2x_mfw_req.h"
54#include "bnx2x_hsi.h" 55#include "bnx2x_hsi.h"
55#include "bnx2x_link.h" 56#include "bnx2x_link.h"
56#include "bnx2x_sp.h" 57#include "bnx2x_sp.h"
@@ -1317,6 +1318,7 @@ struct bnx2x {
1317#define NO_ISCSI_FLAG (1 << 14) 1318#define NO_ISCSI_FLAG (1 << 14)
1318#define NO_FCOE_FLAG (1 << 15) 1319#define NO_FCOE_FLAG (1 << 15)
1319#define BC_SUPPORTS_PFC_STATS (1 << 17) 1320#define BC_SUPPORTS_PFC_STATS (1 << 17)
1321#define BC_SUPPORTS_FCOE_FEATURES (1 << 19)
1320#define USING_SINGLE_MSIX_FLAG (1 << 20) 1322#define USING_SINGLE_MSIX_FLAG (1 << 20)
1321#define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21) 1323#define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21)
1322 1324
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index e7c390c66b2a..76b6e65790f8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -10,6 +10,7 @@
10#define BNX2X_HSI_H 10#define BNX2X_HSI_H
11 11
12#include "bnx2x_fw_defs.h" 12#include "bnx2x_fw_defs.h"
13#include "bnx2x_mfw_req.h"
13 14
14#define FW_ENCODE_32BIT_PATTERN 0x1e1e1e1e 15#define FW_ENCODE_32BIT_PATTERN 0x1e1e1e1e
15 16
@@ -33,12 +34,6 @@ struct license_key {
33 u32 reserved_b[4]; 34 u32 reserved_b[4];
34}; 35};
35 36
36
37#define PORT_0 0
38#define PORT_1 1
39#define PORT_MAX 2
40#define NVM_PATH_MAX 2
41
42/**************************************************************************** 37/****************************************************************************
43 * Shared HW configuration * 38 * Shared HW configuration *
44 ****************************************************************************/ 39 ****************************************************************************/
@@ -1252,6 +1247,7 @@ struct drv_func_mb {
1252 #define REQ_BC_VER_4_VRFY_AFEX_SUPPORTED 0x00070002 1247 #define REQ_BC_VER_4_VRFY_AFEX_SUPPORTED 0x00070002
1253 #define REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED 0x00070014 1248 #define REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED 0x00070014
1254 #define REQ_BC_VER_4_PFC_STATS_SUPPORTED 0x00070201 1249 #define REQ_BC_VER_4_PFC_STATS_SUPPORTED 0x00070201
1250 #define REQ_BC_VER_4_FCOE_FEATURES 0x00070209
1255 1251
1256 #define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 1252 #define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000
1257 #define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 1253 #define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000
@@ -2700,118 +2696,6 @@ struct host_func_stats {
2700/* VIC definitions */ 2696/* VIC definitions */
2701#define VICSTATST_UIF_INDEX 2 2697#define VICSTATST_UIF_INDEX 2
2702 2698
2703/* current drv_info version */
2704#define DRV_INFO_CUR_VER 1
2705
2706/* drv_info op codes supported */
2707enum drv_info_opcode {
2708 ETH_STATS_OPCODE,
2709 FCOE_STATS_OPCODE,
2710 ISCSI_STATS_OPCODE
2711};
2712
2713#define ETH_STAT_INFO_VERSION_LEN 12
2714/* Per PCI Function Ethernet Statistics required from the driver */
2715struct eth_stats_info {
2716 /* Function's Driver Version. padded to 12 */
2717 u8 version[ETH_STAT_INFO_VERSION_LEN];
2718 /* Locally Admin Addr. BigEndian EIU48. Actual size is 6 bytes */
2719 u8 mac_local[8];
2720 u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */
2721 u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */
2722 u32 mtu_size; /* MTU Size. Note : Negotiated MTU */
2723 u32 feature_flags; /* Feature_Flags. */
2724#define FEATURE_ETH_CHKSUM_OFFLOAD_MASK 0x01
2725#define FEATURE_ETH_LSO_MASK 0x02
2726#define FEATURE_ETH_BOOTMODE_MASK 0x1C
2727#define FEATURE_ETH_BOOTMODE_SHIFT 2
2728#define FEATURE_ETH_BOOTMODE_NONE (0x0 << 2)
2729#define FEATURE_ETH_BOOTMODE_PXE (0x1 << 2)
2730#define FEATURE_ETH_BOOTMODE_ISCSI (0x2 << 2)
2731#define FEATURE_ETH_BOOTMODE_FCOE (0x3 << 2)
2732#define FEATURE_ETH_TOE_MASK 0x20
2733 u32 lso_max_size; /* LSO MaxOffloadSize. */
2734 u32 lso_min_seg_cnt; /* LSO MinSegmentCount. */
2735 /* Num Offloaded Connections TCP_IPv4. */
2736 u32 ipv4_ofld_cnt;
2737 /* Num Offloaded Connections TCP_IPv6. */
2738 u32 ipv6_ofld_cnt;
2739 u32 promiscuous_mode; /* Promiscuous Mode. non-zero true */
2740 u32 txq_size; /* TX Descriptors Queue Size */
2741 u32 rxq_size; /* RX Descriptors Queue Size */
2742 /* TX Descriptor Queue Avg Depth. % Avg Queue Depth since last poll */
2743 u32 txq_avg_depth;
2744 /* RX Descriptors Queue Avg Depth. % Avg Queue Depth since last poll */
2745 u32 rxq_avg_depth;
2746 /* IOV_Offload. 0=none; 1=MultiQueue, 2=VEB 3= VEPA*/
2747 u32 iov_offload;
2748 /* Number of NetQueue/VMQ Config'd. */
2749 u32 netq_cnt;
2750 u32 vf_cnt; /* Num VF assigned to this PF. */
2751};
2752
2753/* Per PCI Function FCOE Statistics required from the driver */
2754struct fcoe_stats_info {
2755 u8 version[12]; /* Function's Driver Version. */
2756 u8 mac_local[8]; /* Locally Admin Addr. */
2757 u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */
2758 u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */
2759 /* QoS Priority (per 802.1p). 0-7255 */
2760 u32 qos_priority;
2761 u32 txq_size; /* FCoE TX Descriptors Queue Size. */
2762 u32 rxq_size; /* FCoE RX Descriptors Queue Size. */
2763 /* FCoE TX Descriptor Queue Avg Depth. */
2764 u32 txq_avg_depth;
2765 /* FCoE RX Descriptors Queue Avg Depth. */
2766 u32 rxq_avg_depth;
2767 u32 rx_frames_lo; /* FCoE RX Frames received. */
2768 u32 rx_frames_hi; /* FCoE RX Frames received. */
2769 u32 rx_bytes_lo; /* FCoE RX Bytes received. */
2770 u32 rx_bytes_hi; /* FCoE RX Bytes received. */
2771 u32 tx_frames_lo; /* FCoE TX Frames sent. */
2772 u32 tx_frames_hi; /* FCoE TX Frames sent. */
2773 u32 tx_bytes_lo; /* FCoE TX Bytes sent. */
2774 u32 tx_bytes_hi; /* FCoE TX Bytes sent. */
2775};
2776
2777/* Per PCI Function iSCSI Statistics required from the driver*/
2778struct iscsi_stats_info {
2779 u8 version[12]; /* Function's Driver Version. */
2780 u8 mac_local[8]; /* Locally Admin iSCSI MAC Addr. */
2781 u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */
2782 /* QoS Priority (per 802.1p). 0-7255 */
2783 u32 qos_priority;
2784 u8 initiator_name[64]; /* iSCSI Boot Initiator Node name. */
2785 u8 ww_port_name[64]; /* iSCSI World wide port name */
2786 u8 boot_target_name[64];/* iSCSI Boot Target Name. */
2787 u8 boot_target_ip[16]; /* iSCSI Boot Target IP. */
2788 u32 boot_target_portal; /* iSCSI Boot Target Portal. */
2789 u8 boot_init_ip[16]; /* iSCSI Boot Initiator IP Address. */
2790 u32 max_frame_size; /* Max Frame Size. bytes */
2791 u32 txq_size; /* PDU TX Descriptors Queue Size. */
2792 u32 rxq_size; /* PDU RX Descriptors Queue Size. */
2793 u32 txq_avg_depth; /* PDU TX Descriptor Queue Avg Depth. */
2794 u32 rxq_avg_depth; /* PDU RX Descriptors Queue Avg Depth. */
2795 u32 rx_pdus_lo; /* iSCSI PDUs received. */
2796 u32 rx_pdus_hi; /* iSCSI PDUs received. */
2797 u32 rx_bytes_lo; /* iSCSI RX Bytes received. */
2798 u32 rx_bytes_hi; /* iSCSI RX Bytes received. */
2799 u32 tx_pdus_lo; /* iSCSI PDUs sent. */
2800 u32 tx_pdus_hi; /* iSCSI PDUs sent. */
2801 u32 tx_bytes_lo; /* iSCSI PDU TX Bytes sent. */
2802 u32 tx_bytes_hi; /* iSCSI PDU TX Bytes sent. */
2803 u32 pcp_prior_map_tbl; /* C-PCP to S-PCP Priority MapTable.
2804 * 9 nibbles, the position of each nibble
2805 * represents the C-PCP value, the value
2806 * of the nibble = S-PCP value.
2807 */
2808};
2809
2810union drv_info_to_mcp {
2811 struct eth_stats_info ether_stat;
2812 struct fcoe_stats_info fcoe_stat;
2813 struct iscsi_stats_info iscsi_stat;
2814};
2815 2699
2816/* stats collected for afex. 2700/* stats collected for afex.
2817 * NOTE: structure is exactly as expected to be received by the switch. 2701 * NOTE: structure is exactly as expected to be received by the switch.
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 8ddc78e0d945..5b8b521bdbc3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -74,6 +74,8 @@
74#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" 74#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw"
75#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" 75#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw"
76 76
77#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
78
77/* Time in jiffies before concluding the transmitter is hung */ 79/* Time in jiffies before concluding the transmitter is hung */
78#define TX_TIMEOUT (5*HZ) 80#define TX_TIMEOUT (5*HZ)
79 81
@@ -3060,7 +3062,8 @@ static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp)
3060 struct fcoe_stats_info *fcoe_stat = 3062 struct fcoe_stats_info *fcoe_stat =
3061 &bp->slowpath->drv_info_to_mcp.fcoe_stat; 3063 &bp->slowpath->drv_info_to_mcp.fcoe_stat;
3062 3064
3063 memcpy(fcoe_stat->mac_local, bp->fip_mac, ETH_ALEN); 3065 memcpy(fcoe_stat->mac_local + MAC_LEADING_ZERO_CNT,
3066 bp->fip_mac, ETH_ALEN);
3064 3067
3065 fcoe_stat->qos_priority = 3068 fcoe_stat->qos_priority =
3066 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE]; 3069 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE];
@@ -3151,7 +3154,8 @@ static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp)
3151 struct iscsi_stats_info *iscsi_stat = 3154 struct iscsi_stats_info *iscsi_stat =
3152 &bp->slowpath->drv_info_to_mcp.iscsi_stat; 3155 &bp->slowpath->drv_info_to_mcp.iscsi_stat;
3153 3156
3154 memcpy(iscsi_stat->mac_local, bp->cnic_eth_dev.iscsi_mac, ETH_ALEN); 3157 memcpy(iscsi_stat->mac_local + MAC_LEADING_ZERO_CNT,
3158 bp->cnic_eth_dev.iscsi_mac, ETH_ALEN);
3155 3159
3156 iscsi_stat->qos_priority = 3160 iscsi_stat->qos_priority =
3157 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI]; 3161 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI];
@@ -9732,6 +9736,9 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
9732 bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ? 9736 bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ?
9733 BC_SUPPORTS_PFC_STATS : 0; 9737 BC_SUPPORTS_PFC_STATS : 0;
9734 9738
9739 bp->flags |= (val >= REQ_BC_VER_4_FCOE_FEATURES) ?
9740 BC_SUPPORTS_FCOE_FEATURES : 0;
9741
9735 bp->flags |= (val >= REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF) ? 9742 bp->flags |= (val >= REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF) ?
9736 BC_SUPPORTS_DCBX_MSG_NON_PMF : 0; 9743 BC_SUPPORTS_DCBX_MSG_NON_PMF : 0;
9737 boot_mode = SHMEM_RD(bp, 9744 boot_mode = SHMEM_RD(bp,
@@ -12548,21 +12555,45 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
12548 break; 12555 break;
12549 } 12556 }
12550 case DRV_CTL_ULP_REGISTER_CMD: { 12557 case DRV_CTL_ULP_REGISTER_CMD: {
12551 int ulp_type = ctl->data.ulp_type; 12558 int ulp_type = ctl->data.register_data.ulp_type;
12552 12559
12553 if (CHIP_IS_E3(bp)) { 12560 if (CHIP_IS_E3(bp)) {
12554 int idx = BP_FW_MB_IDX(bp); 12561 int idx = BP_FW_MB_IDX(bp);
12555 u32 cap; 12562 u32 cap = SHMEM2_RD(bp, drv_capabilities_flag[idx]);
12563 int path = BP_PATH(bp);
12564 int port = BP_PORT(bp);
12565 int i;
12566 u32 scratch_offset;
12567 u32 *host_addr;
12556 12568
12557 cap = SHMEM2_RD(bp, drv_capabilities_flag[idx]); 12569 /* first write capability to shmem2 */
12558 if (ulp_type == CNIC_ULP_ISCSI) 12570 if (ulp_type == CNIC_ULP_ISCSI)
12559 cap |= DRV_FLAGS_CAPABILITIES_LOADED_ISCSI; 12571 cap |= DRV_FLAGS_CAPABILITIES_LOADED_ISCSI;
12560 else if (ulp_type == CNIC_ULP_FCOE) 12572 else if (ulp_type == CNIC_ULP_FCOE)
12561 cap |= DRV_FLAGS_CAPABILITIES_LOADED_FCOE; 12573 cap |= DRV_FLAGS_CAPABILITIES_LOADED_FCOE;
12562 SHMEM2_WR(bp, drv_capabilities_flag[idx], cap); 12574 SHMEM2_WR(bp, drv_capabilities_flag[idx], cap);
12575
12576 if ((ulp_type != CNIC_ULP_FCOE) ||
12577 (!SHMEM2_HAS(bp, ncsi_oem_data_addr)) ||
12578 (!(bp->flags & BC_SUPPORTS_FCOE_FEATURES)))
12579 break;
12580
12581 /* if reached here - should write fcoe capabilities */
12582 scratch_offset = SHMEM2_RD(bp, ncsi_oem_data_addr);
12583 if (!scratch_offset)
12584 break;
12585 scratch_offset += offsetof(struct glob_ncsi_oem_data,
12586 fcoe_features[path][port]);
12587 host_addr = (u32 *) &(ctl->data.register_data.
12588 fcoe_features);
12589 for (i = 0; i < sizeof(struct fcoe_capabilities);
12590 i += 4)
12591 REG_WR(bp, scratch_offset + i,
12592 *(host_addr + i/4));
12563 } 12593 }
12564 break; 12594 break;
12565 } 12595 }
12596
12566 case DRV_CTL_ULP_UNREGISTER_CMD: { 12597 case DRV_CTL_ULP_UNREGISTER_CMD: {
12567 int ulp_type = ctl->data.ulp_type; 12598 int ulp_type = ctl->data.ulp_type;
12568 12599
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h
new file mode 100644
index 000000000000..ddd5106ad2f9
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h
@@ -0,0 +1,168 @@
1/* bnx2x_mfw_req.h: Broadcom Everest network driver.
2 *
3 * Copyright (c) 2012 Broadcom Corporation
4 *
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
7 * the Free Software Foundation.
8 */
9
10#ifndef BNX2X_MFW_REQ_H
11#define BNX2X_MFW_REQ_H
12
13#define PORT_0 0
14#define PORT_1 1
15#define PORT_MAX 2
16#define NVM_PATH_MAX 2
17
18/* FCoE capabilities required from the driver */
19struct fcoe_capabilities {
20 u32 capability1;
21 /* Maximum number of I/Os per connection */
22 #define FCOE_IOS_PER_CONNECTION_MASK 0x0000ffff
23 #define FCOE_IOS_PER_CONNECTION_SHIFT 0
24 /* Maximum number of Logins per port */
25 #define FCOE_LOGINS_PER_PORT_MASK 0xffff0000
26 #define FCOE_LOGINS_PER_PORT_SHIFT 16
27
28 u32 capability2;
29 /* Maximum number of exchanges */
30 #define FCOE_NUMBER_OF_EXCHANGES_MASK 0x0000ffff
31 #define FCOE_NUMBER_OF_EXCHANGES_SHIFT 0
32 /* Maximum NPIV WWN per port */
33 #define FCOE_NPIV_WWN_PER_PORT_MASK 0xffff0000
34 #define FCOE_NPIV_WWN_PER_PORT_SHIFT 16
35
36 u32 capability3;
37 /* Maximum number of targets supported */
38 #define FCOE_TARGETS_SUPPORTED_MASK 0x0000ffff
39 #define FCOE_TARGETS_SUPPORTED_SHIFT 0
40 /* Maximum number of outstanding commands across all connections */
41 #define FCOE_OUTSTANDING_COMMANDS_MASK 0xffff0000
42 #define FCOE_OUTSTANDING_COMMANDS_SHIFT 16
43
44 u32 capability4;
45 #define FCOE_CAPABILITY4_STATEFUL 0x00000001
46 #define FCOE_CAPABILITY4_STATELESS 0x00000002
47 #define FCOE_CAPABILITY4_CAPABILITIES_REPORTED_VALID 0x00000004
48};
49
50struct glob_ncsi_oem_data {
51 u32 driver_version;
52 u32 unused[3];
53 struct fcoe_capabilities fcoe_features[NVM_PATH_MAX][PORT_MAX];
54};
55
56/* current drv_info version */
57#define DRV_INFO_CUR_VER 2
58
59/* drv_info op codes supported */
60enum drv_info_opcode {
61 ETH_STATS_OPCODE,
62 FCOE_STATS_OPCODE,
63 ISCSI_STATS_OPCODE
64};
65
66#define ETH_STAT_INFO_VERSION_LEN 12
67/* Per PCI Function Ethernet Statistics required from the driver */
68struct eth_stats_info {
69 /* Function's Driver Version. padded to 12 */
70 u8 version[ETH_STAT_INFO_VERSION_LEN];
71 /* Locally Admin Addr. BigEndian EIU48. Actual size is 6 bytes */
72 u8 mac_local[8];
73 u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */
74 u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */
75 u32 mtu_size; /* MTU Size. Note : Negotiated MTU */
76 u32 feature_flags; /* Feature_Flags. */
77#define FEATURE_ETH_CHKSUM_OFFLOAD_MASK 0x01
78#define FEATURE_ETH_LSO_MASK 0x02
79#define FEATURE_ETH_BOOTMODE_MASK 0x1C
80#define FEATURE_ETH_BOOTMODE_SHIFT 2
81#define FEATURE_ETH_BOOTMODE_NONE (0x0 << 2)
82#define FEATURE_ETH_BOOTMODE_PXE (0x1 << 2)
83#define FEATURE_ETH_BOOTMODE_ISCSI (0x2 << 2)
84#define FEATURE_ETH_BOOTMODE_FCOE (0x3 << 2)
85#define FEATURE_ETH_TOE_MASK 0x20
86 u32 lso_max_size; /* LSO MaxOffloadSize. */
87 u32 lso_min_seg_cnt; /* LSO MinSegmentCount. */
88 /* Num Offloaded Connections TCP_IPv4. */
89 u32 ipv4_ofld_cnt;
90 /* Num Offloaded Connections TCP_IPv6. */
91 u32 ipv6_ofld_cnt;
92 u32 promiscuous_mode; /* Promiscuous Mode. non-zero true */
93 u32 txq_size; /* TX Descriptors Queue Size */
94 u32 rxq_size; /* RX Descriptors Queue Size */
95 /* TX Descriptor Queue Avg Depth. % Avg Queue Depth since last poll */
96 u32 txq_avg_depth;
97 /* RX Descriptors Queue Avg Depth. % Avg Queue Depth since last poll */
98 u32 rxq_avg_depth;
99 /* IOV_Offload. 0=none; 1=MultiQueue, 2=VEB 3= VEPA*/
100 u32 iov_offload;
101 /* Number of NetQueue/VMQ Config'd. */
102 u32 netq_cnt;
103 u32 vf_cnt; /* Num VF assigned to this PF. */
104};
105
106/* Per PCI Function FCOE Statistics required from the driver */
107struct fcoe_stats_info {
108 u8 version[12]; /* Function's Driver Version. */
109 u8 mac_local[8]; /* Locally Admin Addr. */
110 u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */
111 u8 mac_add2[8]; /* Additional Programmed MAC Addr 2. */
112 /* QoS Priority (per 802.1p). 0-7255 */
113 u32 qos_priority;
114 u32 txq_size; /* FCoE TX Descriptors Queue Size. */
115 u32 rxq_size; /* FCoE RX Descriptors Queue Size. */
116 /* FCoE TX Descriptor Queue Avg Depth. */
117 u32 txq_avg_depth;
118 /* FCoE RX Descriptors Queue Avg Depth. */
119 u32 rxq_avg_depth;
120 u32 rx_frames_lo; /* FCoE RX Frames received. */
121 u32 rx_frames_hi; /* FCoE RX Frames received. */
122 u32 rx_bytes_lo; /* FCoE RX Bytes received. */
123 u32 rx_bytes_hi; /* FCoE RX Bytes received. */
124 u32 tx_frames_lo; /* FCoE TX Frames sent. */
125 u32 tx_frames_hi; /* FCoE TX Frames sent. */
126 u32 tx_bytes_lo; /* FCoE TX Bytes sent. */
127 u32 tx_bytes_hi; /* FCoE TX Bytes sent. */
128};
129
130/* Per PCI Function iSCSI Statistics required from the driver*/
131struct iscsi_stats_info {
132 u8 version[12]; /* Function's Driver Version. */
133 u8 mac_local[8]; /* Locally Admin iSCSI MAC Addr. */
134 u8 mac_add1[8]; /* Additional Programmed MAC Addr 1. */
135 /* QoS Priority (per 802.1p). 0-7255 */
136 u32 qos_priority;
137 u8 initiator_name[64]; /* iSCSI Boot Initiator Node name. */
138 u8 ww_port_name[64]; /* iSCSI World wide port name */
139 u8 boot_target_name[64];/* iSCSI Boot Target Name. */
140 u8 boot_target_ip[16]; /* iSCSI Boot Target IP. */
141 u32 boot_target_portal; /* iSCSI Boot Target Portal. */
142 u8 boot_init_ip[16]; /* iSCSI Boot Initiator IP Address. */
143 u32 max_frame_size; /* Max Frame Size. bytes */
144 u32 txq_size; /* PDU TX Descriptors Queue Size. */
145 u32 rxq_size; /* PDU RX Descriptors Queue Size. */
146 u32 txq_avg_depth; /* PDU TX Descriptor Queue Avg Depth. */
147 u32 rxq_avg_depth; /* PDU RX Descriptors Queue Avg Depth. */
148 u32 rx_pdus_lo; /* iSCSI PDUs received. */
149 u32 rx_pdus_hi; /* iSCSI PDUs received. */
150 u32 rx_bytes_lo; /* iSCSI RX Bytes received. */
151 u32 rx_bytes_hi; /* iSCSI RX Bytes received. */
152 u32 tx_pdus_lo; /* iSCSI PDUs sent. */
153 u32 tx_pdus_hi; /* iSCSI PDUs sent. */
154 u32 tx_bytes_lo; /* iSCSI PDU TX Bytes sent. */
155 u32 tx_bytes_hi; /* iSCSI PDU TX Bytes sent. */
156 u32 pcp_prior_map_tbl; /* C-PCP to S-PCP Priority MapTable.
157 * 9 nibbles, the position of each nibble
158 * represents the C-PCP value, the value
159 * of the nibble = S-PCP value.
160 */
161};
162
163union drv_info_to_mcp {
164 struct eth_stats_info ether_stat;
165 struct fcoe_stats_info fcoe_stat;
166 struct iscsi_stats_info iscsi_stat;
167};
168#endif /* BNX2X_MFW_REQ_H */
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index 65e66caea50d..0e9be2ba924e 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -256,11 +256,16 @@ static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg)
256 struct cnic_local *cp = dev->cnic_priv; 256 struct cnic_local *cp = dev->cnic_priv;
257 struct cnic_eth_dev *ethdev = cp->ethdev; 257 struct cnic_eth_dev *ethdev = cp->ethdev;
258 struct drv_ctl_info info; 258 struct drv_ctl_info info;
259 struct fcoe_capabilities *fcoe_cap =
260 &info.data.register_data.fcoe_features;
259 261
260 if (reg) 262 if (reg) {
261 info.cmd = DRV_CTL_ULP_REGISTER_CMD; 263 info.cmd = DRV_CTL_ULP_REGISTER_CMD;
262 else 264 if (ulp_type == CNIC_ULP_FCOE && dev->fcoe_cap)
265 memcpy(fcoe_cap, dev->fcoe_cap, sizeof(*fcoe_cap));
266 } else {
263 info.cmd = DRV_CTL_ULP_UNREGISTER_CMD; 267 info.cmd = DRV_CTL_ULP_UNREGISTER_CMD;
268 }
264 269
265 info.data.ulp_type = ulp_type; 270 info.data.ulp_type = ulp_type;
266 ethdev->drv_ctl(dev->netdev, &info); 271 ethdev->drv_ctl(dev->netdev, &info);
@@ -611,6 +616,8 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
611 616
612 if (ulp_type == CNIC_ULP_ISCSI) 617 if (ulp_type == CNIC_ULP_ISCSI)
613 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); 618 cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
619 else if (ulp_type == CNIC_ULP_FCOE)
620 dev->fcoe_cap = NULL;
614 621
615 synchronize_rcu(); 622 synchronize_rcu();
616 623
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 289274e546be..d63d45591c1f 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -12,6 +12,8 @@
12#ifndef CNIC_IF_H 12#ifndef CNIC_IF_H
13#define CNIC_IF_H 13#define CNIC_IF_H
14 14
15#include "bnx2x/bnx2x_mfw_req.h"
16
15#define CNIC_MODULE_VERSION "2.5.10" 17#define CNIC_MODULE_VERSION "2.5.10"
16#define CNIC_MODULE_RELDATE "March 21, 2012" 18#define CNIC_MODULE_RELDATE "March 21, 2012"
17 19
@@ -131,6 +133,11 @@ struct drv_ctl_l2_ring {
131 u32 cid; 133 u32 cid;
132}; 134};
133 135
136struct drv_ctl_register_data {
137 int ulp_type;
138 struct fcoe_capabilities fcoe_features;
139};
140
134struct drv_ctl_info { 141struct drv_ctl_info {
135 int cmd; 142 int cmd;
136 union { 143 union {
@@ -138,6 +145,7 @@ struct drv_ctl_info {
138 struct drv_ctl_io io; 145 struct drv_ctl_io io;
139 struct drv_ctl_l2_ring ring; 146 struct drv_ctl_l2_ring ring;
140 int ulp_type; 147 int ulp_type;
148 struct drv_ctl_register_data register_data;
141 char bytes[MAX_DRV_CTL_DATA]; 149 char bytes[MAX_DRV_CTL_DATA];
142 } data; 150 } data;
143}; 151};
@@ -305,6 +313,7 @@ struct cnic_dev {
305 int max_rdma_conn; 313 int max_rdma_conn;
306 314
307 union drv_info_to_mcp *stats_addr; 315 union drv_info_to_mcp *stats_addr;
316 struct fcoe_capabilities *fcoe_cap;
308 317
309 void *cnic_priv; 318 void *cnic_priv;
310}; 319};
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 0578fa0dc14b..42969e8a45bd 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -59,6 +59,7 @@
59#include "57xx_hsi_bnx2fc.h" 59#include "57xx_hsi_bnx2fc.h"
60#include "bnx2fc_debug.h" 60#include "bnx2fc_debug.h"
61#include "../../net/ethernet/broadcom/cnic_if.h" 61#include "../../net/ethernet/broadcom/cnic_if.h"
62#include "../../net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h"
62#include "bnx2fc_constants.h" 63#include "bnx2fc_constants.h"
63 64
64#define BNX2FC_NAME "bnx2fc" 65#define BNX2FC_NAME "bnx2fc"
@@ -84,6 +85,8 @@
84#define BNX2FC_NUM_MAX_SESS 1024 85#define BNX2FC_NUM_MAX_SESS 1024
85#define BNX2FC_NUM_MAX_SESS_LOG (ilog2(BNX2FC_NUM_MAX_SESS)) 86#define BNX2FC_NUM_MAX_SESS_LOG (ilog2(BNX2FC_NUM_MAX_SESS))
86 87
88#define BNX2FC_MAX_NPIV 256
89
87#define BNX2FC_MAX_OUTSTANDING_CMNDS 2048 90#define BNX2FC_MAX_OUTSTANDING_CMNDS 2048
88#define BNX2FC_CAN_QUEUE BNX2FC_MAX_OUTSTANDING_CMNDS 91#define BNX2FC_CAN_QUEUE BNX2FC_MAX_OUTSTANDING_CMNDS
89#define BNX2FC_ELSTM_XIDS BNX2FC_CAN_QUEUE 92#define BNX2FC_ELSTM_XIDS BNX2FC_CAN_QUEUE
@@ -206,6 +209,7 @@ struct bnx2fc_hba {
206 struct fcoe_statistics_params *stats_buffer; 209 struct fcoe_statistics_params *stats_buffer;
207 dma_addr_t stats_buf_dma; 210 dma_addr_t stats_buf_dma;
208 struct completion stat_req_done; 211 struct completion stat_req_done;
212 struct fcoe_capabilities fcoe_cap;
209 213
210 /*destroy handling */ 214 /*destroy handling */
211 struct timer_list destroy_timer; 215 struct timer_list destroy_timer;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index f52f668fd247..05fe6620b3f0 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -1326,6 +1326,7 @@ static void bnx2fc_hba_destroy(struct bnx2fc_hba *hba)
1326static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) 1326static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic)
1327{ 1327{
1328 struct bnx2fc_hba *hba; 1328 struct bnx2fc_hba *hba;
1329 struct fcoe_capabilities *fcoe_cap;
1329 int rc; 1330 int rc;
1330 1331
1331 hba = kzalloc(sizeof(*hba), GFP_KERNEL); 1332 hba = kzalloc(sizeof(*hba), GFP_KERNEL);
@@ -1361,6 +1362,21 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic)
1361 printk(KERN_ERR PFX "em_config:bnx2fc_cmd_mgr_alloc failed\n"); 1362 printk(KERN_ERR PFX "em_config:bnx2fc_cmd_mgr_alloc failed\n");
1362 goto cmgr_err; 1363 goto cmgr_err;
1363 } 1364 }
1365 fcoe_cap = &hba->fcoe_cap;
1366
1367 fcoe_cap->capability1 = BNX2FC_TM_MAX_SQES <<
1368 FCOE_IOS_PER_CONNECTION_SHIFT;
1369 fcoe_cap->capability1 |= BNX2FC_NUM_MAX_SESS <<
1370 FCOE_LOGINS_PER_PORT_SHIFT;
1371 fcoe_cap->capability2 = BNX2FC_MAX_OUTSTANDING_CMNDS <<
1372 FCOE_NUMBER_OF_EXCHANGES_SHIFT;
1373 fcoe_cap->capability2 |= BNX2FC_MAX_NPIV <<
1374 FCOE_NPIV_WWN_PER_PORT_SHIFT;
1375 fcoe_cap->capability3 = BNX2FC_NUM_MAX_SESS <<
1376 FCOE_TARGETS_SUPPORTED_SHIFT;
1377 fcoe_cap->capability3 |= BNX2FC_MAX_OUTSTANDING_CMNDS <<
1378 FCOE_OUTSTANDING_COMMANDS_SHIFT;
1379 fcoe_cap->capability4 = FCOE_CAPABILITY4_STATEFUL;
1364 1380
1365 init_waitqueue_head(&hba->shutdown_wait); 1381 init_waitqueue_head(&hba->shutdown_wait);
1366 init_waitqueue_head(&hba->destroy_wait); 1382 init_waitqueue_head(&hba->destroy_wait);
@@ -1691,6 +1707,32 @@ static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba)
1691 hba->pcidev = NULL; 1707 hba->pcidev = NULL;
1692} 1708}
1693 1709
1710/**
1711 * bnx2fc_ulp_get_stats - cnic callback to populate FCoE stats
1712 *
1713 * @handle: transport handle pointing to adapter struture
1714 */
1715static int bnx2fc_ulp_get_stats(void *handle)
1716{
1717 struct bnx2fc_hba *hba = handle;
1718 struct cnic_dev *cnic;
1719 struct fcoe_stats_info *stats_addr;
1720
1721 if (!hba)
1722 return -EINVAL;
1723
1724 cnic = hba->cnic;
1725 stats_addr = &cnic->stats_addr->fcoe_stat;
1726 if (!stats_addr)
1727 return -EINVAL;
1728
1729 strncpy(stats_addr->version, BNX2FC_VERSION,
1730 sizeof(stats_addr->version));
1731 stats_addr->txq_size = BNX2FC_SQ_WQES_MAX;
1732 stats_addr->rxq_size = BNX2FC_CQ_WQES_MAX;
1733
1734 return 0;
1735}
1694 1736
1695 1737
1696/** 1738/**
@@ -1944,6 +1986,7 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev)
1944 adapter_count++; 1986 adapter_count++;
1945 mutex_unlock(&bnx2fc_dev_lock); 1987 mutex_unlock(&bnx2fc_dev_lock);
1946 1988
1989 dev->fcoe_cap = &hba->fcoe_cap;
1947 clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic); 1990 clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
1948 rc = dev->register_device(dev, CNIC_ULP_FCOE, 1991 rc = dev->register_device(dev, CNIC_ULP_FCOE,
1949 (void *) hba); 1992 (void *) hba);
@@ -2643,4 +2686,5 @@ static struct cnic_ulp_ops bnx2fc_cnic_cb = {
2643 .cnic_stop = bnx2fc_ulp_stop, 2686 .cnic_stop = bnx2fc_ulp_stop,
2644 .indicate_kcqes = bnx2fc_indicate_kcqe, 2687 .indicate_kcqes = bnx2fc_indicate_kcqe,
2645 .indicate_netevent = bnx2fc_indicate_netevent, 2688 .indicate_netevent = bnx2fc_indicate_netevent,
2689 .cnic_get_stats = bnx2fc_ulp_get_stats,
2646}; 2690};
diff --git a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
index dc0a08e69c82..f2db5fe7bdc2 100644
--- a/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
+++ b/drivers/scsi/bnx2i/57xx_iscsi_hsi.h
@@ -267,7 +267,13 @@ struct bnx2i_cmd_request {
267 * task statistics for write response 267 * task statistics for write response
268 */ 268 */
269struct bnx2i_write_resp_task_stat { 269struct bnx2i_write_resp_task_stat {
270 u32 num_data_ins; 270#if defined(__BIG_ENDIAN)
271 u16 num_r2ts;
272 u16 num_data_outs;
273#elif defined(__LITTLE_ENDIAN)
274 u16 num_data_outs;
275 u16 num_r2ts;
276#endif
271}; 277};
272 278
273/* 279/*
@@ -275,11 +281,11 @@ struct bnx2i_write_resp_task_stat {
275 */ 281 */
276struct bnx2i_read_resp_task_stat { 282struct bnx2i_read_resp_task_stat {
277#if defined(__BIG_ENDIAN) 283#if defined(__BIG_ENDIAN)
278 u16 num_data_outs; 284 u16 reserved;
279 u16 num_r2ts; 285 u16 num_data_ins;
280#elif defined(__LITTLE_ENDIAN) 286#elif defined(__LITTLE_ENDIAN)
281 u16 num_r2ts; 287 u16 num_data_ins;
282 u16 num_data_outs; 288 u16 reserved;
283#endif 289#endif
284}; 290};
285 291
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index 0c53c28dc3d3..2e326145825c 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -44,6 +44,8 @@
44#include "57xx_iscsi_hsi.h" 44#include "57xx_iscsi_hsi.h"
45#include "57xx_iscsi_constants.h" 45#include "57xx_iscsi_constants.h"
46 46
47#include "../../net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h"
48
47#define BNX2_ISCSI_DRIVER_NAME "bnx2i" 49#define BNX2_ISCSI_DRIVER_NAME "bnx2i"
48 50
49#define BNX2I_MAX_ADAPTERS 8 51#define BNX2I_MAX_ADAPTERS 8
@@ -126,6 +128,43 @@
126#define REG_WR(__hba, offset, val) \ 128#define REG_WR(__hba, offset, val) \
127 writel(val, __hba->regview + offset) 129 writel(val, __hba->regview + offset)
128 130
131#ifdef CONFIG_32BIT
132#define GET_STATS_64(__hba, dst, field) \
133 do { \
134 spin_lock_bh(&__hba->stat_lock); \
135 dst->field##_lo = __hba->stats.field##_lo; \
136 dst->field##_hi = __hba->stats.field##_hi; \
137 spin_unlock_bh(&__hba->stat_lock); \
138 } while (0)
139
140#define ADD_STATS_64(__hba, field, len) \
141 do { \
142 if (spin_trylock(&__hba->stat_lock)) { \
143 if (__hba->stats.field##_lo + len < \
144 __hba->stats.field##_lo) \
145 __hba->stats.field##_hi++; \
146 __hba->stats.field##_lo += len; \
147 spin_unlock(&__hba->stat_lock); \
148 } \
149 } while (0)
150
151#else
152#define GET_STATS_64(__hba, dst, field) \
153 do { \
154 u64 val, *out; \
155 \
156 val = __hba->bnx2i_stats.field; \
157 out = (u64 *)&__hba->stats.field##_lo; \
158 *out = cpu_to_le64(val); \
159 out = (u64 *)&dst->field##_lo; \
160 *out = cpu_to_le64(val); \
161 } while (0)
162
163#define ADD_STATS_64(__hba, field, len) \
164 do { \
165 __hba->bnx2i_stats.field += len; \
166 } while (0)
167#endif
129 168
130/** 169/**
131 * struct generic_pdu_resc - login pdu resource structure 170 * struct generic_pdu_resc - login pdu resource structure
@@ -288,6 +327,15 @@ struct iscsi_cid_queue {
288 struct bnx2i_conn **conn_cid_tbl; 327 struct bnx2i_conn **conn_cid_tbl;
289}; 328};
290 329
330
331struct bnx2i_stats_info {
332 u64 rx_pdus;
333 u64 rx_bytes;
334 u64 tx_pdus;
335 u64 tx_bytes;
336};
337
338
291/** 339/**
292 * struct bnx2i_hba - bnx2i adapter structure 340 * struct bnx2i_hba - bnx2i adapter structure
293 * 341 *
@@ -341,6 +389,8 @@ struct iscsi_cid_queue {
341 * @ctx_ccell_tasks: captures number of ccells and tasks supported by 389 * @ctx_ccell_tasks: captures number of ccells and tasks supported by
342 * currently offloaded connection, used to decode 390 * currently offloaded connection, used to decode
343 * context memory 391 * context memory
392 * @stat_lock: spin lock used by the statistic collector (32 bit)
393 * @stats: local iSCSI statistic collection place holder
344 * 394 *
345 * Adapter Data Structure 395 * Adapter Data Structure
346 */ 396 */
@@ -426,6 +476,12 @@ struct bnx2i_hba {
426 u32 num_sess_opened; 476 u32 num_sess_opened;
427 u32 num_conn_opened; 477 u32 num_conn_opened;
428 unsigned int ctx_ccell_tasks; 478 unsigned int ctx_ccell_tasks;
479
480#ifdef CONFIG_32BIT
481 spinlock_t stat_lock;
482#endif
483 struct bnx2i_stats_info bnx2i_stats;
484 struct iscsi_stats_info stats;
429}; 485};
430 486
431 487
@@ -749,6 +805,8 @@ extern void bnx2i_ulp_init(struct cnic_dev *dev);
749extern void bnx2i_ulp_exit(struct cnic_dev *dev); 805extern void bnx2i_ulp_exit(struct cnic_dev *dev);
750extern void bnx2i_start(void *handle); 806extern void bnx2i_start(void *handle);
751extern void bnx2i_stop(void *handle); 807extern void bnx2i_stop(void *handle);
808extern int bnx2i_get_stats(void *handle);
809
752extern struct bnx2i_hba *get_adapter_list_head(void); 810extern struct bnx2i_hba *get_adapter_list_head(void);
753 811
754struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba, 812struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba,
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index ece47e502282..49e8b056ca10 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1350,6 +1350,7 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session,
1350 struct cqe *cqe) 1350 struct cqe *cqe)
1351{ 1351{
1352 struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data; 1352 struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
1353 struct bnx2i_hba *hba = bnx2i_conn->hba;
1353 struct bnx2i_cmd_response *resp_cqe; 1354 struct bnx2i_cmd_response *resp_cqe;
1354 struct bnx2i_cmd *bnx2i_cmd; 1355 struct bnx2i_cmd *bnx2i_cmd;
1355 struct iscsi_task *task; 1356 struct iscsi_task *task;
@@ -1367,16 +1368,26 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session,
1367 1368
1368 if (bnx2i_cmd->req.op_attr & ISCSI_CMD_REQUEST_READ) { 1369 if (bnx2i_cmd->req.op_attr & ISCSI_CMD_REQUEST_READ) {
1369 conn->datain_pdus_cnt += 1370 conn->datain_pdus_cnt +=
1370 resp_cqe->task_stat.read_stat.num_data_outs; 1371 resp_cqe->task_stat.read_stat.num_data_ins;
1371 conn->rxdata_octets += 1372 conn->rxdata_octets +=
1372 bnx2i_cmd->req.total_data_transfer_length; 1373 bnx2i_cmd->req.total_data_transfer_length;
1374 ADD_STATS_64(hba, rx_pdus,
1375 resp_cqe->task_stat.read_stat.num_data_ins);
1376 ADD_STATS_64(hba, rx_bytes,
1377 bnx2i_cmd->req.total_data_transfer_length);
1373 } else { 1378 } else {
1374 conn->dataout_pdus_cnt += 1379 conn->dataout_pdus_cnt +=
1375 resp_cqe->task_stat.read_stat.num_data_outs; 1380 resp_cqe->task_stat.write_stat.num_data_outs;
1376 conn->r2t_pdus_cnt += 1381 conn->r2t_pdus_cnt +=
1377 resp_cqe->task_stat.read_stat.num_r2ts; 1382 resp_cqe->task_stat.write_stat.num_r2ts;
1378 conn->txdata_octets += 1383 conn->txdata_octets +=
1379 bnx2i_cmd->req.total_data_transfer_length; 1384 bnx2i_cmd->req.total_data_transfer_length;
1385 ADD_STATS_64(hba, tx_pdus,
1386 resp_cqe->task_stat.write_stat.num_data_outs);
1387 ADD_STATS_64(hba, tx_bytes,
1388 bnx2i_cmd->req.total_data_transfer_length);
1389 ADD_STATS_64(hba, rx_pdus,
1390 resp_cqe->task_stat.write_stat.num_r2ts);
1380 } 1391 }
1381 bnx2i_iscsi_unmap_sg_list(bnx2i_cmd); 1392 bnx2i_iscsi_unmap_sg_list(bnx2i_cmd);
1382 1393
@@ -1961,6 +1972,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
1961{ 1972{
1962 struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data; 1973 struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
1963 struct iscsi_session *session = conn->session; 1974 struct iscsi_session *session = conn->session;
1975 struct bnx2i_hba *hba = bnx2i_conn->hba;
1964 struct qp_info *qp; 1976 struct qp_info *qp;
1965 struct bnx2i_nop_in_msg *nopin; 1977 struct bnx2i_nop_in_msg *nopin;
1966 int tgt_async_msg; 1978 int tgt_async_msg;
@@ -1973,7 +1985,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
1973 1985
1974 if (!qp->cq_virt) { 1986 if (!qp->cq_virt) {
1975 printk(KERN_ALERT "bnx2i (%s): cq resr freed in bh execution!", 1987 printk(KERN_ALERT "bnx2i (%s): cq resr freed in bh execution!",
1976 bnx2i_conn->hba->netdev->name); 1988 hba->netdev->name);
1977 goto out; 1989 goto out;
1978 } 1990 }
1979 while (1) { 1991 while (1) {
@@ -1985,9 +1997,9 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
1985 if (nopin->op_code == ISCSI_OP_NOOP_IN && 1997 if (nopin->op_code == ISCSI_OP_NOOP_IN &&
1986 nopin->itt == (u16) RESERVED_ITT) { 1998 nopin->itt == (u16) RESERVED_ITT) {
1987 printk(KERN_ALERT "bnx2i: Unsolicited " 1999 printk(KERN_ALERT "bnx2i: Unsolicited "
1988 "NOP-In detected for suspended " 2000 "NOP-In detected for suspended "
1989 "connection dev=%s!\n", 2001 "connection dev=%s!\n",
1990 bnx2i_conn->hba->netdev->name); 2002 hba->netdev->name);
1991 bnx2i_unsol_pdu_adjust_rq(bnx2i_conn); 2003 bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
1992 goto cqe_out; 2004 goto cqe_out;
1993 } 2005 }
@@ -2001,7 +2013,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
2001 /* Run the kthread engine only for data cmds 2013 /* Run the kthread engine only for data cmds
2002 All other cmds will be completed in this bh! */ 2014 All other cmds will be completed in this bh! */
2003 bnx2i_queue_scsi_cmd_resp(session, bnx2i_conn, nopin); 2015 bnx2i_queue_scsi_cmd_resp(session, bnx2i_conn, nopin);
2004 break; 2016 goto done;
2005 case ISCSI_OP_LOGIN_RSP: 2017 case ISCSI_OP_LOGIN_RSP:
2006 bnx2i_process_login_resp(session, bnx2i_conn, 2018 bnx2i_process_login_resp(session, bnx2i_conn,
2007 qp->cq_cons_qe); 2019 qp->cq_cons_qe);
@@ -2044,11 +2056,15 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn *bnx2i_conn)
2044 printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n", 2056 printk(KERN_ALERT "bnx2i: unknown opcode 0x%x\n",
2045 nopin->op_code); 2057 nopin->op_code);
2046 } 2058 }
2059
2060 ADD_STATS_64(hba, rx_pdus, 1);
2061 ADD_STATS_64(hba, rx_bytes, nopin->data_length);
2062done:
2047 if (!tgt_async_msg) { 2063 if (!tgt_async_msg) {
2048 if (!atomic_read(&bnx2i_conn->ep->num_active_cmds)) 2064 if (!atomic_read(&bnx2i_conn->ep->num_active_cmds))
2049 printk(KERN_ALERT "bnx2i (%s): no active cmd! " 2065 printk(KERN_ALERT "bnx2i (%s): no active cmd! "
2050 "op 0x%x\n", 2066 "op 0x%x\n",
2051 bnx2i_conn->hba->netdev->name, 2067 hba->netdev->name,
2052 nopin->op_code); 2068 nopin->op_code);
2053 else 2069 else
2054 atomic_dec(&bnx2i_conn->ep->num_active_cmds); 2070 atomic_dec(&bnx2i_conn->ep->num_active_cmds);
@@ -2692,6 +2708,7 @@ struct cnic_ulp_ops bnx2i_cnic_cb = {
2692 .cm_remote_close = bnx2i_cm_remote_close, 2708 .cm_remote_close = bnx2i_cm_remote_close,
2693 .cm_remote_abort = bnx2i_cm_remote_abort, 2709 .cm_remote_abort = bnx2i_cm_remote_abort,
2694 .iscsi_nl_send_msg = bnx2i_send_nl_mesg, 2710 .iscsi_nl_send_msg = bnx2i_send_nl_mesg,
2711 .cnic_get_stats = bnx2i_get_stats,
2695 .owner = THIS_MODULE 2712 .owner = THIS_MODULE
2696}; 2713};
2697 2714
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 8b6816706ee5..7729a5223b33 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -381,6 +381,46 @@ void bnx2i_ulp_exit(struct cnic_dev *dev)
381 381
382 382
383/** 383/**
384 * bnx2i_get_stats - Retrieve various statistic from iSCSI offload
385 * @handle: bnx2i_hba
386 *
387 * function callback exported via bnx2i - cnic driver interface to
388 * retrieve various iSCSI offload related statistics.
389 */
390int bnx2i_get_stats(void *handle)
391{
392 struct bnx2i_hba *hba = handle;
393 struct iscsi_stats_info *stats;
394
395 if (!hba)
396 return -EINVAL;
397
398 stats = (struct iscsi_stats_info *)hba->cnic->stats_addr;
399
400 if (!stats)
401 return -ENOMEM;
402
403 memcpy(stats->version, DRV_MODULE_VERSION, sizeof(stats->version));
404 memcpy(stats->mac_add1 + 2, hba->cnic->mac_addr, ETH_ALEN);
405
406 stats->max_frame_size = hba->netdev->mtu;
407 stats->txq_size = hba->max_sqes;
408 stats->rxq_size = hba->max_cqes;
409
410 stats->txq_avg_depth = 0;
411 stats->rxq_avg_depth = 0;
412
413 GET_STATS_64(hba, stats, rx_pdus);
414 GET_STATS_64(hba, stats, rx_bytes);
415
416 GET_STATS_64(hba, stats, tx_pdus);
417 GET_STATS_64(hba, stats, tx_bytes);
418
419 return 0;
420}
421
422
423/**
384 * bnx2i_percpu_thread_create - Create a receive thread for an 424 * bnx2i_percpu_thread_create - Create a receive thread for an
385 * online CPU 425 * online CPU
386 * 426 *
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index f8d516b53161..b40ac017012c 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -874,6 +874,11 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic)
874 hba->conn_ctx_destroy_tmo = 2 * HZ; 874 hba->conn_ctx_destroy_tmo = 2 * HZ;
875 } 875 }
876 876
877#ifdef CONFIG_32BIT
878 spin_lock_init(&hba->stat_lock);
879#endif
880 memset(&hba->stats, 0, sizeof(struct iscsi_stats_info));
881
877 if (iscsi_host_add(shost, &hba->pcidev->dev)) 882 if (iscsi_host_add(shost, &hba->pcidev->dev))
878 goto free_dump_mem; 883 goto free_dump_mem;
879 return hba; 884 return hba;
@@ -1181,12 +1186,18 @@ static int
1181bnx2i_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task) 1186bnx2i_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
1182{ 1187{
1183 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1188 struct bnx2i_conn *bnx2i_conn = conn->dd_data;
1189 struct bnx2i_hba *hba = bnx2i_conn->hba;
1184 struct bnx2i_cmd *cmd = task->dd_data; 1190 struct bnx2i_cmd *cmd = task->dd_data;
1185 1191
1186 memset(bnx2i_conn->gen_pdu.req_buf, 0, ISCSI_DEF_MAX_RECV_SEG_LEN); 1192 memset(bnx2i_conn->gen_pdu.req_buf, 0, ISCSI_DEF_MAX_RECV_SEG_LEN);
1187 1193
1188 bnx2i_setup_cmd_wqe_template(cmd); 1194 bnx2i_setup_cmd_wqe_template(cmd);
1189 bnx2i_conn->gen_pdu.req_buf_size = task->data_count; 1195 bnx2i_conn->gen_pdu.req_buf_size = task->data_count;
1196
1197 /* Tx PDU/data length count */
1198 ADD_STATS_64(hba, tx_pdus, 1);
1199 ADD_STATS_64(hba, tx_bytes, task->data_count);
1200
1190 if (task->data_count) { 1201 if (task->data_count) {
1191 memcpy(bnx2i_conn->gen_pdu.req_buf, task->data, 1202 memcpy(bnx2i_conn->gen_pdu.req_buf, task->data,
1192 task->data_count); 1203 task->data_count);