162306a36Sopenharmony_ci/* bnx2i_sysfs.c: QLogic NetXtreme II iSCSI driver. 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Copyright (c) 2004 - 2013 Broadcom Corporation 462306a36Sopenharmony_ci * Copyright (c) 2014, QLogic Corporation 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 762306a36Sopenharmony_ci * it under the terms of the GNU General Public License as published by 862306a36Sopenharmony_ci * the Free Software Foundation. 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) 1162306a36Sopenharmony_ci * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com) 1262306a36Sopenharmony_ci * Maintained by: QLogic-Storage-Upstream@qlogic.com 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "bnx2i.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/** 1862306a36Sopenharmony_ci * bnx2i_dev_to_hba - maps dev pointer to adapter struct 1962306a36Sopenharmony_ci * @dev: device pointer 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * Map device to hba structure 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_cistatic inline struct bnx2i_hba *bnx2i_dev_to_hba(struct device *dev) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci struct Scsi_Host *shost = class_to_shost(dev); 2662306a36Sopenharmony_ci return iscsi_host_priv(shost); 2762306a36Sopenharmony_ci} 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/** 3162306a36Sopenharmony_ci * bnx2i_show_sq_info - return(s currently configured send queue (SQ) size 3262306a36Sopenharmony_ci * @dev: device pointer 3362306a36Sopenharmony_ci * @attr: device attribute (unused) 3462306a36Sopenharmony_ci * @buf: buffer to return current SQ size parameter 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * Returns current SQ size parameter, this paramater determines the number 3762306a36Sopenharmony_ci * outstanding iSCSI commands supported on a connection 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_cistatic ssize_t bnx2i_show_sq_info(struct device *dev, 4062306a36Sopenharmony_ci struct device_attribute *attr, char *buf) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci return sprintf(buf, "0x%x\n", hba->max_sqes); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/** 4962306a36Sopenharmony_ci * bnx2i_set_sq_info - update send queue (SQ) size parameter 5062306a36Sopenharmony_ci * @dev: device pointer 5162306a36Sopenharmony_ci * @attr: device attribute (unused) 5262306a36Sopenharmony_ci * @buf: buffer to return current SQ size parameter 5362306a36Sopenharmony_ci * @count: parameter buffer size 5462306a36Sopenharmony_ci * 5562306a36Sopenharmony_ci * Interface for user to change shared queue size allocated for each conn 5662306a36Sopenharmony_ci * Must be within SQ limits and a power of 2. For the latter this is needed 5762306a36Sopenharmony_ci * because of how libiscsi preallocates tasks. 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_cistatic ssize_t bnx2i_set_sq_info(struct device *dev, 6062306a36Sopenharmony_ci struct device_attribute *attr, 6162306a36Sopenharmony_ci const char *buf, size_t count) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); 6462306a36Sopenharmony_ci u32 val; 6562306a36Sopenharmony_ci int max_sq_size; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci if (hba->ofld_conns_active) 6862306a36Sopenharmony_ci goto skip_config; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) 7162306a36Sopenharmony_ci max_sq_size = BNX2I_5770X_SQ_WQES_MAX; 7262306a36Sopenharmony_ci else 7362306a36Sopenharmony_ci max_sq_size = BNX2I_570X_SQ_WQES_MAX; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci if (sscanf(buf, " 0x%x ", &val) > 0) { 7662306a36Sopenharmony_ci if ((val >= BNX2I_SQ_WQES_MIN) && (val <= max_sq_size) && 7762306a36Sopenharmony_ci (is_power_of_2(val))) 7862306a36Sopenharmony_ci hba->max_sqes = val; 7962306a36Sopenharmony_ci } 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci return count; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ciskip_config: 8462306a36Sopenharmony_ci printk(KERN_ERR "bnx2i: device busy, cannot change SQ size\n"); 8562306a36Sopenharmony_ci return 0; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/** 9062306a36Sopenharmony_ci * bnx2i_show_ccell_info - returns command cell (HQ) size 9162306a36Sopenharmony_ci * @dev: device pointer 9262306a36Sopenharmony_ci * @attr: device attribute (unused) 9362306a36Sopenharmony_ci * @buf: buffer to return current SQ size parameter 9462306a36Sopenharmony_ci * 9562306a36Sopenharmony_ci * returns per-connection TCP history queue size parameter 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_cistatic ssize_t bnx2i_show_ccell_info(struct device *dev, 9862306a36Sopenharmony_ci struct device_attribute *attr, char *buf) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci return sprintf(buf, "0x%x\n", hba->num_ccell); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/** 10762306a36Sopenharmony_ci * bnx2i_set_ccell_info - set command cell (HQ) size 10862306a36Sopenharmony_ci * @dev: device pointer 10962306a36Sopenharmony_ci * @attr: device attribute (unused) 11062306a36Sopenharmony_ci * @buf: buffer to return current SQ size parameter 11162306a36Sopenharmony_ci * @count: parameter buffer size 11262306a36Sopenharmony_ci * 11362306a36Sopenharmony_ci * updates per-connection TCP history queue size parameter 11462306a36Sopenharmony_ci */ 11562306a36Sopenharmony_cistatic ssize_t bnx2i_set_ccell_info(struct device *dev, 11662306a36Sopenharmony_ci struct device_attribute *attr, 11762306a36Sopenharmony_ci const char *buf, size_t count) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci u32 val; 12062306a36Sopenharmony_ci struct bnx2i_hba *hba = bnx2i_dev_to_hba(dev); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci if (hba->ofld_conns_active) 12362306a36Sopenharmony_ci goto skip_config; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci if (sscanf(buf, " 0x%x ", &val) > 0) { 12662306a36Sopenharmony_ci if ((val >= BNX2I_CCELLS_MIN) && 12762306a36Sopenharmony_ci (val <= BNX2I_CCELLS_MAX)) { 12862306a36Sopenharmony_ci hba->num_ccell = val; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci return count; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ciskip_config: 13562306a36Sopenharmony_ci printk(KERN_ERR "bnx2i: device busy, cannot change CCELL size\n"); 13662306a36Sopenharmony_ci return 0; 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic DEVICE_ATTR(sq_size, S_IRUGO | S_IWUSR, 14162306a36Sopenharmony_ci bnx2i_show_sq_info, bnx2i_set_sq_info); 14262306a36Sopenharmony_cistatic DEVICE_ATTR(num_ccell, S_IRUGO | S_IWUSR, 14362306a36Sopenharmony_ci bnx2i_show_ccell_info, bnx2i_set_ccell_info); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic struct attribute *bnx2i_dev_attributes[] = { 14662306a36Sopenharmony_ci &dev_attr_sq_size.attr, 14762306a36Sopenharmony_ci &dev_attr_num_ccell.attr, 14862306a36Sopenharmony_ci NULL 14962306a36Sopenharmony_ci}; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic const struct attribute_group bnx2i_dev_attr_group = { 15262306a36Sopenharmony_ci .attrs = bnx2i_dev_attributes 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ciconst struct attribute_group *bnx2i_dev_groups[] = { 15662306a36Sopenharmony_ci &bnx2i_dev_attr_group, 15762306a36Sopenharmony_ci NULL 15862306a36Sopenharmony_ci}; 159