| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * QLogic qlcnic NIC Driver |
|---|
| 3 | 4 | * Copyright (c) 2009-2013 QLogic Corporation |
|---|
| 4 | | - * |
|---|
| 5 | | - * See LICENSE.qlcnic for copyright and licensing details. |
|---|
| 6 | 5 | */ |
|---|
| 7 | 6 | |
|---|
| 8 | 7 | #include <linux/vmalloc.h> |
|---|
| .. | .. |
|---|
| 56 | 55 | static void qlcnic_remove(struct pci_dev *pdev); |
|---|
| 57 | 56 | static int qlcnic_open(struct net_device *netdev); |
|---|
| 58 | 57 | static int qlcnic_close(struct net_device *netdev); |
|---|
| 59 | | -static void qlcnic_tx_timeout(struct net_device *netdev); |
|---|
| 58 | +static void qlcnic_tx_timeout(struct net_device *netdev, unsigned int txqueue); |
|---|
| 60 | 59 | static void qlcnic_attach_work(struct work_struct *work); |
|---|
| 61 | 60 | static void qlcnic_fwinit_work(struct work_struct *work); |
|---|
| 62 | 61 | |
|---|
| .. | .. |
|---|
| 396 | 395 | |
|---|
| 397 | 396 | static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], |
|---|
| 398 | 397 | struct net_device *netdev, |
|---|
| 399 | | - const unsigned char *addr, u16 vid, u16 flags) |
|---|
| 398 | + const unsigned char *addr, u16 vid, u16 flags, |
|---|
| 399 | + struct netlink_ext_ack *extack) |
|---|
| 400 | 400 | { |
|---|
| 401 | 401 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
|---|
| 402 | 402 | int err = 0; |
|---|
| .. | .. |
|---|
| 470 | 470 | return 0; |
|---|
| 471 | 471 | } |
|---|
| 472 | 472 | |
|---|
| 473 | | -static void qlcnic_add_vxlan_port(struct net_device *netdev, |
|---|
| 474 | | - struct udp_tunnel_info *ti) |
|---|
| 473 | +static int qlcnic_udp_tunnel_sync(struct net_device *dev, unsigned int table) |
|---|
| 475 | 474 | { |
|---|
| 476 | | - struct qlcnic_adapter *adapter = netdev_priv(netdev); |
|---|
| 477 | | - struct qlcnic_hardware_context *ahw = adapter->ahw; |
|---|
| 475 | + struct qlcnic_adapter *adapter = netdev_priv(dev); |
|---|
| 476 | + struct udp_tunnel_info ti; |
|---|
| 477 | + int err; |
|---|
| 478 | 478 | |
|---|
| 479 | | - if (ti->type != UDP_TUNNEL_TYPE_VXLAN) |
|---|
| 480 | | - return; |
|---|
| 481 | | - |
|---|
| 482 | | - /* Adapter supports only one VXLAN port. Use very first port |
|---|
| 483 | | - * for enabling offload |
|---|
| 484 | | - */ |
|---|
| 485 | | - if (!qlcnic_encap_rx_offload(adapter)) |
|---|
| 486 | | - return; |
|---|
| 487 | | - if (!ahw->vxlan_port_count) { |
|---|
| 488 | | - ahw->vxlan_port_count = 1; |
|---|
| 489 | | - ahw->vxlan_port = ntohs(ti->port); |
|---|
| 490 | | - adapter->flags |= QLCNIC_ADD_VXLAN_PORT; |
|---|
| 491 | | - return; |
|---|
| 479 | + udp_tunnel_nic_get_port(dev, table, 0, &ti); |
|---|
| 480 | + if (ti.port) { |
|---|
| 481 | + err = qlcnic_set_vxlan_port(adapter, ntohs(ti.port)); |
|---|
| 482 | + if (err) |
|---|
| 483 | + return err; |
|---|
| 492 | 484 | } |
|---|
| 493 | | - if (ahw->vxlan_port == ntohs(ti->port)) |
|---|
| 494 | | - ahw->vxlan_port_count++; |
|---|
| 495 | 485 | |
|---|
| 486 | + return qlcnic_set_vxlan_parsing(adapter, ntohs(ti.port)); |
|---|
| 496 | 487 | } |
|---|
| 497 | 488 | |
|---|
| 498 | | -static void qlcnic_del_vxlan_port(struct net_device *netdev, |
|---|
| 499 | | - struct udp_tunnel_info *ti) |
|---|
| 500 | | -{ |
|---|
| 501 | | - struct qlcnic_adapter *adapter = netdev_priv(netdev); |
|---|
| 502 | | - struct qlcnic_hardware_context *ahw = adapter->ahw; |
|---|
| 503 | | - |
|---|
| 504 | | - if (ti->type != UDP_TUNNEL_TYPE_VXLAN) |
|---|
| 505 | | - return; |
|---|
| 506 | | - |
|---|
| 507 | | - if (!qlcnic_encap_rx_offload(adapter) || !ahw->vxlan_port_count || |
|---|
| 508 | | - (ahw->vxlan_port != ntohs(ti->port))) |
|---|
| 509 | | - return; |
|---|
| 510 | | - |
|---|
| 511 | | - ahw->vxlan_port_count--; |
|---|
| 512 | | - if (!ahw->vxlan_port_count) |
|---|
| 513 | | - adapter->flags |= QLCNIC_DEL_VXLAN_PORT; |
|---|
| 514 | | -} |
|---|
| 489 | +static const struct udp_tunnel_nic_info qlcnic_udp_tunnels = { |
|---|
| 490 | + .sync_table = qlcnic_udp_tunnel_sync, |
|---|
| 491 | + .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP, |
|---|
| 492 | + .tables = { |
|---|
| 493 | + { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, |
|---|
| 494 | + }, |
|---|
| 495 | +}; |
|---|
| 515 | 496 | |
|---|
| 516 | 497 | static netdev_features_t qlcnic_features_check(struct sk_buff *skb, |
|---|
| 517 | 498 | struct net_device *dev, |
|---|
| .. | .. |
|---|
| 539 | 520 | .ndo_fdb_del = qlcnic_fdb_del, |
|---|
| 540 | 521 | .ndo_fdb_dump = qlcnic_fdb_dump, |
|---|
| 541 | 522 | .ndo_get_phys_port_id = qlcnic_get_phys_port_id, |
|---|
| 542 | | - .ndo_udp_tunnel_add = qlcnic_add_vxlan_port, |
|---|
| 543 | | - .ndo_udp_tunnel_del = qlcnic_del_vxlan_port, |
|---|
| 523 | + .ndo_udp_tunnel_add = udp_tunnel_nic_add_port, |
|---|
| 524 | + .ndo_udp_tunnel_del = udp_tunnel_nic_del_port, |
|---|
| 544 | 525 | .ndo_features_check = qlcnic_features_check, |
|---|
| 545 | 526 | #ifdef CONFIG_QLCNIC_SRIOV |
|---|
| 546 | 527 | .ndo_set_vf_mac = qlcnic_sriov_set_vf_mac, |
|---|
| .. | .. |
|---|
| 2016 | 1997 | qlcnic_create_sysfs_entries(adapter); |
|---|
| 2017 | 1998 | |
|---|
| 2018 | 1999 | if (qlcnic_encap_rx_offload(adapter)) |
|---|
| 2019 | | - udp_tunnel_get_rx_info(netdev); |
|---|
| 2000 | + udp_tunnel_nic_reset_ntf(netdev); |
|---|
| 2020 | 2001 | |
|---|
| 2021 | 2002 | adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC; |
|---|
| 2022 | 2003 | return 0; |
|---|
| .. | .. |
|---|
| 2334 | 2315 | NETIF_F_TSO6; |
|---|
| 2335 | 2316 | } |
|---|
| 2336 | 2317 | |
|---|
| 2337 | | - if (qlcnic_encap_rx_offload(adapter)) |
|---|
| 2318 | + if (qlcnic_encap_rx_offload(adapter)) { |
|---|
| 2338 | 2319 | netdev->hw_enc_features |= NETIF_F_RXCSUM; |
|---|
| 2320 | + |
|---|
| 2321 | + netdev->udp_tunnel_nic_info = &qlcnic_udp_tunnels; |
|---|
| 2322 | + } |
|---|
| 2339 | 2323 | |
|---|
| 2340 | 2324 | netdev->hw_features = netdev->features; |
|---|
| 2341 | 2325 | netdev->priv_flags |= IFF_UNICAST_FLT; |
|---|
| .. | .. |
|---|
| 2638 | 2622 | "Device does not support MSI interrupts\n"); |
|---|
| 2639 | 2623 | |
|---|
| 2640 | 2624 | if (qlcnic_82xx_check(adapter)) { |
|---|
| 2641 | | - qlcnic_dcb_enable(adapter->dcb); |
|---|
| 2625 | + err = qlcnic_dcb_enable(adapter->dcb); |
|---|
| 2626 | + if (err) { |
|---|
| 2627 | + qlcnic_dcb_free(adapter->dcb); |
|---|
| 2628 | + dev_err(&pdev->dev, "Failed to enable DCB\n"); |
|---|
| 2629 | + goto err_out_free_hw; |
|---|
| 2630 | + } |
|---|
| 2631 | + |
|---|
| 2642 | 2632 | qlcnic_dcb_get_info(adapter->dcb); |
|---|
| 2643 | 2633 | err = qlcnic_setup_intr(adapter); |
|---|
| 2644 | 2634 | |
|---|
| .. | .. |
|---|
| 2812 | 2802 | pci_disable_device(pdev); |
|---|
| 2813 | 2803 | } |
|---|
| 2814 | 2804 | |
|---|
| 2815 | | -#ifdef CONFIG_PM |
|---|
| 2816 | | -static int qlcnic_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 2805 | +static int __maybe_unused qlcnic_suspend(struct device *dev_d) |
|---|
| 2817 | 2806 | { |
|---|
| 2818 | | - int retval; |
|---|
| 2819 | | - |
|---|
| 2820 | | - retval = __qlcnic_shutdown(pdev); |
|---|
| 2821 | | - if (retval) |
|---|
| 2822 | | - return retval; |
|---|
| 2823 | | - |
|---|
| 2824 | | - pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
|---|
| 2825 | | - return 0; |
|---|
| 2807 | + return __qlcnic_shutdown(to_pci_dev(dev_d)); |
|---|
| 2826 | 2808 | } |
|---|
| 2827 | 2809 | |
|---|
| 2828 | | -static int qlcnic_resume(struct pci_dev *pdev) |
|---|
| 2810 | +static int __maybe_unused qlcnic_resume(struct device *dev_d) |
|---|
| 2829 | 2811 | { |
|---|
| 2830 | | - struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); |
|---|
| 2831 | | - int err; |
|---|
| 2832 | | - |
|---|
| 2833 | | - err = pci_enable_device(pdev); |
|---|
| 2834 | | - if (err) |
|---|
| 2835 | | - return err; |
|---|
| 2836 | | - |
|---|
| 2837 | | - pci_set_power_state(pdev, PCI_D0); |
|---|
| 2838 | | - pci_set_master(pdev); |
|---|
| 2839 | | - pci_restore_state(pdev); |
|---|
| 2812 | + struct qlcnic_adapter *adapter = dev_get_drvdata(dev_d); |
|---|
| 2840 | 2813 | |
|---|
| 2841 | 2814 | return __qlcnic_resume(adapter); |
|---|
| 2842 | 2815 | } |
|---|
| 2843 | | -#endif |
|---|
| 2844 | 2816 | |
|---|
| 2845 | 2817 | static int qlcnic_open(struct net_device *netdev) |
|---|
| 2846 | 2818 | { |
|---|
| .. | .. |
|---|
| 2995 | 2967 | static inline void dump_tx_ring_desc(struct qlcnic_host_tx_ring *tx_ring) |
|---|
| 2996 | 2968 | { |
|---|
| 2997 | 2969 | int i; |
|---|
| 2998 | | - struct cmd_desc_type0 *tx_desc_info; |
|---|
| 2999 | 2970 | |
|---|
| 3000 | 2971 | for (i = 0; i < tx_ring->num_desc; i++) { |
|---|
| 3001 | | - tx_desc_info = &tx_ring->desc_head[i]; |
|---|
| 3002 | 2972 | pr_info("TX Desc: %d\n", i); |
|---|
| 3003 | 2973 | print_hex_dump(KERN_INFO, "TX: ", DUMP_PREFIX_OFFSET, 16, 1, |
|---|
| 3004 | 2974 | &tx_ring->desc_head[i], |
|---|
| .. | .. |
|---|
| 3071 | 3041 | |
|---|
| 3072 | 3042 | } |
|---|
| 3073 | 3043 | |
|---|
| 3074 | | -static void qlcnic_tx_timeout(struct net_device *netdev) |
|---|
| 3044 | +static void qlcnic_tx_timeout(struct net_device *netdev, unsigned int txqueue) |
|---|
| 3075 | 3045 | { |
|---|
| 3076 | 3046 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
|---|
| 3077 | 3047 | |
|---|
| .. | .. |
|---|
| 3932 | 3902 | u32 state; |
|---|
| 3933 | 3903 | struct qlcnic_adapter *adapter = pci_get_drvdata(pdev); |
|---|
| 3934 | 3904 | |
|---|
| 3935 | | - pci_cleanup_aer_uncorrect_error_status(pdev); |
|---|
| 3936 | 3905 | state = QLC_SHARED_REG_RD32(adapter, QLCNIC_CRB_DEV_STATE); |
|---|
| 3937 | 3906 | if (state == QLCNIC_DEV_READY && test_and_clear_bit(__QLCNIC_AER, |
|---|
| 3938 | 3907 | &adapter->state)) |
|---|
| .. | .. |
|---|
| 4011 | 3980 | int queue_type) |
|---|
| 4012 | 3981 | { |
|---|
| 4013 | 3982 | struct net_device *netdev = adapter->netdev; |
|---|
| 4014 | | - u8 max_hw_rings = 0; |
|---|
| 4015 | 3983 | char buf[8]; |
|---|
| 4016 | | - int cur_rings; |
|---|
| 4017 | 3984 | |
|---|
| 4018 | | - if (queue_type == QLCNIC_RX_QUEUE) { |
|---|
| 4019 | | - max_hw_rings = adapter->max_sds_rings; |
|---|
| 4020 | | - cur_rings = adapter->drv_sds_rings; |
|---|
| 3985 | + if (queue_type == QLCNIC_RX_QUEUE) |
|---|
| 4021 | 3986 | strcpy(buf, "SDS"); |
|---|
| 4022 | | - } else if (queue_type == QLCNIC_TX_QUEUE) { |
|---|
| 4023 | | - max_hw_rings = adapter->max_tx_rings; |
|---|
| 4024 | | - cur_rings = adapter->drv_tx_rings; |
|---|
| 3987 | + else |
|---|
| 4025 | 3988 | strcpy(buf, "Tx"); |
|---|
| 4026 | | - } |
|---|
| 4027 | 3989 | |
|---|
| 4028 | 3990 | if (!is_power_of_2(ring_cnt)) { |
|---|
| 4029 | 3991 | netdev_err(netdev, "%s rings value should be a power of 2\n", |
|---|
| .. | .. |
|---|
| 4130 | 4092 | qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, |
|---|
| 4131 | 4093 | struct net_device *dev, unsigned long event) |
|---|
| 4132 | 4094 | { |
|---|
| 4095 | + const struct in_ifaddr *ifa; |
|---|
| 4133 | 4096 | struct in_device *indev; |
|---|
| 4134 | 4097 | |
|---|
| 4135 | 4098 | indev = in_dev_get(dev); |
|---|
| 4136 | 4099 | if (!indev) |
|---|
| 4137 | 4100 | return; |
|---|
| 4138 | 4101 | |
|---|
| 4139 | | - for_ifa(indev) { |
|---|
| 4102 | + in_dev_for_each_ifa_rtnl(ifa, indev) { |
|---|
| 4140 | 4103 | switch (event) { |
|---|
| 4141 | 4104 | case NETDEV_UP: |
|---|
| 4142 | 4105 | qlcnic_config_ipaddr(adapter, |
|---|
| .. | .. |
|---|
| 4149 | 4112 | default: |
|---|
| 4150 | 4113 | break; |
|---|
| 4151 | 4114 | } |
|---|
| 4152 | | - } endfor_ifa(indev); |
|---|
| 4115 | + } |
|---|
| 4153 | 4116 | |
|---|
| 4154 | 4117 | in_dev_put(indev); |
|---|
| 4155 | 4118 | } |
|---|
| .. | .. |
|---|
| 4268 | 4231 | .resume = qlcnic_io_resume, |
|---|
| 4269 | 4232 | }; |
|---|
| 4270 | 4233 | |
|---|
| 4234 | +static SIMPLE_DEV_PM_OPS(qlcnic_pm_ops, qlcnic_suspend, qlcnic_resume); |
|---|
| 4235 | + |
|---|
| 4271 | 4236 | static struct pci_driver qlcnic_driver = { |
|---|
| 4272 | 4237 | .name = qlcnic_driver_name, |
|---|
| 4273 | 4238 | .id_table = qlcnic_pci_tbl, |
|---|
| 4274 | 4239 | .probe = qlcnic_probe, |
|---|
| 4275 | 4240 | .remove = qlcnic_remove, |
|---|
| 4276 | | -#ifdef CONFIG_PM |
|---|
| 4277 | | - .suspend = qlcnic_suspend, |
|---|
| 4278 | | - .resume = qlcnic_resume, |
|---|
| 4279 | | -#endif |
|---|
| 4241 | + .driver.pm = &qlcnic_pm_ops, |
|---|
| 4280 | 4242 | .shutdown = qlcnic_shutdown, |
|---|
| 4281 | 4243 | .err_handler = &qlcnic_err_handler, |
|---|
| 4282 | 4244 | #ifdef CONFIG_QLCNIC_SRIOV |
|---|