X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgbe%2Fixgbe_pf.c;h=c0d86c7689b242980b0054fdd63318c0379926b6;hb=f60a9f98ec219c826a5de8ebb2d7d5436733ac29;hp=a54034346da21454815d89c4d4a435c2fce97af9;hpb=ca4a155783a7e7ca877b6043d64027444e7a187f;p=dpdk.git diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c index a54034346d..c0d86c7689 100644 --- a/drivers/net/ixgbe/ixgbe_pf.c +++ b/drivers/net/ixgbe/ixgbe_pf.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ #include "base/ixgbe_common.h" #include "ixgbe_ethdev.h" +#include "rte_pmd_ixgbe.h" #define IXGBE_MAX_VFTA (128) #define IXGBE_VF_MSG_SIZE_DEFAULT 1 @@ -60,7 +61,9 @@ static inline uint16_t dev_num_vf(struct rte_eth_dev *eth_dev) { - return eth_dev->pci_dev->max_vfs; + struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + + return pci_dev->max_vfs; } static inline @@ -97,9 +100,9 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev) struct ixgbe_vf_info **vfinfo = IXGBE_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data->dev_private); struct ixgbe_mirror_info *mirror_info = - IXGBE_DEV_PRIVATE_TO_PFDATA(eth_dev->data->dev_private); + IXGBE_DEV_PRIVATE_TO_PFDATA(eth_dev->data->dev_private); struct ixgbe_uta_info *uta_info = - IXGBE_DEV_PRIVATE_TO_UTA(eth_dev->data->dev_private); + IXGBE_DEV_PRIVATE_TO_UTA(eth_dev->data->dev_private); struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private); uint16_t vf_num; @@ -108,15 +111,16 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev) PMD_INIT_FUNC_TRACE(); RTE_ETH_DEV_SRIOV(eth_dev).active = 0; - if (0 == (vf_num = dev_num_vf(eth_dev))) + vf_num = dev_num_vf(eth_dev); + if (vf_num == 0) return; *vfinfo = rte_zmalloc("vf_info", sizeof(struct ixgbe_vf_info) * vf_num, 0); if (*vfinfo == NULL) rte_panic("Cannot allocate memory for private VF data\n"); - memset(mirror_info,0,sizeof(struct ixgbe_mirror_info)); - memset(uta_info,0,sizeof(struct ixgbe_uta_info)); + memset(mirror_info, 0, sizeof(struct ixgbe_mirror_info)); + memset(uta_info, 0, sizeof(struct ixgbe_uta_info)); hw->mac.mc_filter_type = 0; if (vf_num >= ETH_32_POOLS) { @@ -141,8 +145,6 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev) /* set mb interrupt mask */ ixgbe_mb_intr_setup(eth_dev); - - return; } void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev) @@ -176,6 +178,7 @@ ixgbe_add_tx_flow_control_drop_filter(struct rte_eth_dev *eth_dev) IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private); uint16_t vf_num; int i; + struct ixgbe_ethertype_filter ethertype_filter; if (!hw->mac.ops.set_ethertype_anti_spoofing) { RTE_LOG(INFO, PMD, "ether type anti-spoofing is not" @@ -183,16 +186,23 @@ ixgbe_add_tx_flow_control_drop_filter(struct rte_eth_dev *eth_dev) return; } - /* occupy an entity of ether type filter */ - for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) { - if (!(filter_info->ethertype_mask & (1 << i))) { - filter_info->ethertype_mask |= 1 << i; - filter_info->ethertype_filters[i] = - IXGBE_ETHERTYPE_FLOW_CTRL; - break; - } + i = ixgbe_ethertype_filter_lookup(filter_info, + IXGBE_ETHERTYPE_FLOW_CTRL); + if (i >= 0) { + RTE_LOG(ERR, PMD, "A ether type filter" + " entity for flow control already exists!\n"); + return; } - if (i == IXGBE_MAX_ETQF_FILTERS) { + + ethertype_filter.ethertype = IXGBE_ETHERTYPE_FLOW_CTRL; + ethertype_filter.etqf = IXGBE_ETQF_FILTER_EN | + IXGBE_ETQF_TX_ANTISPOOF | + IXGBE_ETHERTYPE_FLOW_CTRL; + ethertype_filter.etqs = 0; + ethertype_filter.conf = TRUE; + i = ixgbe_ethertype_filter_insert(filter_info, + ðertype_filter); + if (i < 0) { RTE_LOG(ERR, PMD, "Cannot find an unused ether type filter" " entity for flow control.\n"); return; @@ -220,7 +230,8 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev) uint32_t vlanctrl; int i; - if (0 == (vf_num = dev_num_vf(eth_dev))) + vf_num = dev_num_vf(eth_dev); + if (vf_num == 0) return -1; /* enable VMDq and set the default pool for PF */ @@ -236,9 +247,9 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev) vfre_slot = (vf_num >> VFRE_SHIFT) > 0 ? 1 : 0; /* Enable pools reserved to PF only */ - IXGBE_WRITE_REG(hw, IXGBE_VFRE(vfre_slot), (~0) << vfre_offset); + IXGBE_WRITE_REG(hw, IXGBE_VFRE(vfre_slot), (~0U) << vfre_offset); IXGBE_WRITE_REG(hw, IXGBE_VFRE(vfre_slot ^ 1), vfre_slot - 1); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(vfre_slot), (~0) << vfre_offset); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(vfre_slot), (~0U) << vfre_offset); IXGBE_WRITE_REG(hw, IXGBE_VFTE(vfre_slot ^ 1), vfre_slot - 1); /* PFDMA Tx General Switch Control Enables VMDQ loopback */ @@ -280,19 +291,18 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev) } IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - /* + /* * enable vlan filtering and allow all vlan tags through */ - vlanctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); - vlanctrl |= IXGBE_VLNCTRL_VFE; /* enable vlan filters */ - IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlanctrl); + vlanctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlanctrl |= IXGBE_VLNCTRL_VFE; /* enable vlan filters */ + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlanctrl); - /* VFTA - enable all vlan filters */ - for (i = 0; i < IXGBE_MAX_VFTA; i++) { - IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), 0xFFFFFFFF); - } + /* VFTA - enable all vlan filters */ + for (i = 0; i < IXGBE_MAX_VFTA; i++) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(i), 0xFFFFFFFF); /* Enable MAC Anti-Spoofing */ hw->mac.ops.set_mac_anti_spoofing(hw, FALSE, vf_num); @@ -387,15 +397,27 @@ ixgbe_vf_reset_msg(struct rte_eth_dev *dev, uint16_t vf) uint32_t reg_offset, vf_shift; const uint8_t VFRE_SHIFT = 5; /* VFRE 32 bits per slot */ const uint8_t VFRE_MASK = (uint8_t)((1U << VFRE_SHIFT) - 1); + uint8_t nb_q_per_pool; + int i; vf_shift = vf & VFRE_MASK; reg_offset = (vf >> VFRE_SHIFT) > 0 ? 1 : 0; - /* enable transmit and receive for vf */ + /* enable transmit for vf */ reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset)); reg |= (reg | (1 << vf_shift)); IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); + /* enable all queue drop for IOV */ + nb_q_per_pool = RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool; + for (i = vf * nb_q_per_pool; i < (vf + 1) * nb_q_per_pool; i++) { + IXGBE_WRITE_FLUSH(hw); + reg = IXGBE_QDE_ENABLE | IXGBE_QDE_WRITE; + reg |= i << IXGBE_QDE_IDX_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_QDE, reg); + } + + /* enable receive for vf */ reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); reg |= (reg | (1 << vf_shift)); IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); @@ -481,7 +503,7 @@ ixgbe_vf_set_mac_addr(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf) int rar_entry = hw->mac.num_rar_entries - (vf + 1); uint8_t *new_mac = (uint8_t *)(&msgbuf[1]); - if (is_valid_assigned_ether_addr((struct ether_addr*)new_mac)) { + if (is_valid_assigned_ether_addr((struct ether_addr *)new_mac)) { rte_memcpy(vfinfo[vf].vf_mac_addresses, new_mac, 6); return hw->mac.ops.set_rar(hw, rar_entry, new_mac, vf, IXGBE_RAH_AV); } @@ -489,7 +511,7 @@ ixgbe_vf_set_mac_addr(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf) } static int -ixgbe_vf_set_multicast(struct rte_eth_dev *dev, __rte_unused uint32_t vf, uint32_t *msgbuf) +ixgbe_vf_set_multicast(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ixgbe_vf_info *vfinfo = @@ -545,7 +567,7 @@ ixgbe_vf_set_vlan(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf) vfinfo[vf].vlan_count++; else if (vfinfo[vf].vlan_count) vfinfo[vf].vlan_count--; - return hw->mac.ops.set_vfta(hw, vid, vf, (bool)add); + return hw->mac.ops.set_vfta(hw, vid, vf, (bool)add, false); } static int @@ -661,6 +683,7 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf) struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ixgbe_vf_info *vfinfo = *IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private); + struct rte_pmd_ixgbe_mb_event_param ret_param; retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); if (retval) { @@ -675,26 +698,56 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf) /* flush the ack before we write any messages back */ IXGBE_WRITE_FLUSH(hw); + /** + * initialise structure to send to user application + * will return response from user in retval field + */ + ret_param.retval = RTE_PMD_IXGBE_MB_EVENT_PROCEED; + ret_param.vfid = vf; + ret_param.msg_type = msgbuf[0] & 0xFFFF; + ret_param.msg = (void *)msgbuf; + /* perform VF reset */ if (msgbuf[0] == IXGBE_VF_RESET) { int ret = ixgbe_vf_reset(dev, vf, msgbuf); + vfinfo[vf].clear_to_send = true; + + /* notify application about VF reset */ + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, + NULL, &ret_param); return ret; } + /** + * ask user application if we allowed to perform those functions + * if we get ret_param.retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED + * then business as usual, + * if 0, do nothing and send ACK to VF + * if ret_param.retval > 1, do nothing and send NAK to VF + */ + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, + NULL, &ret_param); + + retval = ret_param.retval; + /* check & process VF to PF mailbox message */ switch ((msgbuf[0] & 0xFFFF)) { case IXGBE_VF_SET_MAC_ADDR: - retval = ixgbe_vf_set_mac_addr(dev, vf, msgbuf); + if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) + retval = ixgbe_vf_set_mac_addr(dev, vf, msgbuf); break; case IXGBE_VF_SET_MULTICAST: - retval = ixgbe_vf_set_multicast(dev, vf, msgbuf); + if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) + retval = ixgbe_vf_set_multicast(dev, vf, msgbuf); break; case IXGBE_VF_SET_LPE: - retval = ixgbe_set_vf_lpe(dev, vf, msgbuf); + if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) + retval = ixgbe_set_vf_lpe(dev, vf, msgbuf); break; case IXGBE_VF_SET_VLAN: - retval = ixgbe_vf_set_vlan(dev, vf, msgbuf); + if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) + retval = ixgbe_vf_set_vlan(dev, vf, msgbuf); break; case IXGBE_VF_API_NEGOTIATE: retval = ixgbe_negotiate_vf_api(dev, vf, msgbuf); @@ -704,7 +757,8 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf) msg_size = IXGBE_VF_GET_QUEUE_MSG_SIZE; break; case IXGBE_VF_UPDATE_XCAST_MODE: - retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf); + if (retval == RTE_PMD_IXGBE_MB_EVENT_PROCEED) + retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf); break; default: PMD_DRV_LOG(DEBUG, "Unhandled Msg %8.8x", (unsigned)msgbuf[0]);