diff options
Diffstat (limited to 'drivers/net/myri10ge')
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 556962f9612d..a30146ea51f0 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -163,6 +163,7 @@ struct myri10ge_priv { | |||
163 | int small_bytes; | 163 | int small_bytes; |
164 | int big_bytes; | 164 | int big_bytes; |
165 | struct net_device *dev; | 165 | struct net_device *dev; |
166 | struct napi_struct napi; | ||
166 | struct net_device_stats stats; | 167 | struct net_device_stats stats; |
167 | u8 __iomem *sram; | 168 | u8 __iomem *sram; |
168 | int sram_size; | 169 | int sram_size; |
@@ -1100,7 +1101,7 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) | |||
1100 | } | 1101 | } |
1101 | } | 1102 | } |
1102 | 1103 | ||
1103 | static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) | 1104 | static inline int myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int budget) |
1104 | { | 1105 | { |
1105 | struct myri10ge_rx_done *rx_done = &mgp->rx_done; | 1106 | struct myri10ge_rx_done *rx_done = &mgp->rx_done; |
1106 | unsigned long rx_bytes = 0; | 1107 | unsigned long rx_bytes = 0; |
@@ -1109,10 +1110,11 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) | |||
1109 | 1110 | ||
1110 | int idx = rx_done->idx; | 1111 | int idx = rx_done->idx; |
1111 | int cnt = rx_done->cnt; | 1112 | int cnt = rx_done->cnt; |
1113 | int work_done = 0; | ||
1112 | u16 length; | 1114 | u16 length; |
1113 | __wsum checksum; | 1115 | __wsum checksum; |
1114 | 1116 | ||
1115 | while (rx_done->entry[idx].length != 0 && *limit != 0) { | 1117 | while (rx_done->entry[idx].length != 0 && work_done++ < budget) { |
1116 | length = ntohs(rx_done->entry[idx].length); | 1118 | length = ntohs(rx_done->entry[idx].length); |
1117 | rx_done->entry[idx].length = 0; | 1119 | rx_done->entry[idx].length = 0; |
1118 | checksum = csum_unfold(rx_done->entry[idx].checksum); | 1120 | checksum = csum_unfold(rx_done->entry[idx].checksum); |
@@ -1128,10 +1130,6 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) | |||
1128 | rx_bytes += rx_ok * (unsigned long)length; | 1130 | rx_bytes += rx_ok * (unsigned long)length; |
1129 | cnt++; | 1131 | cnt++; |
1130 | idx = cnt & (myri10ge_max_intr_slots - 1); | 1132 | idx = cnt & (myri10ge_max_intr_slots - 1); |
1131 | |||
1132 | /* limit potential for livelock by only handling a | ||
1133 | * limited number of frames. */ | ||
1134 | (*limit)--; | ||
1135 | } | 1133 | } |
1136 | rx_done->idx = idx; | 1134 | rx_done->idx = idx; |
1137 | rx_done->cnt = cnt; | 1135 | rx_done->cnt = cnt; |
@@ -1145,6 +1143,7 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) | |||
1145 | if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh) | 1143 | if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh) |
1146 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); | 1144 | myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); |
1147 | 1145 | ||
1146 | return work_done; | ||
1148 | } | 1147 | } |
1149 | 1148 | ||
1150 | static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | 1149 | static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) |
@@ -1189,26 +1188,21 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | |||
1189 | } | 1188 | } |
1190 | } | 1189 | } |
1191 | 1190 | ||
1192 | static int myri10ge_poll(struct net_device *netdev, int *budget) | 1191 | static int myri10ge_poll(struct napi_struct *napi, int budget) |
1193 | { | 1192 | { |
1194 | struct myri10ge_priv *mgp = netdev_priv(netdev); | 1193 | struct myri10ge_priv *mgp = container_of(napi, struct myri10ge_priv, napi); |
1194 | struct net_device *netdev = mgp->dev; | ||
1195 | struct myri10ge_rx_done *rx_done = &mgp->rx_done; | 1195 | struct myri10ge_rx_done *rx_done = &mgp->rx_done; |
1196 | int limit, orig_limit, work_done; | 1196 | int work_done; |
1197 | 1197 | ||
1198 | /* process as many rx events as NAPI will allow */ | 1198 | /* process as many rx events as NAPI will allow */ |
1199 | limit = min(*budget, netdev->quota); | 1199 | work_done = myri10ge_clean_rx_done(mgp, budget); |
1200 | orig_limit = limit; | ||
1201 | myri10ge_clean_rx_done(mgp, &limit); | ||
1202 | work_done = orig_limit - limit; | ||
1203 | *budget -= work_done; | ||
1204 | netdev->quota -= work_done; | ||
1205 | 1200 | ||
1206 | if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) { | 1201 | if (rx_done->entry[rx_done->idx].length == 0 || !netif_running(netdev)) { |
1207 | netif_rx_complete(netdev); | 1202 | netif_rx_complete(netdev, napi); |
1208 | put_be32(htonl(3), mgp->irq_claim); | 1203 | put_be32(htonl(3), mgp->irq_claim); |
1209 | return 0; | ||
1210 | } | 1204 | } |
1211 | return 1; | 1205 | return work_done; |
1212 | } | 1206 | } |
1213 | 1207 | ||
1214 | static irqreturn_t myri10ge_intr(int irq, void *arg) | 1208 | static irqreturn_t myri10ge_intr(int irq, void *arg) |
@@ -1226,7 +1220,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) | |||
1226 | /* low bit indicates receives are present, so schedule | 1220 | /* low bit indicates receives are present, so schedule |
1227 | * napi poll handler */ | 1221 | * napi poll handler */ |
1228 | if (stats->valid & 1) | 1222 | if (stats->valid & 1) |
1229 | netif_rx_schedule(mgp->dev); | 1223 | netif_rx_schedule(mgp->dev, &mgp->napi); |
1230 | 1224 | ||
1231 | if (!mgp->msi_enabled) { | 1225 | if (!mgp->msi_enabled) { |
1232 | put_be32(0, mgp->irq_deassert); | 1226 | put_be32(0, mgp->irq_deassert); |
@@ -1853,7 +1847,7 @@ static int myri10ge_open(struct net_device *dev) | |||
1853 | mgp->link_state = htonl(~0U); | 1847 | mgp->link_state = htonl(~0U); |
1854 | mgp->rdma_tags_available = 15; | 1848 | mgp->rdma_tags_available = 15; |
1855 | 1849 | ||
1856 | netif_poll_enable(mgp->dev); /* must happen prior to any irq */ | 1850 | napi_enable(&mgp->napi); /* must happen prior to any irq */ |
1857 | 1851 | ||
1858 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0); | 1852 | status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0); |
1859 | if (status) { | 1853 | if (status) { |
@@ -1897,7 +1891,7 @@ static int myri10ge_close(struct net_device *dev) | |||
1897 | 1891 | ||
1898 | del_timer_sync(&mgp->watchdog_timer); | 1892 | del_timer_sync(&mgp->watchdog_timer); |
1899 | mgp->running = MYRI10GE_ETH_STOPPING; | 1893 | mgp->running = MYRI10GE_ETH_STOPPING; |
1900 | netif_poll_disable(mgp->dev); | 1894 | napi_disable(&mgp->napi); |
1901 | netif_carrier_off(dev); | 1895 | netif_carrier_off(dev); |
1902 | netif_stop_queue(dev); | 1896 | netif_stop_queue(dev); |
1903 | old_down_cnt = mgp->down_cnt; | 1897 | old_down_cnt = mgp->down_cnt; |
@@ -2857,6 +2851,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2857 | mgp = netdev_priv(netdev); | 2851 | mgp = netdev_priv(netdev); |
2858 | memset(mgp, 0, sizeof(*mgp)); | 2852 | memset(mgp, 0, sizeof(*mgp)); |
2859 | mgp->dev = netdev; | 2853 | mgp->dev = netdev; |
2854 | netif_napi_add(netdev, &mgp->napi, | ||
2855 | myri10ge_poll, myri10ge_napi_weight); | ||
2860 | mgp->pdev = pdev; | 2856 | mgp->pdev = pdev; |
2861 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; | 2857 | mgp->csum_flag = MXGEFW_FLAGS_CKSUM; |
2862 | mgp->pause = myri10ge_flow_control; | 2858 | mgp->pause = myri10ge_flow_control; |
@@ -2981,8 +2977,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2981 | netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; | 2977 | netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; |
2982 | if (dac_enabled) | 2978 | if (dac_enabled) |
2983 | netdev->features |= NETIF_F_HIGHDMA; | 2979 | netdev->features |= NETIF_F_HIGHDMA; |
2984 | netdev->poll = myri10ge_poll; | ||
2985 | netdev->weight = myri10ge_napi_weight; | ||
2986 | 2980 | ||
2987 | /* make sure we can get an irq, and that MSI can be | 2981 | /* make sure we can get an irq, and that MSI can be |
2988 | * setup (if available). Also ensure netdev->irq | 2982 | * setup (if available). Also ensure netdev->irq |