]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
qlcnic: Add support for 'set driver version' in 83XX
[mirror_ubuntu-zesty-kernel.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_83xx_hw.c
CommitLineData
577ae39d
JK
1/*
2 * QLogic qlcnic NIC Driver
3 * Copyright (c) 2009-2013 QLogic Corporation
4 *
5 * See LICENSE.qlcnic for copyright and licensing details.
6 */
7
7f966452 8#include "qlcnic.h"
f8468331 9#include "qlcnic_sriov.h"
7f966452
SC
10#include <linux/if_vlan.h>
11#include <linux/ipv6.h>
12#include <linux/ethtool.h>
13#include <linux/interrupt.h>
14
15#define QLCNIC_MAX_TX_QUEUES 1
7f966452 16#define RSS_HASHTYPE_IP_TCP 0x3
f197a7aa 17#define QLC_83XX_FW_MBX_CMD 0
7f966452 18
7f966452
SC
19static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
20 {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
21 {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
22 {QLCNIC_CMD_CREATE_RX_CTX, 136, 27},
23 {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
24 {QLCNIC_CMD_CREATE_TX_CTX, 54, 18},
25 {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1},
26 {QLCNIC_CMD_CONFIGURE_MAC_LEARNING, 2, 1},
27 {QLCNIC_CMD_INTRPT_TEST, 22, 12},
28 {QLCNIC_CMD_SET_MTU, 3, 1},
29 {QLCNIC_CMD_READ_PHY, 4, 2},
30 {QLCNIC_CMD_WRITE_PHY, 5, 1},
31 {QLCNIC_CMD_READ_HW_REG, 4, 1},
32 {QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
33 {QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
34 {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
35 {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
36 {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
37 {QLCNIC_CMD_GET_PCI_INFO, 1, 66},
38 {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
39 {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
40 {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
41 {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
42 {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
43 {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
44 {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
45 {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
46 {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1},
47 {QLCNIC_CMD_CONFIG_PORT, 4, 1},
48 {QLCNIC_CMD_TEMP_SIZE, 1, 4},
49 {QLCNIC_CMD_GET_TEMP_HDR, 5, 5},
50 {QLCNIC_CMD_GET_LINK_EVENT, 2, 1},
51 {QLCNIC_CMD_CONFIG_MAC_VLAN, 4, 3},
52 {QLCNIC_CMD_CONFIG_INTR_COAL, 6, 1},
53 {QLCNIC_CMD_CONFIGURE_RSS, 14, 1},
54 {QLCNIC_CMD_CONFIGURE_LED, 2, 1},
55 {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, 2, 1},
56 {QLCNIC_CMD_CONFIGURE_HW_LRO, 2, 1},
57 {QLCNIC_CMD_GET_STATISTICS, 2, 80},
58 {QLCNIC_CMD_SET_PORT_CONFIG, 2, 1},
59 {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
60 {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
61 {QLCNIC_CMD_IDC_ACK, 5, 1},
62 {QLCNIC_CMD_INIT_NIC_FUNC, 2, 1},
63 {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
64 {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
65 {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
8af3f33d 66 {QLCNIC_CMD_83XX_SET_DRV_VER, 4, 1},
7f966452 67 {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
02feda17 68 {QLCNIC_CMD_CONFIG_VPORT, 4, 4},
f197a7aa 69 {QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
7f966452
SC
70};
71
f8468331 72const u32 qlcnic_83xx_ext_reg_tbl[] = {
7f966452
SC
73 0x38CC, /* Global Reset */
74 0x38F0, /* Wildcard */
75 0x38FC, /* Informant */
76 0x3038, /* Host MBX ctrl */
77 0x303C, /* FW MBX ctrl */
78 0x355C, /* BOOT LOADER ADDRESS REG */
79 0x3560, /* BOOT LOADER SIZE REG */
80 0x3564, /* FW IMAGE ADDR REG */
81 0x1000, /* MBX intr enable */
82 0x1200, /* Default Intr mask */
83 0x1204, /* Default Interrupt ID */
84 0x3780, /* QLC_83XX_IDC_MAJ_VERSION */
85 0x3784, /* QLC_83XX_IDC_DEV_STATE */
86 0x3788, /* QLC_83XX_IDC_DRV_PRESENCE */
87 0x378C, /* QLC_83XX_IDC_DRV_ACK */
88 0x3790, /* QLC_83XX_IDC_CTRL */
89 0x3794, /* QLC_83XX_IDC_DRV_AUDIT */
90 0x3798, /* QLC_83XX_IDC_MIN_VERSION */
91 0x379C, /* QLC_83XX_RECOVER_DRV_LOCK */
92 0x37A0, /* QLC_83XX_IDC_PF_0 */
93 0x37A4, /* QLC_83XX_IDC_PF_1 */
94 0x37A8, /* QLC_83XX_IDC_PF_2 */
95 0x37AC, /* QLC_83XX_IDC_PF_3 */
96 0x37B0, /* QLC_83XX_IDC_PF_4 */
97 0x37B4, /* QLC_83XX_IDC_PF_5 */
98 0x37B8, /* QLC_83XX_IDC_PF_6 */
99 0x37BC, /* QLC_83XX_IDC_PF_7 */
100 0x37C0, /* QLC_83XX_IDC_PF_8 */
101 0x37C4, /* QLC_83XX_IDC_PF_9 */
102 0x37C8, /* QLC_83XX_IDC_PF_10 */
103 0x37CC, /* QLC_83XX_IDC_PF_11 */
104 0x37D0, /* QLC_83XX_IDC_PF_12 */
105 0x37D4, /* QLC_83XX_IDC_PF_13 */
106 0x37D8, /* QLC_83XX_IDC_PF_14 */
107 0x37DC, /* QLC_83XX_IDC_PF_15 */
108 0x37E0, /* QLC_83XX_IDC_DEV_PARTITION_INFO_1 */
109 0x37E4, /* QLC_83XX_IDC_DEV_PARTITION_INFO_2 */
110 0x37F0, /* QLC_83XX_DRV_OP_MODE */
111 0x37F4, /* QLC_83XX_VNIC_STATE */
112 0x3868, /* QLC_83XX_DRV_LOCK */
113 0x386C, /* QLC_83XX_DRV_UNLOCK */
114 0x3504, /* QLC_83XX_DRV_LOCK_ID */
115 0x34A4, /* QLC_83XX_ASIC_TEMP */
116};
117
f8468331 118const u32 qlcnic_83xx_reg_tbl[] = {
7f966452
SC
119 0x34A8, /* PEG_HALT_STAT1 */
120 0x34AC, /* PEG_HALT_STAT2 */
121 0x34B0, /* FW_HEARTBEAT */
122 0x3500, /* FLASH LOCK_ID */
123 0x3528, /* FW_CAPABILITIES */
124 0x3538, /* Driver active, DRV_REG0 */
125 0x3540, /* Device state, DRV_REG1 */
126 0x3544, /* Driver state, DRV_REG2 */
127 0x3548, /* Driver scratch, DRV_REG3 */
128 0x354C, /* Device partiton info, DRV_REG4 */
129 0x3524, /* Driver IDC ver, DRV_REG5 */
130 0x3550, /* FW_VER_MAJOR */
131 0x3554, /* FW_VER_MINOR */
132 0x3558, /* FW_VER_SUB */
133 0x359C, /* NPAR STATE */
134 0x35FC, /* FW_IMG_VALID */
135 0x3650, /* CMD_PEG_STATE */
136 0x373C, /* RCV_PEG_STATE */
137 0x37B4, /* ASIC TEMP */
138 0x356C, /* FW API */
139 0x3570, /* DRV OP MODE */
140 0x3850, /* FLASH LOCK */
141 0x3854, /* FLASH UNLOCK */
142};
143
144static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
145 .read_crb = qlcnic_83xx_read_crb,
146 .write_crb = qlcnic_83xx_write_crb,
147 .read_reg = qlcnic_83xx_rd_reg_indirect,
148 .write_reg = qlcnic_83xx_wrt_reg_indirect,
149 .get_mac_address = qlcnic_83xx_get_mac_address,
150 .setup_intr = qlcnic_83xx_setup_intr,
151 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
152 .mbx_cmd = qlcnic_83xx_mbx_op,
153 .get_func_no = qlcnic_83xx_get_func_no,
154 .api_lock = qlcnic_83xx_cam_lock,
155 .api_unlock = qlcnic_83xx_cam_unlock,
319ecf12
SC
156 .add_sysfs = qlcnic_83xx_add_sysfs,
157 .remove_sysfs = qlcnic_83xx_remove_sysfs,
4be41e92 158 .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag,
7f966452
SC
159 .create_rx_ctx = qlcnic_83xx_create_rx_ctx,
160 .create_tx_ctx = qlcnic_83xx_create_tx_ctx,
7cb03b23
RB
161 .del_rx_ctx = qlcnic_83xx_del_rx_ctx,
162 .del_tx_ctx = qlcnic_83xx_del_tx_ctx,
7f966452
SC
163 .setup_link_event = qlcnic_83xx_setup_link_event,
164 .get_nic_info = qlcnic_83xx_get_nic_info,
165 .get_pci_info = qlcnic_83xx_get_pci_info,
166 .set_nic_info = qlcnic_83xx_set_nic_info,
167 .change_macvlan = qlcnic_83xx_sre_macaddr_change,
4be41e92
SC
168 .napi_enable = qlcnic_83xx_napi_enable,
169 .napi_disable = qlcnic_83xx_napi_disable,
7f966452
SC
170 .config_intr_coal = qlcnic_83xx_config_intr_coal,
171 .config_rss = qlcnic_83xx_config_rss,
172 .config_hw_lro = qlcnic_83xx_config_hw_lro,
7f966452
SC
173 .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
174 .change_l2_filter = qlcnic_83xx_change_l2_filter,
175 .get_board_info = qlcnic_83xx_get_port_info,
52e493d0 176 .set_mac_filter_count = qlcnic_83xx_set_mac_filter_count,
91b7282b 177 .free_mac_list = qlcnic_82xx_free_mac_list,
7f966452
SC
178};
179
180static struct qlcnic_nic_template qlcnic_83xx_ops = {
181 .config_bridged_mode = qlcnic_config_bridged_mode,
182 .config_led = qlcnic_config_led,
629263ac
SC
183 .request_reset = qlcnic_83xx_idc_request_reset,
184 .cancel_idc_work = qlcnic_83xx_idc_exit,
4be41e92
SC
185 .napi_add = qlcnic_83xx_napi_add,
186 .napi_del = qlcnic_83xx_napi_del,
7f966452
SC
187 .config_ipaddr = qlcnic_83xx_config_ipaddr,
188 .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
189};
190
191void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
192{
193 ahw->hw_ops = &qlcnic_83xx_hw_ops;
194 ahw->reg_tbl = (u32 *)qlcnic_83xx_reg_tbl;
195 ahw->ext_reg_tbl = (u32 *)qlcnic_83xx_ext_reg_tbl;
196}
197
198int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
199{
200 u32 fw_major, fw_minor, fw_build;
201 struct pci_dev *pdev = adapter->pdev;
202
203 fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
204 fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
205 fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
206 adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
207
208 dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
209 QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
210
211 return adapter->fw_version;
212}
213
214static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
215{
216 void __iomem *base;
217 u32 val;
218
219 base = adapter->ahw->pci_base0 +
220 QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
221 writel(addr, base);
222 val = readl(base);
223 if (val != addr)
224 return -EIO;
225
226 return 0;
227}
228
229int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr)
230{
231 int ret;
232 struct qlcnic_hardware_context *ahw = adapter->ahw;
233
234 ret = __qlcnic_set_win_base(adapter, (u32) addr);
235 if (!ret) {
236 return QLCRDX(ahw, QLCNIC_WILDCARD);
237 } else {
238 dev_err(&adapter->pdev->dev,
239 "%s failed, addr = 0x%x\n", __func__, (int)addr);
240 return -EIO;
241 }
242}
243
244int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
245 u32 data)
246{
247 int err;
248 struct qlcnic_hardware_context *ahw = adapter->ahw;
249
250 err = __qlcnic_set_win_base(adapter, (u32) addr);
251 if (!err) {
252 QLCWRX(ahw, QLCNIC_WILDCARD, data);
253 return 0;
254 } else {
255 dev_err(&adapter->pdev->dev,
256 "%s failed, addr = 0x%x data = 0x%x\n",
257 __func__, (int)addr, data);
258 return err;
259 }
260}
261
262int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
263{
264 int err, i, num_msix;
265 struct qlcnic_hardware_context *ahw = adapter->ahw;
266
267 if (!num_intr)
268 num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
269 num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
270 num_intr));
271 /* account for AEN interrupt MSI-X based interrupts */
272 num_msix += 1;
da6c8063
RB
273
274 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
275 num_msix += adapter->max_drv_tx_rings;
276
7f966452
SC
277 err = qlcnic_enable_msix(adapter, num_msix);
278 if (err == -ENOMEM)
279 return err;
280 if (adapter->flags & QLCNIC_MSIX_ENABLED)
281 num_msix = adapter->ahw->num_msix;
f8468331
RB
282 else {
283 if (qlcnic_sriov_vf_check(adapter))
284 return -EINVAL;
7f966452 285 num_msix = 1;
f8468331 286 }
7f966452
SC
287 /* setup interrupt mapping table for fw */
288 ahw->intr_tbl = vzalloc(num_msix *
289 sizeof(struct qlcnic_intrpt_config));
290 if (!ahw->intr_tbl)
291 return -ENOMEM;
292 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
293 /* MSI-X enablement failed, use legacy interrupt */
294 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
295 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
296 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
297 adapter->msix_entries[0].vector = adapter->pdev->irq;
298 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
299 }
300
301 for (i = 0; i < num_msix; i++) {
302 if (adapter->flags & QLCNIC_MSIX_ENABLED)
303 ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
304 else
305 ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
306 ahw->intr_tbl[i].id = i;
307 ahw->intr_tbl[i].src = 0;
308 }
309 return 0;
310}
311
ac166700
HM
312inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
313{
314 writel(0, adapter->tgt_mask_reg);
315}
316
45ef92ed
HM
317inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
318{
319 writel(1, adapter->tgt_mask_reg);
320}
321
ac166700
HM
322/* Enable MSI-x and INT-x interrupts */
323void qlcnic_83xx_enable_intr(struct qlcnic_adapter *adapter,
324 struct qlcnic_host_sds_ring *sds_ring)
7f966452
SC
325{
326 writel(0, sds_ring->crb_intr_mask);
ac166700
HM
327}
328
329/* Disable MSI-x and INT-x interrupts */
330void qlcnic_83xx_disable_intr(struct qlcnic_adapter *adapter,
331 struct qlcnic_host_sds_ring *sds_ring)
332{
333 writel(1, sds_ring->crb_intr_mask);
334}
335
336inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
337 *adapter)
338{
339 u32 mask;
340
341 /* Mailbox in MSI-x mode and Legacy Interrupt share the same
342 * source register. We could be here before contexts are created
343 * and sds_ring->crb_intr_mask has not been initialized, calculate
344 * BAR offset for Interrupt Source Register
345 */
346 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
347 writel(0, adapter->ahw->pci_base0 + mask);
348}
349
f036e4f4 350void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
ac166700
HM
351{
352 u32 mask;
353
354 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
355 writel(1, adapter->ahw->pci_base0 + mask);
f036e4f4 356 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
7f966452
SC
357}
358
359static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
360 struct qlcnic_cmd_args *cmd)
361{
362 int i;
363 for (i = 0; i < cmd->rsp.num; i++)
364 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
365}
366
367irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
368{
369 u32 intr_val;
370 struct qlcnic_hardware_context *ahw = adapter->ahw;
371 int retries = 0;
372
373 intr_val = readl(adapter->tgt_status_reg);
374
375 if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
376 return IRQ_NONE;
377
378 if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
379 adapter->stats.spurious_intr++;
380 return IRQ_NONE;
381 }
ac166700
HM
382 /* The barrier is required to ensure writes to the registers */
383 wmb();
384
7f966452
SC
385 /* clear the interrupt trigger control register */
386 writel(0, adapter->isr_int_vec);
ac166700 387 intr_val = readl(adapter->isr_int_vec);
7f966452
SC
388 do {
389 intr_val = readl(adapter->tgt_status_reg);
390 if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
391 break;
392 retries++;
393 } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
394 (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
395
ac166700
HM
396 return IRQ_HANDLED;
397}
398
399static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
400{
401 u32 resp, event;
402 unsigned long flags;
403
404 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
405
406 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
407 if (!(resp & QLCNIC_SET_OWNER))
408 goto out;
409
410 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
411 if (event & QLCNIC_MBX_ASYNC_EVENT)
d1a1105e
RB
412 __qlcnic_83xx_process_aen(adapter);
413
ac166700
HM
414out:
415 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
416 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
417}
418
419irqreturn_t qlcnic_83xx_intr(int irq, void *data)
420{
421 struct qlcnic_adapter *adapter = data;
422 struct qlcnic_host_sds_ring *sds_ring;
423 struct qlcnic_hardware_context *ahw = adapter->ahw;
424
425 if (qlcnic_83xx_clear_legacy_intr(adapter) == IRQ_NONE)
7f966452 426 return IRQ_NONE;
ac166700
HM
427
428 qlcnic_83xx_poll_process_aen(adapter);
429
430 if (ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
431 ahw->diag_cnt++;
432 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
433 return IRQ_HANDLED;
7f966452
SC
434 }
435
ac166700
HM
436 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
437 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
438 } else {
439 sds_ring = &adapter->recv_ctx->sds_rings[0];
440 napi_schedule(&sds_ring->napi);
441 }
7f966452
SC
442
443 return IRQ_HANDLED;
444}
445
446irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
447{
448 struct qlcnic_host_sds_ring *sds_ring = data;
449 struct qlcnic_adapter *adapter = sds_ring->adapter;
450
451 if (adapter->flags & QLCNIC_MSIX_ENABLED)
452 goto done;
453
454 if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
455 return IRQ_NONE;
456
457done:
458 adapter->ahw->diag_cnt++;
459 qlcnic_83xx_enable_intr(adapter, sds_ring);
460
461 return IRQ_HANDLED;
462}
463
464void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
465{
f036e4f4
RB
466 u32 num_msix;
467
45ef92ed
HM
468 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
469 qlcnic_83xx_set_legacy_intr_mask(adapter);
470
f036e4f4 471 qlcnic_83xx_disable_mbx_intr(adapter);
7f966452 472
ac166700
HM
473 if (adapter->flags & QLCNIC_MSIX_ENABLED)
474 num_msix = adapter->ahw->num_msix - 1;
475 else
476 num_msix = 0;
7f966452 477
ac166700
HM
478 msleep(20);
479 synchronize_irq(adapter->msix_entries[num_msix].vector);
480 free_irq(adapter->msix_entries[num_msix].vector, adapter);
7f966452
SC
481}
482
483int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
484{
485 irq_handler_t handler;
486 u32 val;
7f966452
SC
487 int err = 0;
488 unsigned long flags = 0;
489
490 if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
491 !(adapter->flags & QLCNIC_MSIX_ENABLED))
492 flags |= IRQF_SHARED;
493
494 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
495 handler = qlcnic_83xx_handle_aen;
496 val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
aa2a8034 497 err = request_irq(val, handler, flags, "qlcnic-MB", adapter);
7f966452
SC
498 if (err) {
499 dev_err(&adapter->pdev->dev,
500 "failed to register MBX interrupt\n");
501 return err;
502 }
ac166700
HM
503 } else {
504 handler = qlcnic_83xx_intr;
505 val = adapter->msix_entries[0].vector;
506 err = request_irq(val, handler, flags, "qlcnic", adapter);
507 if (err) {
508 dev_err(&adapter->pdev->dev,
509 "failed to register INTx interrupt\n");
510 return err;
511 }
512 qlcnic_83xx_clear_legacy_intr_mask(adapter);
7f966452
SC
513 }
514
515 /* Enable mailbox interrupt */
516 qlcnic_83xx_enable_mbx_intrpt(adapter);
7f966452
SC
517
518 return err;
519}
520
521void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
522{
523 u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
f8468331 524 adapter->ahw->pci_func = (val >> 24) & 0xff;
7f966452
SC
525}
526
527int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
528{
529 void __iomem *addr;
530 u32 val, limit = 0;
531
532 struct qlcnic_hardware_context *ahw = adapter->ahw;
533
534 addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
535 do {
536 val = readl(addr);
537 if (val) {
538 /* write the function number to register */
539 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
540 ahw->pci_func);
541 return 0;
542 }
543 usleep_range(1000, 2000);
544 } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
545
546 return -EIO;
547}
548
549void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
550{
551 void __iomem *addr;
552 u32 val;
553 struct qlcnic_hardware_context *ahw = adapter->ahw;
554
555 addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
556 val = readl(addr);
557}
558
559void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
560 loff_t offset, size_t size)
561{
562 int ret;
563 u32 data;
564
565 if (qlcnic_api_lock(adapter)) {
566 dev_err(&adapter->pdev->dev,
567 "%s: failed to acquire lock. addr offset 0x%x\n",
568 __func__, (u32)offset);
569 return;
570 }
571
572 ret = qlcnic_83xx_rd_reg_indirect(adapter, (u32) offset);
573 qlcnic_api_unlock(adapter);
574
575 if (ret == -EIO) {
576 dev_err(&adapter->pdev->dev,
577 "%s: failed. addr offset 0x%x\n",
578 __func__, (u32)offset);
579 return;
580 }
581 data = ret;
582 memcpy(buf, &data, size);
583}
584
585void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
586 loff_t offset, size_t size)
587{
588 u32 data;
589
590 memcpy(&data, buf, size);
591 qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
592}
593
594int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
595{
596 int status;
597
598 status = qlcnic_83xx_get_port_config(adapter);
599 if (status) {
600 dev_err(&adapter->pdev->dev,
601 "Get Port Info failed\n");
602 } else {
603 if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
604 adapter->ahw->port_type = QLCNIC_XGBE;
605 else
606 adapter->ahw->port_type = QLCNIC_GBE;
629263ac 607
7f966452
SC
608 if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
609 adapter->ahw->link_autoneg = AUTONEG_ENABLE;
610 }
611 return status;
612}
613
52e493d0
JK
614void qlcnic_83xx_set_mac_filter_count(struct qlcnic_adapter *adapter)
615{
616 struct qlcnic_hardware_context *ahw = adapter->ahw;
617 u16 act_pci_fn = ahw->act_pci_func;
618 u16 count;
619
620 ahw->max_mc_count = QLC_83XX_MAX_MC_COUNT;
621 if (act_pci_fn <= 2)
622 count = (QLC_83XX_MAX_UC_COUNT - QLC_83XX_MAX_MC_COUNT) /
623 act_pci_fn;
624 else
625 count = (QLC_83XX_LB_MAX_FILTERS - QLC_83XX_MAX_MC_COUNT) /
626 act_pci_fn;
627 ahw->max_uc_count = count;
628}
629
7f966452
SC
630void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter)
631{
632 u32 val;
633
634 if (adapter->flags & QLCNIC_MSIX_ENABLED)
635 val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
636 else
637 val = BIT_2;
629263ac 638
7f966452 639 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
ac166700 640 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
7f966452
SC
641}
642
643void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
644 const struct pci_device_id *ent)
645{
646 u32 op_mode, priv_level;
647 struct qlcnic_hardware_context *ahw = adapter->ahw;
648
7f966452 649 ahw->fw_hal_version = 2;
7f966452
SC
650 qlcnic_get_func_no(adapter);
651
f8468331
RB
652 if (qlcnic_sriov_vf_check(adapter)) {
653 qlcnic_sriov_vf_set_ops(adapter);
654 return;
655 }
656
7f966452
SC
657 /* Determine function privilege level */
658 op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
659 if (op_mode == QLC_83XX_DEFAULT_OPMODE)
660 priv_level = QLCNIC_MGMT_FUNC;
661 else
662 priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
663 ahw->pci_func);
664
665 if (priv_level == QLCNIC_NON_PRIV_FUNC) {
666 ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
667 dev_info(&adapter->pdev->dev,
668 "HAL Version: %d Non Privileged function\n",
669 ahw->fw_hal_version);
670 adapter->nic_ops = &qlcnic_vf_ops;
671 } else {
02feda17
RB
672 if (pci_find_ext_capability(adapter->pdev,
673 PCI_EXT_CAP_ID_SRIOV))
674 set_bit(__QLCNIC_SRIOV_CAPABLE, &adapter->state);
7f966452
SC
675 adapter->nic_ops = &qlcnic_83xx_ops;
676 }
677}
678
679static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
680 u32 data[]);
681static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
682 u32 data[]);
683
684static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
685 struct qlcnic_cmd_args *cmd)
686{
687 int i;
688
689 dev_info(&adapter->pdev->dev,
690 "Host MBX regs(%d)\n", cmd->req.num);
691 for (i = 0; i < cmd->req.num; i++) {
692 if (i && !(i % 8))
693 pr_info("\n");
694 pr_info("%08x ", cmd->req.arg[i]);
695 }
696 pr_info("\n");
697 dev_info(&adapter->pdev->dev,
698 "FW MBX regs(%d)\n", cmd->rsp.num);
699 for (i = 0; i < cmd->rsp.num; i++) {
700 if (i && !(i % 8))
701 pr_info("\n");
702 pr_info("%08x ", cmd->rsp.arg[i]);
703 }
704 pr_info("\n");
705}
706
65ab999d 707/* Mailbox response for mac rcode */
f197a7aa 708u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
65ab999d
JK
709{
710 u32 fw_data;
711 u8 mac_cmd_rcode;
712
713 fw_data = readl(QLCNIC_MBX_FW(adapter->ahw, 2));
714 mac_cmd_rcode = (u8)fw_data;
715 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
716 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
717 mac_cmd_rcode == QLC_83XX_MAC_ABSENT)
718 return QLCNIC_RCODE_SUCCESS;
719 return 1;
720}
721
9106e5db 722u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time)
7f966452
SC
723{
724 u32 data;
7f966452
SC
725 struct qlcnic_hardware_context *ahw = adapter->ahw;
726 /* wait for mailbox completion */
727 do {
728 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
9106e5db 729 if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) {
7f966452
SC
730 data = QLCNIC_RCODE_TIMEOUT;
731 break;
732 }
733 mdelay(1);
734 } while (!data);
735 return data;
736}
737
738int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
739 struct qlcnic_cmd_args *cmd)
740{
741 int i;
742 u16 opcode;
65ab999d 743 u8 mbx_err_code;
ac166700 744 unsigned long flags;
7f966452 745 struct qlcnic_hardware_context *ahw = adapter->ahw;
9106e5db 746 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0;
7f966452
SC
747
748 opcode = LSW(cmd->req.arg[0]);
629263ac
SC
749 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
750 dev_info(&adapter->pdev->dev,
751 "Mailbox cmd attempted, 0x%x\n", opcode);
752 dev_info(&adapter->pdev->dev, "Mailbox detached\n");
753 return 0;
754 }
755
ac166700 756 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
7f966452
SC
757 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
758
759 if (mbx_val) {
760 QLCDB(adapter, DRV,
761 "Mailbox cmd attempted, 0x%x\n", opcode);
762 QLCDB(adapter, DRV,
763 "Mailbox not available, 0x%x, collect FW dump\n",
764 mbx_val);
765 cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
ac166700 766 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
7f966452
SC
767 return cmd->rsp.arg[0];
768 }
769
770 /* Fill in mailbox registers */
771 mbx_cmd = cmd->req.arg[0];
772 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
773 for (i = 1; i < cmd->req.num; i++)
774 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
775
776 /* Signal FW about the impending command */
777 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
778poll:
9106e5db 779 rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
7f966452 780 if (rsp != QLCNIC_RCODE_TIMEOUT) {
65ab999d
JK
781 /* Get the FW response data */
782 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
483202d5 783 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
d1a1105e 784 __qlcnic_83xx_process_aen(adapter);
9106e5db 785 goto poll;
65ab999d
JK
786 }
787 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
788 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
789 opcode = QLCNIC_MBX_RSP(fw_data);
790 qlcnic_83xx_get_mbx_data(adapter, cmd);
791
792 switch (mbx_err_code) {
793 case QLCNIC_MBX_RSP_OK:
794 case QLCNIC_MBX_PORT_RSP_OK:
7f966452 795 rsp = QLCNIC_RCODE_SUCCESS;
65ab999d
JK
796 break;
797 default:
7f966452 798 if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
65ab999d
JK
799 rsp = qlcnic_83xx_mac_rcode(adapter);
800 if (!rsp)
7f966452 801 goto out;
7f966452 802 }
65ab999d
JK
803 dev_err(&adapter->pdev->dev,
804 "MBX command 0x%x failed with err:0x%x\n",
805 opcode, mbx_err_code);
7f966452
SC
806 rsp = mbx_err_code;
807 qlcnic_dump_mbx(adapter, cmd);
65ab999d 808 break;
7f966452 809 }
65ab999d 810 goto out;
7f966452 811 }
65ab999d
JK
812
813 dev_err(&adapter->pdev->dev, "MBX command 0x%x timed out\n",
814 QLCNIC_MBX_RSP(mbx_cmd));
815 rsp = QLCNIC_RCODE_TIMEOUT;
7f966452
SC
816out:
817 /* clear fw mbx control register */
818 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
ac166700 819 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
7f966452
SC
820 return rsp;
821}
822
823int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
824 struct qlcnic_adapter *adapter, u32 type)
825{
826 int i, size;
827 u32 temp;
828 const struct qlcnic_mailbox_metadata *mbx_tbl;
829
830 mbx_tbl = qlcnic_83xx_mbx_tbl;
831 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
832 for (i = 0; i < size; i++) {
833 if (type == mbx_tbl[i].cmd) {
f197a7aa 834 mbx->op_type = QLC_83XX_FW_MBX_CMD;
7f966452
SC
835 mbx->req.num = mbx_tbl[i].in_args;
836 mbx->rsp.num = mbx_tbl[i].out_args;
837 mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
838 GFP_ATOMIC);
839 if (!mbx->req.arg)
840 return -ENOMEM;
841 mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
842 GFP_ATOMIC);
843 if (!mbx->rsp.arg) {
844 kfree(mbx->req.arg);
845 mbx->req.arg = NULL;
846 return -ENOMEM;
847 }
848 memset(mbx->req.arg, 0, sizeof(u32) * mbx->req.num);
849 memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
850 temp = adapter->ahw->fw_hal_version << 29;
851 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
f197a7aa 852 return 0;
7f966452
SC
853 }
854 }
f197a7aa 855 return -EINVAL;
7f966452
SC
856}
857
858void qlcnic_83xx_idc_aen_work(struct work_struct *work)
859{
860 struct qlcnic_adapter *adapter;
861 struct qlcnic_cmd_args cmd;
862 int i, err = 0;
863
864 adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
b6b4316c
SS
865 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
866 if (err)
867 return;
7f966452
SC
868
869 for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
870 cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
871
872 err = qlcnic_issue_cmd(adapter, &cmd);
873 if (err)
874 dev_info(&adapter->pdev->dev,
875 "%s: Mailbox IDC ACK failed.\n", __func__);
876 qlcnic_free_mbx_args(&cmd);
877}
878
879static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
880 u32 data[])
881{
882 dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
883 QLCNIC_MBX_RSP(data[0]));
629263ac 884 clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
7f966452
SC
885 return;
886}
887
d1a1105e 888void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
7f966452 889{
483202d5 890 u32 event[QLC_83XX_MBX_AEN_CNT];
7f966452
SC
891 int i;
892 struct qlcnic_hardware_context *ahw = adapter->ahw;
893
7f966452
SC
894 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
895 event[i] = readl(QLCNIC_MBX_FW(ahw, i));
896
897 switch (QLCNIC_MBX_RSP(event[0])) {
898
899 case QLCNIC_MBX_LINK_EVENT:
900 qlcnic_83xx_handle_link_aen(adapter, event);
901 break;
902 case QLCNIC_MBX_COMP_EVENT:
903 qlcnic_83xx_handle_idc_comp_aen(adapter, event);
904 break;
905 case QLCNIC_MBX_REQUEST_EVENT:
906 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
907 adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
908 queue_delayed_work(adapter->qlcnic_wq,
909 &adapter->idc_aen_work, 0);
910 break;
911 case QLCNIC_MBX_TIME_EXTEND_EVENT:
912 break;
f197a7aa
RB
913 case QLCNIC_MBX_BC_EVENT:
914 qlcnic_sriov_handle_bc_event(adapter, event[1]);
915 break;
7f966452
SC
916 case QLCNIC_MBX_SFP_INSERT_EVENT:
917 dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
918 QLCNIC_MBX_RSP(event[0]));
919 break;
920 case QLCNIC_MBX_SFP_REMOVE_EVENT:
921 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
922 QLCNIC_MBX_RSP(event[0]));
923 break;
924 default:
925 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
926 QLCNIC_MBX_RSP(event[0]));
927 break;
928 }
929
930 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
7f966452
SC
931}
932
d1a1105e
RB
933static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
934{
935 struct qlcnic_hardware_context *ahw = adapter->ahw;
936 u32 resp, event;
937 unsigned long flags;
938
939 spin_lock_irqsave(&ahw->mbx_lock, flags);
940
941 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
942 if (resp & QLCNIC_SET_OWNER) {
943 event = readl(QLCNIC_MBX_FW(ahw, 0));
944 if (event & QLCNIC_MBX_ASYNC_EVENT)
945 __qlcnic_83xx_process_aen(adapter);
946 }
947
948 spin_unlock_irqrestore(&ahw->mbx_lock, flags);
949}
950
7ed3ce48
RB
951static void qlcnic_83xx_mbx_poll_work(struct work_struct *work)
952{
953 struct qlcnic_adapter *adapter;
954
955 adapter = container_of(work, struct qlcnic_adapter, mbx_poll_work.work);
956
957 if (!test_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
958 return;
959
960 qlcnic_83xx_process_aen(adapter);
961 queue_delayed_work(adapter->qlcnic_wq, &adapter->mbx_poll_work,
962 (HZ / 10));
963}
964
965void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *adapter)
966{
967 if (test_and_set_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
968 return;
969
970 INIT_DELAYED_WORK(&adapter->mbx_poll_work, qlcnic_83xx_mbx_poll_work);
971}
972
973void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *adapter)
974{
975 if (!test_and_clear_bit(__QLCNIC_MBX_POLL_ENABLE, &adapter->state))
976 return;
977 cancel_delayed_work_sync(&adapter->mbx_poll_work);
978}
979
7f966452
SC
980static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
981{
982 int index, i, err, sds_mbx_size;
983 u32 *buf, intrpt_id, intr_mask;
984 u16 context_id;
985 u8 num_sds;
986 struct qlcnic_cmd_args cmd;
987 struct qlcnic_host_sds_ring *sds;
988 struct qlcnic_sds_mbx sds_mbx;
989 struct qlcnic_add_rings_mbx_out *mbx_out;
990 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
991 struct qlcnic_hardware_context *ahw = adapter->ahw;
992
993 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
994 context_id = recv_ctx->context_id;
995 num_sds = (adapter->max_sds_rings - QLCNIC_MAX_RING_SETS);
996 ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
997 QLCNIC_CMD_ADD_RCV_RINGS);
998 cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
999
1000 /* set up status rings, mbx 2-81 */
1001 index = 2;
1002 for (i = 8; i < adapter->max_sds_rings; i++) {
1003 memset(&sds_mbx, 0, sds_mbx_size);
1004 sds = &recv_ctx->sds_rings[i];
1005 sds->consumer = 0;
1006 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
a96227e6
SS
1007 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1008 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
7f966452
SC
1009 sds_mbx.sds_ring_size = sds->num_desc;
1010
1011 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1012 intrpt_id = ahw->intr_tbl[i].id;
1013 else
1014 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1015
1016 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1017 sds_mbx.intrpt_id = intrpt_id;
1018 else
1019 sds_mbx.intrpt_id = 0xffff;
1020 sds_mbx.intrpt_val = 0;
1021 buf = &cmd.req.arg[index];
1022 memcpy(buf, &sds_mbx, sds_mbx_size);
1023 index += sds_mbx_size / sizeof(u32);
1024 }
1025
1026 /* send the mailbox command */
1027 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1028 if (err) {
1029 dev_err(&adapter->pdev->dev,
1030 "Failed to add rings %d\n", err);
1031 goto out;
1032 }
1033
1034 mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
1035 index = 0;
1036 /* status descriptor ring */
1037 for (i = 8; i < adapter->max_sds_rings; i++) {
1038 sds = &recv_ctx->sds_rings[i];
1039 sds->crb_sts_consumer = ahw->pci_base0 +
1040 mbx_out->host_csmr[index];
1041 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1042 intr_mask = ahw->intr_tbl[i].src;
1043 else
1044 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1045
1046 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1047 index++;
1048 }
1049out:
1050 qlcnic_free_mbx_args(&cmd);
1051 return err;
1052}
1053
7cb03b23
RB
1054void qlcnic_83xx_del_rx_ctx(struct qlcnic_adapter *adapter)
1055{
1056 int err;
1057 u32 temp = 0;
1058 struct qlcnic_cmd_args cmd;
1059 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1060
1061 if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX))
1062 return;
1063
1064 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1065 cmd.req.arg[0] |= (0x3 << 29);
1066
1067 if (qlcnic_sriov_pf_check(adapter))
1068 qlcnic_pf_set_interface_id_del_rx_ctx(adapter, &temp);
1069
1070 cmd.req.arg[1] = recv_ctx->context_id | temp;
1071 err = qlcnic_issue_cmd(adapter, &cmd);
1072 if (err)
1073 dev_err(&adapter->pdev->dev,
1074 "Failed to destroy rx ctx in firmware\n");
1075
1076 recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
1077 qlcnic_free_mbx_args(&cmd);
1078}
1079
7f966452
SC
1080int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
1081{
1082 int i, err, index, sds_mbx_size, rds_mbx_size;
1083 u8 num_sds, num_rds;
1084 u32 *buf, intrpt_id, intr_mask, cap = 0;
1085 struct qlcnic_host_sds_ring *sds;
1086 struct qlcnic_host_rds_ring *rds;
1087 struct qlcnic_sds_mbx sds_mbx;
1088 struct qlcnic_rds_mbx rds_mbx;
1089 struct qlcnic_cmd_args cmd;
1090 struct qlcnic_rcv_mbx_out *mbx_out;
1091 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
1092 struct qlcnic_hardware_context *ahw = adapter->ahw;
1093 num_rds = adapter->max_rds_rings;
1094
1095 if (adapter->max_sds_rings <= QLCNIC_MAX_RING_SETS)
1096 num_sds = adapter->max_sds_rings;
1097 else
1098 num_sds = QLCNIC_MAX_RING_SETS;
1099
1100 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
1101 rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
1102 cap = QLCNIC_CAP0_LEGACY_CONTEXT;
1103
1104 if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
1105 cap |= QLC_83XX_FW_CAP_LRO_MSS;
1106
1107 /* set mailbox hdr and capabilities */
b6b4316c
SS
1108 err = qlcnic_alloc_mbx_args(&cmd, adapter,
1109 QLCNIC_CMD_CREATE_RX_CTX);
1110 if (err)
1111 return err;
7cb03b23
RB
1112
1113 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1114 cmd.req.arg[0] |= (0x3 << 29);
1115
7f966452
SC
1116 cmd.req.arg[1] = cap;
1117 cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
1118 (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
7cb03b23
RB
1119
1120 if (qlcnic_sriov_pf_check(adapter))
1121 qlcnic_pf_set_interface_id_create_rx_ctx(adapter,
1122 &cmd.req.arg[6]);
7f966452
SC
1123 /* set up status rings, mbx 8-57/87 */
1124 index = QLC_83XX_HOST_SDS_MBX_IDX;
1125 for (i = 0; i < num_sds; i++) {
1126 memset(&sds_mbx, 0, sds_mbx_size);
1127 sds = &recv_ctx->sds_rings[i];
1128 sds->consumer = 0;
1129 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
a96227e6
SS
1130 sds_mbx.phy_addr_low = LSD(sds->phys_addr);
1131 sds_mbx.phy_addr_high = MSD(sds->phys_addr);
7f966452
SC
1132 sds_mbx.sds_ring_size = sds->num_desc;
1133 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1134 intrpt_id = ahw->intr_tbl[i].id;
1135 else
1136 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1137 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1138 sds_mbx.intrpt_id = intrpt_id;
1139 else
1140 sds_mbx.intrpt_id = 0xffff;
1141 sds_mbx.intrpt_val = 0;
1142 buf = &cmd.req.arg[index];
1143 memcpy(buf, &sds_mbx, sds_mbx_size);
1144 index += sds_mbx_size / sizeof(u32);
1145 }
1146 /* set up receive rings, mbx 88-111/135 */
1147 index = QLCNIC_HOST_RDS_MBX_IDX;
1148 rds = &recv_ctx->rds_rings[0];
1149 rds->producer = 0;
1150 memset(&rds_mbx, 0, rds_mbx_size);
a96227e6
SS
1151 rds_mbx.phy_addr_reg_low = LSD(rds->phys_addr);
1152 rds_mbx.phy_addr_reg_high = MSD(rds->phys_addr);
7f966452
SC
1153 rds_mbx.reg_ring_sz = rds->dma_size;
1154 rds_mbx.reg_ring_len = rds->num_desc;
1155 /* Jumbo ring */
1156 rds = &recv_ctx->rds_rings[1];
1157 rds->producer = 0;
a96227e6
SS
1158 rds_mbx.phy_addr_jmb_low = LSD(rds->phys_addr);
1159 rds_mbx.phy_addr_jmb_high = MSD(rds->phys_addr);
7f966452
SC
1160 rds_mbx.jmb_ring_sz = rds->dma_size;
1161 rds_mbx.jmb_ring_len = rds->num_desc;
1162 buf = &cmd.req.arg[index];
1163 memcpy(buf, &rds_mbx, rds_mbx_size);
1164
1165 /* send the mailbox command */
1166 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1167 if (err) {
1168 dev_err(&adapter->pdev->dev,
1169 "Failed to create Rx ctx in firmware%d\n", err);
1170 goto out;
1171 }
1172 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1173 recv_ctx->context_id = mbx_out->ctx_id;
1174 recv_ctx->state = mbx_out->state;
1175 recv_ctx->virt_port = mbx_out->vport_id;
1176 dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1177 recv_ctx->context_id, recv_ctx->state);
1178 /* Receive descriptor ring */
1179 /* Standard ring */
1180 rds = &recv_ctx->rds_rings[0];
1181 rds->crb_rcv_producer = ahw->pci_base0 +
1182 mbx_out->host_prod[0].reg_buf;
1183 /* Jumbo ring */
1184 rds = &recv_ctx->rds_rings[1];
1185 rds->crb_rcv_producer = ahw->pci_base0 +
1186 mbx_out->host_prod[0].jmb_buf;
1187 /* status descriptor ring */
1188 for (i = 0; i < num_sds; i++) {
1189 sds = &recv_ctx->sds_rings[i];
1190 sds->crb_sts_consumer = ahw->pci_base0 +
1191 mbx_out->host_csmr[i];
1192 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1193 intr_mask = ahw->intr_tbl[i].src;
1194 else
1195 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1196 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1197 }
1198
1199 if (adapter->max_sds_rings > QLCNIC_MAX_RING_SETS)
1200 err = qlcnic_83xx_add_rings(adapter);
1201out:
1202 qlcnic_free_mbx_args(&cmd);
1203 return err;
1204}
1205
7cb03b23
RB
1206void qlcnic_83xx_del_tx_ctx(struct qlcnic_adapter *adapter,
1207 struct qlcnic_host_tx_ring *tx_ring)
1208{
1209 struct qlcnic_cmd_args cmd;
1210 u32 temp = 0;
1211
1212 if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX))
1213 return;
1214
1215 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1216 cmd.req.arg[0] |= (0x3 << 29);
1217
1218 if (qlcnic_sriov_pf_check(adapter))
1219 qlcnic_pf_set_interface_id_del_tx_ctx(adapter, &temp);
1220
1221 cmd.req.arg[1] = tx_ring->ctx_id | temp;
1222 if (qlcnic_issue_cmd(adapter, &cmd))
1223 dev_err(&adapter->pdev->dev,
1224 "Failed to destroy tx ctx in firmware\n");
1225 qlcnic_free_mbx_args(&cmd);
1226}
1227
7f966452
SC
1228int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1229 struct qlcnic_host_tx_ring *tx, int ring)
1230{
1231 int err;
1232 u16 msix_id;
7cb03b23 1233 u32 *buf, intr_mask, temp = 0;
7f966452
SC
1234 struct qlcnic_cmd_args cmd;
1235 struct qlcnic_tx_mbx mbx;
1236 struct qlcnic_tx_mbx_out *mbx_out;
1237 struct qlcnic_hardware_context *ahw = adapter->ahw;
da6c8063 1238 u32 msix_vector;
7f966452
SC
1239
1240 /* Reset host resources */
1241 tx->producer = 0;
1242 tx->sw_consumer = 0;
1243 *(tx->hw_consumer) = 0;
1244
1245 memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1246
1247 /* setup mailbox inbox registerss */
a96227e6
SS
1248 mbx.phys_addr_low = LSD(tx->phys_addr);
1249 mbx.phys_addr_high = MSD(tx->phys_addr);
1250 mbx.cnsmr_index_low = LSD(tx->hw_cons_phys_addr);
1251 mbx.cnsmr_index_high = MSD(tx->hw_cons_phys_addr);
7f966452 1252 mbx.size = tx->num_desc;
da6c8063
RB
1253 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1254 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
1255 msix_vector = adapter->max_sds_rings + ring;
1256 else
1257 msix_vector = adapter->max_sds_rings - 1;
1258 msix_id = ahw->intr_tbl[msix_vector].id;
1259 } else {
7f966452 1260 msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
da6c8063
RB
1261 }
1262
7f966452
SC
1263 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1264 mbx.intr_id = msix_id;
1265 else
1266 mbx.intr_id = 0xffff;
1267 mbx.src = 0;
1268
b6b4316c
SS
1269 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1270 if (err)
1271 return err;
7cb03b23
RB
1272
1273 if (qlcnic_sriov_pf_check(adapter) || qlcnic_sriov_vf_check(adapter))
1274 cmd.req.arg[0] |= (0x3 << 29);
1275
1276 if (qlcnic_sriov_pf_check(adapter))
1277 qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);
1278
7f966452 1279 cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
7cb03b23 1280 cmd.req.arg[5] = QLCNIC_MAX_TX_QUEUES | temp;
7f966452
SC
1281 buf = &cmd.req.arg[6];
1282 memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1283 /* send the mailbox command*/
1284 err = qlcnic_issue_cmd(adapter, &cmd);
1285 if (err) {
1286 dev_err(&adapter->pdev->dev,
1287 "Failed to create Tx ctx in firmware 0x%x\n", err);
1288 goto out;
1289 }
1290 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1291 tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1292 tx->ctx_id = mbx_out->ctx_id;
da6c8063
RB
1293 if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
1294 !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
7f966452
SC
1295 intr_mask = ahw->intr_tbl[adapter->max_sds_rings + ring].src;
1296 tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1297 }
1298 dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n",
1299 tx->ctx_id, mbx_out->state);
1300out:
1301 qlcnic_free_mbx_args(&cmd);
1302 return err;
1303}
1304
13a82b44
MC
1305static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1306 int num_sds_ring)
ba4468db
JK
1307{
1308 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1309 struct qlcnic_host_sds_ring *sds_ring;
1310 struct qlcnic_host_rds_ring *rds_ring;
13a82b44 1311 u16 adapter_state = adapter->is_up;
ba4468db
JK
1312 u8 ring;
1313 int ret;
1314
1315 netif_device_detach(netdev);
1316
1317 if (netif_running(netdev))
1318 __qlcnic_down(adapter, netdev);
1319
1320 qlcnic_detach(adapter);
1321
1322 adapter->max_sds_rings = 1;
1323 adapter->ahw->diag_test = test;
1324 adapter->ahw->linkup = 0;
1325
1326 ret = qlcnic_attach(adapter);
1327 if (ret) {
1328 netif_device_attach(netdev);
1329 return ret;
1330 }
1331
1332 ret = qlcnic_fw_create_ctx(adapter);
1333 if (ret) {
1334 qlcnic_detach(adapter);
13a82b44
MC
1335 if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
1336 adapter->max_sds_rings = num_sds_ring;
1337 qlcnic_attach(adapter);
1338 }
ba4468db
JK
1339 netif_device_attach(netdev);
1340 return ret;
1341 }
1342
1343 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
1344 rds_ring = &adapter->recv_ctx->rds_rings[ring];
1345 qlcnic_post_rx_buffers(adapter, rds_ring, ring);
1346 }
1347
1348 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1349 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1350 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1351 qlcnic_83xx_enable_intr(adapter, sds_ring);
1352 }
1353 }
1354
1355 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1356 /* disable and free mailbox interrupt */
d1a1105e
RB
1357 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1358 qlcnic_83xx_free_mbx_intr(adapter);
ba4468db
JK
1359 adapter->ahw->loopback_state = 0;
1360 adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1361 }
1362
1363 set_bit(__QLCNIC_DEV_UP, &adapter->state);
1364 return 0;
1365}
1366
1367static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1368 int max_sds_rings)
1369{
1370 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1371 struct qlcnic_host_sds_ring *sds_ring;
1372 int ring, err;
1373
1374 clear_bit(__QLCNIC_DEV_UP, &adapter->state);
1375 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1376 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
1377 sds_ring = &adapter->recv_ctx->sds_rings[ring];
ac166700 1378 qlcnic_83xx_disable_intr(adapter, sds_ring);
ba4468db
JK
1379 }
1380 }
1381
1382 qlcnic_fw_destroy_ctx(adapter);
1383 qlcnic_detach(adapter);
1384
1385 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
d1a1105e
RB
1386 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
1387 err = qlcnic_83xx_setup_mbx_intr(adapter);
1388 if (err) {
1389 dev_err(&adapter->pdev->dev,
1390 "%s: failed to setup mbx interrupt\n",
1391 __func__);
1392 goto out;
1393 }
ba4468db
JK
1394 }
1395 }
1396 adapter->ahw->diag_test = 0;
1397 adapter->max_sds_rings = max_sds_rings;
1398
1399 if (qlcnic_attach(adapter))
1400 goto out;
1401
1402 if (netif_running(netdev))
1403 __qlcnic_up(adapter, netdev);
1404out:
1405 netif_device_attach(netdev);
1406}
1407
319ecf12
SC
1408int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
1409 u32 beacon)
1410{
1411 struct qlcnic_cmd_args cmd;
1412 u32 mbx_in;
1413 int i, status = 0;
1414
1415 if (state) {
1416 /* Get LED configuration */
b6b4316c
SS
1417 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1418 QLCNIC_CMD_GET_LED_CONFIG);
1419 if (status)
1420 return status;
1421
319ecf12
SC
1422 status = qlcnic_issue_cmd(adapter, &cmd);
1423 if (status) {
1424 dev_err(&adapter->pdev->dev,
1425 "Get led config failed.\n");
1426 goto mbx_err;
1427 } else {
1428 for (i = 0; i < 4; i++)
1429 adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1];
1430 }
1431 qlcnic_free_mbx_args(&cmd);
1432 /* Set LED Configuration */
1433 mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
1434 LSW(QLC_83XX_LED_CONFIG);
b6b4316c
SS
1435 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1436 QLCNIC_CMD_SET_LED_CONFIG);
1437 if (status)
1438 return status;
1439
319ecf12
SC
1440 cmd.req.arg[1] = mbx_in;
1441 cmd.req.arg[2] = mbx_in;
1442 cmd.req.arg[3] = mbx_in;
1443 if (beacon)
1444 cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON;
1445 status = qlcnic_issue_cmd(adapter, &cmd);
1446 if (status) {
1447 dev_err(&adapter->pdev->dev,
1448 "Set led config failed.\n");
1449 }
1450mbx_err:
1451 qlcnic_free_mbx_args(&cmd);
1452 return status;
1453
1454 } else {
1455 /* Restoring default LED configuration */
b6b4316c
SS
1456 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1457 QLCNIC_CMD_SET_LED_CONFIG);
1458 if (status)
1459 return status;
1460
319ecf12
SC
1461 cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
1462 cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
1463 cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
1464 if (beacon)
1465 cmd.req.arg[4] = adapter->ahw->mbox_reg[3];
1466 status = qlcnic_issue_cmd(adapter, &cmd);
1467 if (status)
1468 dev_err(&adapter->pdev->dev,
1469 "Restoring led config failed.\n");
1470 qlcnic_free_mbx_args(&cmd);
1471 return status;
1472 }
1473}
1474
d16951d9
HM
1475int qlcnic_83xx_set_led(struct net_device *netdev,
1476 enum ethtool_phys_id_state state)
1477{
1478 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1479 int err = -EIO, active = 1;
1480
1481 if (adapter->ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
1482 netdev_warn(netdev,
1483 "LED test is not supported in non-privileged mode\n");
1484 return -EOPNOTSUPP;
1485 }
1486
1487 switch (state) {
1488 case ETHTOOL_ID_ACTIVE:
1489 if (test_and_set_bit(__QLCNIC_LED_ENABLE, &adapter->state))
1490 return -EBUSY;
1491
1492 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1493 break;
1494
1495 err = qlcnic_83xx_config_led(adapter, active, 0);
1496 if (err)
1497 netdev_err(netdev, "Failed to set LED blink state\n");
1498 break;
1499 case ETHTOOL_ID_INACTIVE:
1500 active = 0;
1501
1502 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
1503 break;
1504
1505 err = qlcnic_83xx_config_led(adapter, active, 0);
1506 if (err)
1507 netdev_err(netdev, "Failed to reset LED blink state\n");
1508 break;
1509
1510 default:
1511 return -EINVAL;
1512 }
1513
1514 if (!active || err)
1515 clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
1516
1517 return err;
1518}
1519
7f966452
SC
1520void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter,
1521 int enable)
1522{
1523 struct qlcnic_cmd_args cmd;
1524 int status;
1525
f8468331
RB
1526 if (qlcnic_sriov_vf_check(adapter))
1527 return;
1528
7f966452 1529 if (enable) {
b6b4316c
SS
1530 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1531 QLCNIC_CMD_INIT_NIC_FUNC);
1532 if (status)
1533 return;
1534
d5fcff04 1535 cmd.req.arg[1] = BIT_0 | BIT_31;
7f966452 1536 } else {
b6b4316c
SS
1537 status = qlcnic_alloc_mbx_args(&cmd, adapter,
1538 QLCNIC_CMD_STOP_NIC_FUNC);
1539 if (status)
1540 return;
1541
d5fcff04 1542 cmd.req.arg[1] = BIT_0 | BIT_31;
7f966452
SC
1543 }
1544 status = qlcnic_issue_cmd(adapter, &cmd);
1545 if (status)
1546 dev_err(&adapter->pdev->dev,
1547 "Failed to %s in NIC IDC function event.\n",
1548 (enable ? "register" : "unregister"));
1549
1550 qlcnic_free_mbx_args(&cmd);
1551}
1552
1553int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1554{
1555 struct qlcnic_cmd_args cmd;
1556 int err;
1557
b6b4316c
SS
1558 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1559 if (err)
1560 return err;
1561
7f966452
SC
1562 cmd.req.arg[1] = adapter->ahw->port_config;
1563 err = qlcnic_issue_cmd(adapter, &cmd);
1564 if (err)
1565 dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1566 qlcnic_free_mbx_args(&cmd);
1567 return err;
1568}
1569
1570int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1571{
1572 struct qlcnic_cmd_args cmd;
1573 int err;
1574
b6b4316c
SS
1575 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1576 if (err)
1577 return err;
1578
7f966452
SC
1579 err = qlcnic_issue_cmd(adapter, &cmd);
1580 if (err)
1581 dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1582 else
1583 adapter->ahw->port_config = cmd.rsp.arg[1];
1584 qlcnic_free_mbx_args(&cmd);
1585 return err;
1586}
1587
1588int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1589{
1590 int err;
1591 u32 temp;
1592 struct qlcnic_cmd_args cmd;
1593
b6b4316c
SS
1594 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1595 if (err)
1596 return err;
1597
7f966452
SC
1598 temp = adapter->recv_ctx->context_id << 16;
1599 cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1600 err = qlcnic_issue_cmd(adapter, &cmd);
1601 if (err)
1602 dev_info(&adapter->pdev->dev,
1603 "Setup linkevent mailbox failed\n");
1604 qlcnic_free_mbx_args(&cmd);
1605 return err;
1606}
1607
7cb03b23
RB
1608static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1609 u32 *interface_id)
1610{
1611 if (qlcnic_sriov_pf_check(adapter)) {
1612 qlcnic_pf_set_interface_id_promisc(adapter, interface_id);
1613 } else {
1614 if (!qlcnic_sriov_vf_check(adapter))
1615 *interface_id = adapter->recv_ctx->context_id << 16;
1616 }
1617}
1618
7f966452
SC
1619int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1620{
1621 int err;
7cb03b23 1622 u32 temp = 0;
7f966452
SC
1623 struct qlcnic_cmd_args cmd;
1624
1625 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1626 return -EIO;
1627
b6b4316c
SS
1628 err = qlcnic_alloc_mbx_args(&cmd, adapter,
1629 QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1630 if (err)
1631 return err;
1632
7cb03b23 1633 qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
7f966452
SC
1634 cmd.req.arg[1] = (mode ? 1 : 0) | temp;
1635 err = qlcnic_issue_cmd(adapter, &cmd);
1636 if (err)
1637 dev_info(&adapter->pdev->dev,
1638 "Promiscous mode config failed\n");
7f966452 1639
7cb03b23 1640 qlcnic_free_mbx_args(&cmd);
7f966452
SC
1641 return err;
1642}
1643
ba4468db
JK
1644int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1645{
1646 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1647 struct qlcnic_hardware_context *ahw = adapter->ahw;
1648 int ret = 0, loop = 0, max_sds_rings = adapter->max_sds_rings;
1649
ba4468db 1650 if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
4690a7e4
SC
1651 netdev_warn(netdev,
1652 "Loopback test not supported in non privileged mode\n");
ba4468db
JK
1653 return ret;
1654 }
1655
4690a7e4
SC
1656 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1657 netdev_info(netdev, "Device is resetting\n");
ba4468db 1658 return -EBUSY;
4690a7e4
SC
1659 }
1660
1661 if (qlcnic_get_diag_lock(adapter)) {
1662 netdev_info(netdev, "Device is in diagnostics mode\n");
1663 return -EBUSY;
1664 }
1665
1666 netdev_info(netdev, "%s loopback test in progress\n",
1667 mode == QLCNIC_ILB_MODE ? "internal" : "external");
ba4468db 1668
13a82b44
MC
1669 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
1670 max_sds_rings);
ba4468db
JK
1671 if (ret)
1672 goto fail_diag_alloc;
1673
1674 ret = qlcnic_83xx_set_lb_mode(adapter, mode);
1675 if (ret)
1676 goto free_diag_res;
1677
1678 /* Poll for link up event before running traffic */
1679 do {
2c4a7878 1680 msleep(QLC_83XX_LB_MSLEEP_COUNT);
d1a1105e
RB
1681 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1682 qlcnic_83xx_process_aen(adapter);
1683
2c4a7878
JK
1684 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1685 netdev_info(netdev,
1686 "Device is resetting, free LB test resources\n");
1687 ret = -EIO;
1688 goto free_diag_res;
1689 }
1690 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1691 netdev_info(netdev,
1692 "Firmware didn't sent link up event to loopback request\n");
ba4468db
JK
1693 ret = -QLCNIC_FW_NOT_RESPOND;
1694 qlcnic_83xx_clear_lb_mode(adapter, mode);
1695 goto free_diag_res;
1696 }
1697 } while ((adapter->ahw->linkup && ahw->has_link_events) != 1);
1698
a4325ea2
JK
1699 /* Make sure carrier is off and queue is stopped during loopback */
1700 if (netif_running(netdev)) {
1701 netif_carrier_off(netdev);
1702 netif_stop_queue(netdev);
1703 }
1704
ba4468db
JK
1705 ret = qlcnic_do_lb_test(adapter, mode);
1706
1707 qlcnic_83xx_clear_lb_mode(adapter, mode);
1708
1709free_diag_res:
1710 qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
1711
1712fail_diag_alloc:
1713 adapter->max_sds_rings = max_sds_rings;
4690a7e4 1714 qlcnic_release_diag_lock(adapter);
ba4468db
JK
1715 return ret;
1716}
1717
7f966452
SC
1718int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1719{
1720 struct qlcnic_hardware_context *ahw = adapter->ahw;
2c4a7878 1721 struct net_device *netdev = adapter->netdev;
629263ac 1722 int status = 0, loop = 0;
7f966452
SC
1723 u32 config;
1724
1725 status = qlcnic_83xx_get_port_config(adapter);
1726 if (status)
1727 return status;
1728
1729 config = ahw->port_config;
629263ac 1730 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1731
1732 if (mode == QLCNIC_ILB_MODE)
1733 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1734 if (mode == QLCNIC_ELB_MODE)
1735 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1736
1737 status = qlcnic_83xx_set_port_config(adapter);
1738 if (status) {
2c4a7878
JK
1739 netdev_err(netdev,
1740 "Failed to Set Loopback Mode = 0x%x.\n",
1741 ahw->port_config);
7f966452 1742 ahw->port_config = config;
629263ac 1743 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1744 return status;
1745 }
1746
9a05f92b 1747 /* Wait for Link and IDC Completion AEN */
629263ac 1748 do {
2c4a7878 1749 msleep(QLC_83XX_LB_MSLEEP_COUNT);
d1a1105e
RB
1750 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1751 qlcnic_83xx_process_aen(adapter);
1752
2c4a7878
JK
1753 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1754 netdev_info(netdev,
1755 "Device is resetting, free LB test resources\n");
1756 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1757 return -EIO;
1758 }
1759 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1760 netdev_err(netdev,
1761 "Did not receive IDC completion AEN\n");
629263ac 1762 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
9a05f92b 1763 qlcnic_83xx_clear_lb_mode(adapter, mode);
629263ac
SC
1764 return -EIO;
1765 }
1766 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1767
7f966452
SC
1768 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1769 QLCNIC_MAC_ADD);
1770 return status;
1771}
1772
1773int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1774{
1775 struct qlcnic_hardware_context *ahw = adapter->ahw;
2c4a7878 1776 struct net_device *netdev = adapter->netdev;
629263ac 1777 int status = 0, loop = 0;
7f966452
SC
1778 u32 config = ahw->port_config;
1779
629263ac 1780 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1781 if (mode == QLCNIC_ILB_MODE)
1782 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1783 if (mode == QLCNIC_ELB_MODE)
1784 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1785
1786 status = qlcnic_83xx_set_port_config(adapter);
1787 if (status) {
2c4a7878
JK
1788 netdev_err(netdev,
1789 "Failed to Clear Loopback Mode = 0x%x.\n",
1790 ahw->port_config);
7f966452 1791 ahw->port_config = config;
629263ac 1792 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1793 return status;
1794 }
1795
9a05f92b 1796 /* Wait for Link and IDC Completion AEN */
629263ac 1797 do {
2c4a7878 1798 msleep(QLC_83XX_LB_MSLEEP_COUNT);
d1a1105e
RB
1799 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1800 qlcnic_83xx_process_aen(adapter);
1801
2c4a7878
JK
1802 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
1803 netdev_info(netdev,
1804 "Device is resetting, free LB test resources\n");
1805 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1806 return -EIO;
1807 }
1808
1809 if (loop++ > QLC_83XX_LB_WAIT_COUNT) {
1810 netdev_err(netdev,
1811 "Did not receive IDC completion AEN\n");
629263ac
SC
1812 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1813 return -EIO;
1814 }
1815 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1816
7f966452
SC
1817 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1818 QLCNIC_MAC_DEL);
1819 return status;
1820}
1821
7cb03b23
RB
1822static void qlcnic_83xx_set_interface_id_ipaddr(struct qlcnic_adapter *adapter,
1823 u32 *interface_id)
1824{
1825 if (qlcnic_sriov_pf_check(adapter)) {
1826 qlcnic_pf_set_interface_id_ipaddr(adapter, interface_id);
1827 } else {
1828 if (!qlcnic_sriov_vf_check(adapter))
1829 *interface_id = adapter->recv_ctx->context_id << 16;
1830 }
1831}
1832
7f966452
SC
1833void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1834 int mode)
1835{
1836 int err;
7cb03b23 1837 u32 temp = 0, temp_ip;
7f966452
SC
1838 struct qlcnic_cmd_args cmd;
1839
b6b4316c
SS
1840 err = qlcnic_alloc_mbx_args(&cmd, adapter,
1841 QLCNIC_CMD_CONFIGURE_IP_ADDR);
1842 if (err)
1843 return;
1844
7cb03b23
RB
1845 qlcnic_83xx_set_interface_id_ipaddr(adapter, &temp);
1846
1847 if (mode == QLCNIC_IP_UP)
7f966452 1848 cmd.req.arg[1] = 1 | temp;
7cb03b23 1849 else
7f966452 1850 cmd.req.arg[1] = 2 | temp;
7f966452 1851
283c1c68
M
1852 /*
1853 * Adapter needs IP address in network byte order.
1854 * But hardware mailbox registers go through writel(), hence IP address
1855 * gets swapped on big endian architecture.
1856 * To negate swapping of writel() on big endian architecture
1857 * use swab32(value).
1858 */
1859
1860 temp_ip = swab32(ntohl(ip));
1861 memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
7f966452
SC
1862 err = qlcnic_issue_cmd(adapter, &cmd);
1863 if (err != QLCNIC_RCODE_SUCCESS)
1864 dev_err(&adapter->netdev->dev,
1865 "could not notify %s IP 0x%x request\n",
1866 (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
7cb03b23 1867
7f966452
SC
1868 qlcnic_free_mbx_args(&cmd);
1869}
1870
1871int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
1872{
1873 int err;
1874 u32 temp, arg1;
1875 struct qlcnic_cmd_args cmd;
283c1c68
M
1876 int lro_bit_mask;
1877
1878 lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
7f966452
SC
1879
1880 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1881 return 0;
1882
b6b4316c
SS
1883 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
1884 if (err)
1885 return err;
1886
7f966452 1887 temp = adapter->recv_ctx->context_id << 16;
283c1c68 1888 arg1 = lro_bit_mask | temp;
7f966452
SC
1889 cmd.req.arg[1] = arg1;
1890
1891 err = qlcnic_issue_cmd(adapter, &cmd);
1892 if (err)
1893 dev_info(&adapter->pdev->dev, "LRO config failed\n");
1894 qlcnic_free_mbx_args(&cmd);
1895
1896 return err;
1897}
1898
1899int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
1900{
1901 int err;
1902 u32 word;
1903 struct qlcnic_cmd_args cmd;
1904 const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
1905 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
1906 0x255b0ec26d5a56daULL };
1907
b6b4316c
SS
1908 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
1909 if (err)
1910 return err;
7f966452
SC
1911 /*
1912 * RSS request:
1913 * bits 3-0: Rsvd
1914 * 5-4: hash_type_ipv4
1915 * 7-6: hash_type_ipv6
1916 * 8: enable
1917 * 9: use indirection table
1918 * 16-31: indirection table mask
1919 */
1920 word = ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
1921 ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
1922 ((u32)(enable & 0x1) << 8) |
1923 ((0x7ULL) << 16);
1924 cmd.req.arg[1] = (adapter->recv_ctx->context_id);
1925 cmd.req.arg[2] = word;
1926 memcpy(&cmd.req.arg[4], key, sizeof(key));
1927
1928 err = qlcnic_issue_cmd(adapter, &cmd);
1929
1930 if (err)
1931 dev_info(&adapter->pdev->dev, "RSS config failed\n");
1932 qlcnic_free_mbx_args(&cmd);
1933
1934 return err;
1935
1936}
1937
7cb03b23
RB
1938static void qlcnic_83xx_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
1939 u32 *interface_id)
1940{
1941 if (qlcnic_sriov_pf_check(adapter)) {
1942 qlcnic_pf_set_interface_id_macaddr(adapter, interface_id);
1943 } else {
1944 if (!qlcnic_sriov_vf_check(adapter))
1945 *interface_id = adapter->recv_ctx->context_id << 16;
1946 }
1947}
1948
7f966452 1949int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
f80bc8fe 1950 u16 vlan_id, u8 op)
7f966452
SC
1951{
1952 int err;
7cb03b23 1953 u32 *buf, temp = 0;
7f966452
SC
1954 struct qlcnic_cmd_args cmd;
1955 struct qlcnic_macvlan_mbx mv;
1956
1957 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1958 return -EIO;
1959
1960 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
1961 if (err)
1962 return err;
7f966452 1963
91b7282b
RB
1964 if (vlan_id)
1965 op = (op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
1966 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL;
1967
7cb03b23
RB
1968 cmd.req.arg[1] = op | (1 << 8);
1969 qlcnic_83xx_set_interface_id_macaddr(adapter, &temp);
1970 cmd.req.arg[1] |= temp;
f80bc8fe 1971 mv.vlan = vlan_id;
a96227e6
SS
1972 mv.mac_addr0 = addr[0];
1973 mv.mac_addr1 = addr[1];
1974 mv.mac_addr2 = addr[2];
1975 mv.mac_addr3 = addr[3];
1976 mv.mac_addr4 = addr[4];
1977 mv.mac_addr5 = addr[5];
7f966452
SC
1978 buf = &cmd.req.arg[2];
1979 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1980 err = qlcnic_issue_cmd(adapter, &cmd);
1981 if (err)
1982 dev_err(&adapter->pdev->dev,
1983 "MAC-VLAN %s to CAM failed, err=%d.\n",
1984 ((op == 1) ? "add " : "delete "), err);
1985 qlcnic_free_mbx_args(&cmd);
1986 return err;
1987}
1988
1989void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
f80bc8fe 1990 u16 vlan_id)
7f966452
SC
1991{
1992 u8 mac[ETH_ALEN];
1993 memcpy(&mac, addr, ETH_ALEN);
1994 qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
1995}
1996
1997void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
1998 u8 type, struct qlcnic_cmd_args *cmd)
1999{
2000 switch (type) {
2001 case QLCNIC_SET_STATION_MAC:
2002 case QLCNIC_SET_FAC_DEF_MAC:
2003 memcpy(&cmd->req.arg[2], mac, sizeof(u32));
2004 memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
2005 break;
2006 }
2007 cmd->req.arg[1] = type;
2008}
2009
2010int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
2011{
2012 int err, i;
2013 struct qlcnic_cmd_args cmd;
2014 u32 mac_low, mac_high;
2015
b6b4316c
SS
2016 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
2017 if (err)
2018 return err;
2019
7f966452
SC
2020 qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
2021 err = qlcnic_issue_cmd(adapter, &cmd);
2022
2023 if (err == QLCNIC_RCODE_SUCCESS) {
2024 mac_low = cmd.rsp.arg[1];
2025 mac_high = cmd.rsp.arg[2];
2026
2027 for (i = 0; i < 2; i++)
2028 mac[i] = (u8) (mac_high >> ((1 - i) * 8));
2029 for (i = 2; i < 6; i++)
2030 mac[i] = (u8) (mac_low >> ((5 - i) * 8));
2031 } else {
2032 dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
2033 err);
2034 err = -EIO;
2035 }
2036 qlcnic_free_mbx_args(&cmd);
2037 return err;
2038}
2039
2040void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
2041{
2042 int err;
be273dc1 2043 u16 temp;
7f966452
SC
2044 struct qlcnic_cmd_args cmd;
2045 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2046
2047 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2048 return;
2049
b6b4316c
SS
2050 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2051 if (err)
2052 return;
2053
be273dc1
HM
2054 if (coal->type == QLCNIC_INTR_COAL_TYPE_RX) {
2055 temp = adapter->recv_ctx->context_id;
2056 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
2057 temp = coal->rx_time_us;
2058 cmd.req.arg[2] = coal->rx_packets | temp << 16;
2059 } else if (coal->type == QLCNIC_INTR_COAL_TYPE_TX) {
2060 temp = adapter->tx_ring->ctx_id;
2061 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2062 temp = coal->tx_time_us;
2063 cmd.req.arg[2] = coal->tx_packets | temp << 16;
2064 }
7f966452 2065 cmd.req.arg[3] = coal->flag;
7f966452
SC
2066 err = qlcnic_issue_cmd(adapter, &cmd);
2067 if (err != QLCNIC_RCODE_SUCCESS)
2068 dev_info(&adapter->pdev->dev,
2069 "Failed to send interrupt coalescence parameters\n");
2070 qlcnic_free_mbx_args(&cmd);
2071}
2072
2073static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
2074 u32 data[])
2075{
2076 u8 link_status, duplex;
2077 /* link speed */
2078 link_status = LSB(data[3]) & 1;
2079 adapter->ahw->link_speed = MSW(data[2]);
2080 adapter->ahw->link_autoneg = MSB(MSW(data[3]));
2081 adapter->ahw->module_type = MSB(LSW(data[3]));
2082 duplex = LSB(MSW(data[3]));
2083 if (duplex)
2084 adapter->ahw->link_duplex = DUPLEX_FULL;
2085 else
2086 adapter->ahw->link_duplex = DUPLEX_HALF;
2087 adapter->ahw->has_link_events = 1;
2088 qlcnic_advert_link_change(adapter, link_status);
2089}
2090
2091irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
2092{
2093 struct qlcnic_adapter *adapter = data;
483202d5
JK
2094 unsigned long flags;
2095 u32 mask, resp, event;
2096
2097 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
2098 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
2099 if (!(resp & QLCNIC_SET_OWNER))
2100 goto out;
ac166700 2101
483202d5
JK
2102 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
2103 if (event & QLCNIC_MBX_ASYNC_EVENT)
d1a1105e 2104 __qlcnic_83xx_process_aen(adapter);
483202d5
JK
2105out:
2106 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
2107 writel(0, adapter->ahw->pci_base0 + mask);
2108 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
2109
7f966452
SC
2110 return IRQ_HANDLED;
2111}
2112
2113int qlcnic_enable_eswitch(struct qlcnic_adapter *adapter, u8 port, u8 enable)
2114{
2115 int err = -EIO;
2116 struct qlcnic_cmd_args cmd;
2117
2118 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
2119 dev_err(&adapter->pdev->dev,
2120 "%s: Error, invoked by non management func\n",
2121 __func__);
2122 return err;
2123 }
2124
b6b4316c
SS
2125 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH);
2126 if (err)
2127 return err;
2128
7f966452
SC
2129 cmd.req.arg[1] = (port & 0xf) | BIT_4;
2130 err = qlcnic_issue_cmd(adapter, &cmd);
2131
2132 if (err != QLCNIC_RCODE_SUCCESS) {
2133 dev_err(&adapter->pdev->dev, "Failed to enable eswitch%d\n",
2134 err);
2135 err = -EIO;
2136 }
2137 qlcnic_free_mbx_args(&cmd);
2138
2139 return err;
2140
2141}
2142
2143int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
2144 struct qlcnic_info *nic)
2145{
2146 int i, err = -EIO;
2147 struct qlcnic_cmd_args cmd;
2148
2149 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
2150 dev_err(&adapter->pdev->dev,
2151 "%s: Error, invoked by non management func\n",
2152 __func__);
2153 return err;
2154 }
2155
b6b4316c
SS
2156 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
2157 if (err)
2158 return err;
2159
7f966452
SC
2160 cmd.req.arg[1] = (nic->pci_func << 16);
2161 cmd.req.arg[2] = 0x1 << 16;
2162 cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
2163 cmd.req.arg[4] = nic->capabilities;
2164 cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
2165 cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
2166 cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
2167 for (i = 8; i < 32; i++)
2168 cmd.req.arg[i] = 0;
2169
2170 err = qlcnic_issue_cmd(adapter, &cmd);
2171
2172 if (err != QLCNIC_RCODE_SUCCESS) {
2173 dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
2174 err);
2175 err = -EIO;
2176 }
2177
2178 qlcnic_free_mbx_args(&cmd);
2179
2180 return err;
2181}
2182
2183int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
2184 struct qlcnic_info *npar_info, u8 func_id)
2185{
2186 int err;
2187 u32 temp;
2188 u8 op = 0;
2189 struct qlcnic_cmd_args cmd;
8af3f33d 2190 struct qlcnic_hardware_context *ahw = adapter->ahw;
7f966452 2191
b6b4316c
SS
2192 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
2193 if (err)
2194 return err;
2195
8af3f33d 2196 if (func_id != ahw->pci_func) {
7f966452
SC
2197 temp = func_id << 16;
2198 cmd.req.arg[1] = op | BIT_31 | temp;
2199 } else {
8af3f33d 2200 cmd.req.arg[1] = ahw->pci_func << 16;
7f966452
SC
2201 }
2202 err = qlcnic_issue_cmd(adapter, &cmd);
2203 if (err) {
2204 dev_info(&adapter->pdev->dev,
2205 "Failed to get nic info %d\n", err);
2206 goto out;
2207 }
2208
2209 npar_info->op_type = cmd.rsp.arg[1];
2210 npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
2211 npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
2212 npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
2213 npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
2214 npar_info->capabilities = cmd.rsp.arg[4];
2215 npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
2216 npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
2217 npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
2218 npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
2219 npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
2220 npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
2221 if (cmd.rsp.arg[8] & 0x1)
2222 npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
2223 if (cmd.rsp.arg[8] & 0x10000) {
2224 temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
2225 npar_info->max_linkspeed_reg_offset = temp;
2226 }
8af3f33d
PP
2227 if (npar_info->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS)
2228 memcpy(ahw->extra_capability, &cmd.rsp.arg[16],
2229 sizeof(ahw->extra_capability));
7f966452
SC
2230
2231out:
2232 qlcnic_free_mbx_args(&cmd);
2233 return err;
2234}
2235
2236int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
2237 struct qlcnic_pci_info *pci_info)
2238{
ee9e8b6c
MC
2239 struct qlcnic_hardware_context *ahw = adapter->ahw;
2240 struct device *dev = &adapter->pdev->dev;
2241 struct qlcnic_cmd_args cmd;
7f966452
SC
2242 int i, err = 0, j = 0;
2243 u32 temp;
7f966452 2244
b6b4316c
SS
2245 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
2246 if (err)
2247 return err;
2248
7f966452
SC
2249 err = qlcnic_issue_cmd(adapter, &cmd);
2250
ee9e8b6c 2251 ahw->act_pci_func = 0;
7f966452 2252 if (err == QLCNIC_RCODE_SUCCESS) {
ee9e8b6c 2253 ahw->max_pci_func = cmd.rsp.arg[1] & 0xFF;
7f966452
SC
2254 for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
2255 pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
2256 pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2257 i++;
2258 pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
2259 if (pci_info->type == QLCNIC_TYPE_NIC)
ee9e8b6c 2260 ahw->act_pci_func++;
7f966452
SC
2261 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2262 pci_info->default_port = temp;
2263 i++;
2264 pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
2265 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
2266 pci_info->tx_max_bw = temp;
2267 i = i + 2;
2268 memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
2269 i++;
2270 memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
2271 i = i + 3;
ee9e8b6c
MC
2272 if (ahw->op_mode == QLCNIC_MGMT_FUNC)
2273 dev_info(dev, "id = %d active = %d type = %d\n"
2274 "\tport = %d min bw = %d max bw = %d\n"
2275 "\tmac_addr = %pM\n", pci_info->id,
2276 pci_info->active, pci_info->type,
2277 pci_info->default_port,
2278 pci_info->tx_min_bw,
2279 pci_info->tx_max_bw, pci_info->mac);
7f966452 2280 }
ee9e8b6c
MC
2281 if (ahw->op_mode == QLCNIC_MGMT_FUNC)
2282 dev_info(dev, "Max vNIC functions = %d, active vNIC functions = %d\n",
2283 ahw->max_pci_func, ahw->act_pci_func);
2284
7f966452 2285 } else {
ee9e8b6c 2286 dev_err(dev, "Failed to get PCI Info, error = %d\n", err);
7f966452
SC
2287 err = -EIO;
2288 }
2289
2290 qlcnic_free_mbx_args(&cmd);
2291
2292 return err;
2293}
2294
2295int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
2296{
2297 int i, index, err;
7f966452 2298 u8 max_ints;
e2ab1233 2299 u32 val, temp, type;
7f966452
SC
2300 struct qlcnic_cmd_args cmd;
2301
7dd90cf1 2302 max_ints = adapter->ahw->num_msix - 1;
b6b4316c
SS
2303 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
2304 if (err)
2305 return err;
2306
7f966452 2307 cmd.req.arg[1] = max_ints;
7cb03b23
RB
2308
2309 if (qlcnic_sriov_vf_check(adapter))
2310 cmd.req.arg[1] |= (adapter->ahw->pci_func << 8) | BIT_16;
2311
7f966452
SC
2312 for (i = 0, index = 2; i < max_ints; i++) {
2313 type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
2314 val = type | (adapter->ahw->intr_tbl[i].type << 4);
2315 if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
2316 val |= (adapter->ahw->intr_tbl[i].id << 16);
2317 cmd.req.arg[index++] = val;
2318 }
2319 err = qlcnic_issue_cmd(adapter, &cmd);
2320 if (err) {
2321 dev_err(&adapter->pdev->dev,
2322 "Failed to configure interrupts 0x%x\n", err);
2323 goto out;
2324 }
2325
2326 max_ints = cmd.rsp.arg[1];
2327 for (i = 0, index = 2; i < max_ints; i++, index += 2) {
2328 val = cmd.rsp.arg[index];
2329 if (LSB(val)) {
2330 dev_info(&adapter->pdev->dev,
2331 "Can't configure interrupt %d\n",
2332 adapter->ahw->intr_tbl[i].id);
2333 continue;
2334 }
2335 if (op_type) {
2336 adapter->ahw->intr_tbl[i].id = MSW(val);
2337 adapter->ahw->intr_tbl[i].enabled = 1;
2338 temp = cmd.rsp.arg[index + 1];
2339 adapter->ahw->intr_tbl[i].src = temp;
2340 } else {
2341 adapter->ahw->intr_tbl[i].id = i;
2342 adapter->ahw->intr_tbl[i].enabled = 0;
2343 adapter->ahw->intr_tbl[i].src = 0;
2344 }
2345 }
2346out:
2347 qlcnic_free_mbx_args(&cmd);
2348 return err;
2349}
d865ebb4
SC
2350
2351int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
2352{
2353 int id, timeout = 0;
2354 u32 status = 0;
2355
2356 while (status == 0) {
2357 status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
2358 if (status)
2359 break;
2360
2361 if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
2362 id = QLC_SHARED_REG_RD32(adapter,
2363 QLCNIC_FLASH_LOCK_OWNER);
2364 dev_err(&adapter->pdev->dev,
2365 "%s: failed, lock held by %d\n", __func__, id);
2366 return -EIO;
2367 }
2368 usleep_range(1000, 2000);
2369 }
2370
2371 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
2372 return 0;
2373}
2374
2375void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
2376{
2377 QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
2378 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
2379}
2380
629263ac
SC
2381int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
2382 u32 flash_addr, u8 *p_data,
2383 int count)
d865ebb4
SC
2384{
2385 int i, ret;
2386 u32 word, range, flash_offset, addr = flash_addr;
2387 ulong indirect_add, direct_window;
2388
2389 flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
2390 if (addr & 0x3) {
2391 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2392 return -EIO;
2393 }
2394
2395 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
2396 (addr));
2397
2398 range = flash_offset + (count * sizeof(u32));
2399 /* Check if data is spread across multiple sectors */
2400 if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2401
2402 /* Multi sector read */
2403 for (i = 0; i < count; i++) {
2404 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2405 ret = qlcnic_83xx_rd_reg_indirect(adapter,
2406 indirect_add);
2407 if (ret == -EIO)
2408 return -EIO;
2409
2410 word = ret;
2411 *(u32 *)p_data = word;
2412 p_data = p_data + 4;
2413 addr = addr + 4;
2414 flash_offset = flash_offset + 4;
2415
2416 if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
2417 direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
2418 /* This write is needed once for each sector */
2419 qlcnic_83xx_wrt_reg_indirect(adapter,
2420 direct_window,
2421 (addr));
2422 flash_offset = 0;
2423 }
2424 }
2425 } else {
2426 /* Single sector read */
2427 for (i = 0; i < count; i++) {
2428 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
2429 ret = qlcnic_83xx_rd_reg_indirect(adapter,
2430 indirect_add);
2431 if (ret == -EIO)
2432 return -EIO;
2433
2434 word = ret;
2435 *(u32 *)p_data = word;
2436 p_data = p_data + 4;
2437 addr = addr + 4;
2438 }
2439 }
2440
2441 return 0;
2442}
2443
2444static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
2445{
2446 u32 status;
2447 int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
2448
2449 do {
2450 status = qlcnic_83xx_rd_reg_indirect(adapter,
2451 QLC_83XX_FLASH_STATUS);
2452 if ((status & QLC_83XX_FLASH_STATUS_READY) ==
2453 QLC_83XX_FLASH_STATUS_READY)
2454 break;
2455
2456 msleep(QLC_83XX_FLASH_STATUS_REG_POLL_DELAY);
2457 } while (--retries);
2458
2459 if (!retries)
2460 return -EIO;
2461
2462 return 0;
2463}
2464
a520030e 2465int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *adapter)
d865ebb4
SC
2466{
2467 int ret;
2468 u32 cmd;
2469 cmd = adapter->ahw->fdt.write_statusreg_cmd;
2470 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2471 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
2472 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2473 adapter->ahw->fdt.write_enable_bits);
2474 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2475 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2476 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2477 if (ret)
2478 return -EIO;
2479
2480 return 0;
2481}
2482
a520030e 2483int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *adapter)
d865ebb4
SC
2484{
2485 int ret;
2486
2487 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2488 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
2489 adapter->ahw->fdt.write_statusreg_cmd));
2490 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2491 adapter->ahw->fdt.write_disable_bits);
2492 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2493 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
2494 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2495 if (ret)
2496 return -EIO;
2497
2498 return 0;
2499}
2500
2501int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
2502{
2503 int ret, mfg_id;
2504
2505 if (qlcnic_83xx_lock_flash(adapter))
2506 return -EIO;
2507
2508 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2509 QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
2510 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2511 QLC_83XX_FLASH_READ_CTRL);
2512 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2513 if (ret) {
2514 qlcnic_83xx_unlock_flash(adapter);
2515 return -EIO;
2516 }
2517
2518 mfg_id = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
2519 if (mfg_id == -EIO)
2520 return -EIO;
2521
2522 adapter->flash_mfg_id = (mfg_id & 0xFF);
2523 qlcnic_83xx_unlock_flash(adapter);
2524
2525 return 0;
2526}
2527
2528int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
2529{
2530 int count, fdt_size, ret = 0;
2531
2532 fdt_size = sizeof(struct qlcnic_fdt);
2533 count = fdt_size / sizeof(u32);
2534
2535 if (qlcnic_83xx_lock_flash(adapter))
2536 return -EIO;
2537
2538 memset(&adapter->ahw->fdt, 0, fdt_size);
2539 ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
2540 (u8 *)&adapter->ahw->fdt,
2541 count);
2542
2543 qlcnic_83xx_unlock_flash(adapter);
2544 return ret;
2545}
2546
2547int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
2548 u32 sector_start_addr)
2549{
2550 u32 reversed_addr, addr1, addr2, cmd;
2551 int ret = -EIO;
2552
2553 if (qlcnic_83xx_lock_flash(adapter) != 0)
2554 return -EIO;
2555
2556 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
a520030e 2557 ret = qlcnic_83xx_enable_flash_write(adapter);
d865ebb4
SC
2558 if (ret) {
2559 qlcnic_83xx_unlock_flash(adapter);
2560 dev_err(&adapter->pdev->dev,
2561 "%s failed at %d\n",
2562 __func__, __LINE__);
2563 return ret;
2564 }
2565 }
2566
2567 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2568 if (ret) {
2569 qlcnic_83xx_unlock_flash(adapter);
2570 dev_err(&adapter->pdev->dev,
2571 "%s: failed at %d\n", __func__, __LINE__);
2572 return -EIO;
2573 }
2574
2575 addr1 = (sector_start_addr & 0xFF) << 16;
2576 addr2 = (sector_start_addr & 0xFF0000) >> 16;
2577 reversed_addr = addr1 | addr2;
2578
2579 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2580 reversed_addr);
2581 cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2582 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2583 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2584 else
2585 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2586 QLC_83XX_FLASH_OEM_ERASE_SIG);
2587 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2588 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2589
2590 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2591 if (ret) {
2592 qlcnic_83xx_unlock_flash(adapter);
2593 dev_err(&adapter->pdev->dev,
2594 "%s: failed at %d\n", __func__, __LINE__);
2595 return -EIO;
2596 }
2597
2598 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
a520030e 2599 ret = qlcnic_83xx_disable_flash_write(adapter);
d865ebb4
SC
2600 if (ret) {
2601 qlcnic_83xx_unlock_flash(adapter);
2602 dev_err(&adapter->pdev->dev,
2603 "%s: failed at %d\n", __func__, __LINE__);
2604 return ret;
2605 }
2606 }
2607
2608 qlcnic_83xx_unlock_flash(adapter);
2609
2610 return 0;
2611}
2612
2613int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2614 u32 *p_data)
2615{
2616 int ret = -EIO;
2617 u32 addr1 = 0x00800000 | (addr >> 2);
2618
2619 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2620 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2621 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2622 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2623 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2624 if (ret) {
2625 dev_err(&adapter->pdev->dev,
2626 "%s: failed at %d\n", __func__, __LINE__);
2627 return -EIO;
2628 }
2629
2630 return 0;
2631}
2632
2633int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2634 u32 *p_data, int count)
2635{
2636 u32 temp;
2637 int ret = -EIO;
2638
a520030e
HM
2639 if ((count < QLC_83XX_FLASH_WRITE_MIN) ||
2640 (count > QLC_83XX_FLASH_WRITE_MAX)) {
d865ebb4
SC
2641 dev_err(&adapter->pdev->dev,
2642 "%s: Invalid word count\n", __func__);
2643 return -EIO;
2644 }
2645
2646 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2647 QLC_83XX_FLASH_SPI_CONTROL);
2648 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2649 (temp | QLC_83XX_FLASH_SPI_CTRL));
2650 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2651 QLC_83XX_FLASH_ADDR_TEMP_VAL);
2652
2653 /* First DWORD write */
2654 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2655 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2656 QLC_83XX_FLASH_FIRST_MS_PATTERN);
2657 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2658 if (ret) {
2659 dev_err(&adapter->pdev->dev,
2660 "%s: failed at %d\n", __func__, __LINE__);
2661 return -EIO;
2662 }
2663
2664 count--;
2665 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2666 QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2667 /* Second to N-1 DWORD writes */
2668 while (count != 1) {
2669 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2670 *p_data++);
2671 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2672 QLC_83XX_FLASH_SECOND_MS_PATTERN);
2673 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2674 if (ret) {
2675 dev_err(&adapter->pdev->dev,
2676 "%s: failed at %d\n", __func__, __LINE__);
2677 return -EIO;
2678 }
2679 count--;
2680 }
2681
2682 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2683 QLC_83XX_FLASH_ADDR_TEMP_VAL |
2684 (addr >> 2));
2685 /* Last DWORD write */
2686 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2687 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2688 QLC_83XX_FLASH_LAST_MS_PATTERN);
2689 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2690 if (ret) {
2691 dev_err(&adapter->pdev->dev,
2692 "%s: failed at %d\n", __func__, __LINE__);
2693 return -EIO;
2694 }
2695
2696 ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_SPI_STATUS);
2697 if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2698 dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2699 __func__, __LINE__);
2700 /* Operation failed, clear error bit */
2701 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2702 QLC_83XX_FLASH_SPI_CONTROL);
2703 qlcnic_83xx_wrt_reg_indirect(adapter,
2704 QLC_83XX_FLASH_SPI_CONTROL,
2705 (temp | QLC_83XX_FLASH_SPI_CTRL));
2706 }
2707
2708 return 0;
2709}
629263ac
SC
2710
2711static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2712{
2713 u32 val, id;
2714
2715 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2716
2717 /* Check if recovery need to be performed by the calling function */
2718 if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2719 val = val & ~0x3F;
2720 val = val | ((adapter->portnum << 2) |
2721 QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2722 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2723 dev_info(&adapter->pdev->dev,
2724 "%s: lock recovery initiated\n", __func__);
2725 msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2726 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2727 id = ((val >> 2) & 0xF);
2728 if (id == adapter->portnum) {
2729 val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2730 val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
2731 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2732 /* Force release the lock */
2733 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2734 /* Clear recovery bits */
2735 val = val & ~0x3F;
2736 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2737 dev_info(&adapter->pdev->dev,
2738 "%s: lock recovery completed\n", __func__);
2739 } else {
2740 dev_info(&adapter->pdev->dev,
2741 "%s: func %d to resume lock recovery process\n",
2742 __func__, id);
2743 }
2744 } else {
2745 dev_info(&adapter->pdev->dev,
2746 "%s: lock recovery initiated by other functions\n",
2747 __func__);
2748 }
2749}
2750
2751int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
2752{
2753 u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
2754 int max_attempt = 0;
2755
2756 while (status == 0) {
2757 status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
2758 if (status)
2759 break;
2760
2761 msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
2762 i++;
2763
2764 if (i == 1)
2765 temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2766
2767 if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
2768 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2769 if (val == temp) {
2770 id = val & 0xFF;
2771 dev_info(&adapter->pdev->dev,
2772 "%s: lock to be recovered from %d\n",
2773 __func__, id);
2774 qlcnic_83xx_recover_driver_lock(adapter);
2775 i = 0;
2776 max_attempt++;
2777 } else {
2778 dev_err(&adapter->pdev->dev,
2779 "%s: failed to get lock\n", __func__);
2780 return -EIO;
2781 }
2782 }
2783
2784 /* Force exit from while loop after few attempts */
2785 if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
2786 dev_err(&adapter->pdev->dev,
2787 "%s: failed to get lock\n", __func__);
2788 return -EIO;
2789 }
2790 }
2791
2792 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2793 lock_alive_counter = val >> 8;
2794 lock_alive_counter++;
2795 val = lock_alive_counter << 8 | adapter->portnum;
2796 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2797
2798 return 0;
2799}
2800
2801void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
2802{
2803 u32 val, lock_alive_counter, id;
2804
2805 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2806 id = val & 0xFF;
2807 lock_alive_counter = val >> 8;
2808
2809 if (id != adapter->portnum)
2810 dev_err(&adapter->pdev->dev,
2811 "%s:Warning func %d is unlocking lock owned by %d\n",
2812 __func__, adapter->portnum, id);
2813
2814 val = (lock_alive_counter << 8) | 0xFF;
2815 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2816 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2817}
2818
2819int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
2820 u32 *data, u32 count)
2821{
2822 int i, j, ret = 0;
2823 u32 temp;
2824
2825 /* Check alignment */
2826 if (addr & 0xF)
2827 return -EIO;
2828
2829 mutex_lock(&adapter->ahw->mem_lock);
2830 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0);
2831
2832 for (i = 0; i < count; i++, addr += 16) {
2833 if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
2834 QLCNIC_ADDR_QDR_NET_MAX)) ||
2835 (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
2836 QLCNIC_ADDR_DDR_NET_MAX)))) {
2837 mutex_unlock(&adapter->ahw->mem_lock);
2838 return -EIO;
2839 }
2840
2841 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr);
2842 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO,
2843 *data++);
2844 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI,
2845 *data++);
2846 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO,
2847 *data++);
2848 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
2849 *data++);
2850 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2851 QLCNIC_TA_WRITE_ENABLE);
2852 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2853 QLCNIC_TA_WRITE_START);
2854
2855 for (j = 0; j < MAX_CTL_CHECK; j++) {
2856 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2857 QLCNIC_MS_CTRL);
2858 if ((temp & TA_CTL_BUSY) == 0)
2859 break;
2860 }
2861
2862 /* Status check failure */
2863 if (j >= MAX_CTL_CHECK) {
2864 printk_ratelimited(KERN_WARNING
2865 "MS memory write failed\n");
2866 mutex_unlock(&adapter->ahw->mem_lock);
2867 return -EIO;
2868 }
2869 }
2870
2871 mutex_unlock(&adapter->ahw->mem_lock);
2872
2873 return ret;
2874}
81d0aeb0
SC
2875
2876int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
2877 u8 *p_data, int count)
2878{
2879 int i, ret;
2880 u32 word, addr = flash_addr;
2881 ulong indirect_addr;
2882
2883 if (qlcnic_83xx_lock_flash(adapter) != 0)
2884 return -EIO;
2885
2886 if (addr & 0x3) {
2887 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2888 qlcnic_83xx_unlock_flash(adapter);
2889 return -EIO;
2890 }
2891
2892 for (i = 0; i < count; i++) {
2893 if (qlcnic_83xx_wrt_reg_indirect(adapter,
2894 QLC_83XX_FLASH_DIRECT_WINDOW,
2895 (addr))) {
2896 qlcnic_83xx_unlock_flash(adapter);
2897 return -EIO;
2898 }
2899
2900 indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
2901 ret = qlcnic_83xx_rd_reg_indirect(adapter,
2902 indirect_addr);
2903 if (ret == -EIO)
2904 return -EIO;
2905 word = ret;
1403f43a 2906 *(u32 *)p_data = word;
81d0aeb0
SC
2907 p_data = p_data + 4;
2908 addr = addr + 4;
2909 }
2910
2911 qlcnic_83xx_unlock_flash(adapter);
2912
2913 return 0;
2914}
7e38d04b
SC
2915
2916int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
2917{
7cb03b23 2918 u8 pci_func;
7e38d04b
SC
2919 int err;
2920 u32 config = 0, state;
2921 struct qlcnic_cmd_args cmd;
2922 struct qlcnic_hardware_context *ahw = adapter->ahw;
2923
7cb03b23
RB
2924 if (qlcnic_sriov_vf_check(adapter))
2925 pci_func = adapter->portnum;
2926 else
2927 pci_func = ahw->pci_func;
2928
2929 state = readl(ahw->pci_base0 + QLC_83XX_LINK_STATE(pci_func));
2930 if (!QLC_83xx_FUNC_VAL(state, pci_func)) {
7e38d04b
SC
2931 dev_info(&adapter->pdev->dev, "link state down\n");
2932 return config;
2933 }
b6b4316c
SS
2934
2935 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
2936 if (err)
2937 return err;
2938
7e38d04b
SC
2939 err = qlcnic_issue_cmd(adapter, &cmd);
2940 if (err) {
2941 dev_info(&adapter->pdev->dev,
2942 "Get Link Status Command failed: 0x%x\n", err);
2943 goto out;
2944 } else {
2945 config = cmd.rsp.arg[1];
2946 switch (QLC_83XX_CURRENT_LINK_SPEED(config)) {
2947 case QLC_83XX_10M_LINK:
2948 ahw->link_speed = SPEED_10;
2949 break;
2950 case QLC_83XX_100M_LINK:
2951 ahw->link_speed = SPEED_100;
2952 break;
2953 case QLC_83XX_1G_LINK:
2954 ahw->link_speed = SPEED_1000;
2955 break;
2956 case QLC_83XX_10G_LINK:
2957 ahw->link_speed = SPEED_10000;
2958 break;
2959 default:
2960 ahw->link_speed = 0;
2961 break;
2962 }
2963 config = cmd.rsp.arg[3];
b938662d
HM
2964 if (QLC_83XX_SFP_PRESENT(config)) {
2965 switch (ahw->module_type) {
2966 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
2967 case LINKEVENT_MODULE_OPTICAL_SRLR:
2968 case LINKEVENT_MODULE_OPTICAL_LRM:
2969 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
2970 ahw->supported_type = PORT_FIBRE;
2971 break;
2972 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
2973 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
2974 case LINKEVENT_MODULE_TWINAX:
2975 ahw->supported_type = PORT_TP;
2976 break;
2977 default:
2978 ahw->supported_type = PORT_OTHER;
2979 }
2980 }
7e38d04b
SC
2981 if (config & 1)
2982 err = 1;
2983 }
2984out:
2985 qlcnic_free_mbx_args(&cmd);
2986 return config;
2987}
2988
b938662d
HM
2989int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
2990 struct ethtool_cmd *ecmd)
7e38d04b
SC
2991{
2992 u32 config = 0;
2993 int status = 0;
2994 struct qlcnic_hardware_context *ahw = adapter->ahw;
2995
2996 /* Get port configuration info */
2997 status = qlcnic_83xx_get_port_info(adapter);
2998 /* Get Link Status related info */
2999 config = qlcnic_83xx_test_link(adapter);
3000 ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
3001 /* hard code until there is a way to get it from flash */
3002 ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
b938662d
HM
3003
3004 if (netif_running(adapter->netdev) && ahw->has_link_events) {
3005 ethtool_cmd_speed_set(ecmd, ahw->link_speed);
3006 ecmd->duplex = ahw->link_duplex;
3007 ecmd->autoneg = ahw->link_autoneg;
3008 } else {
3009 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
3010 ecmd->duplex = DUPLEX_UNKNOWN;
3011 ecmd->autoneg = AUTONEG_DISABLE;
3012 }
3013
3014 if (ahw->port_type == QLCNIC_XGBE) {
3015 ecmd->supported = SUPPORTED_1000baseT_Full;
3016 ecmd->advertising = ADVERTISED_1000baseT_Full;
3017 } else {
3018 ecmd->supported = (SUPPORTED_10baseT_Half |
3019 SUPPORTED_10baseT_Full |
3020 SUPPORTED_100baseT_Half |
3021 SUPPORTED_100baseT_Full |
3022 SUPPORTED_1000baseT_Half |
3023 SUPPORTED_1000baseT_Full);
3024 ecmd->advertising = (ADVERTISED_100baseT_Half |
3025 ADVERTISED_100baseT_Full |
3026 ADVERTISED_1000baseT_Half |
3027 ADVERTISED_1000baseT_Full);
3028 }
3029
3030 switch (ahw->supported_type) {
3031 case PORT_FIBRE:
3032 ecmd->supported |= SUPPORTED_FIBRE;
3033 ecmd->advertising |= ADVERTISED_FIBRE;
3034 ecmd->port = PORT_FIBRE;
3035 ecmd->transceiver = XCVR_EXTERNAL;
3036 break;
3037 case PORT_TP:
3038 ecmd->supported |= SUPPORTED_TP;
3039 ecmd->advertising |= ADVERTISED_TP;
3040 ecmd->port = PORT_TP;
3041 ecmd->transceiver = XCVR_INTERNAL;
3042 break;
3043 default:
3044 ecmd->supported |= SUPPORTED_FIBRE;
3045 ecmd->advertising |= ADVERTISED_FIBRE;
3046 ecmd->port = PORT_OTHER;
3047 ecmd->transceiver = XCVR_EXTERNAL;
3048 break;
3049 }
3050 ecmd->phy_address = ahw->physical_port;
7e38d04b
SC
3051 return status;
3052}
3053
3054int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
3055 struct ethtool_cmd *ecmd)
3056{
3057 int status = 0;
3058 u32 config = adapter->ahw->port_config;
3059
3060 if (ecmd->autoneg)
3061 adapter->ahw->port_config |= BIT_15;
3062
3063 switch (ethtool_cmd_speed(ecmd)) {
3064 case SPEED_10:
3065 adapter->ahw->port_config |= BIT_8;
3066 break;
3067 case SPEED_100:
3068 adapter->ahw->port_config |= BIT_9;
3069 break;
3070 case SPEED_1000:
3071 adapter->ahw->port_config |= BIT_10;
3072 break;
3073 case SPEED_10000:
3074 adapter->ahw->port_config |= BIT_11;
3075 break;
3076 default:
3077 return -EINVAL;
3078 }
3079
3080 status = qlcnic_83xx_set_port_config(adapter);
3081 if (status) {
3082 dev_info(&adapter->pdev->dev,
3083 "Faild to Set Link Speed and autoneg.\n");
3084 adapter->ahw->port_config = config;
3085 }
3086 return status;
3087}
3088
3089static inline u64 *qlcnic_83xx_copy_stats(struct qlcnic_cmd_args *cmd,
3090 u64 *data, int index)
3091{
3092 u32 low, hi;
3093 u64 val;
3094
3095 low = cmd->rsp.arg[index];
3096 hi = cmd->rsp.arg[index + 1];
3097 val = (((u64) low) | (((u64) hi) << 32));
3098 *data++ = val;
3099 return data;
3100}
3101
3102static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
3103 struct qlcnic_cmd_args *cmd, u64 *data,
3104 int type, int *ret)
3105{
3106 int err, k, total_regs;
3107
3108 *ret = 0;
3109 err = qlcnic_issue_cmd(adapter, cmd);
3110 if (err != QLCNIC_RCODE_SUCCESS) {
3111 dev_info(&adapter->pdev->dev,
3112 "Error in get statistics mailbox command\n");
3113 *ret = -EIO;
3114 return data;
3115 }
3116 total_regs = cmd->rsp.num;
3117 switch (type) {
3118 case QLC_83XX_STAT_MAC:
3119 /* fill in MAC tx counters */
3120 for (k = 2; k < 28; k += 2)
3121 data = qlcnic_83xx_copy_stats(cmd, data, k);
3122 /* skip 24 bytes of reserved area */
3123 /* fill in MAC rx counters */
3124 for (k += 6; k < 60; k += 2)
3125 data = qlcnic_83xx_copy_stats(cmd, data, k);
3126 /* skip 24 bytes of reserved area */
3127 /* fill in MAC rx frame stats */
3128 for (k += 6; k < 80; k += 2)
3129 data = qlcnic_83xx_copy_stats(cmd, data, k);
52290740
SS
3130 /* fill in eSwitch stats */
3131 for (; k < total_regs; k += 2)
3132 data = qlcnic_83xx_copy_stats(cmd, data, k);
7e38d04b
SC
3133 break;
3134 case QLC_83XX_STAT_RX:
3135 for (k = 2; k < 8; k += 2)
3136 data = qlcnic_83xx_copy_stats(cmd, data, k);
3137 /* skip 8 bytes of reserved data */
3138 for (k += 2; k < 24; k += 2)
3139 data = qlcnic_83xx_copy_stats(cmd, data, k);
3140 /* skip 8 bytes containing RE1FBQ error data */
3141 for (k += 2; k < total_regs; k += 2)
3142 data = qlcnic_83xx_copy_stats(cmd, data, k);
3143 break;
3144 case QLC_83XX_STAT_TX:
3145 for (k = 2; k < 10; k += 2)
3146 data = qlcnic_83xx_copy_stats(cmd, data, k);
3147 /* skip 8 bytes of reserved data */
3148 for (k += 2; k < total_regs; k += 2)
3149 data = qlcnic_83xx_copy_stats(cmd, data, k);
3150 break;
3151 default:
3152 dev_warn(&adapter->pdev->dev, "Unknown get statistics mode\n");
3153 *ret = -EIO;
3154 }
3155 return data;
3156}
3157
3158void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
3159{
3160 struct qlcnic_cmd_args cmd;
7bc27a8c 3161 struct net_device *netdev = adapter->netdev;
7e38d04b
SC
3162 int ret = 0;
3163
b6b4316c
SS
3164 ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
3165 if (ret)
3166 return;
7e38d04b
SC
3167 /* Get Tx stats */
3168 cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
3169 cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
3170 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3171 QLC_83XX_STAT_TX, &ret);
3172 if (ret) {
7bc27a8c 3173 netdev_err(netdev, "Error getting Tx stats\n");
7e38d04b
SC
3174 goto out;
3175 }
3176 /* Get MAC stats */
3177 cmd.req.arg[1] = BIT_2 | (adapter->portnum << 16);
3178 cmd.rsp.num = QLC_83XX_MAC_STAT_REGS;
3179 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3180 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3181 QLC_83XX_STAT_MAC, &ret);
3182 if (ret) {
7bc27a8c 3183 netdev_err(netdev, "Error getting MAC stats\n");
7e38d04b
SC
3184 goto out;
3185 }
3186 /* Get Rx stats */
3187 cmd.req.arg[1] = adapter->recv_ctx->context_id << 16;
3188 cmd.rsp.num = QLC_83XX_RX_STAT_REGS;
3189 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
3190 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
3191 QLC_83XX_STAT_RX, &ret);
3192 if (ret)
7bc27a8c 3193 netdev_err(netdev, "Error getting Rx stats\n");
7e38d04b
SC
3194out:
3195 qlcnic_free_mbx_args(&cmd);
3196}
3197
3198int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
3199{
3200 u32 major, minor, sub;
3201
3202 major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
3203 minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
3204 sub = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
3205
3206 if (adapter->fw_version != QLCNIC_VERSION_CODE(major, minor, sub)) {
3207 dev_info(&adapter->pdev->dev, "%s: Reg test failed\n",
3208 __func__);
3209 return 1;
3210 }
3211 return 0;
3212}
3213
3214int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
3215{
3216 return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
3217 sizeof(adapter->ahw->ext_reg_tbl)) +
3218 (ARRAY_SIZE(qlcnic_83xx_reg_tbl) +
3219 sizeof(adapter->ahw->reg_tbl));
3220}
3221
3222int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
3223{
3224 int i, j = 0;
3225
3226 for (i = QLCNIC_DEV_INFO_SIZE + 1;
3227 j < ARRAY_SIZE(qlcnic_83xx_reg_tbl); i++, j++)
3228 regs_buff[i] = QLC_SHARED_REG_RD32(adapter, j);
3229
3230 for (j = 0; j < ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl); j++)
3231 regs_buff[i++] = QLCRDX(adapter->ahw, j);
3232 return i;
3233}
3234
58ead415 3235int qlcnic_83xx_interrupt_test(struct net_device *netdev)
7e38d04b 3236{
58ead415
JK
3237 struct qlcnic_adapter *adapter = netdev_priv(netdev);
3238 struct qlcnic_hardware_context *ahw = adapter->ahw;
3239 struct qlcnic_cmd_args cmd;
7e38d04b
SC
3240 u32 data;
3241 u16 intrpt_id, id;
58ead415
JK
3242 u8 val;
3243 int ret, max_sds_rings = adapter->max_sds_rings;
3244
4690a7e4
SC
3245 if (qlcnic_get_diag_lock(adapter)) {
3246 netdev_info(netdev, "Device in diagnostics mode\n");
3247 return -EBUSY;
3248 }
58ead415 3249
13a82b44
MC
3250 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
3251 max_sds_rings);
58ead415
JK
3252 if (ret)
3253 goto fail_diag_irq;
3254
3255 ahw->diag_cnt = 0;
b6b4316c
SS
3256 ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST);
3257 if (ret)
3258 goto fail_diag_irq;
7e38d04b
SC
3259
3260 if (adapter->flags & QLCNIC_MSIX_ENABLED)
58ead415 3261 intrpt_id = ahw->intr_tbl[0].id;
7e38d04b 3262 else
58ead415 3263 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
7e38d04b 3264
58ead415
JK
3265 cmd.req.arg[1] = 1;
3266 cmd.req.arg[2] = intrpt_id;
3267 cmd.req.arg[3] = BIT_0;
7e38d04b 3268
58ead415
JK
3269 ret = qlcnic_issue_cmd(adapter, &cmd);
3270 data = cmd.rsp.arg[2];
7e38d04b
SC
3271 id = LSW(data);
3272 val = LSB(MSW(data));
3273 if (id != intrpt_id)
3274 dev_info(&adapter->pdev->dev,
3275 "Interrupt generated: 0x%x, requested:0x%x\n",
3276 id, intrpt_id);
3277 if (val)
58ead415 3278 dev_err(&adapter->pdev->dev,
7e38d04b 3279 "Interrupt test error: 0x%x\n", val);
58ead415
JK
3280 if (ret)
3281 goto done;
3282
3283 msleep(20);
3284 ret = !ahw->diag_cnt;
7e38d04b 3285
58ead415
JK
3286done:
3287 qlcnic_free_mbx_args(&cmd);
3288 qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
3289
3290fail_diag_irq:
3291 adapter->max_sds_rings = max_sds_rings;
4690a7e4 3292 qlcnic_release_diag_lock(adapter);
7e38d04b
SC
3293 return ret;
3294}
3295
3296void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
3297 struct ethtool_pauseparam *pause)
3298{
3299 struct qlcnic_hardware_context *ahw = adapter->ahw;
3300 int status = 0;
3301 u32 config;
3302
3303 status = qlcnic_83xx_get_port_config(adapter);
3304 if (status) {
3305 dev_err(&adapter->pdev->dev,
3306 "%s: Get Pause Config failed\n", __func__);
3307 return;
3308 }
3309 config = ahw->port_config;
3310 if (config & QLC_83XX_CFG_STD_PAUSE) {
3311 if (config & QLC_83XX_CFG_STD_TX_PAUSE)
3312 pause->tx_pause = 1;
3313 if (config & QLC_83XX_CFG_STD_RX_PAUSE)
3314 pause->rx_pause = 1;
3315 }
3316
3317 if (QLC_83XX_AUTONEG(config))
3318 pause->autoneg = 1;
3319}
3320
3321int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
3322 struct ethtool_pauseparam *pause)
3323{
3324 struct qlcnic_hardware_context *ahw = adapter->ahw;
3325 int status = 0;
3326 u32 config;
3327
3328 status = qlcnic_83xx_get_port_config(adapter);
3329 if (status) {
3330 dev_err(&adapter->pdev->dev,
3331 "%s: Get Pause Config failed.\n", __func__);
3332 return status;
3333 }
3334 config = ahw->port_config;
3335
3336 if (ahw->port_type == QLCNIC_GBE) {
3337 if (pause->autoneg)
3338 ahw->port_config |= QLC_83XX_ENABLE_AUTONEG;
3339 if (!pause->autoneg)
3340 ahw->port_config &= ~QLC_83XX_ENABLE_AUTONEG;
3341 } else if ((ahw->port_type == QLCNIC_XGBE) && (pause->autoneg)) {
3342 return -EOPNOTSUPP;
3343 }
3344
3345 if (!(config & QLC_83XX_CFG_STD_PAUSE))
3346 ahw->port_config |= QLC_83XX_CFG_STD_PAUSE;
3347
3348 if (pause->rx_pause && pause->tx_pause) {
3349 ahw->port_config |= QLC_83XX_CFG_STD_TX_RX_PAUSE;
3350 } else if (pause->rx_pause && !pause->tx_pause) {
3351 ahw->port_config &= ~QLC_83XX_CFG_STD_TX_PAUSE;
3352 ahw->port_config |= QLC_83XX_CFG_STD_RX_PAUSE;
3353 } else if (pause->tx_pause && !pause->rx_pause) {
3354 ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
3355 ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
3356 } else if (!pause->rx_pause && !pause->tx_pause) {
3357 ahw->port_config &= ~QLC_83XX_CFG_STD_TX_RX_PAUSE;
3358 }
3359 status = qlcnic_83xx_set_port_config(adapter);
3360 if (status) {
3361 dev_err(&adapter->pdev->dev,
3362 "%s: Set Pause Config failed.\n", __func__);
3363 ahw->port_config = config;
3364 }
3365 return status;
3366}
3367
3368static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter)
3369{
3370 int ret;
3371
3372 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
3373 QLC_83XX_FLASH_OEM_READ_SIG);
3374 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
3375 QLC_83XX_FLASH_READ_CTRL);
3376 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
3377 if (ret)
3378 return -EIO;
3379
3380 ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
3381 return ret & 0xFF;
3382}
3383
3384int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
3385{
3386 int status;
3387
3388 status = qlcnic_83xx_read_flash_status_reg(adapter);
3389 if (status == -EIO) {
3390 dev_info(&adapter->pdev->dev, "%s: EEPROM test failed.\n",
3391 __func__);
3392 return 1;
3393 }
3394 return 0;
3395}