]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/net/qlcnic/qlcnic_ctx.c
qlcnic: offload tx timeout recovery
[net-next-2.6.git] / drivers / net / qlcnic / qlcnic_ctx.c
CommitLineData
af19b491
AKS
1/*
2 * Copyright (C) 2009 - QLogic Corporation.
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 * MA 02111-1307, USA.
19 *
20 * The full GNU General Public License is included in this distribution
21 * in the file called "COPYING".
22 *
23 */
24
25#include "qlcnic.h"
26
af19b491
AKS
27static u32
28qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
29{
30 u32 rsp;
31 int timeout = 0;
32
33 do {
34 /* give atleast 1ms for firmware to respond */
35 msleep(1);
36
37 if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
38 return QLCNIC_CDRP_RSP_TIMEOUT;
39
40 rsp = QLCRD32(adapter, QLCNIC_CDRP_CRB_OFFSET);
41 } while (!QLCNIC_CDRP_IS_RSP(rsp));
42
43 return rsp;
44}
45
7eb9855d 46u32
af19b491
AKS
47qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
48 u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
49{
50 u32 rsp;
51 u32 signature;
52 u32 rcode = QLCNIC_RCODE_SUCCESS;
53 struct pci_dev *pdev = adapter->pdev;
54
55 signature = QLCNIC_CDRP_SIGNATURE_MAKE(pci_fn, version);
56
57 /* Acquire semaphore before accessing CRB */
58 if (qlcnic_api_lock(adapter))
59 return QLCNIC_RCODE_TIMEOUT;
60
61 QLCWR32(adapter, QLCNIC_SIGN_CRB_OFFSET, signature);
62 QLCWR32(adapter, QLCNIC_ARG1_CRB_OFFSET, arg1);
63 QLCWR32(adapter, QLCNIC_ARG2_CRB_OFFSET, arg2);
64 QLCWR32(adapter, QLCNIC_ARG3_CRB_OFFSET, arg3);
65 QLCWR32(adapter, QLCNIC_CDRP_CRB_OFFSET, QLCNIC_CDRP_FORM_CMD(cmd));
66
67 rsp = qlcnic_poll_rsp(adapter);
68
69 if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
70 dev_err(&pdev->dev, "card response timeout.\n");
71 rcode = QLCNIC_RCODE_TIMEOUT;
72 } else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
73 rcode = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
74 dev_err(&pdev->dev, "failed card response code:0x%x\n",
75 rcode);
76 }
77
78 /* Release semaphore */
79 qlcnic_api_unlock(adapter);
80
81 return rcode;
82}
83
84int
85qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)
86{
87 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
88
89 if (recv_ctx->state == QLCNIC_HOST_CTX_STATE_ACTIVE) {
90 if (qlcnic_issue_cmd(adapter,
2e9d722d
AC
91 adapter->ahw.pci_func,
92 adapter->fw_hal_version,
93 recv_ctx->context_id,
94 mtu,
95 0,
96 QLCNIC_CDRP_CMD_SET_MTU)) {
af19b491
AKS
97
98 dev_err(&adapter->pdev->dev, "Failed to set mtu\n");
99 return -EIO;
100 }
101 }
102
103 return 0;
104}
105
106static int
107qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
108{
109 void *addr;
110 struct qlcnic_hostrq_rx_ctx *prq;
111 struct qlcnic_cardrsp_rx_ctx *prsp;
112 struct qlcnic_hostrq_rds_ring *prq_rds;
113 struct qlcnic_hostrq_sds_ring *prq_sds;
114 struct qlcnic_cardrsp_rds_ring *prsp_rds;
115 struct qlcnic_cardrsp_sds_ring *prsp_sds;
116 struct qlcnic_host_rds_ring *rds_ring;
117 struct qlcnic_host_sds_ring *sds_ring;
118
119 dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
120 u64 phys_addr;
121
122 int i, nrds_rings, nsds_rings;
123 size_t rq_size, rsp_size;
2e9d722d 124 u32 cap, reg, val, reg2;
af19b491
AKS
125 int err;
126
127 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
128
129 nrds_rings = adapter->max_rds_rings;
130 nsds_rings = adapter->max_sds_rings;
131
132 rq_size =
133 SIZEOF_HOSTRQ_RX(struct qlcnic_hostrq_rx_ctx, nrds_rings,
134 nsds_rings);
135 rsp_size =
136 SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
137 nsds_rings);
138
139 addr = pci_alloc_consistent(adapter->pdev,
140 rq_size, &hostrq_phys_addr);
141 if (addr == NULL)
142 return -ENOMEM;
143 prq = (struct qlcnic_hostrq_rx_ctx *)addr;
144
145 addr = pci_alloc_consistent(adapter->pdev,
146 rsp_size, &cardrsp_phys_addr);
147 if (addr == NULL) {
148 err = -ENOMEM;
149 goto out_free_rq;
150 }
151 prsp = (struct qlcnic_cardrsp_rx_ctx *)addr;
152
153 prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr);
154
8f891387 155 cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN
156 | QLCNIC_CAP0_VALIDOFF);
af19b491
AKS
157 cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
158
8f891387 159 prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx,
160 msix_handler);
161 prq->txrx_sds_binding = nsds_rings - 1;
162
af19b491
AKS
163 prq->capabilities[0] = cpu_to_le32(cap);
164 prq->host_int_crb_mode =
165 cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
166 prq->host_rds_crb_mode =
167 cpu_to_le32(QLCNIC_HOST_RDS_CRB_MODE_UNIQUE);
168
169 prq->num_rds_rings = cpu_to_le16(nrds_rings);
170 prq->num_sds_rings = cpu_to_le16(nsds_rings);
171 prq->rds_ring_offset = cpu_to_le32(0);
172
173 val = le32_to_cpu(prq->rds_ring_offset) +
174 (sizeof(struct qlcnic_hostrq_rds_ring) * nrds_rings);
175 prq->sds_ring_offset = cpu_to_le32(val);
176
177 prq_rds = (struct qlcnic_hostrq_rds_ring *)(prq->data +
178 le32_to_cpu(prq->rds_ring_offset));
179
180 for (i = 0; i < nrds_rings; i++) {
181
182 rds_ring = &recv_ctx->rds_rings[i];
8a15ad1f 183 rds_ring->producer = 0;
af19b491
AKS
184
185 prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
186 prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
187 prq_rds[i].ring_kind = cpu_to_le32(i);
188 prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
189 }
190
191 prq_sds = (struct qlcnic_hostrq_sds_ring *)(prq->data +
192 le32_to_cpu(prq->sds_ring_offset));
193
194 for (i = 0; i < nsds_rings; i++) {
195
196 sds_ring = &recv_ctx->sds_rings[i];
8a15ad1f
AKS
197 sds_ring->consumer = 0;
198 memset(sds_ring->desc_head, 0, STATUS_DESC_RINGSIZE(sds_ring));
af19b491
AKS
199
200 prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
201 prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
202 prq_sds[i].msi_index = cpu_to_le16(i);
203 }
204
205 phys_addr = hostrq_phys_addr;
206 err = qlcnic_issue_cmd(adapter,
207 adapter->ahw.pci_func,
2e9d722d 208 adapter->fw_hal_version,
af19b491
AKS
209 (u32)(phys_addr >> 32),
210 (u32)(phys_addr & 0xffffffff),
211 rq_size,
212 QLCNIC_CDRP_CMD_CREATE_RX_CTX);
213 if (err) {
214 dev_err(&adapter->pdev->dev,
215 "Failed to create rx ctx in firmware%d\n", err);
216 goto out_free_rsp;
217 }
218
219
220 prsp_rds = ((struct qlcnic_cardrsp_rds_ring *)
221 &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]);
222
223 for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) {
224 rds_ring = &recv_ctx->rds_rings[i];
225
226 reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
2e9d722d
AC
227 if (adapter->fw_hal_version == QLCNIC_FW_BASE)
228 rds_ring->crb_rcv_producer = qlcnic_get_ioaddr(adapter,
af19b491 229 QLCNIC_REG(reg - 0x200));
2e9d722d
AC
230 else
231 rds_ring->crb_rcv_producer = adapter->ahw.pci_base0 +
232 reg;
af19b491
AKS
233 }
234
235 prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
236 &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
237
238 for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
239 sds_ring = &recv_ctx->sds_rings[i];
240
241 reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
2e9d722d 242 reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb);
af19b491 243
2e9d722d
AC
244 if (adapter->fw_hal_version == QLCNIC_FW_BASE) {
245 sds_ring->crb_sts_consumer = qlcnic_get_ioaddr(adapter,
af19b491 246 QLCNIC_REG(reg - 0x200));
2e9d722d
AC
247 sds_ring->crb_intr_mask = qlcnic_get_ioaddr(adapter,
248 QLCNIC_REG(reg2 - 0x200));
249 } else {
250 sds_ring->crb_sts_consumer = adapter->ahw.pci_base0 +
251 reg;
252 sds_ring->crb_intr_mask = adapter->ahw.pci_base0 + reg2;
253 }
af19b491
AKS
254 }
255
256 recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
257 recv_ctx->context_id = le16_to_cpu(prsp->context_id);
258 recv_ctx->virt_port = prsp->virt_port;
259
260out_free_rsp:
261 pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
262out_free_rq:
263 pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
264 return err;
265}
266
267static void
268qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter)
269{
270 struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
271
272 if (qlcnic_issue_cmd(adapter,
273 adapter->ahw.pci_func,
2e9d722d 274 adapter->fw_hal_version,
af19b491
AKS
275 recv_ctx->context_id,
276 QLCNIC_DESTROY_CTX_RESET,
277 0,
278 QLCNIC_CDRP_CMD_DESTROY_RX_CTX)) {
279
280 dev_err(&adapter->pdev->dev,
281 "Failed to destroy rx ctx in firmware\n");
282 }
283}
284
285static int
286qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
287{
288 struct qlcnic_hostrq_tx_ctx *prq;
289 struct qlcnic_hostrq_cds_ring *prq_cds;
290 struct qlcnic_cardrsp_tx_ctx *prsp;
291 void *rq_addr, *rsp_addr;
292 size_t rq_size, rsp_size;
293 u32 temp;
294 int err;
295 u64 phys_addr;
296 dma_addr_t rq_phys_addr, rsp_phys_addr;
297 struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
298
8a15ad1f
AKS
299 /* reset host resources */
300 tx_ring->producer = 0;
301 tx_ring->sw_consumer = 0;
302 *(tx_ring->hw_consumer) = 0;
303
af19b491
AKS
304 rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
305 rq_addr = pci_alloc_consistent(adapter->pdev,
306 rq_size, &rq_phys_addr);
307 if (!rq_addr)
308 return -ENOMEM;
309
310 rsp_size = SIZEOF_CARDRSP_TX(struct qlcnic_cardrsp_tx_ctx);
311 rsp_addr = pci_alloc_consistent(adapter->pdev,
312 rsp_size, &rsp_phys_addr);
313 if (!rsp_addr) {
314 err = -ENOMEM;
315 goto out_free_rq;
316 }
317
318 memset(rq_addr, 0, rq_size);
319 prq = (struct qlcnic_hostrq_tx_ctx *)rq_addr;
320
321 memset(rsp_addr, 0, rsp_size);
322 prsp = (struct qlcnic_cardrsp_tx_ctx *)rsp_addr;
323
324 prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);
325
326 temp = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN |
327 QLCNIC_CAP0_LSO);
328 prq->capabilities[0] = cpu_to_le32(temp);
329
330 prq->host_int_crb_mode =
331 cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
332
333 prq->interrupt_ctl = 0;
334 prq->msi_index = 0;
335 prq->cmd_cons_dma_addr = cpu_to_le64(tx_ring->hw_cons_phys_addr);
336
337 prq_cds = &prq->cds_ring;
338
339 prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
340 prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
341
342 phys_addr = rq_phys_addr;
343 err = qlcnic_issue_cmd(adapter,
344 adapter->ahw.pci_func,
2e9d722d 345 adapter->fw_hal_version,
af19b491
AKS
346 (u32)(phys_addr >> 32),
347 ((u32)phys_addr & 0xffffffff),
348 rq_size,
349 QLCNIC_CDRP_CMD_CREATE_TX_CTX);
350
351 if (err == QLCNIC_RCODE_SUCCESS) {
352 temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
2e9d722d
AC
353 if (adapter->fw_hal_version == QLCNIC_FW_BASE)
354 tx_ring->crb_cmd_producer = qlcnic_get_ioaddr(adapter,
af19b491 355 QLCNIC_REG(temp - 0x200));
2e9d722d
AC
356 else
357 tx_ring->crb_cmd_producer = adapter->ahw.pci_base0 +
358 temp;
af19b491
AKS
359
360 adapter->tx_context_id =
361 le16_to_cpu(prsp->context_id);
362 } else {
363 dev_err(&adapter->pdev->dev,
364 "Failed to create tx ctx in firmware%d\n", err);
365 err = -EIO;
366 }
367
368 pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);
369
370out_free_rq:
371 pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);
372
373 return err;
374}
375
376static void
377qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
378{
379 if (qlcnic_issue_cmd(adapter,
380 adapter->ahw.pci_func,
2e9d722d 381 adapter->fw_hal_version,
af19b491
AKS
382 adapter->tx_context_id,
383 QLCNIC_DESTROY_CTX_RESET,
384 0,
385 QLCNIC_CDRP_CMD_DESTROY_TX_CTX)) {
386
387 dev_err(&adapter->pdev->dev,
388 "Failed to destroy tx ctx in firmware\n");
389 }
390}
391
392int
393qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val)
394{
395
396 if (qlcnic_issue_cmd(adapter,
397 adapter->ahw.pci_func,
2e9d722d 398 adapter->fw_hal_version,
af19b491
AKS
399 reg,
400 0,
401 0,
402 QLCNIC_CDRP_CMD_READ_PHY)) {
403
404 return -EIO;
405 }
406
407 return QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
408}
409
410int
411qlcnic_fw_cmd_set_phy(struct qlcnic_adapter *adapter, u32 reg, u32 val)
412{
413 return qlcnic_issue_cmd(adapter,
414 adapter->ahw.pci_func,
2e9d722d 415 adapter->fw_hal_version,
af19b491
AKS
416 reg,
417 val,
418 0,
419 QLCNIC_CDRP_CMD_WRITE_PHY);
420}
421
422int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
423{
424 void *addr;
425 int err;
426 int ring;
427 struct qlcnic_recv_context *recv_ctx;
428 struct qlcnic_host_rds_ring *rds_ring;
429 struct qlcnic_host_sds_ring *sds_ring;
430 struct qlcnic_host_tx_ring *tx_ring;
431
432 struct pci_dev *pdev = adapter->pdev;
433
434 recv_ctx = &adapter->recv_ctx;
435 tx_ring = adapter->tx_ring;
436
437 tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, sizeof(u32),
438 &tx_ring->hw_cons_phys_addr);
439 if (tx_ring->hw_consumer == NULL) {
440 dev_err(&pdev->dev, "failed to allocate tx consumer\n");
441 return -ENOMEM;
442 }
443 *(tx_ring->hw_consumer) = 0;
444
445 /* cmd desc ring */
446 addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
447 &tx_ring->phys_addr);
448
449 if (addr == NULL) {
450 dev_err(&pdev->dev, "failed to allocate tx desc ring\n");
aadd8184
AC
451 err = -ENOMEM;
452 goto err_out_free;
af19b491
AKS
453 }
454
455 tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
456
457 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
458 rds_ring = &recv_ctx->rds_rings[ring];
459 addr = pci_alloc_consistent(adapter->pdev,
460 RCV_DESC_RINGSIZE(rds_ring),
461 &rds_ring->phys_addr);
462 if (addr == NULL) {
463 dev_err(&pdev->dev,
464 "failed to allocate rds ring [%d]\n", ring);
465 err = -ENOMEM;
466 goto err_out_free;
467 }
468 rds_ring->desc_head = (struct rcv_desc *)addr;
469
470 }
471
472 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
473 sds_ring = &recv_ctx->sds_rings[ring];
474
475 addr = pci_alloc_consistent(adapter->pdev,
476 STATUS_DESC_RINGSIZE(sds_ring),
477 &sds_ring->phys_addr);
478 if (addr == NULL) {
479 dev_err(&pdev->dev,
480 "failed to allocate sds ring [%d]\n", ring);
481 err = -ENOMEM;
482 goto err_out_free;
483 }
484 sds_ring->desc_head = (struct status_desc *)addr;
485 }
486
af19b491
AKS
487 return 0;
488
489err_out_free:
490 qlcnic_free_hw_resources(adapter);
491 return err;
492}
493
8a15ad1f
AKS
494
495int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter)
af19b491 496{
8a15ad1f
AKS
497 int err;
498
499 err = qlcnic_fw_cmd_create_rx_ctx(adapter);
500 if (err)
501 return err;
502
503 err = qlcnic_fw_cmd_create_tx_ctx(adapter);
504 if (err) {
505 qlcnic_fw_cmd_destroy_rx_ctx(adapter);
506 return err;
507 }
af19b491 508
8a15ad1f
AKS
509 set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
510 return 0;
511}
af19b491 512
8a15ad1f
AKS
513void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
514{
af19b491
AKS
515 if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
516 qlcnic_fw_cmd_destroy_rx_ctx(adapter);
517 qlcnic_fw_cmd_destroy_tx_ctx(adapter);
518
519 /* Allow dma queues to drain after context reset */
520 msleep(20);
521 }
8a15ad1f
AKS
522}
523
524void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
525{
526 struct qlcnic_recv_context *recv_ctx;
527 struct qlcnic_host_rds_ring *rds_ring;
528 struct qlcnic_host_sds_ring *sds_ring;
529 struct qlcnic_host_tx_ring *tx_ring;
530 int ring;
af19b491
AKS
531
532 recv_ctx = &adapter->recv_ctx;
533
534 tx_ring = adapter->tx_ring;
535 if (tx_ring->hw_consumer != NULL) {
536 pci_free_consistent(adapter->pdev,
537 sizeof(u32),
538 tx_ring->hw_consumer,
539 tx_ring->hw_cons_phys_addr);
540 tx_ring->hw_consumer = NULL;
541 }
542
543 if (tx_ring->desc_head != NULL) {
544 pci_free_consistent(adapter->pdev,
545 TX_DESC_RINGSIZE(tx_ring),
546 tx_ring->desc_head, tx_ring->phys_addr);
547 tx_ring->desc_head = NULL;
548 }
549
550 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
551 rds_ring = &recv_ctx->rds_rings[ring];
552
553 if (rds_ring->desc_head != NULL) {
554 pci_free_consistent(adapter->pdev,
555 RCV_DESC_RINGSIZE(rds_ring),
556 rds_ring->desc_head,
557 rds_ring->phys_addr);
558 rds_ring->desc_head = NULL;
559 }
560 }
561
562 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
563 sds_ring = &recv_ctx->sds_rings[ring];
564
565 if (sds_ring->desc_head != NULL) {
566 pci_free_consistent(adapter->pdev,
567 STATUS_DESC_RINGSIZE(sds_ring),
568 sds_ring->desc_head,
569 sds_ring->phys_addr);
570 sds_ring->desc_head = NULL;
571 }
572 }
573}
574
2e9d722d
AC
575/* Set MAC address of a NIC partition */
576int qlcnic_set_mac_address(struct qlcnic_adapter *adapter, u8* mac)
577{
578 int err = 0;
579 u32 arg1, arg2, arg3;
580
581 arg1 = adapter->ahw.pci_func | BIT_9;
582 arg2 = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24);
583 arg3 = mac[4] | (mac[5] << 16);
584
585 err = qlcnic_issue_cmd(adapter,
586 adapter->ahw.pci_func,
587 adapter->fw_hal_version,
588 arg1,
589 arg2,
590 arg3,
591 QLCNIC_CDRP_CMD_MAC_ADDRESS);
592
593 if (err != QLCNIC_RCODE_SUCCESS) {
594 dev_err(&adapter->pdev->dev,
595 "Failed to set mac address%d\n", err);
596 err = -EIO;
597 }
598
599 return err;
600}
601
602/* Get MAC address of a NIC partition */
603int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
604{
605 int err;
606 u32 arg1;
607
608 arg1 = adapter->ahw.pci_func | BIT_8;
609 err = qlcnic_issue_cmd(adapter,
610 adapter->ahw.pci_func,
611 adapter->fw_hal_version,
612 arg1,
613 0,
614 0,
615 QLCNIC_CDRP_CMD_MAC_ADDRESS);
616
7f9a0c34 617 if (err == QLCNIC_RCODE_SUCCESS)
2e9d722d
AC
618 qlcnic_fetch_mac(adapter, QLCNIC_ARG1_CRB_OFFSET,
619 QLCNIC_ARG2_CRB_OFFSET, 0, mac);
7f9a0c34 620 else {
2e9d722d
AC
621 dev_err(&adapter->pdev->dev,
622 "Failed to get mac address%d\n", err);
623 err = -EIO;
624 }
625
626 return err;
627}
628
629/* Get info of a NIC partition */
630int qlcnic_get_nic_info(struct qlcnic_adapter *adapter, u8 func_id)
631{
632 int err;
633 dma_addr_t nic_dma_t;
634 struct qlcnic_info *nic_info;
635 void *nic_info_addr;
636 size_t nic_size = sizeof(struct qlcnic_info);
637
638 nic_info_addr = pci_alloc_consistent(adapter->pdev,
639 nic_size, &nic_dma_t);
640 if (!nic_info_addr)
641 return -ENOMEM;
642 memset(nic_info_addr, 0, nic_size);
643
644 nic_info = (struct qlcnic_info *) nic_info_addr;
645 err = qlcnic_issue_cmd(adapter,
646 adapter->ahw.pci_func,
647 adapter->fw_hal_version,
648 MSD(nic_dma_t),
649 LSD(nic_dma_t),
650 (func_id << 16 | nic_size),
651 QLCNIC_CDRP_CMD_GET_NIC_INFO);
652
653 if (err == QLCNIC_RCODE_SUCCESS) {
654 adapter->physical_port = le16_to_cpu(nic_info->phys_port);
655 adapter->switch_mode = le16_to_cpu(nic_info->switch_mode);
656 adapter->max_tx_ques = le16_to_cpu(nic_info->max_tx_ques);
657 adapter->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
658 adapter->min_tx_bw = le16_to_cpu(nic_info->min_tx_bw);
659 adapter->max_tx_bw = le16_to_cpu(nic_info->max_tx_bw);
660 adapter->max_mtu = le16_to_cpu(nic_info->max_mtu);
661 adapter->capabilities = le32_to_cpu(nic_info->capabilities);
662 adapter->max_mac_filters = nic_info->max_mac_filters;
663
0e33c664
AC
664 if (adapter->capabilities & BIT_6)
665 adapter->flags |= QLCNIC_ESWITCH_ENABLED;
666 else
667 adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
668
2e9d722d
AC
669 dev_info(&adapter->pdev->dev,
670 "phy port: %d switch_mode: %d,\n"
671 "\tmax_tx_q: %d max_rx_q: %d min_tx_bw: 0x%x,\n"
672 "\tmax_tx_bw: 0x%x max_mtu:0x%x, capabilities: 0x%x\n",
673 adapter->physical_port, adapter->switch_mode,
674 adapter->max_tx_ques, adapter->max_rx_ques,
675 adapter->min_tx_bw, adapter->max_tx_bw,
676 adapter->max_mtu, adapter->capabilities);
677 } else {
678 dev_err(&adapter->pdev->dev,
679 "Failed to get nic info%d\n", err);
680 err = -EIO;
681 }
682
683 pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
684 return err;
685}
686
687/* Configure a NIC partition */
688int qlcnic_set_nic_info(struct qlcnic_adapter *adapter, struct qlcnic_info *nic)
689{
690 int err = -EIO;
691 u32 func_state;
692 dma_addr_t nic_dma_t;
693 void *nic_info_addr;
694 struct qlcnic_info *nic_info;
695 size_t nic_size = sizeof(struct qlcnic_info);
696
697 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
698 return err;
699
700 if (qlcnic_api_lock(adapter))
701 return err;
702
703 func_state = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT);
704 if (QLC_DEV_CHECK_ACTIVE(func_state, nic->pci_func)) {
705 qlcnic_api_unlock(adapter);
706 return err;
707 }
708
709 qlcnic_api_unlock(adapter);
710
711 nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size,
712 &nic_dma_t);
713 if (!nic_info_addr)
714 return -ENOMEM;
715
716 memset(nic_info_addr, 0, nic_size);
717 nic_info = (struct qlcnic_info *)nic_info_addr;
718
719 nic_info->pci_func = cpu_to_le16(nic->pci_func);
720 nic_info->op_mode = cpu_to_le16(nic->op_mode);
721 nic_info->phys_port = cpu_to_le16(nic->phys_port);
722 nic_info->switch_mode = cpu_to_le16(nic->switch_mode);
723 nic_info->capabilities = cpu_to_le32(nic->capabilities);
724 nic_info->max_mac_filters = nic->max_mac_filters;
725 nic_info->max_tx_ques = cpu_to_le16(nic->max_tx_ques);
726 nic_info->max_rx_ques = cpu_to_le16(nic->max_rx_ques);
727 nic_info->min_tx_bw = cpu_to_le16(nic->min_tx_bw);
728 nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw);
729
730 err = qlcnic_issue_cmd(adapter,
731 adapter->ahw.pci_func,
732 adapter->fw_hal_version,
733 MSD(nic_dma_t),
734 LSD(nic_dma_t),
735 nic_size,
736 QLCNIC_CDRP_CMD_SET_NIC_INFO);
737
738 if (err != QLCNIC_RCODE_SUCCESS) {
739 dev_err(&adapter->pdev->dev,
740 "Failed to set nic info%d\n", err);
741 err = -EIO;
742 }
743
744 pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
745 return err;
746}
747
748/* Get PCI Info of a partition */
749int qlcnic_get_pci_info(struct qlcnic_adapter *adapter)
750{
751 int err = 0, i;
752 dma_addr_t pci_info_dma_t;
753 struct qlcnic_pci_info *npar;
754 void *pci_info_addr;
755 size_t npar_size = sizeof(struct qlcnic_pci_info);
756 size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC;
757
758 pci_info_addr = pci_alloc_consistent(adapter->pdev, pci_size,
759 &pci_info_dma_t);
760 if (!pci_info_addr)
761 return -ENOMEM;
762 memset(pci_info_addr, 0, pci_size);
763
764 if (!adapter->npars)
765 adapter->npars = kzalloc(pci_size, GFP_KERNEL);
766 if (!adapter->npars) {
767 err = -ENOMEM;
768 goto err_npar;
769 }
770
771 if (!adapter->eswitch)
772 adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) *
773 QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL);
774 if (!adapter->eswitch) {
775 err = -ENOMEM;
776 goto err_eswitch;
777 }
778
779 npar = (struct qlcnic_pci_info *) pci_info_addr;
780 err = qlcnic_issue_cmd(adapter,
781 adapter->ahw.pci_func,
782 adapter->fw_hal_version,
783 MSD(pci_info_dma_t),
784 LSD(pci_info_dma_t),
785 pci_size,
786 QLCNIC_CDRP_CMD_GET_PCI_INFO);
787
788 if (err == QLCNIC_RCODE_SUCCESS) {
789 for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++) {
790 adapter->npars[i].id = le32_to_cpu(npar->id);
791 adapter->npars[i].active = le32_to_cpu(npar->active);
792 adapter->npars[i].type = le32_to_cpu(npar->type);
793 adapter->npars[i].default_port =
794 le32_to_cpu(npar->default_port);
795 adapter->npars[i].tx_min_bw =
796 le32_to_cpu(npar->tx_min_bw);
797 adapter->npars[i].tx_max_bw =
798 le32_to_cpu(npar->tx_max_bw);
799 memcpy(adapter->npars[i].mac, npar->mac, ETH_ALEN);
800 }
801 } else {
802 dev_err(&adapter->pdev->dev,
803 "Failed to get PCI Info%d\n", err);
804 kfree(adapter->npars);
805 err = -EIO;
806 }
807 goto err_npar;
808
809err_eswitch:
810 kfree(adapter->npars);
811 adapter->npars = NULL;
812
813err_npar:
814 pci_free_consistent(adapter->pdev, pci_size, pci_info_addr,
815 pci_info_dma_t);
816 return err;
817}
818
819/* Reset a NIC partition */
820
821int qlcnic_reset_partition(struct qlcnic_adapter *adapter, u8 func_no)
822{
823 int err = -EIO;
824
825 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
826 return err;
827
828 err = qlcnic_issue_cmd(adapter,
829 adapter->ahw.pci_func,
830 adapter->fw_hal_version,
831 func_no,
832 0,
833 0,
834 QLCNIC_CDRP_CMD_RESET_NPAR);
835
836 if (err != QLCNIC_RCODE_SUCCESS) {
837 dev_err(&adapter->pdev->dev,
838 "Failed to issue reset partition%d\n", err);
839 err = -EIO;
840 }
841
842 return err;
843}
844
845/* Get eSwitch Capabilities */
846int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port,
847 struct qlcnic_eswitch *eswitch)
848{
849 int err = -EIO;
850 u32 arg1, arg2;
851
852 if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC)
853 return err;
854
855 err = qlcnic_issue_cmd(adapter,
856 adapter->ahw.pci_func,
857 adapter->fw_hal_version,
858 port,
859 0,
860 0,
861 QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY);
862
863 if (err == QLCNIC_RCODE_SUCCESS) {
864 arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
865 arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
866
867 eswitch->port = arg1 & 0xf;
868 eswitch->active_vports = LSB(arg2);
869 eswitch->max_ucast_filters = MSB(arg2);
870 eswitch->max_active_vlans = LSB(MSW(arg2));
871 if (arg1 & BIT_6)
872 eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING;
873 if (arg1 & BIT_7)
874 eswitch->flags |= QLCNIC_SWITCH_PROMISC_MODE;
875 if (arg1 & BIT_8)
876 eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING;
877 } else {
878 dev_err(&adapter->pdev->dev,
879 "Failed to get eswitch capabilities%d\n", err);
880 }
881
882 return err;
883}
884
885/* Get current status of eswitch */
886int qlcnic_get_eswitch_status(struct qlcnic_adapter *adapter, u8 port,
887 struct qlcnic_eswitch *eswitch)
888{
889 int err = -EIO;
890 u32 arg1, arg2;
891
892 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
893 return err;
894
895 err = qlcnic_issue_cmd(adapter,
896 adapter->ahw.pci_func,
897 adapter->fw_hal_version,
898 port,
899 0,
900 0,
901 QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS);
902
903 if (err == QLCNIC_RCODE_SUCCESS) {
904 arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
905 arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
906
907 eswitch->port = arg1 & 0xf;
908 eswitch->active_vports = LSB(arg2);
909 eswitch->active_ucast_filters = MSB(arg2);
910 eswitch->active_vlans = LSB(MSW(arg2));
911 if (arg1 & BIT_6)
912 eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING;
913 if (arg1 & BIT_8)
914 eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING;
915
916 } else {
917 dev_err(&adapter->pdev->dev,
918 "Failed to get eswitch status%d\n", err);
919 }
920
921 return err;
922}
923
924/* Enable/Disable eSwitch */
925int qlcnic_toggle_eswitch(struct qlcnic_adapter *adapter, u8 id, u8 enable)
926{
927 int err = -EIO;
928 u32 arg1, arg2;
929 struct qlcnic_eswitch *eswitch;
930
931 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
932 return err;
933
934 eswitch = &adapter->eswitch[id];
935 if (!eswitch)
936 return err;
937
938 arg1 = eswitch->port | (enable ? BIT_4 : 0);
939 arg2 = eswitch->active_vports | (eswitch->max_ucast_filters << 8) |
940 (eswitch->max_active_vlans << 16);
941 err = qlcnic_issue_cmd(adapter,
942 adapter->ahw.pci_func,
943 adapter->fw_hal_version,
944 arg1,
945 arg2,
946 0,
947 QLCNIC_CDRP_CMD_TOGGLE_ESWITCH);
948
949 if (err != QLCNIC_RCODE_SUCCESS) {
950 dev_err(&adapter->pdev->dev,
951 "Failed to enable eswitch%d\n", eswitch->port);
952 eswitch->flags &= ~QLCNIC_SWITCH_ENABLE;
953 err = -EIO;
954 } else {
955 eswitch->flags |= QLCNIC_SWITCH_ENABLE;
956 dev_info(&adapter->pdev->dev,
957 "Enabled eSwitch for port %d\n", eswitch->port);
958 }
959
960 return err;
961}
962
963/* Configure eSwitch for port mirroring */
964int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
965 u8 enable_mirroring, u8 pci_func)
966{
967 int err = -EIO;
968 u32 arg1;
969
970 if (adapter->op_mode != QLCNIC_MGMT_FUNC ||
971 !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE))
972 return err;
973
974 arg1 = id | (enable_mirroring ? BIT_4 : 0);
975 arg1 |= pci_func << 8;
976
977 err = qlcnic_issue_cmd(adapter,
978 adapter->ahw.pci_func,
979 adapter->fw_hal_version,
980 arg1,
981 0,
982 0,
983 QLCNIC_CDRP_CMD_SET_PORTMIRRORING);
984
985 if (err != QLCNIC_RCODE_SUCCESS) {
986 dev_err(&adapter->pdev->dev,
987 "Failed to configure port mirroring%d on eswitch:%d\n",
988 pci_func, id);
989 } else {
990 dev_info(&adapter->pdev->dev,
991 "Configured eSwitch %d for port mirroring:%d\n",
992 id, pci_func);
993 }
994
995 return err;
996}
997
998/* Configure eSwitch port */
999int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id,
1000 int vlan_tagging, u8 discard_tagged, u8 promsc_mode,
1001 u8 mac_learn, u8 pci_func, u16 vlan_id)
1002{
1003 int err = -EIO;
1004 u32 arg1;
1005 struct qlcnic_eswitch *eswitch;
1006
1007 if (adapter->op_mode != QLCNIC_MGMT_FUNC)
1008 return err;
1009
1010 eswitch = &adapter->eswitch[id];
1011 if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE))
1012 return err;
1013
1014 arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0);
1015 arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0);
1016 arg1 |= pci_func << 8;
1017 if (vlan_tagging)
1018 arg1 |= BIT_5 | (vlan_id << 16);
1019
1020 err = qlcnic_issue_cmd(adapter,
1021 adapter->ahw.pci_func,
1022 adapter->fw_hal_version,
1023 arg1,
1024 0,
1025 0,
1026 QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH);
1027
1028 if (err != QLCNIC_RCODE_SUCCESS) {
1029 dev_err(&adapter->pdev->dev,
1030 "Failed to configure eswitch port%d\n", eswitch->port);
1031 eswitch->flags |= QLCNIC_SWITCH_ENABLE;
1032 } else {
1033 eswitch->flags &= ~QLCNIC_SWITCH_ENABLE;
1034 dev_info(&adapter->pdev->dev,
1035 "Configured eSwitch for port %d\n", eswitch->port);
1036 }
1037
1038 return err;
1039}