From: Naveen Mamindlapalli <[email protected]> Backported PF/VF changes from upstream kernel. -> Avoid modifying netdev->features dynamically by the driver. https://www.kernel.org/doc/html/latest/networking/netdev-features.html -> The MCAM entry allocation is done statically during initialization time. The netdev->features is initialized based on the entries allocated at the low level. -> Removed ndo_features_check callback. -> Used eth_broadcast_addr, eth_zero_addr where ever applicable. -> Use -EOPNOTSUPP instead of -ENOTSUPP.
Change-Id: I81092cd33048c011f6478047788f072b45a08dba Signed-off-by: Naveen Mamindlapalli <[email protected]> Reviewed-on: https://sj1git1.cavium.com/c/IP/SW/kernel/linux/+/42673 Tested-by: sa_ip-sw-jenkins <[email protected]> Reviewed-by: Sunil Kovvuri Goutham <[email protected]> Signed-off-by: Ruiqiang Hao <[email protected]> --- .../ethernet/marvell/octeontx2/nic/otx2_common.h | 6 + .../ethernet/marvell/octeontx2/nic/otx2_flows.c | 135 ++++++++------------- .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 87 +++++++------ .../net/ethernet/marvell/octeontx2/nic/otx2_vf.c | 8 -- 4 files changed, 102 insertions(+), 134 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h index 4612429a354d..2f742d1cc7c3 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -248,6 +248,12 @@ struct otx2_mac_table { struct otx2_flow_config { u16 entry[NPC_MAX_NONCONTIG_ENTRIES]; u32 nr_flows; +#define OTX2_MAX_NTUPLE_FLOWS 32 +#define OTX2_MAX_UNICAST_FLOWS 8 +#define OTX2_MAX_VLAN_FLOWS 1 +#define OTX2_MCAM_COUNT (OTX2_MAX_NTUPLE_FLOWS + \ + OTX2_MAX_UNICAST_FLOWS + \ + OTX2_MAX_VLAN_FLOWS) u32 vf_vlan_offset; u32 ntuple_offset; u32 unicast_offset; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 81b3366db665..7b84ac2a38ec 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c @@ -12,14 +12,6 @@ #include "otx2_common.h" -/* helper macros to support mcam flows */ -#define OTX2_MAX_NTUPLE_FLOWS 32 -#define OTX2_MAX_UNICAST_FLOWS 8 -#define OTX2_MAX_VLAN_FLOWS 1 -#define OTX2_MCAM_COUNT (OTX2_MAX_NTUPLE_FLOWS + \ - OTX2_MAX_UNICAST_FLOWS + \ - OTX2_MAX_VLAN_FLOWS) - #define OTX2_DEFAULT_ACTION 0x1 #define FDSA_MAX_SPORT 32 #define FDSA_SPORT_MASK 0xf8 @@ -33,58 +25,15 @@ struct otx2_flow { int vf; }; -int otx2_mcam_flow_init(struct otx2_nic *pf) -{ - pf->flow_cfg = devm_kzalloc(pf->dev, sizeof(struct otx2_flow_config), - GFP_KERNEL); - if (!pf->flow_cfg) - return -ENOMEM; - - INIT_LIST_HEAD(&pf->flow_cfg->flow_list); - - pf->flow_cfg->ntuple_max_flows = OTX2_MAX_NTUPLE_FLOWS; - - pf->flags |= (OTX2_FLAG_NTUPLE_SUPPORT | - OTX2_FLAG_UCAST_FLTR_SUPPORT | - OTX2_FLAG_RX_VLAN_SUPPORT | - OTX2_FLAG_VF_VLAN_SUPPORT); - - pf->mac_table = devm_kzalloc(pf->dev, sizeof(struct otx2_mac_table) - * OTX2_MAX_UNICAST_FLOWS, GFP_KERNEL); - - if (!pf->mac_table) - return -ENOMEM; - - /* register work queue for ndo callbacks */ - pf->otx2_wq = create_singlethread_workqueue("otx2_ndo_work_queue"); - if (!pf->otx2_wq) - return -ENOMEM; - INIT_WORK(&pf->rx_mode_work, otx2_do_set_rx_mode); - return 0; -} - -void otx2_mcam_flow_del(struct otx2_nic *pf) -{ - otx2_destroy_mcam_flows(pf); - if (pf->otx2_wq) - destroy_workqueue(pf->otx2_wq); -} - int otx2_alloc_mcam_entries(struct otx2_nic *pfvf) { struct otx2_flow_config *flow_cfg = pfvf->flow_cfg; - netdev_features_t wanted = NETIF_F_HW_VLAN_STAG_RX | - NETIF_F_HW_VLAN_CTAG_RX; struct npc_mcam_alloc_entry_req *req; struct npc_mcam_alloc_entry_rsp *rsp; int vf_vlan_max_flows; int i; mutex_lock(&pfvf->mbox.lock); - if (pfvf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC) { - mutex_unlock(&pfvf->mbox.lock); - return 0; - } req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&pfvf->mbox); if (!req) { @@ -106,19 +55,13 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf) (&pfvf->mbox.mbox, 0, &req->hdr); if (rsp->count != req->count) { - netdev_info(pfvf->netdev, "number of rules truncated to %d\n", - rsp->count); netdev_info(pfvf->netdev, - "Disabling RX VLAN offload due to non-availability of MCAM space\n"); + "Unable to allocate %d MCAM entries, got %d\n", + req->count, rsp->count); /* support only ntuples here */ flow_cfg->ntuple_max_flows = rsp->count; flow_cfg->ntuple_offset = 0; - pfvf->netdev->priv_flags &= ~IFF_UNICAST_FLT; - pfvf->flags &= ~OTX2_FLAG_UCAST_FLTR_SUPPORT; - pfvf->flags &= ~OTX2_FLAG_RX_VLAN_SUPPORT; - pfvf->flags &= ~OTX2_FLAG_VF_VLAN_SUPPORT; - pfvf->netdev->features &= ~wanted; - pfvf->netdev->hw_features &= ~wanted; + pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT; } else { flow_cfg->vf_vlan_offset = 0; flow_cfg->ntuple_offset = flow_cfg->vf_vlan_offset + @@ -127,17 +70,53 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf) OTX2_MAX_NTUPLE_FLOWS; flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset + OTX2_MAX_UNICAST_FLOWS; + pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT; + pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT; + pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT; + pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT; } for (i = 0; i < rsp->count; i++) flow_cfg->entry[i] = rsp->entry_list[i]; pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC; + mutex_unlock(&pfvf->mbox.lock); return 0; } +int otx2_mcam_flow_init(struct otx2_nic *pf) +{ + int err; + + pf->flow_cfg = devm_kzalloc(pf->dev, sizeof(struct otx2_flow_config), + GFP_KERNEL); + if (!pf->flow_cfg) + return -ENOMEM; + + INIT_LIST_HEAD(&pf->flow_cfg->flow_list); + + pf->flow_cfg->ntuple_max_flows = OTX2_MAX_NTUPLE_FLOWS; + + err = otx2_alloc_mcam_entries(pf); + if (err) + return err; + + pf->mac_table = devm_kzalloc(pf->dev, sizeof(struct otx2_mac_table) + * OTX2_MAX_UNICAST_FLOWS, GFP_KERNEL); + + if (!pf->mac_table) + return -ENOMEM; + + return 0; +} + +void otx2_mcam_flow_del(struct otx2_nic *pf) +{ + otx2_destroy_mcam_flows(pf); +} + /* On success adds mcam entry * On failure enable promisous mode */ @@ -147,12 +126,6 @@ static int otx2_do_add_macfilter(struct otx2_nic *pf, const u8 *mac) struct npc_install_flow_req *req; int err, i; - if (!(pf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC)) { - err = otx2_alloc_mcam_entries(pf); - if (err) - return err; - } - if (!(pf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT)) return -ENOMEM; @@ -180,7 +153,7 @@ static int otx2_do_add_macfilter(struct otx2_nic *pf, const u8 *mac) } ether_addr_copy(req->packet.dmac, mac); - u64_to_ether_addr(0xffffffffffffull, req->mask.dmac); + eth_broadcast_addr((u8 *)&req->mask.dmac); req->features = BIT_ULL(NPC_DMAC); req->channel = pf->hw.rx_chan_base; req->intf = NIX_INTF_RX; @@ -196,14 +169,8 @@ static int otx2_do_add_macfilter(struct otx2_nic *pf, const u8 *mac) int otx2_add_macfilter(struct net_device *netdev, const u8 *mac) { struct otx2_nic *pf = netdev_priv(netdev); - int err; - err = otx2_do_add_macfilter(pf, mac); - if (err) { - netdev->flags |= IFF_PROMISC; - return err; - } - return 0; + return otx2_do_add_macfilter(pf, mac); } static bool otx2_get_mcamentry_for_mac(struct otx2_nic *pf, const u8 *mac, @@ -523,7 +490,7 @@ static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp, otx2_prepare_ipv6_flow(fsp, req, flow_type); break; default: - return -ENOTSUPP; + return -EOPNOTSUPP; } if (fsp->flow_type & FLOW_EXT) { int skip_user_def = false; @@ -577,7 +544,7 @@ static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp, } if (!req->features) - return -ENOTSUPP; + return -EOPNOTSUPP; return 0; } @@ -644,15 +611,12 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rx_flow_spec *fsp) bool new = false; int err; + if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT)) + return -ENOMEM; + if (ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC) return -EINVAL; - if (!(pfvf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC)) { - err = otx2_alloc_mcam_entries(pfvf); - if (err) - return err; - } - if (fsp->location >= flow_cfg->ntuple_max_flows) return -EINVAL; @@ -738,7 +702,7 @@ int otx2_destroy_ntuple_flows(struct otx2_nic *pfvf) struct otx2_flow *iter, *tmp; int err; - if (!(pfvf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC)) + if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT)) return 0; mutex_lock(&pfvf->mbox.lock); @@ -810,9 +774,6 @@ int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf) struct npc_install_flow_req *req; int err; - if (!(pfvf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC)) - return -ENOMEM; - mutex_lock(&pfvf->mbox.lock); req = otx2_mbox_alloc_msg_npc_install_flow(&pfvf->mbox); if (!req) { @@ -823,7 +784,7 @@ int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf) req->entry = flow_cfg->entry[flow_cfg->rx_vlan_offset]; req->intf = NIX_INTF_RX; ether_addr_copy(req->packet.dmac, pfvf->netdev->dev_addr); - u64_to_ether_addr(0xffffffffffffull, req->mask.dmac); + eth_broadcast_addr((u8 *)&req->mask.dmac); req->channel = pfvf->hw.rx_chan_base; req->op = NIX_RX_ACTION_DEFAULT; req->features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_DMAC); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index b39261255391..7d4564bb42bc 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1647,15 +1647,6 @@ int otx2_open(struct net_device *netdev) if (pf->linfo.link_up && !(pf->pcifunc & RVU_PFVF_FUNC_MASK)) otx2_handle_link_event(pf); - if ((pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT) || - (pf->flags & OTX2_FLAG_VF_VLAN_SUPPORT)) { - if (!(pf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC)) { - err = otx2_alloc_mcam_entries(pf); - if (err) - goto err_tx_stop_queues; - } - } - if (pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT) otx2_enable_rxvlan(pf, true); @@ -1792,12 +1783,18 @@ void otx2_do_set_rx_mode(struct work_struct *work) struct otx2_nic *pf = container_of(work, struct otx2_nic, rx_mode_work); struct net_device *netdev = pf->netdev; struct nix_rx_mode *req; + bool promisc = false; if (!(netdev->flags & IFF_UP)) return; + if ((netdev->flags & IFF_PROMISC) || + (netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) { + promisc = true; + } + /* Write unicast address to mcam entries or del from mcam */ - if (netdev->priv_flags & IFF_UNICAST_FLT) + if (!promisc && netdev->priv_flags & IFF_UNICAST_FLT) __dev_uc_sync(netdev, otx2_add_macfilter, otx2_del_macfilter); mutex_lock(&pf->mbox.lock); @@ -1809,7 +1806,7 @@ void otx2_do_set_rx_mode(struct work_struct *work) req->mode = NIX_RX_MODE_UCAST; - if (netdev->flags & IFF_PROMISC) + if (promisc) req->mode |= NIX_RX_MODE_PROMISC; else if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) req->mode |= NIX_RX_MODE_ALLMULTI; @@ -1996,7 +1993,7 @@ static int otx2_do_set_vf_mac(struct otx2_nic *pf, int vf, const u8 *mac) } ether_addr_copy(req->packet.dmac, mac); - u64_to_ether_addr(0xffffffffffffull, req->mask.dmac); + eth_broadcast_addr((u8 *)&req->mask.dmac); req->features = BIT_ULL(NPC_DMAC); req->channel = pf->hw.rx_chan_base; req->intf = NIX_INTF_RX; @@ -2038,7 +2035,7 @@ static int otx2_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) } int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos, - u16 proto) + __be16 proto) { struct otx2_flow_config *flow_cfg = pf->flow_cfg; struct nix_vtag_config_rsp *vtag_rsp; @@ -2114,7 +2111,7 @@ int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos, req->packet.vlan_tci = htons(vlan); req->mask.vlan_tci = htons(VLAN_VID_MASK); /* af fills the destination mac addr */ - u64_to_ether_addr(0xffffffffffffull, req->mask.dmac); + eth_broadcast_addr((u8 *)&req->mask.dmac); req->features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_DMAC); req->channel = pf->hw.rx_chan_base; req->intf = NIX_INTF_RX; @@ -2139,7 +2136,7 @@ int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos, vtag_req->vtag_size = VTAGSIZE_T4; vtag_req->cfg_type = 0; /* tx vlan cfg */ vtag_req->tx.cfg_vtag0 = 1; - vtag_req->tx.vtag0 = (ntohs(proto) << 16) | vlan; + vtag_req->tx.vtag0 = ((u64)ntohs(proto) << 16) | vlan; err = otx2_sync_mbox_msg(&pf->mbox); if (err) @@ -2159,7 +2156,7 @@ int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos, goto out; } - u64_to_ether_addr(0x0ull, req->mask.dmac); + eth_zero_addr((u8 *)&req->mask.dmac); idx = ((vf * OTX2_PER_VF_VLAN_FLOWS) + OTX2_VF_VLAN_TX_INDEX); req->entry = flow_cfg->entry[flow_cfg->vf_vlan_offset + idx]; req->features = BIT_ULL(NPC_DMAC); @@ -2168,7 +2165,7 @@ int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos, req->vf = vf + 1; req->op = NIX_TX_ACTIONOP_UCAST_DEFAULT; req->vtag0_def = vtag_rsp->vtag0_idx; - req->vtag0_op = 0x1; + req->vtag0_op = VTAG_INSERT; req->set_cntr = 1; err = otx2_sync_mbox_msg(&pf->mbox); @@ -2228,13 +2225,6 @@ static int otx2_get_vf_config(struct net_device *netdev, int vf, return 0; } -static netdev_features_t -otx2_features_check(struct sk_buff *skb, struct net_device *dev, - netdev_features_t features) -{ - return features; -} - static const struct net_device_ops otx2_netdev_ops = { .ndo_open = otx2_open, .ndo_stop = otx2_stop, @@ -2250,9 +2240,19 @@ static const struct net_device_ops otx2_netdev_ops = { .ndo_set_vf_mac = otx2_set_vf_mac, .ndo_set_vf_vlan = otx2_set_vf_vlan, .ndo_get_vf_config = otx2_get_vf_config, - .ndo_features_check = otx2_features_check, }; +static int otx2_wq_init(struct otx2_nic *pf) +{ + pf->otx2_wq = create_singlethread_workqueue("otx2_wq"); + if (!pf->otx2_wq) + return -ENOMEM; + + INIT_WORK(&pf->rx_mode_work, otx2_do_set_rx_mode); + INIT_WORK(&pf->reset_task, otx2_reset_task); + return 0; +} + static int otx2_check_pf_usable(struct otx2_nic *nic) { u64 rev; @@ -2442,20 +2442,27 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) NETIF_F_IPV6_CSUM | NETIF_F_RXHASH | NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6); netdev->features |= netdev->hw_features; - /* Support TSO on tag interface */ - netdev->vlan_features |= netdev->features; - netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_STAG_TX | - NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_STAG_RX; + netdev->hw_features |= NETIF_F_LOOPBACK | NETIF_F_RXALL; - netdev->features |= netdev->hw_features; + err = otx2_mcam_flow_init(pf); + if (err) + goto err_ptp_destroy; - netdev->hw_features |= NETIF_F_LOOPBACK | NETIF_F_NTUPLE | - NETIF_F_RXALL; + if (pf->flags & OTX2_FLAG_NTUPLE_SUPPORT) + netdev->hw_features |= NETIF_F_NTUPLE; - netdev->priv_flags |= IFF_UNICAST_FLT; + if (pf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT) + netdev->priv_flags |= IFF_UNICAST_FLT; + + /* Support TSO on tag interface */ + netdev->vlan_features |= netdev->features; + netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX; + if (pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT) + netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_STAG_RX; + netdev->features |= netdev->hw_features; netdev->gso_max_segs = OTX2_MAX_GSO_SEGS; netdev->watchdog_timeo = netdev->watchdog_timeo ? @@ -2467,15 +2474,13 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) netdev->min_mtu = OTX2_MIN_MTU; netdev->max_mtu = OTX2_MAX_MTU; - INIT_WORK(&pf->reset_task, otx2_reset_task); - err = register_netdev(netdev); if (err) { dev_err(dev, "Failed to register netdevice\n"); - goto err_ptp_destroy; + goto err_del_mcam_entries; } - err = otx2_mcam_flow_init(pf); + err = otx2_wq_init(pf); if (err) goto err_unreg_netdev; @@ -2495,6 +2500,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) err_unreg_netdev: unregister_netdev(netdev); +err_del_mcam_entries: + otx2_mcam_flow_del(pf); err_ptp_destroy: otx2_ptp_destroy(pf); err_detach_rsrc: @@ -2688,6 +2695,8 @@ static void otx2_remove(struct pci_dev *pdev) unregister_netdev(netdev); otx2_sriov_disable(pf->pdev); + if (pf->otx2_wq) + destroy_workqueue(pf->otx2_wq); otx2_ptp_destroy(pf); otx2_mcam_flow_del(pf); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c index 25dd373337b1..d077313971b0 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -441,13 +441,6 @@ static void otx2vf_reset_task(struct work_struct *work) rtnl_unlock(); } -static netdev_features_t -otx2_features_check(struct sk_buff *skb, struct net_device *dev, - netdev_features_t features) -{ - return features; -} - static const struct net_device_ops otx2vf_netdev_ops = { .ndo_open = otx2vf_open, .ndo_stop = otx2vf_stop, @@ -456,7 +449,6 @@ static const struct net_device_ops otx2vf_netdev_ops = { .ndo_change_mtu = otx2vf_change_mtu, .ndo_get_stats64 = otx2_get_stats64, .ndo_tx_timeout = otx2_tx_timeout, - .ndo_features_check = otx2_features_check, }; static int otx2vf_realloc_msix_vectors(struct otx2_nic *vf) -- 2.14.5
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#9404): https://lists.yoctoproject.org/g/linux-yocto/message/9404 Mute This Topic: https://lists.yoctoproject.org/mt/79974877/21656 Group Owner: [email protected] Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
