diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2009-04-07 18:50:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-08 18:58:30 -0400 |
commit | f6d21f44122630cc9549b8ffbab23ea8c68254e0 (patch) | |
tree | f4dd12d962fc94b303e1a6fdcfed691cfdd7b5cb /drivers/net/netxen/netxen_nic_ctx.c | |
parent | f98a9f693b5f4919d9c4085a2fd8d67c7e152f3e (diff) |
netxen: enable rss for NX2031
Enable multiple rx rings for older NX2031 chip, firmware 3.4.336
or newer supports this feature.
Signed-off-by: Amit Kumar Salecha <amit@netxen.com>
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_ctx.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_ctx.c | 127 |
1 files changed, 95 insertions, 32 deletions
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 32f48398398b..fd82adf4f876 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -441,7 +441,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { | |||
441 | NETXEN_NIC_REG(0x120) | 441 | NETXEN_NIC_REG(0x120) |
442 | }, | 442 | }, |
443 | /* crb_sts_consumer: */ | 443 | /* crb_sts_consumer: */ |
444 | NETXEN_NIC_REG(0x138), | 444 | { |
445 | NETXEN_NIC_REG(0x138), | ||
446 | NETXEN_NIC_REG_2(0x000), | ||
447 | NETXEN_NIC_REG_2(0x004), | ||
448 | NETXEN_NIC_REG_2(0x008), | ||
449 | }, | ||
450 | /* sw_int_mask */ | ||
451 | { | ||
452 | CRB_SW_INT_MASK_0, | ||
453 | NETXEN_NIC_REG_2(0x044), | ||
454 | NETXEN_NIC_REG_2(0x048), | ||
455 | NETXEN_NIC_REG_2(0x04c), | ||
456 | }, | ||
445 | }, | 457 | }, |
446 | /* Instance 1 */ | 458 | /* Instance 1 */ |
447 | { | 459 | { |
@@ -454,7 +466,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { | |||
454 | NETXEN_NIC_REG(0x164) | 466 | NETXEN_NIC_REG(0x164) |
455 | }, | 467 | }, |
456 | /* crb_sts_consumer: */ | 468 | /* crb_sts_consumer: */ |
457 | NETXEN_NIC_REG(0x17c), | 469 | { |
470 | NETXEN_NIC_REG(0x17c), | ||
471 | NETXEN_NIC_REG_2(0x020), | ||
472 | NETXEN_NIC_REG_2(0x024), | ||
473 | NETXEN_NIC_REG_2(0x028), | ||
474 | }, | ||
475 | /* sw_int_mask */ | ||
476 | { | ||
477 | CRB_SW_INT_MASK_1, | ||
478 | NETXEN_NIC_REG_2(0x064), | ||
479 | NETXEN_NIC_REG_2(0x068), | ||
480 | NETXEN_NIC_REG_2(0x06c), | ||
481 | }, | ||
458 | }, | 482 | }, |
459 | /* Instance 2 */ | 483 | /* Instance 2 */ |
460 | { | 484 | { |
@@ -467,7 +491,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { | |||
467 | NETXEN_NIC_REG(0x208) | 491 | NETXEN_NIC_REG(0x208) |
468 | }, | 492 | }, |
469 | /* crb_sts_consumer: */ | 493 | /* crb_sts_consumer: */ |
470 | NETXEN_NIC_REG(0x220), | 494 | { |
495 | NETXEN_NIC_REG(0x220), | ||
496 | NETXEN_NIC_REG_2(0x03c), | ||
497 | NETXEN_NIC_REG_2(0x03c), | ||
498 | NETXEN_NIC_REG_2(0x03c), | ||
499 | }, | ||
500 | /* sw_int_mask */ | ||
501 | { | ||
502 | CRB_SW_INT_MASK_2, | ||
503 | NETXEN_NIC_REG_2(0x03c), | ||
504 | NETXEN_NIC_REG_2(0x03c), | ||
505 | NETXEN_NIC_REG_2(0x03c), | ||
506 | }, | ||
471 | }, | 507 | }, |
472 | /* Instance 3 */ | 508 | /* Instance 3 */ |
473 | { | 509 | { |
@@ -480,7 +516,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { | |||
480 | NETXEN_NIC_REG(0x24c) | 516 | NETXEN_NIC_REG(0x24c) |
481 | }, | 517 | }, |
482 | /* crb_sts_consumer: */ | 518 | /* crb_sts_consumer: */ |
483 | NETXEN_NIC_REG(0x264), | 519 | { |
520 | NETXEN_NIC_REG(0x264), | ||
521 | NETXEN_NIC_REG_2(0x03c), | ||
522 | NETXEN_NIC_REG_2(0x03c), | ||
523 | NETXEN_NIC_REG_2(0x03c), | ||
524 | }, | ||
525 | /* sw_int_mask */ | ||
526 | { | ||
527 | CRB_SW_INT_MASK_3, | ||
528 | NETXEN_NIC_REG_2(0x03c), | ||
529 | NETXEN_NIC_REG_2(0x03c), | ||
530 | NETXEN_NIC_REG_2(0x03c), | ||
531 | }, | ||
484 | }, | 532 | }, |
485 | }; | 533 | }; |
486 | 534 | ||
@@ -492,40 +540,50 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) | |||
492 | struct nx_host_sds_ring *sds_ring; | 540 | struct nx_host_sds_ring *sds_ring; |
493 | struct nx_host_tx_ring *tx_ring; | 541 | struct nx_host_tx_ring *tx_ring; |
494 | int ring; | 542 | int ring; |
495 | int func_id = adapter->portnum; | 543 | int port = adapter->portnum; |
544 | struct netxen_ring_ctx *hwctx = adapter->ctx_desc; | ||
545 | u32 signature; | ||
496 | 546 | ||
497 | tx_ring = &adapter->tx_ring; | 547 | tx_ring = &adapter->tx_ring; |
498 | adapter->ctx_desc->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); | 548 | hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); |
499 | adapter->ctx_desc->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); | 549 | hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); |
500 | 550 | ||
501 | recv_ctx = &adapter->recv_ctx; | 551 | recv_ctx = &adapter->recv_ctx; |
502 | 552 | ||
503 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | 553 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { |
504 | rds_ring = &recv_ctx->rds_rings[ring]; | 554 | rds_ring = &recv_ctx->rds_rings[ring]; |
505 | 555 | ||
506 | adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr = | 556 | hwctx->rcv_rings[ring].addr = |
507 | cpu_to_le64(rds_ring->phys_addr); | 557 | cpu_to_le64(rds_ring->phys_addr); |
508 | adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = | 558 | hwctx->rcv_rings[ring].size = |
509 | cpu_to_le32(rds_ring->num_desc); | 559 | cpu_to_le32(rds_ring->num_desc); |
510 | } | 560 | } |
511 | sds_ring = &recv_ctx->sds_rings[0]; | ||
512 | adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); | ||
513 | adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc); | ||
514 | 561 | ||
515 | NXWR32(adapter, CRB_CTX_ADDR_REG_LO(func_id), | 562 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
563 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
564 | |||
565 | if (ring == 0) { | ||
566 | hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); | ||
567 | hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc); | ||
568 | } | ||
569 | hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr); | ||
570 | hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc); | ||
571 | hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring); | ||
572 | } | ||
573 | hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings); | ||
574 | |||
575 | signature = (adapter->max_sds_rings > 1) ? | ||
576 | NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE; | ||
577 | |||
578 | NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port), | ||
516 | lower32(adapter->ctx_desc_phys_addr)); | 579 | lower32(adapter->ctx_desc_phys_addr)); |
517 | NXWR32(adapter, CRB_CTX_ADDR_REG_HI(func_id), | 580 | NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port), |
518 | upper32(adapter->ctx_desc_phys_addr)); | 581 | upper32(adapter->ctx_desc_phys_addr)); |
519 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(func_id), | 582 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), |
520 | NETXEN_CTX_SIGNATURE | func_id); | 583 | signature | port); |
521 | return 0; | 584 | return 0; |
522 | } | 585 | } |
523 | 586 | ||
524 | static uint32_t sw_int_mask[4] = { | ||
525 | CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, | ||
526 | CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 | ||
527 | }; | ||
528 | |||
529 | int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | 587 | int netxen_alloc_hw_resources(struct netxen_adapter *adapter) |
530 | { | 588 | { |
531 | void *addr; | 589 | void *addr; |
@@ -538,6 +596,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
538 | 596 | ||
539 | struct pci_dev *pdev = adapter->pdev; | 597 | struct pci_dev *pdev = adapter->pdev; |
540 | struct net_device *netdev = adapter->netdev; | 598 | struct net_device *netdev = adapter->netdev; |
599 | int port = adapter->portnum; | ||
541 | 600 | ||
542 | addr = pci_alloc_consistent(pdev, | 601 | addr = pci_alloc_consistent(pdev, |
543 | sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), | 602 | sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), |
@@ -549,7 +608,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
549 | } | 608 | } |
550 | memset(addr, 0, sizeof(struct netxen_ring_ctx)); | 609 | memset(addr, 0, sizeof(struct netxen_ring_ctx)); |
551 | adapter->ctx_desc = (struct netxen_ring_ctx *)addr; | 610 | adapter->ctx_desc = (struct netxen_ring_ctx *)addr; |
552 | adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum); | 611 | adapter->ctx_desc->ctx_id = cpu_to_le32(port); |
553 | adapter->ctx_desc->cmd_consumer_offset = | 612 | adapter->ctx_desc->cmd_consumer_offset = |
554 | cpu_to_le64(adapter->ctx_desc_phys_addr + | 613 | cpu_to_le64(adapter->ctx_desc_phys_addr + |
555 | sizeof(struct netxen_ring_ctx)); | 614 | sizeof(struct netxen_ring_ctx)); |
@@ -586,8 +645,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
586 | 645 | ||
587 | if (adapter->fw_major < 4) | 646 | if (adapter->fw_major < 4) |
588 | rds_ring->crb_rcv_producer = | 647 | rds_ring->crb_rcv_producer = |
589 | recv_crb_registers[adapter->portnum]. | 648 | recv_crb_registers[port].crb_rcv_producer[ring]; |
590 | crb_rcv_producer[ring]; | ||
591 | } | 649 | } |
592 | 650 | ||
593 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 651 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
@@ -604,6 +662,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
604 | goto err_out_free; | 662 | goto err_out_free; |
605 | } | 663 | } |
606 | sds_ring->desc_head = (struct status_desc *)addr; | 664 | sds_ring->desc_head = (struct status_desc *)addr; |
665 | |||
666 | sds_ring->crb_sts_consumer = | ||
667 | recv_crb_registers[port].crb_sts_consumer[ring]; | ||
668 | |||
669 | sds_ring->crb_intr_mask = | ||
670 | recv_crb_registers[port].sw_int_mask[ring]; | ||
607 | } | 671 | } |
608 | 672 | ||
609 | 673 | ||
@@ -615,19 +679,11 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
615 | if (err) | 679 | if (err) |
616 | goto err_out_free; | 680 | goto err_out_free; |
617 | } else { | 681 | } else { |
618 | sds_ring = &recv_ctx->sds_rings[0]; | ||
619 | sds_ring->crb_sts_consumer = | ||
620 | recv_crb_registers[adapter->portnum].crb_sts_consumer; | ||
621 | |||
622 | recv_ctx->sds_rings[0].crb_intr_mask = | ||
623 | sw_int_mask[adapter->portnum]; | ||
624 | |||
625 | err = netxen_init_old_ctx(adapter); | 682 | err = netxen_init_old_ctx(adapter); |
626 | if (err) { | 683 | if (err) { |
627 | netxen_free_hw_resources(adapter); | 684 | netxen_free_hw_resources(adapter); |
628 | return err; | 685 | return err; |
629 | } | 686 | } |
630 | |||
631 | } | 687 | } |
632 | 688 | ||
633 | return 0; | 689 | return 0; |
@@ -645,9 +701,16 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) | |||
645 | struct nx_host_tx_ring *tx_ring; | 701 | struct nx_host_tx_ring *tx_ring; |
646 | int ring; | 702 | int ring; |
647 | 703 | ||
704 | int port = adapter->portnum; | ||
705 | |||
648 | if (adapter->fw_major >= 4) { | 706 | if (adapter->fw_major >= 4) { |
649 | nx_fw_cmd_destroy_tx_ctx(adapter); | 707 | nx_fw_cmd_destroy_tx_ctx(adapter); |
650 | nx_fw_cmd_destroy_rx_ctx(adapter); | 708 | nx_fw_cmd_destroy_rx_ctx(adapter); |
709 | } else { | ||
710 | netxen_api_lock(adapter); | ||
711 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), | ||
712 | NETXEN_CTX_RESET | port); | ||
713 | netxen_api_unlock(adapter); | ||
651 | } | 714 | } |
652 | 715 | ||
653 | if (adapter->ctx_desc != NULL) { | 716 | if (adapter->ctx_desc != NULL) { |