diff options
author | Rakesh Babu <rsaladi2@marvell.com> | 2021-08-17 10:14:47 +0530 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-08-17 10:06:33 +0100 |
commit | 3cffaed2136cd66ed4647ad7d718011c263f54af (patch) | |
tree | 6abb808b6994d7ec8f6c8a840bdb1c654e1ec6ba | |
parent | 0b3834aeaf473b2238b83084629d33b564a0114e (diff) |
octeontx2-pf: Ntuple filters support for VF netdev
Add packet flow classification support for both LMAC mapped virtual
functions and loopback VFs. This patch adds supports for ntuple
offload feature.
Signed-off-by: Rakesh Babu <rsaladi2@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
5 files changed, 98 insertions, 60 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c index 5e77bfeef0e5..9bde1bb7e148 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -995,13 +995,11 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target, struct npc_mcam *mcam = &rvu->hw->mcam; struct rvu_npc_mcam_rule dummy = { 0 }; struct rvu_npc_mcam_rule *rule; - bool new = false, msg_from_vf; u16 owner = req->hdr.pcifunc; struct msg_rsp write_rsp; struct mcam_entry *entry; int entry_index, err; - - msg_from_vf = !!(owner & RVU_PFVF_FUNC_MASK); + bool new = false; installed_features = req->features; features = req->features; @@ -1027,7 +1025,7 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target, } /* update mcam entry with default unicast rule attributes */ - if (def_ucast_rule && (msg_from_vf || (req->default_rule && req->append))) { + if (def_ucast_rule && (req->default_rule && req->append)) { missing_features = (def_ucast_rule->features ^ features) & def_ucast_rule->features; if (missing_features) @@ -1130,6 +1128,7 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu, struct npc_install_flow_rsp *rsp) { bool from_vf = !!(req->hdr.pcifunc & RVU_PFVF_FUNC_MASK); + struct rvu_switch *rswitch = &rvu->rswitch; int blkaddr, nixlf, err; struct rvu_pfvf *pfvf; bool pf_set_vfs_mac = false; @@ -1221,15 +1220,12 @@ int rvu_mbox_handler_npc_install_flow(struct rvu *rvu, return 0; } - /* If message is from VF then its flow should not overlap with - * reserved unicast flow. - */ - if (from_vf && pfvf->def_ucast_rule && is_npc_intf_rx(req->intf) && - pfvf->def_ucast_rule->features & req->features) - return NPC_FLOW_VF_OVERLAP; + mutex_lock(&rswitch->switch_lock); + err = npc_install_flow(rvu, blkaddr, target, nixlf, pfvf, + req, rsp, enable, pf_set_vfs_mac); + mutex_unlock(&rswitch->switch_lock); - return npc_install_flow(rvu, blkaddr, target, nixlf, pfvf, req, rsp, - enable, pf_set_vfs_mac); + return err; } static int npc_delete_flow(struct rvu *rvu, struct rvu_npc_mcam_rule *rule, diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h index 2a80cdc848e5..4f95a6923c8d 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -710,6 +710,11 @@ MBOX_UP_CGX_MESSAGES #define RVU_PFVF_FUNC_SHIFT 0 #define RVU_PFVF_FUNC_MASK 0x3FF +static inline bool is_otx2_vf(u16 pcifunc) +{ + return !!(pcifunc & RVU_PFVF_FUNC_MASK); +} + static inline int rvu_get_pf(u16 pcifunc) { return (pcifunc >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK; @@ -815,6 +820,7 @@ int otx2_set_real_num_queues(struct net_device *netdev, int tx_queues, int rx_queues); /* MCAM filter related APIs */ int otx2_mcam_flow_init(struct otx2_nic *pf); +int otx2vf_mcam_flow_init(struct otx2_nic *pfvf); int otx2_alloc_mcam_entries(struct otx2_nic *pfvf); void otx2_mcam_flow_del(struct otx2_nic *pf); int otx2_destroy_ntuple_flows(struct otx2_nic *pf); @@ -828,6 +834,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, int otx2_remove_flow(struct otx2_nic *pfvf, u32 location); int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp, struct npc_install_flow_req *req); +int otx2_get_maxflows(struct otx2_flow_config *flow_cfg); void otx2_rss_ctx_flow_del(struct otx2_nic *pfvf, int ctx_id); int otx2_del_macfilter(struct net_device *netdev, const u8 *mac); int otx2_add_macfilter(struct net_device *netdev, const u8 *mac); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c index b906a0eb6e0d..620da08db317 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c @@ -645,6 +645,7 @@ static int otx2_set_rss_hash_opts(struct otx2_nic *pfvf, static int otx2_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc, u32 *rules) { + bool ntuple = !!(dev->features & NETIF_F_NTUPLE); struct otx2_nic *pfvf = netdev_priv(dev); int ret = -EOPNOTSUPP; @@ -654,14 +655,18 @@ static int otx2_get_rxnfc(struct net_device *dev, ret = 0; break; case ETHTOOL_GRXCLSRLCNT: - nfc->rule_cnt = pfvf->flow_cfg->nr_flows; - ret = 0; + if (netif_running(dev) && ntuple) { + nfc->rule_cnt = pfvf->flow_cfg->nr_flows; + ret = 0; + } break; case ETHTOOL_GRXCLSRULE: - ret = otx2_get_flow(pfvf, nfc, nfc->fs.location); + if (netif_running(dev) && ntuple) + ret = otx2_get_flow(pfvf, nfc, nfc->fs.location); break; case ETHTOOL_GRXCLSRLALL: - ret = otx2_get_all_flows(pfvf, nfc, rules); + if (netif_running(dev) && ntuple) + ret = otx2_get_all_flows(pfvf, nfc, rules); break; case ETHTOOL_GRXFH: return otx2_get_rss_hash_opts(pfvf, nfc); @@ -696,41 +701,6 @@ static int otx2_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc) return ret; } -static int otx2vf_get_rxnfc(struct net_device *dev, - struct ethtool_rxnfc *nfc, u32 *rules) -{ - struct otx2_nic *pfvf = netdev_priv(dev); - int ret = -EOPNOTSUPP; - - switch (nfc->cmd) { - case ETHTOOL_GRXRINGS: - nfc->data = pfvf->hw.rx_queues; - ret = 0; - break; - case ETHTOOL_GRXFH: - return otx2_get_rss_hash_opts(pfvf, nfc); - default: - break; - } - return ret; -} - -static int otx2vf_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc) -{ - struct otx2_nic *pfvf = netdev_priv(dev); - int ret = -EOPNOTSUPP; - - switch (nfc->cmd) { - case ETHTOOL_SRXFH: - ret = otx2_set_rss_hash_opts(pfvf, nfc); - break; - default: - break; - } - - return ret; -} - static u32 otx2_get_rxfh_key_size(struct net_device *netdev) { struct otx2_nic *pfvf = netdev_priv(netdev); @@ -1357,8 +1327,8 @@ static const struct ethtool_ops otx2vf_ethtool_ops = { .get_sset_count = otx2vf_get_sset_count, .set_channels = otx2_set_channels, .get_channels = otx2_get_channels, - .get_rxnfc = otx2vf_get_rxnfc, - .set_rxnfc = otx2vf_set_rxnfc, + .get_rxnfc = otx2_get_rxnfc, + .set_rxnfc = otx2_set_rxnfc, .get_rxfh_key_size = otx2_get_rxfh_key_size, .get_rxfh_indir_size = otx2_get_rxfh_indir_size, .get_rxfh = otx2_get_rxfh, diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 4d9de525802d..a0c4b737283a 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c @@ -92,8 +92,14 @@ static int otx2_alloc_ntuple_mcam_entries(struct otx2_nic *pfvf, u16 count) req->contig = false; req->count = (count - allocated) > NPC_MAX_NONCONTIG_ENTRIES ? NPC_MAX_NONCONTIG_ENTRIES : count - allocated; - req->priority = NPC_MCAM_HIGHER_PRIO; - req->ref_entry = flow_cfg->def_ent[0]; + + /* Allocate higher priority entries for PFs, so that VF's entries + * will be on top of PF. + */ + if (!is_otx2_vf(pfvf->pcifunc)) { + req->priority = NPC_MCAM_HIGHER_PRIO; + req->ref_entry = flow_cfg->def_ent[0]; + } /* Send message to AF */ if (otx2_sync_mbox_msg(&pfvf->mbox)) @@ -121,11 +127,13 @@ exit: flow_cfg->ntuple_max_flows = allocated; flow_cfg->tc_max_flows = allocated; + pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC; + pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT; + if (allocated != count) netdev_info(pfvf->netdev, - "Unable to allocate %d MCAM entries for ntuple, got %d\n", + "Unable to allocate %d MCAM entries, got only %d\n", count, allocated); - return allocated; } @@ -195,12 +203,34 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf) return 0; } - pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT; pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT; return 0; } +int otx2vf_mcam_flow_init(struct otx2_nic *pfvf) +{ + struct otx2_flow_config *flow_cfg; + int count; + + pfvf->flow_cfg = devm_kzalloc(pfvf->dev, + sizeof(struct otx2_flow_config), + GFP_KERNEL); + if (!pfvf->flow_cfg) + return -ENOMEM; + + flow_cfg = pfvf->flow_cfg; + INIT_LIST_HEAD(&flow_cfg->flow_list); + flow_cfg->ntuple_max_flows = 0; + + count = otx2_alloc_ntuple_mcam_entries(pfvf, OTX2_DEFAULT_FLOWCOUNT); + if (count <= 0) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL(otx2vf_mcam_flow_init); + int otx2_mcam_flow_init(struct otx2_nic *pf) { int err; @@ -248,6 +278,7 @@ void otx2_mcam_flow_del(struct otx2_nic *pf) { otx2_destroy_mcam_flows(pf); } +EXPORT_SYMBOL(otx2_mcam_flow_del); /* On success adds mcam entry * On failure enable promisous mode @@ -379,8 +410,11 @@ static void otx2_add_flow_to_list(struct otx2_nic *pfvf, struct otx2_flow *flow) list_add(&flow->list, head); } -static int otx2_get_maxflows(struct otx2_flow_config *flow_cfg) +int otx2_get_maxflows(struct otx2_flow_config *flow_cfg) { + if (!flow_cfg) + return 0; + if (flow_cfg->nr_flows == flow_cfg->ntuple_max_flows || bitmap_weight(&flow_cfg->dmacflt_bmap, flow_cfg->dmacflt_max_flows)) @@ -388,6 +422,7 @@ static int otx2_get_maxflows(struct otx2_flow_config *flow_cfg) else return flow_cfg->ntuple_max_flows; } +EXPORT_SYMBOL(otx2_get_maxflows); int otx2_get_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc, u32 location) @@ -732,7 +767,7 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp, ether_addr_copy(pmask->dmac, eth_mask->h_dest); req->features |= BIT_ULL(NPC_DMAC); } - if (eth_mask->h_proto) { + if (eth_hdr->h_proto) { memcpy(&pkt->etype, ð_hdr->h_proto, sizeof(pkt->etype)); memcpy(&pmask->etype, ð_mask->h_proto, @@ -996,6 +1031,8 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) } if (err) { + if (err == MBOX_MSG_INVALID) + err = -EINVAL; if (new) kfree(flow); return err; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c index 722c601fa98f..83a76d2c2d3f 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -464,6 +464,28 @@ static void otx2vf_reset_task(struct work_struct *work) rtnl_unlock(); } +static int otx2vf_set_features(struct net_device *netdev, + netdev_features_t features) +{ + netdev_features_t changed = features ^ netdev->features; + bool ntuple_enabled = !!(features & NETIF_F_NTUPLE); + struct otx2_nic *vf = netdev_priv(netdev); + + if (changed & NETIF_F_NTUPLE) { + if (!ntuple_enabled) { + otx2_mcam_flow_del(vf); + return 0; + } + + if (!otx2_get_maxflows(vf->flow_cfg)) { + netdev_err(netdev, + "Can't enable NTUPLE, MCAM entries not allocated\n"); + return -EINVAL; + } + } + return 0; +} + static const struct net_device_ops otx2vf_netdev_ops = { .ndo_open = otx2vf_open, .ndo_stop = otx2vf_stop, @@ -471,6 +493,7 @@ static const struct net_device_ops otx2vf_netdev_ops = { .ndo_set_rx_mode = otx2vf_set_rx_mode, .ndo_set_mac_address = otx2_set_mac_address, .ndo_change_mtu = otx2vf_change_mtu, + .ndo_set_features = otx2vf_set_features, .ndo_get_stats64 = otx2_get_stats64, .ndo_tx_timeout = otx2_tx_timeout, }; @@ -627,6 +650,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) NETIF_F_HW_VLAN_STAG_TX; netdev->features |= netdev->hw_features; + netdev->hw_features |= NETIF_F_NTUPLE; netdev->hw_features |= NETIF_F_RXALL; netdev->gso_max_segs = OTX2_MAX_GSO_SEGS; @@ -659,6 +683,10 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id) otx2vf_set_ethtool_ops(netdev); + err = otx2vf_mcam_flow_init(vf); + if (err) + goto err_unreg_netdev; + /* Enable pause frames by default */ vf->flags |= OTX2_FLAG_RX_PAUSE_ENABLED; vf->flags |= OTX2_FLAG_TX_PAUSE_ENABLED; |