]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
qlcnic: helper routine to handle async events
[mirror_ubuntu-bionic-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
SC
8#include "qlcnic.h"
9#include <linux/if_vlan.h>
10#include <linux/ipv6.h>
11#include <linux/ethtool.h>
12#include <linux/interrupt.h>
13
14#define QLCNIC_MAX_TX_QUEUES 1
7f966452
SC
15#define RSS_HASHTYPE_IP_TCP 0x3
16
17/* status descriptor mailbox data
18 * @phy_addr: physical address of buffer
19 * @sds_ring_size: buffer size
20 * @intrpt_id: interrupt id
21 * @intrpt_val: source of interrupt
22 */
23struct qlcnic_sds_mbx {
24 u64 phy_addr;
25 u8 rsvd1[16];
26 u16 sds_ring_size;
27 u16 rsvd2[3];
28 u16 intrpt_id;
29 u8 intrpt_val;
30 u8 rsvd3[5];
31} __packed;
32
33/* receive descriptor buffer data
34 * phy_addr_reg: physical address of regular buffer
35 * phy_addr_jmb: physical address of jumbo buffer
36 * reg_ring_sz: size of regular buffer
37 * reg_ring_len: no. of entries in regular buffer
38 * jmb_ring_len: no. of entries in jumbo buffer
39 * jmb_ring_sz: size of jumbo buffer
40 */
41struct qlcnic_rds_mbx {
42 u64 phy_addr_reg;
43 u64 phy_addr_jmb;
44 u16 reg_ring_sz;
45 u16 reg_ring_len;
46 u16 jmb_ring_sz;
47 u16 jmb_ring_len;
48} __packed;
49
50/* host producers for regular and jumbo rings */
51struct __host_producer_mbx {
52 u32 reg_buf;
53 u32 jmb_buf;
54} __packed;
55
56/* Receive context mailbox data outbox registers
57 * @state: state of the context
58 * @vport_id: virtual port id
59 * @context_id: receive context id
60 * @num_pci_func: number of pci functions of the port
61 * @phy_port: physical port id
62 */
63struct qlcnic_rcv_mbx_out {
64 u8 rcv_num;
65 u8 sts_num;
66 u16 ctx_id;
67 u8 state;
68 u8 num_pci_func;
69 u8 phy_port;
70 u8 vport_id;
71 u32 host_csmr[QLCNIC_MAX_RING_SETS];
72 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
73} __packed;
74
75struct qlcnic_add_rings_mbx_out {
76 u8 rcv_num;
77 u8 sts_num;
78 u16 ctx_id;
79 u32 host_csmr[QLCNIC_MAX_RING_SETS];
80 struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
81} __packed;
82
83/* Transmit context mailbox inbox registers
84 * @phys_addr: DMA address of the transmit buffer
85 * @cnsmr_index: host consumer index
86 * @size: legth of transmit buffer ring
87 * @intr_id: interrput id
88 * @src: src of interrupt
89 */
90struct qlcnic_tx_mbx {
91 u64 phys_addr;
92 u64 cnsmr_index;
93 u16 size;
94 u16 intr_id;
95 u8 src;
96 u8 rsvd[3];
97} __packed;
98
99/* Transmit context mailbox outbox registers
100 * @host_prod: host producer index
101 * @ctx_id: transmit context id
102 * @state: state of the transmit context
103 */
104struct qlcnic_tx_mbx_out {
105 u32 host_prod;
106 u16 ctx_id;
107 u8 state;
108 u8 rsvd;
109} __packed;
110
111static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
112 {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
113 {QLCNIC_CMD_CONFIG_INTRPT, 18, 34},
114 {QLCNIC_CMD_CREATE_RX_CTX, 136, 27},
115 {QLCNIC_CMD_DESTROY_RX_CTX, 2, 1},
116 {QLCNIC_CMD_CREATE_TX_CTX, 54, 18},
117 {QLCNIC_CMD_DESTROY_TX_CTX, 2, 1},
118 {QLCNIC_CMD_CONFIGURE_MAC_LEARNING, 2, 1},
119 {QLCNIC_CMD_INTRPT_TEST, 22, 12},
120 {QLCNIC_CMD_SET_MTU, 3, 1},
121 {QLCNIC_CMD_READ_PHY, 4, 2},
122 {QLCNIC_CMD_WRITE_PHY, 5, 1},
123 {QLCNIC_CMD_READ_HW_REG, 4, 1},
124 {QLCNIC_CMD_GET_FLOW_CTL, 4, 2},
125 {QLCNIC_CMD_SET_FLOW_CTL, 4, 1},
126 {QLCNIC_CMD_READ_MAX_MTU, 4, 2},
127 {QLCNIC_CMD_READ_MAX_LRO, 4, 2},
128 {QLCNIC_CMD_MAC_ADDRESS, 4, 3},
129 {QLCNIC_CMD_GET_PCI_INFO, 1, 66},
130 {QLCNIC_CMD_GET_NIC_INFO, 2, 19},
131 {QLCNIC_CMD_SET_NIC_INFO, 32, 1},
132 {QLCNIC_CMD_GET_ESWITCH_CAPABILITY, 4, 3},
133 {QLCNIC_CMD_TOGGLE_ESWITCH, 4, 1},
134 {QLCNIC_CMD_GET_ESWITCH_STATUS, 4, 3},
135 {QLCNIC_CMD_SET_PORTMIRRORING, 4, 1},
136 {QLCNIC_CMD_CONFIGURE_ESWITCH, 4, 1},
137 {QLCNIC_CMD_GET_ESWITCH_PORT_CONFIG, 4, 3},
138 {QLCNIC_CMD_GET_ESWITCH_STATS, 5, 1},
139 {QLCNIC_CMD_CONFIG_PORT, 4, 1},
140 {QLCNIC_CMD_TEMP_SIZE, 1, 4},
141 {QLCNIC_CMD_GET_TEMP_HDR, 5, 5},
142 {QLCNIC_CMD_GET_LINK_EVENT, 2, 1},
143 {QLCNIC_CMD_CONFIG_MAC_VLAN, 4, 3},
144 {QLCNIC_CMD_CONFIG_INTR_COAL, 6, 1},
145 {QLCNIC_CMD_CONFIGURE_RSS, 14, 1},
146 {QLCNIC_CMD_CONFIGURE_LED, 2, 1},
147 {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, 2, 1},
148 {QLCNIC_CMD_CONFIGURE_HW_LRO, 2, 1},
149 {QLCNIC_CMD_GET_STATISTICS, 2, 80},
150 {QLCNIC_CMD_SET_PORT_CONFIG, 2, 1},
151 {QLCNIC_CMD_GET_PORT_CONFIG, 2, 2},
152 {QLCNIC_CMD_GET_LINK_STATUS, 2, 4},
153 {QLCNIC_CMD_IDC_ACK, 5, 1},
154 {QLCNIC_CMD_INIT_NIC_FUNC, 2, 1},
155 {QLCNIC_CMD_STOP_NIC_FUNC, 2, 1},
156 {QLCNIC_CMD_SET_LED_CONFIG, 5, 1},
157 {QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
158 {QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
159};
160
161static const u32 qlcnic_83xx_ext_reg_tbl[] = {
162 0x38CC, /* Global Reset */
163 0x38F0, /* Wildcard */
164 0x38FC, /* Informant */
165 0x3038, /* Host MBX ctrl */
166 0x303C, /* FW MBX ctrl */
167 0x355C, /* BOOT LOADER ADDRESS REG */
168 0x3560, /* BOOT LOADER SIZE REG */
169 0x3564, /* FW IMAGE ADDR REG */
170 0x1000, /* MBX intr enable */
171 0x1200, /* Default Intr mask */
172 0x1204, /* Default Interrupt ID */
173 0x3780, /* QLC_83XX_IDC_MAJ_VERSION */
174 0x3784, /* QLC_83XX_IDC_DEV_STATE */
175 0x3788, /* QLC_83XX_IDC_DRV_PRESENCE */
176 0x378C, /* QLC_83XX_IDC_DRV_ACK */
177 0x3790, /* QLC_83XX_IDC_CTRL */
178 0x3794, /* QLC_83XX_IDC_DRV_AUDIT */
179 0x3798, /* QLC_83XX_IDC_MIN_VERSION */
180 0x379C, /* QLC_83XX_RECOVER_DRV_LOCK */
181 0x37A0, /* QLC_83XX_IDC_PF_0 */
182 0x37A4, /* QLC_83XX_IDC_PF_1 */
183 0x37A8, /* QLC_83XX_IDC_PF_2 */
184 0x37AC, /* QLC_83XX_IDC_PF_3 */
185 0x37B0, /* QLC_83XX_IDC_PF_4 */
186 0x37B4, /* QLC_83XX_IDC_PF_5 */
187 0x37B8, /* QLC_83XX_IDC_PF_6 */
188 0x37BC, /* QLC_83XX_IDC_PF_7 */
189 0x37C0, /* QLC_83XX_IDC_PF_8 */
190 0x37C4, /* QLC_83XX_IDC_PF_9 */
191 0x37C8, /* QLC_83XX_IDC_PF_10 */
192 0x37CC, /* QLC_83XX_IDC_PF_11 */
193 0x37D0, /* QLC_83XX_IDC_PF_12 */
194 0x37D4, /* QLC_83XX_IDC_PF_13 */
195 0x37D8, /* QLC_83XX_IDC_PF_14 */
196 0x37DC, /* QLC_83XX_IDC_PF_15 */
197 0x37E0, /* QLC_83XX_IDC_DEV_PARTITION_INFO_1 */
198 0x37E4, /* QLC_83XX_IDC_DEV_PARTITION_INFO_2 */
199 0x37F0, /* QLC_83XX_DRV_OP_MODE */
200 0x37F4, /* QLC_83XX_VNIC_STATE */
201 0x3868, /* QLC_83XX_DRV_LOCK */
202 0x386C, /* QLC_83XX_DRV_UNLOCK */
203 0x3504, /* QLC_83XX_DRV_LOCK_ID */
204 0x34A4, /* QLC_83XX_ASIC_TEMP */
205};
206
207static const u32 qlcnic_83xx_reg_tbl[] = {
208 0x34A8, /* PEG_HALT_STAT1 */
209 0x34AC, /* PEG_HALT_STAT2 */
210 0x34B0, /* FW_HEARTBEAT */
211 0x3500, /* FLASH LOCK_ID */
212 0x3528, /* FW_CAPABILITIES */
213 0x3538, /* Driver active, DRV_REG0 */
214 0x3540, /* Device state, DRV_REG1 */
215 0x3544, /* Driver state, DRV_REG2 */
216 0x3548, /* Driver scratch, DRV_REG3 */
217 0x354C, /* Device partiton info, DRV_REG4 */
218 0x3524, /* Driver IDC ver, DRV_REG5 */
219 0x3550, /* FW_VER_MAJOR */
220 0x3554, /* FW_VER_MINOR */
221 0x3558, /* FW_VER_SUB */
222 0x359C, /* NPAR STATE */
223 0x35FC, /* FW_IMG_VALID */
224 0x3650, /* CMD_PEG_STATE */
225 0x373C, /* RCV_PEG_STATE */
226 0x37B4, /* ASIC TEMP */
227 0x356C, /* FW API */
228 0x3570, /* DRV OP MODE */
229 0x3850, /* FLASH LOCK */
230 0x3854, /* FLASH UNLOCK */
231};
232
233static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
234 .read_crb = qlcnic_83xx_read_crb,
235 .write_crb = qlcnic_83xx_write_crb,
236 .read_reg = qlcnic_83xx_rd_reg_indirect,
237 .write_reg = qlcnic_83xx_wrt_reg_indirect,
238 .get_mac_address = qlcnic_83xx_get_mac_address,
239 .setup_intr = qlcnic_83xx_setup_intr,
240 .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
241 .mbx_cmd = qlcnic_83xx_mbx_op,
242 .get_func_no = qlcnic_83xx_get_func_no,
243 .api_lock = qlcnic_83xx_cam_lock,
244 .api_unlock = qlcnic_83xx_cam_unlock,
319ecf12
SC
245 .add_sysfs = qlcnic_83xx_add_sysfs,
246 .remove_sysfs = qlcnic_83xx_remove_sysfs,
4be41e92 247 .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag,
7f966452
SC
248 .create_rx_ctx = qlcnic_83xx_create_rx_ctx,
249 .create_tx_ctx = qlcnic_83xx_create_tx_ctx,
250 .setup_link_event = qlcnic_83xx_setup_link_event,
251 .get_nic_info = qlcnic_83xx_get_nic_info,
252 .get_pci_info = qlcnic_83xx_get_pci_info,
253 .set_nic_info = qlcnic_83xx_set_nic_info,
254 .change_macvlan = qlcnic_83xx_sre_macaddr_change,
4be41e92
SC
255 .napi_enable = qlcnic_83xx_napi_enable,
256 .napi_disable = qlcnic_83xx_napi_disable,
7f966452
SC
257 .config_intr_coal = qlcnic_83xx_config_intr_coal,
258 .config_rss = qlcnic_83xx_config_rss,
259 .config_hw_lro = qlcnic_83xx_config_hw_lro,
260 .config_loopback = qlcnic_83xx_set_lb_mode,
261 .clear_loopback = qlcnic_83xx_clear_lb_mode,
262 .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
263 .change_l2_filter = qlcnic_83xx_change_l2_filter,
264 .get_board_info = qlcnic_83xx_get_port_info,
265};
266
267static struct qlcnic_nic_template qlcnic_83xx_ops = {
268 .config_bridged_mode = qlcnic_config_bridged_mode,
269 .config_led = qlcnic_config_led,
629263ac
SC
270 .request_reset = qlcnic_83xx_idc_request_reset,
271 .cancel_idc_work = qlcnic_83xx_idc_exit,
4be41e92
SC
272 .napi_add = qlcnic_83xx_napi_add,
273 .napi_del = qlcnic_83xx_napi_del,
7f966452
SC
274 .config_ipaddr = qlcnic_83xx_config_ipaddr,
275 .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
276};
277
278void qlcnic_83xx_register_map(struct qlcnic_hardware_context *ahw)
279{
280 ahw->hw_ops = &qlcnic_83xx_hw_ops;
281 ahw->reg_tbl = (u32 *)qlcnic_83xx_reg_tbl;
282 ahw->ext_reg_tbl = (u32 *)qlcnic_83xx_ext_reg_tbl;
283}
284
285int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *adapter)
286{
287 u32 fw_major, fw_minor, fw_build;
288 struct pci_dev *pdev = adapter->pdev;
289
290 fw_major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
291 fw_minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
292 fw_build = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
293 adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build);
294
295 dev_info(&pdev->dev, "Driver v%s, firmware version %d.%d.%d\n",
296 QLCNIC_LINUX_VERSIONID, fw_major, fw_minor, fw_build);
297
298 return adapter->fw_version;
299}
300
301static int __qlcnic_set_win_base(struct qlcnic_adapter *adapter, u32 addr)
302{
303 void __iomem *base;
304 u32 val;
305
306 base = adapter->ahw->pci_base0 +
307 QLC_83XX_CRB_WIN_FUNC(adapter->ahw->pci_func);
308 writel(addr, base);
309 val = readl(base);
310 if (val != addr)
311 return -EIO;
312
313 return 0;
314}
315
316int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *adapter, ulong addr)
317{
318 int ret;
319 struct qlcnic_hardware_context *ahw = adapter->ahw;
320
321 ret = __qlcnic_set_win_base(adapter, (u32) addr);
322 if (!ret) {
323 return QLCRDX(ahw, QLCNIC_WILDCARD);
324 } else {
325 dev_err(&adapter->pdev->dev,
326 "%s failed, addr = 0x%x\n", __func__, (int)addr);
327 return -EIO;
328 }
329}
330
331int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
332 u32 data)
333{
334 int err;
335 struct qlcnic_hardware_context *ahw = adapter->ahw;
336
337 err = __qlcnic_set_win_base(adapter, (u32) addr);
338 if (!err) {
339 QLCWRX(ahw, QLCNIC_WILDCARD, data);
340 return 0;
341 } else {
342 dev_err(&adapter->pdev->dev,
343 "%s failed, addr = 0x%x data = 0x%x\n",
344 __func__, (int)addr, data);
345 return err;
346 }
347}
348
349int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr)
350{
351 int err, i, num_msix;
352 struct qlcnic_hardware_context *ahw = adapter->ahw;
353
354 if (!num_intr)
355 num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
356 num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
357 num_intr));
358 /* account for AEN interrupt MSI-X based interrupts */
359 num_msix += 1;
360 num_msix += adapter->max_drv_tx_rings;
361 err = qlcnic_enable_msix(adapter, num_msix);
362 if (err == -ENOMEM)
363 return err;
364 if (adapter->flags & QLCNIC_MSIX_ENABLED)
365 num_msix = adapter->ahw->num_msix;
366 else
367 num_msix = 1;
368 /* setup interrupt mapping table for fw */
369 ahw->intr_tbl = vzalloc(num_msix *
370 sizeof(struct qlcnic_intrpt_config));
371 if (!ahw->intr_tbl)
372 return -ENOMEM;
373 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
374 /* MSI-X enablement failed, use legacy interrupt */
375 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
376 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
377 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
378 adapter->msix_entries[0].vector = adapter->pdev->irq;
379 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
380 }
381
382 for (i = 0; i < num_msix; i++) {
383 if (adapter->flags & QLCNIC_MSIX_ENABLED)
384 ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
385 else
386 ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
387 ahw->intr_tbl[i].id = i;
388 ahw->intr_tbl[i].src = 0;
389 }
390 return 0;
391}
392
393inline void qlcnic_83xx_enable_intr(struct qlcnic_adapter *adapter,
394 struct qlcnic_host_sds_ring *sds_ring)
395{
396 writel(0, sds_ring->crb_intr_mask);
397 if (!QLCNIC_IS_MSI_FAMILY(adapter))
398 writel(0, adapter->tgt_mask_reg);
399}
400
401static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
402 struct qlcnic_cmd_args *cmd)
403{
404 int i;
405 for (i = 0; i < cmd->rsp.num; i++)
406 cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
407}
408
409irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
410{
411 u32 intr_val;
412 struct qlcnic_hardware_context *ahw = adapter->ahw;
413 int retries = 0;
414
415 intr_val = readl(adapter->tgt_status_reg);
416
417 if (!QLC_83XX_VALID_INTX_BIT31(intr_val))
418 return IRQ_NONE;
419
420 if (QLC_83XX_INTX_FUNC(intr_val) != adapter->ahw->pci_func) {
421 adapter->stats.spurious_intr++;
422 return IRQ_NONE;
423 }
424 /* clear the interrupt trigger control register */
425 writel(0, adapter->isr_int_vec);
426 do {
427 intr_val = readl(adapter->tgt_status_reg);
428 if (QLC_83XX_INTX_FUNC(intr_val) != ahw->pci_func)
429 break;
430 retries++;
431 } while (QLC_83XX_VALID_INTX_BIT30(intr_val) &&
432 (retries < QLC_83XX_LEGACY_INTX_MAX_RETRY));
433
434 if (retries == QLC_83XX_LEGACY_INTX_MAX_RETRY) {
435 dev_info(&adapter->pdev->dev,
436 "Reached maximum retries to clear legacy interrupt\n");
437 return IRQ_NONE;
438 }
439
440 mdelay(QLC_83XX_LEGACY_INTX_DELAY);
441
442 return IRQ_HANDLED;
443}
444
445irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
446{
447 struct qlcnic_host_sds_ring *sds_ring = data;
448 struct qlcnic_adapter *adapter = sds_ring->adapter;
449
450 if (adapter->flags & QLCNIC_MSIX_ENABLED)
451 goto done;
452
453 if (adapter->nic_ops->clear_legacy_intr(adapter) == IRQ_NONE)
454 return IRQ_NONE;
455
456done:
457 adapter->ahw->diag_cnt++;
458 qlcnic_83xx_enable_intr(adapter, sds_ring);
459
460 return IRQ_HANDLED;
461}
462
463void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
464{
465 u32 val = 0;
466 u32 num_msix = adapter->ahw->num_msix - 1;
467
468 val = (num_msix << 8);
469
470 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
471 if (adapter->flags & QLCNIC_MSIX_ENABLED)
472 free_irq(adapter->msix_entries[num_msix].vector, adapter);
473}
474
475int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
476{
477 irq_handler_t handler;
478 u32 val;
479 char name[32];
480 int err = 0;
481 unsigned long flags = 0;
482
483 if (!(adapter->flags & QLCNIC_MSI_ENABLED) &&
484 !(adapter->flags & QLCNIC_MSIX_ENABLED))
485 flags |= IRQF_SHARED;
486
487 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
488 handler = qlcnic_83xx_handle_aen;
489 val = adapter->msix_entries[adapter->ahw->num_msix - 1].vector;
490 snprintf(name, (IFNAMSIZ + 4),
491 "%s[%s]", adapter->netdev->name, "aen");
492 err = request_irq(val, handler, flags, name, adapter);
493 if (err) {
494 dev_err(&adapter->pdev->dev,
495 "failed to register MBX interrupt\n");
496 return err;
497 }
498 }
499
500 /* Enable mailbox interrupt */
501 qlcnic_83xx_enable_mbx_intrpt(adapter);
502 if (adapter->flags & QLCNIC_MSIX_ENABLED)
503 err = qlcnic_83xx_config_intrpt(adapter, 1);
504
505 return err;
506}
507
508void qlcnic_83xx_get_func_no(struct qlcnic_adapter *adapter)
509{
510 u32 val = QLCRDX(adapter->ahw, QLCNIC_INFORMANT);
511 adapter->ahw->pci_func = val & 0xf;
512}
513
514int qlcnic_83xx_cam_lock(struct qlcnic_adapter *adapter)
515{
516 void __iomem *addr;
517 u32 val, limit = 0;
518
519 struct qlcnic_hardware_context *ahw = adapter->ahw;
520
521 addr = ahw->pci_base0 + QLC_83XX_SEM_LOCK_FUNC(ahw->pci_func);
522 do {
523 val = readl(addr);
524 if (val) {
525 /* write the function number to register */
526 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER,
527 ahw->pci_func);
528 return 0;
529 }
530 usleep_range(1000, 2000);
531 } while (++limit <= QLCNIC_PCIE_SEM_TIMEOUT);
532
533 return -EIO;
534}
535
536void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *adapter)
537{
538 void __iomem *addr;
539 u32 val;
540 struct qlcnic_hardware_context *ahw = adapter->ahw;
541
542 addr = ahw->pci_base0 + QLC_83XX_SEM_UNLOCK_FUNC(ahw->pci_func);
543 val = readl(addr);
544}
545
546void qlcnic_83xx_read_crb(struct qlcnic_adapter *adapter, char *buf,
547 loff_t offset, size_t size)
548{
549 int ret;
550 u32 data;
551
552 if (qlcnic_api_lock(adapter)) {
553 dev_err(&adapter->pdev->dev,
554 "%s: failed to acquire lock. addr offset 0x%x\n",
555 __func__, (u32)offset);
556 return;
557 }
558
559 ret = qlcnic_83xx_rd_reg_indirect(adapter, (u32) offset);
560 qlcnic_api_unlock(adapter);
561
562 if (ret == -EIO) {
563 dev_err(&adapter->pdev->dev,
564 "%s: failed. addr offset 0x%x\n",
565 __func__, (u32)offset);
566 return;
567 }
568 data = ret;
569 memcpy(buf, &data, size);
570}
571
572void qlcnic_83xx_write_crb(struct qlcnic_adapter *adapter, char *buf,
573 loff_t offset, size_t size)
574{
575 u32 data;
576
577 memcpy(&data, buf, size);
578 qlcnic_83xx_wrt_reg_indirect(adapter, (u32) offset, data);
579}
580
581int qlcnic_83xx_get_port_info(struct qlcnic_adapter *adapter)
582{
583 int status;
584
585 status = qlcnic_83xx_get_port_config(adapter);
586 if (status) {
587 dev_err(&adapter->pdev->dev,
588 "Get Port Info failed\n");
589 } else {
590 if (QLC_83XX_SFP_10G_CAPABLE(adapter->ahw->port_config))
591 adapter->ahw->port_type = QLCNIC_XGBE;
592 else
593 adapter->ahw->port_type = QLCNIC_GBE;
629263ac 594
7f966452
SC
595 if (QLC_83XX_AUTONEG(adapter->ahw->port_config))
596 adapter->ahw->link_autoneg = AUTONEG_ENABLE;
597 }
598 return status;
599}
600
601void qlcnic_83xx_enable_mbx_intrpt(struct qlcnic_adapter *adapter)
602{
603 u32 val;
604
605 if (adapter->flags & QLCNIC_MSIX_ENABLED)
606 val = BIT_2 | ((adapter->ahw->num_msix - 1) << 8);
607 else
608 val = BIT_2;
629263ac 609
7f966452
SC
610 QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, val);
611}
612
613void qlcnic_83xx_check_vf(struct qlcnic_adapter *adapter,
614 const struct pci_device_id *ent)
615{
616 u32 op_mode, priv_level;
617 struct qlcnic_hardware_context *ahw = adapter->ahw;
618
7f966452 619 ahw->fw_hal_version = 2;
7f966452
SC
620 qlcnic_get_func_no(adapter);
621
622 /* Determine function privilege level */
623 op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
624 if (op_mode == QLC_83XX_DEFAULT_OPMODE)
625 priv_level = QLCNIC_MGMT_FUNC;
626 else
627 priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
628 ahw->pci_func);
629
630 if (priv_level == QLCNIC_NON_PRIV_FUNC) {
631 ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
632 dev_info(&adapter->pdev->dev,
633 "HAL Version: %d Non Privileged function\n",
634 ahw->fw_hal_version);
635 adapter->nic_ops = &qlcnic_vf_ops;
636 } else {
637 adapter->nic_ops = &qlcnic_83xx_ops;
638 }
639}
640
641static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
642 u32 data[]);
643static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
644 u32 data[]);
645
646static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
647 struct qlcnic_cmd_args *cmd)
648{
649 int i;
650
651 dev_info(&adapter->pdev->dev,
652 "Host MBX regs(%d)\n", cmd->req.num);
653 for (i = 0; i < cmd->req.num; i++) {
654 if (i && !(i % 8))
655 pr_info("\n");
656 pr_info("%08x ", cmd->req.arg[i]);
657 }
658 pr_info("\n");
659 dev_info(&adapter->pdev->dev,
660 "FW MBX regs(%d)\n", cmd->rsp.num);
661 for (i = 0; i < cmd->rsp.num; i++) {
662 if (i && !(i % 8))
663 pr_info("\n");
664 pr_info("%08x ", cmd->rsp.arg[i]);
665 }
666 pr_info("\n");
667}
668
669static u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter)
670{
671 u32 data;
672 unsigned long wait_time = 0;
673 struct qlcnic_hardware_context *ahw = adapter->ahw;
674 /* wait for mailbox completion */
675 do {
676 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
677 if (++wait_time > QLCNIC_MBX_TIMEOUT) {
678 data = QLCNIC_RCODE_TIMEOUT;
679 break;
680 }
681 mdelay(1);
682 } while (!data);
683 return data;
684}
685
686int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
687 struct qlcnic_cmd_args *cmd)
688{
689 int i;
690 u16 opcode;
691 u8 mbx_err_code, mac_cmd_rcode;
483202d5 692 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
7f966452
SC
693 struct qlcnic_hardware_context *ahw = adapter->ahw;
694
695 opcode = LSW(cmd->req.arg[0]);
629263ac
SC
696 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
697 dev_info(&adapter->pdev->dev,
698 "Mailbox cmd attempted, 0x%x\n", opcode);
699 dev_info(&adapter->pdev->dev, "Mailbox detached\n");
700 return 0;
701 }
702
7f966452
SC
703 spin_lock(&ahw->mbx_lock);
704 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
705
706 if (mbx_val) {
707 QLCDB(adapter, DRV,
708 "Mailbox cmd attempted, 0x%x\n", opcode);
709 QLCDB(adapter, DRV,
710 "Mailbox not available, 0x%x, collect FW dump\n",
711 mbx_val);
712 cmd->rsp.arg[0] = QLCNIC_RCODE_TIMEOUT;
713 spin_unlock(&ahw->mbx_lock);
714 return cmd->rsp.arg[0];
715 }
716
717 /* Fill in mailbox registers */
718 mbx_cmd = cmd->req.arg[0];
719 writel(mbx_cmd, QLCNIC_MBX_HOST(ahw, 0));
720 for (i = 1; i < cmd->req.num; i++)
721 writel(cmd->req.arg[i], QLCNIC_MBX_HOST(ahw, i));
722
723 /* Signal FW about the impending command */
724 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
725poll:
726 rsp = qlcnic_83xx_mbx_poll(adapter);
727 /* Get the FW response data */
728 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
729 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
730 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
731 opcode = QLCNIC_MBX_RSP(fw_data);
732
733 if (rsp != QLCNIC_RCODE_TIMEOUT) {
483202d5
JK
734 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
735 qlcnic_83xx_process_aen(adapter);
7f966452
SC
736 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
737 if (mbx_val)
738 goto poll;
739 } else if ((mbx_err_code == QLCNIC_MBX_RSP_OK) ||
740 (mbx_err_code == QLCNIC_MBX_PORT_RSP_OK)) {
741 qlcnic_83xx_get_mbx_data(adapter, cmd);
742 rsp = QLCNIC_RCODE_SUCCESS;
743 } else {
744 qlcnic_83xx_get_mbx_data(adapter, cmd);
745 if (opcode == QLCNIC_CMD_CONFIG_MAC_VLAN) {
746 fw_data = readl(QLCNIC_MBX_FW(ahw, 2));
747 mac_cmd_rcode = (u8)fw_data;
748 if (mac_cmd_rcode == QLC_83XX_NO_NIC_RESOURCE ||
749 mac_cmd_rcode == QLC_83XX_MAC_PRESENT ||
750 mac_cmd_rcode == QLC_83XX_MAC_ABSENT) {
751 rsp = QLCNIC_RCODE_SUCCESS;
752 goto out;
753 }
754 }
755 dev_info(&adapter->pdev->dev,
756 "MBX command 0x%x failed with err:0x%x\n",
757 opcode, mbx_err_code);
758 rsp = mbx_err_code;
759 qlcnic_dump_mbx(adapter, cmd);
760 }
761 } else {
762 dev_info(&adapter->pdev->dev,
763 "MBX command 0x%x timed out\n", opcode);
764 qlcnic_dump_mbx(adapter, cmd);
765 }
766out:
767 /* clear fw mbx control register */
768 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
769 spin_unlock(&ahw->mbx_lock);
770 return rsp;
771}
772
773int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
774 struct qlcnic_adapter *adapter, u32 type)
775{
776 int i, size;
777 u32 temp;
778 const struct qlcnic_mailbox_metadata *mbx_tbl;
779
780 mbx_tbl = qlcnic_83xx_mbx_tbl;
781 size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
782 for (i = 0; i < size; i++) {
783 if (type == mbx_tbl[i].cmd) {
784 mbx->req.num = mbx_tbl[i].in_args;
785 mbx->rsp.num = mbx_tbl[i].out_args;
786 mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
787 GFP_ATOMIC);
788 if (!mbx->req.arg)
789 return -ENOMEM;
790 mbx->rsp.arg = kcalloc(mbx->rsp.num, sizeof(u32),
791 GFP_ATOMIC);
792 if (!mbx->rsp.arg) {
793 kfree(mbx->req.arg);
794 mbx->req.arg = NULL;
795 return -ENOMEM;
796 }
797 memset(mbx->req.arg, 0, sizeof(u32) * mbx->req.num);
798 memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
799 temp = adapter->ahw->fw_hal_version << 29;
800 mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
801 break;
802 }
803 }
804 return 0;
805}
806
807void qlcnic_83xx_idc_aen_work(struct work_struct *work)
808{
809 struct qlcnic_adapter *adapter;
810 struct qlcnic_cmd_args cmd;
811 int i, err = 0;
812
813 adapter = container_of(work, struct qlcnic_adapter, idc_aen_work.work);
814 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_IDC_ACK);
815
816 for (i = 1; i < QLC_83XX_MBX_AEN_CNT; i++)
817 cmd.req.arg[i] = adapter->ahw->mbox_aen[i];
818
819 err = qlcnic_issue_cmd(adapter, &cmd);
820 if (err)
821 dev_info(&adapter->pdev->dev,
822 "%s: Mailbox IDC ACK failed.\n", __func__);
823 qlcnic_free_mbx_args(&cmd);
824}
825
826static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
827 u32 data[])
828{
829 dev_dbg(&adapter->pdev->dev, "Completion AEN:0x%x.\n",
830 QLCNIC_MBX_RSP(data[0]));
629263ac 831 clear_bit(QLC_83XX_IDC_COMP_AEN, &adapter->ahw->idc.status);
7f966452
SC
832 return;
833}
834
835void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
836{
483202d5 837 u32 event[QLC_83XX_MBX_AEN_CNT];
7f966452
SC
838 int i;
839 struct qlcnic_hardware_context *ahw = adapter->ahw;
840
7f966452
SC
841 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
842 event[i] = readl(QLCNIC_MBX_FW(ahw, i));
843
844 switch (QLCNIC_MBX_RSP(event[0])) {
845
846 case QLCNIC_MBX_LINK_EVENT:
847 qlcnic_83xx_handle_link_aen(adapter, event);
848 break;
849 case QLCNIC_MBX_COMP_EVENT:
850 qlcnic_83xx_handle_idc_comp_aen(adapter, event);
851 break;
852 case QLCNIC_MBX_REQUEST_EVENT:
853 for (i = 0; i < QLC_83XX_MBX_AEN_CNT; i++)
854 adapter->ahw->mbox_aen[i] = QLCNIC_MBX_RSP(event[i]);
855 queue_delayed_work(adapter->qlcnic_wq,
856 &adapter->idc_aen_work, 0);
857 break;
858 case QLCNIC_MBX_TIME_EXTEND_EVENT:
859 break;
860 case QLCNIC_MBX_SFP_INSERT_EVENT:
861 dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
862 QLCNIC_MBX_RSP(event[0]));
863 break;
864 case QLCNIC_MBX_SFP_REMOVE_EVENT:
865 dev_info(&adapter->pdev->dev, "SFP Removed AEN:0x%x.\n",
866 QLCNIC_MBX_RSP(event[0]));
867 break;
868 default:
869 dev_dbg(&adapter->pdev->dev, "Unsupported AEN:0x%x.\n",
870 QLCNIC_MBX_RSP(event[0]));
871 break;
872 }
873
874 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
7f966452
SC
875}
876
877static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
878{
879 int index, i, err, sds_mbx_size;
880 u32 *buf, intrpt_id, intr_mask;
881 u16 context_id;
882 u8 num_sds;
883 struct qlcnic_cmd_args cmd;
884 struct qlcnic_host_sds_ring *sds;
885 struct qlcnic_sds_mbx sds_mbx;
886 struct qlcnic_add_rings_mbx_out *mbx_out;
887 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
888 struct qlcnic_hardware_context *ahw = adapter->ahw;
889
890 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
891 context_id = recv_ctx->context_id;
892 num_sds = (adapter->max_sds_rings - QLCNIC_MAX_RING_SETS);
893 ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
894 QLCNIC_CMD_ADD_RCV_RINGS);
895 cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
896
897 /* set up status rings, mbx 2-81 */
898 index = 2;
899 for (i = 8; i < adapter->max_sds_rings; i++) {
900 memset(&sds_mbx, 0, sds_mbx_size);
901 sds = &recv_ctx->sds_rings[i];
902 sds->consumer = 0;
903 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
904 sds_mbx.phy_addr = sds->phys_addr;
905 sds_mbx.sds_ring_size = sds->num_desc;
906
907 if (adapter->flags & QLCNIC_MSIX_ENABLED)
908 intrpt_id = ahw->intr_tbl[i].id;
909 else
910 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
911
912 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
913 sds_mbx.intrpt_id = intrpt_id;
914 else
915 sds_mbx.intrpt_id = 0xffff;
916 sds_mbx.intrpt_val = 0;
917 buf = &cmd.req.arg[index];
918 memcpy(buf, &sds_mbx, sds_mbx_size);
919 index += sds_mbx_size / sizeof(u32);
920 }
921
922 /* send the mailbox command */
923 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
924 if (err) {
925 dev_err(&adapter->pdev->dev,
926 "Failed to add rings %d\n", err);
927 goto out;
928 }
929
930 mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
931 index = 0;
932 /* status descriptor ring */
933 for (i = 8; i < adapter->max_sds_rings; i++) {
934 sds = &recv_ctx->sds_rings[i];
935 sds->crb_sts_consumer = ahw->pci_base0 +
936 mbx_out->host_csmr[index];
937 if (adapter->flags & QLCNIC_MSIX_ENABLED)
938 intr_mask = ahw->intr_tbl[i].src;
939 else
940 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
941
942 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
943 index++;
944 }
945out:
946 qlcnic_free_mbx_args(&cmd);
947 return err;
948}
949
950int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
951{
952 int i, err, index, sds_mbx_size, rds_mbx_size;
953 u8 num_sds, num_rds;
954 u32 *buf, intrpt_id, intr_mask, cap = 0;
955 struct qlcnic_host_sds_ring *sds;
956 struct qlcnic_host_rds_ring *rds;
957 struct qlcnic_sds_mbx sds_mbx;
958 struct qlcnic_rds_mbx rds_mbx;
959 struct qlcnic_cmd_args cmd;
960 struct qlcnic_rcv_mbx_out *mbx_out;
961 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
962 struct qlcnic_hardware_context *ahw = adapter->ahw;
963 num_rds = adapter->max_rds_rings;
964
965 if (adapter->max_sds_rings <= QLCNIC_MAX_RING_SETS)
966 num_sds = adapter->max_sds_rings;
967 else
968 num_sds = QLCNIC_MAX_RING_SETS;
969
970 sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
971 rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
972 cap = QLCNIC_CAP0_LEGACY_CONTEXT;
973
974 if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
975 cap |= QLC_83XX_FW_CAP_LRO_MSS;
976
977 /* set mailbox hdr and capabilities */
978 qlcnic_alloc_mbx_args(&cmd, adapter,
979 QLCNIC_CMD_CREATE_RX_CTX);
980 cmd.req.arg[1] = cap;
981 cmd.req.arg[5] = 1 | (num_rds << 5) | (num_sds << 8) |
982 (QLC_83XX_HOST_RDS_MODE_UNIQUE << 16);
983 /* set up status rings, mbx 8-57/87 */
984 index = QLC_83XX_HOST_SDS_MBX_IDX;
985 for (i = 0; i < num_sds; i++) {
986 memset(&sds_mbx, 0, sds_mbx_size);
987 sds = &recv_ctx->sds_rings[i];
988 sds->consumer = 0;
989 memset(sds->desc_head, 0, STATUS_DESC_RINGSIZE(sds));
990 sds_mbx.phy_addr = sds->phys_addr;
991 sds_mbx.sds_ring_size = sds->num_desc;
992 if (adapter->flags & QLCNIC_MSIX_ENABLED)
993 intrpt_id = ahw->intr_tbl[i].id;
994 else
995 intrpt_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
996 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
997 sds_mbx.intrpt_id = intrpt_id;
998 else
999 sds_mbx.intrpt_id = 0xffff;
1000 sds_mbx.intrpt_val = 0;
1001 buf = &cmd.req.arg[index];
1002 memcpy(buf, &sds_mbx, sds_mbx_size);
1003 index += sds_mbx_size / sizeof(u32);
1004 }
1005 /* set up receive rings, mbx 88-111/135 */
1006 index = QLCNIC_HOST_RDS_MBX_IDX;
1007 rds = &recv_ctx->rds_rings[0];
1008 rds->producer = 0;
1009 memset(&rds_mbx, 0, rds_mbx_size);
1010 rds_mbx.phy_addr_reg = rds->phys_addr;
1011 rds_mbx.reg_ring_sz = rds->dma_size;
1012 rds_mbx.reg_ring_len = rds->num_desc;
1013 /* Jumbo ring */
1014 rds = &recv_ctx->rds_rings[1];
1015 rds->producer = 0;
1016 rds_mbx.phy_addr_jmb = rds->phys_addr;
1017 rds_mbx.jmb_ring_sz = rds->dma_size;
1018 rds_mbx.jmb_ring_len = rds->num_desc;
1019 buf = &cmd.req.arg[index];
1020 memcpy(buf, &rds_mbx, rds_mbx_size);
1021
1022 /* send the mailbox command */
1023 err = ahw->hw_ops->mbx_cmd(adapter, &cmd);
1024 if (err) {
1025 dev_err(&adapter->pdev->dev,
1026 "Failed to create Rx ctx in firmware%d\n", err);
1027 goto out;
1028 }
1029 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd.rsp.arg[1];
1030 recv_ctx->context_id = mbx_out->ctx_id;
1031 recv_ctx->state = mbx_out->state;
1032 recv_ctx->virt_port = mbx_out->vport_id;
1033 dev_info(&adapter->pdev->dev, "Rx Context[%d] Created, state:0x%x\n",
1034 recv_ctx->context_id, recv_ctx->state);
1035 /* Receive descriptor ring */
1036 /* Standard ring */
1037 rds = &recv_ctx->rds_rings[0];
1038 rds->crb_rcv_producer = ahw->pci_base0 +
1039 mbx_out->host_prod[0].reg_buf;
1040 /* Jumbo ring */
1041 rds = &recv_ctx->rds_rings[1];
1042 rds->crb_rcv_producer = ahw->pci_base0 +
1043 mbx_out->host_prod[0].jmb_buf;
1044 /* status descriptor ring */
1045 for (i = 0; i < num_sds; i++) {
1046 sds = &recv_ctx->sds_rings[i];
1047 sds->crb_sts_consumer = ahw->pci_base0 +
1048 mbx_out->host_csmr[i];
1049 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1050 intr_mask = ahw->intr_tbl[i].src;
1051 else
1052 intr_mask = QLCRDX(ahw, QLCNIC_DEF_INT_MASK);
1053 sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
1054 }
1055
1056 if (adapter->max_sds_rings > QLCNIC_MAX_RING_SETS)
1057 err = qlcnic_83xx_add_rings(adapter);
1058out:
1059 qlcnic_free_mbx_args(&cmd);
1060 return err;
1061}
1062
1063int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1064 struct qlcnic_host_tx_ring *tx, int ring)
1065{
1066 int err;
1067 u16 msix_id;
1068 u32 *buf, intr_mask;
1069 struct qlcnic_cmd_args cmd;
1070 struct qlcnic_tx_mbx mbx;
1071 struct qlcnic_tx_mbx_out *mbx_out;
1072 struct qlcnic_hardware_context *ahw = adapter->ahw;
1073
1074 /* Reset host resources */
1075 tx->producer = 0;
1076 tx->sw_consumer = 0;
1077 *(tx->hw_consumer) = 0;
1078
1079 memset(&mbx, 0, sizeof(struct qlcnic_tx_mbx));
1080
1081 /* setup mailbox inbox registerss */
1082 mbx.phys_addr = tx->phys_addr;
1083 mbx.cnsmr_index = tx->hw_cons_phys_addr;
1084 mbx.size = tx->num_desc;
1085 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1086 msix_id = ahw->intr_tbl[adapter->max_sds_rings + ring].id;
1087 else
1088 msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
1089 if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
1090 mbx.intr_id = msix_id;
1091 else
1092 mbx.intr_id = 0xffff;
1093 mbx.src = 0;
1094
1095 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CREATE_TX_CTX);
1096 cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
1097 cmd.req.arg[5] = QLCNIC_MAX_TX_QUEUES;
1098 buf = &cmd.req.arg[6];
1099 memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
1100 /* send the mailbox command*/
1101 err = qlcnic_issue_cmd(adapter, &cmd);
1102 if (err) {
1103 dev_err(&adapter->pdev->dev,
1104 "Failed to create Tx ctx in firmware 0x%x\n", err);
1105 goto out;
1106 }
1107 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
1108 tx->crb_cmd_producer = ahw->pci_base0 + mbx_out->host_prod;
1109 tx->ctx_id = mbx_out->ctx_id;
1110 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
1111 intr_mask = ahw->intr_tbl[adapter->max_sds_rings + ring].src;
1112 tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1113 }
1114 dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n",
1115 tx->ctx_id, mbx_out->state);
1116out:
1117 qlcnic_free_mbx_args(&cmd);
1118 return err;
1119}
1120
319ecf12
SC
1121int qlcnic_83xx_config_led(struct qlcnic_adapter *adapter, u32 state,
1122 u32 beacon)
1123{
1124 struct qlcnic_cmd_args cmd;
1125 u32 mbx_in;
1126 int i, status = 0;
1127
1128 if (state) {
1129 /* Get LED configuration */
1130 qlcnic_alloc_mbx_args(&cmd, adapter,
1131 QLCNIC_CMD_GET_LED_CONFIG);
1132 status = qlcnic_issue_cmd(adapter, &cmd);
1133 if (status) {
1134 dev_err(&adapter->pdev->dev,
1135 "Get led config failed.\n");
1136 goto mbx_err;
1137 } else {
1138 for (i = 0; i < 4; i++)
1139 adapter->ahw->mbox_reg[i] = cmd.rsp.arg[i+1];
1140 }
1141 qlcnic_free_mbx_args(&cmd);
1142 /* Set LED Configuration */
1143 mbx_in = (LSW(QLC_83XX_LED_CONFIG) << 16) |
1144 LSW(QLC_83XX_LED_CONFIG);
1145 qlcnic_alloc_mbx_args(&cmd, adapter,
1146 QLCNIC_CMD_SET_LED_CONFIG);
1147 cmd.req.arg[1] = mbx_in;
1148 cmd.req.arg[2] = mbx_in;
1149 cmd.req.arg[3] = mbx_in;
1150 if (beacon)
1151 cmd.req.arg[4] = QLC_83XX_ENABLE_BEACON;
1152 status = qlcnic_issue_cmd(adapter, &cmd);
1153 if (status) {
1154 dev_err(&adapter->pdev->dev,
1155 "Set led config failed.\n");
1156 }
1157mbx_err:
1158 qlcnic_free_mbx_args(&cmd);
1159 return status;
1160
1161 } else {
1162 /* Restoring default LED configuration */
1163 qlcnic_alloc_mbx_args(&cmd, adapter,
1164 QLCNIC_CMD_SET_LED_CONFIG);
1165 cmd.req.arg[1] = adapter->ahw->mbox_reg[0];
1166 cmd.req.arg[2] = adapter->ahw->mbox_reg[1];
1167 cmd.req.arg[3] = adapter->ahw->mbox_reg[2];
1168 if (beacon)
1169 cmd.req.arg[4] = adapter->ahw->mbox_reg[3];
1170 status = qlcnic_issue_cmd(adapter, &cmd);
1171 if (status)
1172 dev_err(&adapter->pdev->dev,
1173 "Restoring led config failed.\n");
1174 qlcnic_free_mbx_args(&cmd);
1175 return status;
1176 }
1177}
1178
7f966452
SC
1179void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *adapter,
1180 int enable)
1181{
1182 struct qlcnic_cmd_args cmd;
1183 int status;
1184
1185 if (enable) {
1186 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INIT_NIC_FUNC);
d5fcff04 1187 cmd.req.arg[1] = BIT_0 | BIT_31;
7f966452
SC
1188 } else {
1189 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_STOP_NIC_FUNC);
d5fcff04 1190 cmd.req.arg[1] = BIT_0 | BIT_31;
7f966452
SC
1191 }
1192 status = qlcnic_issue_cmd(adapter, &cmd);
1193 if (status)
1194 dev_err(&adapter->pdev->dev,
1195 "Failed to %s in NIC IDC function event.\n",
1196 (enable ? "register" : "unregister"));
1197
1198 qlcnic_free_mbx_args(&cmd);
1199}
1200
1201int qlcnic_83xx_set_port_config(struct qlcnic_adapter *adapter)
1202{
1203 struct qlcnic_cmd_args cmd;
1204 int err;
1205
1206 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_PORT_CONFIG);
1207 cmd.req.arg[1] = adapter->ahw->port_config;
1208 err = qlcnic_issue_cmd(adapter, &cmd);
1209 if (err)
1210 dev_info(&adapter->pdev->dev, "Set Port Config failed.\n");
1211 qlcnic_free_mbx_args(&cmd);
1212 return err;
1213}
1214
1215int qlcnic_83xx_get_port_config(struct qlcnic_adapter *adapter)
1216{
1217 struct qlcnic_cmd_args cmd;
1218 int err;
1219
1220 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PORT_CONFIG);
1221 err = qlcnic_issue_cmd(adapter, &cmd);
1222 if (err)
1223 dev_info(&adapter->pdev->dev, "Get Port config failed\n");
1224 else
1225 adapter->ahw->port_config = cmd.rsp.arg[1];
1226 qlcnic_free_mbx_args(&cmd);
1227 return err;
1228}
1229
1230int qlcnic_83xx_setup_link_event(struct qlcnic_adapter *adapter, int enable)
1231{
1232 int err;
1233 u32 temp;
1234 struct qlcnic_cmd_args cmd;
1235
1236 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_EVENT);
1237 temp = adapter->recv_ctx->context_id << 16;
1238 cmd.req.arg[1] = (enable ? 1 : 0) | BIT_8 | temp;
1239 err = qlcnic_issue_cmd(adapter, &cmd);
1240 if (err)
1241 dev_info(&adapter->pdev->dev,
1242 "Setup linkevent mailbox failed\n");
1243 qlcnic_free_mbx_args(&cmd);
1244 return err;
1245}
1246
1247int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
1248{
1249 int err;
1250 u32 temp;
1251 struct qlcnic_cmd_args cmd;
1252
1253 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1254 return -EIO;
1255
1256 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_MAC_RX_MODE);
1257 temp = adapter->recv_ctx->context_id << 16;
1258 cmd.req.arg[1] = (mode ? 1 : 0) | temp;
1259 err = qlcnic_issue_cmd(adapter, &cmd);
1260 if (err)
1261 dev_info(&adapter->pdev->dev,
1262 "Promiscous mode config failed\n");
1263 qlcnic_free_mbx_args(&cmd);
1264
1265 return err;
1266}
1267
1268int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1269{
1270 struct qlcnic_hardware_context *ahw = adapter->ahw;
629263ac 1271 int status = 0, loop = 0;
7f966452
SC
1272 u32 config;
1273
1274 status = qlcnic_83xx_get_port_config(adapter);
1275 if (status)
1276 return status;
1277
1278 config = ahw->port_config;
629263ac 1279 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1280
1281 if (mode == QLCNIC_ILB_MODE)
1282 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_HSS;
1283 if (mode == QLCNIC_ELB_MODE)
1284 ahw->port_config |= QLC_83XX_CFG_LOOPBACK_EXT;
1285
1286 status = qlcnic_83xx_set_port_config(adapter);
1287 if (status) {
1288 dev_err(&adapter->pdev->dev,
1289 "Failed to Set Loopback Mode = 0x%x.\n",
1290 ahw->port_config);
1291 ahw->port_config = config;
629263ac 1292 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1293 return status;
1294 }
1295
629263ac
SC
1296 /* Wait until firmware send IDC Completion AEN */
1297 do {
1298 msleep(300);
1299 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1300 dev_err(&adapter->pdev->dev,
1301 "FW did not generate IDC completion AEN\n");
1302 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1303 return -EIO;
1304 }
1305 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1306
7f966452
SC
1307 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1308 QLCNIC_MAC_ADD);
1309 return status;
1310}
1311
1312int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1313{
1314 struct qlcnic_hardware_context *ahw = adapter->ahw;
629263ac 1315 int status = 0, loop = 0;
7f966452
SC
1316 u32 config = ahw->port_config;
1317
629263ac 1318 set_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1319 if (mode == QLCNIC_ILB_MODE)
1320 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_HSS;
1321 if (mode == QLCNIC_ELB_MODE)
1322 ahw->port_config &= ~QLC_83XX_CFG_LOOPBACK_EXT;
1323
1324 status = qlcnic_83xx_set_port_config(adapter);
1325 if (status) {
1326 dev_err(&adapter->pdev->dev,
1327 "Failed to Clear Loopback Mode = 0x%x.\n",
1328 ahw->port_config);
1329 ahw->port_config = config;
629263ac 1330 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
7f966452
SC
1331 return status;
1332 }
1333
629263ac
SC
1334 /* Wait until firmware send IDC Completion AEN */
1335 do {
1336 msleep(300);
1337 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1338 dev_err(&adapter->pdev->dev,
1339 "Firmware didn't sent IDC completion AEN\n");
1340 clear_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status);
1341 return -EIO;
1342 }
1343 } while (test_bit(QLC_83XX_IDC_COMP_AEN, &ahw->idc.status));
1344
7f966452
SC
1345 qlcnic_sre_macaddr_change(adapter, adapter->mac_addr, 0,
1346 QLCNIC_MAC_DEL);
1347 return status;
1348}
1349
1350void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
1351 int mode)
1352{
1353 int err;
283c1c68 1354 u32 temp, temp_ip;
7f966452
SC
1355 struct qlcnic_cmd_args cmd;
1356
1357 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_IP_ADDR);
1358 if (mode == QLCNIC_IP_UP) {
1359 temp = adapter->recv_ctx->context_id << 16;
1360 cmd.req.arg[1] = 1 | temp;
1361 } else {
1362 temp = adapter->recv_ctx->context_id << 16;
1363 cmd.req.arg[1] = 2 | temp;
1364 }
7f966452 1365
283c1c68
M
1366 /*
1367 * Adapter needs IP address in network byte order.
1368 * But hardware mailbox registers go through writel(), hence IP address
1369 * gets swapped on big endian architecture.
1370 * To negate swapping of writel() on big endian architecture
1371 * use swab32(value).
1372 */
1373
1374 temp_ip = swab32(ntohl(ip));
1375 memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
7f966452
SC
1376 err = qlcnic_issue_cmd(adapter, &cmd);
1377 if (err != QLCNIC_RCODE_SUCCESS)
1378 dev_err(&adapter->netdev->dev,
1379 "could not notify %s IP 0x%x request\n",
1380 (mode == QLCNIC_IP_UP) ? "Add" : "Remove", ip);
1381 qlcnic_free_mbx_args(&cmd);
1382}
1383
1384int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
1385{
1386 int err;
1387 u32 temp, arg1;
1388 struct qlcnic_cmd_args cmd;
283c1c68
M
1389 int lro_bit_mask;
1390
1391 lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
7f966452
SC
1392
1393 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1394 return 0;
1395
1396 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
1397 temp = adapter->recv_ctx->context_id << 16;
283c1c68 1398 arg1 = lro_bit_mask | temp;
7f966452
SC
1399 cmd.req.arg[1] = arg1;
1400
1401 err = qlcnic_issue_cmd(adapter, &cmd);
1402 if (err)
1403 dev_info(&adapter->pdev->dev, "LRO config failed\n");
1404 qlcnic_free_mbx_args(&cmd);
1405
1406 return err;
1407}
1408
1409int qlcnic_83xx_config_rss(struct qlcnic_adapter *adapter, int enable)
1410{
1411 int err;
1412 u32 word;
1413 struct qlcnic_cmd_args cmd;
1414 const u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
1415 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
1416 0x255b0ec26d5a56daULL };
1417
1418 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_RSS);
1419
1420 /*
1421 * RSS request:
1422 * bits 3-0: Rsvd
1423 * 5-4: hash_type_ipv4
1424 * 7-6: hash_type_ipv6
1425 * 8: enable
1426 * 9: use indirection table
1427 * 16-31: indirection table mask
1428 */
1429 word = ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
1430 ((u32)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
1431 ((u32)(enable & 0x1) << 8) |
1432 ((0x7ULL) << 16);
1433 cmd.req.arg[1] = (adapter->recv_ctx->context_id);
1434 cmd.req.arg[2] = word;
1435 memcpy(&cmd.req.arg[4], key, sizeof(key));
1436
1437 err = qlcnic_issue_cmd(adapter, &cmd);
1438
1439 if (err)
1440 dev_info(&adapter->pdev->dev, "RSS config failed\n");
1441 qlcnic_free_mbx_args(&cmd);
1442
1443 return err;
1444
1445}
1446
1447int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,
1448 __le16 vlan_id, u8 op)
1449{
1450 int err;
1451 u32 *buf;
1452 struct qlcnic_cmd_args cmd;
1453 struct qlcnic_macvlan_mbx mv;
1454
1455 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1456 return -EIO;
1457
1458 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
1459 if (err)
1460 return err;
1461 cmd.req.arg[1] = op | (1 << 8) |
1462 (adapter->recv_ctx->context_id << 16);
1463
1464 mv.vlan = le16_to_cpu(vlan_id);
1465 memcpy(&mv.mac, addr, ETH_ALEN);
1466 buf = &cmd.req.arg[2];
1467 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
1468 err = qlcnic_issue_cmd(adapter, &cmd);
1469 if (err)
1470 dev_err(&adapter->pdev->dev,
1471 "MAC-VLAN %s to CAM failed, err=%d.\n",
1472 ((op == 1) ? "add " : "delete "), err);
1473 qlcnic_free_mbx_args(&cmd);
1474 return err;
1475}
1476
1477void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *adapter, u64 *addr,
1478 __le16 vlan_id)
1479{
1480 u8 mac[ETH_ALEN];
1481 memcpy(&mac, addr, ETH_ALEN);
1482 qlcnic_83xx_sre_macaddr_change(adapter, mac, vlan_id, QLCNIC_MAC_ADD);
1483}
1484
1485void qlcnic_83xx_configure_mac(struct qlcnic_adapter *adapter, u8 *mac,
1486 u8 type, struct qlcnic_cmd_args *cmd)
1487{
1488 switch (type) {
1489 case QLCNIC_SET_STATION_MAC:
1490 case QLCNIC_SET_FAC_DEF_MAC:
1491 memcpy(&cmd->req.arg[2], mac, sizeof(u32));
1492 memcpy(&cmd->req.arg[3], &mac[4], sizeof(u16));
1493 break;
1494 }
1495 cmd->req.arg[1] = type;
1496}
1497
1498int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
1499{
1500 int err, i;
1501 struct qlcnic_cmd_args cmd;
1502 u32 mac_low, mac_high;
1503
1504 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_MAC_ADDRESS);
1505 qlcnic_83xx_configure_mac(adapter, mac, QLCNIC_GET_CURRENT_MAC, &cmd);
1506 err = qlcnic_issue_cmd(adapter, &cmd);
1507
1508 if (err == QLCNIC_RCODE_SUCCESS) {
1509 mac_low = cmd.rsp.arg[1];
1510 mac_high = cmd.rsp.arg[2];
1511
1512 for (i = 0; i < 2; i++)
1513 mac[i] = (u8) (mac_high >> ((1 - i) * 8));
1514 for (i = 2; i < 6; i++)
1515 mac[i] = (u8) (mac_low >> ((5 - i) * 8));
1516 } else {
1517 dev_err(&adapter->pdev->dev, "Failed to get mac address%d\n",
1518 err);
1519 err = -EIO;
1520 }
1521 qlcnic_free_mbx_args(&cmd);
1522 return err;
1523}
1524
1525void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
1526{
1527 int err;
1528 u32 temp;
1529 struct qlcnic_cmd_args cmd;
1530 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
1531
1532 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
1533 return;
1534
1535 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
1536 cmd.req.arg[1] = 1 | (adapter->recv_ctx->context_id << 16);
1537 cmd.req.arg[3] = coal->flag;
1538 temp = coal->rx_time_us << 16;
1539 cmd.req.arg[2] = coal->rx_packets | temp;
1540 err = qlcnic_issue_cmd(adapter, &cmd);
1541 if (err != QLCNIC_RCODE_SUCCESS)
1542 dev_info(&adapter->pdev->dev,
1543 "Failed to send interrupt coalescence parameters\n");
1544 qlcnic_free_mbx_args(&cmd);
1545}
1546
1547static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
1548 u32 data[])
1549{
1550 u8 link_status, duplex;
1551 /* link speed */
1552 link_status = LSB(data[3]) & 1;
1553 adapter->ahw->link_speed = MSW(data[2]);
1554 adapter->ahw->link_autoneg = MSB(MSW(data[3]));
1555 adapter->ahw->module_type = MSB(LSW(data[3]));
1556 duplex = LSB(MSW(data[3]));
1557 if (duplex)
1558 adapter->ahw->link_duplex = DUPLEX_FULL;
1559 else
1560 adapter->ahw->link_duplex = DUPLEX_HALF;
1561 adapter->ahw->has_link_events = 1;
1562 qlcnic_advert_link_change(adapter, link_status);
1563}
1564
1565irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
1566{
1567 struct qlcnic_adapter *adapter = data;
483202d5
JK
1568 unsigned long flags;
1569 u32 mask, resp, event;
1570
1571 spin_lock_irqsave(&adapter->ahw->mbx_lock, flags);
1572 resp = QLCRDX(adapter->ahw, QLCNIC_FW_MBX_CTRL);
1573 if (!(resp & QLCNIC_SET_OWNER))
1574 goto out;
1575 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
1576 if (event & QLCNIC_MBX_ASYNC_EVENT)
1577 qlcnic_83xx_process_aen(adapter);
1578out:
1579 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
1580 writel(0, adapter->ahw->pci_base0 + mask);
1581 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
1582
7f966452
SC
1583 return IRQ_HANDLED;
1584}
1585
1586int qlcnic_enable_eswitch(struct qlcnic_adapter *adapter, u8 port, u8 enable)
1587{
1588 int err = -EIO;
1589 struct qlcnic_cmd_args cmd;
1590
1591 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1592 dev_err(&adapter->pdev->dev,
1593 "%s: Error, invoked by non management func\n",
1594 __func__);
1595 return err;
1596 }
1597
1598 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH);
1599 cmd.req.arg[1] = (port & 0xf) | BIT_4;
1600 err = qlcnic_issue_cmd(adapter, &cmd);
1601
1602 if (err != QLCNIC_RCODE_SUCCESS) {
1603 dev_err(&adapter->pdev->dev, "Failed to enable eswitch%d\n",
1604 err);
1605 err = -EIO;
1606 }
1607 qlcnic_free_mbx_args(&cmd);
1608
1609 return err;
1610
1611}
1612
1613int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *adapter,
1614 struct qlcnic_info *nic)
1615{
1616 int i, err = -EIO;
1617 struct qlcnic_cmd_args cmd;
1618
1619 if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
1620 dev_err(&adapter->pdev->dev,
1621 "%s: Error, invoked by non management func\n",
1622 __func__);
1623 return err;
1624 }
1625
1626 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO);
1627 cmd.req.arg[1] = (nic->pci_func << 16);
1628 cmd.req.arg[2] = 0x1 << 16;
1629 cmd.req.arg[3] = nic->phys_port | (nic->switch_mode << 16);
1630 cmd.req.arg[4] = nic->capabilities;
1631 cmd.req.arg[5] = (nic->max_mac_filters & 0xFF) | ((nic->max_mtu) << 16);
1632 cmd.req.arg[6] = (nic->max_tx_ques) | ((nic->max_rx_ques) << 16);
1633 cmd.req.arg[7] = (nic->min_tx_bw) | ((nic->max_tx_bw) << 16);
1634 for (i = 8; i < 32; i++)
1635 cmd.req.arg[i] = 0;
1636
1637 err = qlcnic_issue_cmd(adapter, &cmd);
1638
1639 if (err != QLCNIC_RCODE_SUCCESS) {
1640 dev_err(&adapter->pdev->dev, "Failed to set nic info%d\n",
1641 err);
1642 err = -EIO;
1643 }
1644
1645 qlcnic_free_mbx_args(&cmd);
1646
1647 return err;
1648}
1649
1650int qlcnic_83xx_get_nic_info(struct qlcnic_adapter *adapter,
1651 struct qlcnic_info *npar_info, u8 func_id)
1652{
1653 int err;
1654 u32 temp;
1655 u8 op = 0;
1656 struct qlcnic_cmd_args cmd;
1657
1658 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO);
1659 if (func_id != adapter->ahw->pci_func) {
1660 temp = func_id << 16;
1661 cmd.req.arg[1] = op | BIT_31 | temp;
1662 } else {
1663 cmd.req.arg[1] = adapter->ahw->pci_func << 16;
1664 }
1665 err = qlcnic_issue_cmd(adapter, &cmd);
1666 if (err) {
1667 dev_info(&adapter->pdev->dev,
1668 "Failed to get nic info %d\n", err);
1669 goto out;
1670 }
1671
1672 npar_info->op_type = cmd.rsp.arg[1];
1673 npar_info->pci_func = cmd.rsp.arg[2] & 0xFFFF;
1674 npar_info->op_mode = (cmd.rsp.arg[2] & 0xFFFF0000) >> 16;
1675 npar_info->phys_port = cmd.rsp.arg[3] & 0xFFFF;
1676 npar_info->switch_mode = (cmd.rsp.arg[3] & 0xFFFF0000) >> 16;
1677 npar_info->capabilities = cmd.rsp.arg[4];
1678 npar_info->max_mac_filters = cmd.rsp.arg[5] & 0xFF;
1679 npar_info->max_mtu = (cmd.rsp.arg[5] & 0xFFFF0000) >> 16;
1680 npar_info->max_tx_ques = cmd.rsp.arg[6] & 0xFFFF;
1681 npar_info->max_rx_ques = (cmd.rsp.arg[6] & 0xFFFF0000) >> 16;
1682 npar_info->min_tx_bw = cmd.rsp.arg[7] & 0xFFFF;
1683 npar_info->max_tx_bw = (cmd.rsp.arg[7] & 0xFFFF0000) >> 16;
1684 if (cmd.rsp.arg[8] & 0x1)
1685 npar_info->max_bw_reg_offset = (cmd.rsp.arg[8] & 0x7FFE) >> 1;
1686 if (cmd.rsp.arg[8] & 0x10000) {
1687 temp = (cmd.rsp.arg[8] & 0x7FFE0000) >> 17;
1688 npar_info->max_linkspeed_reg_offset = temp;
1689 }
1690
1691out:
1692 qlcnic_free_mbx_args(&cmd);
1693 return err;
1694}
1695
1696int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *adapter,
1697 struct qlcnic_pci_info *pci_info)
1698{
1699 int i, err = 0, j = 0;
1700 u32 temp;
1701 struct qlcnic_cmd_args cmd;
1702
1703 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_PCI_INFO);
1704 err = qlcnic_issue_cmd(adapter, &cmd);
1705
1706 adapter->ahw->act_pci_func = 0;
1707 if (err == QLCNIC_RCODE_SUCCESS) {
1708 pci_info->func_count = cmd.rsp.arg[1] & 0xFF;
1709 dev_info(&adapter->pdev->dev,
1710 "%s: total functions = %d\n",
1711 __func__, pci_info->func_count);
1712 for (i = 2, j = 0; j < QLCNIC_MAX_PCI_FUNC; j++, pci_info++) {
1713 pci_info->id = cmd.rsp.arg[i] & 0xFFFF;
1714 pci_info->active = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1715 i++;
1716 pci_info->type = cmd.rsp.arg[i] & 0xFFFF;
1717 if (pci_info->type == QLCNIC_TYPE_NIC)
1718 adapter->ahw->act_pci_func++;
1719 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1720 pci_info->default_port = temp;
1721 i++;
1722 pci_info->tx_min_bw = cmd.rsp.arg[i] & 0xFFFF;
1723 temp = (cmd.rsp.arg[i] & 0xFFFF0000) >> 16;
1724 pci_info->tx_max_bw = temp;
1725 i = i + 2;
1726 memcpy(pci_info->mac, &cmd.rsp.arg[i], ETH_ALEN - 2);
1727 i++;
1728 memcpy(pci_info->mac + sizeof(u32), &cmd.rsp.arg[i], 2);
1729 i = i + 3;
1730
1731 dev_info(&adapter->pdev->dev, "%s:\n"
1732 "\tid = %d active = %d type = %d\n"
1733 "\tport = %d min bw = %d max bw = %d\n"
1734 "\tmac_addr = %pM\n", __func__,
1735 pci_info->id, pci_info->active, pci_info->type,
1736 pci_info->default_port, pci_info->tx_min_bw,
1737 pci_info->tx_max_bw, pci_info->mac);
1738 }
1739 } else {
1740 dev_err(&adapter->pdev->dev, "Failed to get PCI Info%d\n",
1741 err);
1742 err = -EIO;
1743 }
1744
1745 qlcnic_free_mbx_args(&cmd);
1746
1747 return err;
1748}
1749
1750int qlcnic_83xx_config_intrpt(struct qlcnic_adapter *adapter, bool op_type)
1751{
1752 int i, index, err;
1753 bool type;
1754 u8 max_ints;
1755 u32 val, temp;
1756 struct qlcnic_cmd_args cmd;
1757
1758 max_ints = adapter->ahw->num_msix;
1759 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTRPT);
1760 cmd.req.arg[1] = max_ints;
1761 for (i = 0, index = 2; i < max_ints; i++) {
1762 type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
1763 val = type | (adapter->ahw->intr_tbl[i].type << 4);
1764 if (adapter->ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
1765 val |= (adapter->ahw->intr_tbl[i].id << 16);
1766 cmd.req.arg[index++] = val;
1767 }
1768 err = qlcnic_issue_cmd(adapter, &cmd);
1769 if (err) {
1770 dev_err(&adapter->pdev->dev,
1771 "Failed to configure interrupts 0x%x\n", err);
1772 goto out;
1773 }
1774
1775 max_ints = cmd.rsp.arg[1];
1776 for (i = 0, index = 2; i < max_ints; i++, index += 2) {
1777 val = cmd.rsp.arg[index];
1778 if (LSB(val)) {
1779 dev_info(&adapter->pdev->dev,
1780 "Can't configure interrupt %d\n",
1781 adapter->ahw->intr_tbl[i].id);
1782 continue;
1783 }
1784 if (op_type) {
1785 adapter->ahw->intr_tbl[i].id = MSW(val);
1786 adapter->ahw->intr_tbl[i].enabled = 1;
1787 temp = cmd.rsp.arg[index + 1];
1788 adapter->ahw->intr_tbl[i].src = temp;
1789 } else {
1790 adapter->ahw->intr_tbl[i].id = i;
1791 adapter->ahw->intr_tbl[i].enabled = 0;
1792 adapter->ahw->intr_tbl[i].src = 0;
1793 }
1794 }
1795out:
1796 qlcnic_free_mbx_args(&cmd);
1797 return err;
1798}
d865ebb4
SC
1799
1800int qlcnic_83xx_lock_flash(struct qlcnic_adapter *adapter)
1801{
1802 int id, timeout = 0;
1803 u32 status = 0;
1804
1805 while (status == 0) {
1806 status = QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_LOCK);
1807 if (status)
1808 break;
1809
1810 if (++timeout >= QLC_83XX_FLASH_LOCK_TIMEOUT) {
1811 id = QLC_SHARED_REG_RD32(adapter,
1812 QLCNIC_FLASH_LOCK_OWNER);
1813 dev_err(&adapter->pdev->dev,
1814 "%s: failed, lock held by %d\n", __func__, id);
1815 return -EIO;
1816 }
1817 usleep_range(1000, 2000);
1818 }
1819
1820 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, adapter->portnum);
1821 return 0;
1822}
1823
1824void qlcnic_83xx_unlock_flash(struct qlcnic_adapter *adapter)
1825{
1826 QLC_SHARED_REG_RD32(adapter, QLCNIC_FLASH_UNLOCK);
1827 QLC_SHARED_REG_WR32(adapter, QLCNIC_FLASH_LOCK_OWNER, 0xFF);
1828}
1829
629263ac
SC
1830int qlcnic_83xx_lockless_flash_read32(struct qlcnic_adapter *adapter,
1831 u32 flash_addr, u8 *p_data,
1832 int count)
d865ebb4
SC
1833{
1834 int i, ret;
1835 u32 word, range, flash_offset, addr = flash_addr;
1836 ulong indirect_add, direct_window;
1837
1838 flash_offset = addr & (QLCNIC_FLASH_SECTOR_SIZE - 1);
1839 if (addr & 0x3) {
1840 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
1841 return -EIO;
1842 }
1843
1844 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_DIRECT_WINDOW,
1845 (addr));
1846
1847 range = flash_offset + (count * sizeof(u32));
1848 /* Check if data is spread across multiple sectors */
1849 if (range > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
1850
1851 /* Multi sector read */
1852 for (i = 0; i < count; i++) {
1853 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
1854 ret = qlcnic_83xx_rd_reg_indirect(adapter,
1855 indirect_add);
1856 if (ret == -EIO)
1857 return -EIO;
1858
1859 word = ret;
1860 *(u32 *)p_data = word;
1861 p_data = p_data + 4;
1862 addr = addr + 4;
1863 flash_offset = flash_offset + 4;
1864
1865 if (flash_offset > (QLCNIC_FLASH_SECTOR_SIZE - 1)) {
1866 direct_window = QLC_83XX_FLASH_DIRECT_WINDOW;
1867 /* This write is needed once for each sector */
1868 qlcnic_83xx_wrt_reg_indirect(adapter,
1869 direct_window,
1870 (addr));
1871 flash_offset = 0;
1872 }
1873 }
1874 } else {
1875 /* Single sector read */
1876 for (i = 0; i < count; i++) {
1877 indirect_add = QLC_83XX_FLASH_DIRECT_DATA(addr);
1878 ret = qlcnic_83xx_rd_reg_indirect(adapter,
1879 indirect_add);
1880 if (ret == -EIO)
1881 return -EIO;
1882
1883 word = ret;
1884 *(u32 *)p_data = word;
1885 p_data = p_data + 4;
1886 addr = addr + 4;
1887 }
1888 }
1889
1890 return 0;
1891}
1892
1893static int qlcnic_83xx_poll_flash_status_reg(struct qlcnic_adapter *adapter)
1894{
1895 u32 status;
1896 int retries = QLC_83XX_FLASH_READ_RETRY_COUNT;
1897
1898 do {
1899 status = qlcnic_83xx_rd_reg_indirect(adapter,
1900 QLC_83XX_FLASH_STATUS);
1901 if ((status & QLC_83XX_FLASH_STATUS_READY) ==
1902 QLC_83XX_FLASH_STATUS_READY)
1903 break;
1904
1905 msleep(QLC_83XX_FLASH_STATUS_REG_POLL_DELAY);
1906 } while (--retries);
1907
1908 if (!retries)
1909 return -EIO;
1910
1911 return 0;
1912}
1913
1914static int qlcnic_83xx_enable_flash_write_op(struct qlcnic_adapter *adapter)
1915{
1916 int ret;
1917 u32 cmd;
1918 cmd = adapter->ahw->fdt.write_statusreg_cmd;
1919 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
1920 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG | cmd));
1921 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
1922 adapter->ahw->fdt.write_enable_bits);
1923 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
1924 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
1925 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
1926 if (ret)
1927 return -EIO;
1928
1929 return 0;
1930}
1931
1932static int qlcnic_83xx_disable_flash_write_op(struct qlcnic_adapter *adapter)
1933{
1934 int ret;
1935
1936 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
1937 (QLC_83XX_FLASH_FDT_WRITE_DEF_SIG |
1938 adapter->ahw->fdt.write_statusreg_cmd));
1939 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
1940 adapter->ahw->fdt.write_disable_bits);
1941 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
1942 QLC_83XX_FLASH_SECOND_ERASE_MS_VAL);
1943 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
1944 if (ret)
1945 return -EIO;
1946
1947 return 0;
1948}
1949
1950int qlcnic_83xx_read_flash_mfg_id(struct qlcnic_adapter *adapter)
1951{
1952 int ret, mfg_id;
1953
1954 if (qlcnic_83xx_lock_flash(adapter))
1955 return -EIO;
1956
1957 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
1958 QLC_83XX_FLASH_FDT_READ_MFG_ID_VAL);
1959 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
1960 QLC_83XX_FLASH_READ_CTRL);
1961 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
1962 if (ret) {
1963 qlcnic_83xx_unlock_flash(adapter);
1964 return -EIO;
1965 }
1966
1967 mfg_id = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
1968 if (mfg_id == -EIO)
1969 return -EIO;
1970
1971 adapter->flash_mfg_id = (mfg_id & 0xFF);
1972 qlcnic_83xx_unlock_flash(adapter);
1973
1974 return 0;
1975}
1976
1977int qlcnic_83xx_read_flash_descriptor_table(struct qlcnic_adapter *adapter)
1978{
1979 int count, fdt_size, ret = 0;
1980
1981 fdt_size = sizeof(struct qlcnic_fdt);
1982 count = fdt_size / sizeof(u32);
1983
1984 if (qlcnic_83xx_lock_flash(adapter))
1985 return -EIO;
1986
1987 memset(&adapter->ahw->fdt, 0, fdt_size);
1988 ret = qlcnic_83xx_lockless_flash_read32(adapter, QLCNIC_FDT_LOCATION,
1989 (u8 *)&adapter->ahw->fdt,
1990 count);
1991
1992 qlcnic_83xx_unlock_flash(adapter);
1993 return ret;
1994}
1995
1996int qlcnic_83xx_erase_flash_sector(struct qlcnic_adapter *adapter,
1997 u32 sector_start_addr)
1998{
1999 u32 reversed_addr, addr1, addr2, cmd;
2000 int ret = -EIO;
2001
2002 if (qlcnic_83xx_lock_flash(adapter) != 0)
2003 return -EIO;
2004
2005 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2006 ret = qlcnic_83xx_enable_flash_write_op(adapter);
2007 if (ret) {
2008 qlcnic_83xx_unlock_flash(adapter);
2009 dev_err(&adapter->pdev->dev,
2010 "%s failed at %d\n",
2011 __func__, __LINE__);
2012 return ret;
2013 }
2014 }
2015
2016 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2017 if (ret) {
2018 qlcnic_83xx_unlock_flash(adapter);
2019 dev_err(&adapter->pdev->dev,
2020 "%s: failed at %d\n", __func__, __LINE__);
2021 return -EIO;
2022 }
2023
2024 addr1 = (sector_start_addr & 0xFF) << 16;
2025 addr2 = (sector_start_addr & 0xFF0000) >> 16;
2026 reversed_addr = addr1 | addr2;
2027
2028 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2029 reversed_addr);
2030 cmd = QLC_83XX_FLASH_FDT_ERASE_DEF_SIG | adapter->ahw->fdt.erase_cmd;
2031 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id)
2032 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, cmd);
2033 else
2034 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2035 QLC_83XX_FLASH_OEM_ERASE_SIG);
2036 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2037 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2038
2039 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2040 if (ret) {
2041 qlcnic_83xx_unlock_flash(adapter);
2042 dev_err(&adapter->pdev->dev,
2043 "%s: failed at %d\n", __func__, __LINE__);
2044 return -EIO;
2045 }
2046
2047 if (adapter->ahw->fdt.mfg_id == adapter->flash_mfg_id) {
2048 ret = qlcnic_83xx_disable_flash_write_op(adapter);
2049 if (ret) {
2050 qlcnic_83xx_unlock_flash(adapter);
2051 dev_err(&adapter->pdev->dev,
2052 "%s: failed at %d\n", __func__, __LINE__);
2053 return ret;
2054 }
2055 }
2056
2057 qlcnic_83xx_unlock_flash(adapter);
2058
2059 return 0;
2060}
2061
2062int qlcnic_83xx_flash_write32(struct qlcnic_adapter *adapter, u32 addr,
2063 u32 *p_data)
2064{
2065 int ret = -EIO;
2066 u32 addr1 = 0x00800000 | (addr >> 2);
2067
2068 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR, addr1);
2069 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data);
2070 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2071 QLC_83XX_FLASH_LAST_ERASE_MS_VAL);
2072 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2073 if (ret) {
2074 dev_err(&adapter->pdev->dev,
2075 "%s: failed at %d\n", __func__, __LINE__);
2076 return -EIO;
2077 }
2078
2079 return 0;
2080}
2081
2082int qlcnic_83xx_flash_bulk_write(struct qlcnic_adapter *adapter, u32 addr,
2083 u32 *p_data, int count)
2084{
2085 u32 temp;
2086 int ret = -EIO;
2087
2088 if ((count < QLC_83XX_FLASH_BULK_WRITE_MIN) ||
2089 (count > QLC_83XX_FLASH_BULK_WRITE_MAX)) {
2090 dev_err(&adapter->pdev->dev,
2091 "%s: Invalid word count\n", __func__);
2092 return -EIO;
2093 }
2094
2095 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2096 QLC_83XX_FLASH_SPI_CONTROL);
2097 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_SPI_CONTROL,
2098 (temp | QLC_83XX_FLASH_SPI_CTRL));
2099 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2100 QLC_83XX_FLASH_ADDR_TEMP_VAL);
2101
2102 /* First DWORD write */
2103 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2104 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2105 QLC_83XX_FLASH_FIRST_MS_PATTERN);
2106 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2107 if (ret) {
2108 dev_err(&adapter->pdev->dev,
2109 "%s: failed at %d\n", __func__, __LINE__);
2110 return -EIO;
2111 }
2112
2113 count--;
2114 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2115 QLC_83XX_FLASH_ADDR_SECOND_TEMP_VAL);
2116 /* Second to N-1 DWORD writes */
2117 while (count != 1) {
2118 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA,
2119 *p_data++);
2120 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2121 QLC_83XX_FLASH_SECOND_MS_PATTERN);
2122 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2123 if (ret) {
2124 dev_err(&adapter->pdev->dev,
2125 "%s: failed at %d\n", __func__, __LINE__);
2126 return -EIO;
2127 }
2128 count--;
2129 }
2130
2131 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2132 QLC_83XX_FLASH_ADDR_TEMP_VAL |
2133 (addr >> 2));
2134 /* Last DWORD write */
2135 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_WRDATA, *p_data++);
2136 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2137 QLC_83XX_FLASH_LAST_MS_PATTERN);
2138 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2139 if (ret) {
2140 dev_err(&adapter->pdev->dev,
2141 "%s: failed at %d\n", __func__, __LINE__);
2142 return -EIO;
2143 }
2144
2145 ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_SPI_STATUS);
2146 if ((ret & QLC_83XX_FLASH_SPI_CTRL) == QLC_83XX_FLASH_SPI_CTRL) {
2147 dev_err(&adapter->pdev->dev, "%s: failed at %d\n",
2148 __func__, __LINE__);
2149 /* Operation failed, clear error bit */
2150 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2151 QLC_83XX_FLASH_SPI_CONTROL);
2152 qlcnic_83xx_wrt_reg_indirect(adapter,
2153 QLC_83XX_FLASH_SPI_CONTROL,
2154 (temp | QLC_83XX_FLASH_SPI_CTRL));
2155 }
2156
2157 return 0;
2158}
629263ac
SC
2159
2160static void qlcnic_83xx_recover_driver_lock(struct qlcnic_adapter *adapter)
2161{
2162 u32 val, id;
2163
2164 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2165
2166 /* Check if recovery need to be performed by the calling function */
2167 if ((val & QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK) == 0) {
2168 val = val & ~0x3F;
2169 val = val | ((adapter->portnum << 2) |
2170 QLC_83XX_NEED_DRV_LOCK_RECOVERY);
2171 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2172 dev_info(&adapter->pdev->dev,
2173 "%s: lock recovery initiated\n", __func__);
2174 msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY);
2175 val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK);
2176 id = ((val >> 2) & 0xF);
2177 if (id == adapter->portnum) {
2178 val = val & ~QLC_83XX_DRV_LOCK_RECOVERY_STATUS_MASK;
2179 val = val | QLC_83XX_DRV_LOCK_RECOVERY_IN_PROGRESS;
2180 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2181 /* Force release the lock */
2182 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2183 /* Clear recovery bits */
2184 val = val & ~0x3F;
2185 QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val);
2186 dev_info(&adapter->pdev->dev,
2187 "%s: lock recovery completed\n", __func__);
2188 } else {
2189 dev_info(&adapter->pdev->dev,
2190 "%s: func %d to resume lock recovery process\n",
2191 __func__, id);
2192 }
2193 } else {
2194 dev_info(&adapter->pdev->dev,
2195 "%s: lock recovery initiated by other functions\n",
2196 __func__);
2197 }
2198}
2199
2200int qlcnic_83xx_lock_driver(struct qlcnic_adapter *adapter)
2201{
2202 u32 lock_alive_counter, val, id, i = 0, status = 0, temp = 0;
2203 int max_attempt = 0;
2204
2205 while (status == 0) {
2206 status = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK);
2207 if (status)
2208 break;
2209
2210 msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY);
2211 i++;
2212
2213 if (i == 1)
2214 temp = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2215
2216 if (i == QLC_83XX_DRV_LOCK_WAIT_COUNTER) {
2217 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2218 if (val == temp) {
2219 id = val & 0xFF;
2220 dev_info(&adapter->pdev->dev,
2221 "%s: lock to be recovered from %d\n",
2222 __func__, id);
2223 qlcnic_83xx_recover_driver_lock(adapter);
2224 i = 0;
2225 max_attempt++;
2226 } else {
2227 dev_err(&adapter->pdev->dev,
2228 "%s: failed to get lock\n", __func__);
2229 return -EIO;
2230 }
2231 }
2232
2233 /* Force exit from while loop after few attempts */
2234 if (max_attempt == QLC_83XX_MAX_DRV_LOCK_RECOVERY_ATTEMPT) {
2235 dev_err(&adapter->pdev->dev,
2236 "%s: failed to get lock\n", __func__);
2237 return -EIO;
2238 }
2239 }
2240
2241 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2242 lock_alive_counter = val >> 8;
2243 lock_alive_counter++;
2244 val = lock_alive_counter << 8 | adapter->portnum;
2245 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2246
2247 return 0;
2248}
2249
2250void qlcnic_83xx_unlock_driver(struct qlcnic_adapter *adapter)
2251{
2252 u32 val, lock_alive_counter, id;
2253
2254 val = QLCRDX(adapter->ahw, QLC_83XX_DRV_LOCK_ID);
2255 id = val & 0xFF;
2256 lock_alive_counter = val >> 8;
2257
2258 if (id != adapter->portnum)
2259 dev_err(&adapter->pdev->dev,
2260 "%s:Warning func %d is unlocking lock owned by %d\n",
2261 __func__, adapter->portnum, id);
2262
2263 val = (lock_alive_counter << 8) | 0xFF;
2264 QLCWRX(adapter->ahw, QLC_83XX_DRV_LOCK_ID, val);
2265 QLCRDX(adapter->ahw, QLC_83XX_DRV_UNLOCK);
2266}
2267
2268int qlcnic_83xx_ms_mem_write128(struct qlcnic_adapter *adapter, u64 addr,
2269 u32 *data, u32 count)
2270{
2271 int i, j, ret = 0;
2272 u32 temp;
2273
2274 /* Check alignment */
2275 if (addr & 0xF)
2276 return -EIO;
2277
2278 mutex_lock(&adapter->ahw->mem_lock);
2279 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_HI, 0);
2280
2281 for (i = 0; i < count; i++, addr += 16) {
2282 if (!((ADDR_IN_RANGE(addr, QLCNIC_ADDR_QDR_NET,
2283 QLCNIC_ADDR_QDR_NET_MAX)) ||
2284 (ADDR_IN_RANGE(addr, QLCNIC_ADDR_DDR_NET,
2285 QLCNIC_ADDR_DDR_NET_MAX)))) {
2286 mutex_unlock(&adapter->ahw->mem_lock);
2287 return -EIO;
2288 }
2289
2290 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_ADDR_LO, addr);
2291 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_LO,
2292 *data++);
2293 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_HI,
2294 *data++);
2295 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_ULO,
2296 *data++);
2297 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_WRTDATA_UHI,
2298 *data++);
2299 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2300 QLCNIC_TA_WRITE_ENABLE);
2301 qlcnic_83xx_wrt_reg_indirect(adapter, QLCNIC_MS_CTRL,
2302 QLCNIC_TA_WRITE_START);
2303
2304 for (j = 0; j < MAX_CTL_CHECK; j++) {
2305 temp = qlcnic_83xx_rd_reg_indirect(adapter,
2306 QLCNIC_MS_CTRL);
2307 if ((temp & TA_CTL_BUSY) == 0)
2308 break;
2309 }
2310
2311 /* Status check failure */
2312 if (j >= MAX_CTL_CHECK) {
2313 printk_ratelimited(KERN_WARNING
2314 "MS memory write failed\n");
2315 mutex_unlock(&adapter->ahw->mem_lock);
2316 return -EIO;
2317 }
2318 }
2319
2320 mutex_unlock(&adapter->ahw->mem_lock);
2321
2322 return ret;
2323}
81d0aeb0
SC
2324
2325int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
2326 u8 *p_data, int count)
2327{
2328 int i, ret;
2329 u32 word, addr = flash_addr;
2330 ulong indirect_addr;
2331
2332 if (qlcnic_83xx_lock_flash(adapter) != 0)
2333 return -EIO;
2334
2335 if (addr & 0x3) {
2336 dev_err(&adapter->pdev->dev, "Illegal addr = 0x%x\n", addr);
2337 qlcnic_83xx_unlock_flash(adapter);
2338 return -EIO;
2339 }
2340
2341 for (i = 0; i < count; i++) {
2342 if (qlcnic_83xx_wrt_reg_indirect(adapter,
2343 QLC_83XX_FLASH_DIRECT_WINDOW,
2344 (addr))) {
2345 qlcnic_83xx_unlock_flash(adapter);
2346 return -EIO;
2347 }
2348
2349 indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr);
2350 ret = qlcnic_83xx_rd_reg_indirect(adapter,
2351 indirect_addr);
2352 if (ret == -EIO)
2353 return -EIO;
2354 word = ret;
1403f43a 2355 *(u32 *)p_data = word;
81d0aeb0
SC
2356 p_data = p_data + 4;
2357 addr = addr + 4;
2358 }
2359
2360 qlcnic_83xx_unlock_flash(adapter);
2361
2362 return 0;
2363}
7e38d04b
SC
2364
2365int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
2366{
2367 int err;
2368 u32 config = 0, state;
2369 struct qlcnic_cmd_args cmd;
2370 struct qlcnic_hardware_context *ahw = adapter->ahw;
2371
2372 state = readl(ahw->pci_base0 + QLC_83XX_LINK_STATE(ahw->pci_func));
2373 if (!QLC_83xx_FUNC_VAL(state, ahw->pci_func)) {
2374 dev_info(&adapter->pdev->dev, "link state down\n");
2375 return config;
2376 }
2377 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
2378 err = qlcnic_issue_cmd(adapter, &cmd);
2379 if (err) {
2380 dev_info(&adapter->pdev->dev,
2381 "Get Link Status Command failed: 0x%x\n", err);
2382 goto out;
2383 } else {
2384 config = cmd.rsp.arg[1];
2385 switch (QLC_83XX_CURRENT_LINK_SPEED(config)) {
2386 case QLC_83XX_10M_LINK:
2387 ahw->link_speed = SPEED_10;
2388 break;
2389 case QLC_83XX_100M_LINK:
2390 ahw->link_speed = SPEED_100;
2391 break;
2392 case QLC_83XX_1G_LINK:
2393 ahw->link_speed = SPEED_1000;
2394 break;
2395 case QLC_83XX_10G_LINK:
2396 ahw->link_speed = SPEED_10000;
2397 break;
2398 default:
2399 ahw->link_speed = 0;
2400 break;
2401 }
2402 config = cmd.rsp.arg[3];
2403 if (config & 1)
2404 err = 1;
2405 }
2406out:
2407 qlcnic_free_mbx_args(&cmd);
2408 return config;
2409}
2410
2411int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter)
2412{
2413 u32 config = 0;
2414 int status = 0;
2415 struct qlcnic_hardware_context *ahw = adapter->ahw;
2416
2417 /* Get port configuration info */
2418 status = qlcnic_83xx_get_port_info(adapter);
2419 /* Get Link Status related info */
2420 config = qlcnic_83xx_test_link(adapter);
2421 ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
2422 /* hard code until there is a way to get it from flash */
2423 ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
2424 return status;
2425}
2426
2427int qlcnic_83xx_set_settings(struct qlcnic_adapter *adapter,
2428 struct ethtool_cmd *ecmd)
2429{
2430 int status = 0;
2431 u32 config = adapter->ahw->port_config;
2432
2433 if (ecmd->autoneg)
2434 adapter->ahw->port_config |= BIT_15;
2435
2436 switch (ethtool_cmd_speed(ecmd)) {
2437 case SPEED_10:
2438 adapter->ahw->port_config |= BIT_8;
2439 break;
2440 case SPEED_100:
2441 adapter->ahw->port_config |= BIT_9;
2442 break;
2443 case SPEED_1000:
2444 adapter->ahw->port_config |= BIT_10;
2445 break;
2446 case SPEED_10000:
2447 adapter->ahw->port_config |= BIT_11;
2448 break;
2449 default:
2450 return -EINVAL;
2451 }
2452
2453 status = qlcnic_83xx_set_port_config(adapter);
2454 if (status) {
2455 dev_info(&adapter->pdev->dev,
2456 "Faild to Set Link Speed and autoneg.\n");
2457 adapter->ahw->port_config = config;
2458 }
2459 return status;
2460}
2461
2462static inline u64 *qlcnic_83xx_copy_stats(struct qlcnic_cmd_args *cmd,
2463 u64 *data, int index)
2464{
2465 u32 low, hi;
2466 u64 val;
2467
2468 low = cmd->rsp.arg[index];
2469 hi = cmd->rsp.arg[index + 1];
2470 val = (((u64) low) | (((u64) hi) << 32));
2471 *data++ = val;
2472 return data;
2473}
2474
2475static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter,
2476 struct qlcnic_cmd_args *cmd, u64 *data,
2477 int type, int *ret)
2478{
2479 int err, k, total_regs;
2480
2481 *ret = 0;
2482 err = qlcnic_issue_cmd(adapter, cmd);
2483 if (err != QLCNIC_RCODE_SUCCESS) {
2484 dev_info(&adapter->pdev->dev,
2485 "Error in get statistics mailbox command\n");
2486 *ret = -EIO;
2487 return data;
2488 }
2489 total_regs = cmd->rsp.num;
2490 switch (type) {
2491 case QLC_83XX_STAT_MAC:
2492 /* fill in MAC tx counters */
2493 for (k = 2; k < 28; k += 2)
2494 data = qlcnic_83xx_copy_stats(cmd, data, k);
2495 /* skip 24 bytes of reserved area */
2496 /* fill in MAC rx counters */
2497 for (k += 6; k < 60; k += 2)
2498 data = qlcnic_83xx_copy_stats(cmd, data, k);
2499 /* skip 24 bytes of reserved area */
2500 /* fill in MAC rx frame stats */
2501 for (k += 6; k < 80; k += 2)
2502 data = qlcnic_83xx_copy_stats(cmd, data, k);
2503 break;
2504 case QLC_83XX_STAT_RX:
2505 for (k = 2; k < 8; k += 2)
2506 data = qlcnic_83xx_copy_stats(cmd, data, k);
2507 /* skip 8 bytes of reserved data */
2508 for (k += 2; k < 24; k += 2)
2509 data = qlcnic_83xx_copy_stats(cmd, data, k);
2510 /* skip 8 bytes containing RE1FBQ error data */
2511 for (k += 2; k < total_regs; k += 2)
2512 data = qlcnic_83xx_copy_stats(cmd, data, k);
2513 break;
2514 case QLC_83XX_STAT_TX:
2515 for (k = 2; k < 10; k += 2)
2516 data = qlcnic_83xx_copy_stats(cmd, data, k);
2517 /* skip 8 bytes of reserved data */
2518 for (k += 2; k < total_regs; k += 2)
2519 data = qlcnic_83xx_copy_stats(cmd, data, k);
2520 break;
2521 default:
2522 dev_warn(&adapter->pdev->dev, "Unknown get statistics mode\n");
2523 *ret = -EIO;
2524 }
2525 return data;
2526}
2527
2528void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data)
2529{
2530 struct qlcnic_cmd_args cmd;
2531 int ret = 0;
2532
2533 qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_STATISTICS);
2534 /* Get Tx stats */
2535 cmd.req.arg[1] = BIT_1 | (adapter->tx_ring->ctx_id << 16);
2536 cmd.rsp.num = QLC_83XX_TX_STAT_REGS;
2537 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
2538 QLC_83XX_STAT_TX, &ret);
2539 if (ret) {
2540 dev_info(&adapter->pdev->dev, "Error getting MAC stats\n");
2541 goto out;
2542 }
2543 /* Get MAC stats */
2544 cmd.req.arg[1] = BIT_2 | (adapter->portnum << 16);
2545 cmd.rsp.num = QLC_83XX_MAC_STAT_REGS;
2546 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
2547 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
2548 QLC_83XX_STAT_MAC, &ret);
2549 if (ret) {
2550 dev_info(&adapter->pdev->dev,
2551 "Error getting Rx stats\n");
2552 goto out;
2553 }
2554 /* Get Rx stats */
2555 cmd.req.arg[1] = adapter->recv_ctx->context_id << 16;
2556 cmd.rsp.num = QLC_83XX_RX_STAT_REGS;
2557 memset(cmd.rsp.arg, 0, sizeof(u32) * cmd.rsp.num);
2558 data = qlcnic_83xx_fill_stats(adapter, &cmd, data,
2559 QLC_83XX_STAT_RX, &ret);
2560 if (ret)
2561 dev_info(&adapter->pdev->dev,
2562 "Error getting Tx stats\n");
2563out:
2564 qlcnic_free_mbx_args(&cmd);
2565}
2566
2567int qlcnic_83xx_reg_test(struct qlcnic_adapter *adapter)
2568{
2569 u32 major, minor, sub;
2570
2571 major = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MAJOR);
2572 minor = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_MINOR);
2573 sub = QLC_SHARED_REG_RD32(adapter, QLCNIC_FW_VERSION_SUB);
2574
2575 if (adapter->fw_version != QLCNIC_VERSION_CODE(major, minor, sub)) {
2576 dev_info(&adapter->pdev->dev, "%s: Reg test failed\n",
2577 __func__);
2578 return 1;
2579 }
2580 return 0;
2581}
2582
2583int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *adapter)
2584{
2585 return (ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl) *
2586 sizeof(adapter->ahw->ext_reg_tbl)) +
2587 (ARRAY_SIZE(qlcnic_83xx_reg_tbl) +
2588 sizeof(adapter->ahw->reg_tbl));
2589}
2590
2591int qlcnic_83xx_get_registers(struct qlcnic_adapter *adapter, u32 *regs_buff)
2592{
2593 int i, j = 0;
2594
2595 for (i = QLCNIC_DEV_INFO_SIZE + 1;
2596 j < ARRAY_SIZE(qlcnic_83xx_reg_tbl); i++, j++)
2597 regs_buff[i] = QLC_SHARED_REG_RD32(adapter, j);
2598
2599 for (j = 0; j < ARRAY_SIZE(qlcnic_83xx_ext_reg_tbl); j++)
2600 regs_buff[i++] = QLCRDX(adapter->ahw, j);
2601 return i;
2602}
2603
2604int qlcnic_83xx_interrupt_test(struct qlcnic_adapter *adapter,
2605 struct qlcnic_cmd_args *cmd)
2606{
2607 u8 val;
2608 int ret;
2609 u32 data;
2610 u16 intrpt_id, id;
2611
2612 if (adapter->flags & QLCNIC_MSIX_ENABLED)
2613 intrpt_id = adapter->ahw->intr_tbl[0].id;
2614 else
2615 intrpt_id = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_ID);
2616
2617 cmd->req.arg[1] = 1;
2618 cmd->req.arg[2] = intrpt_id;
2619 cmd->req.arg[3] = BIT_0;
2620
2621 ret = qlcnic_issue_cmd(adapter, cmd);
2622 data = cmd->rsp.arg[2];
2623 id = LSW(data);
2624 val = LSB(MSW(data));
2625 if (id != intrpt_id)
2626 dev_info(&adapter->pdev->dev,
2627 "Interrupt generated: 0x%x, requested:0x%x\n",
2628 id, intrpt_id);
2629 if (val)
2630 dev_info(&adapter->pdev->dev,
2631 "Interrupt test error: 0x%x\n", val);
2632
2633 return ret;
2634}
2635
2636void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *adapter,
2637 struct ethtool_pauseparam *pause)
2638{
2639 struct qlcnic_hardware_context *ahw = adapter->ahw;
2640 int status = 0;
2641 u32 config;
2642
2643 status = qlcnic_83xx_get_port_config(adapter);
2644 if (status) {
2645 dev_err(&adapter->pdev->dev,
2646 "%s: Get Pause Config failed\n", __func__);
2647 return;
2648 }
2649 config = ahw->port_config;
2650 if (config & QLC_83XX_CFG_STD_PAUSE) {
2651 if (config & QLC_83XX_CFG_STD_TX_PAUSE)
2652 pause->tx_pause = 1;
2653 if (config & QLC_83XX_CFG_STD_RX_PAUSE)
2654 pause->rx_pause = 1;
2655 }
2656
2657 if (QLC_83XX_AUTONEG(config))
2658 pause->autoneg = 1;
2659}
2660
2661int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *adapter,
2662 struct ethtool_pauseparam *pause)
2663{
2664 struct qlcnic_hardware_context *ahw = adapter->ahw;
2665 int status = 0;
2666 u32 config;
2667
2668 status = qlcnic_83xx_get_port_config(adapter);
2669 if (status) {
2670 dev_err(&adapter->pdev->dev,
2671 "%s: Get Pause Config failed.\n", __func__);
2672 return status;
2673 }
2674 config = ahw->port_config;
2675
2676 if (ahw->port_type == QLCNIC_GBE) {
2677 if (pause->autoneg)
2678 ahw->port_config |= QLC_83XX_ENABLE_AUTONEG;
2679 if (!pause->autoneg)
2680 ahw->port_config &= ~QLC_83XX_ENABLE_AUTONEG;
2681 } else if ((ahw->port_type == QLCNIC_XGBE) && (pause->autoneg)) {
2682 return -EOPNOTSUPP;
2683 }
2684
2685 if (!(config & QLC_83XX_CFG_STD_PAUSE))
2686 ahw->port_config |= QLC_83XX_CFG_STD_PAUSE;
2687
2688 if (pause->rx_pause && pause->tx_pause) {
2689 ahw->port_config |= QLC_83XX_CFG_STD_TX_RX_PAUSE;
2690 } else if (pause->rx_pause && !pause->tx_pause) {
2691 ahw->port_config &= ~QLC_83XX_CFG_STD_TX_PAUSE;
2692 ahw->port_config |= QLC_83XX_CFG_STD_RX_PAUSE;
2693 } else if (pause->tx_pause && !pause->rx_pause) {
2694 ahw->port_config &= ~QLC_83XX_CFG_STD_RX_PAUSE;
2695 ahw->port_config |= QLC_83XX_CFG_STD_TX_PAUSE;
2696 } else if (!pause->rx_pause && !pause->tx_pause) {
2697 ahw->port_config &= ~QLC_83XX_CFG_STD_TX_RX_PAUSE;
2698 }
2699 status = qlcnic_83xx_set_port_config(adapter);
2700 if (status) {
2701 dev_err(&adapter->pdev->dev,
2702 "%s: Set Pause Config failed.\n", __func__);
2703 ahw->port_config = config;
2704 }
2705 return status;
2706}
2707
2708static int qlcnic_83xx_read_flash_status_reg(struct qlcnic_adapter *adapter)
2709{
2710 int ret;
2711
2712 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_ADDR,
2713 QLC_83XX_FLASH_OEM_READ_SIG);
2714 qlcnic_83xx_wrt_reg_indirect(adapter, QLC_83XX_FLASH_CONTROL,
2715 QLC_83XX_FLASH_READ_CTRL);
2716 ret = qlcnic_83xx_poll_flash_status_reg(adapter);
2717 if (ret)
2718 return -EIO;
2719
2720 ret = qlcnic_83xx_rd_reg_indirect(adapter, QLC_83XX_FLASH_RDDATA);
2721 return ret & 0xFF;
2722}
2723
2724int qlcnic_83xx_flash_test(struct qlcnic_adapter *adapter)
2725{
2726 int status;
2727
2728 status = qlcnic_83xx_read_flash_status_reg(adapter);
2729 if (status == -EIO) {
2730 dev_info(&adapter->pdev->dev, "%s: EEPROM test failed.\n",
2731 __func__);
2732 return 1;
2733 }
2734 return 0;
2735}