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