Merge v5.14-rc3 into usb-next
[linux-2.6-microblaze.git] / drivers / net / ethernet / marvell / octeontx2 / nic / otx2_dmac_flt.c
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 }