diff options
author | Barak Witkowski <barak@broadcom.com> | 2012-06-25 21:31:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-27 04:20:13 -0400 |
commit | 2e499d3cc13365a87815266dda59904dcb8c8d6c (patch) | |
tree | b9f0e8b8a4356d8beb112cf76b0b97789eb335c3 | |
parent | 747cf6ed3dbf6200af761f5384893c3b621a484c (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.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 120 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 41 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h | 168 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/cnic.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/cnic_if.h | 9 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc.h | 4 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 44 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/57xx_iscsi_hsi.h | 16 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i.h | 58 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_hwi.c | 35 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_init.c | 40 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_iscsi.c | 11 |
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 */ | ||
2707 | enum 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 */ | ||
2715 | struct 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 */ | ||
2754 | struct 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*/ | ||
2778 | struct 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 | |||
2810 | union 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 */ | ||
19 | struct 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 | |||
50 | struct 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 */ | ||
60 | enum 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 */ | ||
68 | struct 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 */ | ||
107 | struct 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*/ | ||
131 | struct 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 | |||
163 | union 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 | ||
136 | struct drv_ctl_register_data { | ||
137 | int ulp_type; | ||
138 | struct fcoe_capabilities fcoe_features; | ||
139 | }; | ||
140 | |||
134 | struct drv_ctl_info { | 141 | struct 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) | |||
1326 | static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) | 1326 | static 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 | */ | ||
1715 | static 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 | */ |
269 | struct bnx2i_write_resp_task_stat { | 269 | struct 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 | */ |
276 | struct bnx2i_read_resp_task_stat { | 282 | struct 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 | |||
331 | struct 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); | |||
749 | extern void bnx2i_ulp_exit(struct cnic_dev *dev); | 805 | extern void bnx2i_ulp_exit(struct cnic_dev *dev); |
750 | extern void bnx2i_start(void *handle); | 806 | extern void bnx2i_start(void *handle); |
751 | extern void bnx2i_stop(void *handle); | 807 | extern void bnx2i_stop(void *handle); |
808 | extern int bnx2i_get_stats(void *handle); | ||
809 | |||
752 | extern struct bnx2i_hba *get_adapter_list_head(void); | 810 | extern struct bnx2i_hba *get_adapter_list_head(void); |
753 | 811 | ||
754 | struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba, | 812 | struct 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); | ||
2062 | done: | ||
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 | */ | ||
390 | int 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 | |||
1181 | bnx2i_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task) | 1186 | bnx2i_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); |