1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2020 Marvell International Ltd.
5 #include <rte_malloc.h>
7 #include "octeontx_ethdev.h"
8 #include "octeontx_logs.h"
9 #include "octeontx_rxtx.h"
12 octeontx_vlan_hw_filter(struct octeontx_nic *nic, uint8_t flag)
14 struct octeontx_vlan_info *vlan = &nic->vlan_info;
15 pki_port_vlan_filter_config_t fltr_conf;
18 if (vlan->filter_on == flag)
21 fltr_conf.port_type = OCTTX_PORT_TYPE_NET;
22 fltr_conf.fltr_conf = flag;
24 rc = octeontx_pki_port_vlan_fltr_config(nic->port_id, &fltr_conf);
26 octeontx_log_err("Fail to configure vlan hw filter for port %d",
31 vlan->filter_on = flag;
38 octeontx_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
40 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
41 struct rte_eth_rxmode *rxmode;
44 rxmode = &dev->data->dev_conf.rxmode;
46 if (mask & RTE_ETH_VLAN_FILTER_MASK) {
47 if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
48 rc = octeontx_vlan_hw_filter(nic, true);
52 nic->rx_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
53 nic->rx_offload_flags |= OCCTX_RX_VLAN_FLTR_F;
55 rc = octeontx_vlan_hw_filter(nic, false);
59 nic->rx_offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
60 nic->rx_offload_flags &= ~OCCTX_RX_VLAN_FLTR_F;
69 octeontx_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
71 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
72 struct octeontx_vlan_info *vlan = &nic->vlan_info;
73 pki_port_vlan_filter_entry_config_t fltr_entry;
74 struct vlan_entry *entry = NULL;
79 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
80 if (entry->vlan_id == vlan_id) {
81 octeontx_log_dbg("Vlan Id is already set");
85 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next)
92 fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
93 fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
94 fltr_entry.vlan_id = vlan_id;
95 fltr_entry.entry_conf = on;
98 entry = rte_zmalloc("octeontx_nic_vlan_entry",
99 sizeof(struct vlan_entry), 0);
101 octeontx_log_err("Failed to allocate memory");
106 rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
109 octeontx_log_err("Fail to configure vlan filter entry "
110 "for port %d", nic->port_id);
117 entry->vlan_id = vlan_id;
118 TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next);
120 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
121 if (entry->vlan_id == vlan_id) {
122 TAILQ_REMOVE(&vlan->fltr_tbl, entry, next);
134 octeontx_dev_vlan_offload_init(struct rte_eth_dev *dev)
136 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
139 TAILQ_INIT(&nic->vlan_info.fltr_tbl);
141 rc = octeontx_dev_vlan_offload_set(dev, RTE_ETH_VLAN_FILTER_MASK);
143 octeontx_log_err("Failed to set vlan offload rc=%d", rc);
149 octeontx_dev_vlan_offload_fini(struct rte_eth_dev *dev)
151 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
152 struct octeontx_vlan_info *vlan = &nic->vlan_info;
153 pki_port_vlan_filter_entry_config_t fltr_entry;
154 struct vlan_entry *entry;
157 TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) {
158 fltr_entry.port_type = OCTTX_PORT_TYPE_NET;
159 fltr_entry.vlan_tpid = RTE_ETHER_TYPE_VLAN;
160 fltr_entry.vlan_id = entry->vlan_id;
161 fltr_entry.entry_conf = 0;
163 rc = octeontx_pki_port_vlan_fltr_entry_config(nic->port_id,
166 octeontx_log_err("Fail to configure vlan filter entry "
167 "for port %d", nic->port_id);
176 octeontx_dev_set_link_up(struct rte_eth_dev *eth_dev)
178 struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
181 rc = octeontx_bgx_port_set_link_state(nic->port_id, true);
185 /* Start tx queues */
186 for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
187 octeontx_dev_tx_queue_start(eth_dev, i);
194 octeontx_dev_set_link_down(struct rte_eth_dev *eth_dev)
196 struct octeontx_nic *nic = octeontx_pmd_priv(eth_dev);
200 for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
201 octeontx_dev_tx_queue_stop(eth_dev, i);
203 return octeontx_bgx_port_set_link_state(nic->port_id, false);
207 octeontx_dev_flow_ctrl_get(struct rte_eth_dev *dev,
208 struct rte_eth_fc_conf *fc_conf)
210 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
211 octeontx_mbox_bgx_port_fc_cfg_t conf;
214 memset(&conf, 0, sizeof(octeontx_mbox_bgx_port_fc_cfg_t));
216 rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
220 if (conf.rx_pause && conf.tx_pause)
221 fc_conf->mode = RTE_ETH_FC_FULL;
222 else if (conf.rx_pause)
223 fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
224 else if (conf.tx_pause)
225 fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
227 fc_conf->mode = RTE_ETH_FC_NONE;
229 /* low_water & high_water values are in Bytes */
230 fc_conf->low_water = conf.low_water;
231 fc_conf->high_water = conf.high_water;
237 octeontx_dev_flow_ctrl_set(struct rte_eth_dev *dev,
238 struct rte_eth_fc_conf *fc_conf)
240 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
241 struct octeontx_fc_info *fc = &nic->fc;
242 octeontx_mbox_bgx_port_fc_cfg_t conf;
243 uint8_t tx_pause, rx_pause;
244 uint16_t max_high_water;
247 if (fc_conf->pause_time || fc_conf->mac_ctrl_frame_fwd ||
249 octeontx_log_err("Below flowctrl parameters are not supported "
250 "pause_time, mac_ctrl_frame_fwd and autoneg");
254 if (fc_conf->high_water == fc->high_water &&
255 fc_conf->low_water == fc->low_water &&
256 fc_conf->mode == fc->mode)
259 max_high_water = fc->rx_fifosz - OCTEONTX_BGX_RSVD_RX_FIFOBYTES;
261 if (fc_conf->high_water > max_high_water ||
262 fc_conf->high_water < fc_conf->low_water) {
263 octeontx_log_err("Invalid high/low water values "
264 "High_water(in Bytes) must <= 0x%x ",
269 if (fc_conf->high_water % BIT(4) || fc_conf->low_water % BIT(4)) {
270 octeontx_log_err("High/low water value must be multiple of 16");
274 rx_pause = (fc_conf->mode == RTE_ETH_FC_FULL) ||
275 (fc_conf->mode == RTE_ETH_FC_RX_PAUSE);
276 tx_pause = (fc_conf->mode == RTE_ETH_FC_FULL) ||
277 (fc_conf->mode == RTE_ETH_FC_TX_PAUSE);
279 conf.high_water = fc_conf->high_water;
280 conf.low_water = fc_conf->low_water;
281 conf.fc_cfg = BGX_PORT_FC_CFG_SET;
282 conf.rx_pause = rx_pause;
283 conf.tx_pause = tx_pause;
285 rc = octeontx_bgx_port_flow_ctrl_cfg(nic->port_id, &conf);
289 fc->high_water = fc_conf->high_water;
290 fc->low_water = fc_conf->low_water;
291 fc->mode = fc_conf->mode;
297 octeontx_dev_flow_ctrl_init(struct rte_eth_dev *dev)
299 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
300 struct octeontx_fc_info *fc = &nic->fc;
301 struct rte_eth_fc_conf fc_conf;
304 rc = octeontx_dev_flow_ctrl_get(dev, &fc_conf);
306 octeontx_log_err("Failed to get flow control info");
310 fc->def_highmark = fc_conf.high_water;
311 fc->def_lowmark = fc_conf.low_water;
312 fc->def_mode = fc_conf.mode;
318 octeontx_dev_flow_ctrl_fini(struct rte_eth_dev *dev)
320 struct octeontx_nic *nic = octeontx_pmd_priv(dev);
321 struct octeontx_fc_info *fc = &nic->fc;
322 struct rte_eth_fc_conf fc_conf;
324 memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf));
326 /* Restore flow control parameters with default values */
327 fc_conf.high_water = fc->def_highmark;
328 fc_conf.low_water = fc->def_lowmark;
329 fc_conf.mode = fc->def_mode;
331 return octeontx_dev_flow_ctrl_set(dev, &fc_conf);