1 /*
2  * QLogic qlcnic NIC Driver
3  * Copyright (c) 2009-2013 QLogic Corporation
4  *
5  * See LICENSE.qlcnic for copyright and licensing details.
6  */
7 
8 #include "qlcnic.h"
9 #include "qlcnic_hw.h"
10 
11 int qlcnic_83xx_enable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
12 {
13 	if (lock) {
14 		if (qlcnic_83xx_lock_driver(adapter))
15 			return -EBUSY;
16 	}
17 	QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_OPER);
18 	if (lock)
19 		qlcnic_83xx_unlock_driver(adapter);
20 
21 	return 0;
22 }
23 
24 int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
25 {
26 	struct qlcnic_hardware_context *ahw = adapter->ahw;
27 
28 	if (lock) {
29 		if (qlcnic_83xx_lock_driver(adapter))
30 			return -EBUSY;
31 	}
32 
33 	QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_NON_OPER);
34 	ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
35 
36 	if (lock)
37 		qlcnic_83xx_unlock_driver(adapter);
38 
39 	return 0;
40 }
41 
42 static int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
43 {
44 	u8 id;
45 	int i, ret = -EBUSY;
46 	u32 data = QLCNIC_MGMT_FUNC;
47 	struct qlcnic_hardware_context *ahw = adapter->ahw;
48 
49 	if (qlcnic_83xx_lock_driver(adapter))
50 		return ret;
51 
52 	if (qlcnic_config_npars) {
53 		for (i = 0; i < ahw->act_pci_func; i++) {
54 			id = adapter->npars[i].pci_func;
55 			if (id == ahw->pci_func)
56 				continue;
57 			data |= qlcnic_config_npars &
58 				QLC_83XX_SET_FUNC_OPMODE(0x3, id);
59 		}
60 	} else {
61 		data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
62 		data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, ahw->pci_func)) |
63 		       QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC,
64 						ahw->pci_func);
65 	}
66 	QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data);
67 
68 	qlcnic_83xx_unlock_driver(adapter);
69 
70 	return 0;
71 }
72 
73 static void
74 qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
75 {
76 	struct qlcnic_hardware_context *ahw = adapter->ahw;
77 
78 	if (ahw->port_type == QLCNIC_XGBE) {
79 		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF;
80 		adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF;
81 		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
82 		adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
83 
84 	} else if (ahw->port_type == QLCNIC_GBE) {
85 		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
86 		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
87 		adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
88 		adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G;
89 	}
90 	adapter->num_txd = MAX_CMD_DESCRIPTORS;
91 	adapter->max_rds_rings = MAX_RDS_RINGS;
92 }
93 
94 
95 /**
96  * qlcnic_83xx_init_mgmt_vnic
97  *
98  * @adapter: adapter structure
99  * Management virtual NIC sets the operational mode of other vNIC's and
100  * configures embedded switch (ESWITCH).
101  * Returns: Success(0) or error code.
102  *
103  **/
104 static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
105 {
106 	int err = -EIO;
107 
108 	qlcnic_83xx_get_minidump_template(adapter);
109 	if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
110 		if (qlcnic_init_pci_info(adapter))
111 			return err;
112 
113 		if (qlcnic_83xx_set_vnic_opmode(adapter))
114 			return err;
115 
116 		if (qlcnic_set_default_offload_settings(adapter))
117 			return err;
118 	} else {
119 		if (qlcnic_reset_npar_config(adapter))
120 			return err;
121 	}
122 
123 	if (qlcnic_83xx_get_port_info(adapter))
124 		return err;
125 
126 	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
127 	adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
128 	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
129 	qlcnic_83xx_enable_vnic_mode(adapter, 1);
130 
131 	dev_info(&adapter->pdev->dev, "HAL Version: %d, Management function\n",
132 		 adapter->ahw->fw_hal_version);
133 
134 	return 0;
135 }
136 
137 static int qlcnic_83xx_init_privileged_vnic(struct qlcnic_adapter *adapter)
138 {
139 	int err = -EIO;
140 
141 	qlcnic_83xx_get_minidump_template(adapter);
142 	if (qlcnic_83xx_get_port_info(adapter))
143 		return err;
144 
145 	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
146 	adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
147 	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
148 
149 	dev_info(&adapter->pdev->dev,
150 		 "HAL Version: %d, Privileged function\n",
151 		 adapter->ahw->fw_hal_version);
152 	return 0;
153 }
154 
155 static int qlcnic_83xx_init_non_privileged_vnic(struct qlcnic_adapter *adapter)
156 {
157 	int err = -EIO;
158 
159 	qlcnic_83xx_get_fw_version(adapter);
160 	if (qlcnic_set_eswitch_port_config(adapter))
161 		return err;
162 
163 	if (qlcnic_83xx_get_port_info(adapter))
164 		return err;
165 
166 	qlcnic_83xx_config_vnic_buff_descriptors(adapter);
167 	adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
168 	adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
169 
170 	dev_info(&adapter->pdev->dev, "HAL Version: %d, Virtual function\n",
171 		 adapter->ahw->fw_hal_version);
172 
173 	return 0;
174 }
175 
176 /**
177  * qlcnic_83xx_vnic_opmode
178  *
179  * @adapter: adapter structure
180  * Identify virtual NIC operational modes.
181  *
182  * Returns: Success(0) or error code.
183  *
184  **/
185 int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
186 {
187 	u32 op_mode, priv_level;
188 	struct qlcnic_hardware_context *ahw = adapter->ahw;
189 	struct qlcnic_nic_template *nic_ops = adapter->nic_ops;
190 
191 	qlcnic_get_func_no(adapter);
192 	op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
193 
194 	if (op_mode == QLC_83XX_DEFAULT_OPMODE)
195 		priv_level = QLCNIC_MGMT_FUNC;
196 	else
197 		priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
198 							 ahw->pci_func);
199 
200 	if (priv_level == QLCNIC_NON_PRIV_FUNC) {
201 		ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
202 		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
203 		nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic;
204 	} else if (priv_level == QLCNIC_PRIV_FUNC) {
205 		ahw->op_mode = QLCNIC_PRIV_FUNC;
206 		ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry;
207 		nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic;
208 	} else if (priv_level == QLCNIC_MGMT_FUNC) {
209 		ahw->op_mode = QLCNIC_MGMT_FUNC;
210 		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
211 		nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic;
212 	} else {
213 		return -EIO;
214 	}
215 
216 	if (ahw->capabilities & BIT_23)
217 		adapter->flags |= QLCNIC_ESWITCH_ENABLED;
218 	else
219 		adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
220 
221 	adapter->ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
222 	adapter->ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;
223 
224 	return 0;
225 }
226