1577ae39dSJitendra Kalsaria /* 2577ae39dSJitendra Kalsaria * QLogic qlcnic NIC Driver 3577ae39dSJitendra Kalsaria * Copyright (c) 2009-2013 QLogic Corporation 4577ae39dSJitendra Kalsaria * 5577ae39dSJitendra Kalsaria * See LICENSE.qlcnic for copyright and licensing details. 6577ae39dSJitendra Kalsaria */ 7577ae39dSJitendra Kalsaria 8d71170fbSSony Chacko #include "qlcnic.h" 9d71170fbSSony Chacko #include "qlcnic_hw.h" 10d71170fbSSony Chacko 11d71170fbSSony Chacko int qlcnic_83xx_enable_vnic_mode(struct qlcnic_adapter *adapter, int lock) 12d71170fbSSony Chacko { 13d71170fbSSony Chacko if (lock) { 14d71170fbSSony Chacko if (qlcnic_83xx_lock_driver(adapter)) 15d71170fbSSony Chacko return -EBUSY; 16d71170fbSSony Chacko } 17d71170fbSSony Chacko QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_OPER); 18d71170fbSSony Chacko if (lock) 19d71170fbSSony Chacko qlcnic_83xx_unlock_driver(adapter); 20d71170fbSSony Chacko 21d71170fbSSony Chacko return 0; 22d71170fbSSony Chacko } 23d71170fbSSony Chacko 24d71170fbSSony Chacko int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock) 25d71170fbSSony Chacko { 26d71170fbSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 27d71170fbSSony Chacko 28d71170fbSSony Chacko if (lock) { 29d71170fbSSony Chacko if (qlcnic_83xx_lock_driver(adapter)) 30d71170fbSSony Chacko return -EBUSY; 31d71170fbSSony Chacko } 32d71170fbSSony Chacko 33d71170fbSSony Chacko QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_NON_OPER); 34d71170fbSSony Chacko ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER; 35d71170fbSSony Chacko 36d71170fbSSony Chacko if (lock) 37d71170fbSSony Chacko qlcnic_83xx_unlock_driver(adapter); 38d71170fbSSony Chacko 39d71170fbSSony Chacko return 0; 40d71170fbSSony Chacko } 41d71170fbSSony Chacko 42486a5bc7SRajesh Borundia int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter) 43d71170fbSSony Chacko { 44d71170fbSSony Chacko u8 id; 457e8fd003SShahed Shaikh int ret = -EBUSY; 46d71170fbSSony Chacko u32 data = QLCNIC_MGMT_FUNC; 47d71170fbSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 48d71170fbSSony Chacko 49d71170fbSSony Chacko if (qlcnic_83xx_lock_driver(adapter)) 50d71170fbSSony Chacko return ret; 51d71170fbSSony Chacko 527e8fd003SShahed Shaikh id = ahw->pci_func; 53d71170fbSSony Chacko data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); 547e8fd003SShahed Shaikh data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, id)) | 557e8fd003SShahed Shaikh QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC, id); 567e8fd003SShahed Shaikh 57d71170fbSSony Chacko QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data); 58d71170fbSSony Chacko 59d71170fbSSony Chacko qlcnic_83xx_unlock_driver(adapter); 60d71170fbSSony Chacko 61d71170fbSSony Chacko return 0; 62d71170fbSSony Chacko } 63d71170fbSSony Chacko 64d71170fbSSony Chacko static void 65d71170fbSSony Chacko qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter) 66d71170fbSSony Chacko { 67d71170fbSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 68d71170fbSSony Chacko 69d71170fbSSony Chacko if (ahw->port_type == QLCNIC_XGBE) { 70d71170fbSSony Chacko adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF; 71d71170fbSSony Chacko adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF; 72d71170fbSSony Chacko adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 73d71170fbSSony Chacko adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; 74d71170fbSSony Chacko 75d71170fbSSony Chacko } else if (ahw->port_type == QLCNIC_GBE) { 76d71170fbSSony Chacko adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G; 77d71170fbSSony Chacko adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 78d71170fbSSony Chacko adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; 79d71170fbSSony Chacko adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G; 80d71170fbSSony Chacko } 81d71170fbSSony Chacko adapter->num_txd = MAX_CMD_DESCRIPTORS; 82d71170fbSSony Chacko adapter->max_rds_rings = MAX_RDS_RINGS; 83d71170fbSSony Chacko } 84d71170fbSSony Chacko 85d71170fbSSony Chacko 86d71170fbSSony Chacko /** 87d71170fbSSony Chacko * qlcnic_83xx_init_mgmt_vnic 88d71170fbSSony Chacko * 89d71170fbSSony Chacko * @adapter: adapter structure 90d71170fbSSony Chacko * Management virtual NIC sets the operational mode of other vNIC's and 91d71170fbSSony Chacko * configures embedded switch (ESWITCH). 92d71170fbSSony Chacko * Returns: Success(0) or error code. 93d71170fbSSony Chacko * 94d71170fbSSony Chacko **/ 95d71170fbSSony Chacko static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter) 96d71170fbSSony Chacko { 979e630955SSucheta Chakraborty struct qlcnic_hardware_context *ahw = adapter->ahw; 989e630955SSucheta Chakraborty struct device *dev = &adapter->pdev->dev; 999e630955SSucheta Chakraborty struct qlcnic_npar_info *npar; 1009e630955SSucheta Chakraborty int i, err = -EIO; 101d71170fbSSony Chacko 1024d53f40fSShahed Shaikh qlcnic_83xx_get_minidump_template(adapter); 1039e630955SSucheta Chakraborty 104d71170fbSSony Chacko if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) { 105d71170fbSSony Chacko if (qlcnic_init_pci_info(adapter)) 106d71170fbSSony Chacko return err; 107d71170fbSSony Chacko 1089e630955SSucheta Chakraborty npar = adapter->npars; 1099e630955SSucheta Chakraborty 1102f514c52SJitendra Kalsaria for (i = 0; i < ahw->total_nic_func; i++, npar++) { 1119e630955SSucheta Chakraborty dev_info(dev, "id:%d active:%d type:%d port:%d min_bw:%d max_bw:%d mac_addr:%pM\n", 1129e630955SSucheta Chakraborty npar->pci_func, npar->active, npar->type, 1139e630955SSucheta Chakraborty npar->phy_port, npar->min_bw, npar->max_bw, 1149e630955SSucheta Chakraborty npar->mac); 1159e630955SSucheta Chakraborty } 1169e630955SSucheta Chakraborty 1179e630955SSucheta Chakraborty dev_info(dev, "Max functions = %d, active functions = %d\n", 1182f514c52SJitendra Kalsaria ahw->max_pci_func, ahw->total_nic_func); 1199e630955SSucheta Chakraborty 120d71170fbSSony Chacko if (qlcnic_83xx_set_vnic_opmode(adapter)) 121d71170fbSSony Chacko return err; 122d71170fbSSony Chacko 123d71170fbSSony Chacko if (qlcnic_set_default_offload_settings(adapter)) 124d71170fbSSony Chacko return err; 125d71170fbSSony Chacko } else { 126d71170fbSSony Chacko if (qlcnic_reset_npar_config(adapter)) 127d71170fbSSony Chacko return err; 128d71170fbSSony Chacko } 129d71170fbSSony Chacko 130d71170fbSSony Chacko if (qlcnic_83xx_get_port_info(adapter)) 131d71170fbSSony Chacko return err; 132d71170fbSSony Chacko 133d71170fbSSony Chacko qlcnic_83xx_config_vnic_buff_descriptors(adapter); 1349e630955SSucheta Chakraborty ahw->msix_supported = qlcnic_use_msi_x ? 1 : 0; 135d71170fbSSony Chacko adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; 136d71170fbSSony Chacko qlcnic_83xx_enable_vnic_mode(adapter, 1); 137d71170fbSSony Chacko 1389e630955SSucheta Chakraborty dev_info(dev, "HAL Version: %d, Management function\n", 1399e630955SSucheta Chakraborty ahw->fw_hal_version); 140d71170fbSSony Chacko 141d71170fbSSony Chacko return 0; 142d71170fbSSony Chacko } 143d71170fbSSony Chacko 144d71170fbSSony Chacko static int qlcnic_83xx_init_privileged_vnic(struct qlcnic_adapter *adapter) 145d71170fbSSony Chacko { 146d71170fbSSony Chacko int err = -EIO; 147d71170fbSSony Chacko 1484d53f40fSShahed Shaikh qlcnic_83xx_get_minidump_template(adapter); 149d71170fbSSony Chacko if (qlcnic_83xx_get_port_info(adapter)) 150d71170fbSSony Chacko return err; 151d71170fbSSony Chacko 152d71170fbSSony Chacko qlcnic_83xx_config_vnic_buff_descriptors(adapter); 153d71170fbSSony Chacko adapter->ahw->msix_supported = !!qlcnic_use_msi_x; 154d71170fbSSony Chacko adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; 155d71170fbSSony Chacko 156d71170fbSSony Chacko dev_info(&adapter->pdev->dev, 157d71170fbSSony Chacko "HAL Version: %d, Privileged function\n", 158d71170fbSSony Chacko adapter->ahw->fw_hal_version); 159d71170fbSSony Chacko return 0; 160d71170fbSSony Chacko } 161d71170fbSSony Chacko 162d71170fbSSony Chacko static int qlcnic_83xx_init_non_privileged_vnic(struct qlcnic_adapter *adapter) 163d71170fbSSony Chacko { 164d71170fbSSony Chacko int err = -EIO; 165d71170fbSSony Chacko 166d71170fbSSony Chacko qlcnic_83xx_get_fw_version(adapter); 167d71170fbSSony Chacko if (qlcnic_set_eswitch_port_config(adapter)) 168d71170fbSSony Chacko return err; 169d71170fbSSony Chacko 170d71170fbSSony Chacko if (qlcnic_83xx_get_port_info(adapter)) 171d71170fbSSony Chacko return err; 172d71170fbSSony Chacko 173d71170fbSSony Chacko qlcnic_83xx_config_vnic_buff_descriptors(adapter); 174d71170fbSSony Chacko adapter->ahw->msix_supported = !!qlcnic_use_msi_x; 175d71170fbSSony Chacko adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; 176d71170fbSSony Chacko 177d71170fbSSony Chacko dev_info(&adapter->pdev->dev, "HAL Version: %d, Virtual function\n", 178d71170fbSSony Chacko adapter->ahw->fw_hal_version); 179d71170fbSSony Chacko 180d71170fbSSony Chacko return 0; 181d71170fbSSony Chacko } 182d71170fbSSony Chacko 183d71170fbSSony Chacko /** 184d71170fbSSony Chacko * qlcnic_83xx_vnic_opmode 185d71170fbSSony Chacko * 186d71170fbSSony Chacko * @adapter: adapter structure 187d71170fbSSony Chacko * Identify virtual NIC operational modes. 188d71170fbSSony Chacko * 189d71170fbSSony Chacko * Returns: Success(0) or error code. 190d71170fbSSony Chacko * 191d71170fbSSony Chacko **/ 192d71170fbSSony Chacko int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter) 193d71170fbSSony Chacko { 194d71170fbSSony Chacko u32 op_mode, priv_level; 195d71170fbSSony Chacko struct qlcnic_hardware_context *ahw = adapter->ahw; 196d71170fbSSony Chacko struct qlcnic_nic_template *nic_ops = adapter->nic_ops; 197d71170fbSSony Chacko 198d71170fbSSony Chacko qlcnic_get_func_no(adapter); 199d71170fbSSony Chacko op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE); 200d71170fbSSony Chacko 201d71170fbSSony Chacko if (op_mode == QLC_83XX_DEFAULT_OPMODE) 202d71170fbSSony Chacko priv_level = QLCNIC_MGMT_FUNC; 203d71170fbSSony Chacko else 204d71170fbSSony Chacko priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode, 205d71170fbSSony Chacko ahw->pci_func); 206b17f2ccaSJitendra Kalsaria switch (priv_level) { 207b17f2ccaSJitendra Kalsaria case QLCNIC_NON_PRIV_FUNC: 208d71170fbSSony Chacko ahw->op_mode = QLCNIC_NON_PRIV_FUNC; 209d71170fbSSony Chacko ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; 210d71170fbSSony Chacko nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic; 211b17f2ccaSJitendra Kalsaria break; 212b17f2ccaSJitendra Kalsaria case QLCNIC_PRIV_FUNC: 213d71170fbSSony Chacko ahw->op_mode = QLCNIC_PRIV_FUNC; 214d71170fbSSony Chacko ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry; 215d71170fbSSony Chacko nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic; 216b17f2ccaSJitendra Kalsaria break; 217b17f2ccaSJitendra Kalsaria case QLCNIC_MGMT_FUNC: 218d71170fbSSony Chacko ahw->op_mode = QLCNIC_MGMT_FUNC; 219d71170fbSSony Chacko ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; 220d71170fbSSony Chacko nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic; 221b17f2ccaSJitendra Kalsaria break; 222b17f2ccaSJitendra Kalsaria default: 223b17f2ccaSJitendra Kalsaria dev_err(&adapter->pdev->dev, "Invalid Virtual NIC opmode\n"); 224d71170fbSSony Chacko return -EIO; 225d71170fbSSony Chacko } 226d71170fbSSony Chacko 227b3f7de83SSucheta Chakraborty if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) { 228d71170fbSSony Chacko adapter->flags |= QLCNIC_ESWITCH_ENABLED; 229b3f7de83SSucheta Chakraborty if (adapter->drv_mac_learn) 230b3f7de83SSucheta Chakraborty adapter->rx_mac_learn = 1; 231b3f7de83SSucheta Chakraborty } else { 232d71170fbSSony Chacko adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; 233b3f7de83SSucheta Chakraborty adapter->rx_mac_learn = 0; 234b3f7de83SSucheta Chakraborty } 235d71170fbSSony Chacko 236b17f2ccaSJitendra Kalsaria ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER; 237b17f2ccaSJitendra Kalsaria ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO; 238d71170fbSSony Chacko 239d71170fbSSony Chacko return 0; 240d71170fbSSony Chacko } 241486a5bc7SRajesh Borundia 242486a5bc7SRajesh Borundia int qlcnic_83xx_check_vnic_state(struct qlcnic_adapter *adapter) 243486a5bc7SRajesh Borundia { 244486a5bc7SRajesh Borundia struct qlcnic_hardware_context *ahw = adapter->ahw; 245486a5bc7SRajesh Borundia struct qlc_83xx_idc *idc = &ahw->idc; 246486a5bc7SRajesh Borundia u32 state; 247486a5bc7SRajesh Borundia 248486a5bc7SRajesh Borundia state = QLCRDX(ahw, QLC_83XX_VNIC_STATE); 249486a5bc7SRajesh Borundia while (state != QLCNIC_DEV_NPAR_OPER && idc->vnic_wait_limit--) { 250486a5bc7SRajesh Borundia msleep(1000); 251486a5bc7SRajesh Borundia state = QLCRDX(ahw, QLC_83XX_VNIC_STATE); 252486a5bc7SRajesh Borundia } 253486a5bc7SRajesh Borundia 254486a5bc7SRajesh Borundia if (!idc->vnic_wait_limit) { 255486a5bc7SRajesh Borundia dev_err(&adapter->pdev->dev, 256486a5bc7SRajesh Borundia "vNIC mode not operational, state check timed out.\n"); 257486a5bc7SRajesh Borundia return -EIO; 258486a5bc7SRajesh Borundia } 259486a5bc7SRajesh Borundia 260486a5bc7SRajesh Borundia return 0; 261486a5bc7SRajesh Borundia } 26235dafcb0SSony Chacko 2634c776aadSSony Chacko int qlcnic_83xx_set_port_eswitch_status(struct qlcnic_adapter *adapter, 26435dafcb0SSony Chacko int func, int *port_id) 26535dafcb0SSony Chacko { 26635dafcb0SSony Chacko struct qlcnic_info nic_info; 26735dafcb0SSony Chacko int err = 0; 26835dafcb0SSony Chacko 26935dafcb0SSony Chacko memset(&nic_info, 0, sizeof(struct qlcnic_info)); 27035dafcb0SSony Chacko 27135dafcb0SSony Chacko err = qlcnic_get_nic_info(adapter, &nic_info, func); 27235dafcb0SSony Chacko if (err) 27335dafcb0SSony Chacko return err; 27435dafcb0SSony Chacko 27535dafcb0SSony Chacko if (nic_info.capabilities & QLC_83XX_ESWITCH_CAPABILITY) 27635dafcb0SSony Chacko *port_id = nic_info.phys_port; 27735dafcb0SSony Chacko else 27835dafcb0SSony Chacko err = -EIO; 27935dafcb0SSony Chacko 2804c776aadSSony Chacko if (!err) 2814c776aadSSony Chacko adapter->eswitch[*port_id].flags |= QLCNIC_SWITCH_ENABLE; 28235dafcb0SSony Chacko 28335dafcb0SSony Chacko return err; 28435dafcb0SSony Chacko } 285