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