1*4882a593Smuzhiyun /* bnx2i_sysfs.c: QLogic NetXtreme II iSCSI driver.
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Copyright (c) 2004 - 2013 Broadcom Corporation
4*4882a593Smuzhiyun * Copyright (c) 2014, QLogic Corporation
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify
7*4882a593Smuzhiyun * it under the terms of the GNU General Public License as published by
8*4882a593Smuzhiyun * the Free Software Foundation.
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
11*4882a593Smuzhiyun * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
12*4882a593Smuzhiyun * Maintained by: QLogic-Storage-Upstream@qlogic.com
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include "bnx2i.h"
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun /**
18*4882a593Smuzhiyun * bnx2i_dev_to_hba - maps dev pointer to adapter struct
19*4882a593Smuzhiyun * @dev: device pointer
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * Map device to hba structure
22*4882a593Smuzhiyun */
bnx2i_dev_to_hba(struct device * dev)23*4882a593Smuzhiyun static inline struct bnx2i_hba *bnx2i_dev_to_hba(struct device *dev)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun struct Scsi_Host *shost = class_to_shost(dev);
26*4882a593Smuzhiyun return iscsi_host_priv(shost);
27*4882a593Smuzhiyun }
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun /**
31*4882a593Smuzhiyun * bnx2i_show_sq_info - return(s currently configured send queue (SQ) size
32*4882a593Smuzhiyun * @dev: device pointer
33*4882a593Smuzhiyun * @attr: device attribute (unused)
34*4882a593Smuzhiyun * @buf: buffer to return current SQ size parameter
35*4882a593Smuzhiyun *
36*4882a593Smuzhiyun * Returns current SQ size parameter, this paramater determines the number
37*4882a593Smuzhiyun * outstanding iSCSI commands supported on a connection
38*4882a593Smuzhiyun */
bnx2i_show_sq_info(struct device * dev,struct device_attribute * attr,char * buf)39*4882a593Smuzhiyun static ssize_t bnx2i_show_sq_info(struct device *dev,
40*4882a593Smuzhiyun struct device_attribute *attr, char *buf)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun return sprintf(buf, "0x%x\n", hba->max_sqes);
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /**
49*4882a593Smuzhiyun * bnx2i_set_sq_info - update send queue (SQ) size parameter
50*4882a593Smuzhiyun * @dev: device pointer
51*4882a593Smuzhiyun * @attr: device attribute (unused)
52*4882a593Smuzhiyun * @buf: buffer to return current SQ size parameter
53*4882a593Smuzhiyun * @count: parameter buffer size
54*4882a593Smuzhiyun *
55*4882a593Smuzhiyun * Interface for user to change shared queue size allocated for each conn
56*4882a593Smuzhiyun * Must be within SQ limits and a power of 2. For the latter this is needed
57*4882a593Smuzhiyun * because of how libiscsi preallocates tasks.
58*4882a593Smuzhiyun */
bnx2i_set_sq_info(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)59*4882a593Smuzhiyun static ssize_t bnx2i_set_sq_info(struct device *dev,
60*4882a593Smuzhiyun struct device_attribute *attr,
61*4882a593Smuzhiyun const char *buf, size_t count)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
64*4882a593Smuzhiyun u32 val;
65*4882a593Smuzhiyun int max_sq_size;
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun if (hba->ofld_conns_active)
68*4882a593Smuzhiyun goto skip_config;
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
71*4882a593Smuzhiyun max_sq_size = BNX2I_5770X_SQ_WQES_MAX;
72*4882a593Smuzhiyun else
73*4882a593Smuzhiyun max_sq_size = BNX2I_570X_SQ_WQES_MAX;
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun if (sscanf(buf, " 0x%x ", &val) > 0) {
76*4882a593Smuzhiyun if ((val >= BNX2I_SQ_WQES_MIN) && (val <= max_sq_size) &&
77*4882a593Smuzhiyun (is_power_of_2(val)))
78*4882a593Smuzhiyun hba->max_sqes = val;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun return count;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun skip_config:
84*4882a593Smuzhiyun printk(KERN_ERR "bnx2i: device busy, cannot change SQ size\n");
85*4882a593Smuzhiyun return 0;
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /**
90*4882a593Smuzhiyun * bnx2i_show_ccell_info - returns command cell (HQ) size
91*4882a593Smuzhiyun * @dev: device pointer
92*4882a593Smuzhiyun * @attr: device attribute (unused)
93*4882a593Smuzhiyun * @buf: buffer to return current SQ size parameter
94*4882a593Smuzhiyun *
95*4882a593Smuzhiyun * returns per-connection TCP history queue size parameter
96*4882a593Smuzhiyun */
bnx2i_show_ccell_info(struct device * dev,struct device_attribute * attr,char * buf)97*4882a593Smuzhiyun static ssize_t bnx2i_show_ccell_info(struct device *dev,
98*4882a593Smuzhiyun struct device_attribute *attr, char *buf)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun return sprintf(buf, "0x%x\n", hba->num_ccell);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /**
107*4882a593Smuzhiyun * bnx2i_get_link_state - set command cell (HQ) size
108*4882a593Smuzhiyun * @dev: device pointer
109*4882a593Smuzhiyun * @attr: device attribute (unused)
110*4882a593Smuzhiyun * @buf: buffer to return current SQ size parameter
111*4882a593Smuzhiyun * @count: parameter buffer size
112*4882a593Smuzhiyun *
113*4882a593Smuzhiyun * updates per-connection TCP history queue size parameter
114*4882a593Smuzhiyun */
bnx2i_set_ccell_info(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)115*4882a593Smuzhiyun static ssize_t bnx2i_set_ccell_info(struct device *dev,
116*4882a593Smuzhiyun struct device_attribute *attr,
117*4882a593Smuzhiyun const char *buf, size_t count)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun u32 val;
120*4882a593Smuzhiyun struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun if (hba->ofld_conns_active)
123*4882a593Smuzhiyun goto skip_config;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun if (sscanf(buf, " 0x%x ", &val) > 0) {
126*4882a593Smuzhiyun if ((val >= BNX2I_CCELLS_MIN) &&
127*4882a593Smuzhiyun (val <= BNX2I_CCELLS_MAX)) {
128*4882a593Smuzhiyun hba->num_ccell = val;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun return count;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun skip_config:
135*4882a593Smuzhiyun printk(KERN_ERR "bnx2i: device busy, cannot change CCELL size\n");
136*4882a593Smuzhiyun return 0;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun static DEVICE_ATTR(sq_size, S_IRUGO | S_IWUSR,
141*4882a593Smuzhiyun bnx2i_show_sq_info, bnx2i_set_sq_info);
142*4882a593Smuzhiyun static DEVICE_ATTR(num_ccell, S_IRUGO | S_IWUSR,
143*4882a593Smuzhiyun bnx2i_show_ccell_info, bnx2i_set_ccell_info);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun struct device_attribute *bnx2i_dev_attributes[] = {
146*4882a593Smuzhiyun &dev_attr_sq_size,
147*4882a593Smuzhiyun &dev_attr_num_ccell,
148*4882a593Smuzhiyun NULL
149*4882a593Smuzhiyun };
150