Back to home page

OSCL-LXR

 
 

    


0001 /* bnx2i.c: QLogic NetXtreme II iSCSI driver.
0002  *
0003  * Copyright (c) 2006 - 2013 Broadcom Corporation
0004  * Copyright (c) 2007, 2008 Red Hat, Inc.  All rights reserved.
0005  * Copyright (c) 2007, 2008 Mike Christie
0006  * Copyright (c) 2014, QLogic Corporation
0007  *
0008  * This program is free software; you can redistribute it and/or modify
0009  * it under the terms of the GNU General Public License as published by
0010  * the Free Software Foundation.
0011  *
0012  * Written by: Anil Veerabhadrappa (anilgv@broadcom.com)
0013  * Previously Maintained by: Eddie Wai (eddie.wai@broadcom.com)
0014  * Maintained by: QLogic-Storage-Upstream@qlogic.com
0015  */
0016 
0017 #include "bnx2i.h"
0018 
0019 static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
0020 static u32 adapter_count;
0021 
0022 #define DRV_MODULE_NAME     "bnx2i"
0023 #define DRV_MODULE_VERSION  "2.7.10.1"
0024 #define DRV_MODULE_RELDATE  "Jul 16, 2014"
0025 
0026 static char version[] =
0027         "QLogic NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
0028         " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
0029 
0030 
0031 MODULE_AUTHOR("Anil Veerabhadrappa <anilgv@broadcom.com> and "
0032           "Eddie Wai <eddie.wai@broadcom.com>");
0033 
0034 MODULE_DESCRIPTION("QLogic NetXtreme II BCM5706/5708/5709/57710/57711/57712"
0035            "/57800/57810/57840 iSCSI Driver");
0036 MODULE_LICENSE("GPL");
0037 MODULE_VERSION(DRV_MODULE_VERSION);
0038 
0039 static DEFINE_MUTEX(bnx2i_dev_lock);
0040 
0041 unsigned int event_coal_min = 24;
0042 module_param(event_coal_min, int, 0664);
0043 MODULE_PARM_DESC(event_coal_min, "Event Coalescing Minimum Commands");
0044 
0045 unsigned int event_coal_div = 2;
0046 module_param(event_coal_div, int, 0664);
0047 MODULE_PARM_DESC(event_coal_div, "Event Coalescing Divide Factor");
0048 
0049 unsigned int en_tcp_dack = 1;
0050 module_param(en_tcp_dack, int, 0664);
0051 MODULE_PARM_DESC(en_tcp_dack, "Enable TCP Delayed ACK");
0052 
0053 unsigned int error_mask1 = 0x00;
0054 module_param(error_mask1, uint, 0664);
0055 MODULE_PARM_DESC(error_mask1, "Config FW iSCSI Error Mask #1");
0056 
0057 unsigned int error_mask2 = 0x00;
0058 module_param(error_mask2, uint, 0664);
0059 MODULE_PARM_DESC(error_mask2, "Config FW iSCSI Error Mask #2");
0060 
0061 unsigned int sq_size;
0062 module_param(sq_size, int, 0664);
0063 MODULE_PARM_DESC(sq_size, "Configure SQ size");
0064 
0065 unsigned int rq_size = BNX2I_RQ_WQES_DEFAULT;
0066 module_param(rq_size, int, 0664);
0067 MODULE_PARM_DESC(rq_size, "Configure RQ size");
0068 
0069 u64 iscsi_error_mask = 0x00;
0070 
0071 DEFINE_PER_CPU(struct bnx2i_percpu_s, bnx2i_percpu);
0072 
0073 /**
0074  * bnx2i_identify_device - identifies NetXtreme II device type
0075  * @hba:        Adapter structure pointer
0076  * @dev:        Corresponding cnic device
0077  *
0078  * This function identifies the NX2 device type and sets appropriate
0079  *  queue mailbox register access method, 5709 requires driver to
0080  *  access MBOX regs using *bin* mode
0081  */
0082 void bnx2i_identify_device(struct bnx2i_hba *hba, struct cnic_dev *dev)
0083 {
0084     hba->cnic_dev_type = 0;
0085     if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
0086         if (hba->pci_did == PCI_DEVICE_ID_NX2_5706 ||
0087             hba->pci_did == PCI_DEVICE_ID_NX2_5706S) {
0088             set_bit(BNX2I_NX2_DEV_5706, &hba->cnic_dev_type);
0089         } else if (hba->pci_did == PCI_DEVICE_ID_NX2_5708 ||
0090             hba->pci_did == PCI_DEVICE_ID_NX2_5708S) {
0091             set_bit(BNX2I_NX2_DEV_5708, &hba->cnic_dev_type);
0092         } else if (hba->pci_did == PCI_DEVICE_ID_NX2_5709 ||
0093             hba->pci_did == PCI_DEVICE_ID_NX2_5709S) {
0094             set_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type);
0095             hba->mail_queue_access = BNX2I_MQ_BIN_MODE;
0096         }
0097     } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
0098         set_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type);
0099     } else {
0100         printk(KERN_ALERT "bnx2i: unknown device, 0x%x\n",
0101                   hba->pci_did);
0102     }
0103 }
0104 
0105 
0106 /**
0107  * get_adapter_list_head - returns head of adapter list
0108  */
0109 struct bnx2i_hba *get_adapter_list_head(void)
0110 {
0111     struct bnx2i_hba *hba = NULL;
0112     struct bnx2i_hba *tmp_hba;
0113 
0114     if (!adapter_count)
0115         goto hba_not_found;
0116 
0117     mutex_lock(&bnx2i_dev_lock);
0118     list_for_each_entry(tmp_hba, &adapter_list, link) {
0119         if (tmp_hba->cnic && tmp_hba->cnic->cm_select_dev) {
0120             hba = tmp_hba;
0121             break;
0122         }
0123     }
0124     mutex_unlock(&bnx2i_dev_lock);
0125 hba_not_found:
0126     return hba;
0127 }
0128 
0129 
0130 /**
0131  * bnx2i_find_hba_for_cnic - maps cnic device instance to bnx2i adapter instance
0132  * @cnic:   pointer to cnic device instance
0133  *
0134  */
0135 struct bnx2i_hba *bnx2i_find_hba_for_cnic(struct cnic_dev *cnic)
0136 {
0137     struct bnx2i_hba *hba, *temp;
0138 
0139     mutex_lock(&bnx2i_dev_lock);
0140     list_for_each_entry_safe(hba, temp, &adapter_list, link) {
0141         if (hba->cnic == cnic) {
0142             mutex_unlock(&bnx2i_dev_lock);
0143             return hba;
0144         }
0145     }
0146     mutex_unlock(&bnx2i_dev_lock);
0147     return NULL;
0148 }
0149 
0150 
0151 /**
0152  * bnx2i_start - cnic callback to initialize & start adapter instance
0153  * @handle: transparent handle pointing to adapter structure
0154  *
0155  * This function maps adapter structure to pcidev structure and initiates
0156  *  firmware handshake to enable/initialize on chip iscsi components
0157  *  This bnx2i - cnic interface api callback is issued after following
0158  *  2 conditions are met -
0159  *    a) underlying network interface is up (marked by event 'NETDEV_UP'
0160  *      from netdev
0161  *    b) bnx2i adapter instance is registered
0162  */
0163 void bnx2i_start(void *handle)
0164 {
0165 #define BNX2I_INIT_POLL_TIME    (1000 / HZ)
0166     struct bnx2i_hba *hba = handle;
0167     int i = HZ;
0168 
0169     /* On some bnx2x devices, it is possible that iSCSI is no
0170      * longer supported after firmware is downloaded.  In that
0171      * case, the iscsi_init_msg will return failure.
0172      */
0173 
0174     bnx2i_send_fw_iscsi_init_msg(hba);
0175     while (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) &&
0176            !test_bit(ADAPTER_STATE_INIT_FAILED, &hba->adapter_state) && i--)
0177         msleep(BNX2I_INIT_POLL_TIME);
0178 }
0179 
0180 
0181 /**
0182  * bnx2i_chip_cleanup - local routine to handle chip cleanup
0183  * @hba:    Adapter instance to register
0184  *
0185  * Driver checks if adapter still has any active connections before
0186  *  executing the cleanup process
0187  */
0188 static void bnx2i_chip_cleanup(struct bnx2i_hba *hba)
0189 {
0190     struct bnx2i_endpoint *bnx2i_ep;
0191     struct list_head *pos, *tmp;
0192 
0193     if (hba->ofld_conns_active) {
0194         /* Stage to force the disconnection
0195          * This is the case where the daemon is either slow or
0196          * not present
0197          */
0198         printk(KERN_ALERT "bnx2i: (%s) chip cleanup for %d active "
0199             "connections\n", hba->netdev->name,
0200             hba->ofld_conns_active);
0201         mutex_lock(&hba->net_dev_lock);
0202         list_for_each_safe(pos, tmp, &hba->ep_active_list) {
0203             bnx2i_ep = list_entry(pos, struct bnx2i_endpoint, link);
0204             /* Clean up the chip only */
0205             bnx2i_hw_ep_disconnect(bnx2i_ep);
0206             bnx2i_ep->cm_sk = NULL;
0207         }
0208         mutex_unlock(&hba->net_dev_lock);
0209     }
0210 }
0211 
0212 
0213 /**
0214  * bnx2i_stop - cnic callback to shutdown adapter instance
0215  * @handle: transparent handle pointing to adapter structure
0216  *
0217  * driver checks if adapter is already in shutdown mode, if not start
0218  *  the shutdown process
0219  */
0220 void bnx2i_stop(void *handle)
0221 {
0222     struct bnx2i_hba *hba = handle;
0223     int conns_active;
0224     int wait_delay = 1 * HZ;
0225 
0226     /* check if cleanup happened in GOING_DOWN context */
0227     if (!test_and_set_bit(ADAPTER_STATE_GOING_DOWN,
0228                   &hba->adapter_state)) {
0229         iscsi_host_for_each_session(hba->shost,
0230                         bnx2i_drop_session);
0231         wait_delay = hba->hba_shutdown_tmo;
0232     }
0233     /* Wait for inflight offload connection tasks to complete before
0234      * proceeding. Forcefully terminate all connection recovery in
0235      * progress at the earliest, either in bind(), send_pdu(LOGIN),
0236      * or conn_start()
0237      */
0238     wait_event_interruptible_timeout(hba->eh_wait,
0239                      (list_empty(&hba->ep_ofld_list) &&
0240                      list_empty(&hba->ep_destroy_list)),
0241                      2 * HZ);
0242     /* Wait for all endpoints to be torn down, Chip will be reset once
0243      *  control returns to network driver. So it is required to cleanup and
0244      * release all connection resources before returning from this routine.
0245      */
0246     while (hba->ofld_conns_active) {
0247         conns_active = hba->ofld_conns_active;
0248         wait_event_interruptible_timeout(hba->eh_wait,
0249                 (hba->ofld_conns_active != conns_active),
0250                 wait_delay);
0251         if (hba->ofld_conns_active == conns_active)
0252             break;
0253     }
0254     bnx2i_chip_cleanup(hba);
0255 
0256     /* This flag should be cleared last so that ep_disconnect() gracefully
0257      * cleans up connection context
0258      */
0259     clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
0260     clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
0261 }
0262 
0263 
0264 /**
0265  * bnx2i_init_one - initialize an adapter instance and allocate memory resources
0266  * @hba:    bnx2i adapter instance
0267  * @cnic:   cnic device handle
0268  *
0269  * Global resource lock is held during critical sections below. This routine is
0270  *  called from either cnic_register_driver() or device hot plug context and
0271  *  and does majority of device specific initialization
0272  */
0273 static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic)
0274 {
0275     int rc;
0276 
0277     mutex_lock(&bnx2i_dev_lock);
0278     if (!cnic->max_iscsi_conn) {
0279         printk(KERN_ALERT "bnx2i: dev %s does not support "
0280             "iSCSI\n", hba->netdev->name);
0281         rc = -EOPNOTSUPP;
0282         goto out;
0283     }
0284 
0285     hba->cnic = cnic;
0286     rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba);
0287     if (!rc) {
0288         hba->age++;
0289         set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
0290         list_add_tail(&hba->link, &adapter_list);
0291         adapter_count++;
0292     } else if (rc == -EBUSY)    /* duplicate registration */
0293         printk(KERN_ALERT "bnx2i, duplicate registration"
0294                   "hba=%p, cnic=%p\n", hba, cnic);
0295     else if (rc == -EAGAIN)
0296         printk(KERN_ERR "bnx2i, driver not registered\n");
0297     else if (rc == -EINVAL)
0298         printk(KERN_ERR "bnx2i, invalid type %d\n", CNIC_ULP_ISCSI);
0299     else
0300         printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc);
0301 
0302 out:
0303     mutex_unlock(&bnx2i_dev_lock);
0304 
0305     return rc;
0306 }
0307 
0308 
0309 /**
0310  * bnx2i_ulp_init - initialize an adapter instance
0311  * @dev:    cnic device handle
0312  *
0313  * Called from cnic_register_driver() context to initialize all enumerated
0314  *  cnic devices. This routine allocate adapter structure and other
0315  *  device specific resources.
0316  */
0317 void bnx2i_ulp_init(struct cnic_dev *dev)
0318 {
0319     struct bnx2i_hba *hba;
0320 
0321     /* Allocate a HBA structure for this device */
0322     hba = bnx2i_alloc_hba(dev);
0323     if (!hba) {
0324         printk(KERN_ERR "bnx2i init: hba initialization failed\n");
0325         return;
0326     }
0327 
0328     /* Get PCI related information and update hba struct members */
0329     clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
0330     if (bnx2i_init_one(hba, dev)) {
0331         printk(KERN_ERR "bnx2i - hba %p init failed\n", hba);
0332         bnx2i_free_hba(hba);
0333     }
0334 }
0335 
0336 
0337 /**
0338  * bnx2i_ulp_exit - shuts down adapter instance and frees all resources
0339  * @dev:    cnic device handle
0340  *
0341  */
0342 void bnx2i_ulp_exit(struct cnic_dev *dev)
0343 {
0344     struct bnx2i_hba *hba;
0345 
0346     hba = bnx2i_find_hba_for_cnic(dev);
0347     if (!hba) {
0348         printk(KERN_INFO "bnx2i_ulp_exit: hba not "
0349                  "found, dev 0x%p\n", dev);
0350         return;
0351     }
0352     mutex_lock(&bnx2i_dev_lock);
0353     list_del_init(&hba->link);
0354     adapter_count--;
0355 
0356     if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
0357         hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
0358         clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
0359     }
0360     mutex_unlock(&bnx2i_dev_lock);
0361 
0362     bnx2i_free_hba(hba);
0363 }
0364 
0365 
0366 /**
0367  * bnx2i_get_stats - Retrieve various statistic from iSCSI offload
0368  * @handle: bnx2i_hba
0369  *
0370  * function callback exported via bnx2i - cnic driver interface to
0371  *      retrieve various iSCSI offload related statistics.
0372  */
0373 int bnx2i_get_stats(void *handle)
0374 {
0375     struct bnx2i_hba *hba = handle;
0376     struct iscsi_stats_info *stats;
0377 
0378     if (!hba)
0379         return -EINVAL;
0380 
0381     stats = (struct iscsi_stats_info *)hba->cnic->stats_addr;
0382 
0383     if (!stats)
0384         return -ENOMEM;
0385 
0386     strlcpy(stats->version, DRV_MODULE_VERSION, sizeof(stats->version));
0387     memcpy(stats->mac_add1 + 2, hba->cnic->mac_addr, ETH_ALEN);
0388 
0389     stats->max_frame_size = hba->netdev->mtu;
0390     stats->txq_size = hba->max_sqes;
0391     stats->rxq_size = hba->max_cqes;
0392 
0393     stats->txq_avg_depth = 0;
0394     stats->rxq_avg_depth = 0;
0395 
0396     GET_STATS_64(hba, stats, rx_pdus);
0397     GET_STATS_64(hba, stats, rx_bytes);
0398 
0399     GET_STATS_64(hba, stats, tx_pdus);
0400     GET_STATS_64(hba, stats, tx_bytes);
0401 
0402     return 0;
0403 }
0404 
0405 
0406 /**
0407  * bnx2i_cpu_online - Create a receive thread for an online CPU
0408  *
0409  * @cpu:    cpu index for the online cpu
0410  */
0411 static int bnx2i_cpu_online(unsigned int cpu)
0412 {
0413     struct bnx2i_percpu_s *p;
0414     struct task_struct *thread;
0415 
0416     p = &per_cpu(bnx2i_percpu, cpu);
0417 
0418     thread = kthread_create_on_node(bnx2i_percpu_io_thread, (void *)p,
0419                     cpu_to_node(cpu),
0420                     "bnx2i_thread/%d", cpu);
0421     if (IS_ERR(thread))
0422         return PTR_ERR(thread);
0423 
0424     /* bind thread to the cpu */
0425     kthread_bind(thread, cpu);
0426     p->iothread = thread;
0427     wake_up_process(thread);
0428     return 0;
0429 }
0430 
0431 static int bnx2i_cpu_offline(unsigned int cpu)
0432 {
0433     struct bnx2i_percpu_s *p;
0434     struct task_struct *thread;
0435     struct bnx2i_work *work, *tmp;
0436 
0437     /* Prevent any new work from being queued for this CPU */
0438     p = &per_cpu(bnx2i_percpu, cpu);
0439     spin_lock_bh(&p->p_work_lock);
0440     thread = p->iothread;
0441     p->iothread = NULL;
0442 
0443     /* Free all work in the list */
0444     list_for_each_entry_safe(work, tmp, &p->work_list, list) {
0445         list_del_init(&work->list);
0446         bnx2i_process_scsi_cmd_resp(work->session,
0447                         work->bnx2i_conn, &work->cqe);
0448         kfree(work);
0449     }
0450 
0451     spin_unlock_bh(&p->p_work_lock);
0452     if (thread)
0453         kthread_stop(thread);
0454     return 0;
0455 }
0456 
0457 static enum cpuhp_state bnx2i_online_state;
0458 
0459 /**
0460  * bnx2i_mod_init - module init entry point
0461  *
0462  * initialize any driver wide global data structures such as endpoint pool,
0463  *  tcp port manager/queue, sysfs. finally driver will register itself
0464  *  with the cnic module
0465  */
0466 static int __init bnx2i_mod_init(void)
0467 {
0468     int err;
0469     unsigned cpu = 0;
0470     struct bnx2i_percpu_s *p;
0471 
0472     printk(KERN_INFO "%s", version);
0473 
0474     if (sq_size && !is_power_of_2(sq_size))
0475         sq_size = roundup_pow_of_two(sq_size);
0476 
0477     bnx2i_scsi_xport_template =
0478             iscsi_register_transport(&bnx2i_iscsi_transport);
0479     if (!bnx2i_scsi_xport_template) {
0480         printk(KERN_ERR "Could not register bnx2i transport.\n");
0481         err = -ENOMEM;
0482         goto out;
0483     }
0484 
0485     err = cnic_register_driver(CNIC_ULP_ISCSI, &bnx2i_cnic_cb);
0486     if (err) {
0487         printk(KERN_ERR "Could not register bnx2i cnic driver.\n");
0488         goto unreg_xport;
0489     }
0490 
0491     /* Create percpu kernel threads to handle iSCSI I/O completions */
0492     for_each_possible_cpu(cpu) {
0493         p = &per_cpu(bnx2i_percpu, cpu);
0494         INIT_LIST_HEAD(&p->work_list);
0495         spin_lock_init(&p->p_work_lock);
0496         p->iothread = NULL;
0497     }
0498 
0499     err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2i:online",
0500                 bnx2i_cpu_online, bnx2i_cpu_offline);
0501     if (err < 0)
0502         goto unreg_driver;
0503     bnx2i_online_state = err;
0504     return 0;
0505 
0506 unreg_driver:
0507     cnic_unregister_driver(CNIC_ULP_ISCSI);
0508 unreg_xport:
0509     iscsi_unregister_transport(&bnx2i_iscsi_transport);
0510 out:
0511     return err;
0512 }
0513 
0514 
0515 /**
0516  * bnx2i_mod_exit - module cleanup/exit entry point
0517  *
0518  * Global resource lock and host adapter lock is held during critical sections
0519  *  in this function. Driver will browse through the adapter list, cleans-up
0520  *  each instance, unregisters iscsi transport name and finally driver will
0521  *  unregister itself with the cnic module
0522  */
0523 static void __exit bnx2i_mod_exit(void)
0524 {
0525     struct bnx2i_hba *hba;
0526 
0527     mutex_lock(&bnx2i_dev_lock);
0528     while (!list_empty(&adapter_list)) {
0529         hba = list_entry(adapter_list.next, struct bnx2i_hba, link);
0530         list_del(&hba->link);
0531         adapter_count--;
0532 
0533         if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
0534             bnx2i_chip_cleanup(hba);
0535             hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
0536             clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
0537         }
0538 
0539         bnx2i_free_hba(hba);
0540     }
0541     mutex_unlock(&bnx2i_dev_lock);
0542 
0543     cpuhp_remove_state(bnx2i_online_state);
0544 
0545     iscsi_unregister_transport(&bnx2i_iscsi_transport);
0546     cnic_unregister_driver(CNIC_ULP_ISCSI);
0547 }
0548 
0549 module_init(bnx2i_mod_init);
0550 module_exit(bnx2i_mod_exit);