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