diff options
Diffstat (limited to 'drivers/net/benet/be_main.c')
-rw-r--r-- | drivers/net/benet/be_main.c | 640 |
1 files changed, 490 insertions, 150 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 02a0443d182..a485f7fdaf3 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * Costa Mesa, CA 92626 | 15 | * Costa Mesa, CA 92626 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/prefetch.h> | ||
18 | #include "be.h" | 19 | #include "be.h" |
19 | #include "be_cmds.h" | 20 | #include "be_cmds.h" |
20 | #include <asm/div64.h> | 21 | #include <asm/div64.h> |
@@ -42,6 +43,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { | |||
42 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, | 43 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) }, |
43 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, | 44 | { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) }, |
44 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)}, | 45 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)}, |
46 | { PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)}, | ||
45 | { 0 } | 47 | { 0 } |
46 | }; | 48 | }; |
47 | MODULE_DEVICE_TABLE(pci, be_dev_ids); | 49 | MODULE_DEVICE_TABLE(pci, be_dev_ids); |
@@ -116,11 +118,6 @@ static char *ue_status_hi_desc[] = { | |||
116 | "Unknown" | 118 | "Unknown" |
117 | }; | 119 | }; |
118 | 120 | ||
119 | static inline bool be_multi_rxq(struct be_adapter *adapter) | ||
120 | { | ||
121 | return (adapter->num_rx_qs > 1); | ||
122 | } | ||
123 | |||
124 | static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) | 121 | static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) |
125 | { | 122 | { |
126 | struct be_dma_mem *mem = &q->dma_mem; | 123 | struct be_dma_mem *mem = &q->dma_mem; |
@@ -250,14 +247,185 @@ netdev_addr: | |||
250 | return status; | 247 | return status; |
251 | } | 248 | } |
252 | 249 | ||
250 | static void populate_be2_stats(struct be_adapter *adapter) | ||
251 | { | ||
252 | |||
253 | struct be_drv_stats *drvs = &adapter->drv_stats; | ||
254 | struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); | ||
255 | struct be_port_rxf_stats_v0 *port_stats = | ||
256 | be_port_rxf_stats_from_cmd(adapter); | ||
257 | struct be_rxf_stats_v0 *rxf_stats = | ||
258 | be_rxf_stats_from_cmd(adapter); | ||
259 | |||
260 | drvs->rx_pause_frames = port_stats->rx_pause_frames; | ||
261 | drvs->rx_crc_errors = port_stats->rx_crc_errors; | ||
262 | drvs->rx_control_frames = port_stats->rx_control_frames; | ||
263 | drvs->rx_in_range_errors = port_stats->rx_in_range_errors; | ||
264 | drvs->rx_frame_too_long = port_stats->rx_frame_too_long; | ||
265 | drvs->rx_dropped_runt = port_stats->rx_dropped_runt; | ||
266 | drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs; | ||
267 | drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs; | ||
268 | drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs; | ||
269 | drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow; | ||
270 | drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length; | ||
271 | drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small; | ||
272 | drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short; | ||
273 | drvs->rx_out_range_errors = port_stats->rx_out_range_errors; | ||
274 | drvs->rx_input_fifo_overflow_drop = | ||
275 | port_stats->rx_input_fifo_overflow; | ||
276 | drvs->rx_dropped_header_too_small = | ||
277 | port_stats->rx_dropped_header_too_small; | ||
278 | drvs->rx_address_match_errors = | ||
279 | port_stats->rx_address_match_errors; | ||
280 | drvs->rx_alignment_symbol_errors = | ||
281 | port_stats->rx_alignment_symbol_errors; | ||
282 | |||
283 | drvs->tx_pauseframes = port_stats->tx_pauseframes; | ||
284 | drvs->tx_controlframes = port_stats->tx_controlframes; | ||
285 | |||
286 | if (adapter->port_num) | ||
287 | drvs->jabber_events = | ||
288 | rxf_stats->port1_jabber_events; | ||
289 | else | ||
290 | drvs->jabber_events = | ||
291 | rxf_stats->port0_jabber_events; | ||
292 | drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; | ||
293 | drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; | ||
294 | drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; | ||
295 | drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; | ||
296 | drvs->forwarded_packets = rxf_stats->forwarded_packets; | ||
297 | drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; | ||
298 | drvs->rx_drops_no_tpre_descr = | ||
299 | rxf_stats->rx_drops_no_tpre_descr; | ||
300 | drvs->rx_drops_too_many_frags = | ||
301 | rxf_stats->rx_drops_too_many_frags; | ||
302 | adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; | ||
303 | } | ||
304 | |||
305 | static void populate_be3_stats(struct be_adapter *adapter) | ||
306 | { | ||
307 | struct be_drv_stats *drvs = &adapter->drv_stats; | ||
308 | struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter); | ||
309 | |||
310 | struct be_rxf_stats_v1 *rxf_stats = | ||
311 | be_rxf_stats_from_cmd(adapter); | ||
312 | struct be_port_rxf_stats_v1 *port_stats = | ||
313 | be_port_rxf_stats_from_cmd(adapter); | ||
314 | |||
315 | drvs->rx_priority_pause_frames = 0; | ||
316 | drvs->pmem_fifo_overflow_drop = 0; | ||
317 | drvs->rx_pause_frames = port_stats->rx_pause_frames; | ||
318 | drvs->rx_crc_errors = port_stats->rx_crc_errors; | ||
319 | drvs->rx_control_frames = port_stats->rx_control_frames; | ||
320 | drvs->rx_in_range_errors = port_stats->rx_in_range_errors; | ||
321 | drvs->rx_frame_too_long = port_stats->rx_frame_too_long; | ||
322 | drvs->rx_dropped_runt = port_stats->rx_dropped_runt; | ||
323 | drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs; | ||
324 | drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs; | ||
325 | drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs; | ||
326 | drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length; | ||
327 | drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small; | ||
328 | drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short; | ||
329 | drvs->rx_out_range_errors = port_stats->rx_out_range_errors; | ||
330 | drvs->rx_dropped_header_too_small = | ||
331 | port_stats->rx_dropped_header_too_small; | ||
332 | drvs->rx_input_fifo_overflow_drop = | ||
333 | port_stats->rx_input_fifo_overflow_drop; | ||
334 | drvs->rx_address_match_errors = | ||
335 | port_stats->rx_address_match_errors; | ||
336 | drvs->rx_alignment_symbol_errors = | ||
337 | port_stats->rx_alignment_symbol_errors; | ||
338 | drvs->rxpp_fifo_overflow_drop = | ||
339 | port_stats->rxpp_fifo_overflow_drop; | ||
340 | drvs->tx_pauseframes = port_stats->tx_pauseframes; | ||
341 | drvs->tx_controlframes = port_stats->tx_controlframes; | ||
342 | drvs->jabber_events = port_stats->jabber_events; | ||
343 | drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; | ||
344 | drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; | ||
345 | drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; | ||
346 | drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; | ||
347 | drvs->forwarded_packets = rxf_stats->forwarded_packets; | ||
348 | drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; | ||
349 | drvs->rx_drops_no_tpre_descr = | ||
350 | rxf_stats->rx_drops_no_tpre_descr; | ||
351 | drvs->rx_drops_too_many_frags = | ||
352 | rxf_stats->rx_drops_too_many_frags; | ||
353 | adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops; | ||
354 | } | ||
355 | |||
356 | static void populate_lancer_stats(struct be_adapter *adapter) | ||
357 | { | ||
358 | |||
359 | struct be_drv_stats *drvs = &adapter->drv_stats; | ||
360 | struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd | ||
361 | (adapter); | ||
362 | drvs->rx_priority_pause_frames = 0; | ||
363 | drvs->pmem_fifo_overflow_drop = 0; | ||
364 | drvs->rx_pause_frames = | ||
365 | make_64bit_val(pport_stats->rx_pause_frames_lo, | ||
366 | pport_stats->rx_pause_frames_hi); | ||
367 | drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi, | ||
368 | pport_stats->rx_crc_errors_lo); | ||
369 | drvs->rx_control_frames = | ||
370 | make_64bit_val(pport_stats->rx_control_frames_hi, | ||
371 | pport_stats->rx_control_frames_lo); | ||
372 | drvs->rx_in_range_errors = pport_stats->rx_in_range_errors; | ||
373 | drvs->rx_frame_too_long = | ||
374 | make_64bit_val(pport_stats->rx_internal_mac_errors_hi, | ||
375 | pport_stats->rx_frames_too_long_lo); | ||
376 | drvs->rx_dropped_runt = pport_stats->rx_dropped_runt; | ||
377 | drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors; | ||
378 | drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors; | ||
379 | drvs->rx_udp_checksum_errs = pport_stats->rx_udp_checksum_errors; | ||
380 | drvs->rx_dropped_tcp_length = | ||
381 | pport_stats->rx_dropped_invalid_tcp_length; | ||
382 | drvs->rx_dropped_too_small = pport_stats->rx_dropped_too_small; | ||
383 | drvs->rx_dropped_too_short = pport_stats->rx_dropped_too_short; | ||
384 | drvs->rx_out_range_errors = pport_stats->rx_out_of_range_errors; | ||
385 | drvs->rx_dropped_header_too_small = | ||
386 | pport_stats->rx_dropped_header_too_small; | ||
387 | drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow; | ||
388 | drvs->rx_address_match_errors = pport_stats->rx_address_match_errors; | ||
389 | drvs->rx_alignment_symbol_errors = | ||
390 | make_64bit_val(pport_stats->rx_symbol_errors_hi, | ||
391 | pport_stats->rx_symbol_errors_lo); | ||
392 | drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow; | ||
393 | drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi, | ||
394 | pport_stats->tx_pause_frames_lo); | ||
395 | drvs->tx_controlframes = | ||
396 | make_64bit_val(pport_stats->tx_control_frames_hi, | ||
397 | pport_stats->tx_control_frames_lo); | ||
398 | drvs->jabber_events = pport_stats->rx_jabbers; | ||
399 | drvs->rx_drops_no_pbuf = 0; | ||
400 | drvs->rx_drops_no_txpb = 0; | ||
401 | drvs->rx_drops_no_erx_descr = 0; | ||
402 | drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue; | ||
403 | drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi, | ||
404 | pport_stats->num_forwards_lo); | ||
405 | drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi, | ||
406 | pport_stats->rx_drops_mtu_lo); | ||
407 | drvs->rx_drops_no_tpre_descr = 0; | ||
408 | drvs->rx_drops_too_many_frags = | ||
409 | make_64bit_val(pport_stats->rx_drops_too_many_frags_hi, | ||
410 | pport_stats->rx_drops_too_many_frags_lo); | ||
411 | } | ||
412 | |||
413 | void be_parse_stats(struct be_adapter *adapter) | ||
414 | { | ||
415 | if (adapter->generation == BE_GEN3) { | ||
416 | if (lancer_chip(adapter)) | ||
417 | populate_lancer_stats(adapter); | ||
418 | else | ||
419 | populate_be3_stats(adapter); | ||
420 | } else { | ||
421 | populate_be2_stats(adapter); | ||
422 | } | ||
423 | } | ||
424 | |||
253 | void netdev_stats_update(struct be_adapter *adapter) | 425 | void netdev_stats_update(struct be_adapter *adapter) |
254 | { | 426 | { |
255 | struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va); | 427 | struct be_drv_stats *drvs = &adapter->drv_stats; |
256 | struct be_rxf_stats *rxf_stats = &hw_stats->rxf; | ||
257 | struct be_port_rxf_stats *port_stats = | ||
258 | &rxf_stats->port[adapter->port_num]; | ||
259 | struct net_device_stats *dev_stats = &adapter->netdev->stats; | 428 | struct net_device_stats *dev_stats = &adapter->netdev->stats; |
260 | struct be_erx_stats *erx_stats = &hw_stats->erx; | ||
261 | struct be_rx_obj *rxo; | 429 | struct be_rx_obj *rxo; |
262 | int i; | 430 | int i; |
263 | 431 | ||
@@ -267,43 +435,54 @@ void netdev_stats_update(struct be_adapter *adapter) | |||
267 | dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes; | 435 | dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes; |
268 | dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts; | 436 | dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts; |
269 | /* no space in linux buffers: best possible approximation */ | 437 | /* no space in linux buffers: best possible approximation */ |
270 | dev_stats->rx_dropped += | 438 | if (adapter->generation == BE_GEN3) { |
271 | erx_stats->rx_drops_no_fragments[rxo->q.id]; | 439 | if (!(lancer_chip(adapter))) { |
440 | struct be_erx_stats_v1 *erx_stats = | ||
441 | be_erx_stats_from_cmd(adapter); | ||
442 | dev_stats->rx_dropped += | ||
443 | erx_stats->rx_drops_no_fragments[rxo->q.id]; | ||
444 | } | ||
445 | } else { | ||
446 | struct be_erx_stats_v0 *erx_stats = | ||
447 | be_erx_stats_from_cmd(adapter); | ||
448 | dev_stats->rx_dropped += | ||
449 | erx_stats->rx_drops_no_fragments[rxo->q.id]; | ||
450 | } | ||
272 | } | 451 | } |
273 | 452 | ||
274 | dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts; | 453 | dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts; |
275 | dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes; | 454 | dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes; |
276 | 455 | ||
277 | /* bad pkts received */ | 456 | /* bad pkts received */ |
278 | dev_stats->rx_errors = port_stats->rx_crc_errors + | 457 | dev_stats->rx_errors = drvs->rx_crc_errors + |
279 | port_stats->rx_alignment_symbol_errors + | 458 | drvs->rx_alignment_symbol_errors + |
280 | port_stats->rx_in_range_errors + | 459 | drvs->rx_in_range_errors + |
281 | port_stats->rx_out_range_errors + | 460 | drvs->rx_out_range_errors + |
282 | port_stats->rx_frame_too_long + | 461 | drvs->rx_frame_too_long + |
283 | port_stats->rx_dropped_too_small + | 462 | drvs->rx_dropped_too_small + |
284 | port_stats->rx_dropped_too_short + | 463 | drvs->rx_dropped_too_short + |
285 | port_stats->rx_dropped_header_too_small + | 464 | drvs->rx_dropped_header_too_small + |
286 | port_stats->rx_dropped_tcp_length + | 465 | drvs->rx_dropped_tcp_length + |
287 | port_stats->rx_dropped_runt + | 466 | drvs->rx_dropped_runt + |
288 | port_stats->rx_tcp_checksum_errs + | 467 | drvs->rx_tcp_checksum_errs + |
289 | port_stats->rx_ip_checksum_errs + | 468 | drvs->rx_ip_checksum_errs + |
290 | port_stats->rx_udp_checksum_errs; | 469 | drvs->rx_udp_checksum_errs; |
291 | 470 | ||
292 | /* detailed rx errors */ | 471 | /* detailed rx errors */ |
293 | dev_stats->rx_length_errors = port_stats->rx_in_range_errors + | 472 | dev_stats->rx_length_errors = drvs->rx_in_range_errors + |
294 | port_stats->rx_out_range_errors + | 473 | drvs->rx_out_range_errors + |
295 | port_stats->rx_frame_too_long; | 474 | drvs->rx_frame_too_long; |
296 | 475 | ||
297 | dev_stats->rx_crc_errors = port_stats->rx_crc_errors; | 476 | dev_stats->rx_crc_errors = drvs->rx_crc_errors; |
298 | 477 | ||
299 | /* frame alignment errors */ | 478 | /* frame alignment errors */ |
300 | dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors; | 479 | dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors; |
301 | 480 | ||
302 | /* receiver fifo overrun */ | 481 | /* receiver fifo overrun */ |
303 | /* drops_no_pbuf is no per i/f, it's per BE card */ | 482 | /* drops_no_pbuf is no per i/f, it's per BE card */ |
304 | dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + | 483 | dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + |
305 | port_stats->rx_input_fifo_overflow + | 484 | drvs->rx_input_fifo_overflow_drop + |
306 | rxf_stats->rx_drops_no_pbuf; | 485 | drvs->rx_drops_no_pbuf; |
307 | } | 486 | } |
308 | 487 | ||
309 | void be_link_status_update(struct be_adapter *adapter, bool link_up) | 488 | void be_link_status_update(struct be_adapter *adapter, bool link_up) |
@@ -703,7 +882,7 @@ static void be_set_multicast_list(struct net_device *netdev) | |||
703 | struct be_adapter *adapter = netdev_priv(netdev); | 882 | struct be_adapter *adapter = netdev_priv(netdev); |
704 | 883 | ||
705 | if (netdev->flags & IFF_PROMISC) { | 884 | if (netdev->flags & IFF_PROMISC) { |
706 | be_cmd_promiscuous_config(adapter, adapter->port_num, 1); | 885 | be_cmd_promiscuous_config(adapter, true); |
707 | adapter->promiscuous = true; | 886 | adapter->promiscuous = true; |
708 | goto done; | 887 | goto done; |
709 | } | 888 | } |
@@ -711,7 +890,7 @@ static void be_set_multicast_list(struct net_device *netdev) | |||
711 | /* BE was previously in promiscuous mode; disable it */ | 890 | /* BE was previously in promiscuous mode; disable it */ |
712 | if (adapter->promiscuous) { | 891 | if (adapter->promiscuous) { |
713 | adapter->promiscuous = false; | 892 | adapter->promiscuous = false; |
714 | be_cmd_promiscuous_config(adapter, adapter->port_num, 0); | 893 | be_cmd_promiscuous_config(adapter, false); |
715 | } | 894 | } |
716 | 895 | ||
717 | /* Enable multicast promisc if num configured exceeds what we support */ | 896 | /* Enable multicast promisc if num configured exceeds what we support */ |
@@ -993,9 +1172,10 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
993 | struct be_rx_obj *rxo, | 1172 | struct be_rx_obj *rxo, |
994 | struct be_rx_compl_info *rxcp) | 1173 | struct be_rx_compl_info *rxcp) |
995 | { | 1174 | { |
1175 | struct net_device *netdev = adapter->netdev; | ||
996 | struct sk_buff *skb; | 1176 | struct sk_buff *skb; |
997 | 1177 | ||
998 | skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); | 1178 | skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN); |
999 | if (unlikely(!skb)) { | 1179 | if (unlikely(!skb)) { |
1000 | if (net_ratelimit()) | 1180 | if (net_ratelimit()) |
1001 | dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); | 1181 | dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); |
@@ -1005,20 +1185,24 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
1005 | 1185 | ||
1006 | skb_fill_rx_data(adapter, rxo, skb, rxcp); | 1186 | skb_fill_rx_data(adapter, rxo, skb, rxcp); |
1007 | 1187 | ||
1008 | if (likely(adapter->rx_csum && csum_passed(rxcp))) | 1188 | if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp))) |
1009 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1189 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1010 | else | 1190 | else |
1011 | skb_checksum_none_assert(skb); | 1191 | skb_checksum_none_assert(skb); |
1012 | 1192 | ||
1013 | skb->truesize = skb->len + sizeof(struct sk_buff); | 1193 | skb->truesize = skb->len + sizeof(struct sk_buff); |
1014 | skb->protocol = eth_type_trans(skb, adapter->netdev); | 1194 | skb->protocol = eth_type_trans(skb, netdev); |
1195 | if (adapter->netdev->features & NETIF_F_RXHASH) | ||
1196 | skb->rxhash = rxcp->rss_hash; | ||
1197 | |||
1015 | 1198 | ||
1016 | if (unlikely(rxcp->vlanf)) { | 1199 | if (unlikely(rxcp->vlanf)) { |
1017 | if (!adapter->vlan_grp || adapter->vlans_added == 0) { | 1200 | if (!adapter->vlan_grp || adapter->vlans_added == 0) { |
1018 | kfree_skb(skb); | 1201 | kfree_skb(skb); |
1019 | return; | 1202 | return; |
1020 | } | 1203 | } |
1021 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, rxcp->vid); | 1204 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, |
1205 | rxcp->vlan_tag); | ||
1022 | } else { | 1206 | } else { |
1023 | netif_receive_skb(skb); | 1207 | netif_receive_skb(skb); |
1024 | } | 1208 | } |
@@ -1072,11 +1256,14 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1072 | skb->data_len = rxcp->pkt_size; | 1256 | skb->data_len = rxcp->pkt_size; |
1073 | skb->truesize += rxcp->pkt_size; | 1257 | skb->truesize += rxcp->pkt_size; |
1074 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1258 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1259 | if (adapter->netdev->features & NETIF_F_RXHASH) | ||
1260 | skb->rxhash = rxcp->rss_hash; | ||
1075 | 1261 | ||
1076 | if (likely(!rxcp->vlanf)) | 1262 | if (likely(!rxcp->vlanf)) |
1077 | napi_gro_frags(&eq_obj->napi); | 1263 | napi_gro_frags(&eq_obj->napi); |
1078 | else | 1264 | else |
1079 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, rxcp->vid); | 1265 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, |
1266 | rxcp->vlan_tag); | ||
1080 | } | 1267 | } |
1081 | 1268 | ||
1082 | static void be_parse_rx_compl_v1(struct be_adapter *adapter, | 1269 | static void be_parse_rx_compl_v1(struct be_adapter *adapter, |
@@ -1101,8 +1288,14 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter, | |||
1101 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl); | 1288 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl); |
1102 | rxcp->pkt_type = | 1289 | rxcp->pkt_type = |
1103 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); | 1290 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); |
1104 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl); | 1291 | rxcp->rss_hash = |
1105 | rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, compl); | 1292 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp); |
1293 | if (rxcp->vlanf) { | ||
1294 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, | ||
1295 | compl); | ||
1296 | rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, | ||
1297 | compl); | ||
1298 | } | ||
1106 | } | 1299 | } |
1107 | 1300 | ||
1108 | static void be_parse_rx_compl_v0(struct be_adapter *adapter, | 1301 | static void be_parse_rx_compl_v0(struct be_adapter *adapter, |
@@ -1127,8 +1320,14 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter, | |||
1127 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl); | 1320 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl); |
1128 | rxcp->pkt_type = | 1321 | rxcp->pkt_type = |
1129 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); | 1322 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); |
1130 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl); | 1323 | rxcp->rss_hash = |
1131 | rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, compl); | 1324 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp); |
1325 | if (rxcp->vlanf) { | ||
1326 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, | ||
1327 | compl); | ||
1328 | rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, | ||
1329 | compl); | ||
1330 | } | ||
1132 | } | 1331 | } |
1133 | 1332 | ||
1134 | static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) | 1333 | static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) |
@@ -1150,15 +1349,20 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) | |||
1150 | else | 1349 | else |
1151 | be_parse_rx_compl_v0(adapter, compl, rxcp); | 1350 | be_parse_rx_compl_v0(adapter, compl, rxcp); |
1152 | 1351 | ||
1153 | /* vlanf could be wrongly set in some cards. ignore if vtm is not set */ | 1352 | if (rxcp->vlanf) { |
1154 | if ((adapter->function_mode & 0x400) && !rxcp->vtm) | 1353 | /* vlanf could be wrongly set in some cards. |
1155 | rxcp->vlanf = 0; | 1354 | * ignore if vtm is not set */ |
1355 | if ((adapter->function_mode & 0x400) && !rxcp->vtm) | ||
1356 | rxcp->vlanf = 0; | ||
1156 | 1357 | ||
1157 | if (!lancer_chip(adapter)) | 1358 | if (!lancer_chip(adapter)) |
1158 | rxcp->vid = swab16(rxcp->vid); | 1359 | rxcp->vlan_tag = swab16(rxcp->vlan_tag); |
1159 | 1360 | ||
1160 | if ((adapter->pvid == rxcp->vid) && !adapter->vlan_tag[rxcp->vid]) | 1361 | if (((adapter->pvid & VLAN_VID_MASK) == |
1161 | rxcp->vlanf = 0; | 1362 | (rxcp->vlan_tag & VLAN_VID_MASK)) && |
1363 | !adapter->vlan_tag[rxcp->vlan_tag]) | ||
1364 | rxcp->vlanf = 0; | ||
1365 | } | ||
1162 | 1366 | ||
1163 | /* As the compl has been parsed, reset it; we wont touch it again */ | 1367 | /* As the compl has been parsed, reset it; we wont touch it again */ |
1164 | compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0; | 1368 | compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0; |
@@ -1255,7 +1459,7 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq) | |||
1255 | return txcp; | 1459 | return txcp; |
1256 | } | 1460 | } |
1257 | 1461 | ||
1258 | static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) | 1462 | static u16 be_tx_compl_process(struct be_adapter *adapter, u16 last_index) |
1259 | { | 1463 | { |
1260 | struct be_queue_info *txq = &adapter->tx_obj.q; | 1464 | struct be_queue_info *txq = &adapter->tx_obj.q; |
1261 | struct be_eth_wrb *wrb; | 1465 | struct be_eth_wrb *wrb; |
@@ -1282,9 +1486,8 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index) | |||
1282 | queue_tail_inc(txq); | 1486 | queue_tail_inc(txq); |
1283 | } while (cur_index != last_index); | 1487 | } while (cur_index != last_index); |
1284 | 1488 | ||
1285 | atomic_sub(num_wrbs, &txq->used); | ||
1286 | |||
1287 | kfree_skb(sent_skb); | 1489 | kfree_skb(sent_skb); |
1490 | return num_wrbs; | ||
1288 | } | 1491 | } |
1289 | 1492 | ||
1290 | static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj) | 1493 | static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj) |
@@ -1367,7 +1570,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1367 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; | 1570 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; |
1368 | struct be_queue_info *txq = &adapter->tx_obj.q; | 1571 | struct be_queue_info *txq = &adapter->tx_obj.q; |
1369 | struct be_eth_tx_compl *txcp; | 1572 | struct be_eth_tx_compl *txcp; |
1370 | u16 end_idx, cmpl = 0, timeo = 0; | 1573 | u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0; |
1371 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; | 1574 | struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list; |
1372 | struct sk_buff *sent_skb; | 1575 | struct sk_buff *sent_skb; |
1373 | bool dummy_wrb; | 1576 | bool dummy_wrb; |
@@ -1377,12 +1580,14 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1377 | while ((txcp = be_tx_compl_get(tx_cq))) { | 1580 | while ((txcp = be_tx_compl_get(tx_cq))) { |
1378 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, | 1581 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, |
1379 | wrb_index, txcp); | 1582 | wrb_index, txcp); |
1380 | be_tx_compl_process(adapter, end_idx); | 1583 | num_wrbs += be_tx_compl_process(adapter, end_idx); |
1381 | cmpl++; | 1584 | cmpl++; |
1382 | } | 1585 | } |
1383 | if (cmpl) { | 1586 | if (cmpl) { |
1384 | be_cq_notify(adapter, tx_cq->id, false, cmpl); | 1587 | be_cq_notify(adapter, tx_cq->id, false, cmpl); |
1588 | atomic_sub(num_wrbs, &txq->used); | ||
1385 | cmpl = 0; | 1589 | cmpl = 0; |
1590 | num_wrbs = 0; | ||
1386 | } | 1591 | } |
1387 | 1592 | ||
1388 | if (atomic_read(&txq->used) == 0 || ++timeo > 200) | 1593 | if (atomic_read(&txq->used) == 0 || ++timeo > 200) |
@@ -1402,7 +1607,8 @@ static void be_tx_compl_clean(struct be_adapter *adapter) | |||
1402 | index_adv(&end_idx, | 1607 | index_adv(&end_idx, |
1403 | wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, | 1608 | wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1, |
1404 | txq->len); | 1609 | txq->len); |
1405 | be_tx_compl_process(adapter, end_idx); | 1610 | num_wrbs = be_tx_compl_process(adapter, end_idx); |
1611 | atomic_sub(num_wrbs, &txq->used); | ||
1406 | } | 1612 | } |
1407 | } | 1613 | } |
1408 | 1614 | ||
@@ -1567,12 +1773,31 @@ static void be_rx_queues_destroy(struct be_adapter *adapter) | |||
1567 | } | 1773 | } |
1568 | } | 1774 | } |
1569 | 1775 | ||
1776 | static u32 be_num_rxqs_want(struct be_adapter *adapter) | ||
1777 | { | ||
1778 | if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && | ||
1779 | !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { | ||
1780 | return 1 + MAX_RSS_QS; /* one default non-RSS queue */ | ||
1781 | } else { | ||
1782 | dev_warn(&adapter->pdev->dev, | ||
1783 | "No support for multiple RX queues\n"); | ||
1784 | return 1; | ||
1785 | } | ||
1786 | } | ||
1787 | |||
1570 | static int be_rx_queues_create(struct be_adapter *adapter) | 1788 | static int be_rx_queues_create(struct be_adapter *adapter) |
1571 | { | 1789 | { |
1572 | struct be_queue_info *eq, *q, *cq; | 1790 | struct be_queue_info *eq, *q, *cq; |
1573 | struct be_rx_obj *rxo; | 1791 | struct be_rx_obj *rxo; |
1574 | int rc, i; | 1792 | int rc, i; |
1575 | 1793 | ||
1794 | adapter->num_rx_qs = min(be_num_rxqs_want(adapter), | ||
1795 | msix_enabled(adapter) ? | ||
1796 | adapter->num_msix_vec - 1 : 1); | ||
1797 | if (adapter->num_rx_qs != MAX_RX_QS) | ||
1798 | dev_warn(&adapter->pdev->dev, | ||
1799 | "Can create only %d RX queues", adapter->num_rx_qs); | ||
1800 | |||
1576 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; | 1801 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; |
1577 | for_all_rx_queues(adapter, rxo, i) { | 1802 | for_all_rx_queues(adapter, rxo, i) { |
1578 | rxo->adapter = adapter; | 1803 | rxo->adapter = adapter; |
@@ -1718,12 +1943,15 @@ static int be_poll_rx(struct napi_struct *napi, int budget) | |||
1718 | break; | 1943 | break; |
1719 | 1944 | ||
1720 | /* Ignore flush completions */ | 1945 | /* Ignore flush completions */ |
1721 | if (rxcp->num_rcvd) { | 1946 | if (rxcp->num_rcvd && rxcp->pkt_size) { |
1722 | if (do_gro(rxcp)) | 1947 | if (do_gro(rxcp)) |
1723 | be_rx_compl_process_gro(adapter, rxo, rxcp); | 1948 | be_rx_compl_process_gro(adapter, rxo, rxcp); |
1724 | else | 1949 | else |
1725 | be_rx_compl_process(adapter, rxo, rxcp); | 1950 | be_rx_compl_process(adapter, rxo, rxcp); |
1951 | } else if (rxcp->pkt_size == 0) { | ||
1952 | be_rx_compl_discard(adapter, rxo, rxcp); | ||
1726 | } | 1953 | } |
1954 | |||
1727 | be_rx_stats_update(rxo, rxcp); | 1955 | be_rx_stats_update(rxo, rxcp); |
1728 | } | 1956 | } |
1729 | 1957 | ||
@@ -1754,12 +1982,12 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1754 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; | 1982 | struct be_queue_info *tx_cq = &adapter->tx_obj.cq; |
1755 | struct be_eth_tx_compl *txcp; | 1983 | struct be_eth_tx_compl *txcp; |
1756 | int tx_compl = 0, mcc_compl, status = 0; | 1984 | int tx_compl = 0, mcc_compl, status = 0; |
1757 | u16 end_idx; | 1985 | u16 end_idx, num_wrbs = 0; |
1758 | 1986 | ||
1759 | while ((txcp = be_tx_compl_get(tx_cq))) { | 1987 | while ((txcp = be_tx_compl_get(tx_cq))) { |
1760 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, | 1988 | end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, |
1761 | wrb_index, txcp); | 1989 | wrb_index, txcp); |
1762 | be_tx_compl_process(adapter, end_idx); | 1990 | num_wrbs += be_tx_compl_process(adapter, end_idx); |
1763 | tx_compl++; | 1991 | tx_compl++; |
1764 | } | 1992 | } |
1765 | 1993 | ||
@@ -1775,6 +2003,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) | |||
1775 | if (tx_compl) { | 2003 | if (tx_compl) { |
1776 | be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); | 2004 | be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl); |
1777 | 2005 | ||
2006 | atomic_sub(num_wrbs, &txq->used); | ||
2007 | |||
1778 | /* As Tx wrbs have been freed up, wake up netdev queue if | 2008 | /* As Tx wrbs have been freed up, wake up netdev queue if |
1779 | * it was stopped due to lack of tx wrbs. | 2009 | * it was stopped due to lack of tx wrbs. |
1780 | */ | 2010 | */ |
@@ -1837,6 +2067,9 @@ static void be_worker(struct work_struct *work) | |||
1837 | struct be_rx_obj *rxo; | 2067 | struct be_rx_obj *rxo; |
1838 | int i; | 2068 | int i; |
1839 | 2069 | ||
2070 | if (!adapter->ue_detected && !lancer_chip(adapter)) | ||
2071 | be_detect_dump_ue(adapter); | ||
2072 | |||
1840 | /* when interrupts are not yet enabled, just reap any pending | 2073 | /* when interrupts are not yet enabled, just reap any pending |
1841 | * mcc completions */ | 2074 | * mcc completions */ |
1842 | if (!netif_running(adapter->netdev)) { | 2075 | if (!netif_running(adapter->netdev)) { |
@@ -1849,15 +2082,16 @@ static void be_worker(struct work_struct *work) | |||
1849 | be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl); | 2082 | be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl); |
1850 | } | 2083 | } |
1851 | 2084 | ||
1852 | if (!adapter->ue_detected && !lancer_chip(adapter)) | ||
1853 | be_detect_dump_ue(adapter); | ||
1854 | |||
1855 | goto reschedule; | 2085 | goto reschedule; |
1856 | } | 2086 | } |
1857 | 2087 | ||
1858 | if (!adapter->stats_cmd_sent) | 2088 | if (!adapter->stats_cmd_sent) { |
1859 | be_cmd_get_stats(adapter, &adapter->stats_cmd); | 2089 | if (lancer_chip(adapter)) |
1860 | 2090 | lancer_cmd_get_pport_stats(adapter, | |
2091 | &adapter->stats_cmd); | ||
2092 | else | ||
2093 | be_cmd_get_stats(adapter, &adapter->stats_cmd); | ||
2094 | } | ||
1861 | be_tx_rate_update(adapter); | 2095 | be_tx_rate_update(adapter); |
1862 | 2096 | ||
1863 | for_all_rx_queues(adapter, rxo, i) { | 2097 | for_all_rx_queues(adapter, rxo, i) { |
@@ -1869,8 +2103,6 @@ static void be_worker(struct work_struct *work) | |||
1869 | be_post_rx_frags(rxo, GFP_KERNEL); | 2103 | be_post_rx_frags(rxo, GFP_KERNEL); |
1870 | } | 2104 | } |
1871 | } | 2105 | } |
1872 | if (!adapter->ue_detected && !lancer_chip(adapter)) | ||
1873 | be_detect_dump_ue(adapter); | ||
1874 | 2106 | ||
1875 | reschedule: | 2107 | reschedule: |
1876 | adapter->work_counter++; | 2108 | adapter->work_counter++; |
@@ -1879,51 +2111,35 @@ reschedule: | |||
1879 | 2111 | ||
1880 | static void be_msix_disable(struct be_adapter *adapter) | 2112 | static void be_msix_disable(struct be_adapter *adapter) |
1881 | { | 2113 | { |
1882 | if (adapter->msix_enabled) { | 2114 | if (msix_enabled(adapter)) { |
1883 | pci_disable_msix(adapter->pdev); | 2115 | pci_disable_msix(adapter->pdev); |
1884 | adapter->msix_enabled = false; | 2116 | adapter->num_msix_vec = 0; |
1885 | } | ||
1886 | } | ||
1887 | |||
1888 | static int be_num_rxqs_get(struct be_adapter *adapter) | ||
1889 | { | ||
1890 | if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && | ||
1891 | !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { | ||
1892 | return 1 + MAX_RSS_QS; /* one default non-RSS queue */ | ||
1893 | } else { | ||
1894 | dev_warn(&adapter->pdev->dev, | ||
1895 | "No support for multiple RX queues\n"); | ||
1896 | return 1; | ||
1897 | } | 2117 | } |
1898 | } | 2118 | } |
1899 | 2119 | ||
1900 | static void be_msix_enable(struct be_adapter *adapter) | 2120 | static void be_msix_enable(struct be_adapter *adapter) |
1901 | { | 2121 | { |
1902 | #define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */ | 2122 | #define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */ |
1903 | int i, status; | 2123 | int i, status, num_vec; |
1904 | 2124 | ||
1905 | adapter->num_rx_qs = be_num_rxqs_get(adapter); | 2125 | num_vec = be_num_rxqs_want(adapter) + 1; |
1906 | 2126 | ||
1907 | for (i = 0; i < (adapter->num_rx_qs + 1); i++) | 2127 | for (i = 0; i < num_vec; i++) |
1908 | adapter->msix_entries[i].entry = i; | 2128 | adapter->msix_entries[i].entry = i; |
1909 | 2129 | ||
1910 | status = pci_enable_msix(adapter->pdev, adapter->msix_entries, | 2130 | status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec); |
1911 | adapter->num_rx_qs + 1); | ||
1912 | if (status == 0) { | 2131 | if (status == 0) { |
1913 | goto done; | 2132 | goto done; |
1914 | } else if (status >= BE_MIN_MSIX_VECTORS) { | 2133 | } else if (status >= BE_MIN_MSIX_VECTORS) { |
2134 | num_vec = status; | ||
1915 | if (pci_enable_msix(adapter->pdev, adapter->msix_entries, | 2135 | if (pci_enable_msix(adapter->pdev, adapter->msix_entries, |
1916 | status) == 0) { | 2136 | num_vec) == 0) |
1917 | adapter->num_rx_qs = status - 1; | ||
1918 | dev_warn(&adapter->pdev->dev, | ||
1919 | "Could alloc only %d MSIx vectors. " | ||
1920 | "Using %d RX Qs\n", status, adapter->num_rx_qs); | ||
1921 | goto done; | 2137 | goto done; |
1922 | } | ||
1923 | } | 2138 | } |
1924 | return; | 2139 | return; |
1925 | done: | 2140 | done: |
1926 | adapter->msix_enabled = true; | 2141 | adapter->num_msix_vec = num_vec; |
2142 | return; | ||
1927 | } | 2143 | } |
1928 | 2144 | ||
1929 | static void be_sriov_enable(struct be_adapter *adapter) | 2145 | static void be_sriov_enable(struct be_adapter *adapter) |
@@ -1931,7 +2147,20 @@ static void be_sriov_enable(struct be_adapter *adapter) | |||
1931 | be_check_sriov_fn_type(adapter); | 2147 | be_check_sriov_fn_type(adapter); |
1932 | #ifdef CONFIG_PCI_IOV | 2148 | #ifdef CONFIG_PCI_IOV |
1933 | if (be_physfn(adapter) && num_vfs) { | 2149 | if (be_physfn(adapter) && num_vfs) { |
1934 | int status; | 2150 | int status, pos; |
2151 | u16 nvfs; | ||
2152 | |||
2153 | pos = pci_find_ext_capability(adapter->pdev, | ||
2154 | PCI_EXT_CAP_ID_SRIOV); | ||
2155 | pci_read_config_word(adapter->pdev, | ||
2156 | pos + PCI_SRIOV_TOTAL_VF, &nvfs); | ||
2157 | |||
2158 | if (num_vfs > nvfs) { | ||
2159 | dev_info(&adapter->pdev->dev, | ||
2160 | "Device supports %d VFs and not %d\n", | ||
2161 | nvfs, num_vfs); | ||
2162 | num_vfs = nvfs; | ||
2163 | } | ||
1935 | 2164 | ||
1936 | status = pci_enable_sriov(adapter->pdev, num_vfs); | 2165 | status = pci_enable_sriov(adapter->pdev, num_vfs); |
1937 | adapter->sriov_enabled = status ? false : true; | 2166 | adapter->sriov_enabled = status ? false : true; |
@@ -2004,8 +2233,7 @@ err_msix: | |||
2004 | err: | 2233 | err: |
2005 | dev_warn(&adapter->pdev->dev, | 2234 | dev_warn(&adapter->pdev->dev, |
2006 | "MSIX Request IRQ failed - err %d\n", status); | 2235 | "MSIX Request IRQ failed - err %d\n", status); |
2007 | pci_disable_msix(adapter->pdev); | 2236 | be_msix_disable(adapter); |
2008 | adapter->msix_enabled = false; | ||
2009 | return status; | 2237 | return status; |
2010 | } | 2238 | } |
2011 | 2239 | ||
@@ -2014,7 +2242,7 @@ static int be_irq_register(struct be_adapter *adapter) | |||
2014 | struct net_device *netdev = adapter->netdev; | 2242 | struct net_device *netdev = adapter->netdev; |
2015 | int status; | 2243 | int status; |
2016 | 2244 | ||
2017 | if (adapter->msix_enabled) { | 2245 | if (msix_enabled(adapter)) { |
2018 | status = be_msix_register(adapter); | 2246 | status = be_msix_register(adapter); |
2019 | if (status == 0) | 2247 | if (status == 0) |
2020 | goto done; | 2248 | goto done; |
@@ -2047,7 +2275,7 @@ static void be_irq_unregister(struct be_adapter *adapter) | |||
2047 | return; | 2275 | return; |
2048 | 2276 | ||
2049 | /* INTx */ | 2277 | /* INTx */ |
2050 | if (!adapter->msix_enabled) { | 2278 | if (!msix_enabled(adapter)) { |
2051 | free_irq(netdev->irq, adapter); | 2279 | free_irq(netdev->irq, adapter); |
2052 | goto done; | 2280 | goto done; |
2053 | } | 2281 | } |
@@ -2089,7 +2317,7 @@ static int be_close(struct net_device *netdev) | |||
2089 | be_cq_notify(adapter, rxo->cq.id, false, 0); | 2317 | be_cq_notify(adapter, rxo->cq.id, false, 0); |
2090 | } | 2318 | } |
2091 | 2319 | ||
2092 | if (adapter->msix_enabled) { | 2320 | if (msix_enabled(adapter)) { |
2093 | vec = be_msix_vec_get(adapter, tx_eq); | 2321 | vec = be_msix_vec_get(adapter, tx_eq); |
2094 | synchronize_irq(vec); | 2322 | synchronize_irq(vec); |
2095 | 2323 | ||
@@ -2142,7 +2370,7 @@ static int be_open(struct net_device *netdev) | |||
2142 | be_async_mcc_enable(adapter); | 2370 | be_async_mcc_enable(adapter); |
2143 | 2371 | ||
2144 | status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, | 2372 | status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, |
2145 | &link_speed); | 2373 | &link_speed, 0); |
2146 | if (status) | 2374 | if (status) |
2147 | goto err; | 2375 | goto err; |
2148 | be_link_status_update(adapter, link_up); | 2376 | be_link_status_update(adapter, link_up); |
@@ -2262,7 +2490,7 @@ static int be_setup(struct be_adapter *adapter) | |||
2262 | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 2490 | BE_IF_FLAGS_PASS_L3L4_ERRORS; |
2263 | en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; | 2491 | en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; |
2264 | 2492 | ||
2265 | if (be_multi_rxq(adapter)) { | 2493 | if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) { |
2266 | cap_flags |= BE_IF_FLAGS_RSS; | 2494 | cap_flags |= BE_IF_FLAGS_RSS; |
2267 | en_flags |= BE_IF_FLAGS_RSS; | 2495 | en_flags |= BE_IF_FLAGS_RSS; |
2268 | } | 2496 | } |
@@ -2319,7 +2547,6 @@ static int be_setup(struct be_adapter *adapter) | |||
2319 | 2547 | ||
2320 | return 0; | 2548 | return 0; |
2321 | 2549 | ||
2322 | be_mcc_queues_destroy(adapter); | ||
2323 | rx_qs_destroy: | 2550 | rx_qs_destroy: |
2324 | be_rx_queues_destroy(adapter); | 2551 | be_rx_queues_destroy(adapter); |
2325 | tx_qs_destroy: | 2552 | tx_qs_destroy: |
@@ -2487,7 +2714,6 @@ static int be_flash_data(struct be_adapter *adapter, | |||
2487 | "cmd to write to flash rom failed.\n"); | 2714 | "cmd to write to flash rom failed.\n"); |
2488 | return -1; | 2715 | return -1; |
2489 | } | 2716 | } |
2490 | yield(); | ||
2491 | } | 2717 | } |
2492 | } | 2718 | } |
2493 | return 0; | 2719 | return 0; |
@@ -2505,32 +2731,96 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr) | |||
2505 | return 0; | 2731 | return 0; |
2506 | } | 2732 | } |
2507 | 2733 | ||
2508 | int be_load_fw(struct be_adapter *adapter, u8 *func) | 2734 | static int lancer_fw_download(struct be_adapter *adapter, |
2735 | const struct firmware *fw) | ||
2509 | { | 2736 | { |
2510 | char fw_file[ETHTOOL_FLASH_MAX_FILENAME]; | 2737 | #define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024) |
2511 | const struct firmware *fw; | 2738 | #define LANCER_FW_DOWNLOAD_LOCATION "/prg" |
2512 | struct flash_file_hdr_g2 *fhdr; | ||
2513 | struct flash_file_hdr_g3 *fhdr3; | ||
2514 | struct image_hdr *img_hdr_ptr = NULL; | ||
2515 | struct be_dma_mem flash_cmd; | 2739 | struct be_dma_mem flash_cmd; |
2516 | int status, i = 0, num_imgs = 0; | 2740 | const u8 *data_ptr = NULL; |
2517 | const u8 *p; | 2741 | u8 *dest_image_ptr = NULL; |
2742 | size_t image_size = 0; | ||
2743 | u32 chunk_size = 0; | ||
2744 | u32 data_written = 0; | ||
2745 | u32 offset = 0; | ||
2746 | int status = 0; | ||
2747 | u8 add_status = 0; | ||
2518 | 2748 | ||
2519 | if (!netif_running(adapter->netdev)) { | 2749 | if (!IS_ALIGNED(fw->size, sizeof(u32))) { |
2520 | dev_err(&adapter->pdev->dev, | 2750 | dev_err(&adapter->pdev->dev, |
2521 | "Firmware load not allowed (interface is down)\n"); | 2751 | "FW Image not properly aligned. " |
2522 | return -EPERM; | 2752 | "Length must be 4 byte aligned.\n"); |
2753 | status = -EINVAL; | ||
2754 | goto lancer_fw_exit; | ||
2755 | } | ||
2756 | |||
2757 | flash_cmd.size = sizeof(struct lancer_cmd_req_write_object) | ||
2758 | + LANCER_FW_DOWNLOAD_CHUNK; | ||
2759 | flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, | ||
2760 | &flash_cmd.dma, GFP_KERNEL); | ||
2761 | if (!flash_cmd.va) { | ||
2762 | status = -ENOMEM; | ||
2763 | dev_err(&adapter->pdev->dev, | ||
2764 | "Memory allocation failure while flashing\n"); | ||
2765 | goto lancer_fw_exit; | ||
2523 | } | 2766 | } |
2524 | 2767 | ||
2525 | strcpy(fw_file, func); | 2768 | dest_image_ptr = flash_cmd.va + |
2769 | sizeof(struct lancer_cmd_req_write_object); | ||
2770 | image_size = fw->size; | ||
2771 | data_ptr = fw->data; | ||
2526 | 2772 | ||
2527 | status = request_firmware(&fw, fw_file, &adapter->pdev->dev); | 2773 | while (image_size) { |
2528 | if (status) | 2774 | chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK); |
2529 | goto fw_exit; | 2775 | |
2776 | /* Copy the image chunk content. */ | ||
2777 | memcpy(dest_image_ptr, data_ptr, chunk_size); | ||
2778 | |||
2779 | status = lancer_cmd_write_object(adapter, &flash_cmd, | ||
2780 | chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION, | ||
2781 | &data_written, &add_status); | ||
2782 | |||
2783 | if (status) | ||
2784 | break; | ||
2785 | |||
2786 | offset += data_written; | ||
2787 | data_ptr += data_written; | ||
2788 | image_size -= data_written; | ||
2789 | } | ||
2790 | |||
2791 | if (!status) { | ||
2792 | /* Commit the FW written */ | ||
2793 | status = lancer_cmd_write_object(adapter, &flash_cmd, | ||
2794 | 0, offset, LANCER_FW_DOWNLOAD_LOCATION, | ||
2795 | &data_written, &add_status); | ||
2796 | } | ||
2797 | |||
2798 | dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va, | ||
2799 | flash_cmd.dma); | ||
2800 | if (status) { | ||
2801 | dev_err(&adapter->pdev->dev, | ||
2802 | "Firmware load error. " | ||
2803 | "Status code: 0x%x Additional Status: 0x%x\n", | ||
2804 | status, add_status); | ||
2805 | goto lancer_fw_exit; | ||
2806 | } | ||
2807 | |||
2808 | dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); | ||
2809 | lancer_fw_exit: | ||
2810 | return status; | ||
2811 | } | ||
2812 | |||
2813 | static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw) | ||
2814 | { | ||
2815 | struct flash_file_hdr_g2 *fhdr; | ||
2816 | struct flash_file_hdr_g3 *fhdr3; | ||
2817 | struct image_hdr *img_hdr_ptr = NULL; | ||
2818 | struct be_dma_mem flash_cmd; | ||
2819 | const u8 *p; | ||
2820 | int status = 0, i = 0, num_imgs = 0; | ||
2530 | 2821 | ||
2531 | p = fw->data; | 2822 | p = fw->data; |
2532 | fhdr = (struct flash_file_hdr_g2 *) p; | 2823 | fhdr = (struct flash_file_hdr_g2 *) p; |
2533 | dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); | ||
2534 | 2824 | ||
2535 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; | 2825 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; |
2536 | flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, | 2826 | flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, |
@@ -2539,7 +2829,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
2539 | status = -ENOMEM; | 2829 | status = -ENOMEM; |
2540 | dev_err(&adapter->pdev->dev, | 2830 | dev_err(&adapter->pdev->dev, |
2541 | "Memory allocation failure while flashing\n"); | 2831 | "Memory allocation failure while flashing\n"); |
2542 | goto fw_exit; | 2832 | goto be_fw_exit; |
2543 | } | 2833 | } |
2544 | 2834 | ||
2545 | if ((adapter->generation == BE_GEN3) && | 2835 | if ((adapter->generation == BE_GEN3) && |
@@ -2567,11 +2857,37 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
2567 | flash_cmd.dma); | 2857 | flash_cmd.dma); |
2568 | if (status) { | 2858 | if (status) { |
2569 | dev_err(&adapter->pdev->dev, "Firmware load error\n"); | 2859 | dev_err(&adapter->pdev->dev, "Firmware load error\n"); |
2570 | goto fw_exit; | 2860 | goto be_fw_exit; |
2571 | } | 2861 | } |
2572 | 2862 | ||
2573 | dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); | 2863 | dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); |
2574 | 2864 | ||
2865 | be_fw_exit: | ||
2866 | return status; | ||
2867 | } | ||
2868 | |||
2869 | int be_load_fw(struct be_adapter *adapter, u8 *fw_file) | ||
2870 | { | ||
2871 | const struct firmware *fw; | ||
2872 | int status; | ||
2873 | |||
2874 | if (!netif_running(adapter->netdev)) { | ||
2875 | dev_err(&adapter->pdev->dev, | ||
2876 | "Firmware load not allowed (interface is down)\n"); | ||
2877 | return -1; | ||
2878 | } | ||
2879 | |||
2880 | status = request_firmware(&fw, fw_file, &adapter->pdev->dev); | ||
2881 | if (status) | ||
2882 | goto fw_exit; | ||
2883 | |||
2884 | dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); | ||
2885 | |||
2886 | if (lancer_chip(adapter)) | ||
2887 | status = lancer_fw_download(adapter, fw); | ||
2888 | else | ||
2889 | status = be_fw_download(adapter, fw); | ||
2890 | |||
2575 | fw_exit: | 2891 | fw_exit: |
2576 | release_firmware(fw); | 2892 | release_firmware(fw); |
2577 | return status; | 2893 | return status; |
@@ -2600,10 +2916,14 @@ static void be_netdev_init(struct net_device *netdev) | |||
2600 | struct be_rx_obj *rxo; | 2916 | struct be_rx_obj *rxo; |
2601 | int i; | 2917 | int i; |
2602 | 2918 | ||
2603 | netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | | 2919 | netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | |
2604 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | | 2920 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | |
2605 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 2921 | NETIF_F_HW_VLAN_TX; |
2606 | NETIF_F_GRO | NETIF_F_TSO6; | 2922 | if (be_multi_rxq(adapter)) |
2923 | netdev->hw_features |= NETIF_F_RXHASH; | ||
2924 | |||
2925 | netdev->features |= netdev->hw_features | | ||
2926 | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; | ||
2607 | 2927 | ||
2608 | netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | | 2928 | netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | |
2609 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | 2929 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
@@ -2613,8 +2933,6 @@ static void be_netdev_init(struct net_device *netdev) | |||
2613 | 2933 | ||
2614 | netdev->flags |= IFF_MULTICAST; | 2934 | netdev->flags |= IFF_MULTICAST; |
2615 | 2935 | ||
2616 | adapter->rx_csum = true; | ||
2617 | |||
2618 | /* Default settings for Rx and Tx flow control */ | 2936 | /* Default settings for Rx and Tx flow control */ |
2619 | adapter->rx_fc = true; | 2937 | adapter->rx_fc = true; |
2620 | adapter->tx_fc = true; | 2938 | adapter->tx_fc = true; |
@@ -2782,7 +3100,14 @@ static int be_stats_init(struct be_adapter *adapter) | |||
2782 | { | 3100 | { |
2783 | struct be_dma_mem *cmd = &adapter->stats_cmd; | 3101 | struct be_dma_mem *cmd = &adapter->stats_cmd; |
2784 | 3102 | ||
2785 | cmd->size = sizeof(struct be_cmd_req_get_stats); | 3103 | if (adapter->generation == BE_GEN2) { |
3104 | cmd->size = sizeof(struct be_cmd_req_get_stats_v0); | ||
3105 | } else { | ||
3106 | if (lancer_chip(adapter)) | ||
3107 | cmd->size = sizeof(struct lancer_cmd_req_pport_stats); | ||
3108 | else | ||
3109 | cmd->size = sizeof(struct be_cmd_req_get_stats_v1); | ||
3110 | } | ||
2786 | cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, | 3111 | cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma, |
2787 | GFP_KERNEL); | 3112 | GFP_KERNEL); |
2788 | if (cmd->va == NULL) | 3113 | if (cmd->va == NULL) |
@@ -2808,6 +3133,7 @@ static void __devexit be_remove(struct pci_dev *pdev) | |||
2808 | 3133 | ||
2809 | be_ctrl_cleanup(adapter); | 3134 | be_ctrl_cleanup(adapter); |
2810 | 3135 | ||
3136 | kfree(adapter->vf_cfg); | ||
2811 | be_sriov_disable(adapter); | 3137 | be_sriov_disable(adapter); |
2812 | 3138 | ||
2813 | be_msix_disable(adapter); | 3139 | be_msix_disable(adapter); |
@@ -2835,7 +3161,8 @@ static int be_get_config(struct be_adapter *adapter) | |||
2835 | 3161 | ||
2836 | memset(mac, 0, ETH_ALEN); | 3162 | memset(mac, 0, ETH_ALEN); |
2837 | 3163 | ||
2838 | if (be_physfn(adapter)) { | 3164 | /* A default permanent address is given to each VF for Lancer*/ |
3165 | if (be_physfn(adapter) || lancer_chip(adapter)) { | ||
2839 | status = be_cmd_mac_addr_query(adapter, mac, | 3166 | status = be_cmd_mac_addr_query(adapter, mac, |
2840 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); | 3167 | MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0); |
2841 | 3168 | ||
@@ -2877,6 +3204,7 @@ static int be_dev_family_check(struct be_adapter *adapter) | |||
2877 | adapter->generation = BE_GEN3; | 3204 | adapter->generation = BE_GEN3; |
2878 | break; | 3205 | break; |
2879 | case OC_DEVICE_ID3: | 3206 | case OC_DEVICE_ID3: |
3207 | case OC_DEVICE_ID4: | ||
2880 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); | 3208 | pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf); |
2881 | if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> | 3209 | if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> |
2882 | SLI_INTF_IF_TYPE_SHIFT; | 3210 | SLI_INTF_IF_TYPE_SHIFT; |
@@ -2886,10 +3214,6 @@ static int be_dev_family_check(struct be_adapter *adapter) | |||
2886 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); | 3214 | dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n"); |
2887 | return -EINVAL; | 3215 | return -EINVAL; |
2888 | } | 3216 | } |
2889 | if (num_vfs > 0) { | ||
2890 | dev_err(&pdev->dev, "VFs not supported\n"); | ||
2891 | return -EINVAL; | ||
2892 | } | ||
2893 | adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> | 3217 | adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >> |
2894 | SLI_INTF_FAMILY_SHIFT); | 3218 | SLI_INTF_FAMILY_SHIFT); |
2895 | adapter->generation = BE_GEN3; | 3219 | adapter->generation = BE_GEN3; |
@@ -2992,16 +3316,23 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
2992 | } | 3316 | } |
2993 | 3317 | ||
2994 | be_sriov_enable(adapter); | 3318 | be_sriov_enable(adapter); |
3319 | if (adapter->sriov_enabled) { | ||
3320 | adapter->vf_cfg = kcalloc(num_vfs, | ||
3321 | sizeof(struct be_vf_cfg), GFP_KERNEL); | ||
3322 | |||
3323 | if (!adapter->vf_cfg) | ||
3324 | goto free_netdev; | ||
3325 | } | ||
2995 | 3326 | ||
2996 | status = be_ctrl_init(adapter); | 3327 | status = be_ctrl_init(adapter); |
2997 | if (status) | 3328 | if (status) |
2998 | goto free_netdev; | 3329 | goto free_vf_cfg; |
2999 | 3330 | ||
3000 | if (lancer_chip(adapter)) { | 3331 | if (lancer_chip(adapter)) { |
3001 | status = lancer_test_and_set_rdy_state(adapter); | 3332 | status = lancer_test_and_set_rdy_state(adapter); |
3002 | if (status) { | 3333 | if (status) { |
3003 | dev_err(&pdev->dev, "Adapter in non recoverable error\n"); | 3334 | dev_err(&pdev->dev, "Adapter in non recoverable error\n"); |
3004 | goto free_netdev; | 3335 | goto ctrl_clean; |
3005 | } | 3336 | } |
3006 | } | 3337 | } |
3007 | 3338 | ||
@@ -3044,9 +3375,24 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
3044 | netif_carrier_off(netdev); | 3375 | netif_carrier_off(netdev); |
3045 | 3376 | ||
3046 | if (be_physfn(adapter) && adapter->sriov_enabled) { | 3377 | if (be_physfn(adapter) && adapter->sriov_enabled) { |
3047 | status = be_vf_eth_addr_config(adapter); | 3378 | u8 mac_speed; |
3048 | if (status) | 3379 | bool link_up; |
3049 | goto unreg_netdev; | 3380 | u16 vf, lnk_speed; |
3381 | |||
3382 | if (!lancer_chip(adapter)) { | ||
3383 | status = be_vf_eth_addr_config(adapter); | ||
3384 | if (status) | ||
3385 | goto unreg_netdev; | ||
3386 | } | ||
3387 | |||
3388 | for (vf = 0; vf < num_vfs; vf++) { | ||
3389 | status = be_cmd_link_status_query(adapter, &link_up, | ||
3390 | &mac_speed, &lnk_speed, vf + 1); | ||
3391 | if (!status) | ||
3392 | adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10; | ||
3393 | else | ||
3394 | goto unreg_netdev; | ||
3395 | } | ||
3050 | } | 3396 | } |
3051 | 3397 | ||
3052 | dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); | 3398 | dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); |
@@ -3063,6 +3409,8 @@ stats_clean: | |||
3063 | be_stats_cleanup(adapter); | 3409 | be_stats_cleanup(adapter); |
3064 | ctrl_clean: | 3410 | ctrl_clean: |
3065 | be_ctrl_cleanup(adapter); | 3411 | be_ctrl_cleanup(adapter); |
3412 | free_vf_cfg: | ||
3413 | kfree(adapter->vf_cfg); | ||
3066 | free_netdev: | 3414 | free_netdev: |
3067 | be_sriov_disable(adapter); | 3415 | be_sriov_disable(adapter); |
3068 | free_netdev(netdev); | 3416 | free_netdev(netdev); |
@@ -3147,16 +3495,15 @@ static void be_shutdown(struct pci_dev *pdev) | |||
3147 | if (!adapter) | 3495 | if (!adapter) |
3148 | return; | 3496 | return; |
3149 | 3497 | ||
3150 | if (netif_running(adapter->netdev)) | 3498 | cancel_delayed_work_sync(&adapter->work); |
3151 | cancel_delayed_work_sync(&adapter->work); | ||
3152 | 3499 | ||
3153 | netif_device_detach(adapter->netdev); | 3500 | netif_device_detach(adapter->netdev); |
3154 | 3501 | ||
3155 | be_cmd_reset_function(adapter); | ||
3156 | |||
3157 | if (adapter->wol) | 3502 | if (adapter->wol) |
3158 | be_setup_wol(adapter, true); | 3503 | be_setup_wol(adapter, true); |
3159 | 3504 | ||
3505 | be_cmd_reset_function(adapter); | ||
3506 | |||
3160 | pci_disable_device(pdev); | 3507 | pci_disable_device(pdev); |
3161 | } | 3508 | } |
3162 | 3509 | ||
@@ -3268,13 +3615,6 @@ static int __init be_init_module(void) | |||
3268 | rx_frag_size = 2048; | 3615 | rx_frag_size = 2048; |
3269 | } | 3616 | } |
3270 | 3617 | ||
3271 | if (num_vfs > 32) { | ||
3272 | printk(KERN_WARNING DRV_NAME | ||
3273 | " : Module param num_vfs must not be greater than 32." | ||
3274 | "Using 32\n"); | ||
3275 | num_vfs = 32; | ||
3276 | } | ||
3277 | |||
3278 | return pci_register_driver(&be_driver); | 3618 | return pci_register_driver(&be_driver); |
3279 | } | 3619 | } |
3280 | module_init(be_init_module); | 3620 | module_init(be_init_module); |