160229dcfSJiawen Wu /* SPDX-License-Identifier: BSD-3-Clause 260229dcfSJiawen Wu * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd. 360229dcfSJiawen Wu * Copyright(c) 2010-2017 Intel Corporation 460229dcfSJiawen Wu */ 560229dcfSJiawen Wu 660229dcfSJiawen Wu #include <rte_ether.h> 760229dcfSJiawen Wu #include <ethdev_driver.h> 860229dcfSJiawen Wu #include <rte_malloc.h> 91f37cb2bSDavid Marchand #include <bus_pci_driver.h> 1060229dcfSJiawen Wu 1160229dcfSJiawen Wu #include "base/ngbe.h" 1260229dcfSJiawen Wu #include "ngbe_ethdev.h" 1360229dcfSJiawen Wu 1460229dcfSJiawen Wu #define NGBE_MAX_VFTA (128) 15e2a289a7SJiawen Wu #define NGBE_VF_MSG_SIZE_DEFAULT 1 16e2a289a7SJiawen Wu #define NGBE_VF_GET_QUEUE_MSG_SIZE 5 1760229dcfSJiawen Wu 1860229dcfSJiawen Wu static inline uint16_t 1960229dcfSJiawen Wu dev_num_vf(struct rte_eth_dev *eth_dev) 2060229dcfSJiawen Wu { 2160229dcfSJiawen Wu struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); 2260229dcfSJiawen Wu 2360229dcfSJiawen Wu /* EM only support 7 VFs. */ 2460229dcfSJiawen Wu return pci_dev->max_vfs; 2560229dcfSJiawen Wu } 2660229dcfSJiawen Wu 2760229dcfSJiawen Wu static inline 2860229dcfSJiawen Wu int ngbe_vf_perm_addr_gen(struct rte_eth_dev *dev, uint16_t vf_num) 2960229dcfSJiawen Wu { 3060229dcfSJiawen Wu unsigned char vf_mac_addr[RTE_ETHER_ADDR_LEN]; 3160229dcfSJiawen Wu struct ngbe_vf_info *vfinfo = *NGBE_DEV_VFDATA(dev); 3260229dcfSJiawen Wu uint16_t vfn; 3360229dcfSJiawen Wu 3460229dcfSJiawen Wu for (vfn = 0; vfn < vf_num; vfn++) { 3560229dcfSJiawen Wu rte_eth_random_addr(vf_mac_addr); 3660229dcfSJiawen Wu /* keep the random address as default */ 3760229dcfSJiawen Wu memcpy(vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 3860229dcfSJiawen Wu RTE_ETHER_ADDR_LEN); 3960229dcfSJiawen Wu } 4060229dcfSJiawen Wu 4160229dcfSJiawen Wu return 0; 4260229dcfSJiawen Wu } 4360229dcfSJiawen Wu 44e2a289a7SJiawen Wu static inline int 45e2a289a7SJiawen Wu ngbe_mb_intr_setup(struct rte_eth_dev *dev) 46e2a289a7SJiawen Wu { 47e2a289a7SJiawen Wu struct ngbe_interrupt *intr = ngbe_dev_intr(dev); 48e2a289a7SJiawen Wu 49e2a289a7SJiawen Wu intr->mask_misc |= NGBE_ICRMISC_VFMBX; 50e2a289a7SJiawen Wu 51e2a289a7SJiawen Wu return 0; 52e2a289a7SJiawen Wu } 53e2a289a7SJiawen Wu 5460229dcfSJiawen Wu int ngbe_pf_host_init(struct rte_eth_dev *eth_dev) 5560229dcfSJiawen Wu { 5660229dcfSJiawen Wu struct ngbe_vf_info **vfinfo = NGBE_DEV_VFDATA(eth_dev); 5760229dcfSJiawen Wu struct ngbe_uta_info *uta_info = NGBE_DEV_UTA_INFO(eth_dev); 5860229dcfSJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 5960229dcfSJiawen Wu uint16_t vf_num; 6060229dcfSJiawen Wu uint8_t nb_queue = 1; 6160229dcfSJiawen Wu int ret = 0; 6260229dcfSJiawen Wu 6360229dcfSJiawen Wu PMD_INIT_FUNC_TRACE(); 6460229dcfSJiawen Wu 6560229dcfSJiawen Wu RTE_ETH_DEV_SRIOV(eth_dev).active = 0; 6660229dcfSJiawen Wu vf_num = dev_num_vf(eth_dev); 6760229dcfSJiawen Wu if (vf_num == 0) 6860229dcfSJiawen Wu return ret; 6960229dcfSJiawen Wu 7060229dcfSJiawen Wu *vfinfo = rte_zmalloc("vf_info", 7160229dcfSJiawen Wu sizeof(struct ngbe_vf_info) * vf_num, 0); 7260229dcfSJiawen Wu if (*vfinfo == NULL) { 7360229dcfSJiawen Wu PMD_INIT_LOG(ERR, 74*f665790aSDavid Marchand "Cannot allocate memory for private VF data"); 7560229dcfSJiawen Wu return -ENOMEM; 7660229dcfSJiawen Wu } 7760229dcfSJiawen Wu 7860229dcfSJiawen Wu ret = rte_eth_switch_domain_alloc(&(*vfinfo)->switch_domain_id); 7960229dcfSJiawen Wu if (ret) { 8060229dcfSJiawen Wu PMD_INIT_LOG(ERR, 8160229dcfSJiawen Wu "failed to allocate switch domain for device %d", ret); 8260229dcfSJiawen Wu rte_free(*vfinfo); 8360229dcfSJiawen Wu *vfinfo = NULL; 8460229dcfSJiawen Wu return ret; 8560229dcfSJiawen Wu } 8660229dcfSJiawen Wu 8760229dcfSJiawen Wu memset(uta_info, 0, sizeof(struct ngbe_uta_info)); 8860229dcfSJiawen Wu hw->mac.mc_filter_type = 0; 8960229dcfSJiawen Wu 9060229dcfSJiawen Wu RTE_ETH_DEV_SRIOV(eth_dev).active = RTE_ETH_8_POOLS; 9160229dcfSJiawen Wu RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = nb_queue; 9260229dcfSJiawen Wu RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx = 9360229dcfSJiawen Wu (uint16_t)(vf_num * nb_queue); 9460229dcfSJiawen Wu 9560229dcfSJiawen Wu ngbe_vf_perm_addr_gen(eth_dev, vf_num); 9660229dcfSJiawen Wu 9760229dcfSJiawen Wu /* init_mailbox_params */ 9860229dcfSJiawen Wu hw->mbx.init_params(hw); 9960229dcfSJiawen Wu 100e2a289a7SJiawen Wu /* set mb interrupt mask */ 101e2a289a7SJiawen Wu ngbe_mb_intr_setup(eth_dev); 102e2a289a7SJiawen Wu 10360229dcfSJiawen Wu return ret; 10460229dcfSJiawen Wu } 10560229dcfSJiawen Wu 10660229dcfSJiawen Wu void ngbe_pf_host_uninit(struct rte_eth_dev *eth_dev) 10760229dcfSJiawen Wu { 10860229dcfSJiawen Wu struct ngbe_vf_info **vfinfo; 10960229dcfSJiawen Wu uint16_t vf_num; 11060229dcfSJiawen Wu int ret; 11160229dcfSJiawen Wu 11260229dcfSJiawen Wu PMD_INIT_FUNC_TRACE(); 11360229dcfSJiawen Wu 11460229dcfSJiawen Wu RTE_ETH_DEV_SRIOV(eth_dev).active = 0; 11560229dcfSJiawen Wu RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = 0; 11660229dcfSJiawen Wu RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx = 0; 11760229dcfSJiawen Wu 11860229dcfSJiawen Wu vf_num = dev_num_vf(eth_dev); 11960229dcfSJiawen Wu if (vf_num == 0) 12060229dcfSJiawen Wu return; 12160229dcfSJiawen Wu 12260229dcfSJiawen Wu vfinfo = NGBE_DEV_VFDATA(eth_dev); 12360229dcfSJiawen Wu if (*vfinfo == NULL) 12460229dcfSJiawen Wu return; 12560229dcfSJiawen Wu 12660229dcfSJiawen Wu ret = rte_eth_switch_domain_free((*vfinfo)->switch_domain_id); 12760229dcfSJiawen Wu if (ret) 12860229dcfSJiawen Wu PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret); 12960229dcfSJiawen Wu 13060229dcfSJiawen Wu rte_free(*vfinfo); 13160229dcfSJiawen Wu *vfinfo = NULL; 13260229dcfSJiawen Wu } 13360229dcfSJiawen Wu 13460229dcfSJiawen Wu int ngbe_pf_host_configure(struct rte_eth_dev *eth_dev) 13560229dcfSJiawen Wu { 13660229dcfSJiawen Wu uint32_t vtctl, fcrth; 13760229dcfSJiawen Wu uint32_t vfre_offset; 13860229dcfSJiawen Wu uint16_t vf_num; 13960229dcfSJiawen Wu const uint8_t VFRE_SHIFT = 5; /* VFRE 32 bits per slot */ 14060229dcfSJiawen Wu const uint8_t VFRE_MASK = (uint8_t)((1U << VFRE_SHIFT) - 1); 14160229dcfSJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 14260229dcfSJiawen Wu uint32_t gpie; 14360229dcfSJiawen Wu uint32_t gcr_ext; 14460229dcfSJiawen Wu uint32_t vlanctrl; 14560229dcfSJiawen Wu int i; 14660229dcfSJiawen Wu 14760229dcfSJiawen Wu vf_num = dev_num_vf(eth_dev); 14860229dcfSJiawen Wu if (vf_num == 0) 14960229dcfSJiawen Wu return -1; 15060229dcfSJiawen Wu 15160229dcfSJiawen Wu /* set the default pool for PF */ 15260229dcfSJiawen Wu vtctl = rd32(hw, NGBE_POOLCTL); 15360229dcfSJiawen Wu vtctl &= ~NGBE_POOLCTL_DEFPL_MASK; 15460229dcfSJiawen Wu vtctl |= NGBE_POOLCTL_DEFPL(vf_num); 15560229dcfSJiawen Wu vtctl |= NGBE_POOLCTL_RPLEN; 15660229dcfSJiawen Wu wr32(hw, NGBE_POOLCTL, vtctl); 15760229dcfSJiawen Wu 15860229dcfSJiawen Wu vfre_offset = vf_num & VFRE_MASK; 15960229dcfSJiawen Wu 16060229dcfSJiawen Wu /* Enable pools reserved to PF only */ 16160229dcfSJiawen Wu wr32(hw, NGBE_POOLRXENA(0), (~0U) << vfre_offset); 16260229dcfSJiawen Wu wr32(hw, NGBE_POOLTXENA(0), (~0U) << vfre_offset); 16360229dcfSJiawen Wu 16460229dcfSJiawen Wu wr32(hw, NGBE_PSRCTL, NGBE_PSRCTL_LBENA); 16560229dcfSJiawen Wu 1667be78d02SJosh Soref /* clear VMDq map to permanent rar 0 */ 16760229dcfSJiawen Wu hw->mac.clear_vmdq(hw, 0, BIT_MASK32); 16860229dcfSJiawen Wu 16960229dcfSJiawen Wu /* clear VMDq map to scan rar 31 */ 17060229dcfSJiawen Wu wr32(hw, NGBE_ETHADDRIDX, hw->mac.num_rar_entries); 17160229dcfSJiawen Wu wr32(hw, NGBE_ETHADDRASS, 0); 17260229dcfSJiawen Wu 17360229dcfSJiawen Wu /* set VMDq map to default PF pool */ 17460229dcfSJiawen Wu hw->mac.set_vmdq(hw, 0, vf_num); 17560229dcfSJiawen Wu 17660229dcfSJiawen Wu /* 17760229dcfSJiawen Wu * SW msut set PORTCTL.VT_Mode the same as GPIE.VT_Mode 17860229dcfSJiawen Wu */ 17960229dcfSJiawen Wu gpie = rd32(hw, NGBE_GPIE); 18060229dcfSJiawen Wu gpie |= NGBE_GPIE_MSIX; 18160229dcfSJiawen Wu gcr_ext = rd32(hw, NGBE_PORTCTL); 18260229dcfSJiawen Wu gcr_ext &= ~NGBE_PORTCTL_NUMVT_MASK; 18360229dcfSJiawen Wu 18460229dcfSJiawen Wu if (RTE_ETH_DEV_SRIOV(eth_dev).active == RTE_ETH_8_POOLS) 18560229dcfSJiawen Wu gcr_ext |= NGBE_PORTCTL_NUMVT_8; 18660229dcfSJiawen Wu 18760229dcfSJiawen Wu wr32(hw, NGBE_PORTCTL, gcr_ext); 18860229dcfSJiawen Wu wr32(hw, NGBE_GPIE, gpie); 18960229dcfSJiawen Wu 19060229dcfSJiawen Wu /* 19160229dcfSJiawen Wu * enable vlan filtering and allow all vlan tags through 19260229dcfSJiawen Wu */ 19360229dcfSJiawen Wu vlanctrl = rd32(hw, NGBE_VLANCTL); 19460229dcfSJiawen Wu vlanctrl |= NGBE_VLANCTL_VFE; /* enable vlan filters */ 19560229dcfSJiawen Wu wr32(hw, NGBE_VLANCTL, vlanctrl); 19660229dcfSJiawen Wu 19760229dcfSJiawen Wu /* enable all vlan filters */ 19860229dcfSJiawen Wu for (i = 0; i < NGBE_MAX_VFTA; i++) 19960229dcfSJiawen Wu wr32(hw, NGBE_VLANTBL(i), 0xFFFFFFFF); 20060229dcfSJiawen Wu 20160229dcfSJiawen Wu /* Enable MAC Anti-Spoofing */ 20260229dcfSJiawen Wu hw->mac.set_mac_anti_spoofing(hw, FALSE, vf_num); 20360229dcfSJiawen Wu 20460229dcfSJiawen Wu /* set flow control threshold to max to avoid tx switch hang */ 20560229dcfSJiawen Wu wr32(hw, NGBE_FCWTRLO, 0); 20660229dcfSJiawen Wu fcrth = rd32(hw, NGBE_PBRXSIZE) - 32; 20760229dcfSJiawen Wu wr32(hw, NGBE_FCWTRHI, fcrth); 20860229dcfSJiawen Wu 20960229dcfSJiawen Wu return 0; 21060229dcfSJiawen Wu } 21160229dcfSJiawen Wu 212e2a289a7SJiawen Wu static void 213e2a289a7SJiawen Wu ngbe_set_rx_mode(struct rte_eth_dev *eth_dev) 214e2a289a7SJiawen Wu { 215e2a289a7SJiawen Wu struct rte_eth_dev_data *dev_data = eth_dev->data; 216e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 217e2a289a7SJiawen Wu u32 fctrl, vmolr; 218e2a289a7SJiawen Wu uint16_t vfn = dev_num_vf(eth_dev); 219e2a289a7SJiawen Wu 220e2a289a7SJiawen Wu /* disable store-bad-packets */ 221e2a289a7SJiawen Wu wr32m(hw, NGBE_SECRXCTL, NGBE_SECRXCTL_SAVEBAD, 0); 222e2a289a7SJiawen Wu 223e2a289a7SJiawen Wu /* Check for Promiscuous and All Multicast modes */ 224e2a289a7SJiawen Wu fctrl = rd32m(hw, NGBE_PSRCTL, 225e2a289a7SJiawen Wu ~(NGBE_PSRCTL_UCP | NGBE_PSRCTL_MCP)); 226e2a289a7SJiawen Wu fctrl |= NGBE_PSRCTL_BCA | 227e2a289a7SJiawen Wu NGBE_PSRCTL_MCHFENA; 228e2a289a7SJiawen Wu 229e2a289a7SJiawen Wu vmolr = rd32m(hw, NGBE_POOLETHCTL(vfn), 230e2a289a7SJiawen Wu ~(NGBE_POOLETHCTL_UCP | 231e2a289a7SJiawen Wu NGBE_POOLETHCTL_MCP | 232e2a289a7SJiawen Wu NGBE_POOLETHCTL_UCHA | 233e2a289a7SJiawen Wu NGBE_POOLETHCTL_MCHA)); 234e2a289a7SJiawen Wu vmolr |= NGBE_POOLETHCTL_BCA | 235e2a289a7SJiawen Wu NGBE_POOLETHCTL_UTA | 236e2a289a7SJiawen Wu NGBE_POOLETHCTL_VLA; 237e2a289a7SJiawen Wu 238e2a289a7SJiawen Wu if (dev_data->promiscuous) { 239e2a289a7SJiawen Wu fctrl |= NGBE_PSRCTL_UCP | 240e2a289a7SJiawen Wu NGBE_PSRCTL_MCP; 241e2a289a7SJiawen Wu /* pf don't want packets routing to vf, so clear UPE */ 242e2a289a7SJiawen Wu vmolr |= NGBE_POOLETHCTL_MCP; 243e2a289a7SJiawen Wu } else if (dev_data->all_multicast) { 244e2a289a7SJiawen Wu fctrl |= NGBE_PSRCTL_MCP; 245e2a289a7SJiawen Wu vmolr |= NGBE_POOLETHCTL_MCP; 246e2a289a7SJiawen Wu } else { 247e2a289a7SJiawen Wu vmolr |= NGBE_POOLETHCTL_UCHA; 248e2a289a7SJiawen Wu vmolr |= NGBE_POOLETHCTL_MCHA; 249e2a289a7SJiawen Wu } 250e2a289a7SJiawen Wu 251e2a289a7SJiawen Wu wr32(hw, NGBE_POOLETHCTL(vfn), vmolr); 252e2a289a7SJiawen Wu 253e2a289a7SJiawen Wu wr32(hw, NGBE_PSRCTL, fctrl); 254e2a289a7SJiawen Wu 255e2a289a7SJiawen Wu ngbe_vlan_hw_strip_config(eth_dev); 256e2a289a7SJiawen Wu } 257e2a289a7SJiawen Wu 258e2a289a7SJiawen Wu static inline void 259e2a289a7SJiawen Wu ngbe_vf_reset_event(struct rte_eth_dev *eth_dev, uint16_t vf) 260e2a289a7SJiawen Wu { 261e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 262e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *(NGBE_DEV_VFDATA(eth_dev)); 263e2a289a7SJiawen Wu int rar_entry = hw->mac.num_rar_entries - (vf + 1); 264e2a289a7SJiawen Wu uint32_t vmolr = rd32(hw, NGBE_POOLETHCTL(vf)); 265e2a289a7SJiawen Wu 266e2a289a7SJiawen Wu vmolr |= (NGBE_POOLETHCTL_UCHA | 267e2a289a7SJiawen Wu NGBE_POOLETHCTL_BCA | NGBE_POOLETHCTL_UTA); 268e2a289a7SJiawen Wu wr32(hw, NGBE_POOLETHCTL(vf), vmolr); 269e2a289a7SJiawen Wu 270e2a289a7SJiawen Wu wr32(hw, NGBE_POOLTAG(vf), 0); 271e2a289a7SJiawen Wu 272e2a289a7SJiawen Wu /* reset multicast table array for vf */ 273e2a289a7SJiawen Wu vfinfo[vf].num_vf_mc_hashes = 0; 274e2a289a7SJiawen Wu 275e2a289a7SJiawen Wu /* reset rx mode */ 276e2a289a7SJiawen Wu ngbe_set_rx_mode(eth_dev); 277e2a289a7SJiawen Wu 278e2a289a7SJiawen Wu hw->mac.clear_rar(hw, rar_entry); 279e2a289a7SJiawen Wu } 280e2a289a7SJiawen Wu 281e2a289a7SJiawen Wu static inline void 282e2a289a7SJiawen Wu ngbe_vf_reset_msg(struct rte_eth_dev *eth_dev, uint16_t vf) 283e2a289a7SJiawen Wu { 284e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 285e2a289a7SJiawen Wu uint32_t reg; 286e2a289a7SJiawen Wu uint32_t vf_shift; 287e2a289a7SJiawen Wu const uint8_t VFRE_SHIFT = 5; /* VFRE 32 bits per slot */ 288e2a289a7SJiawen Wu const uint8_t VFRE_MASK = (uint8_t)((1U << VFRE_SHIFT) - 1); 289e2a289a7SJiawen Wu uint8_t nb_q_per_pool; 290e2a289a7SJiawen Wu int i; 291e2a289a7SJiawen Wu 292e2a289a7SJiawen Wu vf_shift = vf & VFRE_MASK; 293e2a289a7SJiawen Wu 294e2a289a7SJiawen Wu /* enable transmit for vf */ 295e2a289a7SJiawen Wu reg = rd32(hw, NGBE_POOLTXENA(0)); 296e2a289a7SJiawen Wu reg |= (1 << vf_shift); 297e2a289a7SJiawen Wu wr32(hw, NGBE_POOLTXENA(0), reg); 298e2a289a7SJiawen Wu 299e2a289a7SJiawen Wu /* enable all queue drop for IOV */ 300e2a289a7SJiawen Wu nb_q_per_pool = RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool; 301e2a289a7SJiawen Wu for (i = vf * nb_q_per_pool; i < (vf + 1) * nb_q_per_pool; i++) { 302e2a289a7SJiawen Wu ngbe_flush(hw); 303e2a289a7SJiawen Wu reg = 1 << (i % 32); 304e2a289a7SJiawen Wu wr32m(hw, NGBE_QPRXDROP, reg, reg); 305e2a289a7SJiawen Wu } 306e2a289a7SJiawen Wu 307e2a289a7SJiawen Wu /* enable receive for vf */ 308e2a289a7SJiawen Wu reg = rd32(hw, NGBE_POOLRXENA(0)); 309e2a289a7SJiawen Wu reg |= (reg | (1 << vf_shift)); 310e2a289a7SJiawen Wu wr32(hw, NGBE_POOLRXENA(0), reg); 311e2a289a7SJiawen Wu 312e2a289a7SJiawen Wu ngbe_vf_reset_event(eth_dev, vf); 313e2a289a7SJiawen Wu } 314e2a289a7SJiawen Wu 315e2a289a7SJiawen Wu static int 316e2a289a7SJiawen Wu ngbe_disable_vf_mc_promisc(struct rte_eth_dev *eth_dev, uint32_t vf) 317e2a289a7SJiawen Wu { 318e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 319e2a289a7SJiawen Wu uint32_t vmolr; 320e2a289a7SJiawen Wu 321e2a289a7SJiawen Wu vmolr = rd32(hw, NGBE_POOLETHCTL(vf)); 322e2a289a7SJiawen Wu 323*f665790aSDavid Marchand PMD_DRV_LOG(INFO, "VF %u: disabling multicast promiscuous", vf); 324e2a289a7SJiawen Wu 325e2a289a7SJiawen Wu vmolr &= ~NGBE_POOLETHCTL_MCP; 326e2a289a7SJiawen Wu 327e2a289a7SJiawen Wu wr32(hw, NGBE_POOLETHCTL(vf), vmolr); 328e2a289a7SJiawen Wu 329e2a289a7SJiawen Wu return 0; 330e2a289a7SJiawen Wu } 331e2a289a7SJiawen Wu 332e2a289a7SJiawen Wu static int 333e2a289a7SJiawen Wu ngbe_vf_reset(struct rte_eth_dev *eth_dev, uint16_t vf, uint32_t *msgbuf) 334e2a289a7SJiawen Wu { 335e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 336e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *(NGBE_DEV_VFDATA(eth_dev)); 337e2a289a7SJiawen Wu unsigned char *vf_mac = vfinfo[vf].vf_mac_addresses; 338e2a289a7SJiawen Wu int rar_entry = hw->mac.num_rar_entries - (vf + 1); 339e2a289a7SJiawen Wu uint8_t *new_mac = (uint8_t *)(&msgbuf[1]); 340e2a289a7SJiawen Wu 341e2a289a7SJiawen Wu ngbe_vf_reset_msg(eth_dev, vf); 342e2a289a7SJiawen Wu 343e2a289a7SJiawen Wu hw->mac.set_rar(hw, rar_entry, vf_mac, vf, true); 344e2a289a7SJiawen Wu 345e2a289a7SJiawen Wu /* Disable multicast promiscuous at reset */ 346e2a289a7SJiawen Wu ngbe_disable_vf_mc_promisc(eth_dev, vf); 347e2a289a7SJiawen Wu 348e2a289a7SJiawen Wu /* reply to reset with ack and vf mac address */ 349e2a289a7SJiawen Wu msgbuf[0] = NGBE_VF_RESET | NGBE_VT_MSGTYPE_ACK; 350e2a289a7SJiawen Wu rte_memcpy(new_mac, vf_mac, RTE_ETHER_ADDR_LEN); 351e2a289a7SJiawen Wu /* 352e2a289a7SJiawen Wu * Piggyback the multicast filter type so VF can compute the 353e2a289a7SJiawen Wu * correct vectors 354e2a289a7SJiawen Wu */ 355e2a289a7SJiawen Wu msgbuf[3] = hw->mac.mc_filter_type; 356e2a289a7SJiawen Wu ngbe_write_mbx(hw, msgbuf, NGBE_VF_PERMADDR_MSG_LEN, vf); 357e2a289a7SJiawen Wu 358e2a289a7SJiawen Wu return 0; 359e2a289a7SJiawen Wu } 360e2a289a7SJiawen Wu 361e2a289a7SJiawen Wu static int 362e2a289a7SJiawen Wu ngbe_vf_set_mac_addr(struct rte_eth_dev *eth_dev, 363e2a289a7SJiawen Wu uint32_t vf, uint32_t *msgbuf) 364e2a289a7SJiawen Wu { 365e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 366e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *(NGBE_DEV_VFDATA(eth_dev)); 367e2a289a7SJiawen Wu int rar_entry = hw->mac.num_rar_entries - (vf + 1); 368e2a289a7SJiawen Wu uint8_t *new_mac = (uint8_t *)(&msgbuf[1]); 369e2a289a7SJiawen Wu struct rte_ether_addr *ea = (struct rte_ether_addr *)new_mac; 370e2a289a7SJiawen Wu 371e2a289a7SJiawen Wu if (rte_is_valid_assigned_ether_addr(ea)) { 372e2a289a7SJiawen Wu rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, 6); 373e2a289a7SJiawen Wu return hw->mac.set_rar(hw, rar_entry, new_mac, vf, true); 374e2a289a7SJiawen Wu } 375e2a289a7SJiawen Wu return -1; 376e2a289a7SJiawen Wu } 377e2a289a7SJiawen Wu 378e2a289a7SJiawen Wu static int 379e2a289a7SJiawen Wu ngbe_vf_set_multicast(struct rte_eth_dev *eth_dev, 380e2a289a7SJiawen Wu uint32_t vf, uint32_t *msgbuf) 381e2a289a7SJiawen Wu { 382e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 383e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *(NGBE_DEV_VFDATA(eth_dev)); 384e2a289a7SJiawen Wu int nb_entries = (msgbuf[0] & NGBE_VT_MSGINFO_MASK) >> 385e2a289a7SJiawen Wu NGBE_VT_MSGINFO_SHIFT; 386e2a289a7SJiawen Wu uint16_t *hash_list = (uint16_t *)&msgbuf[1]; 387e2a289a7SJiawen Wu uint32_t mta_idx; 388e2a289a7SJiawen Wu uint32_t mta_shift; 389e2a289a7SJiawen Wu const uint32_t NGBE_MTA_INDEX_MASK = 0x7F; 390e2a289a7SJiawen Wu const uint32_t NGBE_MTA_BIT_SHIFT = 5; 391e2a289a7SJiawen Wu const uint32_t NGBE_MTA_BIT_MASK = (0x1 << NGBE_MTA_BIT_SHIFT) - 1; 392e2a289a7SJiawen Wu uint32_t reg_val; 393e2a289a7SJiawen Wu int i; 394e2a289a7SJiawen Wu u32 vmolr = rd32(hw, NGBE_POOLETHCTL(vf)); 395e2a289a7SJiawen Wu 396e2a289a7SJiawen Wu /* Disable multicast promiscuous first */ 397e2a289a7SJiawen Wu ngbe_disable_vf_mc_promisc(eth_dev, vf); 398e2a289a7SJiawen Wu 399e2a289a7SJiawen Wu /* only so many hash values supported */ 400e2a289a7SJiawen Wu nb_entries = RTE_MIN(nb_entries, NGBE_MAX_VF_MC_ENTRIES); 401e2a289a7SJiawen Wu 402e2a289a7SJiawen Wu /* store the mc entries */ 403e2a289a7SJiawen Wu vfinfo->num_vf_mc_hashes = (uint16_t)nb_entries; 404e2a289a7SJiawen Wu for (i = 0; i < nb_entries; i++) 405e2a289a7SJiawen Wu vfinfo->vf_mc_hashes[i] = hash_list[i]; 406e2a289a7SJiawen Wu 407e2a289a7SJiawen Wu if (nb_entries == 0) { 408e2a289a7SJiawen Wu vmolr &= ~NGBE_POOLETHCTL_MCHA; 409e2a289a7SJiawen Wu wr32(hw, NGBE_POOLETHCTL(vf), vmolr); 410e2a289a7SJiawen Wu return 0; 411e2a289a7SJiawen Wu } 412e2a289a7SJiawen Wu 413e2a289a7SJiawen Wu for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) { 414e2a289a7SJiawen Wu mta_idx = (vfinfo->vf_mc_hashes[i] >> NGBE_MTA_BIT_SHIFT) 415e2a289a7SJiawen Wu & NGBE_MTA_INDEX_MASK; 416e2a289a7SJiawen Wu mta_shift = vfinfo->vf_mc_hashes[i] & NGBE_MTA_BIT_MASK; 417e2a289a7SJiawen Wu reg_val = rd32(hw, NGBE_MCADDRTBL(mta_idx)); 418e2a289a7SJiawen Wu reg_val |= (1 << mta_shift); 419e2a289a7SJiawen Wu wr32(hw, NGBE_MCADDRTBL(mta_idx), reg_val); 420e2a289a7SJiawen Wu } 421e2a289a7SJiawen Wu 422e2a289a7SJiawen Wu vmolr |= NGBE_POOLETHCTL_MCHA; 423e2a289a7SJiawen Wu wr32(hw, NGBE_POOLETHCTL(vf), vmolr); 424e2a289a7SJiawen Wu 425e2a289a7SJiawen Wu return 0; 426e2a289a7SJiawen Wu } 427e2a289a7SJiawen Wu 428e2a289a7SJiawen Wu static int 429e2a289a7SJiawen Wu ngbe_vf_set_vlan(struct rte_eth_dev *eth_dev, uint32_t vf, uint32_t *msgbuf) 430e2a289a7SJiawen Wu { 431e2a289a7SJiawen Wu int add, vid; 432e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 433e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *(NGBE_DEV_VFDATA(eth_dev)); 434e2a289a7SJiawen Wu 435e2a289a7SJiawen Wu add = (msgbuf[0] & NGBE_VT_MSGINFO_MASK) 436e2a289a7SJiawen Wu >> NGBE_VT_MSGINFO_SHIFT; 437e2a289a7SJiawen Wu vid = NGBE_PSRVLAN_VID(msgbuf[1]); 438e2a289a7SJiawen Wu 439e2a289a7SJiawen Wu if (add) 440e2a289a7SJiawen Wu vfinfo[vf].vlan_count++; 441e2a289a7SJiawen Wu else if (vfinfo[vf].vlan_count) 442e2a289a7SJiawen Wu vfinfo[vf].vlan_count--; 443e2a289a7SJiawen Wu return hw->mac.set_vfta(hw, vid, vf, (bool)add, false); 444e2a289a7SJiawen Wu } 445e2a289a7SJiawen Wu 446e2a289a7SJiawen Wu static int 447e2a289a7SJiawen Wu ngbe_set_vf_lpe(struct rte_eth_dev *eth_dev, 448e2a289a7SJiawen Wu __rte_unused uint32_t vf, uint32_t *msgbuf) 449e2a289a7SJiawen Wu { 450e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 451e2a289a7SJiawen Wu uint32_t max_frame = msgbuf[1]; 452e2a289a7SJiawen Wu uint32_t max_frs; 453e2a289a7SJiawen Wu 454e2a289a7SJiawen Wu if (max_frame < RTE_ETHER_MIN_LEN || 455e2a289a7SJiawen Wu max_frame > RTE_ETHER_MAX_JUMBO_FRAME_LEN) 456e2a289a7SJiawen Wu return -1; 457e2a289a7SJiawen Wu 458e2a289a7SJiawen Wu max_frs = rd32m(hw, NGBE_FRMSZ, NGBE_FRMSZ_MAX_MASK); 459e2a289a7SJiawen Wu if (max_frs < max_frame) { 460e2a289a7SJiawen Wu wr32m(hw, NGBE_FRMSZ, NGBE_FRMSZ_MAX_MASK, 461e2a289a7SJiawen Wu NGBE_FRMSZ_MAX(max_frame)); 462e2a289a7SJiawen Wu } 463e2a289a7SJiawen Wu 464e2a289a7SJiawen Wu return 0; 465e2a289a7SJiawen Wu } 466e2a289a7SJiawen Wu 467e2a289a7SJiawen Wu static int 468e2a289a7SJiawen Wu ngbe_negotiate_vf_api(struct rte_eth_dev *eth_dev, 469e2a289a7SJiawen Wu uint32_t vf, uint32_t *msgbuf) 470e2a289a7SJiawen Wu { 471e2a289a7SJiawen Wu uint32_t api_version = msgbuf[1]; 472e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *NGBE_DEV_VFDATA(eth_dev); 473e2a289a7SJiawen Wu 474e2a289a7SJiawen Wu switch (api_version) { 475e2a289a7SJiawen Wu case ngbe_mbox_api_10: 476e2a289a7SJiawen Wu case ngbe_mbox_api_11: 477e2a289a7SJiawen Wu case ngbe_mbox_api_12: 478e2a289a7SJiawen Wu case ngbe_mbox_api_13: 479e2a289a7SJiawen Wu vfinfo[vf].api_version = (uint8_t)api_version; 480e2a289a7SJiawen Wu return 0; 481e2a289a7SJiawen Wu default: 482e2a289a7SJiawen Wu break; 483e2a289a7SJiawen Wu } 484e2a289a7SJiawen Wu 485*f665790aSDavid Marchand PMD_DRV_LOG(ERR, "Negotiate invalid api version %u from VF %d", 486e2a289a7SJiawen Wu api_version, vf); 487e2a289a7SJiawen Wu 488e2a289a7SJiawen Wu return -1; 489e2a289a7SJiawen Wu } 490e2a289a7SJiawen Wu 491e2a289a7SJiawen Wu static int 492e2a289a7SJiawen Wu ngbe_get_vf_queues(struct rte_eth_dev *eth_dev, uint32_t vf, uint32_t *msgbuf) 493e2a289a7SJiawen Wu { 494e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *NGBE_DEV_VFDATA(eth_dev); 495e2a289a7SJiawen Wu uint32_t default_q = 0; 496e2a289a7SJiawen Wu 497e2a289a7SJiawen Wu /* Verify if the PF supports the mbox APIs version or not */ 498e2a289a7SJiawen Wu switch (vfinfo[vf].api_version) { 499e2a289a7SJiawen Wu case ngbe_mbox_api_20: 500e2a289a7SJiawen Wu case ngbe_mbox_api_11: 501e2a289a7SJiawen Wu case ngbe_mbox_api_12: 502e2a289a7SJiawen Wu case ngbe_mbox_api_13: 503e2a289a7SJiawen Wu break; 504e2a289a7SJiawen Wu default: 505e2a289a7SJiawen Wu return -1; 506e2a289a7SJiawen Wu } 507e2a289a7SJiawen Wu 508e2a289a7SJiawen Wu /* Notify VF of Rx and Tx queue number */ 509e2a289a7SJiawen Wu msgbuf[NGBE_VF_RX_QUEUES] = RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool; 510e2a289a7SJiawen Wu msgbuf[NGBE_VF_TX_QUEUES] = RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool; 511e2a289a7SJiawen Wu 512e2a289a7SJiawen Wu /* Notify VF of default queue */ 513e2a289a7SJiawen Wu msgbuf[NGBE_VF_DEF_QUEUE] = default_q; 514e2a289a7SJiawen Wu 515e2a289a7SJiawen Wu msgbuf[NGBE_VF_TRANS_VLAN] = 0; 516e2a289a7SJiawen Wu 517e2a289a7SJiawen Wu return 0; 518e2a289a7SJiawen Wu } 519e2a289a7SJiawen Wu 520e2a289a7SJiawen Wu static int 521e2a289a7SJiawen Wu ngbe_set_vf_mc_promisc(struct rte_eth_dev *eth_dev, 522e2a289a7SJiawen Wu uint32_t vf, uint32_t *msgbuf) 523e2a289a7SJiawen Wu { 524e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *(NGBE_DEV_VFDATA(eth_dev)); 525e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 526e2a289a7SJiawen Wu int xcast_mode = msgbuf[1]; /* msgbuf contains the flag to enable */ 527e2a289a7SJiawen Wu u32 vmolr, fctrl, disable, enable; 528e2a289a7SJiawen Wu 529e2a289a7SJiawen Wu switch (vfinfo[vf].api_version) { 530e2a289a7SJiawen Wu case ngbe_mbox_api_12: 531e2a289a7SJiawen Wu /* promisc introduced in 1.3 version */ 532e2a289a7SJiawen Wu if (xcast_mode == NGBEVF_XCAST_MODE_PROMISC) 533e2a289a7SJiawen Wu return -EOPNOTSUPP; 534e2a289a7SJiawen Wu break; 535e2a289a7SJiawen Wu /* Fall threw */ 536e2a289a7SJiawen Wu case ngbe_mbox_api_13: 537e2a289a7SJiawen Wu break; 538e2a289a7SJiawen Wu default: 539e2a289a7SJiawen Wu return -1; 540e2a289a7SJiawen Wu } 541e2a289a7SJiawen Wu 542e2a289a7SJiawen Wu if (vfinfo[vf].xcast_mode == xcast_mode) 543e2a289a7SJiawen Wu goto out; 544e2a289a7SJiawen Wu 545e2a289a7SJiawen Wu switch (xcast_mode) { 546e2a289a7SJiawen Wu case NGBEVF_XCAST_MODE_NONE: 547e2a289a7SJiawen Wu disable = NGBE_POOLETHCTL_BCA | NGBE_POOLETHCTL_MCHA | 548e2a289a7SJiawen Wu NGBE_POOLETHCTL_MCP | NGBE_POOLETHCTL_UCP | 549e2a289a7SJiawen Wu NGBE_POOLETHCTL_VLP; 550e2a289a7SJiawen Wu enable = 0; 551e2a289a7SJiawen Wu break; 552e2a289a7SJiawen Wu case NGBEVF_XCAST_MODE_MULTI: 553e2a289a7SJiawen Wu disable = NGBE_POOLETHCTL_MCP | NGBE_POOLETHCTL_UCP | 554e2a289a7SJiawen Wu NGBE_POOLETHCTL_VLP; 555e2a289a7SJiawen Wu enable = NGBE_POOLETHCTL_BCA | NGBE_POOLETHCTL_MCHA; 556e2a289a7SJiawen Wu break; 557e2a289a7SJiawen Wu case NGBEVF_XCAST_MODE_ALLMULTI: 558e2a289a7SJiawen Wu disable = NGBE_POOLETHCTL_UCP | NGBE_POOLETHCTL_VLP; 559e2a289a7SJiawen Wu enable = NGBE_POOLETHCTL_BCA | NGBE_POOLETHCTL_MCHA | 560e2a289a7SJiawen Wu NGBE_POOLETHCTL_MCP; 561e2a289a7SJiawen Wu break; 562e2a289a7SJiawen Wu case NGBEVF_XCAST_MODE_PROMISC: 563e2a289a7SJiawen Wu fctrl = rd32(hw, NGBE_PSRCTL); 564e2a289a7SJiawen Wu if (!(fctrl & NGBE_PSRCTL_UCP)) { 565e2a289a7SJiawen Wu /* VF promisc requires PF in promisc */ 566e2a289a7SJiawen Wu PMD_DRV_LOG(ERR, 567*f665790aSDavid Marchand "Enabling VF promisc requires PF in promisc"); 568e2a289a7SJiawen Wu return -1; 569e2a289a7SJiawen Wu } 570e2a289a7SJiawen Wu 571e2a289a7SJiawen Wu disable = 0; 572e2a289a7SJiawen Wu enable = NGBE_POOLETHCTL_BCA | NGBE_POOLETHCTL_MCHA | 573e2a289a7SJiawen Wu NGBE_POOLETHCTL_MCP | NGBE_POOLETHCTL_UCP | 574e2a289a7SJiawen Wu NGBE_POOLETHCTL_VLP; 575e2a289a7SJiawen Wu break; 576e2a289a7SJiawen Wu default: 577e2a289a7SJiawen Wu return -1; 578e2a289a7SJiawen Wu } 579e2a289a7SJiawen Wu 580e2a289a7SJiawen Wu vmolr = rd32(hw, NGBE_POOLETHCTL(vf)); 581e2a289a7SJiawen Wu vmolr &= ~disable; 582e2a289a7SJiawen Wu vmolr |= enable; 583e2a289a7SJiawen Wu wr32(hw, NGBE_POOLETHCTL(vf), vmolr); 584e2a289a7SJiawen Wu vfinfo[vf].xcast_mode = xcast_mode; 585e2a289a7SJiawen Wu 586e2a289a7SJiawen Wu out: 587e2a289a7SJiawen Wu msgbuf[1] = xcast_mode; 588e2a289a7SJiawen Wu 589e2a289a7SJiawen Wu return 0; 590e2a289a7SJiawen Wu } 591e2a289a7SJiawen Wu 592e2a289a7SJiawen Wu static int 593e2a289a7SJiawen Wu ngbe_set_vf_macvlan_msg(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf) 594e2a289a7SJiawen Wu { 595e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(dev); 596e2a289a7SJiawen Wu struct ngbe_vf_info *vf_info = *(NGBE_DEV_VFDATA(dev)); 597e2a289a7SJiawen Wu uint8_t *new_mac = (uint8_t *)(&msgbuf[1]); 598e2a289a7SJiawen Wu struct rte_ether_addr *ea = (struct rte_ether_addr *)new_mac; 599e2a289a7SJiawen Wu int index = (msgbuf[0] & NGBE_VT_MSGINFO_MASK) >> 600e2a289a7SJiawen Wu NGBE_VT_MSGINFO_SHIFT; 601e2a289a7SJiawen Wu 602e2a289a7SJiawen Wu if (index) { 603e2a289a7SJiawen Wu if (!rte_is_valid_assigned_ether_addr(ea)) { 604*f665790aSDavid Marchand PMD_DRV_LOG(ERR, "set invalid mac vf:%d", vf); 605e2a289a7SJiawen Wu return -1; 606e2a289a7SJiawen Wu } 607e2a289a7SJiawen Wu 608e2a289a7SJiawen Wu vf_info[vf].mac_count++; 609e2a289a7SJiawen Wu 610e2a289a7SJiawen Wu hw->mac.set_rar(hw, vf_info[vf].mac_count, 611e2a289a7SJiawen Wu new_mac, vf, true); 612e2a289a7SJiawen Wu } else { 613e2a289a7SJiawen Wu if (vf_info[vf].mac_count) { 614e2a289a7SJiawen Wu hw->mac.clear_rar(hw, vf_info[vf].mac_count); 615e2a289a7SJiawen Wu vf_info[vf].mac_count = 0; 616e2a289a7SJiawen Wu } 617e2a289a7SJiawen Wu } 618e2a289a7SJiawen Wu return 0; 619e2a289a7SJiawen Wu } 620e2a289a7SJiawen Wu 621e2a289a7SJiawen Wu static int 622e2a289a7SJiawen Wu ngbe_rcv_msg_from_vf(struct rte_eth_dev *eth_dev, uint16_t vf) 623e2a289a7SJiawen Wu { 624e2a289a7SJiawen Wu uint16_t mbx_size = NGBE_P2VMBX_SIZE; 625e2a289a7SJiawen Wu uint16_t msg_size = NGBE_VF_MSG_SIZE_DEFAULT; 626e2a289a7SJiawen Wu uint32_t msgbuf[NGBE_P2VMBX_SIZE]; 627e2a289a7SJiawen Wu int32_t retval; 628e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 629e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *NGBE_DEV_VFDATA(eth_dev); 630e2a289a7SJiawen Wu struct ngbe_mb_event_param ret_param; 631e2a289a7SJiawen Wu 632e2a289a7SJiawen Wu retval = ngbe_read_mbx(hw, msgbuf, mbx_size, vf); 633e2a289a7SJiawen Wu if (retval) { 634e2a289a7SJiawen Wu PMD_DRV_LOG(ERR, "Error mbx recv msg from VF %d", vf); 635e2a289a7SJiawen Wu return retval; 636e2a289a7SJiawen Wu } 637e2a289a7SJiawen Wu 638e2a289a7SJiawen Wu /* do nothing with the message already been processed */ 639e2a289a7SJiawen Wu if (msgbuf[0] & (NGBE_VT_MSGTYPE_ACK | NGBE_VT_MSGTYPE_NACK)) 640e2a289a7SJiawen Wu return retval; 641e2a289a7SJiawen Wu 642e2a289a7SJiawen Wu /* flush the ack before we write any messages back */ 643e2a289a7SJiawen Wu ngbe_flush(hw); 644e2a289a7SJiawen Wu 645e2a289a7SJiawen Wu /** 646e2a289a7SJiawen Wu * initialise structure to send to user application 647e2a289a7SJiawen Wu * will return response from user in retval field 648e2a289a7SJiawen Wu */ 649e2a289a7SJiawen Wu ret_param.retval = NGBE_MB_EVENT_PROCEED; 650e2a289a7SJiawen Wu ret_param.vfid = vf; 651e2a289a7SJiawen Wu ret_param.msg_type = msgbuf[0] & 0xFFFF; 652e2a289a7SJiawen Wu ret_param.msg = (void *)msgbuf; 653e2a289a7SJiawen Wu 654e2a289a7SJiawen Wu /* perform VF reset */ 655e2a289a7SJiawen Wu if (msgbuf[0] == NGBE_VF_RESET) { 656e2a289a7SJiawen Wu int ret = ngbe_vf_reset(eth_dev, vf, msgbuf); 657e2a289a7SJiawen Wu 658e2a289a7SJiawen Wu vfinfo[vf].clear_to_send = true; 659e2a289a7SJiawen Wu 660e2a289a7SJiawen Wu /* notify application about VF reset */ 661e2a289a7SJiawen Wu rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_VF_MBOX, 662e2a289a7SJiawen Wu &ret_param); 663e2a289a7SJiawen Wu return ret; 664e2a289a7SJiawen Wu } 665e2a289a7SJiawen Wu 666e2a289a7SJiawen Wu /** 667e2a289a7SJiawen Wu * ask user application if we allowed to perform those functions 668e2a289a7SJiawen Wu * if we get ret_param.retval == RTE_PMD_COMPAT_MB_EVENT_PROCEED 669e2a289a7SJiawen Wu * then business as usual, 670e2a289a7SJiawen Wu * if 0, do nothing and send ACK to VF 671e2a289a7SJiawen Wu * if ret_param.retval > 1, do nothing and send NAK to VF 672e2a289a7SJiawen Wu */ 673e2a289a7SJiawen Wu rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_VF_MBOX, 674e2a289a7SJiawen Wu &ret_param); 675e2a289a7SJiawen Wu 676e2a289a7SJiawen Wu retval = ret_param.retval; 677e2a289a7SJiawen Wu 678e2a289a7SJiawen Wu /* check & process VF to PF mailbox message */ 679e2a289a7SJiawen Wu switch ((msgbuf[0] & 0xFFFF)) { 680e2a289a7SJiawen Wu case NGBE_VF_SET_MAC_ADDR: 681e2a289a7SJiawen Wu if (retval == NGBE_MB_EVENT_PROCEED) 682e2a289a7SJiawen Wu retval = ngbe_vf_set_mac_addr(eth_dev, vf, msgbuf); 683e2a289a7SJiawen Wu break; 684e2a289a7SJiawen Wu case NGBE_VF_SET_MULTICAST: 685e2a289a7SJiawen Wu if (retval == NGBE_MB_EVENT_PROCEED) 686e2a289a7SJiawen Wu retval = ngbe_vf_set_multicast(eth_dev, vf, msgbuf); 687e2a289a7SJiawen Wu break; 688e2a289a7SJiawen Wu case NGBE_VF_SET_LPE: 689e2a289a7SJiawen Wu if (retval == NGBE_MB_EVENT_PROCEED) 690e2a289a7SJiawen Wu retval = ngbe_set_vf_lpe(eth_dev, vf, msgbuf); 691e2a289a7SJiawen Wu break; 692e2a289a7SJiawen Wu case NGBE_VF_SET_VLAN: 693e2a289a7SJiawen Wu if (retval == NGBE_MB_EVENT_PROCEED) 694e2a289a7SJiawen Wu retval = ngbe_vf_set_vlan(eth_dev, vf, msgbuf); 695e2a289a7SJiawen Wu break; 696e2a289a7SJiawen Wu case NGBE_VF_API_NEGOTIATE: 697e2a289a7SJiawen Wu retval = ngbe_negotiate_vf_api(eth_dev, vf, msgbuf); 698e2a289a7SJiawen Wu break; 699e2a289a7SJiawen Wu case NGBE_VF_GET_QUEUES: 700e2a289a7SJiawen Wu retval = ngbe_get_vf_queues(eth_dev, vf, msgbuf); 701e2a289a7SJiawen Wu msg_size = NGBE_VF_GET_QUEUE_MSG_SIZE; 702e2a289a7SJiawen Wu break; 703e2a289a7SJiawen Wu case NGBE_VF_UPDATE_XCAST_MODE: 704e2a289a7SJiawen Wu if (retval == NGBE_MB_EVENT_PROCEED) 705e2a289a7SJiawen Wu retval = ngbe_set_vf_mc_promisc(eth_dev, vf, msgbuf); 706e2a289a7SJiawen Wu break; 707e2a289a7SJiawen Wu case NGBE_VF_SET_MACVLAN: 708e2a289a7SJiawen Wu if (retval == NGBE_MB_EVENT_PROCEED) 709e2a289a7SJiawen Wu retval = ngbe_set_vf_macvlan_msg(eth_dev, vf, msgbuf); 710e2a289a7SJiawen Wu break; 711e2a289a7SJiawen Wu default: 712e2a289a7SJiawen Wu PMD_DRV_LOG(DEBUG, "Unhandled Msg %8.8x", (uint32_t)msgbuf[0]); 713e2a289a7SJiawen Wu retval = NGBE_ERR_MBX; 714e2a289a7SJiawen Wu break; 715e2a289a7SJiawen Wu } 716e2a289a7SJiawen Wu 717e2a289a7SJiawen Wu /* response the VF according to the message process result */ 718e2a289a7SJiawen Wu if (retval) 719e2a289a7SJiawen Wu msgbuf[0] |= NGBE_VT_MSGTYPE_NACK; 720e2a289a7SJiawen Wu else 721e2a289a7SJiawen Wu msgbuf[0] |= NGBE_VT_MSGTYPE_ACK; 722e2a289a7SJiawen Wu 723e2a289a7SJiawen Wu msgbuf[0] |= NGBE_VT_MSGTYPE_CTS; 724e2a289a7SJiawen Wu 725e2a289a7SJiawen Wu ngbe_write_mbx(hw, msgbuf, msg_size, vf); 726e2a289a7SJiawen Wu 727e2a289a7SJiawen Wu return retval; 728e2a289a7SJiawen Wu } 729e2a289a7SJiawen Wu 730e2a289a7SJiawen Wu static inline void 731e2a289a7SJiawen Wu ngbe_rcv_ack_from_vf(struct rte_eth_dev *eth_dev, uint16_t vf) 732e2a289a7SJiawen Wu { 733e2a289a7SJiawen Wu uint32_t msg = NGBE_VT_MSGTYPE_NACK; 734e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 735e2a289a7SJiawen Wu struct ngbe_vf_info *vfinfo = *NGBE_DEV_VFDATA(eth_dev); 736e2a289a7SJiawen Wu 737e2a289a7SJiawen Wu if (!vfinfo[vf].clear_to_send) 738e2a289a7SJiawen Wu ngbe_write_mbx(hw, &msg, 1, vf); 739e2a289a7SJiawen Wu } 740e2a289a7SJiawen Wu 741e2a289a7SJiawen Wu void ngbe_pf_mbx_process(struct rte_eth_dev *eth_dev) 742e2a289a7SJiawen Wu { 743e2a289a7SJiawen Wu uint16_t vf; 744e2a289a7SJiawen Wu struct ngbe_hw *hw = ngbe_dev_hw(eth_dev); 745e2a289a7SJiawen Wu 746e2a289a7SJiawen Wu for (vf = 0; vf < dev_num_vf(eth_dev); vf++) { 747e2a289a7SJiawen Wu /* check & process vf function level reset */ 748e2a289a7SJiawen Wu if (!ngbe_check_for_rst(hw, vf)) 749e2a289a7SJiawen Wu ngbe_vf_reset_event(eth_dev, vf); 750e2a289a7SJiawen Wu 751e2a289a7SJiawen Wu /* check & process vf mailbox messages */ 752e2a289a7SJiawen Wu if (!ngbe_check_for_msg(hw, vf)) 753e2a289a7SJiawen Wu ngbe_rcv_msg_from_vf(eth_dev, vf); 754e2a289a7SJiawen Wu 755e2a289a7SJiawen Wu /* check & process acks from vf */ 756e2a289a7SJiawen Wu if (!ngbe_check_for_ack(hw, vf)) 757e2a289a7SJiawen Wu ngbe_rcv_ack_from_vf(eth_dev, vf); 758e2a289a7SJiawen Wu } 759e2a289a7SJiawen Wu } 760