1
2
3
4
5
6
7
8#include <linux/if_vlan.h>
9#include <linux/ipv6.h>
10#include <linux/ethtool.h>
11#include <linux/interrupt.h>
12#include <linux/aer.h>
13
14#include "qlcnic.h"
15#include "qlcnic_sriov.h"
16
17static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *);
18static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8);
19static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *, u8 *, u8,
20 struct qlcnic_cmd_args *);
21static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *);
22static irqreturn_t qlcnic_83xx_handle_aen(int, void *);
23static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *,
24 pci_channel_state_t);
25static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *);
26static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *);
27static void qlcnic_83xx_io_resume(struct pci_dev *);
28static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *, u8);
29static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *);
30static int qlcnic_83xx_resume(struct qlcnic_adapter *);
31static int qlcnic_83xx_shutdown(struct pci_dev *);
32static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
33
34#define RSS_HASHTYPE_IP_TCP 0x3
35#define QLC_83XX_FW_MBX_CMD 0
36#define QLC_SKIP_INACTIVE_PCI_REGS 7
37#define QLC_MAX_LEGACY_FUNC_SUPP 8
38
39
40#define QLC_83XX_MODULE_FIBRE_10GBASE_LRM 0x1
41#define QLC_83XX_MODULE_FIBRE_10GBASE_LR 0x2
42#define QLC_83XX_MODULE_FIBRE_10GBASE_SR 0x3
43#define QLC_83XX_MODULE_DA_10GE_PASSIVE_CP 0x4
44
45
46#define QLC_83XX_MODULE_DA_10GE_ACTIVE_CP 0x5
47
48
49#define QLC_83XX_MODULE_DA_10GE_LEGACY_CP 0x6
50
51
52#define QLC_83XX_MODULE_FIBRE_1000BASE_SX 0x7
53#define QLC_83XX_MODULE_FIBRE_1000BASE_LX 0x8
54#define QLC_83XX_MODULE_FIBRE_1000BASE_CX 0x9
55#define QLC_83XX_MODULE_TP_1000BASE_T 0xa
56#define QLC_83XX_MODULE_DA_1GE_PASSIVE_CP 0xb
57
58
59#define QLC_83XX_MODULE_UNKNOWN 0xf
60
61
62#define QLC_83XX_10_CAPABLE BIT_8
63#define QLC_83XX_100_CAPABLE BIT_9
64#define QLC_83XX_1G_CAPABLE BIT_10
65#define QLC_83XX_10G_CAPABLE BIT_11
66#define QLC_83XX_AUTONEG_ENABLE BIT_15
67
68static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
69 {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
70 {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
71 {QLCNIC_CMD_CREATE_RX_CTX, 136, 27},
72 {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
73 {QLCNIC_CMD_CREATE_TX_CTX, 54, 18},
74 {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1},
75 {QLCNIC_CMD_CONFIGURE_MAC_LEARNING, 2, 1},
76 {QLCNIC_CMD_INTRPT_TEST, 22, 12},
77 {QLCNIC_CMD_SET_MTU, 3, 1},
78 {QLCNIC_CMD_READ_PHY, 4, 2},
79 {QLCNIC_CMD_WRITE_PHY, 5, 1},
80 {QLCNIC_CMD_READ_HW_REG, 4, 1},
81 {QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
82 {QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
83 {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
84 {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
85 {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
86 {QLCNIC_CMD_GET_PCI_INFO, 1, 129},
87 {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
88 {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
89 {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
90 {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
91 {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
92 {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
93 {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
94 {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
95 {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1},
96 {QLCNIC_CMD_CONFIG_PORT, 4, 1},
97 {QLCNIC_CMD_TEMP_SIZE, 1, 4},
98 {QLCNIC_CMD_GET_TEMP_HDR, 5, 5},
99 {QLCNIC_CMD_GET_LINK_EVENT, 2, 1},
100 {QLCNIC_CMD_CONFIG_MAC_VLAN, 4, 3},
101 {QLCNIC_CMD_CONFIG_INTR_COAL, 6, 1},
102 {QLCNIC_CMD_CONFIGURE_RSS, 14, 1},
103 {QLCNIC_CMD_CONFIGURE_LED, 2, 1},
104 {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, 2, 1},
105 {QLCNIC_CMD_CONFIGURE_HW_LRO, 2, 1},
106 {QLCNIC_CMD_GET_STATISTICS, 2, 80},
107 {QLCNIC_CMD_SET_PORT_CONFIG, 2, 1},
108 {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
109 {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
110 {QLCNIC_CMD_IDC_ACK, 5, 1},
111 {QLCNIC_CMD_INIT_NIC_FUNC, 3, 1},
112 {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
113 {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
114 {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
115 {QLCNIC_CMD_83XX_SET_DRV_VER, 4, 1},
116 {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
117 {QLCNIC_CMD_CONFIG_VPORT, 4, 4},
118 {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
119 {QLCNIC_CMD_DCB_QUERY_CAP, 1, 2},
120 {QLCNIC_CMD_DCB_QUERY_PARAM, 1, 50},
121 {QLCNIC_CMD_SET_INGRESS_ENCAP, 2, 1},
122 {QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP, 4, 1},
123};
124
125const u32 qlcnic_83xx_ext_reg_tbl[] = {
126 0x38CC,
127 0x38F0,
128 0x38FC,
129 0x3038,
130 0x303C,
131 0x355C,
132 0x3560,
133 0x3564,
134 0x1000,
135 0x1200,
136 0x1204,
137 0x3780,
138 0x3784,
139 0x3788,
140 0x378C,
141 0x3790,
142 0x3794,
143 0x3798,
144 0x379C,
145 0x37A0,
146 0x37A4,
147 0x37A8,
148 0x37AC,
149 0x37B0,
150 0x37B4,
151 0x37B8,
152 0x37BC,
153 0x37C0,
154 0x37C4,
155 0x37C8,
156 0x37CC,
157 0x37D0,
158 0x37D4,
159 0x37D8,
160 0x37DC,
161 0x37E0,
162 0x37E4,
163 0x37F0,
164 0x37F4,
165 0x3868,
166 0x386C,
167 0x3504,
168 0x34A4,
169};
170
171const u32 qlcnic_83xx_reg_tbl[] = {
172 0x34A8,
173 0x34AC,
174 0x34B0,
175 0x3500,
176 0x3528,
177 0x3538,
178 0x3540,
179 0x3544,
180 0x3548,
181 0x354C,
182 0x3524,
183 0x3550,
184 0x3554,
185 0x3558,
186 0x359C,
187 0x35FC,
188 0x3650,
189 0x373C,
190 0x37B4,
191 0x356C,
192 0x3570,
193 0x3850,
194 0x3854,
195};
196
197static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
198 .read_crb = qlcnic_83xx_read_crb,
199 .write_crb = qlcnic_83xx_write_crb,
200 .read_reg = qlcnic_83xx_rd_reg_indirect,
201 .write_reg = qlcnic_83xx_wrt_reg_indirect,
202 .get_mac_address = qlcnic_83xx_get_mac_address,
203 .setup_intr = qlcnic_83xx_setup_intr,
204 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
205 .mbx_cmd = qlcnic_83xx_issue_cmd,
206 .get_func_no = qlcnic_83xx_get_func_no,
207 .api_lock = qlcnic_83xx_cam_lock,
208 .api_unlock = qlcnic_83xx_cam_unlock,
209 .add_sysfs = qlcnic_83xx_add_sysfs,
210 .remove_sysfs = qlcnic_83xx_remove_sysfs,
211 .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag,
212 .create_rx_ctx = qlcnic_83xx_create_rx_ctx,
213 .create_tx_ctx = qlcnic_83xx_create_tx_ctx,
214 .del_rx_ctx = qlcnic_83xx_del_rx_ctx,
215 .del_tx_ctx = qlcnic_83xx_del_tx_ctx,
216 .setup_link_event = qlcnic_83xx_setup_link_event,
217 .get_nic_info = qlcnic_83xx_get_nic_info,
218 .get_pci_info = qlcnic_83xx_get_pci_info,
219 .set_nic_info = qlcnic_83xx_set_nic_info,
220 .change_macvlan = qlcnic_83xx_sre_macaddr_change,
221 .napi_enable = qlcnic_83xx_napi_enable,
222 .napi_disable = qlcnic_83xx_napi_disable,
223 .config_intr_coal = qlcnic_83xx_config_intr_coal,
224 .config_rss = qlcnic_83xx_config_rss,
225 .config_hw_lro = qlcnic_83xx_config_hw_lro,
226 .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
227 .change_l2_filter = qlcnic_83xx_change_l2_filter,
228 .get_board_info = qlcnic_83xx_get_port_info,
229 .set_mac_filter_count = qlcnic_83xx_set_mac_filter_count,
230 .free_mac_list = qlcnic_82xx_free_mac_list,
231 .io_error_detected = qlcnic_83xx_io_error_detected,
232 .io_slot_reset = qlcnic_83xx_io_slot_reset,
233 .io_resume = qlcnic_83xx_io_resume,
234 .get_beacon_state = qlcnic_83xx_get_beacon_state,
235 .enable_sds_intr = qlcnic_83xx_enable_sds_intr,
236 .disable_sds_intr = qlcnic_83xx_disable_sds_intr,
237 .enable_tx_intr = qlcnic_83xx_enable_tx_intr,
238 .disable_tx_intr = qlcnic_83xx_disable_tx_intr,
239 .get_saved_state = qlcnic_83xx_get_saved_state,
240 .set_saved_state = qlcnic_83xx_set_saved_state,
241 .cache_tmpl_hdr_values = qlcnic_83xx_cache_tmpl_hdr_values,
242 .get_cap_size = qlcnic_83xx_get_cap_size,
243 .set_sys_info = qlcnic_83xx_set_sys_info,
244 .store_cap_mask = qlcnic_83xx_store_cap_mask,
245 .encap_rx_offload = qlcnic_83xx_encap_rx_offload,
246 .encap_tx_offload = qlcnic_83xx_encap_tx_offload,
247};
248
249static struct qlcnic_nic_template qlcnic_83xx_ops = {
250 .config_bridged_mode = qlcnic_config_bridged_mode,
251 .config_led = qlcnic_config_led,
252 .request_reset = qlcnic_83xx_idc_request_reset,
253 .cancel_idc_work = qlcnic_83xx_idc_exit,
254 .napi_add = qlcnic_83xx_napi_add,
255 .napi_del = qlcnic_83xx_napi_del,
256 .config_ipaddr = qlcnic_83xx_config_ipaddr,
257 .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
258 .shutdown = qlcnic_83xx_shutdown,
259 .resume = qlcnic_83xx_resume,
260};
261
262void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
263{
264 ahw->hw_ops = &qlcnic_83xx_hw_ops;
265 ahw->reg_tbl = (u32 *)qlcnic_83xx_reg_tbl;
266 ahw->ext_reg_tbl = (u32 *)qlcnic_83xx_ext_reg_tbl;
267}
268
269int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
270{
271 u32 fw_major, fw_minor, fw_build;
272 struct pci_dev *pdev = adapter->pdev;
273
274 fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
275 fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
276 fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
277 adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
278
279 dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
280 QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
281
282 return adapter->fw_version;
283}
284
285static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
286{
287 void __iomem *base;
288 u32 val;
289
290 base = adapter->ahw->pci_base0 +
291 QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
292 writel(addr, base);
293 val = readl(base);
294 if (val != addr)
295 return -EIO;
296
297 return 0;
298}
299
300int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
301 int *err)
302{
303 struct qlcnic_hardware_context *ahw = adapter->ahw;
304
305 *err = __qlcnic_set_win_base(adapter, (u32) addr);
306 if (!*err) {
307 return QLCRDX(ahw, QLCNIC_WILDCARD);
308 } else {
309 dev_err(&adapter->pdev->dev,
310 "%s failed, addr = 0x%lx\n", __func__, addr);
311 return -EIO;
312 }
313}
314
315int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
316 u32 data)
317{
318 int err;
319 struct qlcnic_hardware_context *ahw = adapter->ahw;
320
321 err = __qlcnic_set_win_base(adapter, (u32) addr);
322 if (!err) {
323 QLCWRX(ahw, QLCNIC_WILDCARD, data);
324 return 0;
325 } else {
326 dev_err(&adapter->pdev->dev,
327 "%s failed, addr = 0x%x data = 0x%x\n",
328 __func__, (int)addr, data);
329 return err;
330 }
331}
332
333static void qlcnic_83xx_enable_legacy(struct qlcnic_adapter *adapter)
334{
335 struct qlcnic_hardware_context *ahw = adapter->ahw;
336
337
338 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
339 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
340 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
341 adapter->msix_entries[0].vector = adapter->pdev->irq;
342 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
343}
344
345static int qlcnic_83xx_calculate_msix_vector(struct qlcnic_adapter *adapter)
346{
347 int num_msix;
348
349 num_msix = adapter->drv_sds_rings;
350
351
352 num_msix += 1;
353
354 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
355 num_msix += adapter->drv_tx_rings;
356
357 return num_msix;
358}
359
360int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
361{
362 struct qlcnic_hardware_context *ahw = adapter->ahw;
363 int err, i, num_msix;
364
365 if (adapter->flags & QLCNIC_TSS_RSS) {
366 err = qlcnic_setup_tss_rss_intr(adapter);
367 if (err < 0)
368 return err;
369 num_msix = ahw->num_msix;
370 } else {
371 num_msix = qlcnic_83xx_calculate_msix_vector(adapter);
372
373 err = qlcnic_enable_msix(adapter, num_msix);
374 if (err == -ENOMEM)
375 return err;
376
377 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
378 num_msix = ahw->num_msix;
379 } else {
380 if (qlcnic_sriov_vf_check(adapter))
381 return -EINVAL;
382 num_msix = 1;
383 adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
384 adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
385 }
386 }
387
388
389 ahw->intr_tbl = vzalloc(num_msix *
390 sizeof(struct qlcnic_intrpt_config));
391 if (!ahw->intr_tbl)
392 return -ENOMEM;
393
394 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
395 if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) {
396 dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n",
397 ahw->pci_func);
398 return -EOPNOTSUPP;
399 }
400
401 qlcnic_83xx_enable_legacy(adapter);
402 }
403
404 for (i = 0; i < num_msix; i++) {
405 if (adapter->flags & QLCNIC_MSIX_ENABLED)
406 ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
407 else
408 ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
409 ahw->intr_tbl[i].id = i;
410 ahw->intr_tbl[i].src = 0;
411 }
412
413 return 0;
414}
415
416static inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
417{
418 writel(0, adapter->tgt_mask_reg);
419}
420
421static inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
422{
423 if (adapter->tgt_mask_reg)
424 writel(1, adapter->tgt_mask_reg);
425}
426
427static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
428 *adapter)
429{
430 u32 mask;
431
432
433
434
435
436
437 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
438 writel(0, adapter->ahw->pci_base0 + mask);
439}
440
441void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
442{
443 u32 mask;
444
445 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
446 writel(1, adapter->ahw->pci_base0 + mask);
447 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
448}
449
450static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
451 struct qlcnic_cmd_args *cmd)
452{
453 int i;
454
455 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
456 return;
457
458 for (i = 0; i < cmd->rsp.num; i++)
459 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
460}
461
462irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
463{
464 u32 intr_val;
465 struct qlcnic_hardware_context *ahw = adapter->ahw;
466 int retries = 0;
467
468 intr_val = readl(adapter->tgt_status_reg);
469
470 if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
471 return IRQ_NONE;
472
473 if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
474 adapter->stats.spurious_intr++;
475 return IRQ_NONE;
476 }
477
478 wmb();
479
480
481 writel(0, adapter->isr_int_vec);
482 intr_val = readl(adapter->isr_int_vec);
483 do {
484 intr_val = readl(adapter->tgt_status_reg);
485 if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
486 break;
487 retries++;
488 } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
489 (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
490
491 return IRQ_HANDLED;
492}
493
494static inline void qlcnic_83xx_notify_mbx_response(struct qlcnic_mailbox *mbx)
495{
496 mbx->rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
497 complete(&mbx->completion);
498}
499
500static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
501{
502 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
503 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
504 unsigned long flags;
505
506 spin_lock_irqsave(&mbx->aen_lock, flags);
507 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
508 if (!(resp & QLCNIC_SET_OWNER))
509 goto out;
510
511 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
512 if (event & QLCNIC_MBX_ASYNC_EVENT) {
513 __qlcnic_83xx_process_aen(adapter);
514 } else {
515 if (mbx->rsp_status != rsp_status)
516 qlcnic_83xx_notify_mbx_response(mbx);
517 }
518out:
519 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
520 spin_unlock_irqrestore(&mbx->aen_lock, flags);
521}
522
523irqreturn_t qlcnic_83xx_intr(int irq, void *data)
524{
525 struct qlcnic_adapter *adapter = data;
526 struct qlcnic_host_sds_ring *sds_ring;
527 struct qlcnic_hardware_context *ahw = adapter->ahw;
528
529 if (qlcnic_83xx_clear_legacy_intr(adapter) == IRQ_NONE)
530 return IRQ_NONE;
531
532 qlcnic_83xx_poll_process_aen(adapter);
533
534 if (ahw->diag_test) {
535 if (ahw->diag_test == QLCNIC_INTERRUPT_TEST)
536 ahw->diag_cnt++;
537 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
538 return IRQ_HANDLED;
539 }
540
541 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
542 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
543 } else {
544 sds_ring = &adapter->recv_ctx->sds_rings[0];
545 napi_schedule(&sds_ring->napi);
546 }
547
548 return IRQ_HANDLED;
549}
550
551irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
552{
553 struct qlcnic_host_sds_ring *sds_ring = data;
554 struct qlcnic_adapter *adapter = sds_ring->adapter;
555
556 if (adapter->flags & QLCNIC_MSIX_ENABLED)
557 goto done;
558
559 if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
560 return IRQ_NONE;
561
562done:
563 adapter->ahw->diag_cnt++;
564 qlcnic_enable_sds_intr(adapter, sds_ring);
565
566 return IRQ_HANDLED;
567}
568
569void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
570{
571 u32 num_msix;
572
573 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
574 qlcnic_83xx_set_legacy_intr_mask(adapter);
575
576 qlcnic_83xx_disable_mbx_intr(adapter);
577
578 if (adapter->flags & QLCNIC_MSIX_ENABLED)
579 num_msix = adapter->ahw->num_msix - 1;
580 else
581 num_msix = 0;
582
583 msleep(20);
584
585 if (adapter->msix_entries) {
586 synchronize_irq(adapter->msix_entries[num_msix].vector);
587 free_irq(adapter->msix_entries[num_msix].vector, adapter);
588 }
589}
590
591int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
592{
593 irq_handler_t handler;
594 u32 val;
595 int err = 0;
596 unsigned long flags = 0;
597
598 if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
599 !(adapter->flags & QLCNIC_MSIX_ENABLED))
600 flags |= IRQF_SHARED;
601
602 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
603 handler = qlcnic_83xx_handle_aen;
604 val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
605 err = request_irq(val, handler, flags, "qlcnic-MB", adapter);
606 if (err) {
607 dev_err(&adapter->pdev->dev,
608 "failed to register MBX interrupt\n");
609 return err;
610 }
611 } else {
612 handler = qlcnic_83xx_intr;
613 val = adapter->msix_entries[0].vector;
614 err = request_irq(val, handler, flags, "qlcnic", adapter);
615 if (err) {
616 dev_err(&adapter->pdev->dev,
617 "failed to register INTx interrupt\n");
618 return err;
619 }
620 qlcnic_83xx_clear_legacy_intr_mask(adapter);
621 }
622
623
624 qlcnic_83xx_enable_mbx_interrupt(adapter);
625
626 return err;
627}
628
629void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
630{
631 u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
632 adapter->ahw->pci_func = (val >> 24) & 0xff;
633}
634
635int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
636{
637 void __iomem *addr;
638 u32 val, limit = 0;
639
640 struct qlcnic_hardware_context *ahw = adapter->ahw;
641
642 addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
643 do {
644 val = readl(addr);
645 if (val) {
646
647 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
648 ahw->pci_func);
649 return 0;
650 }
651 usleep_range(1000, 2000);
652 } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
653
654 return -EIO;
655}
656
657void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
658{
659 void __iomem *addr;
660 u32 val;
661 struct qlcnic_hardware_context *ahw = adapter->ahw;
662
663 addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
664 val = readl(addr);
665}
666
667void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
668 loff_t offset, size_t size)
669{
670 int ret = 0;
671 u32 data;
672
673 if (qlcnic_api_lock(adapter)) {
674 dev_err(&adapter->pdev->dev,
675 "%s: failed to acquire lock. addr offset 0x%x\n",
676 __func__, (u32)offset);
677 return;
678 }
679
680 data = QLCRD32(adapter, (u32) offset, &ret);
681 qlcnic_api_unlock(adapter);
682
683 if (ret == -EIO) {
684 dev_err(&adapter->pdev->dev,
685 "%s: failed. addr offset 0x%x\n",
686 __func__, (u32)offset);
687 return;
688 }
689 memcpy(buf, &data, size);
690}
691
692void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
693 loff_t offset, size_t size)
694{
695 u32 data;
696
697 memcpy(&data, buf, size);
698 qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
699}
700
701int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
702{
703 struct qlcnic_hardware_context *ahw = adapter->ahw;
704 int status;
705
706 status = qlcnic_83xx_get_port_config(adapter);
707 if (status) {
708 dev_err(&adapter->pdev->dev,
709 "Get Port Info failed\n");
710 } else {
711
712 if (ahw->port_config & QLC_83XX_10G_CAPABLE) {
713 ahw->port_type = QLCNIC_XGBE;
714 } else if (ahw->port_config & QLC_83XX_10_CAPABLE ||
715 ahw->port_config & QLC_83XX_100_CAPABLE ||
716 ahw->port_config & QLC_83XX_1G_CAPABLE) {
717 ahw->port_type = QLCNIC_GBE;
718 } else {
719 ahw->port_type = QLCNIC_XGBE;
720 }
721
722 if (QLC_83XX_AUTONEG(ahw->port_config))
723 ahw->link_autoneg = AUTONEG_ENABLE;
724
725 }
726 return status;
727}
728
729static void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
730{
731 struct qlcnic_hardware_context *ahw = adapter->ahw;
732 u16 act_pci_fn = ahw->total_nic_func;
733 u16 count;
734
735 ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
736 if (act_pci_fn <= 2)
737 count = (QLC_83XX_MAX_UC_COUNT - QLC_83XX_MAX_MC_COUNT) /
738 act_pci_fn;
739 else
740 count = (QLC_83XX_LB_MAX_FILTERS - QLC_83XX_MAX_MC_COUNT) /
741 act_pci_fn;
742 ahw->max_uc_count = count;
743}
744
745void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *adapter)
746{
747 u32 val;
748
749 if (adapter->flags & QLCNIC_MSIX_ENABLED)
750 val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
751 else
752 val = BIT_2;
753
754 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
755 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
756}
757
758void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
759 const struct pci_device_id *ent)
760{
761 u32 op_mode, priv_level;
762 struct qlcnic_hardware_context *ahw = adapter->ahw;
763
764 ahw->fw_hal_version = 2;
765 qlcnic_get_func_no(adapter);
766
767 if (qlcnic_sriov_vf_check(adapter)) {
768 qlcnic_sriov_vf_set_ops(adapter);
769 return;
770 }
771
772
773 op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
774 if (op_mode == QLC_83XX_DEFAULT_OPMODE)
775 priv_level = QLCNIC_MGMT_FUNC;
776 else
777 priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
778 ahw->pci_func);
779
780 if (priv_level == QLCNIC_NON_PRIV_FUNC) {
781 ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
782 dev_info(&adapter->pdev->dev,
783 "HAL Version: %d Non Privileged function\n",
784 ahw->fw_hal_version);
785 adapter->nic_ops = &qlcnic_vf_ops;
786 } else {
787 if (pci_find_ext_capability(adapter->pdev,
788 PCI_EXT_CAP_ID_SRIOV))
789 set_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state);
790 adapter->nic_ops = &qlcnic_83xx_ops;
791 }
792}
793
794static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
795 u32 data[]);
796static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
797 u32 data[]);
798
799void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
800 struct qlcnic_cmd_args *cmd)
801{
802 int i;
803
804 if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
805 return;
806
807 dev_info(&adapter->pdev->dev,
808 "Host MBX regs(%d)\n", cmd->req.num);
809 for (i = 0; i < cmd->req.num; i++) {
810 if (i && !(i % 8))
811 pr_info("\n");
812 pr_info("%08x ", cmd->req.arg[i]);
813 }
814 pr_info("\n");
815 dev_info(&adapter->pdev->dev,
816 "FW MBX regs(%d)\n", cmd->rsp.num);
817 for (i = 0; i < cmd->rsp.num; i++) {
818 if (i && !(i % 8))
819 pr_info("\n");
820 pr_info("%08x ", cmd->rsp.arg[i]);
821 }
822 pr_info("\n");
823}
824
825static void qlcnic_83xx_poll_for_mbx_completion(struct qlcnic_adapter *adapter,
826 struct qlcnic_cmd_args *cmd)
827{
828 struct qlcnic_hardware_context *ahw = adapter->ahw;
829 int opcode = LSW(cmd->req.arg[0]);
830 unsigned long max_loops;
831
832 max_loops = cmd->total_cmds * QLC_83XX_MBX_CMD_LOOP;
833
834 for (; max_loops; max_loops--) {
835 if (atomic_read(&cmd->rsp_status) ==
836 QLC_83XX_MBX_RESPONSE_ARRIVED)
837 return;
838
839 udelay(1);
840 }
841
842 dev_err(&adapter->pdev->dev,
843 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
844 __func__, opcode, cmd->type, ahw->pci_func, ahw->op_mode);
845 flush_workqueue(ahw->mailbox->work_q);
846 return;
847}
848
849int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
850 struct qlcnic_cmd_args *cmd)
851{
852 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
853 struct qlcnic_hardware_context *ahw = adapter->ahw;
854 int cmd_type, err, opcode;
855 unsigned long timeout;
856
857 if (!mbx)
858 return -EIO;
859
860 opcode = LSW(cmd->req.arg[0]);
861 cmd_type = cmd->type;
862 err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
863 if (err) {
864 dev_err(&adapter->pdev->dev,
865 "%s: Mailbox not available, cmd_op=0x%x, cmd_context=0x%x, pci_func=0x%x, op_mode=0x%x\n",
866 __func__, opcode, cmd->type, ahw->pci_func,
867 ahw->op_mode);
868 return err;
869 }
870
871 switch (cmd_type) {
872 case QLC_83XX_MBX_CMD_WAIT:
873 if (!wait_for_completion_timeout(&cmd->completion, timeout)) {
874 dev_err(&adapter->pdev->dev,
875 "%s: Mailbox command timed out, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
876 __func__, opcode, cmd_type, ahw->pci_func,
877 ahw->op_mode);
878 flush_workqueue(mbx->work_q);
879 }
880 break;
881 case QLC_83XX_MBX_CMD_NO_WAIT:
882 return 0;
883 case QLC_83XX_MBX_CMD_BUSY_WAIT:
884 qlcnic_83xx_poll_for_mbx_completion(adapter, cmd);
885 break;
886 default:
887 dev_err(&adapter->pdev->dev,
888 "%s: Invalid mailbox command, cmd_op=0x%x, cmd_type=0x%x, pci_func=0x%x, op_mode=0x%x\n",
889 __func__, opcode, cmd_type, ahw->pci_func,
890 ahw->op_mode);
891 qlcnic_83xx_detach_mailbox_work(adapter);
892 }
893
894 return cmd->rsp_opcode;
895}
896
897int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
898 struct qlcnic_adapter *adapter, u32 type)
899{
900 int i, size;
901 u32 temp;
902 const struct qlcnic_mailbox_metadata *mbx_tbl;
903
904 memset(mbx, 0, sizeof(struct qlcnic_cmd_args));
905 mbx_tbl = qlcnic_83xx_mbx_tbl;
906 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
907 for (i = 0; i < size; i++) {
908 if (type == mbx_tbl[i].cmd) {
909 mbx->op_type = QLC_83XX_FW_MBX_CMD;
910 mbx->req.num = mbx_tbl[i].in_args;
911 mbx->rsp.num = mbx_tbl[i].out_args;
912 mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
913 GFP_ATOMIC);
914 if (!mbx->req.arg)
915 return -ENOMEM;
916 mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
917 GFP_ATOMIC);
918 if (!mbx->rsp.arg) {
919 kfree(mbx->req.arg);
920 mbx->req.arg = NULL;
921 return -ENOMEM;
922 }
923 temp = adapter->ahw->fw_hal_version << 29;
924 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
925 mbx->cmd_op = type;
926 return 0;
927 }
928 }
929
930 dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n",
931 __func__, type);
932 return -EINVAL;
933}
934
935void qlcnic_83xx_idc_aen_work(struct work_struct *work)
936{
937 struct qlcnic_adapter *adapter;
938 struct qlcnic_cmd_args cmd;
939 int i, err = 0;
940
941 adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
942 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
943 if (err)
944 return;
945
946 for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
947 cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
948
949 err = qlcnic_issue_cmd(adapter, &cmd);
950 if (err)
951 dev_info(&adapter->pdev->dev,
952 "%s: Mailbox IDC ACK failed.\n", __func__);
953 qlcnic_free_mbx_args(&cmd);
954}
955
956static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
957 u32 data[])
958{
959 dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
960 QLCNIC_MBX_RSP(data[0]));
961 clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
962 return;
963}
964
965static void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
966{
967 struct qlcnic_hardware_context *ahw = adapter->ahw;
968 u32 event[QLC_83XX_MBX_AEN_CNT];
969 int i;
970
971 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
972 event[i] = readl(QLCNIC_MBX_FW(ahw, i));
973
974 switch (QLCNIC_MBX_RSP(event[0])) {
975
976 case QLCNIC_MBX_LINK_EVENT:
977 qlcnic_83xx_handle_link_aen(adapter, event);
978 break;
979 case QLCNIC_MBX_COMP_EVENT:
980 qlcnic_83xx_handle_idc_comp_aen(adapter, event);
981 break;
982 case QLCNIC_MBX_REQUEST_EVENT:
983 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
984 adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
985 queue_delayed_work(adapter->qlcnic_wq,
986 &adapter->idc_aen_work, 0);
987 break;
988 case QLCNIC_MBX_TIME_EXTEND_EVENT:
989 ahw->extend_lb_time = event[1] >> 8 & 0xf;
990 break;
991 case QLCNIC_MBX_BC_EVENT:
992 qlcnic_sriov_handle_bc_event(adapter, event[1]);
993 break;
994 case QLCNIC_MBX_SFP_INSERT_EVENT:
995 dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
996 QLCNIC_MBX_RSP(event[0]));
997 break;
998 case QLCNIC_MBX_SFP_REMOVE_EVENT:
999 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
1000 QLCNIC_MBX_RSP(event[0]));
1001 break;
1002 case QLCNIC_MBX_DCBX_CONFIG_CHANGE_EVENT:
1003 qlcnic_dcb_aen_handler(adapter->dcb, (void *)&event[1]);
1004 break;
1005 default:
1006 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
1007 QLCNIC_MBX_RSP(event[0]));
1008 break;
1009 }
1010
1011 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
1012}
1013
1014static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
1015{
1016 u32 resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
1017 struct qlcnic_hardware_context *ahw = adapter->ahw;
1018 struct qlcnic_mailbox *mbx = ahw->mailbox;
1019 unsigned long flags;
1020
1021 spin_lock_irqsave(&mbx->aen_lock, flags);
1022 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
1023 if (resp & QLCNIC_SET_OWNER) {
1024 event = readl(QLCNIC_MBX_FW(ahw, 0));
1025 if (event & QLCNIC_MBX_ASYNC_EVENT) {
1026 __qlcnic_83xx_process_aen(adapter);
1027 } else {
1028 if (mbx->rsp_status != rsp_status)
1029 qlcnic_83xx_notify_mbx_response(mbx);
1030 }
1031 }
1032 spin_unlock_irqrestore(&mbx->aen_lock, flags);
1033}
1034
1035static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
1036{
1037 struct qlcnic_adapter *adapter;
1038
1039 adapter = container_of(work, struct qlcnic_adapter, mbx_poll_work.work);
1040
1041 if (!test_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1042 return;
1043
1044 qlcnic_83xx_process_aen(adapter);
1045 queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work,
1046 (HZ / 10));
1047}
1048
1049void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
1050{
1051 if (test_and_set_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1052 return;
1053
1054 INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
1055 queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work, 0);
1056}
1057
1058void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
1059{
1060 if (!test_and_clear_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
1061 return;
1062 cancel_delayed_work_sync(&adapter->mbx_poll_work);
1063}
1064
1065static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
1066{
1067 int index, i, err, sds_mbx_size;
1068 u32 *buf, intrpt_id, intr_mask;
1069 u16 context_id;
1070 u8 num_sds;
1071 struct qlcnic_cmd_args cmd;
1072 struct qlcnic_host_sds_ring *sds;
1073 struct qlcnic_sds_mbx sds_mbx;
1074 struct qlcnic_add_rings_mbx_out *mbx_out;
1075 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1076 struct qlcnic_hardware_context *ahw = adapter->ahw;
1077
1078 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1079 context_id = recv_ctx->context_id;
1080 num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS;
1081 ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
1082 QLCNIC_CMD_ADD_RCV_RINGS);
1083 cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
1084
1085
1086 index = 2;
1087 for (i = 8; i < adapter->drv_sds_rings; i++) {
1088 memset(&sds_mbx, 0, sds_mbx_size);
1089 sds = &recv_ctx->sds_rings[i];
1090 sds->consumer = 0;
1091 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1092 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1093 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1094 sds_mbx.sds_ring_size = sds->num_desc;
1095
1096 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1097 intrpt_id = ahw->intr_tbl[i].id;
1098 else
1099 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1100
1101 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1102 sds_mbx.intrpt_id = intrpt_id;
1103 else
1104 sds_mbx.intrpt_id = 0xffff;
1105 sds_mbx.intrpt_val = 0;
1106 buf = &cmd.req.arg[index];
1107 memcpy(buf, &sds_mbx, sds_mbx_size);
1108 index += sds_mbx_size / sizeof(u32);
1109 }
1110
1111
1112 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1113 if (err) {
1114 dev_err(&adapter->pdev->dev,
1115 "Failed to add rings %d\n", err);
1116 goto out;
1117 }
1118
1119 mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
1120 index = 0;
1121
1122 for (i = 8; i < adapter->drv_sds_rings; i++) {
1123 sds = &recv_ctx->sds_rings[i];
1124 sds->crb_sts_consumer = ahw->pci_base0 +
1125 mbx_out->host_csmr[index];
1126 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1127 intr_mask = ahw->intr_tbl[i].src;
1128 else
1129 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1130
1131 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1132 index++;
1133 }
1134out:
1135 qlcnic_free_mbx_args(&cmd);
1136 return err;
1137}
1138
1139void qlcnic_83xx_del_rx_ctx(struct qlcnic_adapter *adapter)
1140{
1141 int err;
1142 u32 temp = 0;
1143 struct qlcnic_cmd_args cmd;
1144 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1145
1146 if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX))
1147 return;
1148
1149 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1150 cmd.req.arg[0] |= (0x3 << 29);
1151
1152 if (qlcnic_sriov_pf_check(adapter))
1153 qlcnic_pf_set_interface_id_del_rx_ctx(adapter, &temp);
1154
1155 cmd.req.arg[1] = recv_ctx->context_id | temp;
1156 err = qlcnic_issue_cmd(adapter, &cmd);
1157 if (err)
1158 dev_err(&adapter->pdev->dev,
1159 "Failed to destroy rx ctx in firmware\n");
1160
1161 recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
1162 qlcnic_free_mbx_args(&cmd);
1163}
1164
1165int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
1166{
1167 int i, err, index, sds_mbx_size, rds_mbx_size;
1168 u8 num_sds, num_rds;
1169 u32 *buf, intrpt_id, intr_mask, cap = 0;
1170 struct qlcnic_host_sds_ring *sds;
1171 struct qlcnic_host_rds_ring *rds;
1172 struct qlcnic_sds_mbx sds_mbx;
1173 struct qlcnic_rds_mbx rds_mbx;
1174 struct qlcnic_cmd_args cmd;
1175 struct qlcnic_rcv_mbx_out *mbx_out;
1176 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1177 struct qlcnic_hardware_context *ahw = adapter->ahw;
1178 num_rds = adapter->max_rds_rings;
1179
1180 if (adapter->drv_sds_rings <= QLCNIC_MAX_SDS_RINGS)
1181 num_sds = adapter->drv_sds_rings;
1182 else
1183 num_sds = QLCNIC_MAX_SDS_RINGS;
1184
1185 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1186 rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
1187 cap = QLCNIC_CAP0_LEGACY_CONTEXT;
1188
1189 if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
1190 cap |= QLC_83XX_FW_CAP_LRO_MSS;
1191
1192
1193 err = qlcnic_alloc_mbx_args(&cmd, adapter,
1194 QLCNIC_CMD_CREATE_RX_CTX);
1195 if (err)
1196 return err;
1197
1198 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1199 cmd.req.arg[0] |= (0x3 << 29);
1200
1201 cmd.req.arg[1] = cap;
1202 cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
1203 (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
1204
1205 if (qlcnic_sriov_pf_check(adapter))
1206 qlcnic_pf_set_interface_id_create_rx_ctx(adapter,
1207 &cmd.req.arg[6]);
1208
1209 index = QLC_83XX_HOST_SDS_MBX_IDX;
1210 for (i = 0; i < num_sds; i++) {
1211 memset(&sds_mbx, 0, sds_mbx_size);
1212 sds = &recv_ctx->sds_rings[i];
1213 sds->consumer = 0;
1214 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
1215 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1216 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
1217 sds_mbx.sds_ring_size = sds->num_desc;
1218 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1219 intrpt_id = ahw->intr_tbl[i].id;
1220 else
1221 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1222 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1223 sds_mbx.intrpt_id = intrpt_id;
1224 else
1225 sds_mbx.intrpt_id = 0xffff;
1226 sds_mbx.intrpt_val = 0;
1227 buf = &cmd.req.arg[index];
1228 memcpy(buf, &sds_mbx, sds_mbx_size);
1229 index += sds_mbx_size / sizeof(u32);
1230 }
1231
1232 index = QLCNIC_HOST_RDS_MBX_IDX;
1233 rds = &recv_ctx->rds_rings[0];
1234 rds->producer = 0;
1235 memset(&rds_mbx, 0, rds_mbx_size);
1236 rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
1237 rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
1238 rds_mbx.reg_ring_sz = rds->dma_size;
1239 rds_mbx.reg_ring_len = rds->num_desc;
1240
1241 rds = &recv_ctx->rds_rings[1];
1242 rds->producer = 0;
1243 rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
1244 rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
1245 rds_mbx.jmb_ring_sz = rds->dma_size;
1246 rds_mbx.jmb_ring_len = rds->num_desc;
1247 buf = &cmd.req.arg[index];
1248 memcpy(buf, &rds_mbx, rds_mbx_size);
1249
1250
1251 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1252 if (err) {
1253 dev_err(&adapter->pdev->dev,
1254 "Failed to create Rx ctx in firmware%d\n", err);
1255 goto out;
1256 }
1257 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1258 recv_ctx->context_id = mbx_out->ctx_id;
1259 recv_ctx->state = mbx_out->state;
1260 recv_ctx->virt_port = mbx_out->vport_id;
1261 dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1262 recv_ctx->context_id, recv_ctx->state);
1263
1264
1265 rds = &recv_ctx->rds_rings[0];
1266 rds->crb_rcv_producer = ahw->pci_base0 +
1267 mbx_out->host_prod[0].reg_buf;
1268
1269 rds = &recv_ctx->rds_rings[1];
1270 rds->crb_rcv_producer = ahw->pci_base0 +
1271 mbx_out->host_prod[0].jmb_buf;
1272
1273 for (i = 0; i < num_sds; i++) {
1274 sds = &recv_ctx->sds_rings[i];
1275 sds->crb_sts_consumer = ahw->pci_base0 +
1276 mbx_out->host_csmr[i];
1277 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1278 intr_mask = ahw->intr_tbl[i].src;
1279 else
1280 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1281 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1282 }
1283
1284 if (adapter->drv_sds_rings > QLCNIC_MAX_SDS_RINGS)
1285 err = qlcnic_83xx_add_rings(adapter);
1286out:
1287 qlcnic_free_mbx_args(&cmd);
1288 return err;
1289}
1290
1291void qlcnic_83xx_del_tx_ctx(struct qlcnic_adapter *adapter,
1292 struct qlcnic_host_tx_ring *tx_ring)
1293{
1294 struct qlcnic_cmd_args cmd;
1295 u32 temp = 0;
1296
1297 if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX))
1298 return;
1299
1300 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1301 cmd.req.arg[0] |= (0x3 << 29);
1302
1303 if (qlcnic_sriov_pf_check(adapter))
1304 qlcnic_pf_set_interface_id_del_tx_ctx(adapter, &temp);
1305
1306 cmd.req.arg[1] = tx_ring->ctx_id | temp;
1307 if (qlcnic_issue_cmd(adapter, &cmd))
1308 dev_err(&adapter->pdev->dev,
1309 "Failed to destroy tx ctx in firmware\n");
1310 qlcnic_free_mbx_args(&cmd);
1311}
1312
1313int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1314 struct qlcnic_host_tx_ring *tx, int ring)
1315{
1316 int err;
1317 u16 msix_id;
1318 u32 *buf, intr_mask, temp = 0;
1319 struct qlcnic_cmd_args cmd;
1320 struct qlcnic_tx_mbx mbx;
1321 struct qlcnic_tx_mbx_out *mbx_out;
1322 struct qlcnic_hardware_context *ahw = adapter->ahw;
1323 u32 msix_vector;
1324
1325
1326 tx->producer = 0;
1327 tx->sw_consumer = 0;
1328 *(tx->hw_consumer) = 0;
1329
1330 memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1331
1332
1333 mbx.phys_addr_low = LSD(tx->phys_addr);
1334 mbx.phys_addr_high = MSD(tx->phys_addr);
1335 mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
1336 mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
1337 mbx.size = tx->num_desc;
1338 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1339 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
1340 msix_vector = adapter->drv_sds_rings + ring;
1341 else
1342 msix_vector = adapter->drv_sds_rings - 1;
1343 msix_id = ahw->intr_tbl[msix_vector].id;
1344 } else {
1345 msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1346 }
1347
1348 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1349 mbx.intr_id = msix_id;
1350 else
1351 mbx.intr_id = 0xffff;
1352 mbx.src = 0;
1353
1354 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1355 if (err)
1356 return err;
1357
1358 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1359 cmd.req.arg[0] |= (0x3 << 29);
1360
1361 if (qlcnic_sriov_pf_check(adapter))
1362 qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);
1363
1364 cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
1365 cmd.req.arg[5] = QLCNIC_SINGLE_RING | temp;
1366
1367 buf = &cmd.req.arg[6];
1368 memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1369
1370 err = qlcnic_issue_cmd(adapter, &cmd);
1371 if (err) {
1372 netdev_err(adapter->netdev,
1373 "Failed to create Tx ctx in firmware 0x%x\n", err);
1374 goto out;
1375 }
1376 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1377 tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1378 tx->ctx_id = mbx_out->ctx_id;
1379 if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
1380 !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
1381 intr_mask = ahw->intr_tbl[adapter->drv_sds_rings + ring].src;
1382 tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1383 }
1384 netdev_info(adapter->netdev,
1385 "Tx Context[0x%x] Created, state:0x%x\n",
1386 tx->ctx_id, mbx_out->state);
1387out:
1388 qlcnic_free_mbx_args(&cmd);
1389 return err;
1390}
1391
1392static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1393 u8 num_sds_ring)
1394{
1395 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1396 struct qlcnic_host_sds_ring *sds_ring;
1397 struct qlcnic_host_rds_ring *rds_ring;
1398 u16 adapter_state = adapter->is_up;
1399 u8 ring;
1400 int ret;
1401
1402 netif_device_detach(netdev);
1403
1404 if (netif_running(netdev))
1405 __qlcnic_down(adapter, netdev);
1406
1407 qlcnic_detach(adapter);
1408
1409 adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
1410 adapter->ahw->diag_test = test;
1411 adapter->ahw->linkup = 0;
1412
1413 ret = qlcnic_attach(adapter);
1414 if (ret) {
1415 netif_device_attach(netdev);
1416 return ret;
1417 }
1418
1419 ret = qlcnic_fw_create_ctx(adapter);
1420 if (ret) {
1421 qlcnic_detach(adapter);
1422 if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
1423 adapter->drv_sds_rings = num_sds_ring;
1424 qlcnic_attach(adapter);
1425 }
1426 netif_device_attach(netdev);
1427 return ret;
1428 }
1429
1430 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1431 rds_ring = &adapter->recv_ctx->rds_rings[ring];
1432 qlcnic_post_rx_buffers(adapter, rds_ring, ring);
1433 }
1434
1435 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1436 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1437 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1438 qlcnic_enable_sds_intr(adapter, sds_ring);
1439 }
1440 }
1441
1442 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1443 adapter->ahw->loopback_state = 0;
1444 adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1445 }
1446
1447 set_bit(__QLCNIC_DEV_UP, &adapter->state);
1448 return 0;
1449}
1450
1451static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1452 u8 drv_sds_rings)
1453{
1454 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1455 struct qlcnic_host_sds_ring *sds_ring;
1456 int ring;
1457
1458 clear_bit(__QLCNIC_DEV_UP, &adapter->state);
1459 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1460 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1461 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1462 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1463 qlcnic_disable_sds_intr(adapter, sds_ring);
1464 }
1465 }
1466
1467 qlcnic_fw_destroy_ctx(adapter);
1468 qlcnic_detach(adapter);
1469
1470 adapter->ahw->diag_test = 0;
1471 adapter->drv_sds_rings = drv_sds_rings;
1472
1473 if (qlcnic_attach(adapter))
1474 goto out;
1475
1476 if (netif_running(netdev))
1477 __qlcnic_up(adapter, netdev);
1478
1479out:
1480 netif_device_attach(netdev);
1481}
1482
1483static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *adapter)
1484{
1485 struct qlcnic_hardware_context *ahw = adapter->ahw;
1486 struct qlcnic_cmd_args cmd;
1487 u8 beacon_state;
1488 int err = 0;
1489
1490 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LED_CONFIG);
1491 if (!err) {
1492 err = qlcnic_issue_cmd(adapter, &cmd);
1493 if (!err) {
1494 beacon_state = cmd.rsp.arg[4];
1495 if (beacon_state == QLCNIC_BEACON_DISABLE)
1496 ahw->beacon_state = QLC_83XX_BEACON_OFF;
1497 else if (beacon_state == QLC_83XX_ENABLE_BEACON)
1498 ahw->beacon_state = QLC_83XX_BEACON_ON;
1499 }
1500 } else {
1501 netdev_err(adapter->netdev, "Get beacon state failed, err=%d\n",
1502 err);
1503 }
1504
1505 qlcnic_free_mbx_args(&cmd);
1506
1507 return;
1508}
1509
1510int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
1511 u32 beacon)
1512{
1513 struct qlcnic_cmd_args cmd;
1514 u32 mbx_in;
1515 int i, status = 0;
1516
1517 if (state) {
1518
1519 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1520 QLCNIC_CMD_GET_LED_CONFIG);
1521 if (status)
1522 return status;
1523
1524 status = qlcnic_issue_cmd(adapter, &cmd);
1525 if (status) {
1526 dev_err(&adapter->pdev->dev,
1527 "Get led config failed.\n");
1528 goto mbx_err;
1529 } else {
1530 for (i = 0; i < 4; i++)
1531 adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1];
1532 }
1533 qlcnic_free_mbx_args(&cmd);
1534
1535 mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
1536 LSW(QLC_83XX_LED_CONFIG);
1537 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1538 QLCNIC_CMD_SET_LED_CONFIG);
1539 if (status)
1540 return status;
1541
1542 cmd.req.arg[1] = mbx_in;
1543 cmd.req.arg[2] = mbx_in;
1544 cmd.req.arg[3] = mbx_in;
1545 if (beacon)
1546 cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON;
1547 status = qlcnic_issue_cmd(adapter, &cmd);
1548 if (status) {
1549 dev_err(&adapter->pdev->dev,
1550 "Set led config failed.\n");
1551 }
1552mbx_err:
1553 qlcnic_free_mbx_args(&cmd);
1554 return status;
1555
1556 } else {
1557
1558 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1559 QLCNIC_CMD_SET_LED_CONFIG);
1560 if (status)
1561 return status;
1562
1563 cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
1564 cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
1565 cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
1566 if (beacon)
1567 cmd.req.arg[4] = adapter->ahw->mbox_reg[3];
1568 status = qlcnic_issue_cmd(adapter, &cmd);
1569 if (status)
1570 dev_err(&adapter->pdev->dev,
1571 "Restoring led config failed.\n");
1572 qlcnic_free_mbx_args(&cmd);
1573 return status;
1574 }
1575}
1576
1577int qlcnic_83xx_set_led(struct net_device *netdev,
1578 enum ethtool_phys_id_state state)
1579{
1580 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1581 int err = -EIO, active = 1;
1582
1583 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1584 netdev_warn(netdev,
1585 "LED test is not supported in non-privileged mode\n");
1586 return -EOPNOTSUPP;
1587 }
1588
1589 switch (state) {
1590 case ETHTOOL_ID_ACTIVE:
1591 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1592 return -EBUSY;
1593
1594 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1595 break;
1596
1597 err = qlcnic_83xx_config_led(adapter, active, 0);
1598 if (err)
1599 netdev_err(netdev, "Failed to set LED blink state\n");
1600 break;
1601 case ETHTOOL_ID_INACTIVE:
1602 active = 0;
1603
1604 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1605 break;
1606
1607 err = qlcnic_83xx_config_led(adapter, active, 0);
1608 if (err)
1609 netdev_err(netdev, "Failed to reset LED blink state\n");
1610 break;
1611
1612 default:
1613 return -EINVAL;
1614 }
1615
1616 if (!active || err)
1617 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1618
1619 return err;
1620}
1621
1622void qlcnic_83xx_initialize_nic(struct qlcnic_adapter *adapter, int enable)
1623{
1624 struct qlcnic_cmd_args cmd;
1625 int status;
1626
1627 if (qlcnic_sriov_vf_check(adapter))
1628 return;
1629
1630 if (enable)
1631 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1632 QLCNIC_CMD_INIT_NIC_FUNC);
1633 else
1634 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1635 QLCNIC_CMD_STOP_NIC_FUNC);
1636
1637 if (status)
1638 return;
1639
1640 cmd.req.arg[1] = QLC_REGISTER_LB_IDC | QLC_INIT_FW_RESOURCES;
1641
1642 if (adapter->dcb)
1643 cmd.req.arg[1] |= QLC_REGISTER_DCB_AEN;
1644
1645 status = qlcnic_issue_cmd(adapter, &cmd);
1646 if (status)
1647 dev_err(&adapter->pdev->dev,
1648 "Failed to %s in NIC IDC function event.\n",
1649 (enable ? "register" : "unregister"));
1650
1651 qlcnic_free_mbx_args(&cmd);
1652}
1653
1654static int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1655{
1656 struct qlcnic_cmd_args cmd;
1657 int err;
1658
1659 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1660 if (err)
1661 return err;
1662
1663 cmd.req.arg[1] = adapter->ahw->port_config;
1664 err = qlcnic_issue_cmd(adapter, &cmd);
1665 if (err)
1666 dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1667 qlcnic_free_mbx_args(&cmd);
1668 return err;
1669}
1670
1671static int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1672{
1673 struct qlcnic_cmd_args cmd;
1674 int err;
1675
1676 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1677 if (err)
1678 return err;
1679
1680 err = qlcnic_issue_cmd(adapter, &cmd);
1681 if (err)
1682 dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1683 else
1684 adapter->ahw->port_config = cmd.rsp.arg[1];
1685 qlcnic_free_mbx_args(&cmd);
1686 return err;
1687}
1688
1689int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1690{
1691 int err;
1692 u32 temp;
1693 struct qlcnic_cmd_args cmd;
1694
1695 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1696 if (err)
1697 return err;
1698
1699 temp = adapter->recv_ctx->context_id << 16;
1700 cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1701 err = qlcnic_issue_cmd(adapter, &cmd);
1702 if (err)
1703 dev_info(&adapter->pdev->dev,
1704 "Setup linkevent mailbox failed\n");
1705 qlcnic_free_mbx_args(&cmd);
1706 return err;
1707}
1708
1709static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1710 u32 *interface_id)
1711{
1712 if (qlcnic_sriov_pf_check(adapter)) {
1713 qlcnic_alloc_lb_filters_mem(adapter);
1714 qlcnic_pf_set_interface_id_promisc(adapter, interface_id);
1715 adapter->rx_mac_learn = true;
1716 } else {
1717 if (!qlcnic_sriov_vf_check(adapter))
1718 *interface_id = adapter->recv_ctx->context_id << 16;
1719 }
1720}
1721
1722int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1723{
1724 struct qlcnic_cmd_args *cmd = NULL;
1725 u32 temp = 0;
1726 int err;
1727
1728 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1729 return -EIO;
1730
1731 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
1732 if (!cmd)
1733 return -ENOMEM;
1734
1735 err = qlcnic_alloc_mbx_args(cmd, adapter,
1736 QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1737 if (err)
1738 goto out;
1739
1740 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
1741 qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
1742
1743 if (qlcnic_84xx_check(adapter) && qlcnic_sriov_pf_check(adapter))
1744 mode = VPORT_MISS_MODE_ACCEPT_ALL;
1745
1746 cmd->req.arg[1] = mode | temp;
1747 err = qlcnic_issue_cmd(adapter, cmd);
1748 if (!err)
1749 return err;
1750
1751 qlcnic_free_mbx_args(cmd);
1752
1753out:
1754 kfree(cmd);
1755 return err;
1756}
1757
1758int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1759{
1760 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1761 struct qlcnic_hardware_context *ahw = adapter->ahw;
1762 u8 drv_sds_rings = adapter->drv_sds_rings;
1763 u8 drv_tx_rings = adapter->drv_tx_rings;
1764 int ret = 0, loop = 0;
1765
1766 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1767 netdev_warn(netdev,
1768 "Loopback test not supported in non privileged mode\n");
1769 return -ENOTSUPP;
1770 }
1771
1772 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1773 netdev_info(netdev, "Device is resetting\n");
1774 return -EBUSY;
1775 }
1776
1777 if (qlcnic_get_diag_lock(adapter)) {
1778 netdev_info(netdev, "Device is in diagnostics mode\n");
1779 return -EBUSY;
1780 }
1781
1782 netdev_info(netdev, "%s loopback test in progress\n",
1783 mode == QLCNIC_ILB_MODE ? "internal" : "external");
1784
1785 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
1786 drv_sds_rings);
1787 if (ret)
1788 goto fail_diag_alloc;
1789
1790 ret = qlcnic_83xx_set_lb_mode(adapter, mode);
1791 if (ret)
1792 goto free_diag_res;
1793
1794
1795 do {
1796 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1797
1798 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1799 netdev_info(netdev,
1800 "Device is resetting, free LB test resources\n");
1801 ret = -EBUSY;
1802 goto free_diag_res;
1803 }
1804 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1805 netdev_info(netdev,
1806 "Firmware didn't sent link up event to loopback request\n");
1807 ret = -ETIMEDOUT;
1808 qlcnic_83xx_clear_lb_mode(adapter, mode);
1809 goto free_diag_res;
1810 }
1811 } while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
1812
1813 ret = qlcnic_do_lb_test(adapter, mode);
1814
1815 qlcnic_83xx_clear_lb_mode(adapter, mode);
1816
1817free_diag_res:
1818 qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
1819
1820fail_diag_alloc:
1821 adapter->drv_sds_rings = drv_sds_rings;
1822 adapter->drv_tx_rings = drv_tx_rings;
1823 qlcnic_release_diag_lock(adapter);
1824 return ret;
1825}
1826
1827static void qlcnic_extend_lb_idc_cmpltn_wait(struct qlcnic_adapter *adapter,
1828 u32 *max_wait_count)
1829{
1830 struct qlcnic_hardware_context *ahw = adapter->ahw;
1831 int temp;
1832
1833 netdev_info(adapter->netdev, "Received loopback IDC time extend event for 0x%x seconds\n",
1834 ahw->extend_lb_time);
1835 temp = ahw->extend_lb_time * 1000;
1836 *max_wait_count += temp / QLC_83XX_LB_MSLEEP_COUNT;
1837 ahw->extend_lb_time = 0;
1838}
1839
1840static int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1841{
1842 struct qlcnic_hardware_context *ahw = adapter->ahw;
1843 struct net_device *netdev = adapter->netdev;
1844 u32 config, max_wait_count;
1845 int status = 0, loop = 0;
1846
1847 ahw->extend_lb_time = 0;
1848 max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1849 status = qlcnic_83xx_get_port_config(adapter);
1850 if (status)
1851 return status;
1852
1853 config = ahw->port_config;
1854
1855
1856 if ((config & QLC_83XX_CFG_LOOPBACK_HSS) ||
1857 (config & QLC_83XX_CFG_LOOPBACK_EXT)) {
1858 netdev_err(netdev,
1859 "Port already in Loopback mode.\n");
1860 return -EINPROGRESS;
1861 }
1862
1863 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1864
1865 if (mode == QLCNIC_ILB_MODE)
1866 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1867 if (mode == QLCNIC_ELB_MODE)
1868 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1869
1870 status = qlcnic_83xx_set_port_config(adapter);
1871 if (status) {
1872 netdev_err(netdev,
1873 "Failed to Set Loopback Mode = 0x%x.\n",
1874 ahw->port_config);
1875 ahw->port_config = config;
1876 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1877 return status;
1878 }
1879
1880
1881 do {
1882 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1883
1884 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1885 netdev_info(netdev,
1886 "Device is resetting, free LB test resources\n");
1887 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1888 return -EBUSY;
1889 }
1890
1891 if (ahw->extend_lb_time)
1892 qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1893 &max_wait_count);
1894
1895 if (loop++ > max_wait_count) {
1896 netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1897 __func__);
1898 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1899 qlcnic_83xx_clear_lb_mode(adapter, mode);
1900 return -ETIMEDOUT;
1901 }
1902 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1903
1904 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1905 QLCNIC_MAC_ADD);
1906 return status;
1907}
1908
1909static int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1910{
1911 struct qlcnic_hardware_context *ahw = adapter->ahw;
1912 u32 config = ahw->port_config, max_wait_count;
1913 struct net_device *netdev = adapter->netdev;
1914 int status = 0, loop = 0;
1915
1916 ahw->extend_lb_time = 0;
1917 max_wait_count = QLC_83XX_LB_WAIT_COUNT;
1918 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1919 if (mode == QLCNIC_ILB_MODE)
1920 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1921 if (mode == QLCNIC_ELB_MODE)
1922 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1923
1924 status = qlcnic_83xx_set_port_config(adapter);
1925 if (status) {
1926 netdev_err(netdev,
1927 "Failed to Clear Loopback Mode = 0x%x.\n",
1928 ahw->port_config);
1929 ahw->port_config = config;
1930 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1931 return status;
1932 }
1933
1934
1935 do {
1936 msleep(QLC_83XX_LB_MSLEEP_COUNT);
1937
1938 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1939 netdev_info(netdev,
1940 "Device is resetting, free LB test resources\n");
1941 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1942 return -EBUSY;
1943 }
1944
1945 if (ahw->extend_lb_time)
1946 qlcnic_extend_lb_idc_cmpltn_wait(adapter,
1947 &max_wait_count);
1948
1949 if (loop++ > max_wait_count) {
1950 netdev_err(netdev, "%s: Did not receive loopback IDC completion AEN\n",
1951 __func__);
1952 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1953 return -ETIMEDOUT;
1954 }
1955 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1956
1957 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1958 QLCNIC_MAC_DEL);
1959 return status;
1960}
1961
1962static void qlcnic_83xx_set_interface_id_ipaddr(struct qlcnic_adapter *adapter,
1963 u32 *interface_id)
1964{
1965 if (qlcnic_sriov_pf_check(adapter)) {
1966 qlcnic_pf_set_interface_id_ipaddr(adapter, interface_id);
1967 } else {
1968 if (!qlcnic_sriov_vf_check(adapter))
1969 *interface_id = adapter->recv_ctx->context_id << 16;
1970 }
1971}
1972
1973void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1974 int mode)
1975{
1976 int err;
1977 u32 temp = 0, temp_ip;
1978 struct qlcnic_cmd_args cmd;
1979
1980 err = qlcnic_alloc_mbx_args(&cmd, adapter,
1981 QLCNIC_CMD_CONFIGURE_IP_ADDR);
1982 if (err)
1983 return;
1984
1985 qlcnic_83xx_set_interface_id_ipaddr(adapter, &temp);
1986
1987 if (mode == QLCNIC_IP_UP)
1988 cmd.req.arg[1] = 1 | temp;
1989 else
1990 cmd.req.arg[1] = 2 | temp;
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000 temp_ip = swab32(ntohl(ip));
2001 memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
2002 err = qlcnic_issue_cmd(adapter, &cmd);
2003 if (err != QLCNIC_RCODE_SUCCESS)
2004 dev_err(&adapter->netdev->dev,
2005 "could not notify %s IP 0x%x request\n",
2006 (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
2007
2008 qlcnic_free_mbx_args(&cmd);
2009}
2010
2011int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
2012{
2013 int err;
2014 u32 temp, arg1;
2015 struct qlcnic_cmd_args cmd;
2016 int lro_bit_mask;
2017
2018 lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
2019
2020 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2021 return 0;
2022
2023 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
2024 if (err)
2025 return err;
2026
2027 temp = adapter->recv_ctx->context_id << 16;
2028 arg1 = lro_bit_mask | temp;
2029 cmd.req.arg[1] = arg1;
2030
2031 err = qlcnic_issue_cmd(adapter, &cmd);
2032 if (err)
2033 dev_info(&adapter->pdev->dev, "LRO config failed\n");
2034 qlcnic_free_mbx_args(&cmd);
2035
2036 return err;
2037}
2038
2039int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
2040{
2041 int err;
2042 u32 word;
2043 struct qlcnic_cmd_args cmd;
2044 const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
2045 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
2046 0x255b0ec26d5a56daULL };
2047
2048 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
2049 if (err)
2050 return err;
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060 word = ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
2061 ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
2062 ((u32)(enable & 0x1) << 8) |
2063 ((0x7ULL) << 16);
2064 cmd.req.arg[1] = (adapter->recv_ctx->context_id);
2065 cmd.req.arg[2] = word;
2066 memcpy(&cmd.req.arg[4], key, sizeof(key));
2067
2068 err = qlcnic_issue_cmd(adapter, &cmd);
2069
2070 if (err)
2071 dev_info(&adapter->pdev->dev, "RSS config failed\n");
2072 qlcnic_free_mbx_args(&cmd);
2073
2074 return err;
2075
2076}
2077
2078static void qlcnic_83xx_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
2079 u32 *interface_id)
2080{
2081 if (qlcnic_sriov_pf_check(adapter)) {
2082 qlcnic_pf_set_interface_id_macaddr(adapter, interface_id);
2083 } else {
2084 if (!qlcnic_sriov_vf_check(adapter))
2085 *interface_id = adapter->recv_ctx->context_id << 16;
2086 }
2087}
2088
2089int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
2090 u16 vlan_id, u8 op)
2091{
2092 struct qlcnic_cmd_args *cmd = NULL;
2093 struct qlcnic_macvlan_mbx mv;
2094 u32 *buf, temp = 0;
2095 int err;
2096
2097 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2098 return -EIO;
2099
2100 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
2101 if (!cmd)
2102 return -ENOMEM;
2103
2104 err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
2105 if (err)
2106 goto out;
2107
2108 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
2109
2110 if (vlan_id)
2111 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
2112 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
2113
2114 cmd->req.arg[1] = op | (1 << 8);
2115 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
2116 cmd->req.arg[1] |= temp;
2117 mv.vlan = vlan_id;
2118 mv.mac_addr0 = addr[0];
2119 mv.mac_addr1 = addr[1];
2120 mv.mac_addr2 = addr[2];
2121 mv.mac_addr3 = addr[3];
2122 mv.mac_addr4 = addr[4];
2123 mv.mac_addr5 = addr[5];
2124 buf = &cmd->req.arg[2];
2125 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
2126 err = qlcnic_issue_cmd(adapter, cmd);
2127 if (!err)
2128 return err;
2129
2130 qlcnic_free_mbx_args(cmd);
2131out:
2132 kfree(cmd);
2133 return err;
2134}
2135
2136void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
2137 u16 vlan_id,
2138 struct qlcnic_host_tx_ring *tx_ring)
2139{
2140 u8 mac[ETH_ALEN];
2141 memcpy(&mac, addr, ETH_ALEN);
2142 qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
2143}
2144
2145static void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
2146 u8 type, struct qlcnic_cmd_args *cmd)
2147{
2148 switch (type) {
2149 case QLCNIC_SET_STATION_MAC:
2150 case QLCNIC_SET_FAC_DEF_MAC:
2151 memcpy(&cmd->req.arg[2], mac, sizeof(u32));
2152 memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
2153 break;
2154 }
2155 cmd->req.arg[1] = type;
2156}
2157
2158int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
2159 u8 function)
2160{
2161 int err, i;
2162 struct qlcnic_cmd_args cmd;
2163 u32 mac_low, mac_high;
2164
2165 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
2166 if (err)
2167 return err;
2168
2169 qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
2170 err = qlcnic_issue_cmd(adapter, &cmd);
2171
2172 if (err == QLCNIC_RCODE_SUCCESS) {
2173 mac_low = cmd.rsp.arg[1];
2174 mac_high = cmd.rsp.arg[2];
2175
2176 for (i = 0; i < 2; i++)
2177 mac[i] = (u8) (mac_high >> ((1 - i) * 8));
2178 for (i = 2; i < 6; i++)
2179 mac[i] = (u8) (mac_low >> ((5 - i) * 8));
2180 } else {
2181 dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
2182 err);
2183 err = -EIO;
2184 }
2185 qlcnic_free_mbx_args(&cmd);
2186 return err;
2187}
2188
2189static int qlcnic_83xx_set_rx_intr_coal(struct qlcnic_adapter *adapter)
2190{
2191 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2192 struct qlcnic_cmd_args cmd;
2193 u16 temp;
2194 int err;
2195
2196 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2197 if (err)
2198 return err;
2199
2200 temp = adapter->recv_ctx->context_id;
2201 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
2202 temp = coal->rx_time_us;
2203 cmd.req.arg[2] = coal->rx_packets | temp << 16;
2204 cmd.req.arg[3] = coal->flag;
2205
2206 err = qlcnic_issue_cmd(adapter, &cmd);
2207 if (err != QLCNIC_RCODE_SUCCESS)
2208 netdev_err(adapter->netdev,
2209 "failed to set interrupt coalescing parameters\n");
2210
2211 qlcnic_free_mbx_args(&cmd);
2212
2213 return err;
2214}
2215
2216static int qlcnic_83xx_set_tx_intr_coal(struct qlcnic_adapter *adapter)
2217{
2218 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2219 struct qlcnic_cmd_args cmd;
2220 u16 temp;
2221 int err;
2222
2223 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2224 if (err)
2225 return err;
2226
2227 temp = adapter->tx_ring->ctx_id;
2228 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2229 temp = coal->tx_time_us;
2230 cmd.req.arg[2] = coal->tx_packets | temp << 16;
2231 cmd.req.arg[3] = coal->flag;
2232
2233 err = qlcnic_issue_cmd(adapter, &cmd);
2234 if (err != QLCNIC_RCODE_SUCCESS)
2235 netdev_err(adapter->netdev,
2236 "failed to set interrupt coalescing parameters\n");
2237
2238 qlcnic_free_mbx_args(&cmd);
2239
2240 return err;
2241}
2242
2243int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *adapter)
2244{
2245 int err = 0;
2246
2247 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2248 if (err)
2249 netdev_err(adapter->netdev,
2250 "failed to set Rx coalescing parameters\n");
2251
2252 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2253 if (err)
2254 netdev_err(adapter->netdev,
2255 "failed to set Tx coalescing parameters\n");
2256
2257 return err;
2258}
2259
2260int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter,
2261 struct ethtool_coalesce *ethcoal)
2262{
2263 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2264 u32 rx_coalesce_usecs, rx_max_frames;
2265 u32 tx_coalesce_usecs, tx_max_frames;
2266 int err;
2267
2268 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2269 return -EIO;
2270
2271 tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
2272 tx_max_frames = ethcoal->tx_max_coalesced_frames;
2273 rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
2274 rx_max_frames = ethcoal->rx_max_coalesced_frames;
2275 coal->flag = QLCNIC_INTR_DEFAULT;
2276
2277 if ((coal->rx_time_us == rx_coalesce_usecs) &&
2278 (coal->rx_packets == rx_max_frames)) {
2279 coal->type = QLCNIC_INTR_COAL_TYPE_TX;
2280 coal->tx_time_us = tx_coalesce_usecs;
2281 coal->tx_packets = tx_max_frames;
2282 } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
2283 (coal->tx_packets == tx_max_frames)) {
2284 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
2285 coal->rx_time_us = rx_coalesce_usecs;
2286 coal->rx_packets = rx_max_frames;
2287 } else {
2288 coal->type = QLCNIC_INTR_COAL_TYPE_RX_TX;
2289 coal->rx_time_us = rx_coalesce_usecs;
2290 coal->rx_packets = rx_max_frames;
2291 coal->tx_time_us = tx_coalesce_usecs;
2292 coal->tx_packets = tx_max_frames;
2293 }
2294
2295 switch (coal->type) {
2296 case QLCNIC_INTR_COAL_TYPE_RX:
2297 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2298 break;
2299 case QLCNIC_INTR_COAL_TYPE_TX:
2300 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2301 break;
2302 case QLCNIC_INTR_COAL_TYPE_RX_TX:
2303 err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
2304 break;
2305 default:
2306 err = -EINVAL;
2307 netdev_err(adapter->netdev,
2308 "Invalid Interrupt coalescing type\n");
2309 break;
2310 }
2311
2312 return err;
2313}
2314
2315static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
2316 u32 data[])
2317{
2318 struct qlcnic_hardware_context *ahw = adapter->ahw;
2319 u8 link_status, duplex;
2320
2321 link_status = LSB(data[3]) & 1;
2322 if (link_status) {
2323 ahw->link_speed = MSW(data[2]);
2324 duplex = LSB(MSW(data[3]));
2325 if (duplex)
2326 ahw->link_duplex = DUPLEX_FULL;
2327 else
2328 ahw->link_duplex = DUPLEX_HALF;
2329 } else {
2330 ahw->link_speed = SPEED_UNKNOWN;
2331 ahw->link_duplex = DUPLEX_UNKNOWN;
2332 }
2333
2334 ahw->link_autoneg = MSB(MSW(data[3]));
2335 ahw->module_type = MSB(LSW(data[3]));
2336 ahw->has_link_events = 1;
2337 ahw->lb_mode = data[4] & QLCNIC_LB_MODE_MASK;
2338 qlcnic_advert_link_change(adapter, link_status);
2339}
2340
2341static irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2342{
2343 u32 mask, resp, event, rsp_status = QLC_83XX_MBX_RESPONSE_ARRIVED;
2344 struct qlcnic_adapter *adapter = data;
2345 struct qlcnic_mailbox *mbx;
2346 unsigned long flags;
2347
2348 mbx = adapter->ahw->mailbox;
2349 spin_lock_irqsave(&mbx->aen_lock, flags);
2350 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
2351 if (!(resp & QLCNIC_SET_OWNER))
2352 goto out;
2353
2354 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2355 if (event & QLCNIC_MBX_ASYNC_EVENT) {
2356 __qlcnic_83xx_process_aen(adapter);
2357 } else {
2358 if (mbx->rsp_status != rsp_status)
2359 qlcnic_83xx_notify_mbx_response(mbx);
2360 else
2361 adapter->stats.mbx_spurious_intr++;
2362 }
2363
2364out:
2365 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
2366 writel(0, adapter->ahw->pci_base0 + mask);
2367 spin_unlock_irqrestore(&mbx->aen_lock, flags);
2368 return IRQ_HANDLED;
2369}
2370
2371int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
2372 struct qlcnic_info *nic)
2373{
2374 int i, err = -EIO;
2375 struct qlcnic_cmd_args cmd;
2376
2377 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
2378 dev_err(&adapter->pdev->dev,
2379 "%s: Error, invoked by non management func\n",
2380 __func__);
2381 return err;
2382 }
2383
2384 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
2385 if (err)
2386 return err;
2387
2388 cmd.req.arg[1] = (nic->pci_func << 16);
2389 cmd.req.arg[2] = 0x1 << 16;
2390 cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
2391 cmd.req.arg[4] = nic->capabilities;
2392 cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
2393 cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
2394 cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
2395 for (i = 8; i < 32; i++)
2396 cmd.req.arg[i] = 0;
2397
2398 err = qlcnic_issue_cmd(adapter, &cmd);
2399
2400 if (err != QLCNIC_RCODE_SUCCESS) {
2401 dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
2402 err);
2403 err = -EIO;
2404 }
2405
2406 qlcnic_free_mbx_args(&cmd);
2407
2408 return err;
2409}
2410
2411int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
2412 struct qlcnic_info *npar_info, u8 func_id)
2413{
2414 int err;
2415 u32 temp;
2416 u8 op = 0;
2417 struct qlcnic_cmd_args cmd;
2418 struct qlcnic_hardware_context *ahw = adapter->ahw;
2419
2420 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
2421 if (err)
2422 return err;
2423
2424 if (func_id != ahw->pci_func) {
2425 temp = func_id << 16;
2426 cmd.req.arg[1] = op | BIT_31 | temp;
2427 } else {
2428 cmd.req.arg[1] = ahw->pci_func << 16;
2429 }
2430 err = qlcnic_issue_cmd(adapter, &cmd);
2431 if (err) {
2432 dev_info(&adapter->pdev->dev,
2433 "Failed to get nic info %d\n", err);
2434 goto out;
2435 }
2436
2437 npar_info->op_type = cmd.rsp.arg[1];
2438 npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
2439 npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
2440 npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
2441 npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
2442 npar_info->capabilities = cmd.rsp.arg[4];
2443 npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
2444 npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
2445 npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
2446 npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
2447 npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
2448 npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
2449 if (cmd.rsp.arg[8] & 0x1)
2450 npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
2451 if (cmd.rsp.arg[8] & 0x10000) {
2452 temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
2453 npar_info->max_linkspeed_reg_offset = temp;
2454 }
2455
2456 memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
2457 sizeof(ahw->extra_capability));
2458
2459out:
2460 qlcnic_free_mbx_args(&cmd);
2461 return err;
2462}
2463
2464int qlcnic_get_pci_func_type(struct qlcnic_adapter *adapter, u16 type,
2465 u16 *nic, u16 *fcoe, u16 *iscsi)
2466{
2467 struct device *dev = &adapter->pdev->dev;
2468 int err = 0;
2469
2470 switch (type) {
2471 case QLCNIC_TYPE_NIC:
2472 (*nic)++;
2473 break;
2474 case QLCNIC_TYPE_FCOE:
2475 (*fcoe)++;
2476 break;
2477 case QLCNIC_TYPE_ISCSI:
2478 (*iscsi)++;
2479 break;
2480 default:
2481 dev_err(dev, "%s: Unknown PCI type[%x]\n",
2482 __func__, type);
2483 err = -EIO;
2484 }
2485
2486 return err;
2487}
2488
2489int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
2490 struct qlcnic_pci_info *pci_info)
2491{
2492 struct qlcnic_hardware_context *ahw = adapter->ahw;
2493 struct device *dev = &adapter->pdev->dev;
2494 u16 nic = 0, fcoe = 0, iscsi = 0;
2495 struct qlcnic_cmd_args cmd;
2496 int i, err = 0, j = 0;
2497 u32 temp;
2498
2499 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
2500 if (err)
2501 return err;
2502
2503 err = qlcnic_issue_cmd(adapter, &cmd);
2504
2505 ahw->total_nic_func = 0;
2506 if (err == QLCNIC_RCODE_SUCCESS) {
2507 ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
2508 for (i = 2, j = 0; j < ahw->max_vnic_func; j++, pci_info++) {
2509 pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
2510 pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2511 i++;
2512 if (!pci_info->active) {
2513 i += QLC_SKIP_INACTIVE_PCI_REGS;
2514 continue;
2515 }
2516 pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
2517 err = qlcnic_get_pci_func_type(adapter, pci_info->type,
2518 &nic, &fcoe, &iscsi);
2519 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2520 pci_info->default_port = temp;
2521 i++;
2522 pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
2523 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2524 pci_info->tx_max_bw = temp;
2525 i = i + 2;
2526 memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
2527 i++;
2528 memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
2529 i = i + 3;
2530 }
2531 } else {
2532 dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
2533 err = -EIO;
2534 }
2535
2536 ahw->total_nic_func = nic;
2537 ahw->total_pci_func = nic + fcoe + iscsi;
2538 if (ahw->total_nic_func == 0 || ahw->total_pci_func == 0) {
2539 dev_err(dev, "%s: Invalid function count: total nic func[%x], total pci func[%x]\n",
2540 __func__, ahw->total_nic_func, ahw->total_pci_func);
2541 err = -EIO;
2542 }
2543 qlcnic_free_mbx_args(&cmd);
2544
2545 return err;
2546}
2547
2548int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
2549{
2550 int i, index, err;
2551 u8 max_ints;
2552 u32 val, temp, type;
2553 struct qlcnic_cmd_args cmd;
2554
2555 max_ints = adapter->ahw->num_msix - 1;
2556 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
2557 if (err)
2558 return err;
2559
2560 cmd.req.arg[1] = max_ints;
2561
2562 if (qlcnic_sriov_vf_check(adapter))
2563 cmd.req.arg[1] |= (adapter->ahw->pci_func << 8) | BIT_16;
2564
2565 for (i = 0, index = 2; i < max_ints; i++) {
2566 type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
2567 val = type | (adapter->ahw->intr_tbl[i].type << 4);
2568 if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
2569 val |= (adapter->ahw->intr_tbl[i].id << 16);
2570 cmd.req.arg[index++] = val;
2571 }
2572 err = qlcnic_issue_cmd(adapter, &cmd);
2573 if (err) {
2574 dev_err(&adapter->pdev->dev,
2575 "Failed to configure interrupts 0x%x\n", err);
2576 goto out;
2577 }
2578
2579 max_ints = cmd.rsp.arg[1];
2580 for (i = 0, index = 2; i < max_ints; i++, index += 2) {
2581 val = cmd.rsp.arg[index];
2582 if (LSB(val)) {
2583 dev_info(&adapter->pdev->dev,
2584 "Can't configure interrupt %d\n",
2585 adapter->ahw->intr_tbl[i].id);
2586 continue;
2587 }
2588 if (op_type) {
2589 adapter->ahw->intr_tbl[i].id = MSW(val);
2590 adapter->ahw->intr_tbl[i].enabled = 1;
2591 temp = cmd.rsp.arg[index + 1];
2592 adapter->ahw->intr_tbl[i].src = temp;
2593 } else {
2594 adapter->ahw->intr_tbl[i].id = i;
2595 adapter->ahw->intr_tbl[i].enabled = 0;
2596 adapter->ahw->intr_tbl[i].src = 0;
2597 }
2598 }
2599out:
2600 qlcnic_free_mbx_args(&cmd);
2601 return err;
2602}
2603
2604int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
2605{
2606 int id, timeout = 0;
2607 u32 status = 0;
2608
2609 while (status == 0) {
2610 status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
2611 if (status)
2612 break;
2613
2614 if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
2615 id = QLC_SHARED_REG_RD32(adapter,
2616 QLCNIC_FLASH_LOCK_OWNER);
2617 dev_err(&adapter->pdev->dev,
2618 "%s: failed, lock held by %d\n", __func__, id);
2619 return -EIO;
2620 }
2621 usleep_range(1000, 2000);
2622 }
2623
2624 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
2625 return 0;
2626}
2627
2628void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
2629{
2630 QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
2631 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
2632}
2633
2634int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
2635 u32 flash_addr, u8 *p_data,
2636 int count)
2637{
2638 u32 word, range, flash_offset, addr = flash_addr, ret;
2639 ulong indirect_add, direct_window;
2640 int i, err = 0;
2641
2642 flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
2643 if (addr & 0x3) {
2644 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2645 return -EIO;
2646 }
2647
2648 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
2649 (addr & 0xFFFF0000));
2650
2651 range = flash_offset + (count * sizeof(u32));
2652
2653 if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2654
2655
2656 for (i = 0; i < count; i++) {
2657 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2658 ret = QLCRD32(adapter, indirect_add, &err);
2659 if (err == -EIO)
2660 return err;
2661
2662 word = ret;
2663 *(u32 *)p_data = word;
2664 p_data = p_data + 4;
2665 addr = addr + 4;
2666 flash_offset = flash_offset + 4;
2667
2668 if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2669 direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
2670
2671 qlcnic_83xx_wrt_reg_indirect(adapter,
2672 direct_window,
2673 (addr));
2674 flash_offset = 0;
2675 }
2676 }
2677 } else {
2678
2679 for (i = 0; i < count; i++) {
2680 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2681 ret = QLCRD32(adapter, indirect_add, &err);
2682 if (err == -EIO)
2683 return err;
2684
2685 word = ret;
2686 *(u32 *)p_data = word;
2687 p_data = p_data + 4;
2688 addr = addr + 4;
2689 }
2690 }
2691
2692 return 0;
2693}
2694
2695static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
2696{
2697 u32 status;
2698 int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
2699 int err = 0;
2700
2701 do {
2702 status = QLCRD32(adapter, QLC_83XX_FLASH_STATUS, &err);
2703 if (err == -EIO)
2704 return err;
2705
2706 if ((status & QLC_83XX_FLASH_STATUS_READY) ==
2707 QLC_83XX_FLASH_STATUS_READY)
2708 break;
2709
2710 usleep_range(1000, 1100);
2711 } while (--retries);
2712
2713 if (!retries)
2714 return -EIO;
2715
2716 return 0;
2717}
2718
2719int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *adapter)
2720{
2721 int ret;
2722 u32 cmd;
2723 cmd = adapter->ahw->fdt.write_statusreg_cmd;
2724 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2725 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
2726 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2727 adapter->ahw->fdt.write_enable_bits);
2728 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2729 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2730 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2731 if (ret)
2732 return -EIO;
2733
2734 return 0;
2735}
2736
2737int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter)
2738{
2739 int ret;
2740
2741 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2742 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
2743 adapter->ahw->fdt.write_statusreg_cmd));
2744 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2745 adapter->ahw->fdt.write_disable_bits);
2746 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2747 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2748 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2749 if (ret)
2750 return -EIO;
2751
2752 return 0;
2753}
2754
2755int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
2756{
2757 int ret, err = 0;
2758 u32 mfg_id;
2759
2760 if (qlcnic_83xx_lock_flash(adapter))
2761 return -EIO;
2762
2763 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2764 QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
2765 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2766 QLC_83XX_FLASH_READ_CTRL);
2767 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2768 if (ret) {
2769 qlcnic_83xx_unlock_flash(adapter);
2770 return -EIO;
2771 }
2772
2773 mfg_id = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
2774 if (err == -EIO) {
2775 qlcnic_83xx_unlock_flash(adapter);
2776 return err;
2777 }
2778
2779 adapter->flash_mfg_id = (mfg_id & 0xFF);
2780 qlcnic_83xx_unlock_flash(adapter);
2781
2782 return 0;
2783}
2784
2785int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
2786{
2787 int count, fdt_size, ret = 0;
2788
2789 fdt_size = sizeof(struct qlcnic_fdt);
2790 count = fdt_size / sizeof(u32);
2791
2792 if (qlcnic_83xx_lock_flash(adapter))
2793 return -EIO;
2794
2795 memset(&adapter->ahw->fdt, 0, fdt_size);
2796 ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
2797 (u8 *)&adapter->ahw->fdt,
2798 count);
2799 qlcnic_swap32_buffer((u32 *)&adapter->ahw->fdt, count);
2800 qlcnic_83xx_unlock_flash(adapter);
2801 return ret;
2802}
2803
2804int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
2805 u32 sector_start_addr)
2806{
2807 u32 reversed_addr, addr1, addr2, cmd;
2808 int ret = -EIO;
2809
2810 if (qlcnic_83xx_lock_flash(adapter) != 0)
2811 return -EIO;
2812
2813 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2814 ret = qlcnic_83xx_enable_flash_write(adapter);
2815 if (ret) {
2816 qlcnic_83xx_unlock_flash(adapter);
2817 dev_err(&adapter->pdev->dev,
2818 "%s failed at %d\n",
2819 __func__, __LINE__);
2820 return ret;
2821 }
2822 }
2823
2824 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2825 if (ret) {
2826 qlcnic_83xx_unlock_flash(adapter);
2827 dev_err(&adapter->pdev->dev,
2828 "%s: failed at %d\n", __func__, __LINE__);
2829 return -EIO;
2830 }
2831
2832 addr1 = (sector_start_addr & 0xFF) << 16;
2833 addr2 = (sector_start_addr & 0xFF0000) >> 16;
2834 reversed_addr = addr1 | addr2 | (sector_start_addr & 0xFF00);
2835
2836 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2837 reversed_addr);
2838 cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2839 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2840 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2841 else
2842 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2843 QLC_83XX_FLASH_OEM_ERASE_SIG);
2844 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2845 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2846
2847 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2848 if (ret) {
2849 qlcnic_83xx_unlock_flash(adapter);
2850 dev_err(&adapter->pdev->dev,
2851 "%s: failed at %d\n", __func__, __LINE__);
2852 return -EIO;
2853 }
2854
2855 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2856 ret = qlcnic_83xx_disable_flash_write(adapter);
2857 if (ret) {
2858 qlcnic_83xx_unlock_flash(adapter);
2859 dev_err(&adapter->pdev->dev,
2860 "%s: failed at %d\n", __func__, __LINE__);
2861 return ret;
2862 }
2863 }
2864
2865 qlcnic_83xx_unlock_flash(adapter);
2866
2867 return 0;
2868}
2869
2870int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2871 u32 *p_data)
2872{
2873 int ret = -EIO;
2874 u32 addr1 = 0x00800000 | (addr >> 2);
2875
2876 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2877 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2878 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2879 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2880 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2881 if (ret) {
2882 dev_err(&adapter->pdev->dev,
2883 "%s: failed at %d\n", __func__, __LINE__);
2884 return -EIO;
2885 }
2886
2887 return 0;
2888}
2889
2890int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2891 u32 *p_data, int count)
2892{
2893 u32 temp;
2894 int ret = -EIO, err = 0;
2895
2896 if ((count < QLC_83XX_FLASH_WRITE_MIN) ||
2897 (count > QLC_83XX_FLASH_WRITE_MAX)) {
2898 dev_err(&adapter->pdev->dev,
2899 "%s: Invalid word count\n", __func__);
2900 return -EIO;
2901 }
2902
2903 temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2904 if (err == -EIO)
2905 return err;
2906
2907 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2908 (temp | QLC_83XX_FLASH_SPI_CTRL));
2909 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2910 QLC_83XX_FLASH_ADDR_TEMP_VAL);
2911
2912
2913 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2914 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2915 QLC_83XX_FLASH_FIRST_MS_PATTERN);
2916 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2917 if (ret) {
2918 dev_err(&adapter->pdev->dev,
2919 "%s: failed at %d\n", __func__, __LINE__);
2920 return -EIO;
2921 }
2922
2923 count--;
2924 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2925 QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2926
2927 while (count != 1) {
2928 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2929 *p_data++);
2930 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2931 QLC_83XX_FLASH_SECOND_MS_PATTERN);
2932 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2933 if (ret) {
2934 dev_err(&adapter->pdev->dev,
2935 "%s: failed at %d\n", __func__, __LINE__);
2936 return -EIO;
2937 }
2938 count--;
2939 }
2940
2941 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2942 QLC_83XX_FLASH_ADDR_TEMP_VAL |
2943 (addr >> 2));
2944
2945 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2946 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2947 QLC_83XX_FLASH_LAST_MS_PATTERN);
2948 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2949 if (ret) {
2950 dev_err(&adapter->pdev->dev,
2951 "%s: failed at %d\n", __func__, __LINE__);
2952 return -EIO;
2953 }
2954
2955 ret = QLCRD32(adapter, QLC_83XX_FLASH_SPI_STATUS, &err);
2956 if (err == -EIO)
2957 return err;
2958
2959 if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2960 dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2961 __func__, __LINE__);
2962
2963 temp = QLCRD32(adapter, QLC_83XX_FLASH_SPI_CONTROL, &err);
2964 if (err == -EIO)
2965 return err;
2966
2967 qlcnic_83xx_wrt_reg_indirect(adapter,
2968 QLC_83XX_FLASH_SPI_CONTROL,
2969 (temp | QLC_83XX_FLASH_SPI_CTRL));
2970 }
2971
2972 return 0;
2973}
2974
2975static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2976{
2977 u32 val, id;
2978
2979 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2980
2981
2982 if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2983 val = val & ~0x3F;
2984 val = val | ((adapter->portnum << 2) |
2985 QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2986 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2987 dev_info(&adapter->pdev->dev,
2988 "%s: lock recovery initiated\n", __func__);
2989 msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2990 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2991 id = ((val >> 2) & 0xF);
2992 if (id == adapter->portnum) {
2993 val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2994 val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
2995 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2996
2997 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2998
2999 val = val & ~0x3F;
3000 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
3001 dev_info(&adapter->pdev->dev,
3002 "%s: lock recovery completed\n", __func__);
3003 } else {
3004 dev_info(&adapter->pdev->dev,
3005 "%s: func %d to resume lock recovery process\n",
3006 __func__, id);
3007 }
3008 } else {
3009 dev_info(&adapter->pdev->dev,
3010 "%s: lock recovery initiated by other functions\n",
3011 __func__);
3012 }
3013}
3014
3015int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
3016{
3017 u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
3018 int max_attempt = 0;
3019
3020 while (status == 0) {
3021 status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
3022 if (status)
3023 break;
3024
3025 msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
3026 i++;
3027
3028 if (i == 1)
3029 temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3030
3031 if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
3032 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3033 if (val == temp) {
3034 id = val & 0xFF;
3035 dev_info(&adapter->pdev->dev,
3036 "%s: lock to be recovered from %d\n",
3037 __func__, id);
3038 qlcnic_83xx_recover_driver_lock(adapter);
3039 i = 0;
3040 max_attempt++;
3041 } else {
3042 dev_err(&adapter->pdev->dev,
3043 "%s: failed to get lock\n", __func__);
3044 return -EIO;
3045 }
3046 }
3047
3048
3049 if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
3050 dev_err(&adapter->pdev->dev,
3051 "%s: failed to get lock\n", __func__);
3052 return -EIO;
3053 }
3054 }
3055
3056 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3057 lock_alive_counter = val >> 8;
3058 lock_alive_counter++;
3059 val = lock_alive_counter << 8 | adapter->portnum;
3060 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3061
3062 return 0;
3063}
3064
3065void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
3066{
3067 u32 val, lock_alive_counter, id;
3068
3069 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
3070 id = val & 0xFF;
3071 lock_alive_counter = val >> 8;
3072
3073 if (id != adapter->portnum)
3074 dev_err(&adapter->pdev->dev,
3075 "%s:Warning func %d is unlocking lock owned by %d\n",
3076 __func__, adapter->portnum, id);
3077
3078 val = (lock_alive_counter << 8) | 0xFF;
3079 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
3080 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
3081}
3082
3083int qlcnic_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
3084 u32 *data, u32 count)
3085{
3086 int i, j, ret = 0;
3087 u32 temp;
3088
3089
3090 if (addr & 0xF)
3091 return -EIO;
3092
3093 mutex_lock(&adapter->ahw->mem_lock);
3094 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_HI, 0);
3095
3096 for (i = 0; i < count; i++, addr += 16) {
3097 if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
3098 QLCNIC_ADDR_QDR_NET_MAX)) ||
3099 (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
3100 QLCNIC_ADDR_DDR_NET_MAX)))) {
3101 mutex_unlock(&adapter->ahw->mem_lock);
3102 return -EIO;
3103 }
3104
3105 qlcnic_ind_wr(adapter, QLCNIC_MS_ADDR_LO, addr);
3106 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_LO, *data++);
3107 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_HI, *data++);
3108 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_ULO, *data++);
3109 qlcnic_ind_wr(adapter, QLCNIC_MS_WRTDATA_UHI, *data++);
3110 qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_ENABLE);
3111 qlcnic_ind_wr(adapter, QLCNIC_MS_CTRL, QLCNIC_TA_WRITE_START);
3112
3113 for (j = 0; j < MAX_CTL_CHECK; j++) {
3114 temp = qlcnic_ind_rd(adapter, QLCNIC_MS_CTRL);
3115
3116 if ((temp & TA_CTL_BUSY) == 0)
3117 break;
3118 }
3119
3120
3121 if (j >= MAX_CTL_CHECK) {
3122 printk_ratelimited(KERN_WARNING
3123 "MS memory write failed\n");
3124 mutex_unlock(&adapter->ahw->mem_lock);
3125 return -EIO;
3126 }
3127 }
3128
3129 mutex_unlock(&adapter->ahw->mem_lock);
3130
3131 return ret;
3132}
3133
3134int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
3135 u8 *p_data, int count)
3136{
3137 u32 word, addr = flash_addr, ret;
3138 ulong indirect_addr;
3139 int i, err = 0;
3140
3141 if (qlcnic_83xx_lock_flash(adapter) != 0)
3142 return -EIO;
3143
3144 if (addr & 0x3) {
3145 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
3146 qlcnic_83xx_unlock_flash(adapter);
3147 return -EIO;
3148 }
3149
3150 for (i = 0; i < count; i++) {
3151 if (qlcnic_83xx_wrt_reg_indirect(adapter,
3152 QLC_83XX_FLASH_DIRECT_WINDOW,
3153 (addr))) {
3154 qlcnic_83xx_unlock_flash(adapter);
3155 return -EIO;
3156 }
3157
3158 indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
3159 ret = QLCRD32(adapter, indirect_addr, &err);
3160 if (err == -EIO)
3161 return err;
3162
3163 word = ret;
3164 *(u32 *)p_data = word;
3165 p_data = p_data + 4;
3166 addr = addr + 4;
3167 }
3168
3169 qlcnic_83xx_unlock_flash(adapter);
3170
3171 return 0;
3172}
3173
3174void qlcnic_83xx_get_port_type(struct qlcnic_adapter *adapter)
3175{
3176 struct qlcnic_hardware_context *ahw = adapter->ahw;
3177 struct qlcnic_cmd_args cmd;
3178 u32 config;
3179 int err;
3180
3181 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
3182 if (err)
3183 return;
3184
3185 err = qlcnic_issue_cmd(adapter, &cmd);
3186 if (err) {
3187 dev_info(&adapter->pdev->dev,
3188 "Get Link Status Command failed: 0x%x\n", err);
3189 goto out;
3190 } else {
3191 config = cmd.rsp.arg[3];
3192
3193 switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
3194 case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
3195 case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
3196 case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
3197 case QLC_83XX_MODULE_TP_1000BASE_T:
3198 ahw->port_type = QLCNIC_GBE;
3199 break;
3200 default:
3201 ahw->port_type = QLCNIC_XGBE;
3202 }
3203 }
3204out:
3205 qlcnic_free_mbx_args(&cmd);
3206}
3207
3208int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
3209{
3210 u8 pci_func;
3211 int err;
3212 u32 config = 0, state;
3213 struct qlcnic_cmd_args cmd;
3214 struct qlcnic_hardware_context *ahw = adapter->ahw;
3215
3216 if (qlcnic_sriov_vf_check(adapter))
3217 pci_func = adapter->portnum;
3218 else
3219 pci_func = ahw->pci_func;
3220
3221 state = readl(ahw->pci_base0 + QLC_83XX_LINK_STATE(pci_func));
3222 if (!QLC_83xx_FUNC_VAL(state, pci_func)) {
3223 dev_info(&adapter->pdev->dev, "link state down\n");
3224 return config;
3225 }
3226
3227 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
3228 if (err)
3229 return err;
3230
3231 err = qlcnic_issue_cmd(adapter, &cmd);
3232 if (err) {
3233 dev_info(&adapter->pdev->dev,
3234 "Get Link Status Command failed: 0x%x\n", err);
3235 goto out;
3236 } else {
3237 config = cmd.rsp.arg[1];
3238 switch (QLC_83XX_CURRENT_LINK_SPEED(config)) {
3239 case QLC_83XX_10M_LINK:
3240 ahw->link_speed = SPEED_10;
3241 break;
3242 case QLC_83XX_100M_LINK:
3243 ahw->link_speed = SPEED_100;
3244 break;
3245 case QLC_83XX_1G_LINK:
3246 ahw->link_speed = SPEED_1000;
3247 break;
3248 case QLC_83XX_10G_LINK:
3249 ahw->link_speed = SPEED_10000;
3250 break;
3251 default:
3252 ahw->link_speed = 0;
3253 break;
3254 }
3255 config = cmd.rsp.arg[3];
3256 switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
3257 case QLC_83XX_MODULE_FIBRE_10GBASE_LRM:
3258 case QLC_83XX_MODULE_FIBRE_10GBASE_LR:
3259 case QLC_83XX_MODULE_FIBRE_10GBASE_SR:
3260 ahw->supported_type = PORT_FIBRE;
3261 ahw->port_type = QLCNIC_XGBE;
3262 break;
3263 case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
3264 case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
3265 case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
3266 ahw->supported_type = PORT_FIBRE;
3267 ahw->port_type = QLCNIC_GBE;
3268 break;
3269 case QLC_83XX_MODULE_TP_1000BASE_T:
3270 ahw->supported_type = PORT_TP;
3271 ahw->port_type = QLCNIC_GBE;
3272 break;
3273 case QLC_83XX_MODULE_DA_10GE_PASSIVE_CP:
3274 case QLC_83XX_MODULE_DA_10GE_ACTIVE_CP:
3275 case QLC_83XX_MODULE_DA_10GE_LEGACY_CP:
3276 case QLC_83XX_MODULE_DA_1GE_PASSIVE_CP:
3277 ahw->supported_type = PORT_DA;
3278 ahw->port_type = QLCNIC_XGBE;
3279 break;
3280 default:
3281 ahw->supported_type = PORT_OTHER;
3282 ahw->port_type = QLCNIC_XGBE;
3283 }
3284 if (config & 1)
3285 err = 1;
3286 }
3287out:
3288 qlcnic_free_mbx_args(&cmd);
3289 return config;
3290}
3291
3292int qlcnic_83xx_get_link_ksettings(struct qlcnic_adapter *adapter,
3293 struct ethtool_link_ksettings *ecmd)
3294{
3295 struct qlcnic_hardware_context *ahw = adapter->ahw;
3296 u32 config = 0;
3297 int status = 0;
3298 u32 supported, advertising;
3299
3300 if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
3301
3302 status = qlcnic_83xx_get_port_info(adapter);
3303
3304 config = qlcnic_83xx_test_link(adapter);
3305 ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
3306 }
3307
3308
3309 ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
3310
3311 if (netif_running(adapter->netdev) && ahw->has_link_events) {
3312 ecmd->base.speed = ahw->link_speed;
3313 ecmd->base.duplex = ahw->link_duplex;
3314 ecmd->base.autoneg = ahw->link_autoneg;
3315 } else {
3316 ecmd->base.speed = SPEED_UNKNOWN;
3317 ecmd->base.duplex = DUPLEX_UNKNOWN;
3318 ecmd->base.autoneg = AUTONEG_DISABLE;
3319 }
3320
3321 supported = (SUPPORTED_10baseT_Full |
3322 SUPPORTED_100baseT_Full |
3323 SUPPORTED_1000baseT_Full |
3324 SUPPORTED_10000baseT_Full |
3325 SUPPORTED_Autoneg);
3326
3327 ethtool_convert_link_mode_to_legacy_u32(&advertising,
3328 ecmd->link_modes.advertising);
3329
3330 if (ecmd->base.autoneg == AUTONEG_ENABLE) {
3331 if (ahw->port_config & QLC_83XX_10_CAPABLE)
3332 advertising |= SUPPORTED_10baseT_Full;
3333 if (ahw->port_config & QLC_83XX_100_CAPABLE)
3334 advertising |= SUPPORTED_100baseT_Full;
3335 if (ahw->port_config & QLC_83XX_1G_CAPABLE)
3336 advertising |= SUPPORTED_1000baseT_Full;
3337 if (ahw->port_config & QLC_83XX_10G_CAPABLE)
3338 advertising |= SUPPORTED_10000baseT_Full;
3339 if (ahw->port_config & QLC_83XX_AUTONEG_ENABLE)
3340 advertising |= ADVERTISED_Autoneg;
3341 } else {
3342 switch (ahw->link_speed) {
3343 case SPEED_10:
3344 advertising = SUPPORTED_10baseT_Full;
3345 break;
3346 case SPEED_100:
3347 advertising = SUPPORTED_100baseT_Full;
3348 break;
3349 case SPEED_1000:
3350 advertising = SUPPORTED_1000baseT_Full;
3351 break;
3352 case SPEED_10000:
3353 advertising = SUPPORTED_10000baseT_Full;
3354 break;
3355 default:
3356 break;
3357 }
3358
3359 }
3360
3361 switch (ahw->supported_type) {
3362 case PORT_FIBRE:
3363 supported |= SUPPORTED_FIBRE;
3364 advertising |= ADVERTISED_FIBRE;
3365 ecmd->base.port = PORT_FIBRE;
3366 break;
3367 case PORT_TP:
3368 supported |= SUPPORTED_TP;
3369 advertising |= ADVERTISED_TP;
3370 ecmd->base.port = PORT_TP;
3371 break;
3372 case PORT_DA:
3373 supported |= SUPPORTED_FIBRE;
3374 advertising |= ADVERTISED_FIBRE;
3375 ecmd->base.port = PORT_DA;
3376 break;
3377 default:
3378 supported |= SUPPORTED_FIBRE;
3379 advertising |= ADVERTISED_FIBRE;
3380 ecmd->base.port = PORT_OTHER;
3381 break;
3382 }
3383 ecmd->base.phy_address = ahw->physical_port;
3384
3385 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
3386 supported);
3387 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
3388 advertising);
3389
3390 return status;
3391}
3392
3393int qlcnic_83xx_set_link_ksettings(struct qlcnic_adapter *adapter,
3394 const struct ethtool_link_ksettings *ecmd)
3395{
3396 struct qlcnic_hardware_context *ahw = adapter->ahw;
3397 u32 config = adapter->ahw->port_config;
3398 int status = 0;
3399
3400
3401 if (ecmd->base.duplex == DUPLEX_HALF) {
3402 netdev_info(adapter->netdev,
3403 "Half duplex mode not supported\n");
3404 return -EINVAL;
3405 }
3406
3407 if (ecmd->base.autoneg) {
3408 ahw->port_config |= QLC_83XX_AUTONEG_ENABLE;
3409 ahw->port_config |= (QLC_83XX_100_CAPABLE |
3410 QLC_83XX_1G_CAPABLE |
3411 QLC_83XX_10G_CAPABLE);
3412 } else {
3413 ahw->port_config &= ~QLC_83XX_AUTONEG_ENABLE;
3414 switch (ecmd->base.speed) {
3415 case SPEED_10:
3416 ahw->port_config &= ~(QLC_83XX_100_CAPABLE |
3417 QLC_83XX_1G_CAPABLE |
3418 QLC_83XX_10G_CAPABLE);
3419 ahw->port_config |= QLC_83XX_10_CAPABLE;
3420 break;
3421 case SPEED_100:
3422 ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3423 QLC_83XX_1G_CAPABLE |
3424 QLC_83XX_10G_CAPABLE);
3425 ahw->port_config |= QLC_83XX_100_CAPABLE;
3426 break;
3427 case SPEED_1000:
3428 ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3429 QLC_83XX_100_CAPABLE |
3430 QLC_83XX_10G_CAPABLE);
3431 ahw->port_config |= QLC_83XX_1G_CAPABLE;
3432 break;
3433 case SPEED_10000:
3434 ahw->port_config &= ~(QLC_83XX_10_CAPABLE |
3435 QLC_83XX_100_CAPABLE |
3436 QLC_83XX_1G_CAPABLE);
3437 ahw->port_config |= QLC_83XX_10G_CAPABLE;
3438 break;
3439 default:
3440 return -EINVAL;
3441 }
3442 }
3443
3444 status = qlcnic_83xx_set_port_config(adapter);
3445 if (status) {
3446 netdev_info(adapter->netdev,
3447 "Failed to Set Link Speed and autoneg.\n");
3448 ahw->port_config = config;
3449 }
3450 return status;
3451}
3452
3453static inline u64 *qlcnic_83xx_copy_stats(struct qlcnic_cmd_args *cmd,
3454 u64 *data, int index)
3455{
3456 u32 low, hi;
3457 u64 val;
3458
3459 low = cmd->rsp.arg[index];
3460 hi = cmd->rsp.arg[index + 1];
3461 val = (((u64) low) | (((u64) hi) << 32));
3462 *data++ = val;
3463 return data;
3464}
3465
3466static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
3467 struct qlcnic_cmd_args *cmd, u64 *data,
3468 int type, int *ret)
3469{
3470 int err, k, total_regs;
3471
3472 *ret = 0;
3473 err = qlcnic_issue_cmd(adapter, cmd);
3474 if (err != QLCNIC_RCODE_SUCCESS) {
3475 dev_info(&adapter->pdev->dev,
3476 "Error in get statistics mailbox command\n");
3477 *ret = -EIO;
3478 return data;
3479 }
3480 total_regs = cmd->rsp.num;
3481 switch (type) {
3482 case QLC_83XX_STAT_MAC:
3483
3484 for (k = 2; k < 28; k += 2)
3485 data = qlcnic_83xx_copy_stats(cmd, data, k);
3486
3487
3488 for (k += 6; k < 60; k += 2)
3489 data = qlcnic_83xx_copy_stats(cmd, data, k);
3490
3491
3492 for (k += 6; k < 80; k += 2)
3493 data = qlcnic_83xx_copy_stats(cmd, data, k);
3494
3495 for (; k < total_regs; k += 2)
3496 data = qlcnic_83xx_copy_stats(cmd, data, k);
3497 break;
3498 case QLC_83XX_STAT_RX:
3499 for (k = 2; k < 8; k += 2)
3500 data = qlcnic_83xx_copy_stats(cmd, data, k);
3501
3502 for (k += 2; k < 24; k += 2)
3503 data = qlcnic_83xx_copy_stats(cmd, data, k);
3504
3505 for (k += 2; k < total_regs; k += 2)
3506 data = qlcnic_83xx_copy_stats(cmd, data, k);
3507 break;
3508 case QLC_83XX_STAT_TX:
3509 for (k = 2; k < 10; k += 2)
3510 data = qlcnic_83xx_copy_stats(cmd, data, k);
3511
3512 for (k += 2; k < total_regs; k += 2)
3513 data = qlcnic_83xx_copy_stats(cmd, data, k);
3514 break;
3515 default:
3516 dev_warn(&adapter->pdev->dev, "Unknown get statistics mode\n");
3517 *ret = -EIO;
3518 }
3519 return data;
3520}
3521
3522void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
3523{
3524 struct qlcnic_cmd_args cmd;
3525 struct net_device *netdev = adapter->netdev;
3526 int ret = 0;
3527
3528 ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
3529 if (ret)
3530 return;
3531
3532 cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
3533 cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
3534 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3535 QLC_83XX_STAT_TX, &ret);
3536 if (ret) {
3537 netdev_err(netdev, "Error getting Tx stats\n");
3538 goto out;
3539 }
3540
3541 cmd.req.arg[1] = BIT_2 | (adapter->portnum << 16);
3542 cmd.rsp.num = QLC_83XX_MAC_STAT_REGS;
3543 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3544 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3545 QLC_83XX_STAT_MAC, &ret);
3546 if (ret) {
3547 netdev_err(netdev, "Error getting MAC stats\n");
3548 goto out;
3549 }
3550
3551 cmd.req.arg[1] = adapter->recv_ctx->context_id << 16;
3552 cmd.rsp.num = QLC_83XX_RX_STAT_REGS;
3553 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3554 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3555 QLC_83XX_STAT_RX, &ret);
3556 if (ret)
3557 netdev_err(netdev, "Error getting Rx stats\n");
3558out:
3559 qlcnic_free_mbx_args(&cmd);
3560}
3561
3562#define QLCNIC_83XX_ADD_PORT0 BIT_0
3563#define QLCNIC_83XX_ADD_PORT1 BIT_1
3564#define QLCNIC_83XX_EXTENDED_MEM_SIZE 13
3565int qlcnic_83xx_extend_md_capab(struct qlcnic_adapter *adapter)
3566{
3567 struct qlcnic_cmd_args cmd;
3568 int err;
3569
3570 err = qlcnic_alloc_mbx_args(&cmd, adapter,
3571 QLCNIC_CMD_83XX_EXTEND_ISCSI_DUMP_CAP);
3572 if (err)
3573 return err;
3574
3575 cmd.req.arg[1] = (QLCNIC_83XX_ADD_PORT0 | QLCNIC_83XX_ADD_PORT1);
3576 cmd.req.arg[2] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3577 cmd.req.arg[3] = QLCNIC_83XX_EXTENDED_MEM_SIZE;
3578
3579 err = qlcnic_issue_cmd(adapter, &cmd);
3580 if (err)
3581 dev_err(&adapter->pdev->dev,
3582 "failed to issue extend iSCSI minidump capability\n");
3583
3584 return err;
3585}
3586
3587int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
3588{
3589 u32 major, minor, sub;
3590
3591 major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
3592 minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
3593 sub = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
3594
3595 if (adapter->fw_version != QLCNIC_VERSION_CODE(major, minor, sub)) {
3596 dev_info(&adapter->pdev->dev, "%s: Reg test failed\n",
3597 __func__);
3598 return 1;
3599 }
3600 return 0;
3601}
3602
3603inline int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
3604{
3605 return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
3606 sizeof(*adapter->ahw->ext_reg_tbl)) +
3607 (ARRAY_SIZE(qlcnic_83xx_reg_tbl) *
3608 sizeof(*adapter->ahw->reg_tbl));
3609}
3610
3611int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
3612{
3613 int i, j = 0;
3614
3615 for (i = QLCNIC_DEV_INFO_SIZE + 1;
3616 j < ARRAY_SIZE(qlcnic_83xx_reg_tbl); i++, j++)
3617 regs_buff[i] = QLC_SHARED_REG_RD32(adapter, j);
3618
3619 for (j = 0; j < ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl); j++)
3620 regs_buff[i++] = QLCRDX(adapter->ahw, j);
3621 return i;
3622}
3623
3624int qlcnic_83xx_interrupt_test(struct net_device *netdev)
3625{
3626 struct qlcnic_adapter *adapter = netdev_priv(netdev);
3627 struct qlcnic_hardware_context *ahw = adapter->ahw;
3628 struct qlcnic_cmd_args cmd;
3629 u8 val, drv_sds_rings = adapter->drv_sds_rings;
3630 u8 drv_tx_rings = adapter->drv_tx_rings;
3631 u32 data;
3632 u16 intrpt_id, id;
3633 int ret;
3634
3635 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
3636 netdev_info(netdev, "Device is resetting\n");
3637 return -EBUSY;
3638 }
3639
3640 if (qlcnic_get_diag_lock(adapter)) {
3641 netdev_info(netdev, "Device in diagnostics mode\n");
3642 return -EBUSY;
3643 }
3644
3645 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
3646 drv_sds_rings);
3647 if (ret)
3648 goto fail_diag_irq;
3649
3650 ahw->diag_cnt = 0;
3651 ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
3652 if (ret)
3653 goto fail_diag_irq;
3654
3655 if (adapter->flags & QLCNIC_MSIX_ENABLED)
3656 intrpt_id = ahw->intr_tbl[0].id;
3657 else
3658 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
3659
3660 cmd.req.arg[1] = 1;
3661 cmd.req.arg[2] = intrpt_id;
3662 cmd.req.arg[3] = BIT_0;
3663
3664 ret = qlcnic_issue_cmd(adapter, &cmd);
3665 data = cmd.rsp.arg[2];
3666 id = LSW(data);
3667 val = LSB(MSW(data));
3668 if (id != intrpt_id)
3669 dev_info(&adapter->pdev->dev,
3670 "Interrupt generated: 0x%x, requested:0x%x\n",
3671 id, intrpt_id);
3672 if (val)
3673 dev_err(&adapter->pdev->dev,
3674 "Interrupt test error: 0x%x\n", val);
3675 if (ret)
3676 goto done;
3677
3678 msleep(20);
3679 ret = !ahw->diag_cnt;
3680
3681done:
3682 qlcnic_free_mbx_args(&cmd);
3683 qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);
3684
3685fail_diag_irq:
3686 adapter->drv_sds_rings = drv_sds_rings;
3687 adapter->drv_tx_rings = drv_tx_rings;
3688 qlcnic_release_diag_lock(adapter);
3689 return ret;
3690}
3691
3692void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
3693 struct ethtool_pauseparam *pause)
3694{
3695 struct qlcnic_hardware_context *ahw = adapter->ahw;
3696 int status = 0;
3697 u32 config;
3698
3699 status = qlcnic_83xx_get_port_config(adapter);
3700 if (status) {
3701 dev_err(&adapter->pdev->dev,
3702 "%s: Get Pause Config failed\n", __func__);
3703 return;
3704 }
3705 config = ahw->port_config;
3706 if (config & QLC_83XX_CFG_STD_PAUSE) {
3707 switch (MSW(config)) {
3708 case QLC_83XX_TX_PAUSE:
3709 pause->tx_pause = 1;
3710 break;
3711 case QLC_83XX_RX_PAUSE:
3712 pause->rx_pause = 1;
3713 break;
3714 case QLC_83XX_TX_RX_PAUSE:
3715 default:
3716
3717
3718
3719 pause->tx_pause = 1;
3720 pause->rx_pause = 1;
3721 }
3722 }
3723
3724 if (QLC_83XX_AUTONEG(config))
3725 pause->autoneg = 1;
3726}
3727
3728int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
3729 struct ethtool_pauseparam *pause)
3730{
3731 struct qlcnic_hardware_context *ahw = adapter->ahw;
3732 int status = 0;
3733 u32 config;
3734
3735 status = qlcnic_83xx_get_port_config(adapter);
3736 if (status) {
3737 dev_err(&adapter->pdev->dev,
3738 "%s: Get Pause Config failed.\n", __func__);
3739 return status;
3740 }
3741 config = ahw->port_config;
3742
3743 if (ahw->port_type == QLCNIC_GBE) {
3744 if (pause->autoneg)
3745 ahw->port_config |= QLC_83XX_ENABLE_AUTONEG;
3746 if (!pause->autoneg)
3747 ahw->port_config &= ~QLC_83XX_ENABLE_AUTONEG;
3748 } else if ((ahw->port_type == QLCNIC_XGBE) && (pause->autoneg)) {
3749 return -EOPNOTSUPP;
3750 }
3751
3752 if (!(config & QLC_83XX_CFG_STD_PAUSE))
3753 ahw->port_config |= QLC_83XX_CFG_STD_PAUSE;
3754
3755 if (pause->rx_pause && pause->tx_pause) {
3756 ahw->port_config |= QLC_83XX_CFG_STD_TX_RX_PAUSE;
3757 } else if (pause->rx_pause && !pause->tx_pause) {
3758 ahw->port_config &= ~QLC_83XX_CFG_STD_TX_PAUSE;
3759 ahw->port_config |= QLC_83XX_CFG_STD_RX_PAUSE;
3760 } else if (pause->tx_pause && !pause->rx_pause) {
3761 ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
3762 ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
3763 } else if (!pause->rx_pause && !pause->tx_pause) {
3764 ahw->port_config &= ~(QLC_83XX_CFG_STD_TX_RX_PAUSE |
3765 QLC_83XX_CFG_STD_PAUSE);
3766 }
3767 status = qlcnic_83xx_set_port_config(adapter);
3768 if (status) {
3769 dev_err(&adapter->pdev->dev,
3770 "%s: Set Pause Config failed.\n", __func__);
3771 ahw->port_config = config;
3772 }
3773 return status;
3774}
3775
3776static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter)
3777{
3778 int ret, err = 0;
3779 u32 temp;
3780
3781 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
3782 QLC_83XX_FLASH_OEM_READ_SIG);
3783 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
3784 QLC_83XX_FLASH_READ_CTRL);
3785 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
3786 if (ret)
3787 return -EIO;
3788
3789 temp = QLCRD32(adapter, QLC_83XX_FLASH_RDDATA, &err);
3790 if (err == -EIO)
3791 return err;
3792
3793 return temp & 0xFF;
3794}
3795
3796int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
3797{
3798 int status;
3799
3800 status = qlcnic_83xx_read_flash_status_reg(adapter);
3801 if (status == -EIO) {
3802 dev_info(&adapter->pdev->dev, "%s: EEPROM test failed.\n",
3803 __func__);
3804 return 1;
3805 }
3806 return 0;
3807}
3808
3809static int qlcnic_83xx_shutdown(struct pci_dev *pdev)
3810{
3811 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
3812 struct net_device *netdev = adapter->netdev;
3813 int retval;
3814
3815 netif_device_detach(netdev);
3816 qlcnic_cancel_idc_work(adapter);
3817
3818 if (netif_running(netdev))
3819 qlcnic_down(adapter, netdev);
3820
3821 qlcnic_83xx_disable_mbx_intr(adapter);
3822 cancel_delayed_work_sync(&adapter->idc_aen_work);
3823
3824 retval = pci_save_state(pdev);
3825 if (retval)
3826 return retval;
3827
3828 return 0;
3829}
3830
3831static int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
3832{
3833 struct qlcnic_hardware_context *ahw = adapter->ahw;
3834 struct qlc_83xx_idc *idc = &ahw->idc;
3835 int err = 0;
3836
3837 err = qlcnic_83xx_idc_init(adapter);
3838 if (err)
3839 return err;
3840
3841 if (ahw->nic_mode == QLCNIC_VNIC_MODE) {
3842 if (ahw->op_mode == QLCNIC_MGMT_FUNC) {
3843 qlcnic_83xx_set_vnic_opmode(adapter);
3844 } else {
3845 err = qlcnic_83xx_check_vnic_state(adapter);
3846 if (err)
3847 return err;
3848 }
3849 }
3850
3851 err = qlcnic_83xx_idc_reattach_driver(adapter);
3852 if (err)
3853 return err;
3854
3855 qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state,
3856 idc->delay);
3857 return err;
3858}
3859
3860void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx)
3861{
3862 INIT_COMPLETION(mbx->completion);
3863 set_bit(QLC_83XX_MBX_READY, &mbx->status);
3864}
3865
3866void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
3867{
3868 if (!mbx)
3869 return;
3870
3871 destroy_workqueue(mbx->work_q);
3872 kfree(mbx);
3873}
3874
3875static inline void
3876qlcnic_83xx_notify_cmd_completion(struct qlcnic_adapter *adapter,
3877 struct qlcnic_cmd_args *cmd)
3878{
3879 atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_ARRIVED);
3880
3881 if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) {
3882 qlcnic_free_mbx_args(cmd);
3883 kfree(cmd);
3884 return;
3885 }
3886 complete(&cmd->completion);
3887}
3888
3889static void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
3890{
3891 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3892 struct list_head *head = &mbx->cmd_q;
3893 struct qlcnic_cmd_args *cmd = NULL;
3894
3895 spin_lock(&mbx->queue_lock);
3896
3897 while (!list_empty(head)) {
3898 cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
3899 dev_info(&adapter->pdev->dev, "%s: Mailbox command 0x%x\n",
3900 __func__, cmd->cmd_op);
3901 list_del(&cmd->list);
3902 mbx->num_cmds--;
3903 qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3904 }
3905
3906 spin_unlock(&mbx->queue_lock);
3907}
3908
3909static int qlcnic_83xx_check_mbx_status(struct qlcnic_adapter *adapter)
3910{
3911 struct qlcnic_hardware_context *ahw = adapter->ahw;
3912 struct qlcnic_mailbox *mbx = ahw->mailbox;
3913 u32 host_mbx_ctrl;
3914
3915 if (!test_bit(QLC_83XX_MBX_READY, &mbx->status))
3916 return -EBUSY;
3917
3918 host_mbx_ctrl = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
3919 if (host_mbx_ctrl) {
3920 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3921 ahw->idc.collect_dump = 1;
3922 return -EIO;
3923 }
3924
3925 return 0;
3926}
3927
3928static inline void qlcnic_83xx_signal_mbx_cmd(struct qlcnic_adapter *adapter,
3929 u8 issue_cmd)
3930{
3931 if (issue_cmd)
3932 QLCWRX(adapter->ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
3933 else
3934 QLCWRX(adapter->ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
3935}
3936
3937static void qlcnic_83xx_dequeue_mbx_cmd(struct qlcnic_adapter *adapter,
3938 struct qlcnic_cmd_args *cmd)
3939{
3940 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3941
3942 spin_lock(&mbx->queue_lock);
3943
3944 list_del(&cmd->list);
3945 mbx->num_cmds--;
3946
3947 spin_unlock(&mbx->queue_lock);
3948
3949 qlcnic_83xx_notify_cmd_completion(adapter, cmd);
3950}
3951
3952static void qlcnic_83xx_encode_mbx_cmd(struct qlcnic_adapter *adapter,
3953 struct qlcnic_cmd_args *cmd)
3954{
3955 u32 mbx_cmd, fw_hal_version, hdr_size, total_size, tmp;
3956 struct qlcnic_hardware_context *ahw = adapter->ahw;
3957 int i, j;
3958
3959 if (cmd->op_type != QLC_83XX_MBX_POST_BC_OP) {
3960 mbx_cmd = cmd->req.arg[0];
3961 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3962 for (i = 1; i < cmd->req.num; i++)
3963 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
3964 } else {
3965 fw_hal_version = ahw->fw_hal_version;
3966 hdr_size = sizeof(struct qlcnic_bc_hdr) / sizeof(u32);
3967 total_size = cmd->pay_size + hdr_size;
3968 tmp = QLCNIC_CMD_BC_EVENT_SETUP | total_size << 16;
3969 mbx_cmd = tmp | fw_hal_version << 29;
3970 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
3971
3972
3973 mbx_cmd = 0x1 | 1 << 4;
3974
3975 if (qlcnic_sriov_pf_check(adapter))
3976 mbx_cmd |= cmd->func_num << 5;
3977
3978 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 1));
3979
3980 for (i = 2, j = 0; j < hdr_size; i++, j++)
3981 writel(*(cmd->hdr++), QLCNIC_MBX_HOST(ahw, i));
3982 for (j = 0; j < cmd->pay_size; j++, i++)
3983 writel(*(cmd->pay++), QLCNIC_MBX_HOST(ahw, i));
3984 }
3985}
3986
3987void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *adapter)
3988{
3989 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
3990
3991 if (!mbx)
3992 return;
3993
3994 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
3995 complete(&mbx->completion);
3996 cancel_work_sync(&mbx->work);
3997 flush_workqueue(mbx->work_q);
3998 qlcnic_83xx_flush_mbx_queue(adapter);
3999}
4000
4001static int qlcnic_83xx_enqueue_mbx_cmd(struct qlcnic_adapter *adapter,
4002 struct qlcnic_cmd_args *cmd,
4003 unsigned long *timeout)
4004{
4005 struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
4006
4007 if (test_bit(QLC_83XX_MBX_READY, &mbx->status)) {
4008 atomic_set(&cmd->rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);
4009 init_completion(&cmd->completion);
4010 cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_UNKNOWN;
4011
4012 spin_lock(&mbx->queue_lock);
4013
4014 list_add_tail(&cmd->list, &mbx->cmd_q);
4015 mbx->num_cmds++;
4016 cmd->total_cmds = mbx->num_cmds;
4017 *timeout = cmd->total_cmds * QLC_83XX_MBX_TIMEOUT;
4018 queue_work(mbx->work_q, &mbx->work);
4019
4020 spin_unlock(&mbx->queue_lock);
4021
4022 return 0;
4023 }
4024
4025 return -EBUSY;
4026}
4027
4028static int qlcnic_83xx_check_mac_rcode(struct qlcnic_adapter *adapter,
4029 struct qlcnic_cmd_args *cmd)
4030{
4031 u8 mac_cmd_rcode;
4032 u32 fw_data;
4033
4034 if (cmd->cmd_op == QLCNIC_CMD_CONFIG_MAC_VLAN) {
4035 fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2));
4036 mac_cmd_rcode = (u8)fw_data;
4037 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
4038 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
4039 mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
4040 cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
4041 return QLCNIC_RCODE_SUCCESS;
4042 }
4043 }
4044
4045 return -EINVAL;
4046}
4047
4048static void qlcnic_83xx_decode_mbx_rsp(struct qlcnic_adapter *adapter,
4049 struct qlcnic_cmd_args *cmd)
4050{
4051 struct qlcnic_hardware_context *ahw = adapter->ahw;
4052 struct device *dev = &adapter->pdev->dev;
4053 u8 mbx_err_code;
4054 u32 fw_data;
4055
4056 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
4057 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
4058 qlcnic_83xx_get_mbx_data(adapter, cmd);
4059
4060 switch (mbx_err_code) {
4061 case QLCNIC_MBX_RSP_OK:
4062 case QLCNIC_MBX_PORT_RSP_OK:
4063 cmd->rsp_opcode = QLCNIC_RCODE_SUCCESS;
4064 break;
4065 default:
4066 if (!qlcnic_83xx_check_mac_rcode(adapter, cmd))
4067 break;
4068
4069 dev_err(dev, "%s: Mailbox command failed, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x, error=0x%x\n",
4070 __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
4071 ahw->op_mode, mbx_err_code);
4072 cmd->rsp_opcode = QLC_83XX_MBX_RESPONSE_FAILED;
4073 qlcnic_dump_mbx(adapter, cmd);
4074 }
4075
4076 return;
4077}
4078
4079static inline void qlcnic_dump_mailbox_registers(struct qlcnic_adapter *adapter)
4080{
4081 struct qlcnic_hardware_context *ahw = adapter->ahw;
4082 u32 offset;
4083
4084 offset = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
4085 dev_info(&adapter->pdev->dev, "Mbx interrupt mask=0x%x, Mbx interrupt enable=0x%x, Host mbx control=0x%x, Fw mbx control=0x%x",
4086 readl(ahw->pci_base0 + offset),
4087 QLCRDX(ahw, QLCNIC_MBX_INTR_ENBL),
4088 QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL),
4089 QLCRDX(ahw, QLCNIC_FW_MBX_CTRL));
4090}
4091
4092static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
4093{
4094 struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox,
4095 work);
4096 struct qlcnic_adapter *adapter = mbx->adapter;
4097 const struct qlcnic_mbx_ops *mbx_ops = mbx->ops;
4098 struct device *dev = &adapter->pdev->dev;
4099 struct list_head *head = &mbx->cmd_q;
4100 struct qlcnic_hardware_context *ahw;
4101 struct qlcnic_cmd_args *cmd = NULL;
4102 unsigned long flags;
4103
4104 ahw = adapter->ahw;
4105
4106 while (true) {
4107 if (qlcnic_83xx_check_mbx_status(adapter)) {
4108 qlcnic_83xx_flush_mbx_queue(adapter);
4109 return;
4110 }
4111
4112 spin_lock_irqsave(&mbx->aen_lock, flags);
4113 mbx->rsp_status = QLC_83XX_MBX_RESPONSE_WAIT;
4114 spin_unlock_irqrestore(&mbx->aen_lock, flags);
4115
4116 spin_lock(&mbx->queue_lock);
4117
4118 if (list_empty(head)) {
4119 spin_unlock(&mbx->queue_lock);
4120 return;
4121 }
4122 cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
4123
4124 spin_unlock(&mbx->queue_lock);
4125
4126 mbx_ops->encode_cmd(adapter, cmd);
4127 mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_REQUEST);
4128
4129 if (wait_for_completion_timeout(&mbx->completion,
4130 QLC_83XX_MBX_TIMEOUT)) {
4131 mbx_ops->decode_resp(adapter, cmd);
4132 mbx_ops->nofity_fw(adapter, QLC_83XX_MBX_COMPLETION);
4133 } else {
4134 dev_err(dev, "%s: Mailbox command timeout, opcode=0x%x, cmd_type=0x%x, func=0x%x, op_mode=0x%x\n",
4135 __func__, cmd->cmd_op, cmd->type, ahw->pci_func,
4136 ahw->op_mode);
4137 clear_bit(QLC_83XX_MBX_READY, &mbx->status);
4138 qlcnic_dump_mailbox_registers(adapter);
4139 qlcnic_83xx_get_mbx_data(adapter, cmd);
4140 qlcnic_dump_mbx(adapter, cmd);
4141 qlcnic_83xx_idc_request_reset(adapter,
4142 QLCNIC_FORCE_FW_DUMP_KEY);
4143 cmd->rsp_opcode = QLCNIC_RCODE_TIMEOUT;
4144 }
4145 mbx_ops->dequeue_cmd(adapter, cmd);
4146 }
4147}
4148
4149static const struct qlcnic_mbx_ops qlcnic_83xx_mbx_ops = {
4150 .enqueue_cmd = qlcnic_83xx_enqueue_mbx_cmd,
4151 .dequeue_cmd = qlcnic_83xx_dequeue_mbx_cmd,
4152 .decode_resp = qlcnic_83xx_decode_mbx_rsp,
4153 .encode_cmd = qlcnic_83xx_encode_mbx_cmd,
4154 .nofity_fw = qlcnic_83xx_signal_mbx_cmd,
4155};
4156
4157int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *adapter)
4158{
4159 struct qlcnic_hardware_context *ahw = adapter->ahw;
4160 struct qlcnic_mailbox *mbx;
4161
4162 ahw->mailbox = kzalloc(sizeof(*mbx), GFP_KERNEL);
4163 if (!ahw->mailbox)
4164 return -ENOMEM;
4165
4166 mbx = ahw->mailbox;
4167 mbx->ops = &qlcnic_83xx_mbx_ops;
4168 mbx->adapter = adapter;
4169
4170 spin_lock_init(&mbx->queue_lock);
4171 spin_lock_init(&mbx->aen_lock);
4172 INIT_LIST_HEAD(&mbx->cmd_q);
4173 init_completion(&mbx->completion);
4174
4175 mbx->work_q = create_singlethread_workqueue("qlcnic_mailbox");
4176 if (mbx->work_q == NULL) {
4177 kfree(mbx);
4178 return -ENOMEM;
4179 }
4180
4181 INIT_WORK(&mbx->work, qlcnic_83xx_mailbox_worker);
4182 set_bit(QLC_83XX_MBX_READY, &mbx->status);
4183 return 0;
4184}
4185
4186static pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *pdev,
4187 pci_channel_state_t state)
4188{
4189 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4190
4191 if (state == pci_channel_io_perm_failure)
4192 return PCI_ERS_RESULT_DISCONNECT;
4193
4194 if (state == pci_channel_io_normal)
4195 return PCI_ERS_RESULT_RECOVERED;
4196
4197 set_bit(__QLCNIC_AER, &adapter->state);
4198 set_bit(__QLCNIC_RESETTING, &adapter->state);
4199
4200 qlcnic_83xx_aer_stop_poll_work(adapter);
4201
4202 pci_save_state(pdev);
4203 pci_disable_device(pdev);
4204
4205 return PCI_ERS_RESULT_NEED_RESET;
4206}
4207
4208static pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *pdev)
4209{
4210 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4211 int err = 0;
4212
4213 pdev->error_state = pci_channel_io_normal;
4214 err = pci_enable_device(pdev);
4215 if (err)
4216 goto disconnect;
4217
4218 pci_set_power_state(pdev, PCI_D0);
4219 pci_set_master(pdev);
4220 pci_restore_state(pdev);
4221
4222 err = qlcnic_83xx_aer_reset(adapter);
4223 if (err == 0)
4224 return PCI_ERS_RESULT_RECOVERED;
4225disconnect:
4226 clear_bit(__QLCNIC_AER, &adapter->state);
4227 clear_bit(__QLCNIC_RESETTING, &adapter->state);
4228 return PCI_ERS_RESULT_DISCONNECT;
4229}
4230
4231static void qlcnic_83xx_io_resume(struct pci_dev *pdev)
4232{
4233 struct qlcnic_adapter *adapter = pci_get_drvdata(pdev);
4234
4235 pci_cleanup_aer_uncorrect_error_status(pdev);
4236 if (test_and_clear_bit(__QLCNIC_AER, &adapter->state))
4237 qlcnic_83xx_aer_start_poll_work(adapter);
4238}
4239