aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c157
1 files changed, 118 insertions, 39 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 00eaeee235e..274d1e0c893 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -135,20 +135,71 @@ static uint32_t msi_tgt_status[8] = {
135 135
136static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; 136static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
137 137
138static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) 138static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
139{ 139{
140 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0); 140 struct netxen_adapter *adapter = sds_ring->adapter;
141
142 adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
141} 143}
142 144
143static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) 145static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
144{ 146{
145 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1); 147 struct netxen_adapter *adapter = sds_ring->adapter;
148
149 adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1);
146 150
147 if (!NETXEN_IS_MSI_FAMILY(adapter)) 151 if (!NETXEN_IS_MSI_FAMILY(adapter))
148 adapter->pci_write_immediate(adapter, 152 adapter->pci_write_immediate(adapter,
149 adapter->legacy_intr.tgt_mask_reg, 0xfbff); 153 adapter->legacy_intr.tgt_mask_reg, 0xfbff);
150} 154}
151 155
156static void
157netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
158{
159 int ring;
160 struct nx_host_sds_ring *sds_ring;
161 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
162
163 if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
164 adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
165 else
166 adapter->max_sds_rings = 1;
167
168 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
169 sds_ring = &recv_ctx->sds_rings[ring];
170 netif_napi_add(netdev, &sds_ring->napi,
171 netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
172 }
173}
174
175static void
176netxen_napi_enable(struct netxen_adapter *adapter)
177{
178 int ring;
179 struct nx_host_sds_ring *sds_ring;
180 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
181
182 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
183 sds_ring = &recv_ctx->sds_rings[ring];
184 napi_enable(&sds_ring->napi);
185 netxen_nic_enable_int(sds_ring);
186 }
187}
188
189static void
190netxen_napi_disable(struct netxen_adapter *adapter)
191{
192 int ring;
193 struct nx_host_sds_ring *sds_ring;
194 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
195
196 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
197 sds_ring = &recv_ctx->sds_rings[ring];
198 netxen_nic_disable_int(sds_ring);
199 napi_disable(&sds_ring->napi);
200 }
201}
202
152static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) 203static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
153{ 204{
154 struct pci_dev *pdev = adapter->pdev; 205 struct pci_dev *pdev = adapter->pdev;
@@ -226,7 +277,6 @@ static void netxen_check_options(struct netxen_adapter *adapter)
226 adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS; 277 adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
227 adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS; 278 adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
228 279
229 adapter->max_possible_rss_rings = 1;
230 return; 280 return;
231} 281}
232 282
@@ -447,6 +497,7 @@ request_msi:
447 dev_info(&pdev->dev, "using msi interrupts\n"); 497 dev_info(&pdev->dev, "using msi interrupts\n");
448 } else 498 } else
449 dev_info(&pdev->dev, "using legacy interrupts\n"); 499 dev_info(&pdev->dev, "using legacy interrupts\n");
500 adapter->msix_entries[0].vector = pdev->irq;
450 } 501 }
451} 502}
452 503
@@ -671,8 +722,12 @@ static int
671netxen_nic_request_irq(struct netxen_adapter *adapter) 722netxen_nic_request_irq(struct netxen_adapter *adapter)
672{ 723{
673 irq_handler_t handler; 724 irq_handler_t handler;
725 struct nx_host_sds_ring *sds_ring;
726 int err, ring;
727
674 unsigned long flags = IRQF_SAMPLE_RANDOM; 728 unsigned long flags = IRQF_SAMPLE_RANDOM;
675 struct net_device *netdev = adapter->netdev; 729 struct net_device *netdev = adapter->netdev;
730 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
676 731
677 if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) || 732 if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
678 (adapter->intr_scheme != INTR_SCHEME_PERPORT)) { 733 (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
@@ -693,8 +748,30 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
693 } 748 }
694 adapter->irq = netdev->irq; 749 adapter->irq = netdev->irq;
695 750
696 return request_irq(adapter->irq, handler, 751 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
697 flags, netdev->name, adapter); 752 sds_ring = &recv_ctx->sds_rings[ring];
753 sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring);
754 err = request_irq(sds_ring->irq, handler,
755 flags, sds_ring->name, sds_ring);
756 if (err)
757 return err;
758 }
759
760 return 0;
761}
762
763static void
764netxen_nic_free_irq(struct netxen_adapter *adapter)
765{
766 int ring;
767 struct nx_host_sds_ring *sds_ring;
768
769 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
770
771 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
772 sds_ring = &recv_ctx->sds_rings[ring];
773 free_irq(sds_ring->irq, sds_ring);
774 }
698} 775}
699 776
700static int 777static int
@@ -719,8 +796,10 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
719 adapter->ahw.linkup = 0; 796 adapter->ahw.linkup = 0;
720 mod_timer(&adapter->watchdog_timer, jiffies); 797 mod_timer(&adapter->watchdog_timer, jiffies);
721 798
722 napi_enable(&adapter->napi); 799 netxen_napi_enable(adapter);
723 netxen_nic_enable_int(adapter); 800
801 if (adapter->max_sds_rings > 1)
802 netxen_config_rss(adapter, 1);
724 803
725 return 0; 804 return 0;
726} 805}
@@ -730,13 +809,11 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
730{ 809{
731 netif_carrier_off(netdev); 810 netif_carrier_off(netdev);
732 netif_stop_queue(netdev); 811 netif_stop_queue(netdev);
733 napi_disable(&adapter->napi); 812 netxen_napi_disable(adapter);
734 813
735 if (adapter->stop_port) 814 if (adapter->stop_port)
736 adapter->stop_port(adapter); 815 adapter->stop_port(adapter);
737 816
738 netxen_nic_disable_int(adapter);
739
740 netxen_release_tx_buffers(adapter); 817 netxen_release_tx_buffers(adapter);
741 818
742 FLUSH_SCHEDULED_WORK(); 819 FLUSH_SCHEDULED_WORK();
@@ -750,6 +827,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
750 struct net_device *netdev = adapter->netdev; 827 struct net_device *netdev = adapter->netdev;
751 struct pci_dev *pdev = adapter->pdev; 828 struct pci_dev *pdev = adapter->pdev;
752 int err, ring; 829 int err, ring;
830 struct nx_host_rds_ring *rds_ring;
753 831
754 err = netxen_init_firmware(adapter); 832 err = netxen_init_firmware(adapter);
755 if (err != 0) { 833 if (err != 0) {
@@ -788,8 +866,10 @@ netxen_nic_attach(struct netxen_adapter *adapter)
788 netxen_nic_update_cmd_consumer(adapter, 0); 866 netxen_nic_update_cmd_consumer(adapter, 0);
789 } 867 }
790 868
791 for (ring = 0; ring < adapter->max_rds_rings; ring++) 869 for (ring = 0; ring < adapter->max_rds_rings; ring++) {
792 netxen_post_rx_buffers(adapter, ring); 870 rds_ring = &adapter->recv_ctx.rds_rings[ring];
871 netxen_post_rx_buffers(adapter, ring, rds_ring);
872 }
793 873
794 err = netxen_nic_request_irq(adapter); 874 err = netxen_nic_request_irq(adapter);
795 if (err) { 875 if (err) {
@@ -812,8 +892,7 @@ err_out_free_sw:
812static void 892static void
813netxen_nic_detach(struct netxen_adapter *adapter) 893netxen_nic_detach(struct netxen_adapter *adapter)
814{ 894{
815 if (adapter->irq) 895 netxen_nic_free_irq(adapter);
816 free_irq(adapter->irq, adapter);
817 896
818 netxen_release_rx_buffers(adapter); 897 netxen_release_rx_buffers(adapter);
819 netxen_free_hw_resources(adapter); 898 netxen_free_hw_resources(adapter);
@@ -883,14 +962,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
883 goto err_out_free_netdev; 962 goto err_out_free_netdev;
884 963
885 rwlock_init(&adapter->adapter_lock); 964 rwlock_init(&adapter->adapter_lock);
965 spin_lock_init(&adapter->tx_clean_lock);
886 966
887 err = netxen_setup_pci_map(adapter); 967 err = netxen_setup_pci_map(adapter);
888 if (err) 968 if (err)
889 goto err_out_free_netdev; 969 goto err_out_free_netdev;
890 970
891 netif_napi_add(netdev, &adapter->napi,
892 netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
893
894 /* This will be reset for mezz cards */ 971 /* This will be reset for mezz cards */
895 adapter->portnum = pci_func_id; 972 adapter->portnum = pci_func_id;
896 adapter->rx_csum = 1; 973 adapter->rx_csum = 1;
@@ -963,10 +1040,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
963 1040
964 netxen_setup_intr(adapter); 1041 netxen_setup_intr(adapter);
965 1042
966 if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) 1043 netdev->irq = adapter->msix_entries[0].vector;
967 netdev->irq = adapter->msix_entries[0].vector; 1044
968 else 1045 netxen_napi_add(adapter, netdev);
969 netdev->irq = pdev->irq;
970 1046
971 err = netxen_receive_peg_ready(adapter); 1047 err = netxen_receive_peg_ready(adapter);
972 if (err) 1048 if (err)
@@ -1520,13 +1596,11 @@ static void netxen_tx_timeout_task(struct work_struct *work)
1520 printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", 1596 printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
1521 netxen_nic_driver_name, adapter->netdev->name); 1597 netxen_nic_driver_name, adapter->netdev->name);
1522 1598
1523 netxen_nic_disable_int(adapter); 1599 netxen_napi_disable(adapter);
1524 napi_disable(&adapter->napi);
1525 1600
1526 adapter->netdev->trans_start = jiffies; 1601 adapter->netdev->trans_start = jiffies;
1527 1602
1528 napi_enable(&adapter->napi); 1603 netxen_napi_enable(adapter);
1529 netxen_nic_enable_int(adapter);
1530 netif_wake_queue(adapter->netdev); 1604 netif_wake_queue(adapter->netdev);
1531} 1605}
1532 1606
@@ -1564,7 +1638,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
1564 1638
1565static irqreturn_t netxen_intr(int irq, void *data) 1639static irqreturn_t netxen_intr(int irq, void *data)
1566{ 1640{
1567 struct netxen_adapter *adapter = data; 1641 struct nx_host_sds_ring *sds_ring = data;
1642 struct netxen_adapter *adapter = sds_ring->adapter;
1568 u32 status = 0; 1643 u32 status = 0;
1569 1644
1570 status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); 1645 status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1595,7 +1670,7 @@ static irqreturn_t netxen_intr(int irq, void *data)
1595 1670
1596 /* clear interrupt */ 1671 /* clear interrupt */
1597 if (adapter->fw_major < 4) 1672 if (adapter->fw_major < 4)
1598 netxen_nic_disable_int(adapter); 1673 netxen_nic_disable_int(sds_ring);
1599 1674
1600 adapter->pci_write_immediate(adapter, 1675 adapter->pci_write_immediate(adapter,
1601 adapter->legacy_intr.tgt_status_reg, 1676 adapter->legacy_intr.tgt_status_reg,
@@ -1604,45 +1679,49 @@ static irqreturn_t netxen_intr(int irq, void *data)
1604 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); 1679 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1605 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); 1680 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1606 1681
1607 napi_schedule(&adapter->napi); 1682 napi_schedule(&sds_ring->napi);
1608 1683
1609 return IRQ_HANDLED; 1684 return IRQ_HANDLED;
1610} 1685}
1611 1686
1612static irqreturn_t netxen_msi_intr(int irq, void *data) 1687static irqreturn_t netxen_msi_intr(int irq, void *data)
1613{ 1688{
1614 struct netxen_adapter *adapter = data; 1689 struct nx_host_sds_ring *sds_ring = data;
1690 struct netxen_adapter *adapter = sds_ring->adapter;
1615 1691
1616 /* clear interrupt */ 1692 /* clear interrupt */
1617 adapter->pci_write_immediate(adapter, 1693 adapter->pci_write_immediate(adapter,
1618 msi_tgt_status[adapter->ahw.pci_func], 0xffffffff); 1694 msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
1619 1695
1620 napi_schedule(&adapter->napi); 1696 napi_schedule(&sds_ring->napi);
1621 return IRQ_HANDLED; 1697 return IRQ_HANDLED;
1622} 1698}
1623 1699
1624static irqreturn_t netxen_msix_intr(int irq, void *data) 1700static irqreturn_t netxen_msix_intr(int irq, void *data)
1625{ 1701{
1626 struct netxen_adapter *adapter = data; 1702 struct nx_host_sds_ring *sds_ring = data;
1627 1703
1628 napi_schedule(&adapter->napi); 1704 napi_schedule(&sds_ring->napi);
1629 return IRQ_HANDLED; 1705 return IRQ_HANDLED;
1630} 1706}
1631 1707
1632static int netxen_nic_poll(struct napi_struct *napi, int budget) 1708static int netxen_nic_poll(struct napi_struct *napi, int budget)
1633{ 1709{
1634 struct netxen_adapter *adapter = 1710 struct nx_host_sds_ring *sds_ring =
1635 container_of(napi, struct netxen_adapter, napi); 1711 container_of(napi, struct nx_host_sds_ring, napi);
1712
1713 struct netxen_adapter *adapter = sds_ring->adapter;
1714
1636 int tx_complete; 1715 int tx_complete;
1637 int work_done; 1716 int work_done;
1638 1717
1639 tx_complete = netxen_process_cmd_ring(adapter); 1718 tx_complete = netxen_process_cmd_ring(adapter);
1640 1719
1641 work_done = netxen_process_rcv_ring(adapter, budget); 1720 work_done = netxen_process_rcv_ring(sds_ring, budget);
1642 1721
1643 if ((work_done < budget) && tx_complete) { 1722 if ((work_done < budget) && tx_complete) {
1644 napi_complete(&adapter->napi); 1723 napi_complete(&sds_ring->napi);
1645 netxen_nic_enable_int(adapter); 1724 netxen_nic_enable_int(sds_ring);
1646 } 1725 }
1647 1726
1648 return work_done; 1727 return work_done;