diff options
Diffstat (limited to 'drivers/net/ethernet/cavium/liquidio/lio_main.c')
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_main.c | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index 927617cbf6a9..51583ae4b1eb 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -1421,7 +1421,7 @@ static bool fw_type_is_none(void) */ static void octeon_destroy_resources(struct octeon_device *oct) { - int i; + int i, refcount; struct msix_entry *msix_entries; struct octeon_device_priv *oct_priv = (struct octeon_device_priv *)oct->priv; @@ -1556,10 +1556,14 @@ static void octeon_destroy_resources(struct octeon_device *oct) /* fallthrough */ case OCT_DEV_PCI_MAP_DONE: + refcount = octeon_deregister_device(oct); + if (!fw_type_is_none()) { - /* Soft reset the octeon device before exiting */ - if (!OCTEON_CN23XX_PF(oct) || - (OCTEON_CN23XX_PF(oct) && !oct->octeon_id)) + /* Soft reset the octeon device before exiting. + * Implementation note: here, we reset the device + * if it is a CN6XXX OR the last CN23XX device. + */ + if (OCTEON_CN6XXX(oct) || !refcount) oct->fn_list.soft_reset(oct); } @@ -3020,6 +3024,7 @@ static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr) case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_NTP_ALL: conf.rx_filter = HWTSTAMP_FILTER_ALL; break; default: @@ -3586,6 +3591,10 @@ static netdev_features_t liquidio_fix_features(struct net_device *netdev, (lio->dev_capability & NETIF_F_LRO)) request &= ~NETIF_F_LRO; + if ((request & NETIF_F_HW_VLAN_CTAG_FILTER) && + !(lio->dev_capability & NETIF_F_HW_VLAN_CTAG_FILTER)) + request &= ~NETIF_F_HW_VLAN_CTAG_FILTER; + return request; } @@ -3598,14 +3607,14 @@ static int liquidio_set_features(struct net_device *netdev, { struct lio *lio = netdev_priv(netdev); - if (!((netdev->features ^ features) & NETIF_F_LRO)) - return 0; - - if ((features & NETIF_F_LRO) && (lio->dev_capability & NETIF_F_LRO)) + if ((features & NETIF_F_LRO) && + (lio->dev_capability & NETIF_F_LRO) && + !(netdev->features & NETIF_F_LRO)) liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE, OCTNIC_LROIPV4 | OCTNIC_LROIPV6); else if (!(features & NETIF_F_LRO) && - (lio->dev_capability & NETIF_F_LRO)) + (lio->dev_capability & NETIF_F_LRO) && + (netdev->features & NETIF_F_LRO)) liquidio_set_feature(netdev, OCTNET_CMD_LRO_DISABLE, OCTNIC_LROIPV4 | OCTNIC_LROIPV6); @@ -3624,6 +3633,17 @@ static int liquidio_set_features(struct net_device *netdev, liquidio_set_rxcsum_command(netdev, OCTNET_CMD_TNL_RX_CSUM_CTL, OCTNET_CMD_RXCSUM_DISABLE); + if ((features & NETIF_F_HW_VLAN_CTAG_FILTER) && + (lio->dev_capability & NETIF_F_HW_VLAN_CTAG_FILTER) && + !(netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) + liquidio_set_feature(netdev, OCTNET_CMD_VLAN_FILTER_CTL, + OCTNET_CMD_VLAN_FILTER_ENABLE); + else if (!(features & NETIF_F_HW_VLAN_CTAG_FILTER) && + (lio->dev_capability & NETIF_F_HW_VLAN_CTAG_FILTER) && + (netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) + liquidio_set_feature(netdev, OCTNET_CMD_VLAN_FILTER_CTL, + OCTNET_CMD_VLAN_FILTER_DISABLE); + return 0; } @@ -3694,6 +3714,9 @@ static int liquidio_set_vf_mac(struct net_device *netdev, int vfidx, u8 *mac) struct octeon_device *oct = lio->oct_dev; int retval; + if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced) + return -EINVAL; + retval = __liquidio_set_vf_mac(netdev, vfidx, mac, true); if (!retval) cn23xx_tell_vf_its_macaddr_changed(oct, vfidx, mac); @@ -3876,7 +3899,7 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) union oct_link_status *ls; int i; - if (recv_pkt->buffer_size[0] != sizeof(*ls)) { + if (recv_pkt->buffer_size[0] != (sizeof(*ls) + OCT_DROQ_INFO_SIZE)) { dev_err(&oct->pci_dev->dev, "Malformed NIC_INFO, len=%d, ifidx=%d\n", recv_pkt->buffer_size[0], recv_pkt->rh.r_nic_info.gmxport); @@ -3884,7 +3907,8 @@ static int lio_nic_info(struct octeon_recv_info *recv_info, void *buf) } gmxport = recv_pkt->rh.r_nic_info.gmxport; - ls = (union oct_link_status *)get_rbd(recv_pkt->buffer_ptr[0]); + ls = (union oct_link_status *)(get_rbd(recv_pkt->buffer_ptr[0]) + + OCT_DROQ_INFO_SIZE); octeon_swap_8B_data((u64 *)ls, (sizeof(union oct_link_status)) >> 3); for (i = 0; i < oct->ifcount; i++) { @@ -4191,7 +4215,8 @@ static int setup_nic_devices(struct octeon_device *octeon_dev) liquidio_set_feature(netdev, OCTNET_CMD_LRO_ENABLE, OCTNIC_LROIPV4 | OCTNIC_LROIPV6); - liquidio_set_feature(netdev, OCTNET_CMD_ENABLE_VLAN_FILTER, 0); + liquidio_set_feature(netdev, OCTNET_CMD_VLAN_FILTER_CTL, + OCTNET_CMD_VLAN_FILTER_ENABLE); if ((debug != -1) && (debug & NETIF_MSG_HW)) liquidio_set_feature(netdev, @@ -4441,7 +4466,7 @@ octeon_recv_vf_drv_notice(struct octeon_recv_info *recv_info, void *buf) u64 *data, vf_num; notice = recv_pkt->rh.r.ossp; - data = (u64 *)get_rbd(recv_pkt->buffer_ptr[0]); + data = (u64 *)(get_rbd(recv_pkt->buffer_ptr[0]) + OCT_DROQ_INFO_SIZE); /* the first 64-bit word of data is the vf_num */ vf_num = data[0]; @@ -4511,6 +4536,15 @@ static int octeon_device_init(struct octeon_device *octeon_dev) atomic_set(&octeon_dev->status, OCT_DEV_PCI_MAP_DONE); + /* Only add a reference after setting status 'OCT_DEV_PCI_MAP_DONE', + * since that is what is required for the reference to be removed + * during de-initialization (see 'octeon_destroy_resources'). + */ + octeon_register_device(octeon_dev, octeon_dev->pci_dev->bus->number, + PCI_SLOT(octeon_dev->pci_dev->devfn), + PCI_FUNC(octeon_dev->pci_dev->devfn), + true); + octeon_dev->app_mode = CVM_DRV_INVALID_APP; if (OCTEON_CN23XX_PF(octeon_dev)) { |