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