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
otx2_dmacflt_do_add(struct otx2_nic * pf,const u8 * mac,u8 * dmac_index)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
otx2_dmacflt_add_pfmac(struct otx2_nic * pf)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
otx2_dmacflt_add(struct otx2_nic * pf,const u8 * mac,u8 bit_pos)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
otx2_dmacflt_do_remove(struct otx2_nic * pfvf,const u8 * mac,u8 dmac_index)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
otx2_dmacflt_remove_pfmac(struct otx2_nic * pf)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
otx2_dmacflt_remove(struct otx2_nic * pf,const u8 * mac,u8 bit_pos)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 */
otx2_dmacflt_get_max_cnt(struct otx2_nic * pf)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
otx2_dmacflt_update(struct otx2_nic * pf,u8 * mac,u8 bit_pos)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