aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi')
-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
7 files changed, 194 insertions, 14 deletions
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);