xref: /dpdk/drivers/net/octeontx/octeontx_ethdev_ops.c (revision 9b1249d9ff695531e4a737bbf9bf519e0bf8130c)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2020 Marvell International Ltd.
3  */
4 
5 #include <rte_malloc.h>
6 
7 #include "octeontx_ethdev.h"
8 #include "octeontx_logs.h"
9 #include "octeontx_rxtx.h"
10 
11 static int
12 octeontx_vlan_hw_filter(struct octeontx_nic *nic, uint8_t flag)
13 {
14 	struct octeontx_vlan_info *vlan = &nic->vlan_info;
15 	pki_port_vlan_filter_config_t fltr_conf;
16 	int rc = 0;
17 
18 	if (vlan->filter_on == flag)
19 		return rc;
20 
21 	fltr_conf.port_type = OCTTX_PORT_TYPE_NET;
22 	fltr_conf.fltr_conf = flag;
23 
24 	rc = octeontx_pki_port_vlan_fltr_config(nic->port_id, &fltr_conf);
25 	if (rc != 0) {
26 		octeontx_log_err("Fail to configure vlan hw filter for port %d",
27 				 nic->port_id);
28 		goto done;
29 	}
30 
31 	vlan->filter_on = flag;
32 
33 done:
34 	return rc;
35 }
36 
37 int
38 octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
39 {
40 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
41 	struct rte_eth_rxmode *rxmode;
42 	int rc = 0;
43 
44 	rxmode = &dev->data->dev_conf.rxmode;
45 
46 	if (mask & ETH_VLAN_EXTEND_MASK) {
47 		octeontx_log_err("Extend offload not supported");
48 		return -ENOTSUP;
49 	}
50 
51 	if (mask & ETH_VLAN_STRIP_MASK) {
52 		octeontx_log_err("VLAN strip offload not supported");
53 		return -ENOTSUP;
54 	}
55 
56 	if (mask & ETH_VLAN_FILTER_MASK) {
57 		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
58 			rc = octeontx_vlan_hw_filter(nic, true);
59 			if (rc)
60 				goto done;
61 
62 			nic->rx_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
63 			nic->rx_offload_flags |= OCCTX_RX_VLAN_FLTR_F;
64 		} else {
65 			rc = octeontx_vlan_hw_filter(nic, false);
66 			if (rc)
67 				goto done;
68 
69 			nic->rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
70 			nic->rx_offload_flags &= ~OCCTX_RX_VLAN_FLTR_F;
71 		}
72 	}
73 
74 done:
75 	return rc;
76 }
77 
78 int
79 octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
80 {
81 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
82 	struct octeontx_vlan_info *vlan = &nic->vlan_info;
83 	pki_port_vlan_filter_entry_config_t fltr_entry;
84 	struct vlan_entry *entry = NULL;
85 	int entry_count = 0;
86 	int rc = -EINVAL;
87 
88 	if (on) {
89 		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
90 			if (entry->vlan_id == vlan_id) {
91 				octeontx_log_dbg("Vlan Id is already set");
92 				return 0;
93 			}
94 	} else {
95 		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
96 			entry_count++;
97 
98 		if (!entry_count)
99 			return 0;
100 	}
101 
102 	fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
103 	fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
104 	fltr_entry.vlan_id = vlan_id;
105 	fltr_entry.entry_conf = on;
106 
107 	if (on) {
108 		entry = rte_zmalloc("octeontx_nic_vlan_entry",
109 				    sizeof(struct vlan_entry), 0);
110 		if (!entry) {
111 			octeontx_log_err("Failed to allocate memory");
112 			return -ENOMEM;
113 		}
114 	}
115 
116 	rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
117 						      &fltr_entry);
118 	if (rc != 0) {
119 		octeontx_log_err("Fail to configure vlan filter entry "
120 				 "for port %d", nic->port_id);
121 		if (entry)
122 			rte_free(entry);
123 
124 		goto done;
125 	}
126 
127 	if (on) {
128 		entry->vlan_id  = vlan_id;
129 		TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next);
130 	} else {
131 		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
132 			if (entry->vlan_id == vlan_id) {
133 				TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
134 				rte_free(entry);
135 				break;
136 			}
137 		}
138 	}
139 
140 done:
141 	return rc;
142 }
143 
144 int
145 octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev)
146 {
147 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
148 	int rc;
149 
150 	TAILQ_INIT(&nic->vlan_info.fltr_tbl);
151 
152 	rc = octeontx_dev_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
153 	if (rc)
154 		octeontx_log_err("Failed to set vlan offload rc=%d", rc);
155 
156 	return rc;
157 }
158 
159 int
160 octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev)
161 {
162 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
163 	struct octeontx_vlan_info *vlan = &nic->vlan_info;
164 	pki_port_vlan_filter_entry_config_t fltr_entry;
165 	struct vlan_entry *entry;
166 	int rc = 0;
167 
168 	TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
169 		fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
170 		fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
171 		fltr_entry.vlan_id = entry->vlan_id;
172 		fltr_entry.entry_conf = 0;
173 
174 		rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
175 							      &fltr_entry);
176 		if (rc != 0) {
177 			octeontx_log_err("Fail to configure vlan filter entry "
178 					 "for port %d", nic->port_id);
179 			break;
180 		}
181 	}
182 
183 	return rc;
184 }
185 
186 int
187 octeontx_dev_set_link_up(struct rte_eth_dev *eth_dev)
188 {
189 	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
190 	int rc, i;
191 
192 	rc = octeontx_bgx_port_set_link_state(nic->port_id, true);
193 	if (rc)
194 		goto done;
195 
196 	/* Start tx queues  */
197 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
198 		octeontx_dev_tx_queue_start(eth_dev, i);
199 
200 done:
201 	return rc;
202 }
203 
204 int
205 octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev)
206 {
207 	struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
208 	int i;
209 
210 	/* Stop tx queues  */
211 	for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
212 		octeontx_dev_tx_queue_stop(eth_dev, i);
213 
214 	return octeontx_bgx_port_set_link_state(nic->port_id, false);
215 }
216 
217 int
218 octeontx_dev_flow_ctrl_get(struct rte_eth_dev *dev,
219 			   struct rte_eth_fc_conf *fc_conf)
220 {
221 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
222 	octeontx_mbox_bgx_port_fc_cfg_t conf;
223 	int rc;
224 
225 	memset(&conf, 0, sizeof(octeontx_mbox_bgx_port_fc_cfg_t));
226 
227 	rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
228 	if (rc)
229 		return rc;
230 
231 	if (conf.rx_pause && conf.tx_pause)
232 		fc_conf->mode = RTE_FC_FULL;
233 	else if (conf.rx_pause)
234 		fc_conf->mode = RTE_FC_RX_PAUSE;
235 	else if (conf.tx_pause)
236 		fc_conf->mode = RTE_FC_TX_PAUSE;
237 	else
238 		fc_conf->mode = RTE_FC_NONE;
239 
240 	/* low_water & high_water values are in Bytes */
241 	fc_conf->low_water = conf.low_water;
242 	fc_conf->high_water = conf.high_water;
243 
244 	return rc;
245 }
246 
247 int
248 octeontx_dev_flow_ctrl_set(struct rte_eth_dev *dev,
249 			   struct rte_eth_fc_conf *fc_conf)
250 {
251 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
252 	struct octeontx_fc_info *fc = &nic->fc;
253 	octeontx_mbox_bgx_port_fc_cfg_t conf;
254 	uint8_t tx_pause, rx_pause;
255 	uint16_t max_high_water;
256 	int rc;
257 
258 	if (fc_conf->pause_time || fc_conf->mac_ctrl_frame_fwd ||
259 	    fc_conf->autoneg) {
260 		octeontx_log_err("Below flowctrl parameters are not supported "
261 				 "pause_time, mac_ctrl_frame_fwd and autoneg");
262 		return -EINVAL;
263 	}
264 
265 	if (fc_conf->high_water == fc->high_water &&
266 	    fc_conf->low_water == fc->low_water &&
267 	    fc_conf->mode == fc->mode)
268 		return 0;
269 
270 	max_high_water = fc->rx_fifosz - OCTEONTX_BGX_RSVD_RX_FIFOBYTES;
271 
272 	if (fc_conf->high_water > max_high_water ||
273 	    fc_conf->high_water < fc_conf->low_water) {
274 		octeontx_log_err("Invalid high/low water values "
275 				 "High_water(in Bytes) must <= 0x%x ",
276 				 max_high_water);
277 		return -EINVAL;
278 	}
279 
280 	if (fc_conf->high_water % BIT(4) || fc_conf->low_water % BIT(4)) {
281 		octeontx_log_err("High/low water value must be multiple of 16");
282 		return -EINVAL;
283 	}
284 
285 	rx_pause = (fc_conf->mode == RTE_FC_FULL) ||
286 			(fc_conf->mode == RTE_FC_RX_PAUSE);
287 	tx_pause = (fc_conf->mode == RTE_FC_FULL) ||
288 			(fc_conf->mode == RTE_FC_TX_PAUSE);
289 
290 	conf.high_water = fc_conf->high_water;
291 	conf.low_water = fc_conf->low_water;
292 	conf.fc_cfg = BGX_PORT_FC_CFG_SET;
293 	conf.rx_pause = rx_pause;
294 	conf.tx_pause = tx_pause;
295 
296 	rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
297 	if (rc)
298 		return rc;
299 
300 	fc->high_water = fc_conf->high_water;
301 	fc->low_water = fc_conf->low_water;
302 	fc->mode = fc_conf->mode;
303 
304 	return rc;
305 }
306 
307 int
308 octeontx_dev_flow_ctrl_init(struct rte_eth_dev *dev)
309 {
310 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
311 	struct octeontx_fc_info *fc = &nic->fc;
312 	struct rte_eth_fc_conf fc_conf;
313 	int rc;
314 
315 	rc = octeontx_dev_flow_ctrl_get(dev, &fc_conf);
316 	if (rc) {
317 		octeontx_log_err("Failed to get flow control info");
318 		return rc;
319 	}
320 
321 	fc->def_highmark = fc_conf.high_water;
322 	fc->def_lowmark = fc_conf.low_water;
323 	fc->def_mode = fc_conf.mode;
324 
325 	return rc;
326 }
327 
328 int
329 octeontx_dev_flow_ctrl_fini(struct rte_eth_dev *dev)
330 {
331 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
332 	struct octeontx_fc_info *fc = &nic->fc;
333 	struct rte_eth_fc_conf fc_conf;
334 
335 	memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf));
336 
337 	/* Restore flow control parameters with default values */
338 	fc_conf.high_water = fc->def_highmark;
339 	fc_conf.low_water = fc->def_lowmark;
340 	fc_conf.mode = fc->def_mode;
341 
342 	return octeontx_dev_flow_ctrl_set(dev, &fc_conf);
343 }
344