| // SPDX-License-Identifier: GPL-2.0 |
| /* Marvell RVU Ethernet driver |
| * |
| * Copyright (C) 2021 Marvell. |
| * |
| */ |
| |
| #include "otx2_common.h" |
| |
| static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac, |
| u8 *dmac_index) |
| { |
| struct cgx_mac_addr_add_req *req; |
| struct cgx_mac_addr_add_rsp *rsp; |
| int err; |
| |
| mutex_lock(&pf->mbox.lock); |
| |
| req = otx2_mbox_alloc_msg_cgx_mac_addr_add(&pf->mbox); |
| if (!req) { |
| mutex_unlock(&pf->mbox.lock); |
| return -ENOMEM; |
| } |
| |
| ether_addr_copy(req->mac_addr, mac); |
| err = otx2_sync_mbox_msg(&pf->mbox); |
| |
| if (!err) { |
| rsp = (struct cgx_mac_addr_add_rsp *) |
| otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr); |
| *dmac_index = rsp->index; |
| } |
| |
| mutex_unlock(&pf->mbox.lock); |
| return err; |
| } |
| |
| static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf) |
| { |
| struct cgx_mac_addr_set_or_get *req; |
| int err; |
| |
| mutex_lock(&pf->mbox.lock); |
| |
| req = otx2_mbox_alloc_msg_cgx_mac_addr_set(&pf->mbox); |
| if (!req) { |
| mutex_unlock(&pf->mbox.lock); |
| return -ENOMEM; |
| } |
| |
| ether_addr_copy(req->mac_addr, pf->netdev->dev_addr); |
| err = otx2_sync_mbox_msg(&pf->mbox); |
| |
| mutex_unlock(&pf->mbox.lock); |
| return err; |
| } |
| |
| int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos) |
| { |
| u8 *dmacindex; |
| |
| /* Store dmacindex returned by CGX/RPM driver which will |
| * be used for macaddr update/remove |
| */ |
| dmacindex = &pf->flow_cfg->bmap_to_dmacindex[bit_pos]; |
| |
| if (ether_addr_equal(mac, pf->netdev->dev_addr)) |
| return otx2_dmacflt_add_pfmac(pf); |
| else |
| return otx2_dmacflt_do_add(pf, mac, dmacindex); |
| } |
| |
| static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac, |
| u8 dmac_index) |
| { |
| struct cgx_mac_addr_del_req *req; |
| int err; |
| |
| mutex_lock(&pfvf->mbox.lock); |
| req = otx2_mbox_alloc_msg_cgx_mac_addr_del(&pfvf->mbox); |
| if (!req) { |
| mutex_unlock(&pfvf->mbox.lock); |
| return -ENOMEM; |
| } |
| |
| req->index = dmac_index; |
| |
| err = otx2_sync_mbox_msg(&pfvf->mbox); |
| mutex_unlock(&pfvf->mbox.lock); |
| |
| return err; |
| } |
| |
| static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf) |
| { |
| struct msg_req *req; |
| int err; |
| |
| mutex_lock(&pf->mbox.lock); |
| req = otx2_mbox_alloc_msg_cgx_mac_addr_reset(&pf->mbox); |
| if (!req) { |
| mutex_unlock(&pf->mbox.lock); |
| return -ENOMEM; |
| } |
| |
| err = otx2_sync_mbox_msg(&pf->mbox); |
| |
| mutex_unlock(&pf->mbox.lock); |
| return err; |
| } |
| |
| int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac, |
| u8 bit_pos) |
| { |
| u8 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos]; |
| |
| if (ether_addr_equal(mac, pf->netdev->dev_addr)) |
| return otx2_dmacflt_remove_pfmac(pf); |
| else |
| return otx2_dmacflt_do_remove(pf, mac, dmacindex); |
| } |
| |
| /* CGX/RPM blocks support max unicast entries of 32. |
| * on typical configuration MAC block associated |
| * with 4 lmacs, each lmac will have 8 dmac entries |
| */ |
| int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf) |
| { |
| struct cgx_max_dmac_entries_get_rsp *rsp; |
| struct msg_req *msg; |
| int err; |
| |
| mutex_lock(&pf->mbox.lock); |
| msg = otx2_mbox_alloc_msg_cgx_mac_max_entries_get(&pf->mbox); |
| |
| if (!msg) { |
| mutex_unlock(&pf->mbox.lock); |
| return -ENOMEM; |
| } |
| |
| err = otx2_sync_mbox_msg(&pf->mbox); |
| if (err) |
| goto out; |
| |
| rsp = (struct cgx_max_dmac_entries_get_rsp *) |
| otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &msg->hdr); |
| pf->flow_cfg->dmacflt_max_flows = rsp->max_dmac_filters; |
| |
| out: |
| mutex_unlock(&pf->mbox.lock); |
| return err; |
| } |
| |
| int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos) |
| { |
| struct cgx_mac_addr_update_req *req; |
| int rc; |
| |
| mutex_lock(&pf->mbox.lock); |
| |
| req = otx2_mbox_alloc_msg_cgx_mac_addr_update(&pf->mbox); |
| |
| if (!req) { |
| mutex_unlock(&pf->mbox.lock); |
| return -ENOMEM; |
| } |
| |
| ether_addr_copy(req->mac_addr, mac); |
| req->index = pf->flow_cfg->bmap_to_dmacindex[bit_pos]; |
| rc = otx2_sync_mbox_msg(&pf->mbox); |
| |
| mutex_unlock(&pf->mbox.lock); |
| return rc; |
| } |