^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* bnx2fc_fcoe.c: QLogic Linux FCoE offload driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file contains the code that interacts with libfc, libfcoe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * cnic modules to create FCoE instances, send/receive non-offloaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * FIP/FCoE packets, listen to link events etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2008-2013 Broadcom Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2014-2016 QLogic Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2016-2017 Cavium Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "bnx2fc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static struct list_head adapter_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static struct list_head if_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static u32 adapter_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static DEFINE_MUTEX(bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define DRV_MODULE_NAME "bnx2fc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DRV_MODULE_VERSION BNX2FC_VERSION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DRV_MODULE_RELDATE "October 15, 2015"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static char version[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) "QLogic FCoE Driver " DRV_MODULE_NAME \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) MODULE_AUTHOR("Bhanu Prakash Gollapudi <bprakash@broadcom.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MODULE_DESCRIPTION("QLogic FCoE Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_VERSION(DRV_MODULE_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define BNX2FC_MAX_QUEUE_DEPTH 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define BNX2FC_MIN_QUEUE_DEPTH 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FCOE_WORD_TO_BYTE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct scsi_transport_template *bnx2fc_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static struct scsi_transport_template *bnx2fc_vport_xport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct workqueue_struct *bnx2fc_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* bnx2fc structure needs only one instance of the fcoe_percpu_s structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Here the io threads are per cpu but the l2 thread is just one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct fcoe_percpu_s bnx2fc_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static DEFINE_SPINLOCK(bnx2fc_global_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static struct cnic_ulp_ops bnx2fc_cnic_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static struct libfc_function_template bnx2fc_libfc_fcn_templ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static struct scsi_host_template bnx2fc_shost_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static struct fc_function_template bnx2fc_transport_function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct fc_function_template bnx2fc_vport_xport_function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int bnx2fc_create(struct net_device *netdev, enum fip_mode fip_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void __bnx2fc_destroy(struct bnx2fc_interface *interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int bnx2fc_destroy(struct net_device *net_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int bnx2fc_enable(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int bnx2fc_disable(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* fcoe_syfs control interface handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static int bnx2fc_ctlr_alloc(struct net_device *netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void bnx2fc_recv_frame(struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static void bnx2fc_start_disc(struct bnx2fc_interface *interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int bnx2fc_lport_config(struct fc_lport *lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int bnx2fc_em_config(struct fc_lport *lport, struct bnx2fc_hba *hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int bnx2fc_bind_adapter_devices(struct bnx2fc_hba *hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static void bnx2fc_unbind_adapter_devices(struct bnx2fc_hba *hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct device *parent, int npiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static void bnx2fc_port_destroy(struct fcoe_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *phys_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static inline void bnx2fc_interface_put(struct bnx2fc_interface *interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static int bnx2fc_fw_init(struct bnx2fc_hba *hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void bnx2fc_port_shutdown(struct fc_lport *lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void bnx2fc_stop(struct bnx2fc_interface *interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int __init bnx2fc_mod_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void __exit bnx2fc_mod_exit(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned int bnx2fc_debug_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MODULE_PARM_DESC(debug_logging,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) "Option to enable extended logging,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "\t\tDefault is 0 - no logging.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "\t\t0x01 - SCSI cmd error, cleanup.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "\t\t0x02 - Session setup, cleanup, etc.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) "\t\t0x04 - lport events, link, mtu, etc.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) "\t\t0x08 - ELS logs.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) "\t\t0x10 - fcoe L2 fame related logs.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) "\t\t0xff - LOG all messages.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static uint bnx2fc_devloss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) module_param_named(devloss_tmo, bnx2fc_devloss_tmo, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) MODULE_PARM_DESC(devloss_tmo, " Change devloss_tmo for the remote ports "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) "attached via bnx2fc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static uint bnx2fc_max_luns = BNX2FC_MAX_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) module_param_named(max_luns, bnx2fc_max_luns, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) MODULE_PARM_DESC(max_luns, " Change the default max_lun per SCSI host. Default "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) "0xffff.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static uint bnx2fc_queue_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) module_param_named(queue_depth, bnx2fc_queue_depth, uint, S_IRUGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) MODULE_PARM_DESC(queue_depth, " Change the default queue depth of SCSI devices "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "attached via bnx2fc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static uint bnx2fc_log_fka;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) module_param_named(log_fka, bnx2fc_log_fka, uint, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) MODULE_PARM_DESC(log_fka, " Print message to kernel log when fcoe is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "initiating a FIP keep alive when debug logging is enabled.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline struct net_device *bnx2fc_netdev(const struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return ((struct bnx2fc_interface *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct fcoe_ctlr_device *ctlr_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) fcoe_fcf_dev_to_ctlr_dev(fcf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct bnx2fc_interface *fcoe = fcoe_ctlr_priv(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) fcf_dev->vlan_id = fcoe->vlan_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static void bnx2fc_clean_rx_queue(struct fc_lport *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct fcoe_percpu_s *bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct fcoe_rcv_info *fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct sk_buff_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct sk_buff *skb, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) bg = &bnx2fc_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) spin_lock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) list = &bg->fcoe_rx_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) skb_queue_walk_safe(list, skb, next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) fr = fcoe_dev_from_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (fr->fr_dev == lp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) __skb_unlink(skb, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) spin_unlock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int bnx2fc_get_paged_crc_eof(struct sk_buff *skb, int tlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) spin_lock(&bnx2fc_global_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) rc = fcoe_get_paged_crc_eof(skb, tlen, &bnx2fc_global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) spin_unlock(&bnx2fc_global_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void bnx2fc_abort_io(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * This function is no-op for bnx2fc, but we do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * not want to leave it as NULL either, as libfc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * can call the default function which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * fc_fcp_abort_io.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static void bnx2fc_cleanup(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct bnx2fc_hba *hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct bnx2fc_rport *tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) BNX2FC_MISC_DBG("Entered %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mutex_lock(&hba->hba_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) spin_lock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) for (i = 0; i < BNX2FC_NUM_MAX_SESS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) tgt = hba->tgt_ofld_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (tgt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Cleanup IOs belonging to requested vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (tgt->port == port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) spin_unlock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) BNX2FC_TGT_DBG(tgt, "flush/cleanup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) bnx2fc_flush_active_ios(tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) spin_lock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) spin_unlock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mutex_unlock(&hba->hba_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int bnx2fc_xmit_l2_frame(struct bnx2fc_rport *tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct fc_rport_priv *rdata = tgt->rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) BNX2FC_TGT_DBG(tgt, "Xmit L2 frame rport = 0x%x, oxid = 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) "r_ctl = 0x%x\n", rdata->ids.port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ntohs(fh->fh_ox_id), fh->fh_r_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if ((fh->fh_type == FC_TYPE_ELS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) (fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) switch (fc_frame_payload_op(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case ELS_ADISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rc = bnx2fc_send_adisc(tgt, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case ELS_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) rc = bnx2fc_send_logo(tgt, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case ELS_RLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) rc = bnx2fc_send_rls(tgt, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) } else if ((fh->fh_type == FC_TYPE_BLS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) (fh->fh_r_ctl == FC_RCTL_BA_ABTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) BNX2FC_TGT_DBG(tgt, "ABTS frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) BNX2FC_TGT_DBG(tgt, "Send L2 frame type 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) "rctl 0x%x thru non-offload path\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) fh->fh_type, fh->fh_r_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * bnx2fc_xmit - bnx2fc's FCoE frame transmit function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * @lport: the associated local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @fp: the fc_frame to be transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct ethhdr *eh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct fcoe_crc_eof *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct fcoe_hdr *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct bnx2fc_rport *tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u8 sof, eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) unsigned int hlen, tlen, elen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int wlen, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) port = (struct fcoe_port *)lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) skb = fp_skb(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!lport->link_up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) BNX2FC_HBA_DBG(lport, "bnx2fc_xmit link down\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (!ctlr->sel_fcf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) BNX2FC_HBA_DBG(lport, "FCF not selected yet!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (fcoe_ctlr_els_send(ctlr, lport, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) sof = fr_sof(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) eof = fr_eof(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * Snoop the frame header to check if the frame is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * an offloaded session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * tgt_ofld_list access is synchronized using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * both hba mutex and hba lock. Atleast hba mutex or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * hba lock needs to be held for read access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) spin_lock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) tgt = bnx2fc_tgt_lookup(port, ntoh24(fh->fh_d_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (tgt && (test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* This frame is for offloaded session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) BNX2FC_HBA_DBG(lport, "xmit: Frame is for offloaded session "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) "port_id = 0x%x\n", ntoh24(fh->fh_d_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) spin_unlock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) rc = bnx2fc_xmit_l2_frame(tgt, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (rc != -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) spin_unlock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) elen = sizeof(struct ethhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) hlen = sizeof(struct fcoe_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) tlen = sizeof(struct fcoe_crc_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) skb->ip_summed = CHECKSUM_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) crc = fcoe_fc_crc(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* copy port crc and eof to the skb buff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (skb_is_nonlinear(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) skb_frag_t *frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (bnx2fc_get_paged_crc_eof(skb, tlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) cp = kmap_atomic(skb_frag_page(frag)) + skb_frag_off(frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) cp = skb_put(skb, tlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) memset(cp, 0, sizeof(*cp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) cp->fcoe_eof = eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) cp->fcoe_crc32 = cpu_to_le32(~crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (skb_is_nonlinear(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) kunmap_atomic(cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) cp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* adjust skb network/transport offsets to match mac/fcoe/port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) skb_push(skb, elen + hlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) skb->mac_len = elen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) skb->protocol = htons(ETH_P_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) skb->dev = interface->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* fill up mac and fcoe headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) eh = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) eh->h_proto = htons(ETH_P_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (ctlr->map_dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* insert GW address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) hp = (struct fcoe_hdr *)(eh + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) memset(hp, 0, sizeof(*hp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (FC_FCOE_VER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) hp->fcoe_sof = sof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (lport->seq_offload && fr_max_payload(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) skb_shinfo(skb)->gso_size = fr_max_payload(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) skb_shinfo(skb)->gso_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) skb_shinfo(skb)->gso_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /*update tx stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) stats->TxFrames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) stats->TxWords += wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* send down to lld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) fr_dev(fp) = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (port->fcoe_pending_queue.qlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) fcoe_check_wait_queue(lport, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) else if (fcoe_start_io(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) fcoe_check_wait_queue(lport, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * bnx2fc_rcv - This is bnx2fc's receive function called by NET_RX_SOFTIRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * @skb: the receive socket buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * @dev: associated net device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * @ptype: context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * @olddev: last device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * This function receives the packet and builds FC frame and passes it up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct packet_type *ptype, struct net_device *olddev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct fcoe_rcv_info *fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct fcoe_percpu_s *bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct sk_buff *tmp_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) interface = container_of(ptype, struct bnx2fc_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) fcoe_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (unlikely(lport == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) printk(KERN_ERR PFX "bnx2fc_rcv: lport is NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) tmp_skb = skb_share_check(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!tmp_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) skb = tmp_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * Check for minimum frame length, and make sure required FCoE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * and FC headers are pulled into the linear data area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (unlikely((skb->len < FCOE_MIN_FRAME) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) !pskb_may_pull(skb, FCOE_HEADER_LEN)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) fr = fcoe_dev_from_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) fr->fr_dev = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) bg = &bnx2fc_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) spin_lock(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) __skb_queue_tail(&bg->fcoe_rx_list, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (bg->fcoe_rx_list.qlen == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) wake_up_process(bg->kthread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) spin_unlock(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int bnx2fc_l2_rcv_thread(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct fcoe_percpu_s *bg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) set_user_nice(current, MIN_NICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) while (!kthread_should_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) spin_lock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) spin_unlock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) bnx2fc_recv_frame(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) spin_lock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) __set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) spin_unlock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) __set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static void bnx2fc_recv_frame(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u64 crc_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) u32 fr_len, fr_crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct fcoe_rcv_info *fr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct fc_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct fc_frame_header *fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct fcoe_crc_eof crc_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct fc_frame *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct fc_lport *vn_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct fcoe_port *port, *phys_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u8 *mac = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u8 *dest_mac = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct fcoe_hdr *hp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) fr = fcoe_dev_from_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) lport = fr->fr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (unlikely(lport == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) printk(KERN_ERR PFX "Invalid lport struct\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (skb_is_nonlinear(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) skb_linearize(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) mac = eth_hdr(skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dest_mac = eth_hdr(skb)->h_dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* Pull the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) hp = (struct fcoe_hdr *) skb_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) fh = (struct fc_frame_header *) skb_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) skb_pull(skb, sizeof(struct fcoe_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) fr_len = skb->len - sizeof(struct fcoe_crc_eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) stats->RxFrames++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) fp = (struct fc_frame *)skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) fc_frame_init(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) fr_dev(fp) = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) fr_sof(fp) = hp->fcoe_sof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) fr_eof(fp) = crc_eof.fcoe_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) fr_crc(fp) = crc_eof.fcoe_crc32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (pskb_trim(skb, fr_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) phys_port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) interface = phys_port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) fh = fc_frame_header_get(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (ntoh24(&dest_mac[3]) != ntoh24(fh->fh_d_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) BNX2FC_HBA_DBG(lport, "FC frame d_id mismatch with MAC %pM.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dest_mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (vn_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) port = lport_priv(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (!ether_addr_equal(port->data_src_addr, dest_mac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) BNX2FC_HBA_DBG(lport, "fpma mismatch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (ctlr->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!ether_addr_equal(mac, ctlr->dest_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) BNX2FC_HBA_DBG(lport, "Wrong source address: mac:%pM dest_addr:%pM.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) mac, ctlr->dest_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) fh->fh_type == FC_TYPE_FCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Drop FCP data. We dont this in L2 path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (fh->fh_r_ctl == FC_RCTL_ELS_REQ &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) fh->fh_type == FC_TYPE_ELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) switch (fc_frame_payload_op(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) case ELS_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* drop non-FIP LOGO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /* Drop incoming ABTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * If the destination ID from the frame header does not match what we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * have on record for lport and the search for a NPIV port came up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * empty then this is not addressed to our port so simply drop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (lport->port_id != ntoh24(fh->fh_d_id) && !vn_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) BNX2FC_HBA_DBG(lport, "Dropping frame due to destination mismatch: lport->port_id=%x fh->d_id=%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) lport->port_id, ntoh24(fh->fh_d_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) fr_crc = le32_to_cpu(fr_crc(fp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (unlikely(fr_crc != ~crc32(~0, skb->data, fr_len))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) stats = per_cpu_ptr(lport->stats, get_cpu());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) crc_err = (stats->InvalidCRCCount++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (crc_err < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) printk(KERN_WARNING PFX "dropping frame with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) "CRC error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) fc_exch_recv(lport, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * bnx2fc_percpu_io_thread - thread per cpu for ios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * @arg: ptr to bnx2fc_percpu_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static int bnx2fc_percpu_io_thread(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct bnx2fc_percpu_s *p = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct bnx2fc_work *work, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) LIST_HEAD(work_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) set_user_nice(current, MIN_NICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) while (!kthread_should_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) spin_lock_bh(&p->fp_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) while (!list_empty(&p->work_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) list_splice_init(&p->work_list, &work_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) spin_unlock_bh(&p->fp_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) list_for_each_entry_safe(work, tmp, &work_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) list_del_init(&work->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) bnx2fc_process_cq_compl(work->tgt, work->wqe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) work->rq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) work->num_rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) work->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) kfree(work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) spin_lock_bh(&p->fp_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) __set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) spin_unlock_bh(&p->fp_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) __set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct fc_host_statistics *bnx2fc_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct fc_lport *lport = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct bnx2fc_hba *hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct fcoe_statistics_params *fw_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) fw_stats = (struct fcoe_statistics_params *)hba->stats_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (!fw_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) mutex_lock(&hba->hba_stats_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) bnx2fc_stats = fc_get_host_stats(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) init_completion(&hba->stat_req_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (bnx2fc_send_stat_req(hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) goto unlock_stats_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) rc = wait_for_completion_timeout(&hba->stat_req_done, (2 * HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) BNX2FC_HBA_DBG(lport, "FW stat req timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) goto unlock_stats_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) BNX2FC_STATS(hba, rx_stat2, fc_crc_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) bnx2fc_stats->invalid_crc_count += hba->bfw_stats.fc_crc_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) BNX2FC_STATS(hba, tx_stat, fcoe_tx_pkt_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) bnx2fc_stats->tx_frames += hba->bfw_stats.fcoe_tx_pkt_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) BNX2FC_STATS(hba, tx_stat, fcoe_tx_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) bnx2fc_stats->tx_words += ((hba->bfw_stats.fcoe_tx_byte_cnt) / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) BNX2FC_STATS(hba, rx_stat0, fcoe_rx_pkt_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) bnx2fc_stats->rx_frames += hba->bfw_stats.fcoe_rx_pkt_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) BNX2FC_STATS(hba, rx_stat0, fcoe_rx_byte_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) bnx2fc_stats->rx_words += ((hba->bfw_stats.fcoe_rx_byte_cnt) / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) bnx2fc_stats->dumped_frames = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) bnx2fc_stats->lip_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) bnx2fc_stats->nos_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) bnx2fc_stats->loss_of_sync_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) bnx2fc_stats->loss_of_signal_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) bnx2fc_stats->prim_seq_protocol_err_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) memcpy(&hba->prev_stats, hba->stats_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) sizeof(struct fcoe_statistics_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) unlock_stats_mutex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) mutex_unlock(&hba->hba_stats_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return bnx2fc_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct bnx2fc_hba *hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct Scsi_Host *shost = lport->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) shost->max_cmd_len = BNX2FC_MAX_CMD_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) shost->max_lun = bnx2fc_max_luns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) shost->max_id = BNX2FC_MAX_FCP_TGT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) shost->max_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (lport->vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) shost->transportt = bnx2fc_vport_xport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) shost->transportt = bnx2fc_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /* Add the new host to SCSI-ml */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) rc = scsi_add_host(lport->host, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) printk(KERN_ERR PFX "Error on scsi_add_host\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (!lport->vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) fc_host_max_npiv_vports(lport->host) = USHRT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) snprintf(fc_host_symbolic_name(lport->host), 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) "%s (QLogic %s) v%s over %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) BNX2FC_NAME, hba->chip_num, BNX2FC_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) interface->netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int bnx2fc_link_ok(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct bnx2fc_hba *hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct net_device *dev = hba->phys_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if ((dev->flags & IFF_UP) && netif_carrier_ok(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) clear_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) set_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * bnx2fc_get_link_state - get network link state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * @hba: adapter instance pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * updates adapter structure flag based on netdev state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) void bnx2fc_get_link_state(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (test_bit(__LINK_STATE_NOCARRIER, &hba->phys_dev->state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) set_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) clear_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) u64 wwnn, wwpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* require support for get_pauseparam ethtool op. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!hba->phys_dev->ethtool_ops ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) !hba->phys_dev->ethtool_ops->get_pauseparam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (fc_set_mfs(lport, BNX2FC_MFS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) skb_queue_head_init(&port->fcoe_pending_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) port->fcoe_pending_queue_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) timer_setup(&port->timer, fcoe_queue_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) fcoe_link_speed_update(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (!lport->vport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) fc_set_wwnn(lport, wwnn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) fc_set_wwpn(lport, wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static void bnx2fc_destroy_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct bnx2fc_hba *hba = from_timer(hba, t, destroy_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) printk(KERN_ERR PFX "ERROR:bnx2fc_destroy_timer - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) "Destroy compl not received!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) set_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) wake_up_interruptible(&hba->destroy_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * bnx2fc_indicate_netevent - Generic netdev event handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * @context: adapter structure pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * @event: event type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * @vlan_id: vlan id - associated vlan id with this event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * Handles NETDEV_UP, NETDEV_DOWN, NETDEV_GOING_DOWN,NETDEV_CHANGE and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * NETDEV_CHANGE_MTU events. Handle NETDEV_UNREGISTER only for vlans.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static void bnx2fc_indicate_netevent(void *context, unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) u16 vlan_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct bnx2fc_hba *hba = (struct bnx2fc_hba *)context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct fcoe_ctlr_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct fc_lport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct bnx2fc_interface *interface, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int wait_for_upload = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) u32 link_possible = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (vlan_id != 0 && event != NETDEV_UNREGISTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) case NETDEV_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) printk(KERN_ERR "indicate_netevent: "\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) "hba is not UP!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case NETDEV_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) link_possible = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case NETDEV_GOING_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) set_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) link_possible = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) case NETDEV_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case NETDEV_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (!vlan_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) list_for_each_entry_safe(interface, tmp, &if_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (interface->hba == hba &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) interface->vlan_id == (vlan_id & VLAN_VID_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) __bnx2fc_destroy(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) list_for_each_entry(interface, &if_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (interface->hba != hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) interface->netdev->name, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) fcoe_link_speed_update(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (link_possible && !bnx2fc_link_ok(lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) switch (cdev->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) case FCOE_CTLR_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) pr_info("Link up while interface is disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) case FCOE_CTLR_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) case FCOE_CTLR_UNUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /* Reset max recv frame size to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) fc_set_mfs(lport, BNX2FC_MFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * ctlr link up will only be handled during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * enable to avoid sending discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) * solicitation on a stale vlan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (interface->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) } else if (fcoe_ctlr_link_down(ctlr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) switch (cdev->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) case FCOE_CTLR_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) pr_info("Link down while interface is disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) case FCOE_CTLR_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) case FCOE_CTLR_UNUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) mutex_lock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) list_for_each_entry(vport, &lport->vports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) fc_host_port_type(vport->host) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) FC_PORTTYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) mutex_unlock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) fc_host_port_type(lport->host) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) FC_PORTTYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) per_cpu_ptr(lport->stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) get_cpu())->LinkFailureCount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) put_cpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) fcoe_clean_pending_queue(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) wait_for_upload = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (wait_for_upload) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) clear_bit(ADAPTER_STATE_READY, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) init_waitqueue_head(&hba->shutdown_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) BNX2FC_MISC_DBG("indicate_netevent "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) "num_ofld_sess = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) hba->num_ofld_sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) hba->wait_for_link_down = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) wait_event_interruptible(hba->shutdown_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) (hba->num_ofld_sess == 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) BNX2FC_MISC_DBG("wakeup - num_ofld_sess = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) hba->num_ofld_sess);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) hba->wait_for_link_down = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) flush_signals(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static int bnx2fc_libfc_config(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /* Set the function pointers set by bnx2fc driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) memcpy(&lport->tt, &bnx2fc_libfc_fcn_templ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) sizeof(struct libfc_function_template));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) fc_elsct_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) fc_exch_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) fc_disc_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) fc_disc_config(lport, lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static int bnx2fc_em_config(struct fc_lport *lport, struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) int fcoe_min_xid, fcoe_max_xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) fcoe_min_xid = hba->max_xid + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (nr_cpu_ids <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) fcoe_max_xid = hba->max_xid + FCOE_XIDS_PER_CPU_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) fcoe_max_xid = hba->max_xid + FCOE_MAX_XID_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (!fc_exch_mgr_alloc(lport, FC_CLASS_3, fcoe_min_xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) fcoe_max_xid, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) printk(KERN_ERR PFX "em_config:fc_exch_mgr_alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static int bnx2fc_lport_config(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) lport->link_up = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) lport->qfull = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) lport->max_retry_count = BNX2FC_MAX_RETRY_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) lport->max_rport_retry_count = BNX2FC_MAX_RPORT_RETRY_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) lport->e_d_tov = 2 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) lport->r_a_tov = 10 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) lport->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) lport->does_npiv = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) memset(&lport->rnid_gen, 0, sizeof(struct fc_els_rnid_gen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) lport->rnid_gen.rnid_atype = BNX2FC_RNID_HBA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /* alloc stats structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (fc_lport_init_stats(lport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /* Finish fc_lport configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) fc_lport_config(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * bnx2fc_fip_recv - handle a received FIP frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * @skb: the received skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * @dev: associated &net_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * @ptype: the &packet_type structure which was used to register this handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * @orig_dev: original receive &net_device, in case @ dev is a bond.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static int bnx2fc_fip_recv(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct packet_type *ptype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) interface = container_of(ptype, struct bnx2fc_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) fip_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) fcoe_ctlr_recv(ctlr, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * bnx2fc_update_src_mac - Update Ethernet MAC filters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * @lport: The local port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * @addr: Location of data to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * Remove any previously-set unicast MAC filter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * Add secondary FCoE MAC address filter for our OUI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static void bnx2fc_update_src_mac(struct fc_lport *lport, u8 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) memcpy(port->data_src_addr, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * bnx2fc_get_src_mac - return the ethernet source address for an lport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * @lport: libfc port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static u8 *bnx2fc_get_src_mac(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) port = (struct fcoe_port *)lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return port->data_src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * bnx2fc_fip_send - send an Ethernet-encapsulated FIP frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * @fip: FCoE controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * @skb: FIP Packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static void bnx2fc_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) struct fip_header *fiph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct ethhdr *eth_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) u16 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) u8 sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) fiph = (struct fip_header *) ((void *)skb->data + 2 * ETH_ALEN + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) eth_hdr = (struct ethhdr *)skb_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) op = ntohs(fiph->fip_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) sub = fiph->fip_subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (op == FIP_OP_CTRL && sub == FIP_SC_SOL && bnx2fc_log_fka)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) BNX2FC_MISC_DBG("Sending FKA from %pM to %pM.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) eth_hdr->h_source, eth_hdr->h_dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) skb->dev = bnx2fc_from_ctlr(fip)->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) dev_queue_xmit(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct Scsi_Host *shost = vport_to_shost(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct fc_lport *n_port = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct fcoe_port *port = lport_priv(n_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct net_device *netdev = interface->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct fc_lport *vn_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) char buf[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) rc = fcoe_validate_vport_create(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) printk(KERN_ERR PFX "Failed to create vport, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) "WWPN (0x%s) already exists\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) printk(KERN_ERR PFX "vn ports cannot be created on"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) "this interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) vn_port = bnx2fc_if_create(interface, &vport->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (!vn_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) printk(KERN_ERR PFX "bnx2fc_vport_create (%s) failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (bnx2fc_devloss_tmo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) fc_host_dev_loss_tmo(vn_port->host) = bnx2fc_devloss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (disabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) fc_vport_set_state(vport, FC_VPORT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) vn_port->boot_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) fc_lport_init(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) fc_fabric_login(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) fc_vport_setlink(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static void bnx2fc_free_vport(struct bnx2fc_hba *hba, struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct bnx2fc_lport *blport, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) spin_lock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) list_for_each_entry_safe(blport, tmp, &hba->vports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (blport->lport == lport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) list_del(&blport->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) kfree(blport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) spin_unlock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static int bnx2fc_vport_destroy(struct fc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct Scsi_Host *shost = vport_to_shost(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) struct fc_lport *n_port = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct fc_lport *vn_port = vport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct fcoe_port *port = lport_priv(vn_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct fc_lport *v_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) mutex_lock(&n_port->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) list_for_each_entry(v_port, &n_port->vports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (v_port->vport == vport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) mutex_unlock(&n_port->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) list_del(&vn_port->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) mutex_unlock(&n_port->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) bnx2fc_free_vport(interface->hba, port->lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) bnx2fc_port_shutdown(port->lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) bnx2fc_port_destroy(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) bnx2fc_interface_put(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static int bnx2fc_vport_disable(struct fc_vport *vport, bool disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct fc_lport *lport = vport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) fc_vport_set_state(vport, FC_VPORT_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) fc_fabric_logoff(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) lport->boot_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) fc_fabric_login(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) fc_vport_setlink(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static int bnx2fc_interface_setup(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) struct net_device *netdev = interface->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct net_device *physdev = interface->hba->phys_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) int sel_san_mac = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /* setup Source MAC Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) for_each_dev_addr(physdev, ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) BNX2FC_MISC_DBG("net_config: ha->type = %d, fip_mac = ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) ha->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) printk(KERN_INFO "%2x:%2x:%2x:%2x:%2x:%2x\n", ha->addr[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ha->addr[1], ha->addr[2], ha->addr[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ha->addr[4], ha->addr[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) (is_valid_ether_addr(ha->addr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) memcpy(ctlr->ctl_src_addr, ha->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) sel_san_mac = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) BNX2FC_MISC_DBG("Found SAN MAC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (!sel_san_mac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) interface->fip_packet_type.func = bnx2fc_fip_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) interface->fip_packet_type.type = htons(ETH_P_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) interface->fip_packet_type.dev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) dev_add_pack(&interface->fip_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) interface->fcoe_packet_type.func = bnx2fc_rcv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) interface->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) interface->fcoe_packet_type.dev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) dev_add_pack(&interface->fcoe_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) static int bnx2fc_attach_transport(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) bnx2fc_transport_template =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) fc_attach_transport(&bnx2fc_transport_function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (bnx2fc_transport_template == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) printk(KERN_ERR PFX "Failed to attach FC transport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) bnx2fc_vport_xport_template =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) fc_attach_transport(&bnx2fc_vport_xport_function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (bnx2fc_vport_xport_template == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) "Failed to attach FC transport for vport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) fc_release_transport(bnx2fc_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) bnx2fc_transport_template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static void bnx2fc_release_transport(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) fc_release_transport(bnx2fc_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) fc_release_transport(bnx2fc_vport_xport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) bnx2fc_transport_template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) bnx2fc_vport_xport_template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) static void bnx2fc_interface_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct fcoe_ctlr_device *ctlr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) interface = container_of(kref, struct bnx2fc_interface, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) BNX2FC_MISC_DBG("Interface is being released\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) netdev = interface->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) /* tear-down FIP controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) fcoe_ctlr_destroy(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) fcoe_ctlr_device_delete(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) dev_put(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static inline void bnx2fc_interface_get(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) kref_get(&interface->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static inline void bnx2fc_interface_put(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) kref_put(&interface->kref, bnx2fc_interface_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) static void bnx2fc_hba_destroy(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /* Free the command manager */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (hba->cmd_mgr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) bnx2fc_cmd_mgr_free(hba->cmd_mgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) hba->cmd_mgr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) kfree(hba->tgt_ofld_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) bnx2fc_unbind_pcidev(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) kfree(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) * bnx2fc_hba_create - create a new bnx2fc hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) * @cnic: pointer to cnic device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * Creates a new FCoE hba on the given device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) struct fcoe_capabilities *fcoe_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) hba = kzalloc(sizeof(*hba), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (!hba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) printk(KERN_ERR PFX "Unable to allocate hba structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) spin_lock_init(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) mutex_init(&hba->hba_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) mutex_init(&hba->hba_stats_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) hba->cnic = cnic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) hba->max_tasks = cnic->max_fcoe_exchanges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) hba->elstm_xids = (hba->max_tasks / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) hba->max_outstanding_cmds = hba->elstm_xids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) hba->max_xid = (hba->max_tasks - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) rc = bnx2fc_bind_pcidev(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) printk(KERN_ERR PFX "create_adapter: bind error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) goto bind_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) hba->phys_dev = cnic->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) hba->next_conn_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) hba->tgt_ofld_list =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) kcalloc(BNX2FC_NUM_MAX_SESS, sizeof(struct bnx2fc_rport *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (!hba->tgt_ofld_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) printk(KERN_ERR PFX "Unable to allocate tgt offload list\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) goto tgtofld_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) hba->num_ofld_sess = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) hba->cmd_mgr = bnx2fc_cmd_mgr_alloc(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) if (!hba->cmd_mgr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) printk(KERN_ERR PFX "em_config:bnx2fc_cmd_mgr_alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) goto cmgr_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) fcoe_cap = &hba->fcoe_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) fcoe_cap->capability1 = BNX2FC_TM_MAX_SQES <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) FCOE_IOS_PER_CONNECTION_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) fcoe_cap->capability1 |= BNX2FC_NUM_MAX_SESS <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) FCOE_LOGINS_PER_PORT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) fcoe_cap->capability2 = hba->max_outstanding_cmds <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) FCOE_NUMBER_OF_EXCHANGES_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) fcoe_cap->capability2 |= BNX2FC_MAX_NPIV <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) FCOE_NPIV_WWN_PER_PORT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) fcoe_cap->capability3 = BNX2FC_NUM_MAX_SESS <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) FCOE_TARGETS_SUPPORTED_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) fcoe_cap->capability3 |= hba->max_outstanding_cmds <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) FCOE_OUTSTANDING_COMMANDS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) fcoe_cap->capability4 = FCOE_CAPABILITY4_STATEFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) init_waitqueue_head(&hba->shutdown_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) init_waitqueue_head(&hba->destroy_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) INIT_LIST_HEAD(&hba->vports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) cmgr_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) kfree(hba->tgt_ofld_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) tgtofld_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) bnx2fc_unbind_pcidev(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) bind_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) kfree(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) static struct bnx2fc_interface *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) bnx2fc_interface_create(struct bnx2fc_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) enum fip_mode fip_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) struct fcoe_ctlr_device *ctlr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) size = (sizeof(*interface) + sizeof(struct fcoe_ctlr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &bnx2fc_fcoe_sysfs_templ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (!ctlr_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) printk(KERN_ERR PFX "Unable to allocate interface structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ctlr = fcoe_ctlr_device_priv(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ctlr->cdev = ctlr_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) interface = fcoe_ctlr_priv(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) dev_hold(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) kref_init(&interface->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) interface->hba = hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) interface->netdev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) /* Initialize FIP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) fcoe_ctlr_init(ctlr, fip_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) ctlr->send = bnx2fc_fip_send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) ctlr->update_mac = bnx2fc_update_src_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) ctlr->get_src_addr = bnx2fc_get_src_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) rc = bnx2fc_interface_setup(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) fcoe_ctlr_destroy(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) dev_put(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) fcoe_ctlr_device_delete(ctlr_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) * bnx2fc_if_create - Create FCoE instance on a given interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) * @interface: FCoE interface to create a local port on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * @parent: Device pointer to be the parent in sysfs for the SCSI host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * @npiv: Indicates if the port is vport or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * Creates a fc_lport instance and a Scsi_Host instance and configure them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * Returns: Allocated fc_lport or an error pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct device *parent, int npiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) struct fc_lport *lport, *n_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) struct fcoe_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) struct fc_vport *vport = dev_to_vport(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) struct bnx2fc_lport *blport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) struct bnx2fc_hba *hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (!blport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) BNX2FC_HBA_DBG(ctlr->lp, "Unable to alloc blport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* Allocate Scsi_Host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) bnx2fc_shost_template.can_queue = hba->max_outstanding_cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (!npiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) lport = libfc_host_alloc(&bnx2fc_shost_template, sizeof(*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) lport = libfc_vport_create(vport, sizeof(*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (!lport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) printk(KERN_ERR PFX "could not allocate scsi host structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) goto free_blport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) shost = lport->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) port->lport = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) port->priv = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) port->get_netdev = bnx2fc_netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) /* Configure fcoe_port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) rc = bnx2fc_lport_config(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) goto lp_config_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if (npiv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) printk(KERN_ERR PFX "Setting vport names, 0x%llX 0x%llX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) vport->node_name, vport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) fc_set_wwnn(lport, vport->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) fc_set_wwpn(lport, vport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) /* Configure netdev and networking properties of the lport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) rc = bnx2fc_net_config(lport, interface->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) printk(KERN_ERR PFX "Error on bnx2fc_net_config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) goto lp_config_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) rc = bnx2fc_shost_config(lport, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) printk(KERN_ERR PFX "Couldn't configure shost for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) interface->netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) goto lp_config_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) /* Initialize the libfc library */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) rc = bnx2fc_libfc_config(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) printk(KERN_ERR PFX "Couldn't configure libfc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) goto shost_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (bnx2fc_devloss_tmo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) fc_host_dev_loss_tmo(shost) = bnx2fc_devloss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) /* Allocate exchange manager */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (!npiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) rc = bnx2fc_em_config(lport, hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) shost = vport_to_shost(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) n_port = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) rc = fc_exch_mgr_list_clone(n_port, lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) printk(KERN_ERR PFX "Error on bnx2fc_em_config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) goto shost_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) bnx2fc_interface_get(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) spin_lock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) blport->lport = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) list_add_tail(&blport->list, &hba->vports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) spin_unlock_bh(&hba->hba_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) shost_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) scsi_remove_host(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) lp_config_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) scsi_host_put(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) free_blport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) kfree(blport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) static void bnx2fc_net_cleanup(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) /* Dont listen for Ethernet packets anymore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) __dev_remove_pack(&interface->fcoe_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) __dev_remove_pack(&interface->fip_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) struct fc_lport *lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) struct bnx2fc_hba *hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) /* Stop the transmit retry timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) del_timer_sync(&port->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) /* Free existing transmit skbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) fcoe_clean_pending_queue(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) bnx2fc_net_cleanup(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) bnx2fc_free_vport(hba, lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) static void bnx2fc_if_destroy(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) /* Free queued packets for the receive thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) bnx2fc_clean_rx_queue(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /* Detach from scsi-ml */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) fc_remove_host(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) scsi_remove_host(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) * Note that only the physical lport will have the exchange manager.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) * for vports, this function is NOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) fc_exch_mgr_free(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) /* Free memory used by statistical counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) fc_lport_free_stats(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) /* Release Scsi_Host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) scsi_host_put(lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static void __bnx2fc_destroy(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) struct fc_lport *lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) bnx2fc_interface_cleanup(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) bnx2fc_stop(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) list_del(&interface->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) bnx2fc_port_destroy(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) bnx2fc_interface_put(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) * bnx2fc_destroy - Destroy a bnx2fc FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * @netdev: The net device that the FCoE interface is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) * Called from sysfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static int bnx2fc_destroy(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct bnx2fc_interface *interface = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) struct workqueue_struct *timer_work_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) interface = bnx2fc_interface_lookup(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) if (!interface || !ctlr->lp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) printk(KERN_ERR PFX "bnx2fc_destroy: interface or lport not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) goto netdev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) timer_work_queue = interface->timer_work_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) __bnx2fc_destroy(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) destroy_workqueue(timer_work_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) netdev_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) static void bnx2fc_port_destroy(struct fcoe_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) lport = port->lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) BNX2FC_HBA_DBG(lport, "Entered %s, destroying lport %p\n", __func__, lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) bnx2fc_if_destroy(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) static void bnx2fc_unbind_adapter_devices(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) bnx2fc_free_fw_resc(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) bnx2fc_free_task_ctx(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) * bnx2fc_bind_adapter_devices - binds bnx2fc adapter with the associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) * pci structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) * @hba: Adapter instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) static int bnx2fc_bind_adapter_devices(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (bnx2fc_setup_task_ctx(hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) goto mem_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (bnx2fc_setup_fw_resc(hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) goto mem_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) mem_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) bnx2fc_unbind_adapter_devices(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) struct cnic_dev *cnic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (!hba->cnic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) printk(KERN_ERR PFX "cnic is NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) cnic = hba->cnic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) pdev = hba->pcidev = cnic->pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) if (!hba->pcidev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) switch (pdev->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) case PCI_DEVICE_ID_NX2_57710:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) strncpy(hba->chip_num, "BCM57710", BCM_CHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) case PCI_DEVICE_ID_NX2_57711:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) strncpy(hba->chip_num, "BCM57711", BCM_CHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) case PCI_DEVICE_ID_NX2_57712:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) case PCI_DEVICE_ID_NX2_57712_MF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) case PCI_DEVICE_ID_NX2_57712_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) strncpy(hba->chip_num, "BCM57712", BCM_CHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) case PCI_DEVICE_ID_NX2_57800:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) case PCI_DEVICE_ID_NX2_57800_MF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) case PCI_DEVICE_ID_NX2_57800_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) strncpy(hba->chip_num, "BCM57800", BCM_CHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) case PCI_DEVICE_ID_NX2_57810:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) case PCI_DEVICE_ID_NX2_57810_MF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) case PCI_DEVICE_ID_NX2_57810_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) strncpy(hba->chip_num, "BCM57810", BCM_CHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) case PCI_DEVICE_ID_NX2_57840:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) case PCI_DEVICE_ID_NX2_57840_MF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) case PCI_DEVICE_ID_NX2_57840_VF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) case PCI_DEVICE_ID_NX2_57840_2_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) case PCI_DEVICE_ID_NX2_57840_4_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) strncpy(hba->chip_num, "BCM57840", BCM_CHIP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) pr_err(PFX "Unknown device id 0x%x\n", pdev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) pci_dev_get(hba->pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (hba->pcidev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) hba->chip_num[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) pci_dev_put(hba->pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) hba->pcidev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) * bnx2fc_ulp_get_stats - cnic callback to populate FCoE stats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) * @handle: transport handle pointing to adapter struture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) static int bnx2fc_ulp_get_stats(void *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) struct bnx2fc_hba *hba = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) struct cnic_dev *cnic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) struct fcoe_stats_info *stats_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) if (!hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) cnic = hba->cnic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) stats_addr = &cnic->stats_addr->fcoe_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (!stats_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) strncpy(stats_addr->version, BNX2FC_VERSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) sizeof(stats_addr->version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) stats_addr->txq_size = BNX2FC_SQ_WQES_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) stats_addr->rxq_size = BNX2FC_CQ_WQES_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) * bnx2fc_ulp_start - cnic callback to initialize & start adapter instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) * @handle: transport handle pointing to adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) * This function maps adapter structure to pcidev structure and initiates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) * firmware handshake to enable/initialize on-chip FCoE components.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) * This bnx2fc - cnic interface api callback is used after following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) * conditions are met -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) * a) underlying network interface is up (marked by event NETDEV_UP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) * from netdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) * b) bnx2fc adatper structure is registered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) static void bnx2fc_ulp_start(void *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) struct bnx2fc_hba *hba = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) bnx2fc_fw_init(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) BNX2FC_MISC_DBG("bnx2fc started.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) list_for_each_entry(interface, &if_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) if (interface->hba == hba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) /* Kick off Fabric discovery*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) printk(KERN_ERR PFX "ulp_init: start discovery\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) lport->tt.frame_send = bnx2fc_xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) bnx2fc_start_disc(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) static void bnx2fc_port_shutdown(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) BNX2FC_MISC_DBG("Entered %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) fc_fabric_logoff(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) fc_lport_destroy(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) static void bnx2fc_stop(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) struct fc_lport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) bnx2fc_port_shutdown(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) mutex_lock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) list_for_each_entry(vport, &lport->vports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) fc_host_port_type(vport->host) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) FC_PORTTYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) mutex_unlock(&lport->lp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) fcoe_ctlr_link_down(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) fcoe_clean_pending_queue(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static int bnx2fc_fw_init(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) #define BNX2FC_INIT_POLL_TIME (1000 / HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) int rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) int i = HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) rc = bnx2fc_bind_adapter_devices(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) printk(KERN_ALERT PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) "bnx2fc_bind_adapter_devices failed - rc = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) rc = bnx2fc_send_fw_fcoe_init_msg(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) printk(KERN_ALERT PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) "bnx2fc_send_fw_fcoe_init_msg failed - rc = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) goto err_unbind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * Wait until the adapter init message is complete, and adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) * state is UP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) while (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) && i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) msleep(BNX2FC_INIT_POLL_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) printk(KERN_ERR PFX "bnx2fc_start: %s failed to initialize. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) "Ignoring...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) hba->cnic->netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) goto err_unbind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) set_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) err_unbind:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) bnx2fc_unbind_adapter_devices(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (test_and_clear_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (bnx2fc_send_fw_fcoe_destroy_msg(hba) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) timer_setup(&hba->destroy_timer, bnx2fc_destroy_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) hba->destroy_timer.expires = BNX2FC_FW_TIMEOUT +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) add_timer(&hba->destroy_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) wait_event_interruptible(hba->destroy_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) test_bit(BNX2FC_FLAG_DESTROY_CMPL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) &hba->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) clear_bit(BNX2FC_FLAG_DESTROY_CMPL, &hba->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) /* This should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) flush_signals(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) del_timer_sync(&hba->destroy_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) bnx2fc_unbind_adapter_devices(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) * bnx2fc_ulp_stop - cnic callback to shutdown adapter instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) * @handle: transport handle pointing to adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) * Driver checks if adapter is already in shutdown mode, if not start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * the shutdown process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) static void bnx2fc_ulp_stop(void *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) struct bnx2fc_hba *hba = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) printk(KERN_ERR "ULP_STOP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) list_for_each_entry(interface, &if_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if (interface->hba == hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) bnx2fc_stop(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) BUG_ON(hba->num_ofld_sess != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) mutex_lock(&hba->hba_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) clear_bit(ADAPTER_STATE_GOING_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) clear_bit(ADAPTER_STATE_READY, &hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) mutex_unlock(&hba->hba_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) bnx2fc_fw_destroy(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) static void bnx2fc_start_disc(struct bnx2fc_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) int wait_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) BNX2FC_MISC_DBG("Entered %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) /* Kick off FIP/FLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) printk(KERN_ERR PFX "Init not done yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (!bnx2fc_link_ok(lport) && interface->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) BNX2FC_HBA_DBG(lport, "ctlr_link_up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) /* wait for the FCF to be selected before issuing FLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) while (!ctlr->sel_fcf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) msleep(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) /* give up after 3 secs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (++wait_cnt > 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) /* Reset max receive frame size to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) if (fc_set_mfs(lport, BNX2FC_MFS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) fc_lport_init(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) fc_fabric_login(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) * bnx2fc_ulp_init - Initialize an adapter instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) * @dev : cnic device handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) * Called from cnic_register_driver() context to initialize all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) * enumerated cnic devices. This routine allocates adapter structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) * and other device specific resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) static void bnx2fc_ulp_init(struct cnic_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) BNX2FC_MISC_DBG("Entered %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) /* bnx2fc works only when bnx2x is loaded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (!test_bit(CNIC_F_BNX2X_CLASS, &dev->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) (dev->max_fcoe_conn == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) printk(KERN_ERR PFX "bnx2fc FCoE not supported on %s,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) " flags: %lx fcoe_conn: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) dev->netdev->name, dev->flags, dev->max_fcoe_conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) hba = bnx2fc_hba_create(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) if (!hba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) printk(KERN_ERR PFX "hba initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) pr_info(PFX "FCoE initialized for %s.\n", dev->netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) /* Add HBA to the adapter list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) list_add_tail(&hba->list, &adapter_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) adapter_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) dev->fcoe_cap = &hba->fcoe_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) rc = dev->register_device(dev, CNIC_ULP_FCOE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) (void *) hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) printk(KERN_ERR PFX "register_device failed, rc = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) set_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) /* Assumes rtnl_lock and the bnx2fc_dev_lock are already taken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) static int __bnx2fc_disable(struct fcoe_ctlr *ctlr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) if (interface->enabled == true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) if (!ctlr->lp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) pr_err(PFX "__bnx2fc_disable: lport not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) interface->enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) fcoe_ctlr_link_down(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) fcoe_clean_pending_queue(ctlr->lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) * Deperecated: Use bnx2fc_enabled()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) static int bnx2fc_disable(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) interface = bnx2fc_interface_lookup(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) if (!interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) pr_err(PFX "bnx2fc_disable: interface not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) rc = __bnx2fc_disable(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) static uint bnx2fc_npiv_create_vports(struct fc_lport *lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) struct cnic_fc_npiv_tbl *npiv_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) struct fc_vport_identifiers vpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) uint i, created = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) u64 wwnn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) char wwpn_str[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) char wwnn_str[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) if (npiv_tbl->count > MAX_NPIV_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) BNX2FC_HBA_DBG(lport, "Exceeded count max of npiv table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) /* Sanity check the first entry to make sure it's not 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) if (wwn_to_u64(npiv_tbl->wwnn[0]) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) wwn_to_u64(npiv_tbl->wwpn[0]) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) BNX2FC_HBA_DBG(lport, "First NPIV table entries invalid.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) vpid.roles = FC_PORT_ROLE_FCP_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) vpid.vport_type = FC_PORTTYPE_NPIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) vpid.disable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) for (i = 0; i < npiv_tbl->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) wwnn = wwn_to_u64(npiv_tbl->wwnn[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (wwnn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) * If we get a 0 element from for the WWNN then assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) * the WWNN should be the same as the physical port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) wwnn = lport->wwnn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) vpid.node_name = wwnn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) vpid.port_name = wwn_to_u64(npiv_tbl->wwpn[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) scnprintf(vpid.symbolic_name, sizeof(vpid.symbolic_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) "NPIV[%u]:%016llx-%016llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) created, vpid.port_name, vpid.node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) fcoe_wwn_to_str(vpid.node_name, wwnn_str, sizeof(wwnn_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) fcoe_wwn_to_str(vpid.port_name, wwpn_str, sizeof(wwpn_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) BNX2FC_HBA_DBG(lport, "Creating vport %s:%s.\n", wwnn_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) wwpn_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) if (fc_vport_create(lport->host, 0, &vpid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) created++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) BNX2FC_HBA_DBG(lport, "Failed to create vport\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) return created;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) static int __bnx2fc_enable(struct fcoe_ctlr *ctlr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) struct cnic_fc_npiv_tbl *npiv_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) if (interface->enabled == false) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if (!ctlr->lp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) pr_err(PFX "__bnx2fc_enable: lport not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) } else if (!bnx2fc_link_ok(ctlr->lp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) interface->enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) /* Create static NPIV ports if any are contained in NVRAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) hba = interface->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) lport = ctlr->lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) if (!hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) if (!hba->cnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) if (!lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (!lport->host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) if (!hba->cnic->get_fc_npiv_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) npiv_tbl = kzalloc(sizeof(struct cnic_fc_npiv_tbl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) if (!npiv_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) if (hba->cnic->get_fc_npiv_tbl(hba->cnic, npiv_tbl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) goto done_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) bnx2fc_npiv_create_vports(lport, npiv_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) done_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) kfree(npiv_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) * Deprecated: Use bnx2fc_enabled()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) static int bnx2fc_enable(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) interface = bnx2fc_interface_lookup(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) if (!interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) pr_err(PFX "bnx2fc_enable: interface not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) rc = __bnx2fc_enable(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * bnx2fc_ctlr_enabled() - Enable or disable an FCoE Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) * @cdev: The FCoE Controller that is being enabled or disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) * fcoe_sysfs will ensure that the state of 'enabled' has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) * changed, so no checking is necessary here. This routine simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) * calls fcoe_enable or fcoe_disable, both of which are deprecated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) * When those routines are removed the functionality can be merged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) switch (cdev->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) case FCOE_CTLR_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) return __bnx2fc_enable(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) case FCOE_CTLR_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) return __bnx2fc_disable(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) case FCOE_CTLR_UNUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) enum bnx2fc_create_link_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) BNX2FC_CREATE_LINK_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) BNX2FC_CREATE_LINK_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) * _bnx2fc_create() - Create bnx2fc FCoE interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) * @fip_mode: The FIP mode for this creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) * @link_state: The ctlr link state on creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) * Called from either the libfcoe 'create' module parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) * via fcoe_create or from fcoe_syfs's ctlr_create file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) * libfcoe's 'create' module parameter is deprecated so some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) * consolidation of code can be done when that interface is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) * removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) static int _bnx2fc_create(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) enum fip_mode fip_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) enum bnx2fc_create_link_state link_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) struct fcoe_ctlr_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) struct fcoe_ctlr *ctlr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) struct net_device *phys_dev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) struct fc_lport *lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) struct ethtool_drvinfo drvinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) int vlan_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) BNX2FC_MISC_DBG("Entered bnx2fc_create\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) if (fip_mode != FIP_MODE_FABRIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) printk(KERN_ERR "fip mode not FABRIC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) if (!try_module_get(THIS_MODULE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) goto mod_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) /* obtain physical netdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) if (is_vlan_dev(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) phys_dev = vlan_dev_real_dev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) /* verify if the physical device is a netxtreme2 device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) if (phys_dev->ethtool_ops && phys_dev->ethtool_ops->get_drvinfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) memset(&drvinfo, 0, sizeof(drvinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) phys_dev->ethtool_ops->get_drvinfo(phys_dev, &drvinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) if (strncmp(drvinfo.driver, "bnx2x", strlen("bnx2x"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) printk(KERN_ERR PFX "Not a netxtreme2 device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) goto netdev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) printk(KERN_ERR PFX "unable to obtain drv_info\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) goto netdev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) /* obtain interface and initialize rest of the structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) hba = bnx2fc_hba_lookup(phys_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) if (!hba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) printk(KERN_ERR PFX "bnx2fc_create: hba not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) goto netdev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) if (bnx2fc_interface_lookup(netdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) rc = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) goto netdev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) interface = bnx2fc_interface_create(hba, netdev, fip_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) if (!interface) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) printk(KERN_ERR PFX "bnx2fc_interface_create failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) goto netdev_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) if (is_vlan_dev(netdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) vlan_id = vlan_dev_vlan_id(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) interface->vlan_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) ctlr = bnx2fc_to_ctlr(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) interface->vlan_id = vlan_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) interface->tm_timeout = BNX2FC_TM_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) interface->timer_work_queue =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) create_singlethread_workqueue("bnx2fc_timer_wq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) if (!interface->timer_work_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) printk(KERN_ERR PFX "ulp_init could not create timer_wq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) goto ifput_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) lport = bnx2fc_if_create(interface, &cdev->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) if (!lport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) printk(KERN_ERR PFX "Failed to create interface (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) netdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) goto if_create_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) /* Add interface to if_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) list_add_tail(&interface->list, &if_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) lport->boot_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) /* Make this master N_port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) ctlr->lp = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (link_state == BNX2FC_CREATE_LINK_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) cdev->enabled = FCOE_CTLR_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) cdev->enabled = FCOE_CTLR_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) if (link_state == BNX2FC_CREATE_LINK_UP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) !bnx2fc_link_ok(lport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) fcoe_ctlr_link_up(ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) BNX2FC_HBA_DBG(lport, "create: START DISC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) bnx2fc_start_disc(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) if (link_state == BNX2FC_CREATE_LINK_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) interface->enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) * Release from kref_init in bnx2fc_interface_setup, on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) * lport should be holding a reference taken in bnx2fc_if_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) bnx2fc_interface_put(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) /* put netdev that was held while calling dev_get_by_name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) if_create_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) destroy_workqueue(interface->timer_work_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) ifput_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) bnx2fc_net_cleanup(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) bnx2fc_interface_put(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) goto mod_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) netdev_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) mod_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) * bnx2fc_create() - Create a bnx2fc interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) * @netdev : The net_device object the Ethernet interface to create on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) * @fip_mode: The FIP mode for this creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) * Called from fcoe transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) * Returns: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) static int bnx2fc_create(struct net_device *netdev, enum fip_mode fip_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) return _bnx2fc_create(netdev, fip_mode, BNX2FC_CREATE_LINK_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) * bnx2fc_ctlr_alloc() - Allocate a bnx2fc interface from fcoe_sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) * @netdev: The net_device to be used by the allocated FCoE Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) * This routine is called from fcoe_sysfs. It will start the fcoe_ctlr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) * in a link_down state. The allows the user an opportunity to configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) * the FCoE Controller from sysfs before enabling the FCoE Controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) * Creating in with this routine starts the FCoE Controller in Fabric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) * mode. The user can change to VN2VN or another mode before enabling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) static int bnx2fc_ctlr_alloc(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) return _bnx2fc_create(netdev, FIP_MODE_FABRIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) BNX2FC_CREATE_LINK_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) * bnx2fc_find_hba_for_cnic - maps cnic instance to bnx2fc hba instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) * @cnic: Pointer to cnic device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) static struct bnx2fc_hba *bnx2fc_find_hba_for_cnic(struct cnic_dev *cnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) /* Called with bnx2fc_dev_lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) list_for_each_entry(hba, &adapter_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) if (hba->cnic == cnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) return hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) struct bnx2fc_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) /* Called with bnx2fc_dev_lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) list_for_each_entry(interface, &if_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) if (interface->netdev == netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) return interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) *phys_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) /* Called with bnx2fc_dev_lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) list_for_each_entry(hba, &adapter_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) if (hba->phys_dev == phys_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) return hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) printk(KERN_ERR PFX "adapter_lookup: hba NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) * bnx2fc_ulp_exit - shuts down adapter instance and frees all resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) * @dev: cnic device handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) static void bnx2fc_ulp_exit(struct cnic_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) struct bnx2fc_hba *hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) struct bnx2fc_interface *interface, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) BNX2FC_MISC_DBG("Entered bnx2fc_ulp_exit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) if (!test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) printk(KERN_ERR PFX "bnx2fc port check: %s, flags: %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) dev->netdev->name, dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) hba = bnx2fc_find_hba_for_cnic(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) if (!hba) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) printk(KERN_ERR PFX "bnx2fc_ulp_exit: hba not found, dev 0%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) list_del_init(&hba->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) adapter_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) list_for_each_entry_safe(interface, tmp, &if_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) /* destroy not called yet, move to quiesced list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) if (interface->hba == hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) __bnx2fc_destroy(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) bnx2fc_ulp_stop(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) /* unregister cnic device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (test_and_clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) hba->cnic->unregister_device(hba->cnic, CNIC_ULP_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) bnx2fc_hba_destroy(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) static void bnx2fc_rport_terminate_io(struct fc_rport *rport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) /* This is a no-op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) * bnx2fc_fcoe_reset - Resets the fcoe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) * @shost: shost the reset is from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) * Returns: always 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) static int bnx2fc_fcoe_reset(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) struct fc_lport *lport = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) fc_lport_reset(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) static bool bnx2fc_match(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) struct net_device *phys_dev = netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) if (is_vlan_dev(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) phys_dev = vlan_dev_real_dev(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) if (bnx2fc_hba_lookup(phys_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) static struct fcoe_transport bnx2fc_transport = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) .name = {"bnx2fc"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) .attached = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) .list = LIST_HEAD_INIT(bnx2fc_transport.list),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) .alloc = bnx2fc_ctlr_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) .match = bnx2fc_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) .create = bnx2fc_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) .destroy = bnx2fc_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) .enable = bnx2fc_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) .disable = bnx2fc_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) * bnx2fc_cpu_online - Create a receive thread for an online CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) * @cpu: cpu index for the online cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) static int bnx2fc_cpu_online(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) struct bnx2fc_percpu_s *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) struct task_struct *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) p = &per_cpu(bnx2fc_percpu, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) thread = kthread_create_on_node(bnx2fc_percpu_io_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) (void *)p, cpu_to_node(cpu),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) "bnx2fc_thread/%d", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) if (IS_ERR(thread))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) return PTR_ERR(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) /* bind thread to the cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) kthread_bind(thread, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) p->iothread = thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) wake_up_process(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) static int bnx2fc_cpu_offline(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) struct bnx2fc_percpu_s *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) struct task_struct *thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) struct bnx2fc_work *work, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) BNX2FC_MISC_DBG("destroying io thread for CPU %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) /* Prevent any new work from being queued for this CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) p = &per_cpu(bnx2fc_percpu, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) spin_lock_bh(&p->fp_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) thread = p->iothread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) p->iothread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) /* Free all work in the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) list_for_each_entry_safe(work, tmp, &p->work_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) list_del_init(&work->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) bnx2fc_process_cq_compl(work->tgt, work->wqe, work->rq_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) work->num_rq, work->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) kfree(work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) spin_unlock_bh(&p->fp_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) if (thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) kthread_stop(thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) static int bnx2fc_slave_configure(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) if (!bnx2fc_queue_depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) scsi_change_queue_depth(sdev, bnx2fc_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) static enum cpuhp_state bnx2fc_online_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) * bnx2fc_mod_init - module init entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) * Initialize driver wide global data structures, and register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) * with cnic module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) static int __init bnx2fc_mod_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) struct fcoe_percpu_s *bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) struct task_struct *l2_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) unsigned int cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) struct bnx2fc_percpu_s *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) printk(KERN_INFO PFX "%s", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) /* register as a fcoe transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) rc = fcoe_transport_attach(&bnx2fc_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) printk(KERN_ERR "failed to register an fcoe transport, check "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) "if libfcoe is loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) INIT_LIST_HEAD(&adapter_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) INIT_LIST_HEAD(&if_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) mutex_init(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) adapter_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) /* Attach FC transport template */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) rc = bnx2fc_attach_transport();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) goto detach_ft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) bnx2fc_wq = alloc_workqueue("bnx2fc", 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) if (!bnx2fc_wq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) goto release_bt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) bg = &bnx2fc_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) skb_queue_head_init(&bg->fcoe_rx_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) l2_thread = kthread_create(bnx2fc_l2_rcv_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) (void *)bg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) "bnx2fc_l2_thread");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) if (IS_ERR(l2_thread)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) rc = PTR_ERR(l2_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) goto free_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) wake_up_process(l2_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) spin_lock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) bg->kthread = l2_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) spin_unlock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) p = &per_cpu(bnx2fc_percpu, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) INIT_LIST_HEAD(&p->work_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) spin_lock_init(&p->fp_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2fc:online",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) bnx2fc_cpu_online, bnx2fc_cpu_offline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) goto stop_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) bnx2fc_online_state = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) cnic_register_driver(CNIC_ULP_FCOE, &bnx2fc_cnic_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) stop_thread:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) kthread_stop(l2_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) free_wq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) destroy_workqueue(bnx2fc_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) release_bt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) bnx2fc_release_transport();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) detach_ft:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) fcoe_transport_detach(&bnx2fc_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) static void __exit bnx2fc_mod_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) LIST_HEAD(to_be_deleted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) struct bnx2fc_hba *hba, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) struct fcoe_percpu_s *bg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) struct task_struct *l2_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) * NOTE: Since cnic calls register_driver routine rtnl_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) * it will have higher precedence than bnx2fc_dev_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) * unregister_device() cannot be called with bnx2fc_dev_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) * held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) mutex_lock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) list_splice_init(&adapter_list, &to_be_deleted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) adapter_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) mutex_unlock(&bnx2fc_dev_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) /* Unregister with cnic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) list_for_each_entry_safe(hba, next, &to_be_deleted, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) list_del_init(&hba->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) printk(KERN_ERR PFX "MOD_EXIT:destroy hba = 0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) bnx2fc_ulp_stop(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) /* unregister cnic device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) if (test_and_clear_bit(BNX2FC_CNIC_REGISTERED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) &hba->reg_with_cnic))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) hba->cnic->unregister_device(hba->cnic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) CNIC_ULP_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) bnx2fc_hba_destroy(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) cnic_unregister_driver(CNIC_ULP_FCOE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) /* Destroy global thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) bg = &bnx2fc_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) spin_lock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) l2_thread = bg->kthread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) bg->kthread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) while ((skb = __skb_dequeue(&bg->fcoe_rx_list)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) spin_unlock_bh(&bg->fcoe_rx_list.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) if (l2_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) kthread_stop(l2_thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) cpuhp_remove_state(bnx2fc_online_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) destroy_workqueue(bnx2fc_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) * detach from scsi transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) * must happen after all destroys are done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) bnx2fc_release_transport();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) /* detach from fcoe transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) fcoe_transport_detach(&bnx2fc_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) module_init(bnx2fc_mod_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) module_exit(bnx2fc_mod_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) .set_fcoe_ctlr_enabled = bnx2fc_ctlr_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) .get_fcoe_fcf_selected = fcoe_fcf_get_selected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) static struct fc_function_template bnx2fc_transport_function = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) .show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) .show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) .show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) .show_host_supported_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) .show_host_active_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) .show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) .show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) .show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) .get_host_speed = fc_get_host_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) .show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) .show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) .get_host_port_state = fc_get_host_port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) .show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) .show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) .dd_fcrport_size = (sizeof(struct fc_rport_libfc_priv) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) sizeof(struct bnx2fc_rport)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) .show_rport_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) .show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) .show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) .show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) .show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) .show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) .show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) .get_fc_host_stats = bnx2fc_get_host_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) .issue_fc_host_lip = bnx2fc_fcoe_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) .terminate_rport_io = bnx2fc_rport_terminate_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) .vport_create = bnx2fc_vport_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) .vport_delete = bnx2fc_vport_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) .vport_disable = bnx2fc_vport_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) .bsg_request = fc_lport_bsg_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) static struct fc_function_template bnx2fc_vport_xport_function = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) .show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) .show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) .show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) .show_host_supported_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) .show_host_active_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) .show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) .show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) .show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) .get_host_speed = fc_get_host_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) .show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) .show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) .get_host_port_state = fc_get_host_port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) .show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) .show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) .dd_fcrport_size = (sizeof(struct fc_rport_libfc_priv) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) sizeof(struct bnx2fc_rport)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) .show_rport_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) .show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) .show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) .show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) .show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) .show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) .show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) .get_fc_host_stats = fc_get_host_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) .issue_fc_host_lip = bnx2fc_fcoe_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) .terminate_rport_io = fc_rport_terminate_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) .bsg_request = fc_lport_bsg_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) * Additional scsi_host attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) bnx2fc_tm_timeout_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) struct fc_lport *lport = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) sprintf(buf, "%u\n", interface->tm_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) bnx2fc_tm_timeout_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) struct Scsi_Host *shost = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) struct fc_lport *lport = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) struct fcoe_port *port = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) struct bnx2fc_interface *interface = port->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) int rval, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) rval = kstrtouint(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) if (val > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) interface->tm_timeout = (u8)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) static DEVICE_ATTR(tm_timeout, S_IRUGO|S_IWUSR, bnx2fc_tm_timeout_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) bnx2fc_tm_timeout_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) static struct device_attribute *bnx2fc_host_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) &dev_attr_tm_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) * scsi_host_template structure used while registering with SCSI-ml
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) static struct scsi_host_template bnx2fc_shost_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) .name = "QLogic Offload FCoE Initiator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) .queuecommand = bnx2fc_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) .eh_timed_out = fc_eh_timed_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) .eh_abort_handler = bnx2fc_eh_abort, /* abts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) .eh_device_reset_handler = bnx2fc_eh_device_reset, /* lun reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) .eh_target_reset_handler = bnx2fc_eh_target_reset, /* tgt reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) .eh_host_reset_handler = fc_eh_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) .slave_alloc = fc_slave_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) .change_queue_depth = scsi_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) .this_id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) .cmd_per_lun = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) .sg_tablesize = BNX2FC_MAX_BDS_PER_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) .dma_boundary = 0x7fff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) .max_sectors = 0x3fbf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) .track_queue_depth = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) .slave_configure = bnx2fc_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) .shost_attrs = bnx2fc_host_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) static struct libfc_function_template bnx2fc_libfc_fcn_templ = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) .frame_send = bnx2fc_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) .elsct_send = bnx2fc_elsct_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) .fcp_abort_io = bnx2fc_abort_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) .fcp_cleanup = bnx2fc_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) .get_lesb = fcoe_get_lesb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) .rport_event_callback = bnx2fc_rport_event_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) * bnx2fc_cnic_cb - global template of bnx2fc - cnic driver interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) * structure carrying callback function pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) static struct cnic_ulp_ops bnx2fc_cnic_cb = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) .cnic_init = bnx2fc_ulp_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) .cnic_exit = bnx2fc_ulp_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) .cnic_start = bnx2fc_ulp_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) .cnic_stop = bnx2fc_ulp_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) .indicate_kcqes = bnx2fc_indicate_kcqe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) .indicate_netevent = bnx2fc_indicate_netevent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) .cnic_get_stats = bnx2fc_ulp_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) };