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