diff options
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 5 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_nl.c | 16 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 268 |
4 files changed, 158 insertions, 133 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 4b44a8efac8c..61cb4153a183 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 *) | |||
367 | extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); | 368 | extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); |
368 | extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); | 369 | extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); |
369 | extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); | 370 | extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); |
370 | extern void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter); | ||
371 | extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); | 371 | extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); |
372 | extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); | ||
372 | void ixgbe_napi_add_all(struct ixgbe_adapter *adapter); | 373 | void ixgbe_napi_add_all(struct ixgbe_adapter *adapter); |
373 | void ixgbe_napi_del_all(struct ixgbe_adapter *adapter); | 374 | void ixgbe_napi_del_all(struct ixgbe_adapter *adapter); |
374 | extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32); | 375 | extern 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 bd0a0c276952..99e0c106e671 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 d822c92058c3..c0167d617b1e 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 be5eabce9e35..165bfa600b4b 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) | |||
1303 | static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, | 1302 | static 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 | ||
1312 | static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, | 1312 | static 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) | |||
1450 | free_queue_irqs: | 1451 | free_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 | ||
1462 | static void ixgbe_set_itr(struct ixgbe_adapter *adapter) | 1463 | static 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 | ||
3130 | try_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 | **/ | ||
3138 | static 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 | |||
3170 | err_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 | **/ | ||
3189 | static 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 | |||
3145 | void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter) | 3212 | void 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 | ||
3271 | err_alloc_queues: | ||
3272 | ixgbe_free_q_vectors(adapter); | ||
3273 | err_alloc_q_vectors: | ||
3274 | ixgbe_reset_interrupt_capability(adapter); | ||
3197 | err_set_interrupt: | 3275 | err_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 | **/ | ||
3286 | void 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); |
3200 | err_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 | */ | ||
3681 | void 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 | |||
3707 | void 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 |
3725 | static int ixgbe_resume(struct pci_dev *pdev) | 3767 | static 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, | |||
5012 | err_register: | 5050 | err_register: |
5013 | ixgbe_release_hw_control(adapter); | 5051 | ixgbe_release_hw_control(adapter); |
5014 | err_hw_init: | 5052 | err_hw_init: |
5053 | ixgbe_clear_interrupt_scheme(adapter); | ||
5015 | err_sw_init: | 5054 | err_sw_init: |
5016 | ixgbe_reset_interrupt_capability(adapter); | ||
5017 | err_eeprom: | 5055 | err_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 | ||