1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell OcteonTx2 RVU Physcial Function ethernet driver 3 * 4 * Copyright (C) 2021 Marvell. 5 */ 6 7 #include "otx2_common.h" 8 9 static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac, 10 u8 *dmac_index) 11 { 12 struct cgx_mac_addr_add_req *req; 13 struct cgx_mac_addr_add_rsp *rsp; 14 int err; 15 16 mutex_lock(&pf->mbox.lock); 17 18 req = otx2_mbox_alloc_msg_cgx_mac_addr_add(&pf->mbox); 19 if (!req) { 20 mutex_unlock(&pf->mbox.lock); 21 return -ENOMEM; 22 } 23 24 ether_addr_copy(req->mac_addr, mac); 25 err = otx2_sync_mbox_msg(&pf->mbox); 26 27 if (!err) { 28 rsp = (struct cgx_mac_addr_add_rsp *) 29 otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr); 30 *dmac_index = rsp->index; 31 } 32 33 mutex_unlock(&pf->mbox.lock); 34 return err; 35 } 36 37 static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf) 38 { 39 struct cgx_mac_addr_set_or_get *req; 40 int err; 41 42 mutex_lock(&pf->mbox.lock); 43 44 req = otx2_mbox_alloc_msg_cgx_mac_addr_set(&pf->mbox); 45 if (!req) { 46 mutex_unlock(&pf->mbox.lock); 47 return -ENOMEM; 48 } 49 50 ether_addr_copy(req->mac_addr, pf->netdev->dev_addr); 51 err = otx2_sync_mbox_msg(&pf->mbox); 52 53 mutex_unlock(&pf->mbox.lock); 54 return err; 55 } 56 57 int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos) 58 { 59 u8 *dmacindex; 60 61 /* Store dmacindex returned by CGX/RPM driver which will 62 * be used for macaddr update/remove 63 */ 64 dmacindex = &pf->flow_cfg->bmap_to_dmacindex[bit_pos]; 65 66 if (ether_addr_equal(mac, pf->netdev->dev_addr)) 67 return otx2_dmacflt_add_pfmac(pf); 68 else 69 return otx2_dmacflt_do_add(pf, mac, dmacindex); 70 } 71 72 static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac, 73 u8 dmac_index) 74 { 75 struct cgx_mac_addr_del_req *req; 76 int err; 77 78 mutex_lock(&pfvf->mbox.lock); 79 req = otx2_mbox_alloc_msg_cgx_mac_addr_del(&pfvf->mbox); 80 if (!req) { 81 mutex_unlock(&pfvf->mbox.lock); 82 return -ENOMEM; 83 } 84 85 req->index = dmac_index; 86 87 err = otx2_sync_mbox_msg(&pfvf->mbox); 88 mutex_unlock(&pfvf->mbox.lock); 89 90 return err; 91 } 92 93 static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf) 94 { 95 struct msg_req *req; 96 int err; 97 98 mutex_lock(&pf->mbox.lock); 99 req = otx2_mbox_alloc_msg_cgx_mac_addr_reset(&pf->mbox); 100 if (!req) { 101 mutex_unlock(&pf->mbox.lock); 102 return -ENOMEM; 103 } 104 105 err = otx2_sync_mbox_msg(&pf->mbox); 106 107 mutex_unlock(&pf->mbox.lock); 108 return err; 109 } 110 111 int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac, 112 u8 bit_pos) 113 { 114 u8 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos]; 115 116 if (ether_addr_equal(mac, pf->netdev->dev_addr)) 117 return otx2_dmacflt_remove_pfmac(pf); 118 else 119 return otx2_dmacflt_do_remove(pf, mac, dmacindex); 120 } 121 122 /* CGX/RPM blocks support max unicast entries of 32. 123 * on typical configuration MAC block associated 124 * with 4 lmacs, each lmac will have 8 dmac entries 125 */ 126 int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf) 127 { 128 struct cgx_max_dmac_entries_get_rsp *rsp; 129 struct msg_req *msg; 130 int err; 131 132 mutex_lock(&pf->mbox.lock); 133 msg = otx2_mbox_alloc_msg_cgx_mac_max_entries_get(&pf->mbox); 134 135 if (!msg) { 136 mutex_unlock(&pf->mbox.lock); 137 return -ENOMEM; 138 } 139 140 err = otx2_sync_mbox_msg(&pf->mbox); 141 if (err) 142 goto out; 143 144 rsp = (struct cgx_max_dmac_entries_get_rsp *) 145 otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &msg->hdr); 146 pf->flow_cfg->dmacflt_max_flows = rsp->max_dmac_filters; 147 148 out: 149 mutex_unlock(&pf->mbox.lock); 150 return err; 151 } 152 153 int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos) 154 { 155 struct cgx_mac_addr_update_req *req; 156 int rc; 157 158 mutex_lock(&pf->mbox.lock); 159 160 req = otx2_mbox_alloc_msg_cgx_mac_addr_update(&pf->mbox); 161 162 if (!req) { 163 mutex_unlock(&pf->mbox.lock); 164 return -ENOMEM; 165 } 166 167 ether_addr_copy(req->mac_addr, mac); 168 req->index = pf->flow_cfg->bmap_to_dmacindex[bit_pos]; 169 rc = otx2_sync_mbox_msg(&pf->mbox); 170 171 mutex_unlock(&pf->mbox.lock); 172 return rc; 173 } 174