// SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2022 - 2024 Mucse Corporation. */ #include #include #include #include #include #include #include #include #include #include #include #include "rnpgbe.h" #include "rnpgbe_type.h" #include "rnpgbe_sriov.h" int rnpgbe_msg_post_status_signle(struct rnpgbe_adapter *adapter, enum PF_STATUS status, int vf); #if IS_ENABLED(CONFIG_PCI_IOV) static int __rnpgbe_enable_sriov(struct rnpgbe_adapter *adapter) { struct rnpgbe_hw *hw = &adapter->hw; int num_vf_macvlans, i, num_vebvlans; struct vf_macvlans *mv_list; struct vf_vebvlans *vv_list = NULL; /* sriov and dcb cannot open together */ /* reset numtc */ adapter->flags &= (~RNP_FLAG_DCB_ENABLED); netdev_reset_tc(adapter->netdev); e_info(probe, "SR-IOV enabled with %d VFs\n", adapter->num_vfs); /* Enable VMDq flag so device will be set in VM mode */ adapter->flags |= RNP_FLAG_VMDQ_ENABLED; if (!adapter->ring_feature[RING_F_VMDQ].limit) adapter->ring_feature[RING_F_VMDQ].limit = 1; adapter->ring_feature[RING_F_VMDQ].offset = hw->max_vfs - 1; num_vf_macvlans = hw->num_rar_entries - (hw->max_pf_macvlans + 1 + adapter->num_vfs); num_vebvlans = hw->num_vebvlan_entries; mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans), GFP_KERNEL); adapter->mv_list = mv_list; if (num_vebvlans) { vv_list = kcalloc(num_vebvlans, sizeof(struct vf_vebvlans), GFP_KERNEL); hw->vv_list = vv_list; } if (mv_list) { /* Initialize list of VF macvlans */ INIT_LIST_HEAD(&adapter->vf_mvs.l); for (i = 0; i < num_vf_macvlans; i++) { mv_list->vf = -1; mv_list->free = true; mv_list->rar_entry = hw->mac.num_rar_entries - (i + adapter->num_vfs + 1); list_add(&mv_list->l, &adapter->vf_mvs.l); mv_list++; } } if (vv_list) { /* Initialize list of VF macvlans */ INIT_LIST_HEAD(&hw->vf_vas.l); for (i = 0; i < num_vebvlans; i++) { vv_list->vid = -1; vv_list->vid = 0; vv_list->free = true; vv_list->veb_entry = i; list_add(&vv_list->l, &hw->vf_vas.l); vv_list++; } } adapter->flags2 |= RNP_FLAG2_BRIDGE_MODE_VEB; hw->ops.set_sriov_status(hw, true); adapter->vfinfo = kcalloc(adapter->num_vfs, sizeof(struct vf_data_storage), GFP_KERNEL); if (adapter->vfinfo) { /* limit trafffic classes based on VFs enabled */ /* TODO analyze VF need support pfc or traffic classes */ /* We do not support RSS w/ SR-IOV */ adapter->ring_feature[RING_F_RSS].limit = hw->sriov_ring_limit; /* Disable RSC when in SR-IOV mode */ adapter->flags2 &= ~(RNP_FLAG2_RSC_CAPABLE | RNP_FLAG2_RSC_ENABLED); adapter->flags |= RNP_FLAG_SRIOV_ENABLED; /* force close eee if open sriov */ adapter->eee_enabled = 0; return 0; } return -ENOMEM; } void rnpgbe_enable_sriov_true(struct rnpgbe_adapter *adapter) { int err = 0; if (!(adapter->flags & RNP_FLAG_SRIOV_ENABLED)) return; adapter->flags |= RNP_FLAG_SRIOV_INIT_DONE; err = pci_enable_sriov(adapter->pdev, adapter->num_vfs); if (err) { e_err(drv, "Failed to enable PCI sriov: %d num %d\n", err, adapter->num_vfs); e_err(drv, "We cannot handle this error\n"); } adapter->flags |= RNP_FLAG_VF_INIT_DONE; } /* Note this function is called when the user wants to enable SR-IOV * VFs using the now deprecated module parameter * never used */ void rnpgbe_enable_sriov(struct rnpgbe_adapter *adapter) { int pre_existing_vfs = 0; struct rnpgbe_hw *hw = &adapter->hw; pre_existing_vfs = pci_num_vf(adapter->pdev); if (!pre_existing_vfs && !adapter->num_vfs) return; if (!pre_existing_vfs) { dev_warn(&adapter->pdev->dev, "Enabling SR-IOV VFs using the module parameter is deprecated"); dev_warn(&adapter->pdev->dev, "- please use the pci sysfs interface.\n"); } /* If there are pre-existing VFs then we have to force * use of that many - over ride any module parameter value. * This may result from the user unloading the PF driver * while VFs were assigned to guest VMs or because the VFs * have been created via the new PCI SR-IOV sysfs interface. */ if (pre_existing_vfs) { adapter->num_vfs = pre_existing_vfs; dev_warn(&adapter->pdev->dev, "Virtual Functions already enabled for this device - Please"); dev_warn(&adapter->pdev->dev, "reload all VF drivers to avoid spoofed packet errors\n"); } else { int i; /* The rnpgbe supports up to 64 VFs per physical function * but this implementation limits allocation to 126 so that * basic networking resources are still available to the * physical function. If the user requests greater than * 64 VFs then it is an error - reset to default of zero. */ adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, hw->max_vfs - 1); if (__rnpgbe_enable_sriov(adapter)) { e_err(probe, "Failed to alloc memory for sriov\n"); adapter->num_vfs = 0; } for (i = 0; i < adapter->num_vfs; i++) rnpgbe_vf_configuration(adapter->pdev, (i | 0x10000000)); } } static bool rnpgbe_vfs_are_assigned(struct rnpgbe_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; struct pci_dev *vfdev; unsigned int dev_id = RNP_DEV_ID_N10_PF0_VF_N; unsigned int vendor_id = PCI_VENDOR_ID_MUCSE; switch (adapter->pdev->device) { case RNP_DEV_ID_N10_PF0: case RNP_DEV_ID_N10_PF1: vendor_id = 0x1dab; if (rnpgbe_is_pf1(pdev)) dev_id = RNP_DEV_ID_N10_PF1_VF; else dev_id = RNP_DEV_ID_N10_PF0_VF; break; case PCI_DEVICE_ID_N10_PF0: case PCI_DEVICE_ID_N10_PF1: vendor_id = PCI_VENDOR_ID_MUCSE; if (rnpgbe_is_pf1(pdev)) dev_id = RNP_DEV_ID_N10_PF1_VF_N; else dev_id = RNP_DEV_ID_N10_PF0_VF_N; break; case PCI_DEVICE_ID_N500_QUAD_PORT: case PCI_DEVICE_ID_N500_DUAL_PORT: vendor_id = PCI_VENDOR_ID_MUCSE; dev_id = PCI_DEVICE_ID_N500_VF; break; } /* loop through all the VFs to see if we own any that are assigned */ vfdev = pci_get_device(vendor_id, dev_id, NULL); while (vfdev) { /* if we don't own it we don't care */ if (vfdev->is_virtfn && vfdev->physfn == pdev) { /* if it is assigned we cannot release it */ if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED) return true; } vfdev = pci_get_device(vendor_id, dev_id, vfdev); } return false; } #endif /* CONFIG_PCI_IOV */ int rnpgbe_disable_sriov(struct rnpgbe_adapter *adapter) { struct rnpgbe_hw *hw = &adapter->hw; int rss; int time = 0; if (!(adapter->flags & RNP_FLAG_SRIOV_ENABLED)) return 0; adapter->num_vfs = 0; adapter->flags &= ~RNP_FLAG_SRIOV_ENABLED; adapter->flags &= ~RNP_FLAG_SRIOV_INIT_DONE; adapter->flags &= ~RNP_FLAG_VF_INIT_DONE; adapter->vlan_count = 0; msleep(100); hw->ops.set_mac_rx(hw, false); hw->ops.set_sriov_status(hw, false); /* set num VFs to 0 to prevent access to vfinfo */ while (test_and_set_bit(__RNP_USE_VFINFI, &adapter->state)) { msleep(100); time++; if (time > 100) { e_err(drv, "wait flags timeout\n"); break; } } if (time < 100) clear_bit(__RNP_USE_VFINFI, &adapter->state); /* free VF control structures */ kfree(adapter->vfinfo); adapter->vfinfo = NULL; /* free macvlan list */ kfree(hw->vv_list); hw->vv_list = NULL; kfree(adapter->mv_list); adapter->mv_list = NULL; #if IS_ENABLED(CONFIG_PCI_IOV) /* If our VFs are assigned we cannot shut down SR-IOV * without causing issues, so just leave the hardware * available but disabled */ if (rnpgbe_vfs_are_assigned(adapter)) { e_dev_warn("Unloading driver while VFs are assigned - VFs will not be"); e_dev_warn(" deallocated\n"); return -EPERM; } /* disable iov and allow time for transactions to clear */ pci_disable_sriov(adapter->pdev); #endif /* CONFIG_PCI_IOV */ /* set default pool back to 0 */ /* Disable VMDq flag so device will be set in VM mode */ if (adapter->ring_feature[RING_F_VMDQ].limit == 1) adapter->flags &= ~RNP_FLAG_VMDQ_ENABLED; adapter->ring_feature[RING_F_VMDQ].offset = 0; rss = min_t(int, adapter->max_ring_pair_counts, num_online_cpus()); rss = min_t(int, rss, hw->mac.max_msix_vectors - adapter->num_other_vectors); adapter->ring_feature[RING_F_RSS].limit = rss; /* take a breather then clean up driver data */ msleep(100); return 0; } static bool check_ari_mode(struct pci_dev *dev) { struct pci_bus *bus = dev->bus; return bus->self && bus->self->ari_enabled; } static int rnpgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs) { #if IS_ENABLED(CONFIG_PCI_IOV) struct rnpgbe_adapter *adapter = pci_get_drvdata(dev); struct rnpgbe_hw *hw = &adapter->hw; int err = 0; int i; int pre_existing_vfs = pci_num_vf(dev); if (pre_existing_vfs && pre_existing_vfs != num_vfs) err = rnpgbe_disable_sriov(adapter); else if (pre_existing_vfs && pre_existing_vfs == num_vfs) goto out; if (hw->feature_flags & RNP_VEB_VLAN_MASK_EN) { if (adapter->vlan_count > hw->max_vfs - 1) { dev_err(&adapter->pdev->dev, "vlans is too much, delete less than %d vlans\n", hw->max_vfs - 1); err = -EOPNOTSUPP; goto err_out; } } else if (adapter->vlan_count > 1) { dev_err(&adapter->pdev->dev, "only 1 vlan in sriov mode, delete other vlans\n"); dev_err(&adapter->pdev->dev, "please delete all vlans first\n"); err = -EOPNOTSUPP; goto err_out; } adapter->vlan_count = 0; if (err) goto err_out; /* While the SR-IOV capability structure reports total VFs to be * 64 we limit the actual number that can be allocated to 63 so * that some transmit/receive resources can be reserved to the * PF. The PCI bus driver already checks for other values out of * range. */ if (check_ari_mode(dev)) { if (num_vfs > (hw->max_vfs - 1)) { err = -EPERM; goto err_out; } } else { if (num_vfs > hw->max_vfs_noari) { err = -EPERM; goto err_out; } } /* maybe to early */ adapter->num_vfs = num_vfs; err = __rnpgbe_enable_sriov(adapter); if (err) goto err_out; for (i = 0; i < adapter->num_vfs; i++) rnpgbe_vf_configuration(dev, (i | 0x10000000)); if (hw->ops.clr_rar_all) hw->ops.clr_rar_all(hw); rnpgbe_sriov_reinit(adapter); adapter->flags |= RNP_FLAG_SRIOV_INIT_DONE; err = pci_enable_sriov(dev, num_vfs); if (err) { e_dev_warn("Failed to enable PCI sriov: %d num %d\n", err, num_vfs); rnpgbe_disable_sriov(adapter); rnpgbe_sriov_reinit(adapter); goto err_out; } adapter->flags |= RNP_FLAG_VF_INIT_DONE; out: return num_vfs; err_out: return err; #endif /* CONFIG_PCI_IOV */ return 0; } static int rnpgbe_pci_sriov_disable(struct pci_dev *dev) { struct rnpgbe_adapter *adapter = pci_get_drvdata(dev); int err; u32 current_flags = adapter->flags; err = rnpgbe_disable_sriov(adapter); /* Only reinit if no error and state changed */ if (!err && current_flags != adapter->flags) { adapter->flags &= ~RNP_FLAG_VMDQ_ENABLED; #if IS_ENABLED(CONFIG_PCI_IOV) rnpgbe_sriov_reinit(adapter); #endif /* CONFIG_PCI_IOV */ } return err; } static int rnpgbe_set_vf_multicasts(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { int entries = (msgbuf[0] & RNP_VT_MSGINFO_MASK) >> RNP_VT_MSGINFO_SHIFT; u16 *hash_list = (u16 *)&msgbuf[1]; struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; struct rnpgbe_hw *hw = &adapter->hw; int i; /* only so many hash values supported */ entries = min(entries, RNP_MAX_VF_MC_ENTRIES); /* salt away the number of multi cast addresses assigned * to this VF for later use to restore when the PF multi cast * list changes */ vfinfo->num_vf_mc_hashes = entries; /* VFs are limited to using the MTA hash table for their multicast * addresses */ for (i = 0; i < entries; i++) vfinfo->vf_mc_hashes[i] = hash_list[i]; for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) hw->ops.set_sriov_vf_mc(hw, vfinfo->vf_mc_hashes[i]); return 0; } void rnpgbe_restore_vf_macs(struct rnpgbe_adapter *adapter) { struct rnpgbe_hw *hw = &adapter->hw; int vf; u8 *mac_addr; int rar_entry; for (vf = 0; vf < adapter->num_vfs; vf++) { mac_addr = adapter->vfinfo[vf].vf_mac_addresses; rar_entry = hw->mac.num_rar_entries - (vf + 1); hw->ops.set_rar_with_vf(hw, mac_addr, rar_entry, vf, true); } } void rnpgbe_restore_vf_macvlans(struct rnpgbe_adapter *adapter) { struct rnpgbe_hw *hw = &adapter->hw; struct list_head *pos; struct vf_macvlans *entry; list_for_each(pos, &adapter->vf_mvs.l) { entry = list_entry(pos, struct vf_macvlans, l); if (!entry->free) { hw_dbg(hw, " vf:%d MACVLAN: RAR[%d] <= %pM\n", entry->vf, entry->rar_entry, entry->vf_macvlan); hw->ops.set_rar_with_vf(hw, entry->vf_macvlan, entry->rar_entry, entry->vf, true); } } } void rnpgbe_restore_vf_multicasts(struct rnpgbe_adapter *adapter) { /* Restore any VF macvlans */ rnpgbe_restore_vf_macvlans(adapter); } static int rnpgbe_set_vf_vlan(struct rnpgbe_adapter *adapter, int add, int vid, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; int true_handle = 1; int i; /* VLAN 0 is a special case, don't allow it to be removed */ if (!vid && !add) return 0; /* should check other vf */ if ((adapter->flags & RNP_FLAG_SRIOV_ENABLED)) { /* if other vf use this vlan, don't true remove */ if (add) goto skip_check; /* check equal pf_vlan? */ if (vid == adapter->vf_vlan) true_handle = 0; if (!test_and_set_bit(__RNP_USE_VFINFI, &adapter->state)) { for (i = 0; i < adapter->num_vfs; i++) { /* check if other vf_vlan still valid */ if (i != vf && vid == adapter->vfinfo[i].vf_vlan) true_handle = 0; /* check if other pf_vlan still valid */ if (i != vf && vid == adapter->vfinfo[i].pf_vlan) true_handle = 0; } clear_bit(__RNP_USE_VFINFI, &adapter->state); } } skip_check: if (true_handle) hw->ops.set_vf_vlan_filter(hw, vid, vf, (bool)add, false); if (adapter->priv_flags & RNP_PRIV_FLAG_SRIOV_VLAN_MODE) { if (hw->ops.set_vf_vlan_mode) hw->ops.set_vf_vlan_mode(hw, vid, vf, (bool)add); } return 0; } static inline void rnpgbe_vf_reset_event(struct rnpgbe_adapter *adapter, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; int rar_entry = hw->mac.num_rar_entries - (vf + 1); int i; /* reset multicast table array for vf */ adapter->vfinfo[vf].num_vf_mc_hashes = 0; /* Flush and reset the mta with the new values */ rnpgbe_set_rx_mode(adapter->netdev); /* clear this rar_entry */ hw->ops.clr_rar(hw, rar_entry); /* reset VF api back to unknown */ adapter->vfinfo[vf].vf_api = 0; /* clear vf multicast */ for (i = 0; i < RNP_MAX_VF_MC_ENTRIES; i++) adapter->vfinfo[vf].vf_mc_hashes[i] = 0; /* clear vf vlan setup */ adapter->vfinfo[vf].vf_vlan = 0; adapter->vfinfo[vf].vlan_count = 0; } static int rnpgbe_set_vf_mac(struct rnpgbe_adapter *adapter, int vf, unsigned char *mac_addr) { struct rnpgbe_hw *hw = &adapter->hw; /* this rar_entry may be cofict with mac vlan with pf */ int rar_entry = hw->mac.num_rar_entries - (vf + 1); memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, 6); /* setup to the hw */ hw->ops.set_rar_with_vf(hw, mac_addr, rar_entry, vf, true); return 0; } static int rnpgbe_set_vf_macvlan(struct rnpgbe_adapter *adapter, int vf, int index, unsigned char *mac_addr) { struct rnpgbe_hw *hw = &adapter->hw; struct list_head *pos; struct vf_macvlans *entry; /* index = 0 , only earase */ /* index = 1 , earase and then set */ if (index <= 1) { list_for_each(pos, &adapter->vf_mvs.l) { entry = list_entry(pos, struct vf_macvlans, l); if (entry->vf == vf) { entry->vf = -1; entry->free = true; entry->is_macvlan = false; hw->ops.clr_rar(hw, entry->rar_entry); } } } /* If index was zero then we were asked to clear the uc list * for the VF. We're done. */ if (!index) return 0; entry = NULL; list_for_each(pos, &adapter->vf_mvs.l) { entry = list_entry(pos, struct vf_macvlans, l); if (entry->free) break; } /* If we traversed the entire list and didn't find a free entry * then we're out of space on the RAR table. Also entry may * be NULL because the original memory allocation for the list * failed, which is not fatal but does mean we can't support * VF requests for MACVLAN because we couldn't allocate * memory for the list management required. */ if (!entry || !entry->free) return -ENOSPC; entry->free = false; entry->is_macvlan = true; entry->vf = vf; memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN); hw->ops.set_rar_with_vf(hw, entry->vf_macvlan, entry->rar_entry, entry->vf, true); return 0; } int rnpgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) { unsigned char vf_mac_addr[6]; struct rnpgbe_adapter *adapter = pci_get_drvdata(pdev); unsigned int vfn = (event_mask & 0x3f); bool enable = ((event_mask & 0x10000000U) != 0); if (enable) { eth_zero_addr(vf_mac_addr); memcpy(vf_mac_addr, adapter->hw.mac.perm_addr, 6); vf_mac_addr[5] = vf_mac_addr[5] + (0x80 | vfn); vf_mac_addr[4] = vf_mac_addr[4] + (pdev->devfn); memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6); } return 0; } static int rnpgbe_vf_reset_msg(struct rnpgbe_adapter *adapter, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; u32 msgbuf[RNP_VF_PERMADDR_MSG_LEN]; u8 *addr = (u8 *)(&msgbuf[1]); /* reset the filters for the device */ rnpgbe_vf_reset_event(adapter, vf); /* set vf mac address */ if (!is_zero_ether_addr(vf_mac)) rnpgbe_set_vf_mac(adapter, vf, vf_mac); /* enable VF mailbox for further messages */ adapter->vfinfo[vf].clear_to_send = true; /* Enable counting of spoofed packets in the SSVPC register */ /* reply to reset with ack and vf mac address */ msgbuf[0] = RNP_VF_RESET; if (!is_zero_ether_addr(vf_mac)) { msgbuf[0] |= RNP_VT_MSGTYPE_ACK; memcpy(addr, vf_mac, ETH_ALEN); } else { msgbuf[0] |= RNP_VT_MSGTYPE_NACK; dev_warn(&adapter->pdev->dev, "VF %d has no MAC address assigned, you may have to assign", vf); dev_warn(&adapter->pdev->dev, "one manually\n"); } /* Piggyback the multicast filter type so VF can compute the * correct vectors */ msgbuf[RNP_VF_MC_TYPE_WORD] = 0; /* setup link status , pause mode, ft padding mode */ /* link status */ /* pause mode */ msgbuf[RNP_VF_MC_TYPE_WORD] |= (0xff & hw->fc.current_mode) << 16; if (adapter->priv_flags & RNP_PRIV_FLAG_FT_PADDING) msgbuf[RNP_VF_MC_TYPE_WORD] |= (0x01 << 8); else msgbuf[RNP_VF_MC_TYPE_WORD] |= (0x00 << 8); /* mc_type */ msgbuf[RNP_VF_MC_TYPE_WORD] |= rd32(hw, RNP_ETH_DMAC_MCSTCTRL) & 0x03; msgbuf[RNP_VF_DMA_VERSION_WORD] = rd32(hw, RNP_DMA_VERSION); msgbuf[RNP_VF_VLAN_WORD] = adapter->vfinfo[vf].pf_vlan; /* fixme tx fetch to be added here */ msgbuf[RNP_VF_PHY_TYPE_WORD] = (hw->mac_type << 16) | hw->phy_type; msgbuf[RNP_VF_FW_VERSION_WORD] = (hw->fw_version); if (adapter->vfinfo[vf].link_state == rnpgbe_link_state_auto) { msgbuf[RNP_VF_LINK_STATUS_WORD] = (adapter->link_up ? RNP_PF_LINK_UP : 0) | adapter->link_speed; } else if (adapter->vfinfo[vf].link_state == rnpgbe_link_state_on) { msgbuf[RNP_VF_LINK_STATUS_WORD] = RNP_PF_LINK_UP | adapter->link_speed; } else { msgbuf[RNP_VF_LINK_STATUS_WORD] = 0; } msgbuf[RNP_VF_AXI_MHZ] = hw->usecstocount; if (adapter->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER) msgbuf[RNP_VF_FEATURE] |= PF_FEATRURE_VLAN_FILTER; if (hw->ncsi_en) msgbuf[RNP_VF_FEATURE] |= PF_NCSI_EN; /* now vf maybe has no irq handler if it is the first reset*/ rnpgbe_write_mbx(hw, msgbuf, RNP_VF_PERMADDR_MSG_LEN, vf); return 0; } static int rnpgbe_get_vf_mac_addr(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { u8 *mac = ((u8 *)(&msgbuf[1])); memcpy(mac, adapter->vfinfo[vf].vf_mac_addresses, 6); return 0; } /* vf call setup a new mac */ static int rnpgbe_set_vf_mac_addr(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { u8 *new_mac = ((u8 *)(&msgbuf[1])); if (!is_valid_ether_addr(new_mac)) { e_warn(drv, "VF %d attempted to set invalid mac\n", vf); return -1; } if (adapter->vfinfo[vf].pf_set_mac && memcmp(adapter->vfinfo[vf].vf_mac_addresses, new_mac, ETH_ALEN)) { e_warn(drv, "VF %d attempted to override administratively set MAC address\n", vf); e_warn(drv, "Reload the VF driver to resume operations\n"); return -1; } rnpgbe_set_vf_mac(adapter, vf, new_mac); return 0; } static int rnpgbe_set_vf_vlan_msg(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { int add = ((msgbuf[0] & RNP_VT_MSGINFO_MASK) >> RNP_VT_MSGINFO_SHIFT); int vid = (msgbuf[1] & RNP_VLVF_VLANID_MASK); int err; if (adapter->vfinfo[vf].pf_vlan) { e_warn(drv, "VF %d attempted to override administratively set VLAN ", vf); e_warn(drv, "configuration\n"); e_warn(drv, "Reload the VF driver to resume operations\n"); return -1; } if ((add) && adapter->vfinfo[vf].vlan_count) { e_warn(drv, "VF %d attempted to set more than 1 vlan", vf); e_warn(drv, " vlan now %d, try to set %d\n", adapter->vfinfo[vf].vf_vlan, vid); return -1; } /* vlan 0 has no work todo */ if (!vid) return 0; if (add) { adapter->vfinfo[vf].vlan_count++; /* store vf vlan setup */ adapter->vfinfo[vf].vf_vlan = vid; } else if (adapter->vfinfo[vf].vlan_count) { adapter->vfinfo[vf].vf_vlan = 0; adapter->vfinfo[vf].vlan_count--; } err = rnpgbe_set_vf_vlan(adapter, add, vid, vf); return err; } static int rnpgbe_set_vf_vlan_strip_msg(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; int vlan_strip_on = !!(msgbuf[1] >> 31); int queue_cnt = msgbuf[1] & 0xffff; int err = 0, i; for (i = 0; i < queue_cnt; i++) { if (vlan_strip_on) hw->ops.set_vlan_strip(hw, msgbuf[2 + i], true); else hw->ops.set_vlan_strip(hw, msgbuf[2 + i], false); } return err; } static int rnpgbe_set_vf_macvlan_msg(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { u8 *new_mac = ((u8 *)(&msgbuf[1])); int index = (msgbuf[0] & RNP_VT_MSGINFO_MASK) >> RNP_VT_MSGINFO_SHIFT; int err; if (adapter->vfinfo[vf].pf_set_mac && index > 0) { e_warn(drv, "VF %d requested MACVLAN filter but is administratively denied\n", vf); return -1; } /* An non-zero index indicates the VF is setting a filter */ if (index) { if (!is_valid_ether_addr(new_mac)) { e_warn(drv, "VF %d attempted to set invalid mac\n", vf); return -1; } } err = rnpgbe_set_vf_macvlan(adapter, vf, index, new_mac); if (err == -ENOSPC) e_warn(drv, "VF %d has requested a MACVLAN filter but there is no space\n", vf); return err; } static int rnpgbe_negotiate_vf_api(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { adapter->vfinfo[vf].vf_api = 0; return 0; } static int rnpgbe_get_vf_reg(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { u32 reg = msgbuf[1]; msgbuf[1] = rd32(&adapter->hw, reg); return 0; } static int rnpgbe_set_vf_mtu(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { struct net_device *netdev = adapter->netdev; if (msgbuf[1] > netdev->mtu) { e_dev_warn("vf %d try to change mtu large than pf limit\n", vf); return -1; } else { return 0; } } static int rnpgbe_get_vf_mtu(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { struct net_device *netdev = adapter->netdev; msgbuf[1] = netdev->mtu; return 0; } static int rnpgbe_get_vf_fw(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; msgbuf[1] = hw->fw_version; return 0; } static int rnpgbe_get_vf_link(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { if (adapter->vfinfo[vf].link_state == rnpgbe_link_state_auto) { msgbuf[1] = (adapter->link_up ? RNP_PF_LINK_UP : 0) | adapter->link_speed; } else if (adapter->vfinfo[vf].link_state == rnpgbe_link_state_on) { msgbuf[1] = RNP_PF_LINK_UP | adapter->link_speed; } else { msgbuf[1] = 0; } return 0; } static int rnpgbe_get_vf_dma_frag(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { /* we fixed 1536 bytes */ msgbuf[1] = 1536; return 0; } static int rnpgbe_vf_get_stats_clr(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; struct rnpgbe_dma_info *dma = &hw->dma; if (dma_rd32(dma, RNP500_STATISTIC_CRL(vf))) msgbuf[1] = 1; else msgbuf[1] = 0; return 0; } static int rnpgbe_vf_set_stats_clr(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; struct rnpgbe_dma_info *dma = &hw->dma; if (msgbuf[1]) dma_wr32(dma, RNP500_STATISTIC_CRL(vf), 1); else dma_wr32(dma, RNP500_STATISTIC_CRL(vf), 0); return 0; } static int rnpgbe_get_vf_queues(struct rnpgbe_adapter *adapter, u32 *msgbuf, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; msgbuf[RNP_VF_TX_QUEUES] = hw->sriov_ring_limit; msgbuf[RNP_VF_RX_QUEUES] = hw->sriov_ring_limit; msgbuf[RNP_VF_TRANS_VLAN] = adapter->vfinfo[vf].pf_vlan; msgbuf[RNP_VF_DEF_QUEUE] = 0; if (hw->hw_type == rnpgbe_hw_n400) { /* n400, we use */ /* vf0 use ring4 */ /* vf1 use ring8 */ msgbuf[RNP_VF_QUEUE_START] = vf * 4 + 4; } else { msgbuf[RNP_VF_QUEUE_START] = vf * hw->sriov_ring_limit; } msgbuf[RNP_VF_QUEUE_DEPTH] = (adapter->tx_ring_item_count << 16) | adapter->rx_ring_item_count; return 0; } static int rnpgbe_rcv_msg_from_vf(struct rnpgbe_adapter *adapter, u32 vf) { u32 mbx_size = RNP_VFMAILBOX_SIZE; u32 msgbuf[RNP_VFMAILBOX_SIZE]; struct rnpgbe_hw *hw = &adapter->hw; s32 retval; vf_dbg("msg from vf:%d\n", vf); retval = rnpgbe_read_mbx(hw, msgbuf, mbx_size, vf); if (retval) { pr_err("Error receiving message from VF\n"); return retval; } vf_dbg("msg[0]=0x%08x\n", msgbuf[0]); /* this is a message we already processed, do nothing */ if (msgbuf[0] & (RNP_VT_MSGTYPE_ACK | RNP_VT_MSGTYPE_NACK)) return retval; /* flush the ack before we write any messages back */ /* clear vf_num */ msgbuf[0] &= (~RNP_VF_MASK); /* this is a vf reset irq */ if ((msgbuf[0] & RNP_MAIL_CMD_MASK) == RNP_VF_RESET) { vf_dbg("vf %d up\n", vf); return rnpgbe_vf_reset_msg(adapter, vf); } /* until the vf completes a virtual function reset it should not be * allowed to start any configuration. */ if (!adapter->vfinfo[vf].clear_to_send) { vf_dbg("wait vf clear to send\n"); msgbuf[0] |= RNP_VT_MSGTYPE_NACK; rnpgbe_write_mbx(hw, msgbuf, 1, vf); return retval; } switch ((msgbuf[0] & RNP_MAIL_CMD_MASK)) { case RNP_VF_SET_MAC_ADDR: retval = rnpgbe_set_vf_mac_addr(adapter, msgbuf, vf); break; case RNP_VF_SET_MULTICAST: retval = rnpgbe_set_vf_multicasts(adapter, msgbuf, vf); break; case RNP_VF_SET_VLAN: retval = rnpgbe_set_vf_vlan_msg(adapter, msgbuf, vf); break; case RNP_VF_SET_VLAN_STRIP: retval = rnpgbe_set_vf_vlan_strip_msg(adapter, msgbuf, vf); break; case RNP_VF_GET_MACADDR: retval = rnpgbe_get_vf_mac_addr(adapter, msgbuf, vf); break; case RNP_VF_SET_MACVLAN: retval = rnpgbe_set_vf_macvlan_msg(adapter, msgbuf, vf); break; case RNP_VF_API_NEGOTIATE: retval = rnpgbe_negotiate_vf_api(adapter, msgbuf, vf); break; case RNP_VF_GET_QUEUES: retval = rnpgbe_get_vf_queues(adapter, msgbuf, vf); break; case RNP_VF_REG_RD: retval = rnpgbe_get_vf_reg(adapter, msgbuf, vf); break; case RNP_VF_GET_MTU: retval = rnpgbe_get_vf_mtu(adapter, msgbuf, vf); break; case RNP_VF_SET_MTU: retval = rnpgbe_set_vf_mtu(adapter, msgbuf, vf); break; case RNP_VF_GET_FW: retval = rnpgbe_get_vf_fw(adapter, msgbuf, vf); break; case RNP_VF_GET_LINK: retval = rnpgbe_get_vf_link(adapter, msgbuf, vf); break; case RNP_PF_REMOVE: vf_dbg("vf %d removed\n", vf); adapter->vfinfo[vf].clear_to_send = false; adapter->vfinfo[vf].vf_vlan = 0; retval = 1; break; case RNP_VF_RESET_PF: adapter->flags2 |= RNP_FLAG2_RESET_PF; retval = 1; break; case RNP_VF_GET_DMA_FRAG: retval = rnpgbe_get_vf_dma_frag(adapter, msgbuf, vf); break; case RNP_VF_SET_STATS_CLR: retval = rnpgbe_vf_set_stats_clr(adapter, msgbuf, vf); break; case RNP_VF_GET_STATS_CLR: retval = rnpgbe_vf_get_stats_clr(adapter, msgbuf, vf); break; default: e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); retval = RNP_ERR_MBX; break; } /* notify the VF of the results of what it sent us */ if (retval) msgbuf[0] |= RNP_VT_MSGTYPE_NACK; else msgbuf[0] |= RNP_VT_MSGTYPE_ACK; /* write vf_num */ msgbuf[0] |= (vf << 21); msgbuf[0] |= RNP_VT_MSGTYPE_CTS; if ((msgbuf[0] & RNP_MAIL_CMD_MASK) != RNP_PF_REMOVE) rnpgbe_write_mbx(hw, msgbuf, mbx_size, vf); return retval; } static void rnpgbe_rcv_ack_from_vf(struct rnpgbe_adapter *adapter, u32 vf) { struct rnpgbe_hw *hw = &adapter->hw; u32 msg = RNP_VT_MSGTYPE_NACK; /* if device isn't clear to send it shouldn't be reading either */ if (!adapter->vfinfo[vf].clear_to_send) rnpgbe_write_mbx(hw, &msg, 1, vf); } void rnpgbe_msg_task(struct rnpgbe_adapter *adapter) { struct rnpgbe_hw *hw = &adapter->hw; u32 vf; rnpgbe_fw_msg_handler(adapter); if (!(adapter->flags & RNP_FLAG_SRIOV_INIT_DONE)) return; for (vf = 0; vf < adapter->num_vfs; vf++) { if (test_and_set_bit(__VF_MBX_USED, &adapter->vfinfo[vf].status)) { adapter->miss_time++; e_info(drv, "we missed some irqs %d\n", vf); continue; } /* process any messages pending */ if (!rnpgbe_check_for_msg(hw, vf)) rnpgbe_rcv_msg_from_vf(adapter, vf); /* process any acks */ if (!rnpgbe_check_for_ack(hw, vf)) rnpgbe_rcv_ack_from_vf(adapter, vf); clear_bit(__VF_MBX_USED, &adapter->vfinfo[vf].status); } } static int rnpgbe_msg_post_status_signle_link(struct rnpgbe_adapter *adapter, int vf, int link_state) { u32 msgbuf[RNP_VFMAILBOX_SIZE]; struct rnpgbe_hw *hw = &adapter->hw; struct rnpgbe_mbx_info *mbx = &hw->mbx; msgbuf[0] = RNP_PF_SET_LINK | (vf << RNP_VNUM_OFFSET); switch (link_state) { case rnpgbe_link_state_on: msgbuf[1] = RNP_PF_LINK_UP | adapter->link_speed; break; case rnpgbe_link_state_off: msgbuf[1] = 0; break; case rnpgbe_link_state_auto: if (adapter->link_up) msgbuf[1] = RNP_PF_LINK_UP | adapter->link_speed; else msgbuf[1] = 0; break; } return mbx->ops.write(hw, msgbuf, 2, vf); } int rnpgbe_msg_post_status_signle(struct rnpgbe_adapter *adapter, enum PF_STATUS status, int vf) { u32 msgbuf[RNP_VFMAILBOX_SIZE]; struct rnpgbe_hw *hw = &adapter->hw; struct rnpgbe_mbx_info *mbx = &hw->mbx; switch (status) { case PF_FCS_STATUS: msgbuf[0] = RNP_PF_SET_FCS | (vf << RNP_VNUM_OFFSET); if (adapter->netdev->features & NETIF_F_RXFCS) msgbuf[1] = 1; else msgbuf[1] = 0; break; case PF_PAUSE_STATUS: msgbuf[0] = RNP_PF_SET_PAUSE | (vf << RNP_VNUM_OFFSET); msgbuf[1] = hw->fc.requested_mode; break; case PF_FT_PADDING_STATUS: msgbuf[0] = RNP_PF_SET_FT_PADDING | (vf << RNP_VNUM_OFFSET); if (adapter->priv_flags & RNP_PRIV_FLAG_FT_PADDING) msgbuf[1] = 1; else msgbuf[1] = 0; break; case PF_VLAN_FILTER_STATUS: msgbuf[0] = RNP_PF_SET_VLAN_FILTER | (vf << RNP_VNUM_OFFSET); if (adapter->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER) msgbuf[1] = 1; else msgbuf[1] = 0; break; case PF_SET_VLAN_STATUS: msgbuf[0] = RNP_PF_SET_VLAN | (vf << RNP_VNUM_OFFSET); msgbuf[1] = adapter->vfinfo[vf].pf_vlan; break; case PF_SET_LINK_STATUS: if (adapter->vfinfo[vf].link_state != rnpgbe_link_state_auto) return 0; /* only update link state if in auto mode */ msgbuf[0] = RNP_PF_SET_LINK | (vf << RNP_VNUM_OFFSET); if (adapter->link_up) msgbuf[1] = RNP_PF_LINK_UP | adapter->link_speed; else msgbuf[1] = 0; break; case PF_SET_MTU: msgbuf[0] = RNP_PF_SET_MTU | (vf << RNP_VNUM_OFFSET); msgbuf[1] = adapter->netdev->mtu; break; case PF_SET_RESET: msgbuf[0] = RNP_PF_SET_RESET | (vf << RNP_VNUM_OFFSET); msgbuf[1] = 0; break; } return mbx->ops.write_posted(hw, msgbuf, 2, vf); } /* try to send mailbox to all active vf */ int rnpgbe_msg_post_status(struct rnpgbe_adapter *adapter, enum PF_STATUS status) { u32 vf; int err = 0; if (!(adapter->flags & RNP_FLAG_SRIOV_ENABLED)) return 0; /* broadcast */ for (vf = 0; vf < adapter->num_vfs; vf++) { if (!(adapter->vfinfo[vf].clear_to_send)) continue; if (!test_bit(__RNP_IN_IRQ, &adapter->state)) { if (test_and_set_bit(__VF_MBX_USED, &adapter->vfinfo[vf].status)) { adapter->miss_time++; return -1; } err |= rnpgbe_msg_post_status_signle(adapter, status, vf); clear_bit(__VF_MBX_USED, &adapter->vfinfo[vf].status); } } return err; } void rnpgbe_ping_all_vfs(struct rnpgbe_adapter *adapter) { struct rnpgbe_hw *hw = &adapter->hw; u32 ping; int i; for (i = 0; i < adapter->num_vfs; i++) { ping = RNP_PF_CONTROL_PRING_MSG; /* only send to active vf */ ping |= RNP_VT_MSGTYPE_CTS; rnpgbe_write_mbx(hw, &ping, 1, i); } } int rnpgbe_get_vf_ringnum(struct rnpgbe_hw *hw, int vf, int num) { return vf; } int rnpgbe_setup_ring_maxrate(struct rnpgbe_adapter *adapter, int ring, u64 max_rate) { struct rnpgbe_hw *hw = &adapter->hw; struct rnpgbe_dma_info *dma = &hw->dma; int samples_1sec = adapter->hw.usecstocount * 1000000; dma_ring_wr32(dma, RING_OFFSET(ring) + RNP_DMA_REG_TX_FLOW_CTRL_TM, samples_1sec); dma_ring_wr32(dma, RING_OFFSET(ring) + RNP_DMA_REG_TX_FLOW_CTRL_TH, max_rate); return 0; } static int rnpgbe_disable_port_vlan(struct rnpgbe_adapter *adapter, int vf) { struct rnpgbe_hw *hw = &adapter->hw; int err; err = rnpgbe_set_vf_vlan(adapter, false, adapter->vfinfo[vf].pf_vlan, vf); if (adapter->priv_flags & RNP_PRIV_FLAG_SRIOV_VLAN_MODE) { if (hw->ops.set_vf_vlan_mode) { hw->ops.set_vf_vlan_mode(hw, adapter->vfinfo[vf].pf_vlan, vf, false); } } adapter->vfinfo[vf].pf_vlan = 0; adapter->vfinfo[vf].pf_qos = 0; /* clear veb */ hw->ops.set_vf_vlan_filter(hw, 0, vf, false, true); return err; } static int rnpgbe_enable_port_vlan(struct rnpgbe_adapter *adapter, int vf, u16 vlan, u8 qos) { struct rnpgbe_hw *hw = &adapter->hw; int err; err = rnpgbe_set_vf_vlan(adapter, true, vlan, vf); if (err) goto out; adapter->vfinfo[vf].pf_vlan = vlan; adapter->vfinfo[vf].pf_qos = qos; dev_info(&adapter->pdev->dev, "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf); if (test_bit(__RNP_DOWN, &adapter->state)) { dev_warn(&adapter->pdev->dev, "The VF VLAN has been set, but the PF device is not up.\n"); dev_warn(&adapter->pdev->dev, "Bring the PF device up before attempting to use the VF device.\n"); } hw->ops.set_vf_vlan_filter(hw, vlan, vf, true, true); /* if in sriov vlan mode should setup pfvlvf table */ if (adapter->priv_flags & RNP_PRIV_FLAG_SRIOV_VLAN_MODE) { if (hw->ops.set_vf_vlan_mode) hw->ops.set_vf_vlan_mode(hw, vlan, vf, true); } out: return err; } int rnpgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos, __be16 vlan_proto) { int err = 0; struct rnpgbe_adapter *adapter = netdev_priv(netdev); /* VLAN IDs accepted range 0-4094 */ if (vf < 0 || vf >= adapter->num_vfs || vlan > VLAN_VID_MASK - 1 || qos > 7) return -EINVAL; if (vlan_proto != htons(ETH_P_8021Q)) return -EPROTONOSUPPORT; if (vlan || qos) { /* Check if there is already a port VLAN set, if so * we have to delete the old one first before we * can set the new one. The usage model had * previously assumed the user would delete the * old port VLAN before setting a new one but this * is not necessarily the case. */ if (adapter->vfinfo[vf].vf_vlan) { dev_err(&adapter->pdev->dev, "vf set vlan before, delete it before add new\n"); err = -EINVAL; goto out; } if (adapter->vfinfo[vf].pf_vlan) err = rnpgbe_disable_port_vlan(adapter, vf); if (err) goto out; err = rnpgbe_enable_port_vlan(adapter, vf, vlan, qos); } else { /* if vf set vlan, return error */ if (!adapter->vfinfo[vf].pf_vlan && adapter->vfinfo[vf].vf_vlan) { dev_err(&adapter->pdev->dev, "pf can't delete vf set vlan\n"); err = -EINVAL; goto out; } else if (adapter->vfinfo[vf].pf_vlan) { err = rnpgbe_disable_port_vlan(adapter, vf); } } /* send mbx to vf */ if (adapter->vfinfo[vf].clear_to_send) rnpgbe_msg_post_status_signle(adapter, PF_SET_VLAN_STATUS, vf); out: return err; } int rnpgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting) { struct rnpgbe_adapter *adapter = netdev_priv(netdev); if (vf < 0 || vf >= adapter->num_vfs) return -EINVAL; /* maybe we not support this in hw */ adapter->vfinfo[vf].spoofchk_enabled = setting; return 0; } int rnpgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting) { struct rnpgbe_adapter *adapter = netdev_priv(netdev); if (vf < 0 || vf >= adapter->num_vfs) return -EINVAL; /* nothing to do */ if (adapter->vfinfo[vf].trusted == setting) return 0; adapter->vfinfo[vf].trusted = setting; e_info(drv, "VF %u is %strusted\n", vf, setting ? "" : "not "); return 0; } int rnpgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state) { struct rnpgbe_adapter *adapter = netdev_priv(netdev); int ret = 0; if (vf < 0 || vf >= adapter->num_vfs) { dev_err(&adapter->pdev->dev, "NDO set VF link - invalid VF identifier %d\n", vf); ret = -EINVAL; goto out; } switch (state) { case IFLA_VF_LINK_STATE_ENABLE: dev_info(&adapter->pdev->dev, "NDO set VF %d link state %d\n", vf, state); adapter->vfinfo[vf].link_state = rnpgbe_link_state_on; rnpgbe_msg_post_status_signle_link(adapter, vf, rnpgbe_link_state_on); break; case IFLA_VF_LINK_STATE_DISABLE: dev_info(&adapter->pdev->dev, "NDO set VF %d link state disable\n", vf); adapter->vfinfo[vf].link_state = rnpgbe_link_state_off; rnpgbe_msg_post_status_signle_link(adapter, vf, rnpgbe_link_state_off); break; case IFLA_VF_LINK_STATE_AUTO: dev_info(&adapter->pdev->dev, "NDO set VF %d link state auto\n", vf); adapter->vfinfo[vf].link_state = rnpgbe_link_state_auto; rnpgbe_msg_post_status_signle_link(adapter, vf, rnpgbe_link_state_auto); break; default: dev_err(&adapter->pdev->dev, "NDO set VF %d - invalid link state %d\n", vf, state); ret = -EINVAL; } out: return ret; } int rnpgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int __always_unused min_tx_rate, int max_tx_rate) { struct rnpgbe_adapter *adapter = netdev_priv(netdev); struct rnpgbe_hw *hw = &adapter->hw; /* limit vf ring rate */ int ring_max_rate; int vf_ring; int link_speed = 0; u64 real_rate = 0; if (vf >= hw->max_vfs - 1) return -EINVAL; switch (adapter->link_speed) { case RNP_LINK_SPEED_40GB_FULL: link_speed = 40000; break; case RNP_LINK_SPEED_25GB_FULL: link_speed = 25000; break; case RNP_LINK_SPEED_10GB_FULL: link_speed = 10000; break; case RNP_LINK_SPEED_1GB_FULL: link_speed = 1000; break; case RNP_LINK_SPEED_100_FULL: link_speed = 100; break; } /* rate limit cannot be less than 1Mbs or greater than link speed */ if (max_tx_rate && (max_tx_rate <= 1 || max_tx_rate > link_speed)) return -EINVAL; adapter->vfinfo[vf].tx_rate = max_tx_rate; ring_max_rate = max_tx_rate / hw->sriov_ring_limit; real_rate = (ring_max_rate * 1024 * 128); vf_ring = rnpgbe_get_vf_ringnum(hw, vf, 0); rnpgbe_setup_ring_maxrate(adapter, vf_ring, real_rate); return 0; } int rnpgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) { struct rnpgbe_adapter *adapter = netdev_priv(netdev); if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs) return -EINVAL; adapter->vfinfo[vf].pf_set_mac = true; dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n", mac, vf); dev_info(&adapter->pdev->dev, "Reload the VF driver to make this"); dev_info(&adapter->pdev->dev, "change effective."); if (test_bit(__RNP_DOWN, &adapter->state)) { dev_warn(&adapter->pdev->dev, "The VF MAC address has been set,"); dev_warn(&adapter->pdev->dev, " but the PF device is not up.\n"); dev_warn(&adapter->pdev->dev, "Bring the PF device up before"); dev_warn(&adapter->pdev->dev, " attempting to use the VF device.\n"); } rnpgbe_set_vf_mac(adapter, vf, mac); /* send reset to vf only vf is up */ if (adapter->vfinfo[vf].clear_to_send) rnpgbe_msg_post_status_signle(adapter, PF_SET_RESET, vf); return 0; } int rnpgbe_ndo_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *ivi) { struct rnpgbe_adapter *adapter = netdev_priv(netdev); if (vf >= adapter->num_vfs) return -EINVAL; ivi->vf = vf; memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); ivi->max_tx_rate = adapter->vfinfo[vf].tx_rate; ivi->min_tx_rate = 0; if (adapter->vfinfo[vf].pf_vlan) ivi->vlan = adapter->vfinfo[vf].pf_vlan; else ivi->vlan = adapter->vfinfo[vf].vf_vlan; ivi->qos = adapter->vfinfo[vf].pf_qos; ivi->spoofchk = adapter->vfinfo[vf].spoofchk_enabled; ivi->linkstate = adapter->vfinfo[vf].link_state; ivi->trusted = adapter->vfinfo[vf].trusted; return 0; } int rnpgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs) { if (num_vfs == 0) return rnpgbe_pci_sriov_disable(dev); else return rnpgbe_pci_sriov_enable(dev, num_vfs); }