xref: /dpdk/drivers/net/octeontx/octeontx_ethdev_ops.c (revision 56139e85abec19ac9e91aed610abdb0c3629a638)
1*56139e85SVamsi Attunuru /* SPDX-License-Identifier: BSD-3-Clause
2*56139e85SVamsi Attunuru  * Copyright(C) 2020 Marvell International Ltd.
3*56139e85SVamsi Attunuru  */
4*56139e85SVamsi Attunuru 
5*56139e85SVamsi Attunuru #include <rte_malloc.h>
6*56139e85SVamsi Attunuru 
7*56139e85SVamsi Attunuru #include "octeontx_ethdev.h"
8*56139e85SVamsi Attunuru #include "octeontx_logs.h"
9*56139e85SVamsi Attunuru #include "octeontx_rxtx.h"
10*56139e85SVamsi Attunuru 
11*56139e85SVamsi Attunuru static int
12*56139e85SVamsi Attunuru octeontx_vlan_hw_filter(struct octeontx_nic *nic, uint8_t flag)
13*56139e85SVamsi Attunuru {
14*56139e85SVamsi Attunuru 	struct octeontx_vlan_info *vlan = &nic->vlan_info;
15*56139e85SVamsi Attunuru 	pki_port_vlan_filter_config_t fltr_conf;
16*56139e85SVamsi Attunuru 	int rc = 0;
17*56139e85SVamsi Attunuru 
18*56139e85SVamsi Attunuru 	if (vlan->filter_on == flag)
19*56139e85SVamsi Attunuru 		return rc;
20*56139e85SVamsi Attunuru 
21*56139e85SVamsi Attunuru 	fltr_conf.port_type = OCTTX_PORT_TYPE_NET;
22*56139e85SVamsi Attunuru 	fltr_conf.fltr_conf = flag;
23*56139e85SVamsi Attunuru 
24*56139e85SVamsi Attunuru 	rc = octeontx_pki_port_vlan_fltr_config(nic->port_id, &fltr_conf);
25*56139e85SVamsi Attunuru 	if (rc != 0) {
26*56139e85SVamsi Attunuru 		octeontx_log_err("Fail to configure vlan hw filter for port %d",
27*56139e85SVamsi Attunuru 				 nic->port_id);
28*56139e85SVamsi Attunuru 		goto done;
29*56139e85SVamsi Attunuru 	}
30*56139e85SVamsi Attunuru 
31*56139e85SVamsi Attunuru 	vlan->filter_on = flag;
32*56139e85SVamsi Attunuru 
33*56139e85SVamsi Attunuru done:
34*56139e85SVamsi Attunuru 	return rc;
35*56139e85SVamsi Attunuru }
36*56139e85SVamsi Attunuru 
37*56139e85SVamsi Attunuru int
38*56139e85SVamsi Attunuru octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
39*56139e85SVamsi Attunuru {
40*56139e85SVamsi Attunuru 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
41*56139e85SVamsi Attunuru 	struct rte_eth_rxmode *rxmode;
42*56139e85SVamsi Attunuru 	int rc = 0;
43*56139e85SVamsi Attunuru 
44*56139e85SVamsi Attunuru 	rxmode = &dev->data->dev_conf.rxmode;
45*56139e85SVamsi Attunuru 
46*56139e85SVamsi Attunuru 	if (mask & ETH_VLAN_EXTEND_MASK) {
47*56139e85SVamsi Attunuru 		octeontx_log_err("Extend offload not supported");
48*56139e85SVamsi Attunuru 		return -ENOTSUP;
49*56139e85SVamsi Attunuru 	}
50*56139e85SVamsi Attunuru 
51*56139e85SVamsi Attunuru 	if (mask & ETH_VLAN_STRIP_MASK) {
52*56139e85SVamsi Attunuru 		octeontx_log_err("VLAN strip offload not supported");
53*56139e85SVamsi Attunuru 		return -ENOTSUP;
54*56139e85SVamsi Attunuru 	}
55*56139e85SVamsi Attunuru 
56*56139e85SVamsi Attunuru 	if (mask & ETH_VLAN_FILTER_MASK) {
57*56139e85SVamsi Attunuru 		if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
58*56139e85SVamsi Attunuru 			rc = octeontx_vlan_hw_filter(nic, true);
59*56139e85SVamsi Attunuru 			if (rc)
60*56139e85SVamsi Attunuru 				goto done;
61*56139e85SVamsi Attunuru 
62*56139e85SVamsi Attunuru 			nic->rx_offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
63*56139e85SVamsi Attunuru 			nic->rx_offload_flags |= OCCTX_RX_VLAN_FLTR_F;
64*56139e85SVamsi Attunuru 		} else {
65*56139e85SVamsi Attunuru 			rc = octeontx_vlan_hw_filter(nic, false);
66*56139e85SVamsi Attunuru 			if (rc)
67*56139e85SVamsi Attunuru 				goto done;
68*56139e85SVamsi Attunuru 
69*56139e85SVamsi Attunuru 			nic->rx_offloads &= ~DEV_RX_OFFLOAD_VLAN_FILTER;
70*56139e85SVamsi Attunuru 			nic->rx_offload_flags &= ~OCCTX_RX_VLAN_FLTR_F;
71*56139e85SVamsi Attunuru 		}
72*56139e85SVamsi Attunuru 	}
73*56139e85SVamsi Attunuru 
74*56139e85SVamsi Attunuru done:
75*56139e85SVamsi Attunuru 	return rc;
76*56139e85SVamsi Attunuru }
77*56139e85SVamsi Attunuru 
78*56139e85SVamsi Attunuru int
79*56139e85SVamsi Attunuru octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
80*56139e85SVamsi Attunuru {
81*56139e85SVamsi Attunuru 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
82*56139e85SVamsi Attunuru 	struct octeontx_vlan_info *vlan = &nic->vlan_info;
83*56139e85SVamsi Attunuru 	pki_port_vlan_filter_entry_config_t fltr_entry;
84*56139e85SVamsi Attunuru 	struct vlan_entry *entry = NULL;
85*56139e85SVamsi Attunuru 	int entry_count = 0;
86*56139e85SVamsi Attunuru 	int rc = -EINVAL;
87*56139e85SVamsi Attunuru 
88*56139e85SVamsi Attunuru 	if (on) {
89*56139e85SVamsi Attunuru 		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
90*56139e85SVamsi Attunuru 			if (entry->vlan_id == vlan_id) {
91*56139e85SVamsi Attunuru 				octeontx_log_dbg("Vlan Id is already set");
92*56139e85SVamsi Attunuru 				return 0;
93*56139e85SVamsi Attunuru 			}
94*56139e85SVamsi Attunuru 	} else {
95*56139e85SVamsi Attunuru 		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
96*56139e85SVamsi Attunuru 			entry_count++;
97*56139e85SVamsi Attunuru 
98*56139e85SVamsi Attunuru 		if (!entry_count)
99*56139e85SVamsi Attunuru 			return 0;
100*56139e85SVamsi Attunuru 	}
101*56139e85SVamsi Attunuru 
102*56139e85SVamsi Attunuru 	fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
103*56139e85SVamsi Attunuru 	fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
104*56139e85SVamsi Attunuru 	fltr_entry.vlan_id = vlan_id;
105*56139e85SVamsi Attunuru 	fltr_entry.entry_conf = on;
106*56139e85SVamsi Attunuru 
107*56139e85SVamsi Attunuru 	if (on) {
108*56139e85SVamsi Attunuru 		entry = rte_zmalloc("octeontx_nic_vlan_entry",
109*56139e85SVamsi Attunuru 				    sizeof(struct vlan_entry), 0);
110*56139e85SVamsi Attunuru 		if (!entry) {
111*56139e85SVamsi Attunuru 			octeontx_log_err("Failed to allocate memory");
112*56139e85SVamsi Attunuru 			return -ENOMEM;
113*56139e85SVamsi Attunuru 		}
114*56139e85SVamsi Attunuru 	}
115*56139e85SVamsi Attunuru 
116*56139e85SVamsi Attunuru 	rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
117*56139e85SVamsi Attunuru 						      &fltr_entry);
118*56139e85SVamsi Attunuru 	if (rc != 0) {
119*56139e85SVamsi Attunuru 		octeontx_log_err("Fail to configure vlan filter entry "
120*56139e85SVamsi Attunuru 				 "for port %d", nic->port_id);
121*56139e85SVamsi Attunuru 		if (entry)
122*56139e85SVamsi Attunuru 			rte_free(entry);
123*56139e85SVamsi Attunuru 
124*56139e85SVamsi Attunuru 		goto done;
125*56139e85SVamsi Attunuru 	}
126*56139e85SVamsi Attunuru 
127*56139e85SVamsi Attunuru 	if (on) {
128*56139e85SVamsi Attunuru 		entry->vlan_id  = vlan_id;
129*56139e85SVamsi Attunuru 		TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next);
130*56139e85SVamsi Attunuru 	} else {
131*56139e85SVamsi Attunuru 		TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
132*56139e85SVamsi Attunuru 			if (entry->vlan_id == vlan_id) {
133*56139e85SVamsi Attunuru 				TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
134*56139e85SVamsi Attunuru 				rte_free(entry);
135*56139e85SVamsi Attunuru 				break;
136*56139e85SVamsi Attunuru 			}
137*56139e85SVamsi Attunuru 		}
138*56139e85SVamsi Attunuru 	}
139*56139e85SVamsi Attunuru 
140*56139e85SVamsi Attunuru done:
141*56139e85SVamsi Attunuru 	return rc;
142*56139e85SVamsi Attunuru }
143*56139e85SVamsi Attunuru 
144*56139e85SVamsi Attunuru int
145*56139e85SVamsi Attunuru octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev)
146*56139e85SVamsi Attunuru {
147*56139e85SVamsi Attunuru 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
148*56139e85SVamsi Attunuru 	int rc;
149*56139e85SVamsi Attunuru 
150*56139e85SVamsi Attunuru 	TAILQ_INIT(&nic->vlan_info.fltr_tbl);
151*56139e85SVamsi Attunuru 
152*56139e85SVamsi Attunuru 	rc = octeontx_dev_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
153*56139e85SVamsi Attunuru 	if (rc)
154*56139e85SVamsi Attunuru 		octeontx_log_err("Failed to set vlan offload rc=%d", rc);
155*56139e85SVamsi Attunuru 
156*56139e85SVamsi Attunuru 	return rc;
157*56139e85SVamsi Attunuru }
158*56139e85SVamsi Attunuru 
159*56139e85SVamsi Attunuru int
160*56139e85SVamsi Attunuru octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev)
161*56139e85SVamsi Attunuru {
162*56139e85SVamsi Attunuru 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
163*56139e85SVamsi Attunuru 	struct octeontx_vlan_info *vlan = &nic->vlan_info;
164*56139e85SVamsi Attunuru 	pki_port_vlan_filter_entry_config_t fltr_entry;
165*56139e85SVamsi Attunuru 	struct vlan_entry *entry;
166*56139e85SVamsi Attunuru 	int rc = 0;
167*56139e85SVamsi Attunuru 
168*56139e85SVamsi Attunuru 	TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
169*56139e85SVamsi Attunuru 		fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
170*56139e85SVamsi Attunuru 		fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
171*56139e85SVamsi Attunuru 		fltr_entry.vlan_id = entry->vlan_id;
172*56139e85SVamsi Attunuru 		fltr_entry.entry_conf = 0;
173*56139e85SVamsi Attunuru 
174*56139e85SVamsi Attunuru 		rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
175*56139e85SVamsi Attunuru 							      &fltr_entry);
176*56139e85SVamsi Attunuru 		if (rc != 0) {
177*56139e85SVamsi Attunuru 			octeontx_log_err("Fail to configure vlan filter entry "
178*56139e85SVamsi Attunuru 					 "for port %d", nic->port_id);
179*56139e85SVamsi Attunuru 			break;
180*56139e85SVamsi Attunuru 		}
181*56139e85SVamsi Attunuru 	}
182*56139e85SVamsi Attunuru 
183*56139e85SVamsi Attunuru 	return rc;
184*56139e85SVamsi Attunuru }
185