aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c88
2 files changed, 54 insertions, 36 deletions
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index b9b9178e174e..c8aa9fb81d3c 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -178,7 +178,7 @@ struct enic {
178 unsigned int rq_count; 178 unsigned int rq_count;
179 u64 rq_truncated_pkts; 179 u64 rq_truncated_pkts;
180 u64 rq_bad_fcs; 180 u64 rq_bad_fcs;
181 struct napi_struct napi[ENIC_RQ_MAX]; 181 struct napi_struct napi[ENIC_RQ_MAX + ENIC_WQ_MAX];
182 182
183 /* interrupt resource cache line section */ 183 /* interrupt resource cache line section */
184 ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; 184 ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index d4918eef5050..9348febc0743 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -316,40 +316,15 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
316 return IRQ_HANDLED; 316 return IRQ_HANDLED;
317} 317}
318 318
319static irqreturn_t enic_isr_msix_rq(int irq, void *data) 319static irqreturn_t enic_isr_msix(int irq, void *data)
320{ 320{
321 struct napi_struct *napi = data; 321 struct napi_struct *napi = data;
322 322
323 /* schedule NAPI polling for RQ cleanup */
324 napi_schedule(napi); 323 napi_schedule(napi);
325 324
326 return IRQ_HANDLED; 325 return IRQ_HANDLED;
327} 326}
328 327
329static irqreturn_t enic_isr_msix_wq(int irq, void *data)
330{
331 struct enic *enic = data;
332 unsigned int cq;
333 unsigned int intr;
334 unsigned int wq_work_to_do = -1; /* no limit */
335 unsigned int wq_work_done;
336 unsigned int wq_irq;
337
338 wq_irq = (u32)irq - enic->msix_entry[enic_msix_wq_intr(enic, 0)].vector;
339 cq = enic_cq_wq(enic, wq_irq);
340 intr = enic_msix_wq_intr(enic, wq_irq);
341
342 wq_work_done = vnic_cq_service(&enic->cq[cq],
343 wq_work_to_do, enic_wq_service, NULL);
344
345 vnic_intr_return_credits(&enic->intr[intr],
346 wq_work_done,
347 1 /* unmask intr */,
348 1 /* reset intr timer */);
349
350 return IRQ_HANDLED;
351}
352
353static irqreturn_t enic_isr_msix_err(int irq, void *data) 328static irqreturn_t enic_isr_msix_err(int irq, void *data)
354{ 329{
355 struct enic *enic = data; 330 struct enic *enic = data;
@@ -1274,7 +1249,36 @@ int enic_busy_poll(struct napi_struct *napi)
1274} 1249}
1275#endif /* CONFIG_NET_RX_BUSY_POLL */ 1250#endif /* CONFIG_NET_RX_BUSY_POLL */
1276 1251
1277static int enic_poll_msix(struct napi_struct *napi, int budget) 1252static int enic_poll_msix_wq(struct napi_struct *napi, int budget)
1253{
1254 struct net_device *netdev = napi->dev;
1255 struct enic *enic = netdev_priv(netdev);
1256 unsigned int wq_index = (napi - &enic->napi[0]) - enic->rq_count;
1257 struct vnic_wq *wq = &enic->wq[wq_index];
1258 unsigned int cq;
1259 unsigned int intr;
1260 unsigned int wq_work_to_do = -1; /* clean all desc possible */
1261 unsigned int wq_work_done;
1262 unsigned int wq_irq;
1263
1264 wq_irq = wq->index;
1265 cq = enic_cq_wq(enic, wq_irq);
1266 intr = enic_msix_wq_intr(enic, wq_irq);
1267 wq_work_done = vnic_cq_service(&enic->cq[cq], wq_work_to_do,
1268 enic_wq_service, NULL);
1269
1270 vnic_intr_return_credits(&enic->intr[intr], wq_work_done,
1271 0 /* don't unmask intr */,
1272 1 /* reset intr timer */);
1273 if (!wq_work_done) {
1274 napi_complete(napi);
1275 vnic_intr_unmask(&enic->intr[intr]);
1276 }
1277
1278 return 0;
1279}
1280
1281static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
1278{ 1282{
1279 struct net_device *netdev = napi->dev; 1283 struct net_device *netdev = napi->dev;
1280 struct enic *enic = netdev_priv(netdev); 1284 struct enic *enic = netdev_priv(netdev);
@@ -1399,17 +1403,19 @@ static int enic_request_intr(struct enic *enic)
1399 snprintf(enic->msix[intr].devname, 1403 snprintf(enic->msix[intr].devname,
1400 sizeof(enic->msix[intr].devname), 1404 sizeof(enic->msix[intr].devname),
1401 "%.11s-rx-%d", netdev->name, i); 1405 "%.11s-rx-%d", netdev->name, i);
1402 enic->msix[intr].isr = enic_isr_msix_rq; 1406 enic->msix[intr].isr = enic_isr_msix;
1403 enic->msix[intr].devid = &enic->napi[i]; 1407 enic->msix[intr].devid = &enic->napi[i];
1404 } 1408 }
1405 1409
1406 for (i = 0; i < enic->wq_count; i++) { 1410 for (i = 0; i < enic->wq_count; i++) {
1411 int wq = enic_cq_wq(enic, i);
1412
1407 intr = enic_msix_wq_intr(enic, i); 1413 intr = enic_msix_wq_intr(enic, i);
1408 snprintf(enic->msix[intr].devname, 1414 snprintf(enic->msix[intr].devname,
1409 sizeof(enic->msix[intr].devname), 1415 sizeof(enic->msix[intr].devname),
1410 "%.11s-tx-%d", netdev->name, i); 1416 "%.11s-tx-%d", netdev->name, i);
1411 enic->msix[intr].isr = enic_isr_msix_wq; 1417 enic->msix[intr].isr = enic_isr_msix;
1412 enic->msix[intr].devid = enic; 1418 enic->msix[intr].devid = &enic->napi[wq];
1413 } 1419 }
1414 1420
1415 intr = enic_msix_err_intr(enic); 1421 intr = enic_msix_err_intr(enic);
@@ -1585,7 +1591,9 @@ static int enic_open(struct net_device *netdev)
1585 enic_busy_poll_init_lock(&enic->rq[i]); 1591 enic_busy_poll_init_lock(&enic->rq[i]);
1586 napi_enable(&enic->napi[i]); 1592 napi_enable(&enic->napi[i]);
1587 } 1593 }
1588 1594 if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
1595 for (i = 0; i < enic->wq_count; i++)
1596 napi_enable(&enic->napi[enic_cq_wq(enic, i)]);
1589 enic_dev_enable(enic); 1597 enic_dev_enable(enic);
1590 1598
1591 for (i = 0; i < enic->intr_count; i++) 1599 for (i = 0; i < enic->intr_count; i++)
@@ -1633,6 +1641,9 @@ static int enic_stop(struct net_device *netdev)
1633 1641
1634 netif_carrier_off(netdev); 1642 netif_carrier_off(netdev);
1635 netif_tx_disable(netdev); 1643 netif_tx_disable(netdev);
1644 if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
1645 for (i = 0; i < enic->wq_count; i++)
1646 napi_disable(&enic->napi[enic_cq_wq(enic, i)]);
1636 1647
1637 if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) 1648 if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
1638 enic_dev_del_station_addr(enic); 1649 enic_dev_del_station_addr(enic);
@@ -1752,13 +1763,14 @@ static void enic_poll_controller(struct net_device *netdev)
1752 case VNIC_DEV_INTR_MODE_MSIX: 1763 case VNIC_DEV_INTR_MODE_MSIX:
1753 for (i = 0; i < enic->rq_count; i++) { 1764 for (i = 0; i < enic->rq_count; i++) {
1754 intr = enic_msix_rq_intr(enic, i); 1765 intr = enic_msix_rq_intr(enic, i);
1755 enic_isr_msix_rq(enic->msix_entry[intr].vector, 1766 enic_isr_msix(enic->msix_entry[intr].vector,
1756 &enic->napi[i]); 1767 &enic->napi[i]);
1757 } 1768 }
1758 1769
1759 for (i = 0; i < enic->wq_count; i++) { 1770 for (i = 0; i < enic->wq_count; i++) {
1760 intr = enic_msix_wq_intr(enic, i); 1771 intr = enic_msix_wq_intr(enic, i);
1761 enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); 1772 enic_isr_msix(enic->msix_entry[intr].vector,
1773 &enic->napi[enic_cq_wq(enic, i)]);
1762 } 1774 }
1763 1775
1764 break; 1776 break;
@@ -2159,6 +2171,9 @@ static void enic_dev_deinit(struct enic *enic)
2159 napi_hash_del(&enic->napi[i]); 2171 napi_hash_del(&enic->napi[i]);
2160 netif_napi_del(&enic->napi[i]); 2172 netif_napi_del(&enic->napi[i]);
2161 } 2173 }
2174 if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
2175 for (i = 0; i < enic->wq_count; i++)
2176 netif_napi_del(&enic->napi[enic_cq_wq(enic, i)]);
2162 2177
2163 enic_free_vnic_resources(enic); 2178 enic_free_vnic_resources(enic);
2164 enic_clear_intr_mode(enic); 2179 enic_clear_intr_mode(enic);
@@ -2229,9 +2244,12 @@ static int enic_dev_init(struct enic *enic)
2229 case VNIC_DEV_INTR_MODE_MSIX: 2244 case VNIC_DEV_INTR_MODE_MSIX:
2230 for (i = 0; i < enic->rq_count; i++) { 2245 for (i = 0; i < enic->rq_count; i++) {
2231 netif_napi_add(netdev, &enic->napi[i], 2246 netif_napi_add(netdev, &enic->napi[i],
2232 enic_poll_msix, 64); 2247 enic_poll_msix_rq, NAPI_POLL_WEIGHT);
2233 napi_hash_add(&enic->napi[i]); 2248 napi_hash_add(&enic->napi[i]);
2234 } 2249 }
2250 for (i = 0; i < enic->wq_count; i++)
2251 netif_napi_add(netdev, &enic->napi[enic_cq_wq(enic, i)],
2252 enic_poll_msix_wq, NAPI_POLL_WEIGHT);
2235 break; 2253 break;
2236 } 2254 }
2237 2255