aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-05-06 06:43:28 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-06 18:33:45 -0400
commit7a921c93626e7481b5d8788d8511995aa2d2b591 (patch)
treeeaf4dc4c387fb1456374f1633278eec29060f0c1 /drivers
parentdcb4ea2ea2ba990a59db5a4cc402df3c2bd389b3 (diff)
ixgbe: make q_vectors dynamic to reduce netdev size
Currently the q_vectors are being allocated statically inside of the adapter struct. This increases the overall size of the adapter struct when we can easily allocate the vectors dynamically. This patch changes that behavior so that the q_vectors are allocated dynamically and the napi structures are automatically allocated inside of the q_vectors as needed. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ixgbe/ixgbe.h5
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c16
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c268
4 files changed, 158 insertions, 133 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 4b44a8efac8..61cb4153a18 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -187,6 +187,7 @@ struct ixgbe_q_vector {
187 u8 tx_itr; 187 u8 tx_itr;
188 u8 rx_itr; 188 u8 rx_itr;
189 u32 eitr; 189 u32 eitr;
190 u32 v_idx; /* vector index in list */
190}; 191};
191 192
192/* Helper macros to switch between ints/sec and what the register uses. 193/* Helper macros to switch between ints/sec and what the register uses.
@@ -230,7 +231,7 @@ struct ixgbe_adapter {
230 struct vlan_group *vlgrp; 231 struct vlan_group *vlgrp;
231 u16 bd_number; 232 u16 bd_number;
232 struct work_struct reset_task; 233 struct work_struct reset_task;
233 struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS]; 234 struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
234 char name[MAX_MSIX_COUNT][IFNAMSIZ + 9]; 235 char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
235 struct ixgbe_dcb_config dcb_cfg; 236 struct ixgbe_dcb_config dcb_cfg;
236 struct ixgbe_dcb_config temp_dcb_cfg; 237 struct ixgbe_dcb_config temp_dcb_cfg;
@@ -367,8 +368,8 @@ extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *)
367extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); 368extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
368extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); 369extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
369extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); 370extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
370extern void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter);
371extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); 371extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
372extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
372void ixgbe_napi_add_all(struct ixgbe_adapter *adapter); 373void ixgbe_napi_add_all(struct ixgbe_adapter *adapter);
373void ixgbe_napi_del_all(struct ixgbe_adapter *adapter); 374void ixgbe_napi_del_all(struct ixgbe_adapter *adapter);
374extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32); 375extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32);
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index bd0a0c27695..99e0c106e67 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -124,13 +124,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
124 124
125 if (netif_running(netdev)) 125 if (netif_running(netdev))
126 netdev->netdev_ops->ndo_stop(netdev); 126 netdev->netdev_ops->ndo_stop(netdev);
127 ixgbe_reset_interrupt_capability(adapter); 127 ixgbe_clear_interrupt_scheme(adapter);
128 ixgbe_napi_del_all(adapter);
129 INIT_LIST_HEAD(&netdev->napi_list);
130 kfree(adapter->tx_ring);
131 kfree(adapter->rx_ring);
132 adapter->tx_ring = NULL;
133 adapter->rx_ring = NULL;
134 128
135 adapter->hw.fc.requested_mode = ixgbe_fc_pfc; 129 adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
136 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; 130 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
@@ -144,13 +138,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
144 adapter->hw.fc.requested_mode = ixgbe_fc_default; 138 adapter->hw.fc.requested_mode = ixgbe_fc_default;
145 if (netif_running(netdev)) 139 if (netif_running(netdev))
146 netdev->netdev_ops->ndo_stop(netdev); 140 netdev->netdev_ops->ndo_stop(netdev);
147 ixgbe_reset_interrupt_capability(adapter); 141 ixgbe_clear_interrupt_scheme(adapter);
148 ixgbe_napi_del_all(adapter);
149 INIT_LIST_HEAD(&netdev->napi_list);
150 kfree(adapter->tx_ring);
151 kfree(adapter->rx_ring);
152 adapter->tx_ring = NULL;
153 adapter->rx_ring = NULL;
154 142
155 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; 143 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
156 adapter->flags |= IXGBE_FLAG_RSS_ENABLED; 144 adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index d822c92058c..c0167d617b1 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -1114,7 +1114,7 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
1114 } 1114 }
1115 1115
1116 for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { 1116 for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
1117 struct ixgbe_q_vector *q_vector = &adapter->q_vector[i]; 1117 struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
1118 if (q_vector->txr_count && !q_vector->rxr_count) 1118 if (q_vector->txr_count && !q_vector->rxr_count)
1119 /* tx vector gets half the rate */ 1119 /* tx vector gets half the rate */
1120 q_vector->eitr = (adapter->eitr_param >> 1); 1120 q_vector->eitr = (adapter->eitr_param >> 1);
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index be5eabce9e3..165bfa600b4 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -468,7 +468,7 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
468 bool is_vlan = (status & IXGBE_RXD_STAT_VP); 468 bool is_vlan = (status & IXGBE_RXD_STAT_VP);
469 u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); 469 u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
470 470
471 skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]); 471 skb_record_rx_queue(skb, q_vector->v_idx);
472 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { 472 if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
473 if (adapter->vlgrp && is_vlan && (tag != 0)) 473 if (adapter->vlgrp && is_vlan && (tag != 0))
474 vlan_gro_receive(napi, adapter->vlgrp, tag, skb); 474 vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
@@ -835,7 +835,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
835 * corresponding register. 835 * corresponding register.
836 */ 836 */
837 for (v_idx = 0; v_idx < q_vectors; v_idx++) { 837 for (v_idx = 0; v_idx < q_vectors; v_idx++) {
838 q_vector = &adapter->q_vector[v_idx]; 838 q_vector = adapter->q_vector[v_idx];
839 /* XXX for_each_bit(...) */ 839 /* XXX for_each_bit(...) */
840 r_idx = find_first_bit(q_vector->rxr_idx, 840 r_idx = find_first_bit(q_vector->rxr_idx,
841 adapter->num_rx_queues); 841 adapter->num_rx_queues);
@@ -984,8 +984,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
984 struct ixgbe_adapter *adapter = q_vector->adapter; 984 struct ixgbe_adapter *adapter = q_vector->adapter;
985 u32 new_itr; 985 u32 new_itr;
986 u8 current_itr, ret_itr; 986 u8 current_itr, ret_itr;
987 int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) / 987 int i, r_idx, v_idx = q_vector->v_idx;
988 sizeof(struct ixgbe_q_vector);
989 struct ixgbe_ring *rx_ring, *tx_ring; 988 struct ixgbe_ring *rx_ring, *tx_ring;
990 989
991 r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); 990 r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
@@ -1303,19 +1302,21 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
1303static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, 1302static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
1304 int r_idx) 1303 int r_idx)
1305{ 1304{
1306 a->q_vector[v_idx].adapter = a; 1305 struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
1307 set_bit(r_idx, a->q_vector[v_idx].rxr_idx); 1306
1308 a->q_vector[v_idx].rxr_count++; 1307 set_bit(r_idx, q_vector->rxr_idx);
1308 q_vector->rxr_count++;
1309 a->rx_ring[r_idx].v_idx = 1 << v_idx; 1309 a->rx_ring[r_idx].v_idx = 1 << v_idx;
1310} 1310}
1311 1311
1312static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, 1312static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
1313 int r_idx) 1313 int t_idx)
1314{ 1314{
1315 a->q_vector[v_idx].adapter = a; 1315 struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
1316 set_bit(r_idx, a->q_vector[v_idx].txr_idx); 1316
1317 a->q_vector[v_idx].txr_count++; 1317 set_bit(t_idx, q_vector->txr_idx);
1318 a->tx_ring[r_idx].v_idx = 1 << v_idx; 1318 q_vector->txr_count++;
1319 a->tx_ring[t_idx].v_idx = 1 << v_idx;
1319} 1320}
1320 1321
1321/** 1322/**
@@ -1411,7 +1412,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
1411 (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ 1412 (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
1412 &ixgbe_msix_clean_many) 1413 &ixgbe_msix_clean_many)
1413 for (vector = 0; vector < q_vectors; vector++) { 1414 for (vector = 0; vector < q_vectors; vector++) {
1414 handler = SET_HANDLER(&adapter->q_vector[vector]); 1415 handler = SET_HANDLER(adapter->q_vector[vector]);
1415 1416
1416 if(handler == &ixgbe_msix_clean_rx) { 1417 if(handler == &ixgbe_msix_clean_rx) {
1417 sprintf(adapter->name[vector], "%s-%s-%d", 1418 sprintf(adapter->name[vector], "%s-%s-%d",
@@ -1427,7 +1428,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
1427 1428
1428 err = request_irq(adapter->msix_entries[vector].vector, 1429 err = request_irq(adapter->msix_entries[vector].vector,
1429 handler, 0, adapter->name[vector], 1430 handler, 0, adapter->name[vector],
1430 &(adapter->q_vector[vector])); 1431 adapter->q_vector[vector]);
1431 if (err) { 1432 if (err) {
1432 DPRINTK(PROBE, ERR, 1433 DPRINTK(PROBE, ERR,
1433 "request_irq failed for MSIX interrupt " 1434 "request_irq failed for MSIX interrupt "
@@ -1450,7 +1451,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
1450free_queue_irqs: 1451free_queue_irqs:
1451 for (i = vector - 1; i >= 0; i--) 1452 for (i = vector - 1; i >= 0; i--)
1452 free_irq(adapter->msix_entries[--vector].vector, 1453 free_irq(adapter->msix_entries[--vector].vector,
1453 &(adapter->q_vector[i])); 1454 adapter->q_vector[i]);
1454 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; 1455 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
1455 pci_disable_msix(adapter->pdev); 1456 pci_disable_msix(adapter->pdev);
1456 kfree(adapter->msix_entries); 1457 kfree(adapter->msix_entries);
@@ -1461,7 +1462,7 @@ out:
1461 1462
1462static void ixgbe_set_itr(struct ixgbe_adapter *adapter) 1463static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
1463{ 1464{
1464 struct ixgbe_q_vector *q_vector = adapter->q_vector; 1465 struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
1465 u8 current_itr; 1466 u8 current_itr;
1466 u32 new_itr = q_vector->eitr; 1467 u32 new_itr = q_vector->eitr;
1467 struct ixgbe_ring *rx_ring = &adapter->rx_ring[0]; 1468 struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
@@ -1539,6 +1540,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
1539 struct net_device *netdev = data; 1540 struct net_device *netdev = data;
1540 struct ixgbe_adapter *adapter = netdev_priv(netdev); 1541 struct ixgbe_adapter *adapter = netdev_priv(netdev);
1541 struct ixgbe_hw *hw = &adapter->hw; 1542 struct ixgbe_hw *hw = &adapter->hw;
1543 struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
1542 u32 eicr; 1544 u32 eicr;
1543 1545
1544 /* 1546 /*
@@ -1566,13 +1568,13 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
1566 1568
1567 ixgbe_check_fan_failure(adapter, eicr); 1569 ixgbe_check_fan_failure(adapter, eicr);
1568 1570
1569 if (napi_schedule_prep(&adapter->q_vector[0].napi)) { 1571 if (napi_schedule_prep(&(q_vector->napi))) {
1570 adapter->tx_ring[0].total_packets = 0; 1572 adapter->tx_ring[0].total_packets = 0;
1571 adapter->tx_ring[0].total_bytes = 0; 1573 adapter->tx_ring[0].total_bytes = 0;
1572 adapter->rx_ring[0].total_packets = 0; 1574 adapter->rx_ring[0].total_packets = 0;
1573 adapter->rx_ring[0].total_bytes = 0; 1575 adapter->rx_ring[0].total_bytes = 0;
1574 /* would disable interrupts here but EIAM disabled it */ 1576 /* would disable interrupts here but EIAM disabled it */
1575 __napi_schedule(&adapter->q_vector[0].napi); 1577 __napi_schedule(&(q_vector->napi));
1576 } 1578 }
1577 1579
1578 return IRQ_HANDLED; 1580 return IRQ_HANDLED;
@@ -1583,7 +1585,7 @@ static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter)
1583 int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; 1585 int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
1584 1586
1585 for (i = 0; i < q_vectors; i++) { 1587 for (i = 0; i < q_vectors; i++) {
1586 struct ixgbe_q_vector *q_vector = &adapter->q_vector[i]; 1588 struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
1587 bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES); 1589 bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
1588 bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES); 1590 bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
1589 q_vector->rxr_count = 0; 1591 q_vector->rxr_count = 0;
@@ -1634,7 +1636,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
1634 i--; 1636 i--;
1635 for (; i >= 0; i--) { 1637 for (; i >= 0; i--) {
1636 free_irq(adapter->msix_entries[i].vector, 1638 free_irq(adapter->msix_entries[i].vector,
1637 &(adapter->q_vector[i])); 1639 adapter->q_vector[i]);
1638 } 1640 }
1639 1641
1640 ixgbe_reset_q_vectors(adapter); 1642 ixgbe_reset_q_vectors(adapter);
@@ -2135,7 +2137,7 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
2135 2137
2136 for (q_idx = 0; q_idx < q_vectors; q_idx++) { 2138 for (q_idx = 0; q_idx < q_vectors; q_idx++) {
2137 struct napi_struct *napi; 2139 struct napi_struct *napi;
2138 q_vector = &adapter->q_vector[q_idx]; 2140 q_vector = adapter->q_vector[q_idx];
2139 if (!q_vector->rxr_count) 2141 if (!q_vector->rxr_count)
2140 continue; 2142 continue;
2141 napi = &q_vector->napi; 2143 napi = &q_vector->napi;
@@ -2158,7 +2160,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
2158 q_vectors = 1; 2160 q_vectors = 1;
2159 2161
2160 for (q_idx = 0; q_idx < q_vectors; q_idx++) { 2162 for (q_idx = 0; q_idx < q_vectors; q_idx++) {
2161 q_vector = &adapter->q_vector[q_idx]; 2163 q_vector = adapter->q_vector[q_idx];
2162 if (!q_vector->rxr_count) 2164 if (!q_vector->rxr_count)
2163 continue; 2165 continue;
2164 napi_disable(&q_vector->napi); 2166 napi_disable(&q_vector->napi);
@@ -2498,8 +2500,6 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
2498 /* hardware has been reset, we need to reload some things */ 2500 /* hardware has been reset, we need to reload some things */
2499 ixgbe_configure(adapter); 2501 ixgbe_configure(adapter);
2500 2502
2501 ixgbe_napi_add_all(adapter);
2502
2503 return ixgbe_up_complete(adapter); 2503 return ixgbe_up_complete(adapter);
2504} 2504}
2505 2505
@@ -2877,9 +2877,6 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
2877 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; 2877 adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
2878 kfree(adapter->msix_entries); 2878 kfree(adapter->msix_entries);
2879 adapter->msix_entries = NULL; 2879 adapter->msix_entries = NULL;
2880 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
2881 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
2882 ixgbe_set_num_queues(adapter);
2883 } else { 2880 } else {
2884 adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */ 2881 adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
2885 /* 2882 /*
@@ -3103,31 +3100,20 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
3103 * mean we disable MSI-X capabilities of the adapter. */ 3100 * mean we disable MSI-X capabilities of the adapter. */
3104 adapter->msix_entries = kcalloc(v_budget, 3101 adapter->msix_entries = kcalloc(v_budget,
3105 sizeof(struct msix_entry), GFP_KERNEL); 3102 sizeof(struct msix_entry), GFP_KERNEL);
3106 if (!adapter->msix_entries) { 3103 if (adapter->msix_entries) {
3107 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; 3104 for (vector = 0; vector < v_budget; vector++)
3108 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; 3105 adapter->msix_entries[vector].entry = vector;
3109 ixgbe_set_num_queues(adapter);
3110 kfree(adapter->tx_ring);
3111 kfree(adapter->rx_ring);
3112 err = ixgbe_alloc_queues(adapter);
3113 if (err) {
3114 DPRINTK(PROBE, ERR, "Unable to allocate memory "
3115 "for queues\n");
3116 goto out;
3117 }
3118
3119 goto try_msi;
3120 }
3121 3106
3122 for (vector = 0; vector < v_budget; vector++) 3107 ixgbe_acquire_msix_vectors(adapter, v_budget);
3123 adapter->msix_entries[vector].entry = vector;
3124 3108
3125 ixgbe_acquire_msix_vectors(adapter, v_budget); 3109 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
3110 goto out;
3111 }
3126 3112
3127 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) 3113 adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
3128 goto out; 3114 adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
3115 ixgbe_set_num_queues(adapter);
3129 3116
3130try_msi:
3131 err = pci_enable_msi(adapter->pdev); 3117 err = pci_enable_msi(adapter->pdev);
3132 if (!err) { 3118 if (!err) {
3133 adapter->flags |= IXGBE_FLAG_MSI_ENABLED; 3119 adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
@@ -3142,6 +3128,87 @@ out:
3142 return err; 3128 return err;
3143} 3129}
3144 3130
3131/**
3132 * ixgbe_alloc_q_vectors - Allocate memory for interrupt vectors
3133 * @adapter: board private structure to initialize
3134 *
3135 * We allocate one q_vector per queue interrupt. If allocation fails we
3136 * return -ENOMEM.
3137 **/
3138static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
3139{
3140 int q_idx, num_q_vectors;
3141 struct ixgbe_q_vector *q_vector;
3142 int napi_vectors;
3143 int (*poll)(struct napi_struct *, int);
3144
3145 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
3146 num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
3147 napi_vectors = adapter->num_rx_queues;
3148 poll = &ixgbe_clean_rxonly;
3149 } else {
3150 num_q_vectors = 1;
3151 napi_vectors = 1;
3152 poll = &ixgbe_poll;
3153 }
3154
3155 for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
3156 q_vector = kzalloc(sizeof(struct ixgbe_q_vector), GFP_KERNEL);
3157 if (!q_vector)
3158 goto err_out;
3159 q_vector->adapter = adapter;
3160 q_vector->v_idx = q_idx;
3161 q_vector->eitr = adapter->eitr_param;
3162 if (q_idx < napi_vectors)
3163 netif_napi_add(adapter->netdev, &q_vector->napi,
3164 (*poll), 64);
3165 adapter->q_vector[q_idx] = q_vector;
3166 }
3167
3168 return 0;
3169
3170err_out:
3171 while (q_idx) {
3172 q_idx--;
3173 q_vector = adapter->q_vector[q_idx];
3174 netif_napi_del(&q_vector->napi);
3175 kfree(q_vector);
3176 adapter->q_vector[q_idx] = NULL;
3177 }
3178 return -ENOMEM;
3179}
3180
3181/**
3182 * ixgbe_free_q_vectors - Free memory allocated for interrupt vectors
3183 * @adapter: board private structure to initialize
3184 *
3185 * This function frees the memory allocated to the q_vectors. In addition if
3186 * NAPI is enabled it will delete any references to the NAPI struct prior
3187 * to freeing the q_vector.
3188 **/
3189static void ixgbe_free_q_vectors(struct ixgbe_adapter *adapter)
3190{
3191 int q_idx, num_q_vectors;
3192 int napi_vectors;
3193
3194 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
3195 num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
3196 napi_vectors = adapter->num_rx_queues;
3197 } else {
3198 num_q_vectors = 1;
3199 napi_vectors = 1;
3200 }
3201
3202 for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
3203 struct ixgbe_q_vector *q_vector = adapter->q_vector[q_idx];
3204
3205 adapter->q_vector[q_idx] = NULL;
3206 if (q_idx < napi_vectors)
3207 netif_napi_del(&q_vector->napi);
3208 kfree(q_vector);
3209 }
3210}
3211
3145void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter) 3212void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
3146{ 3213{
3147 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { 3214 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -3173,18 +3240,25 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
3173 /* Number of supported queues */ 3240 /* Number of supported queues */
3174 ixgbe_set_num_queues(adapter); 3241 ixgbe_set_num_queues(adapter);
3175 3242
3176 err = ixgbe_alloc_queues(adapter);
3177 if (err) {
3178 DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
3179 goto err_alloc_queues;
3180 }
3181
3182 err = ixgbe_set_interrupt_capability(adapter); 3243 err = ixgbe_set_interrupt_capability(adapter);
3183 if (err) { 3244 if (err) {
3184 DPRINTK(PROBE, ERR, "Unable to setup interrupt capabilities\n"); 3245 DPRINTK(PROBE, ERR, "Unable to setup interrupt capabilities\n");
3185 goto err_set_interrupt; 3246 goto err_set_interrupt;
3186 } 3247 }
3187 3248
3249 err = ixgbe_alloc_q_vectors(adapter);
3250 if (err) {
3251 DPRINTK(PROBE, ERR, "Unable to allocate memory for queue "
3252 "vectors\n");
3253 goto err_alloc_q_vectors;
3254 }
3255
3256 err = ixgbe_alloc_queues(adapter);
3257 if (err) {
3258 DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
3259 goto err_alloc_queues;
3260 }
3261
3188 DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, " 3262 DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
3189 "Tx Queue count = %u\n", 3263 "Tx Queue count = %u\n",
3190 (adapter->num_rx_queues > 1) ? "Enabled" : 3264 (adapter->num_rx_queues > 1) ? "Enabled" :
@@ -3194,11 +3268,30 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
3194 3268
3195 return 0; 3269 return 0;
3196 3270
3271err_alloc_queues:
3272 ixgbe_free_q_vectors(adapter);
3273err_alloc_q_vectors:
3274 ixgbe_reset_interrupt_capability(adapter);
3197err_set_interrupt: 3275err_set_interrupt:
3276 return err;
3277}
3278
3279/**
3280 * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings
3281 * @adapter: board private structure to clear interrupt scheme on
3282 *
3283 * We go through and clear interrupt specific resources and reset the structure
3284 * to pre-load conditions
3285 **/
3286void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
3287{
3198 kfree(adapter->tx_ring); 3288 kfree(adapter->tx_ring);
3199 kfree(adapter->rx_ring); 3289 kfree(adapter->rx_ring);
3200err_alloc_queues: 3290 adapter->tx_ring = NULL;
3201 return err; 3291 adapter->rx_ring = NULL;
3292
3293 ixgbe_free_q_vectors(adapter);
3294 ixgbe_reset_interrupt_capability(adapter);
3202} 3295}
3203 3296
3204/** 3297/**
@@ -3619,8 +3712,6 @@ static int ixgbe_open(struct net_device *netdev)
3619 3712
3620 ixgbe_configure(adapter); 3713 ixgbe_configure(adapter);
3621 3714
3622 ixgbe_napi_add_all(adapter);
3623
3624 err = ixgbe_request_irq(adapter); 3715 err = ixgbe_request_irq(adapter);
3625 if (err) 3716 if (err)
3626 goto err_req_irq; 3717 goto err_req_irq;
@@ -3672,55 +3763,6 @@ static int ixgbe_close(struct net_device *netdev)
3672 return 0; 3763 return 0;
3673} 3764}
3674 3765
3675/**
3676 * ixgbe_napi_add_all - prep napi structs for use
3677 * @adapter: private struct
3678 *
3679 * helper function to napi_add each possible q_vector->napi
3680 */
3681void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
3682{
3683 int q_idx, q_vectors;
3684 struct net_device *netdev = adapter->netdev;
3685 int (*poll)(struct napi_struct *, int);
3686
3687 /* check if we already have our netdev->napi_list populated */
3688 if (&netdev->napi_list != netdev->napi_list.next)
3689 return;
3690
3691 if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
3692 poll = &ixgbe_clean_rxonly;
3693 /* Only enable as many vectors as we have rx queues. */
3694 q_vectors = adapter->num_rx_queues;
3695 } else {
3696 poll = &ixgbe_poll;
3697 /* only one q_vector for legacy modes */
3698 q_vectors = 1;
3699 }
3700
3701 for (q_idx = 0; q_idx < q_vectors; q_idx++) {
3702 struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
3703 netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
3704 }
3705}
3706
3707void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
3708{
3709 int q_idx;
3710 int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
3711
3712 /* legacy and MSI only use one vector */
3713 if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
3714 q_vectors = 1;
3715
3716 for (q_idx = 0; q_idx < q_vectors; q_idx++) {
3717 struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
3718 if (!q_vector->rxr_count)
3719 continue;
3720 netif_napi_del(&q_vector->napi);
3721 }
3722}
3723
3724#ifdef CONFIG_PM 3766#ifdef CONFIG_PM
3725static int ixgbe_resume(struct pci_dev *pdev) 3767static int ixgbe_resume(struct pci_dev *pdev)
3726{ 3768{
@@ -3782,11 +3824,7 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
3782 ixgbe_free_all_tx_resources(adapter); 3824 ixgbe_free_all_tx_resources(adapter);
3783 ixgbe_free_all_rx_resources(adapter); 3825 ixgbe_free_all_rx_resources(adapter);
3784 } 3826 }
3785 ixgbe_reset_interrupt_capability(adapter); 3827 ixgbe_clear_interrupt_scheme(adapter);
3786 ixgbe_napi_del_all(adapter);
3787 INIT_LIST_HEAD(&netdev->napi_list);
3788 kfree(adapter->tx_ring);
3789 kfree(adapter->rx_ring);
3790 3828
3791#ifdef CONFIG_PM 3829#ifdef CONFIG_PM
3792 retval = pci_save_state(pdev); 3830 retval = pci_save_state(pdev);
@@ -5012,8 +5050,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
5012err_register: 5050err_register:
5013 ixgbe_release_hw_control(adapter); 5051 ixgbe_release_hw_control(adapter);
5014err_hw_init: 5052err_hw_init:
5053 ixgbe_clear_interrupt_scheme(adapter);
5015err_sw_init: 5054err_sw_init:
5016 ixgbe_reset_interrupt_capability(adapter);
5017err_eeprom: 5055err_eeprom:
5018 clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); 5056 clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
5019 del_timer_sync(&adapter->sfp_timer); 5057 del_timer_sync(&adapter->sfp_timer);
@@ -5071,7 +5109,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
5071 if (netdev->reg_state == NETREG_REGISTERED) 5109 if (netdev->reg_state == NETREG_REGISTERED)
5072 unregister_netdev(netdev); 5110 unregister_netdev(netdev);
5073 5111
5074 ixgbe_reset_interrupt_capability(adapter); 5112 ixgbe_clear_interrupt_scheme(adapter);
5075 5113
5076 ixgbe_release_hw_control(adapter); 5114 ixgbe_release_hw_control(adapter);
5077 5115
@@ -5079,8 +5117,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
5079 pci_release_regions(pdev); 5117 pci_release_regions(pdev);
5080 5118
5081 DPRINTK(PROBE, INFO, "complete\n"); 5119 DPRINTK(PROBE, INFO, "complete\n");
5082 kfree(adapter->tx_ring);
5083 kfree(adapter->rx_ring);
5084 5120
5085 free_netdev(netdev); 5121 free_netdev(netdev);
5086 5122