aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_ctx.c
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-03-13 10:52:05 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-14 17:00:33 -0400
commitd8b100c5da003b6f8c410453e1e6e74ced8d1cc1 (patch)
tree75d895254bb70859ef5c3b4cab2d5da313af8e87 /drivers/net/netxen/netxen_nic_ctx.c
parent9b3ef55c6ddbe8c7b76707eae9a77d874fe2cec0 (diff)
netxen: add receive side scaling (rss) support
This patch enables the load balancing capability of firmware and hardware to spray traffic into different cpus through separate rx msix interrupts. The feature is being enabled for NX3031, NX2031 (old) will be enabled later. This depends on msi-x and compatibility with msi and legacy is maintained by enabling single rx ring. 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.c117
1 files changed, 68 insertions, 49 deletions
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 2e66335bd000..9234473bc08a 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -169,6 +169,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
169 nx_cardrsp_rds_ring_t *prsp_rds; 169 nx_cardrsp_rds_ring_t *prsp_rds;
170 nx_cardrsp_sds_ring_t *prsp_sds; 170 nx_cardrsp_sds_ring_t *prsp_sds;
171 struct nx_host_rds_ring *rds_ring; 171 struct nx_host_rds_ring *rds_ring;
172 struct nx_host_sds_ring *sds_ring;
172 173
173 dma_addr_t hostrq_phys_addr, cardrsp_phys_addr; 174 dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
174 u64 phys_addr; 175 u64 phys_addr;
@@ -181,9 +182,8 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
181 182
182 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 183 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
183 184
184 /* only one sds ring for now */
185 nrds_rings = adapter->max_rds_rings; 185 nrds_rings = adapter->max_rds_rings;
186 nsds_rings = 1; 186 nsds_rings = adapter->max_sds_rings;
187 187
188 rq_size = 188 rq_size =
189 SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings); 189 SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
@@ -239,11 +239,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
239 prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + 239 prq_sds = (nx_hostrq_sds_ring_t *)(prq->data +
240 le32_to_cpu(prq->sds_ring_offset)); 240 le32_to_cpu(prq->sds_ring_offset));
241 241
242 prq_sds[0].host_phys_addr = 242 for (i = 0; i < nsds_rings; i++) {
243 cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); 243
244 prq_sds[0].ring_size = cpu_to_le32(adapter->num_rxd); 244 sds_ring = &recv_ctx->sds_rings[i];
245 /* only one msix vector for now */ 245
246 prq_sds[0].msi_index = cpu_to_le16(0); 246 prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
247 prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
248 prq_sds[i].msi_index = cpu_to_le16(i);
249 }
247 250
248 phys_addr = hostrq_phys_addr; 251 phys_addr = hostrq_phys_addr;
249 err = netxen_issue_cmd(adapter, 252 err = netxen_issue_cmd(adapter,
@@ -272,11 +275,16 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
272 275
273 prsp_sds = ((nx_cardrsp_sds_ring_t *) 276 prsp_sds = ((nx_cardrsp_sds_ring_t *)
274 &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]); 277 &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
275 reg = le32_to_cpu(prsp_sds[0].host_consumer_crb);
276 recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
277 278
278 reg = le32_to_cpu(prsp_sds[0].interrupt_crb); 279 for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
279 adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200); 280 sds_ring = &recv_ctx->sds_rings[i];
281
282 reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
283 sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
284
285 reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
286 sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
287 }
280 288
281 recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); 289 recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
282 recv_ctx->context_id = le16_to_cpu(prsp->context_id); 290 recv_ctx->context_id = le16_to_cpu(prsp->context_id);
@@ -488,6 +496,7 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
488{ 496{
489 struct netxen_recv_context *recv_ctx; 497 struct netxen_recv_context *recv_ctx;
490 struct nx_host_rds_ring *rds_ring; 498 struct nx_host_rds_ring *rds_ring;
499 struct nx_host_sds_ring *sds_ring;
491 int ring; 500 int ring;
492 int func_id = adapter->portnum; 501 int func_id = adapter->portnum;
493 502
@@ -506,10 +515,9 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
506 adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = 515 adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
507 cpu_to_le32(rds_ring->num_desc); 516 cpu_to_le32(rds_ring->num_desc);
508 } 517 }
509 adapter->ctx_desc->sts_ring_addr = 518 sds_ring = &recv_ctx->sds_rings[0];
510 cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); 519 adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
511 adapter->ctx_desc->sts_ring_size = 520 adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
512 cpu_to_le32(adapter->num_rxd);
513 521
514 adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id), 522 adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
515 lower32(adapter->ctx_desc_phys_addr)); 523 lower32(adapter->ctx_desc_phys_addr));
@@ -534,6 +542,10 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
534 int ring; 542 int ring;
535 struct netxen_recv_context *recv_ctx; 543 struct netxen_recv_context *recv_ctx;
536 struct nx_host_rds_ring *rds_ring; 544 struct nx_host_rds_ring *rds_ring;
545 struct nx_host_sds_ring *sds_ring;
546
547 struct pci_dev *pdev = adapter->pdev;
548 struct net_device *netdev = adapter->netdev;
537 549
538 err = netxen_receive_peg_ready(adapter); 550 err = netxen_receive_peg_ready(adapter);
539 if (err) { 551 if (err) {
@@ -542,12 +554,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
542 return err; 554 return err;
543 } 555 }
544 556
545 addr = pci_alloc_consistent(adapter->pdev, 557 addr = pci_alloc_consistent(pdev,
546 sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), 558 sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
547 &adapter->ctx_desc_phys_addr); 559 &adapter->ctx_desc_phys_addr);
548 560
549 if (addr == NULL) { 561 if (addr == NULL) {
550 DPRINTK(ERR, "failed to allocate hw context\n"); 562 dev_err(&pdev->dev, "failed to allocate hw context\n");
551 return -ENOMEM; 563 return -ENOMEM;
552 } 564 }
553 memset(addr, 0, sizeof(struct netxen_ring_ctx)); 565 memset(addr, 0, sizeof(struct netxen_ring_ctx));
@@ -560,14 +572,13 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
560 (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); 572 (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
561 573
562 /* cmd desc ring */ 574 /* cmd desc ring */
563 addr = pci_alloc_consistent(adapter->pdev, 575 addr = pci_alloc_consistent(pdev,
564 sizeof(struct cmd_desc_type0) * 576 TX_DESC_RINGSIZE(adapter),
565 adapter->num_txd,
566 &hw->cmd_desc_phys_addr); 577 &hw->cmd_desc_phys_addr);
567 578
568 if (addr == NULL) { 579 if (addr == NULL) {
569 printk(KERN_ERR "%s failed to allocate tx desc ring\n", 580 dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
570 netxen_nic_driver_name); 581 netdev->name);
571 return -ENOMEM; 582 return -ENOMEM;
572 } 583 }
573 584
@@ -576,15 +587,14 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
576 recv_ctx = &adapter->recv_ctx; 587 recv_ctx = &adapter->recv_ctx;
577 588
578 for (ring = 0; ring < adapter->max_rds_rings; ring++) { 589 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
579 /* rx desc ring */
580 rds_ring = &recv_ctx->rds_rings[ring]; 590 rds_ring = &recv_ctx->rds_rings[ring];
581 addr = pci_alloc_consistent(adapter->pdev, 591 addr = pci_alloc_consistent(adapter->pdev,
582 RCV_DESC_RINGSIZE, 592 RCV_DESC_RINGSIZE(rds_ring),
583 &rds_ring->phys_addr); 593 &rds_ring->phys_addr);
584 if (addr == NULL) { 594 if (addr == NULL) {
585 printk(KERN_ERR "%s failed to allocate rx " 595 dev_err(&pdev->dev,
586 "desc ring[%d]\n", 596 "%s: failed to allocate rds ring [%d]\n",
587 netxen_nic_driver_name, ring); 597 netdev->name, ring);
588 err = -ENOMEM; 598 err = -ENOMEM;
589 goto err_out_free; 599 goto err_out_free;
590 } 600 }
@@ -596,22 +606,22 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
596 crb_rcv_producer[ring]; 606 crb_rcv_producer[ring];
597 } 607 }
598 608
599 /* status desc ring */ 609 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
600 addr = pci_alloc_consistent(adapter->pdev, 610 sds_ring = &recv_ctx->sds_rings[ring];
601 STATUS_DESC_RINGSIZE, 611
602 &recv_ctx->rcv_status_desc_phys_addr); 612 addr = pci_alloc_consistent(adapter->pdev,
603 if (addr == NULL) { 613 STATUS_DESC_RINGSIZE(sds_ring),
604 printk(KERN_ERR "%s failed to allocate sts desc ring\n", 614 &sds_ring->phys_addr);
605 netxen_nic_driver_name); 615 if (addr == NULL) {
606 err = -ENOMEM; 616 dev_err(&pdev->dev,
607 goto err_out_free; 617 "%s: failed to allocate sds ring [%d]\n",
618 netdev->name, ring);
619 err = -ENOMEM;
620 goto err_out_free;
621 }
622 sds_ring->desc_head = (struct status_desc *)addr;
608 } 623 }
609 recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
610 624
611 if (adapter->fw_major < 4)
612 recv_ctx->crb_sts_consumer =
613 recv_crb_registers[adapter->portnum].
614 crb_sts_consumer;
615 625
616 if (adapter->fw_major >= 4) { 626 if (adapter->fw_major >= 4) {
617 adapter->intr_scheme = INTR_SCHEME_PERPORT; 627 adapter->intr_scheme = INTR_SCHEME_PERPORT;
@@ -624,12 +634,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
624 if (err) 634 if (err)
625 goto err_out_free; 635 goto err_out_free;
626 } else { 636 } else {
637 sds_ring = &recv_ctx->sds_rings[0];
638 sds_ring->crb_sts_consumer =
639 recv_crb_registers[adapter->portnum].crb_sts_consumer;
627 640
628 adapter->intr_scheme = adapter->pci_read_normalize(adapter, 641 adapter->intr_scheme = adapter->pci_read_normalize(adapter,
629 CRB_NIC_CAPABILITIES_FW); 642 CRB_NIC_CAPABILITIES_FW);
630 adapter->msi_mode = adapter->pci_read_normalize(adapter, 643 adapter->msi_mode = adapter->pci_read_normalize(adapter,
631 CRB_NIC_MSI_MODE_FW); 644 CRB_NIC_MSI_MODE_FW);
632 adapter->crb_intr_mask = sw_int_mask[adapter->portnum]; 645 recv_ctx->sds_rings[0].crb_intr_mask =
646 sw_int_mask[adapter->portnum];
633 647
634 err = netxen_init_old_ctx(adapter); 648 err = netxen_init_old_ctx(adapter);
635 if (err) { 649 if (err) {
@@ -650,6 +664,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
650{ 664{
651 struct netxen_recv_context *recv_ctx; 665 struct netxen_recv_context *recv_ctx;
652 struct nx_host_rds_ring *rds_ring; 666 struct nx_host_rds_ring *rds_ring;
667 struct nx_host_sds_ring *sds_ring;
653 int ring; 668 int ring;
654 669
655 if (adapter->fw_major >= 4) { 670 if (adapter->fw_major >= 4) {
@@ -681,19 +696,23 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
681 696
682 if (rds_ring->desc_head != NULL) { 697 if (rds_ring->desc_head != NULL) {
683 pci_free_consistent(adapter->pdev, 698 pci_free_consistent(adapter->pdev,
684 RCV_DESC_RINGSIZE, 699 RCV_DESC_RINGSIZE(rds_ring),
685 rds_ring->desc_head, 700 rds_ring->desc_head,
686 rds_ring->phys_addr); 701 rds_ring->phys_addr);
687 rds_ring->desc_head = NULL; 702 rds_ring->desc_head = NULL;
688 } 703 }
689 } 704 }
690 705
691 if (recv_ctx->rcv_status_desc_head != NULL) { 706 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
692 pci_free_consistent(adapter->pdev, 707 sds_ring = &recv_ctx->sds_rings[ring];
693 STATUS_DESC_RINGSIZE, 708
694 recv_ctx->rcv_status_desc_head, 709 if (sds_ring->desc_head != NULL) {
695 recv_ctx->rcv_status_desc_phys_addr); 710 pci_free_consistent(adapter->pdev,
696 recv_ctx->rcv_status_desc_head = NULL; 711 STATUS_DESC_RINGSIZE(sds_ring),
712 sds_ring->desc_head,
713 sds_ring->phys_addr);
714 sds_ring->desc_head = NULL;
715 }
697 } 716 }
698} 717}
699 718