.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
---|
2 | | -/* Copyright(c) 2013 - 2018 Intel Corporation. */ |
---|
| 2 | +/* Copyright(c) 2013 - 2019 Intel Corporation. */ |
---|
3 | 3 | |
---|
4 | 4 | #include "fm10k.h" |
---|
5 | 5 | #include <linux/vmalloc.h> |
---|
.. | .. |
---|
54 | 54 | **/ |
---|
55 | 55 | static int fm10k_setup_all_tx_resources(struct fm10k_intfc *interface) |
---|
56 | 56 | { |
---|
57 | | - int i, err = 0; |
---|
| 57 | + int i, err; |
---|
58 | 58 | |
---|
59 | 59 | for (i = 0; i < interface->num_tx_queues; i++) { |
---|
60 | 60 | err = fm10k_setup_tx_resources(interface->tx_ring[i]); |
---|
.. | .. |
---|
121 | 121 | **/ |
---|
122 | 122 | static int fm10k_setup_all_rx_resources(struct fm10k_intfc *interface) |
---|
123 | 123 | { |
---|
124 | | - int i, err = 0; |
---|
| 124 | + int i, err; |
---|
125 | 125 | |
---|
126 | 126 | for (i = 0; i < interface->num_rx_queues; i++) { |
---|
127 | 127 | err = fm10k_setup_rx_resources(interface->rx_ring[i]); |
---|
.. | .. |
---|
169 | 169 | **/ |
---|
170 | 170 | static void fm10k_clean_tx_ring(struct fm10k_ring *tx_ring) |
---|
171 | 171 | { |
---|
172 | | - struct fm10k_tx_buffer *tx_buffer; |
---|
173 | 172 | unsigned long size; |
---|
174 | 173 | u16 i; |
---|
175 | 174 | |
---|
.. | .. |
---|
179 | 178 | |
---|
180 | 179 | /* Free all the Tx ring sk_buffs */ |
---|
181 | 180 | for (i = 0; i < tx_ring->count; i++) { |
---|
182 | | - tx_buffer = &tx_ring->tx_buffer[i]; |
---|
| 181 | + struct fm10k_tx_buffer *tx_buffer = &tx_ring->tx_buffer[i]; |
---|
| 182 | + |
---|
183 | 183 | fm10k_unmap_and_free_tx_resource(tx_ring, tx_buffer); |
---|
184 | 184 | } |
---|
185 | 185 | |
---|
.. | .. |
---|
253 | 253 | if (!rx_ring->rx_buffer) |
---|
254 | 254 | return; |
---|
255 | 255 | |
---|
256 | | - if (rx_ring->skb) |
---|
257 | | - dev_kfree_skb(rx_ring->skb); |
---|
| 256 | + dev_kfree_skb(rx_ring->skb); |
---|
258 | 257 | rx_ring->skb = NULL; |
---|
259 | 258 | |
---|
260 | 259 | /* Free all the Rx ring sk_buffs */ |
---|
.. | .. |
---|
368 | 367 | } |
---|
369 | 368 | |
---|
370 | 369 | /** |
---|
371 | | - * fm10k_free_udp_port_info |
---|
372 | | - * @interface: board private structure |
---|
373 | | - * |
---|
374 | | - * This function frees both geneve_port and vxlan_port structures |
---|
375 | | - **/ |
---|
376 | | -static void fm10k_free_udp_port_info(struct fm10k_intfc *interface) |
---|
377 | | -{ |
---|
378 | | - struct fm10k_udp_port *port; |
---|
379 | | - |
---|
380 | | - /* flush all entries from vxlan list */ |
---|
381 | | - port = list_first_entry_or_null(&interface->vxlan_port, |
---|
382 | | - struct fm10k_udp_port, list); |
---|
383 | | - while (port) { |
---|
384 | | - list_del(&port->list); |
---|
385 | | - kfree(port); |
---|
386 | | - port = list_first_entry_or_null(&interface->vxlan_port, |
---|
387 | | - struct fm10k_udp_port, |
---|
388 | | - list); |
---|
389 | | - } |
---|
390 | | - |
---|
391 | | - /* flush all entries from geneve list */ |
---|
392 | | - port = list_first_entry_or_null(&interface->geneve_port, |
---|
393 | | - struct fm10k_udp_port, list); |
---|
394 | | - while (port) { |
---|
395 | | - list_del(&port->list); |
---|
396 | | - kfree(port); |
---|
397 | | - port = list_first_entry_or_null(&interface->vxlan_port, |
---|
398 | | - struct fm10k_udp_port, |
---|
399 | | - list); |
---|
400 | | - } |
---|
401 | | -} |
---|
402 | | - |
---|
403 | | -/** |
---|
404 | 370 | * fm10k_restore_udp_port_info |
---|
405 | 371 | * @interface: board private structure |
---|
406 | 372 | * |
---|
.. | .. |
---|
409 | 375 | static void fm10k_restore_udp_port_info(struct fm10k_intfc *interface) |
---|
410 | 376 | { |
---|
411 | 377 | struct fm10k_hw *hw = &interface->hw; |
---|
412 | | - struct fm10k_udp_port *port; |
---|
413 | 378 | |
---|
414 | 379 | /* only the PF supports configuring tunnels */ |
---|
415 | 380 | if (hw->mac.type != fm10k_mac_pf) |
---|
416 | 381 | return; |
---|
417 | 382 | |
---|
418 | | - port = list_first_entry_or_null(&interface->vxlan_port, |
---|
419 | | - struct fm10k_udp_port, list); |
---|
420 | | - |
---|
421 | 383 | /* restore tunnel configuration register */ |
---|
422 | 384 | fm10k_write_reg(hw, FM10K_TUNNEL_CFG, |
---|
423 | | - (port ? ntohs(port->port) : 0) | |
---|
| 385 | + ntohs(interface->vxlan_port) | |
---|
424 | 386 | (ETH_P_TEB << FM10K_TUNNEL_CFG_NVGRE_SHIFT)); |
---|
425 | | - |
---|
426 | | - port = list_first_entry_or_null(&interface->geneve_port, |
---|
427 | | - struct fm10k_udp_port, list); |
---|
428 | 387 | |
---|
429 | 388 | /* restore Geneve tunnel configuration register */ |
---|
430 | 389 | fm10k_write_reg(hw, FM10K_TUNNEL_CFG_GENEVE, |
---|
431 | | - (port ? ntohs(port->port) : 0)); |
---|
432 | | -} |
---|
433 | | - |
---|
434 | | -static struct fm10k_udp_port * |
---|
435 | | -fm10k_remove_tunnel_port(struct list_head *ports, |
---|
436 | | - struct udp_tunnel_info *ti) |
---|
437 | | -{ |
---|
438 | | - struct fm10k_udp_port *port; |
---|
439 | | - |
---|
440 | | - list_for_each_entry(port, ports, list) { |
---|
441 | | - if ((port->port == ti->port) && |
---|
442 | | - (port->sa_family == ti->sa_family)) { |
---|
443 | | - list_del(&port->list); |
---|
444 | | - return port; |
---|
445 | | - } |
---|
446 | | - } |
---|
447 | | - |
---|
448 | | - return NULL; |
---|
449 | | -} |
---|
450 | | - |
---|
451 | | -static void fm10k_insert_tunnel_port(struct list_head *ports, |
---|
452 | | - struct udp_tunnel_info *ti) |
---|
453 | | -{ |
---|
454 | | - struct fm10k_udp_port *port; |
---|
455 | | - |
---|
456 | | - /* remove existing port entry from the list so that the newest items |
---|
457 | | - * are always at the tail of the list. |
---|
458 | | - */ |
---|
459 | | - port = fm10k_remove_tunnel_port(ports, ti); |
---|
460 | | - if (!port) { |
---|
461 | | - port = kmalloc(sizeof(*port), GFP_ATOMIC); |
---|
462 | | - if (!port) |
---|
463 | | - return; |
---|
464 | | - port->port = ti->port; |
---|
465 | | - port->sa_family = ti->sa_family; |
---|
466 | | - } |
---|
467 | | - |
---|
468 | | - list_add_tail(&port->list, ports); |
---|
| 390 | + ntohs(interface->geneve_port)); |
---|
469 | 391 | } |
---|
470 | 392 | |
---|
471 | 393 | /** |
---|
472 | | - * fm10k_udp_tunnel_add |
---|
| 394 | + * fm10k_udp_tunnel_sync - Called when UDP tunnel ports change |
---|
473 | 395 | * @dev: network interface device structure |
---|
474 | | - * @ti: Tunnel endpoint information |
---|
| 396 | + * @table: Tunnel table (according to tables of @fm10k_udp_tunnels) |
---|
475 | 397 | * |
---|
476 | | - * This function is called when a new UDP tunnel port has been added. |
---|
| 398 | + * This function is called when a new UDP tunnel port is added or deleted. |
---|
477 | 399 | * Due to hardware restrictions, only one port per type can be offloaded at |
---|
478 | | - * once. |
---|
| 400 | + * once. Core will send to the driver a port of its choice. |
---|
479 | 401 | **/ |
---|
480 | | -static void fm10k_udp_tunnel_add(struct net_device *dev, |
---|
481 | | - struct udp_tunnel_info *ti) |
---|
| 402 | +static int fm10k_udp_tunnel_sync(struct net_device *dev, unsigned int table) |
---|
482 | 403 | { |
---|
483 | 404 | struct fm10k_intfc *interface = netdev_priv(dev); |
---|
| 405 | + struct udp_tunnel_info ti; |
---|
484 | 406 | |
---|
485 | | - /* only the PF supports configuring tunnels */ |
---|
486 | | - if (interface->hw.mac.type != fm10k_mac_pf) |
---|
487 | | - return; |
---|
488 | | - |
---|
489 | | - switch (ti->type) { |
---|
490 | | - case UDP_TUNNEL_TYPE_VXLAN: |
---|
491 | | - fm10k_insert_tunnel_port(&interface->vxlan_port, ti); |
---|
492 | | - break; |
---|
493 | | - case UDP_TUNNEL_TYPE_GENEVE: |
---|
494 | | - fm10k_insert_tunnel_port(&interface->geneve_port, ti); |
---|
495 | | - break; |
---|
496 | | - default: |
---|
497 | | - return; |
---|
498 | | - } |
---|
| 407 | + udp_tunnel_nic_get_port(dev, table, 0, &ti); |
---|
| 408 | + if (!table) |
---|
| 409 | + interface->vxlan_port = ti.port; |
---|
| 410 | + else |
---|
| 411 | + interface->geneve_port = ti.port; |
---|
499 | 412 | |
---|
500 | 413 | fm10k_restore_udp_port_info(interface); |
---|
| 414 | + return 0; |
---|
501 | 415 | } |
---|
502 | 416 | |
---|
503 | | -/** |
---|
504 | | - * fm10k_udp_tunnel_del |
---|
505 | | - * @dev: network interface device structure |
---|
506 | | - * @ti: Tunnel end point information |
---|
507 | | - * |
---|
508 | | - * This function is called when a new UDP tunnel port is deleted. The freed |
---|
509 | | - * port will be removed from the list, then we reprogram the offloaded port |
---|
510 | | - * based on the head of the list. |
---|
511 | | - **/ |
---|
512 | | -static void fm10k_udp_tunnel_del(struct net_device *dev, |
---|
513 | | - struct udp_tunnel_info *ti) |
---|
514 | | -{ |
---|
515 | | - struct fm10k_intfc *interface = netdev_priv(dev); |
---|
516 | | - struct fm10k_udp_port *port = NULL; |
---|
517 | | - |
---|
518 | | - if (interface->hw.mac.type != fm10k_mac_pf) |
---|
519 | | - return; |
---|
520 | | - |
---|
521 | | - switch (ti->type) { |
---|
522 | | - case UDP_TUNNEL_TYPE_VXLAN: |
---|
523 | | - port = fm10k_remove_tunnel_port(&interface->vxlan_port, ti); |
---|
524 | | - break; |
---|
525 | | - case UDP_TUNNEL_TYPE_GENEVE: |
---|
526 | | - port = fm10k_remove_tunnel_port(&interface->geneve_port, ti); |
---|
527 | | - break; |
---|
528 | | - default: |
---|
529 | | - return; |
---|
530 | | - } |
---|
531 | | - |
---|
532 | | - /* if we did remove a port we need to free its memory */ |
---|
533 | | - kfree(port); |
---|
534 | | - |
---|
535 | | - fm10k_restore_udp_port_info(interface); |
---|
536 | | -} |
---|
| 417 | +static const struct udp_tunnel_nic_info fm10k_udp_tunnels = { |
---|
| 418 | + .sync_table = fm10k_udp_tunnel_sync, |
---|
| 419 | + .tables = { |
---|
| 420 | + { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, |
---|
| 421 | + { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_GENEVE, }, |
---|
| 422 | + }, |
---|
| 423 | +}; |
---|
537 | 424 | |
---|
538 | 425 | /** |
---|
539 | 426 | * fm10k_open - Called when a network interface is made active |
---|
.. | .. |
---|
581 | 468 | if (err) |
---|
582 | 469 | goto err_set_queues; |
---|
583 | 470 | |
---|
584 | | - udp_tunnel_get_rx_info(netdev); |
---|
585 | | - |
---|
586 | 471 | fm10k_up(interface); |
---|
587 | 472 | |
---|
588 | 473 | return 0; |
---|
.. | .. |
---|
615 | 500 | fm10k_down(interface); |
---|
616 | 501 | |
---|
617 | 502 | fm10k_qv_free_irq(interface); |
---|
618 | | - |
---|
619 | | - fm10k_free_udp_port_info(interface); |
---|
620 | 503 | |
---|
621 | 504 | fm10k_free_all_tx_resources(interface); |
---|
622 | 505 | fm10k_free_all_rx_resources(interface); |
---|
.. | .. |
---|
697 | 580 | /** |
---|
698 | 581 | * fm10k_tx_timeout - Respond to a Tx Hang |
---|
699 | 582 | * @netdev: network interface device structure |
---|
| 583 | + * @txqueue: the index of the Tx queue that timed out |
---|
700 | 584 | **/ |
---|
701 | | -static void fm10k_tx_timeout(struct net_device *netdev) |
---|
| 585 | +static void fm10k_tx_timeout(struct net_device *netdev, unsigned int txqueue) |
---|
702 | 586 | { |
---|
703 | 587 | struct fm10k_intfc *interface = netdev_priv(netdev); |
---|
| 588 | + struct fm10k_ring *tx_ring; |
---|
704 | 589 | bool real_tx_hang = false; |
---|
705 | | - int i; |
---|
706 | 590 | |
---|
707 | | -#define TX_TIMEO_LIMIT 16000 |
---|
708 | | - for (i = 0; i < interface->num_tx_queues; i++) { |
---|
709 | | - struct fm10k_ring *tx_ring = interface->tx_ring[i]; |
---|
710 | | - |
---|
711 | | - if (check_for_tx_hang(tx_ring) && fm10k_check_tx_hang(tx_ring)) |
---|
712 | | - real_tx_hang = true; |
---|
| 591 | + if (txqueue >= interface->num_tx_queues) { |
---|
| 592 | + WARN(1, "invalid Tx queue index %d", txqueue); |
---|
| 593 | + return; |
---|
713 | 594 | } |
---|
714 | 595 | |
---|
| 596 | + tx_ring = interface->tx_ring[txqueue]; |
---|
| 597 | + if (check_for_tx_hang(tx_ring) && fm10k_check_tx_hang(tx_ring)) |
---|
| 598 | + real_tx_hang = true; |
---|
| 599 | + |
---|
| 600 | +#define TX_TIMEO_LIMIT 16000 |
---|
715 | 601 | if (real_tx_hang) { |
---|
716 | 602 | fm10k_tx_timeout_reset(interface); |
---|
717 | 603 | } else { |
---|
.. | .. |
---|
851 | 737 | /* Don't free requests for other interfaces */ |
---|
852 | 738 | if (r->mac.glort != glort) |
---|
853 | 739 | break; |
---|
854 | | - /* fall through */ |
---|
| 740 | + fallthrough; |
---|
855 | 741 | case FM10K_VLAN_REQUEST: |
---|
856 | 742 | if (vlans) { |
---|
857 | 743 | list_del(&r->list); |
---|
.. | .. |
---|
871 | 757 | u16 glort = interface->glort; |
---|
872 | 758 | u16 vid = interface->vid; |
---|
873 | 759 | bool set = !!(vid / VLAN_N_VID); |
---|
874 | | - int err = -EHOSTDOWN; |
---|
| 760 | + int err; |
---|
875 | 761 | |
---|
876 | 762 | /* drop any leading bits on the VLAN ID */ |
---|
877 | 763 | vid &= VLAN_N_VID - 1; |
---|
.. | .. |
---|
891 | 777 | u16 glort = interface->glort; |
---|
892 | 778 | u16 vid = interface->vid; |
---|
893 | 779 | bool set = !!(vid / VLAN_N_VID); |
---|
894 | | - int err = -EHOSTDOWN; |
---|
| 780 | + int err; |
---|
895 | 781 | |
---|
896 | 782 | /* drop any leading bits on the VLAN ID */ |
---|
897 | 783 | vid &= VLAN_N_VID - 1; |
---|
.. | .. |
---|
1444 | 1330 | static void fm10k_assign_l2_accel(struct fm10k_intfc *interface, |
---|
1445 | 1331 | struct fm10k_l2_accel *l2_accel) |
---|
1446 | 1332 | { |
---|
1447 | | - struct fm10k_ring *ring; |
---|
1448 | 1333 | int i; |
---|
1449 | 1334 | |
---|
1450 | 1335 | for (i = 0; i < interface->num_rx_queues; i++) { |
---|
1451 | | - ring = interface->rx_ring[i]; |
---|
| 1336 | + struct fm10k_ring *ring = interface->rx_ring[i]; |
---|
| 1337 | + |
---|
1452 | 1338 | rcu_assign_pointer(ring->l2_accel, l2_accel); |
---|
1453 | 1339 | } |
---|
1454 | 1340 | |
---|
.. | .. |
---|
1463 | 1349 | struct fm10k_l2_accel *old_l2_accel = NULL; |
---|
1464 | 1350 | struct fm10k_dglort_cfg dglort = { 0 }; |
---|
1465 | 1351 | struct fm10k_hw *hw = &interface->hw; |
---|
1466 | | - int size = 0, i; |
---|
| 1352 | + int size, i; |
---|
1467 | 1353 | u16 vid, glort; |
---|
1468 | 1354 | |
---|
1469 | 1355 | /* The hardware supported by fm10k only filters on the destination MAC |
---|
.. | .. |
---|
1644 | 1530 | .ndo_set_vf_vlan = fm10k_ndo_set_vf_vlan, |
---|
1645 | 1531 | .ndo_set_vf_rate = fm10k_ndo_set_vf_bw, |
---|
1646 | 1532 | .ndo_get_vf_config = fm10k_ndo_get_vf_config, |
---|
1647 | | - .ndo_udp_tunnel_add = fm10k_udp_tunnel_add, |
---|
1648 | | - .ndo_udp_tunnel_del = fm10k_udp_tunnel_del, |
---|
| 1533 | + .ndo_get_vf_stats = fm10k_ndo_get_vf_stats, |
---|
| 1534 | + .ndo_udp_tunnel_add = udp_tunnel_nic_add_port, |
---|
| 1535 | + .ndo_udp_tunnel_del = udp_tunnel_nic_del_port, |
---|
1649 | 1536 | .ndo_dfwd_add_station = fm10k_dfwd_add_station, |
---|
1650 | 1537 | .ndo_dfwd_del_station = fm10k_dfwd_del_station, |
---|
1651 | 1538 | .ndo_features_check = fm10k_features_check, |
---|
.. | .. |
---|
1692 | 1579 | NETIF_F_SG; |
---|
1693 | 1580 | |
---|
1694 | 1581 | dev->features |= NETIF_F_GSO_UDP_TUNNEL; |
---|
| 1582 | + |
---|
| 1583 | + dev->udp_tunnel_nic_info = &fm10k_udp_tunnels; |
---|
1695 | 1584 | } |
---|
1696 | 1585 | |
---|
1697 | 1586 | /* all features defined to this point should be changeable */ |
---|