1521 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Marvell RVU Ethernet driver3 *4 * Copyright (C) 2020 Marvell.5 *6 */7 8#include <net/ipv6.h>9#include <linux/sort.h>10 11#include "otx2_common.h"12 13#define OTX2_DEFAULT_ACTION 0x114 15struct otx2_flow {16 struct ethtool_rx_flow_spec flow_spec;17 struct list_head list;18 u32 location;19 u32 entry;20 bool is_vf;21 u8 rss_ctx_id;22#define DMAC_FILTER_RULE BIT(0)23#define PFC_FLOWCTRL_RULE BIT(1)24 u16 rule_type;25 int vf;26};27 28enum dmac_req {29 DMAC_ADDR_UPDATE,30 DMAC_ADDR_DEL31};32 33static void otx2_clear_ntuple_flow_info(struct otx2_nic *pfvf, struct otx2_flow_config *flow_cfg)34{35 devm_kfree(pfvf->dev, flow_cfg->flow_ent);36 flow_cfg->flow_ent = NULL;37 flow_cfg->max_flows = 0;38}39 40static int otx2_free_ntuple_mcam_entries(struct otx2_nic *pfvf)41{42 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;43 struct npc_mcam_free_entry_req *req;44 int ent, err;45 46 if (!flow_cfg->max_flows)47 return 0;48 49 mutex_lock(&pfvf->mbox.lock);50 for (ent = 0; ent < flow_cfg->max_flows; ent++) {51 req = otx2_mbox_alloc_msg_npc_mcam_free_entry(&pfvf->mbox);52 if (!req)53 break;54 55 req->entry = flow_cfg->flow_ent[ent];56 57 /* Send message to AF to free MCAM entries */58 err = otx2_sync_mbox_msg(&pfvf->mbox);59 if (err)60 break;61 }62 mutex_unlock(&pfvf->mbox.lock);63 otx2_clear_ntuple_flow_info(pfvf, flow_cfg);64 return 0;65}66 67static int mcam_entry_cmp(const void *a, const void *b)68{69 return *(u16 *)a - *(u16 *)b;70}71 72int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count)73{74 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;75 struct npc_mcam_alloc_entry_req *req;76 struct npc_mcam_alloc_entry_rsp *rsp;77 int ent, allocated = 0;78 79 /* Free current ones and allocate new ones with requested count */80 otx2_free_ntuple_mcam_entries(pfvf);81 82 if (!count)83 return 0;84 85 flow_cfg->flow_ent = devm_kmalloc_array(pfvf->dev, count,86 sizeof(u16), GFP_KERNEL);87 if (!flow_cfg->flow_ent) {88 netdev_err(pfvf->netdev,89 "%s: Unable to allocate memory for flow entries\n",90 __func__);91 return -ENOMEM;92 }93 94 mutex_lock(&pfvf->mbox.lock);95 96 /* In a single request a max of NPC_MAX_NONCONTIG_ENTRIES MCAM entries97 * can only be allocated.98 */99 while (allocated < count) {100 req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&pfvf->mbox);101 if (!req)102 goto exit;103 104 req->contig = false;105 req->count = (count - allocated) > NPC_MAX_NONCONTIG_ENTRIES ?106 NPC_MAX_NONCONTIG_ENTRIES : count - allocated;107 108 /* Allocate higher priority entries for PFs, so that VF's entries109 * will be on top of PF.110 */111 if (!is_otx2_vf(pfvf->pcifunc)) {112 req->priority = NPC_MCAM_HIGHER_PRIO;113 req->ref_entry = flow_cfg->def_ent[0];114 }115 116 /* Send message to AF */117 if (otx2_sync_mbox_msg(&pfvf->mbox))118 goto exit;119 120 rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp121 (&pfvf->mbox.mbox, 0, &req->hdr);122 123 for (ent = 0; ent < rsp->count; ent++)124 flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent];125 126 allocated += rsp->count;127 128 /* If this request is not fulfilled, no need to send129 * further requests.130 */131 if (rsp->count != req->count)132 break;133 }134 135 /* Multiple MCAM entry alloc requests could result in non-sequential136 * MCAM entries in the flow_ent[] array. Sort them in an ascending order,137 * otherwise user installed ntuple filter index and MCAM entry index will138 * not be in sync.139 */140 if (allocated)141 sort(&flow_cfg->flow_ent[0], allocated,142 sizeof(flow_cfg->flow_ent[0]), mcam_entry_cmp, NULL);143 144exit:145 mutex_unlock(&pfvf->mbox.lock);146 147 flow_cfg->max_flows = allocated;148 149 if (allocated) {150 pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;151 pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;152 }153 154 if (allocated != count)155 netdev_info(pfvf->netdev,156 "Unable to allocate %d MCAM entries, got only %d\n",157 count, allocated);158 return allocated;159}160EXPORT_SYMBOL(otx2_alloc_mcam_entries);161 162int otx2_mcam_entry_init(struct otx2_nic *pfvf)163{164 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;165 struct npc_get_field_status_req *freq;166 struct npc_get_field_status_rsp *frsp;167 struct npc_mcam_alloc_entry_req *req;168 struct npc_mcam_alloc_entry_rsp *rsp;169 int vf_vlan_max_flows;170 int ent, count;171 172 vf_vlan_max_flows = pfvf->total_vfs * OTX2_PER_VF_VLAN_FLOWS;173 count = flow_cfg->ucast_flt_cnt +174 OTX2_MAX_VLAN_FLOWS + vf_vlan_max_flows;175 176 flow_cfg->def_ent = devm_kmalloc_array(pfvf->dev, count,177 sizeof(u16), GFP_KERNEL);178 if (!flow_cfg->def_ent)179 return -ENOMEM;180 181 mutex_lock(&pfvf->mbox.lock);182 183 req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&pfvf->mbox);184 if (!req) {185 mutex_unlock(&pfvf->mbox.lock);186 return -ENOMEM;187 }188 189 req->contig = false;190 req->count = count;191 192 /* Send message to AF */193 if (otx2_sync_mbox_msg(&pfvf->mbox)) {194 mutex_unlock(&pfvf->mbox.lock);195 return -EINVAL;196 }197 198 rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp199 (&pfvf->mbox.mbox, 0, &req->hdr);200 201 if (rsp->count != req->count) {202 netdev_info(pfvf->netdev,203 "Unable to allocate MCAM entries for ucast, vlan and vf_vlan\n");204 mutex_unlock(&pfvf->mbox.lock);205 devm_kfree(pfvf->dev, flow_cfg->def_ent);206 return 0;207 }208 209 for (ent = 0; ent < rsp->count; ent++)210 flow_cfg->def_ent[ent] = rsp->entry_list[ent];211 212 flow_cfg->vf_vlan_offset = 0;213 flow_cfg->unicast_offset = vf_vlan_max_flows;214 flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset +215 flow_cfg->ucast_flt_cnt;216 pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT;217 218 /* Check if NPC_DMAC field is supported219 * by the mkex profile before setting VLAN support flag.220 */221 freq = otx2_mbox_alloc_msg_npc_get_field_status(&pfvf->mbox);222 if (!freq) {223 mutex_unlock(&pfvf->mbox.lock);224 return -ENOMEM;225 }226 227 freq->field = NPC_DMAC;228 if (otx2_sync_mbox_msg(&pfvf->mbox)) {229 mutex_unlock(&pfvf->mbox.lock);230 return -EINVAL;231 }232 233 frsp = (struct npc_get_field_status_rsp *)otx2_mbox_get_rsp234 (&pfvf->mbox.mbox, 0, &freq->hdr);235 236 if (frsp->enable) {237 pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;238 pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT;239 }240 241 pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;242 mutex_unlock(&pfvf->mbox.lock);243 244 /* Allocate entries for Ntuple filters */245 count = otx2_alloc_mcam_entries(pfvf, OTX2_DEFAULT_FLOWCOUNT);246 if (count <= 0) {247 otx2_clear_ntuple_flow_info(pfvf, flow_cfg);248 return 0;249 }250 251 pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;252 253 refcount_set(&flow_cfg->mark_flows, 1);254 return 0;255}256EXPORT_SYMBOL(otx2_mcam_entry_init);257 258/* TODO : revisit on size */259#define OTX2_DMAC_FLTR_BITMAP_SZ (4 * 2048 + 32)260 261int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)262{263 struct otx2_flow_config *flow_cfg;264 265 pfvf->flow_cfg = devm_kzalloc(pfvf->dev,266 sizeof(struct otx2_flow_config),267 GFP_KERNEL);268 if (!pfvf->flow_cfg)269 return -ENOMEM;270 271 pfvf->flow_cfg->dmacflt_bmap = devm_kcalloc(pfvf->dev,272 BITS_TO_LONGS(OTX2_DMAC_FLTR_BITMAP_SZ),273 sizeof(long), GFP_KERNEL);274 if (!pfvf->flow_cfg->dmacflt_bmap)275 return -ENOMEM;276 277 flow_cfg = pfvf->flow_cfg;278 INIT_LIST_HEAD(&flow_cfg->flow_list);279 INIT_LIST_HEAD(&flow_cfg->flow_list_tc);280 flow_cfg->max_flows = 0;281 282 return 0;283}284EXPORT_SYMBOL(otx2vf_mcam_flow_init);285 286int otx2_mcam_flow_init(struct otx2_nic *pf)287{288 int err;289 290 pf->flow_cfg = devm_kzalloc(pf->dev, sizeof(struct otx2_flow_config),291 GFP_KERNEL);292 if (!pf->flow_cfg)293 return -ENOMEM;294 295 pf->flow_cfg->dmacflt_bmap = devm_kcalloc(pf->dev,296 BITS_TO_LONGS(OTX2_DMAC_FLTR_BITMAP_SZ),297 sizeof(long), GFP_KERNEL);298 if (!pf->flow_cfg->dmacflt_bmap)299 return -ENOMEM;300 301 INIT_LIST_HEAD(&pf->flow_cfg->flow_list);302 INIT_LIST_HEAD(&pf->flow_cfg->flow_list_tc);303 304 pf->flow_cfg->ucast_flt_cnt = OTX2_DEFAULT_UNICAST_FLOWS;305 306 /* Allocate bare minimum number of MCAM entries needed for307 * unicast and ntuple filters.308 */309 err = otx2_mcam_entry_init(pf);310 if (err)311 return err;312 313 /* Check if MCAM entries are allocate or not */314 if (!(pf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT))315 return 0;316 317 pf->mac_table = devm_kzalloc(pf->dev, sizeof(struct otx2_mac_table)318 * pf->flow_cfg->ucast_flt_cnt, GFP_KERNEL);319 if (!pf->mac_table)320 return -ENOMEM;321 322 otx2_dmacflt_get_max_cnt(pf);323 324 /* DMAC filters are not allocated */325 if (!pf->flow_cfg->dmacflt_max_flows)326 return 0;327 328 pf->flow_cfg->bmap_to_dmacindex =329 devm_kzalloc(pf->dev, sizeof(u32) *330 pf->flow_cfg->dmacflt_max_flows,331 GFP_KERNEL);332 333 if (!pf->flow_cfg->bmap_to_dmacindex)334 return -ENOMEM;335 336 pf->flags |= OTX2_FLAG_DMACFLTR_SUPPORT;337 338 return 0;339}340 341void otx2_mcam_flow_del(struct otx2_nic *pf)342{343 otx2_destroy_mcam_flows(pf);344}345EXPORT_SYMBOL(otx2_mcam_flow_del);346 347/* On success adds mcam entry348 * On failure enable promisous mode349 */350static int otx2_do_add_macfilter(struct otx2_nic *pf, const u8 *mac)351{352 struct otx2_flow_config *flow_cfg = pf->flow_cfg;353 struct npc_install_flow_req *req;354 int err, i;355 356 if (!(pf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT))357 return -ENOMEM;358 359 /* dont have free mcam entries or uc list is greater than alloted */360 if (netdev_uc_count(pf->netdev) > pf->flow_cfg->ucast_flt_cnt)361 return -ENOMEM;362 363 mutex_lock(&pf->mbox.lock);364 req = otx2_mbox_alloc_msg_npc_install_flow(&pf->mbox);365 if (!req) {366 mutex_unlock(&pf->mbox.lock);367 return -ENOMEM;368 }369 370 /* unicast offset starts with 32 0..31 for ntuple */371 for (i = 0; i < pf->flow_cfg->ucast_flt_cnt; i++) {372 if (pf->mac_table[i].inuse)373 continue;374 ether_addr_copy(pf->mac_table[i].addr, mac);375 pf->mac_table[i].inuse = true;376 pf->mac_table[i].mcam_entry =377 flow_cfg->def_ent[i + flow_cfg->unicast_offset];378 req->entry = pf->mac_table[i].mcam_entry;379 break;380 }381 382 ether_addr_copy(req->packet.dmac, mac);383 eth_broadcast_addr((u8 *)&req->mask.dmac);384 req->features = BIT_ULL(NPC_DMAC);385 req->channel = pf->hw.rx_chan_base;386 req->intf = NIX_INTF_RX;387 req->op = NIX_RX_ACTION_DEFAULT;388 req->set_cntr = 1;389 390 err = otx2_sync_mbox_msg(&pf->mbox);391 mutex_unlock(&pf->mbox.lock);392 393 return err;394}395 396int otx2_add_macfilter(struct net_device *netdev, const u8 *mac)397{398 struct otx2_nic *pf = netdev_priv(netdev);399 400 if (!bitmap_empty(pf->flow_cfg->dmacflt_bmap,401 pf->flow_cfg->dmacflt_max_flows))402 netdev_warn(netdev,403 "Add %pM to CGX/RPM DMAC filters list as well\n",404 mac);405 406 return otx2_do_add_macfilter(pf, mac);407}408 409static bool otx2_get_mcamentry_for_mac(struct otx2_nic *pf, const u8 *mac,410 int *mcam_entry)411{412 int i;413 414 for (i = 0; i < pf->flow_cfg->ucast_flt_cnt; i++) {415 if (!pf->mac_table[i].inuse)416 continue;417 418 if (ether_addr_equal(pf->mac_table[i].addr, mac)) {419 *mcam_entry = pf->mac_table[i].mcam_entry;420 pf->mac_table[i].inuse = false;421 return true;422 }423 }424 return false;425}426 427int otx2_del_macfilter(struct net_device *netdev, const u8 *mac)428{429 struct otx2_nic *pf = netdev_priv(netdev);430 struct npc_delete_flow_req *req;431 int err, mcam_entry;432 433 /* check does mcam entry exists for given mac */434 if (!otx2_get_mcamentry_for_mac(pf, mac, &mcam_entry))435 return 0;436 437 mutex_lock(&pf->mbox.lock);438 req = otx2_mbox_alloc_msg_npc_delete_flow(&pf->mbox);439 if (!req) {440 mutex_unlock(&pf->mbox.lock);441 return -ENOMEM;442 }443 req->entry = mcam_entry;444 /* Send message to AF */445 err = otx2_sync_mbox_msg(&pf->mbox);446 mutex_unlock(&pf->mbox.lock);447 448 return err;449}450 451static struct otx2_flow *otx2_find_flow(struct otx2_nic *pfvf, u32 location)452{453 struct otx2_flow *iter;454 455 list_for_each_entry(iter, &pfvf->flow_cfg->flow_list, list) {456 if (iter->location == location)457 return iter;458 }459 460 return NULL;461}462 463static void otx2_add_flow_to_list(struct otx2_nic *pfvf, struct otx2_flow *flow)464{465 struct list_head *head = &pfvf->flow_cfg->flow_list;466 struct otx2_flow *iter;467 468 list_for_each_entry(iter, &pfvf->flow_cfg->flow_list, list) {469 if (iter->location > flow->location)470 break;471 head = &iter->list;472 }473 474 list_add(&flow->list, head);475}476 477int otx2_get_maxflows(struct otx2_flow_config *flow_cfg)478{479 if (!flow_cfg)480 return 0;481 482 if (flow_cfg->nr_flows == flow_cfg->max_flows ||483 !bitmap_empty(flow_cfg->dmacflt_bmap,484 flow_cfg->dmacflt_max_flows))485 return flow_cfg->max_flows + flow_cfg->dmacflt_max_flows;486 else487 return flow_cfg->max_flows;488}489EXPORT_SYMBOL(otx2_get_maxflows);490 491int otx2_get_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc,492 u32 location)493{494 struct otx2_flow *iter;495 496 if (location >= otx2_get_maxflows(pfvf->flow_cfg))497 return -EINVAL;498 499 list_for_each_entry(iter, &pfvf->flow_cfg->flow_list, list) {500 if (iter->location == location) {501 nfc->fs = iter->flow_spec;502 nfc->rss_context = iter->rss_ctx_id;503 return 0;504 }505 }506 507 return -ENOENT;508}509 510int otx2_get_all_flows(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc,511 u32 *rule_locs)512{513 u32 rule_cnt = nfc->rule_cnt;514 u32 location = 0;515 int idx = 0;516 int err = 0;517 518 nfc->data = otx2_get_maxflows(pfvf->flow_cfg);519 while ((!err || err == -ENOENT) && idx < rule_cnt) {520 err = otx2_get_flow(pfvf, nfc, location);521 if (!err)522 rule_locs[idx++] = location;523 location++;524 }525 nfc->rule_cnt = rule_cnt;526 527 return err;528}529 530static int otx2_prepare_ipv4_flow(struct ethtool_rx_flow_spec *fsp,531 struct npc_install_flow_req *req,532 u32 flow_type)533{534 struct ethtool_usrip4_spec *ipv4_usr_mask = &fsp->m_u.usr_ip4_spec;535 struct ethtool_usrip4_spec *ipv4_usr_hdr = &fsp->h_u.usr_ip4_spec;536 struct ethtool_tcpip4_spec *ipv4_l4_mask = &fsp->m_u.tcp_ip4_spec;537 struct ethtool_tcpip4_spec *ipv4_l4_hdr = &fsp->h_u.tcp_ip4_spec;538 struct ethtool_ah_espip4_spec *ah_esp_hdr = &fsp->h_u.ah_ip4_spec;539 struct ethtool_ah_espip4_spec *ah_esp_mask = &fsp->m_u.ah_ip4_spec;540 struct flow_msg *pmask = &req->mask;541 struct flow_msg *pkt = &req->packet;542 543 switch (flow_type) {544 case IP_USER_FLOW:545 if (ipv4_usr_mask->ip4src) {546 memcpy(&pkt->ip4src, &ipv4_usr_hdr->ip4src,547 sizeof(pkt->ip4src));548 memcpy(&pmask->ip4src, &ipv4_usr_mask->ip4src,549 sizeof(pmask->ip4src));550 req->features |= BIT_ULL(NPC_SIP_IPV4);551 }552 if (ipv4_usr_mask->ip4dst) {553 memcpy(&pkt->ip4dst, &ipv4_usr_hdr->ip4dst,554 sizeof(pkt->ip4dst));555 memcpy(&pmask->ip4dst, &ipv4_usr_mask->ip4dst,556 sizeof(pmask->ip4dst));557 req->features |= BIT_ULL(NPC_DIP_IPV4);558 }559 if (ipv4_usr_mask->tos) {560 pkt->tos = ipv4_usr_hdr->tos;561 pmask->tos = ipv4_usr_mask->tos;562 req->features |= BIT_ULL(NPC_TOS);563 }564 if (ipv4_usr_mask->proto) {565 switch (ipv4_usr_hdr->proto) {566 case IPPROTO_ICMP:567 req->features |= BIT_ULL(NPC_IPPROTO_ICMP);568 break;569 case IPPROTO_TCP:570 req->features |= BIT_ULL(NPC_IPPROTO_TCP);571 break;572 case IPPROTO_UDP:573 req->features |= BIT_ULL(NPC_IPPROTO_UDP);574 break;575 case IPPROTO_SCTP:576 req->features |= BIT_ULL(NPC_IPPROTO_SCTP);577 break;578 case IPPROTO_AH:579 req->features |= BIT_ULL(NPC_IPPROTO_AH);580 break;581 case IPPROTO_ESP:582 req->features |= BIT_ULL(NPC_IPPROTO_ESP);583 break;584 default:585 return -EOPNOTSUPP;586 }587 }588 pkt->etype = cpu_to_be16(ETH_P_IP);589 pmask->etype = cpu_to_be16(0xFFFF);590 req->features |= BIT_ULL(NPC_ETYPE);591 break;592 case TCP_V4_FLOW:593 case UDP_V4_FLOW:594 case SCTP_V4_FLOW:595 pkt->etype = cpu_to_be16(ETH_P_IP);596 pmask->etype = cpu_to_be16(0xFFFF);597 req->features |= BIT_ULL(NPC_ETYPE);598 if (ipv4_l4_mask->ip4src) {599 memcpy(&pkt->ip4src, &ipv4_l4_hdr->ip4src,600 sizeof(pkt->ip4src));601 memcpy(&pmask->ip4src, &ipv4_l4_mask->ip4src,602 sizeof(pmask->ip4src));603 req->features |= BIT_ULL(NPC_SIP_IPV4);604 }605 if (ipv4_l4_mask->ip4dst) {606 memcpy(&pkt->ip4dst, &ipv4_l4_hdr->ip4dst,607 sizeof(pkt->ip4dst));608 memcpy(&pmask->ip4dst, &ipv4_l4_mask->ip4dst,609 sizeof(pmask->ip4dst));610 req->features |= BIT_ULL(NPC_DIP_IPV4);611 }612 if (ipv4_l4_mask->tos) {613 pkt->tos = ipv4_l4_hdr->tos;614 pmask->tos = ipv4_l4_mask->tos;615 req->features |= BIT_ULL(NPC_TOS);616 }617 if (ipv4_l4_mask->psrc) {618 memcpy(&pkt->sport, &ipv4_l4_hdr->psrc,619 sizeof(pkt->sport));620 memcpy(&pmask->sport, &ipv4_l4_mask->psrc,621 sizeof(pmask->sport));622 if (flow_type == UDP_V4_FLOW)623 req->features |= BIT_ULL(NPC_SPORT_UDP);624 else if (flow_type == TCP_V4_FLOW)625 req->features |= BIT_ULL(NPC_SPORT_TCP);626 else627 req->features |= BIT_ULL(NPC_SPORT_SCTP);628 }629 if (ipv4_l4_mask->pdst) {630 memcpy(&pkt->dport, &ipv4_l4_hdr->pdst,631 sizeof(pkt->dport));632 memcpy(&pmask->dport, &ipv4_l4_mask->pdst,633 sizeof(pmask->dport));634 if (flow_type == UDP_V4_FLOW)635 req->features |= BIT_ULL(NPC_DPORT_UDP);636 else if (flow_type == TCP_V4_FLOW)637 req->features |= BIT_ULL(NPC_DPORT_TCP);638 else639 req->features |= BIT_ULL(NPC_DPORT_SCTP);640 }641 if (flow_type == UDP_V4_FLOW)642 req->features |= BIT_ULL(NPC_IPPROTO_UDP);643 else if (flow_type == TCP_V4_FLOW)644 req->features |= BIT_ULL(NPC_IPPROTO_TCP);645 else646 req->features |= BIT_ULL(NPC_IPPROTO_SCTP);647 break;648 case AH_V4_FLOW:649 case ESP_V4_FLOW:650 pkt->etype = cpu_to_be16(ETH_P_IP);651 pmask->etype = cpu_to_be16(0xFFFF);652 req->features |= BIT_ULL(NPC_ETYPE);653 if (ah_esp_mask->ip4src) {654 memcpy(&pkt->ip4src, &ah_esp_hdr->ip4src,655 sizeof(pkt->ip4src));656 memcpy(&pmask->ip4src, &ah_esp_mask->ip4src,657 sizeof(pmask->ip4src));658 req->features |= BIT_ULL(NPC_SIP_IPV4);659 }660 if (ah_esp_mask->ip4dst) {661 memcpy(&pkt->ip4dst, &ah_esp_hdr->ip4dst,662 sizeof(pkt->ip4dst));663 memcpy(&pmask->ip4dst, &ah_esp_mask->ip4dst,664 sizeof(pmask->ip4dst));665 req->features |= BIT_ULL(NPC_DIP_IPV4);666 }667 if (ah_esp_mask->tos) {668 pkt->tos = ah_esp_hdr->tos;669 pmask->tos = ah_esp_mask->tos;670 req->features |= BIT_ULL(NPC_TOS);671 }672 673 /* NPC profile doesn't extract AH/ESP header fields */674 if (ah_esp_mask->spi & ah_esp_hdr->spi)675 return -EOPNOTSUPP;676 677 if (flow_type == AH_V4_FLOW)678 req->features |= BIT_ULL(NPC_IPPROTO_AH);679 else680 req->features |= BIT_ULL(NPC_IPPROTO_ESP);681 break;682 default:683 break;684 }685 686 return 0;687}688 689static int otx2_prepare_ipv6_flow(struct ethtool_rx_flow_spec *fsp,690 struct npc_install_flow_req *req,691 u32 flow_type)692{693 struct ethtool_usrip6_spec *ipv6_usr_mask = &fsp->m_u.usr_ip6_spec;694 struct ethtool_usrip6_spec *ipv6_usr_hdr = &fsp->h_u.usr_ip6_spec;695 struct ethtool_tcpip6_spec *ipv6_l4_mask = &fsp->m_u.tcp_ip6_spec;696 struct ethtool_tcpip6_spec *ipv6_l4_hdr = &fsp->h_u.tcp_ip6_spec;697 struct ethtool_ah_espip6_spec *ah_esp_hdr = &fsp->h_u.ah_ip6_spec;698 struct ethtool_ah_espip6_spec *ah_esp_mask = &fsp->m_u.ah_ip6_spec;699 struct flow_msg *pmask = &req->mask;700 struct flow_msg *pkt = &req->packet;701 702 switch (flow_type) {703 case IPV6_USER_FLOW:704 if (!ipv6_addr_any((struct in6_addr *)ipv6_usr_mask->ip6src)) {705 memcpy(&pkt->ip6src, &ipv6_usr_hdr->ip6src,706 sizeof(pkt->ip6src));707 memcpy(&pmask->ip6src, &ipv6_usr_mask->ip6src,708 sizeof(pmask->ip6src));709 req->features |= BIT_ULL(NPC_SIP_IPV6);710 }711 if (!ipv6_addr_any((struct in6_addr *)ipv6_usr_mask->ip6dst)) {712 memcpy(&pkt->ip6dst, &ipv6_usr_hdr->ip6dst,713 sizeof(pkt->ip6dst));714 memcpy(&pmask->ip6dst, &ipv6_usr_mask->ip6dst,715 sizeof(pmask->ip6dst));716 req->features |= BIT_ULL(NPC_DIP_IPV6);717 }718 if (ipv6_usr_hdr->l4_proto == IPPROTO_FRAGMENT) {719 pkt->next_header = ipv6_usr_hdr->l4_proto;720 pmask->next_header = ipv6_usr_mask->l4_proto;721 req->features |= BIT_ULL(NPC_IPFRAG_IPV6);722 }723 pkt->etype = cpu_to_be16(ETH_P_IPV6);724 pmask->etype = cpu_to_be16(0xFFFF);725 req->features |= BIT_ULL(NPC_ETYPE);726 break;727 case TCP_V6_FLOW:728 case UDP_V6_FLOW:729 case SCTP_V6_FLOW:730 pkt->etype = cpu_to_be16(ETH_P_IPV6);731 pmask->etype = cpu_to_be16(0xFFFF);732 req->features |= BIT_ULL(NPC_ETYPE);733 if (!ipv6_addr_any((struct in6_addr *)ipv6_l4_mask->ip6src)) {734 memcpy(&pkt->ip6src, &ipv6_l4_hdr->ip6src,735 sizeof(pkt->ip6src));736 memcpy(&pmask->ip6src, &ipv6_l4_mask->ip6src,737 sizeof(pmask->ip6src));738 req->features |= BIT_ULL(NPC_SIP_IPV6);739 }740 if (!ipv6_addr_any((struct in6_addr *)ipv6_l4_mask->ip6dst)) {741 memcpy(&pkt->ip6dst, &ipv6_l4_hdr->ip6dst,742 sizeof(pkt->ip6dst));743 memcpy(&pmask->ip6dst, &ipv6_l4_mask->ip6dst,744 sizeof(pmask->ip6dst));745 req->features |= BIT_ULL(NPC_DIP_IPV6);746 }747 if (ipv6_l4_mask->psrc) {748 memcpy(&pkt->sport, &ipv6_l4_hdr->psrc,749 sizeof(pkt->sport));750 memcpy(&pmask->sport, &ipv6_l4_mask->psrc,751 sizeof(pmask->sport));752 if (flow_type == UDP_V6_FLOW)753 req->features |= BIT_ULL(NPC_SPORT_UDP);754 else if (flow_type == TCP_V6_FLOW)755 req->features |= BIT_ULL(NPC_SPORT_TCP);756 else757 req->features |= BIT_ULL(NPC_SPORT_SCTP);758 }759 if (ipv6_l4_mask->pdst) {760 memcpy(&pkt->dport, &ipv6_l4_hdr->pdst,761 sizeof(pkt->dport));762 memcpy(&pmask->dport, &ipv6_l4_mask->pdst,763 sizeof(pmask->dport));764 if (flow_type == UDP_V6_FLOW)765 req->features |= BIT_ULL(NPC_DPORT_UDP);766 else if (flow_type == TCP_V6_FLOW)767 req->features |= BIT_ULL(NPC_DPORT_TCP);768 else769 req->features |= BIT_ULL(NPC_DPORT_SCTP);770 }771 if (flow_type == UDP_V6_FLOW)772 req->features |= BIT_ULL(NPC_IPPROTO_UDP);773 else if (flow_type == TCP_V6_FLOW)774 req->features |= BIT_ULL(NPC_IPPROTO_TCP);775 else776 req->features |= BIT_ULL(NPC_IPPROTO_SCTP);777 break;778 case AH_V6_FLOW:779 case ESP_V6_FLOW:780 pkt->etype = cpu_to_be16(ETH_P_IPV6);781 pmask->etype = cpu_to_be16(0xFFFF);782 req->features |= BIT_ULL(NPC_ETYPE);783 if (!ipv6_addr_any((struct in6_addr *)ah_esp_hdr->ip6src)) {784 memcpy(&pkt->ip6src, &ah_esp_hdr->ip6src,785 sizeof(pkt->ip6src));786 memcpy(&pmask->ip6src, &ah_esp_mask->ip6src,787 sizeof(pmask->ip6src));788 req->features |= BIT_ULL(NPC_SIP_IPV6);789 }790 if (!ipv6_addr_any((struct in6_addr *)ah_esp_hdr->ip6dst)) {791 memcpy(&pkt->ip6dst, &ah_esp_hdr->ip6dst,792 sizeof(pkt->ip6dst));793 memcpy(&pmask->ip6dst, &ah_esp_mask->ip6dst,794 sizeof(pmask->ip6dst));795 req->features |= BIT_ULL(NPC_DIP_IPV6);796 }797 798 /* NPC profile doesn't extract AH/ESP header fields */799 if ((ah_esp_mask->spi & ah_esp_hdr->spi) ||800 (ah_esp_mask->tclass & ah_esp_hdr->tclass))801 return -EOPNOTSUPP;802 803 if (flow_type == AH_V6_FLOW)804 req->features |= BIT_ULL(NPC_IPPROTO_AH);805 else806 req->features |= BIT_ULL(NPC_IPPROTO_ESP);807 break;808 default:809 break;810 }811 812 return 0;813}814 815static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,816 struct npc_install_flow_req *req)817{818 struct ethhdr *eth_mask = &fsp->m_u.ether_spec;819 struct ethhdr *eth_hdr = &fsp->h_u.ether_spec;820 struct flow_msg *pmask = &req->mask;821 struct flow_msg *pkt = &req->packet;822 u32 flow_type;823 int ret;824 825 flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);826 switch (flow_type) {827 /* bits not set in mask are don't care */828 case ETHER_FLOW:829 if (!is_zero_ether_addr(eth_mask->h_source)) {830 ether_addr_copy(pkt->smac, eth_hdr->h_source);831 ether_addr_copy(pmask->smac, eth_mask->h_source);832 req->features |= BIT_ULL(NPC_SMAC);833 }834 if (!is_zero_ether_addr(eth_mask->h_dest)) {835 ether_addr_copy(pkt->dmac, eth_hdr->h_dest);836 ether_addr_copy(pmask->dmac, eth_mask->h_dest);837 req->features |= BIT_ULL(NPC_DMAC);838 }839 if (eth_hdr->h_proto) {840 memcpy(&pkt->etype, ð_hdr->h_proto,841 sizeof(pkt->etype));842 memcpy(&pmask->etype, ð_mask->h_proto,843 sizeof(pmask->etype));844 req->features |= BIT_ULL(NPC_ETYPE);845 }846 break;847 case IP_USER_FLOW:848 case TCP_V4_FLOW:849 case UDP_V4_FLOW:850 case SCTP_V4_FLOW:851 case AH_V4_FLOW:852 case ESP_V4_FLOW:853 ret = otx2_prepare_ipv4_flow(fsp, req, flow_type);854 if (ret)855 return ret;856 break;857 case IPV6_USER_FLOW:858 case TCP_V6_FLOW:859 case UDP_V6_FLOW:860 case SCTP_V6_FLOW:861 case AH_V6_FLOW:862 case ESP_V6_FLOW:863 ret = otx2_prepare_ipv6_flow(fsp, req, flow_type);864 if (ret)865 return ret;866 break;867 default:868 return -EOPNOTSUPP;869 }870 if (fsp->flow_type & FLOW_EXT) {871 u16 vlan_etype;872 873 if (fsp->m_ext.vlan_etype) {874 /* Partial masks not supported */875 if (be16_to_cpu(fsp->m_ext.vlan_etype) != 0xFFFF)876 return -EINVAL;877 878 vlan_etype = be16_to_cpu(fsp->h_ext.vlan_etype);879 880 /* Drop rule with vlan_etype == 802.1Q881 * and vlan_id == 0 is not supported882 */883 if (vlan_etype == ETH_P_8021Q && !fsp->m_ext.vlan_tci &&884 fsp->ring_cookie == RX_CLS_FLOW_DISC)885 return -EINVAL;886 887 /* Only ETH_P_8021Q and ETH_P_802AD types supported */888 if (vlan_etype != ETH_P_8021Q &&889 vlan_etype != ETH_P_8021AD)890 return -EINVAL;891 892 memcpy(&pkt->vlan_etype, &fsp->h_ext.vlan_etype,893 sizeof(pkt->vlan_etype));894 memcpy(&pmask->vlan_etype, &fsp->m_ext.vlan_etype,895 sizeof(pmask->vlan_etype));896 897 if (vlan_etype == ETH_P_8021Q)898 req->features |= BIT_ULL(NPC_VLAN_ETYPE_CTAG);899 else900 req->features |= BIT_ULL(NPC_VLAN_ETYPE_STAG);901 }902 903 if (fsp->m_ext.vlan_tci) {904 memcpy(&pkt->vlan_tci, &fsp->h_ext.vlan_tci,905 sizeof(pkt->vlan_tci));906 memcpy(&pmask->vlan_tci, &fsp->m_ext.vlan_tci,907 sizeof(pmask->vlan_tci));908 req->features |= BIT_ULL(NPC_OUTER_VID);909 }910 911 if (fsp->m_ext.data[1]) {912 if (flow_type == IP_USER_FLOW) {913 if (be32_to_cpu(fsp->h_ext.data[1]) != IPV4_FLAG_MORE)914 return -EINVAL;915 916 pkt->ip_flag = be32_to_cpu(fsp->h_ext.data[1]);917 pmask->ip_flag = be32_to_cpu(fsp->m_ext.data[1]);918 req->features |= BIT_ULL(NPC_IPFRAG_IPV4);919 } else if (fsp->h_ext.data[1] ==920 cpu_to_be32(OTX2_DEFAULT_ACTION)) {921 /* Not Drop/Direct to queue but use action922 * in default entry923 */924 req->op = NIX_RX_ACTION_DEFAULT;925 }926 }927 }928 929 if (fsp->flow_type & FLOW_MAC_EXT &&930 !is_zero_ether_addr(fsp->m_ext.h_dest)) {931 ether_addr_copy(pkt->dmac, fsp->h_ext.h_dest);932 ether_addr_copy(pmask->dmac, fsp->m_ext.h_dest);933 req->features |= BIT_ULL(NPC_DMAC);934 }935 936 if (!req->features)937 return -EOPNOTSUPP;938 939 return 0;940}941 942static int otx2_is_flow_rule_dmacfilter(struct otx2_nic *pfvf,943 struct ethtool_rx_flow_spec *fsp)944{945 struct ethhdr *eth_mask = &fsp->m_u.ether_spec;946 struct ethhdr *eth_hdr = &fsp->h_u.ether_spec;947 u64 ring_cookie = fsp->ring_cookie;948 u32 flow_type;949 950 if (!(pfvf->flags & OTX2_FLAG_DMACFLTR_SUPPORT))951 return false;952 953 flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);954 955 /* CGX/RPM block dmac filtering configured for white listing956 * check for action other than DROP957 */958 if (flow_type == ETHER_FLOW && ring_cookie != RX_CLS_FLOW_DISC &&959 !ethtool_get_flow_spec_ring_vf(ring_cookie)) {960 if (is_zero_ether_addr(eth_mask->h_dest) &&961 is_valid_ether_addr(eth_hdr->h_dest))962 return true;963 }964 965 return false;966}967 968static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow)969{970 u64 ring_cookie = flow->flow_spec.ring_cookie;971#ifdef CONFIG_DCB972 int vlan_prio, qidx, pfc_rule = 0;973#endif974 struct npc_install_flow_req *req;975 int err, vf = 0;976 977 mutex_lock(&pfvf->mbox.lock);978 req = otx2_mbox_alloc_msg_npc_install_flow(&pfvf->mbox);979 if (!req) {980 mutex_unlock(&pfvf->mbox.lock);981 return -ENOMEM;982 }983 984 err = otx2_prepare_flow_request(&flow->flow_spec, req);985 if (err) {986 /* free the allocated msg above */987 otx2_mbox_reset(&pfvf->mbox.mbox, 0);988 mutex_unlock(&pfvf->mbox.lock);989 return err;990 }991 992 req->entry = flow->entry;993 req->intf = NIX_INTF_RX;994 req->set_cntr = 1;995 req->channel = pfvf->hw.rx_chan_base;996 if (ring_cookie == RX_CLS_FLOW_DISC) {997 req->op = NIX_RX_ACTIONOP_DROP;998 } else {999 /* change to unicast only if action of default entry is not1000 * requested by user1001 */1002 if (flow->flow_spec.flow_type & FLOW_RSS) {1003 req->op = NIX_RX_ACTIONOP_RSS;1004 req->index = flow->rss_ctx_id;1005 req->flow_key_alg = pfvf->hw.flowkey_alg_idx;1006 } else {1007 req->op = NIX_RX_ACTIONOP_UCAST;1008 req->index = ethtool_get_flow_spec_ring(ring_cookie);1009 }1010 vf = ethtool_get_flow_spec_ring_vf(ring_cookie);1011 if (vf > pci_num_vf(pfvf->pdev)) {1012 mutex_unlock(&pfvf->mbox.lock);1013 return -EINVAL;1014 }1015 1016#ifdef CONFIG_DCB1017 /* Identify PFC rule if PFC enabled and ntuple rule is vlan */1018 if (!vf && (req->features & BIT_ULL(NPC_OUTER_VID)) &&1019 pfvf->pfc_en && req->op != NIX_RX_ACTIONOP_RSS) {1020 vlan_prio = ntohs(req->packet.vlan_tci) &1021 ntohs(req->mask.vlan_tci);1022 1023 /* Get the priority */1024 vlan_prio >>= 13;1025 flow->rule_type |= PFC_FLOWCTRL_RULE;1026 /* Check if PFC enabled for this priority */1027 if (pfvf->pfc_en & BIT(vlan_prio)) {1028 pfc_rule = true;1029 qidx = req->index;1030 }1031 }1032#endif1033 }1034 1035 /* ethtool ring_cookie has (VF + 1) for VF */1036 if (vf) {1037 req->vf = vf;1038 flow->is_vf = true;1039 flow->vf = vf;1040 }1041 1042 /* Send message to AF */1043 err = otx2_sync_mbox_msg(&pfvf->mbox);1044 1045#ifdef CONFIG_DCB1046 if (!err && pfc_rule)1047 otx2_update_bpid_in_rqctx(pfvf, vlan_prio, qidx, true);1048#endif1049 1050 mutex_unlock(&pfvf->mbox.lock);1051 return err;1052}1053 1054static int otx2_add_flow_with_pfmac(struct otx2_nic *pfvf,1055 struct otx2_flow *flow)1056{1057 struct otx2_flow *pf_mac;1058 struct ethhdr *eth_hdr;1059 1060 pf_mac = kzalloc(sizeof(*pf_mac), GFP_KERNEL);1061 if (!pf_mac)1062 return -ENOMEM;1063 1064 pf_mac->entry = 0;1065 pf_mac->rule_type |= DMAC_FILTER_RULE;1066 pf_mac->location = pfvf->flow_cfg->max_flows;1067 memcpy(&pf_mac->flow_spec, &flow->flow_spec,1068 sizeof(struct ethtool_rx_flow_spec));1069 pf_mac->flow_spec.location = pf_mac->location;1070 1071 /* Copy PF mac address */1072 eth_hdr = &pf_mac->flow_spec.h_u.ether_spec;1073 ether_addr_copy(eth_hdr->h_dest, pfvf->netdev->dev_addr);1074 1075 /* Install DMAC filter with PF mac address */1076 otx2_dmacflt_add(pfvf, eth_hdr->h_dest, 0);1077 1078 otx2_add_flow_to_list(pfvf, pf_mac);1079 pfvf->flow_cfg->nr_flows++;1080 set_bit(0, pfvf->flow_cfg->dmacflt_bmap);1081 1082 return 0;1083}1084 1085int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)1086{1087 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;1088 struct ethtool_rx_flow_spec *fsp = &nfc->fs;1089 struct otx2_flow *flow;1090 struct ethhdr *eth_hdr;1091 bool new = false;1092 int err = 0;1093 u64 vf_num;1094 u32 ring;1095 1096 if (!flow_cfg->max_flows) {1097 netdev_err(pfvf->netdev,1098 "Ntuple rule count is 0, allocate and retry\n");1099 return -EINVAL;1100 }1101 1102 ring = ethtool_get_flow_spec_ring(fsp->ring_cookie);1103 if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT))1104 return -ENOMEM;1105 1106 /* Number of queues on a VF can be greater or less than1107 * the PF's queue. Hence no need to check for the1108 * queue count. Hence no need to check queue count if PF1109 * is installing for its VF. Below is the expected vf_num value1110 * based on the ethtool commands.1111 *1112 * e.g.1113 * 1. ethtool -U <netdev> ... action -1 ==> vf_num:2551114 * 2. ethtool -U <netdev> ... action <queue_num> ==> vf_num:01115 * 3. ethtool -U <netdev> ... vf <vf_idx> queue <queue_num> ==>1116 * vf_num:vf_idx+11117 */1118 vf_num = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);1119 if (!is_otx2_vf(pfvf->pcifunc) && !vf_num &&1120 ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC)1121 return -EINVAL;1122 1123 if (fsp->location >= otx2_get_maxflows(flow_cfg))1124 return -EINVAL;1125 1126 flow = otx2_find_flow(pfvf, fsp->location);1127 if (!flow) {1128 flow = kzalloc(sizeof(*flow), GFP_KERNEL);1129 if (!flow)1130 return -ENOMEM;1131 flow->location = fsp->location;1132 flow->entry = flow_cfg->flow_ent[flow->location];1133 new = true;1134 }1135 /* struct copy */1136 flow->flow_spec = *fsp;1137 1138 if (fsp->flow_type & FLOW_RSS)1139 flow->rss_ctx_id = nfc->rss_context;1140 1141 if (otx2_is_flow_rule_dmacfilter(pfvf, &flow->flow_spec)) {1142 eth_hdr = &flow->flow_spec.h_u.ether_spec;1143 1144 /* Sync dmac filter table with updated fields */1145 if (flow->rule_type & DMAC_FILTER_RULE)1146 return otx2_dmacflt_update(pfvf, eth_hdr->h_dest,1147 flow->entry);1148 1149 if (bitmap_full(flow_cfg->dmacflt_bmap,1150 flow_cfg->dmacflt_max_flows)) {1151 netdev_warn(pfvf->netdev,1152 "Can't insert the rule %d as max allowed dmac filters are %d\n",1153 flow->location +1154 flow_cfg->dmacflt_max_flows,1155 flow_cfg->dmacflt_max_flows);1156 err = -EINVAL;1157 if (new)1158 kfree(flow);1159 return err;1160 }1161 1162 /* Install PF mac address to DMAC filter list */1163 if (!test_bit(0, flow_cfg->dmacflt_bmap))1164 otx2_add_flow_with_pfmac(pfvf, flow);1165 1166 flow->rule_type |= DMAC_FILTER_RULE;1167 flow->entry = find_first_zero_bit(flow_cfg->dmacflt_bmap,1168 flow_cfg->dmacflt_max_flows);1169 fsp->location = flow_cfg->max_flows + flow->entry;1170 flow->flow_spec.location = fsp->location;1171 flow->location = fsp->location;1172 1173 set_bit(flow->entry, flow_cfg->dmacflt_bmap);1174 otx2_dmacflt_add(pfvf, eth_hdr->h_dest, flow->entry);1175 1176 } else {1177 if (flow->location >= pfvf->flow_cfg->max_flows) {1178 netdev_warn(pfvf->netdev,1179 "Can't insert non dmac ntuple rule at %d, allowed range %d-0\n",1180 flow->location,1181 flow_cfg->max_flows - 1);1182 err = -EINVAL;1183 } else {1184 err = otx2_add_flow_msg(pfvf, flow);1185 }1186 }1187 1188 if (err) {1189 if (err == MBOX_MSG_INVALID)1190 err = -EINVAL;1191 if (new)1192 kfree(flow);1193 return err;1194 }1195 1196 /* add the new flow installed to list */1197 if (new) {1198 otx2_add_flow_to_list(pfvf, flow);1199 flow_cfg->nr_flows++;1200 }1201 1202 if (flow->is_vf)1203 netdev_info(pfvf->netdev,1204 "Make sure that VF's queue number is within its queue limit\n");1205 return 0;1206}1207 1208static int otx2_remove_flow_msg(struct otx2_nic *pfvf, u16 entry, bool all)1209{1210 struct npc_delete_flow_req *req;1211 int err;1212 1213 mutex_lock(&pfvf->mbox.lock);1214 req = otx2_mbox_alloc_msg_npc_delete_flow(&pfvf->mbox);1215 if (!req) {1216 mutex_unlock(&pfvf->mbox.lock);1217 return -ENOMEM;1218 }1219 1220 req->entry = entry;1221 if (all)1222 req->all = 1;1223 1224 /* Send message to AF */1225 err = otx2_sync_mbox_msg(&pfvf->mbox);1226 mutex_unlock(&pfvf->mbox.lock);1227 return err;1228}1229 1230static void otx2_update_rem_pfmac(struct otx2_nic *pfvf, int req)1231{1232 struct otx2_flow *iter;1233 struct ethhdr *eth_hdr;1234 bool found = false;1235 1236 list_for_each_entry(iter, &pfvf->flow_cfg->flow_list, list) {1237 if ((iter->rule_type & DMAC_FILTER_RULE) && iter->entry == 0) {1238 eth_hdr = &iter->flow_spec.h_u.ether_spec;1239 if (req == DMAC_ADDR_DEL) {1240 otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,1241 0);1242 clear_bit(0, pfvf->flow_cfg->dmacflt_bmap);1243 found = true;1244 } else {1245 ether_addr_copy(eth_hdr->h_dest,1246 pfvf->netdev->dev_addr);1247 1248 otx2_dmacflt_update(pfvf, eth_hdr->h_dest, 0);1249 }1250 break;1251 }1252 }1253 1254 if (found) {1255 list_del(&iter->list);1256 kfree(iter);1257 pfvf->flow_cfg->nr_flows--;1258 }1259}1260 1261int otx2_remove_flow(struct otx2_nic *pfvf, u32 location)1262{1263 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;1264 struct otx2_flow *flow;1265 int err;1266 1267 if (location >= otx2_get_maxflows(flow_cfg))1268 return -EINVAL;1269 1270 flow = otx2_find_flow(pfvf, location);1271 if (!flow)1272 return -ENOENT;1273 1274 if (flow->rule_type & DMAC_FILTER_RULE) {1275 struct ethhdr *eth_hdr = &flow->flow_spec.h_u.ether_spec;1276 1277 /* user not allowed to remove dmac filter with interface mac */1278 if (ether_addr_equal(pfvf->netdev->dev_addr, eth_hdr->h_dest))1279 return -EPERM;1280 1281 err = otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,1282 flow->entry);1283 clear_bit(flow->entry, flow_cfg->dmacflt_bmap);1284 /* If all dmac filters are removed delete macfilter with1285 * interface mac address and configure CGX/RPM block in1286 * promiscuous mode1287 */1288 if (bitmap_weight(flow_cfg->dmacflt_bmap,1289 flow_cfg->dmacflt_max_flows) == 1)1290 otx2_update_rem_pfmac(pfvf, DMAC_ADDR_DEL);1291 } else {1292#ifdef CONFIG_DCB1293 if (flow->rule_type & PFC_FLOWCTRL_RULE)1294 otx2_update_bpid_in_rqctx(pfvf, 0,1295 flow->flow_spec.ring_cookie,1296 false);1297#endif1298 1299 err = otx2_remove_flow_msg(pfvf, flow->entry, false);1300 }1301 1302 if (err)1303 return err;1304 1305 list_del(&flow->list);1306 kfree(flow);1307 flow_cfg->nr_flows--;1308 1309 return 0;1310}1311 1312void otx2_rss_ctx_flow_del(struct otx2_nic *pfvf, int ctx_id)1313{1314 struct otx2_flow *flow, *tmp;1315 int err;1316 1317 list_for_each_entry_safe(flow, tmp, &pfvf->flow_cfg->flow_list, list) {1318 if (flow->rss_ctx_id != ctx_id)1319 continue;1320 err = otx2_remove_flow(pfvf, flow->location);1321 if (err)1322 netdev_warn(pfvf->netdev,1323 "Can't delete the rule %d associated with this rss group err:%d",1324 flow->location, err);1325 }1326}1327 1328int otx2_destroy_ntuple_flows(struct otx2_nic *pfvf)1329{1330 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;1331 struct npc_delete_flow_req *req;1332 struct otx2_flow *iter, *tmp;1333 int err;1334 1335 if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT))1336 return 0;1337 1338 if (!flow_cfg->max_flows)1339 return 0;1340 1341 mutex_lock(&pfvf->mbox.lock);1342 req = otx2_mbox_alloc_msg_npc_delete_flow(&pfvf->mbox);1343 if (!req) {1344 mutex_unlock(&pfvf->mbox.lock);1345 return -ENOMEM;1346 }1347 1348 req->start = flow_cfg->flow_ent[0];1349 req->end = flow_cfg->flow_ent[flow_cfg->max_flows - 1];1350 err = otx2_sync_mbox_msg(&pfvf->mbox);1351 mutex_unlock(&pfvf->mbox.lock);1352 1353 list_for_each_entry_safe(iter, tmp, &flow_cfg->flow_list, list) {1354 list_del(&iter->list);1355 kfree(iter);1356 flow_cfg->nr_flows--;1357 }1358 return err;1359}1360 1361int otx2_destroy_mcam_flows(struct otx2_nic *pfvf)1362{1363 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;1364 struct npc_mcam_free_entry_req *req;1365 struct otx2_flow *iter, *tmp;1366 int err;1367 1368 if (!(pfvf->flags & OTX2_FLAG_MCAM_ENTRIES_ALLOC))1369 return 0;1370 1371 /* remove all flows */1372 err = otx2_remove_flow_msg(pfvf, 0, true);1373 if (err)1374 return err;1375 1376 list_for_each_entry_safe(iter, tmp, &flow_cfg->flow_list, list) {1377 list_del(&iter->list);1378 kfree(iter);1379 flow_cfg->nr_flows--;1380 }1381 1382 mutex_lock(&pfvf->mbox.lock);1383 req = otx2_mbox_alloc_msg_npc_mcam_free_entry(&pfvf->mbox);1384 if (!req) {1385 mutex_unlock(&pfvf->mbox.lock);1386 return -ENOMEM;1387 }1388 1389 req->all = 1;1390 /* Send message to AF to free MCAM entries */1391 err = otx2_sync_mbox_msg(&pfvf->mbox);1392 if (err) {1393 mutex_unlock(&pfvf->mbox.lock);1394 return err;1395 }1396 1397 pfvf->flags &= ~OTX2_FLAG_MCAM_ENTRIES_ALLOC;1398 flow_cfg->max_flows = 0;1399 mutex_unlock(&pfvf->mbox.lock);1400 1401 return 0;1402}1403 1404int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf)1405{1406 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;1407 struct npc_install_flow_req *req;1408 int err;1409 1410 mutex_lock(&pfvf->mbox.lock);1411 req = otx2_mbox_alloc_msg_npc_install_flow(&pfvf->mbox);1412 if (!req) {1413 mutex_unlock(&pfvf->mbox.lock);1414 return -ENOMEM;1415 }1416 1417 req->entry = flow_cfg->def_ent[flow_cfg->rx_vlan_offset];1418 req->intf = NIX_INTF_RX;1419 ether_addr_copy(req->packet.dmac, pfvf->netdev->dev_addr);1420 eth_broadcast_addr((u8 *)&req->mask.dmac);1421 req->channel = pfvf->hw.rx_chan_base;1422 req->op = NIX_RX_ACTION_DEFAULT;1423 req->features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_DMAC);1424 req->vtag0_valid = true;1425 req->vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0;1426 1427 /* Send message to AF */1428 err = otx2_sync_mbox_msg(&pfvf->mbox);1429 mutex_unlock(&pfvf->mbox.lock);1430 return err;1431}1432 1433static int otx2_delete_rxvlan_offload_flow(struct otx2_nic *pfvf)1434{1435 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;1436 struct npc_delete_flow_req *req;1437 int err;1438 1439 mutex_lock(&pfvf->mbox.lock);1440 req = otx2_mbox_alloc_msg_npc_delete_flow(&pfvf->mbox);1441 if (!req) {1442 mutex_unlock(&pfvf->mbox.lock);1443 return -ENOMEM;1444 }1445 1446 req->entry = flow_cfg->def_ent[flow_cfg->rx_vlan_offset];1447 /* Send message to AF */1448 err = otx2_sync_mbox_msg(&pfvf->mbox);1449 mutex_unlock(&pfvf->mbox.lock);1450 return err;1451}1452 1453int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable)1454{1455 struct nix_vtag_config *req;1456 struct mbox_msghdr *rsp_hdr;1457 int err;1458 1459 /* Dont have enough mcam entries */1460 if (!(pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT))1461 return -ENOMEM;1462 1463 if (enable) {1464 err = otx2_install_rxvlan_offload_flow(pf);1465 if (err)1466 return err;1467 } else {1468 err = otx2_delete_rxvlan_offload_flow(pf);1469 if (err)1470 return err;1471 }1472 1473 mutex_lock(&pf->mbox.lock);1474 req = otx2_mbox_alloc_msg_nix_vtag_cfg(&pf->mbox);1475 if (!req) {1476 mutex_unlock(&pf->mbox.lock);1477 return -ENOMEM;1478 }1479 1480 /* config strip, capture and size */1481 req->vtag_size = VTAGSIZE_T4;1482 req->cfg_type = 1; /* rx vlan cfg */1483 req->rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0;1484 req->rx.strip_vtag = enable;1485 req->rx.capture_vtag = enable;1486 1487 err = otx2_sync_mbox_msg(&pf->mbox);1488 if (err) {1489 mutex_unlock(&pf->mbox.lock);1490 return err;1491 }1492 1493 rsp_hdr = otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);1494 if (IS_ERR(rsp_hdr)) {1495 mutex_unlock(&pf->mbox.lock);1496 return PTR_ERR(rsp_hdr);1497 }1498 1499 mutex_unlock(&pf->mbox.lock);1500 return rsp_hdr->rc;1501}1502 1503void otx2_dmacflt_reinstall_flows(struct otx2_nic *pf)1504{1505 struct otx2_flow *iter;1506 struct ethhdr *eth_hdr;1507 1508 list_for_each_entry(iter, &pf->flow_cfg->flow_list, list) {1509 if (iter->rule_type & DMAC_FILTER_RULE) {1510 eth_hdr = &iter->flow_spec.h_u.ether_spec;1511 otx2_dmacflt_add(pf, eth_hdr->h_dest,1512 iter->entry);1513 }1514 }1515}1516 1517void otx2_dmacflt_update_pfmac_flow(struct otx2_nic *pfvf)1518{1519 otx2_update_rem_pfmac(pfvf, DMAC_ADDR_UPDATE);1520}1521