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