net/ixgbe/base: fix pointer check
[dpdk.git] / drivers / net / ixgbe / ixgbe_pf.c
index 2ffbd1f..56393ff 100644 (file)
@@ -97,9 +97,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 +108,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 +142,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)
@@ -220,7 +219,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 +236,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 +280,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);
@@ -312,8 +311,7 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 static void
 set_rx_mode(struct rte_eth_dev *dev)
 {
-       struct rte_eth_dev_data *dev_data =
-               (struct rte_eth_dev_data*)dev->data->dev_private;
+       struct rte_eth_dev_data *dev_data = dev->data;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
        uint16_t vfn = dev_num_vf(dev);
@@ -409,6 +407,40 @@ ixgbe_vf_reset_msg(struct rte_eth_dev *dev, uint16_t vf)
        ixgbe_vf_reset_event(dev, vf);
 }
 
+static int
+ixgbe_enable_vf_mc_promisc(struct rte_eth_dev *dev, uint32_t vf)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t vmolr;
+
+       vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+
+       RTE_LOG(INFO, PMD, "VF %u: enabling multicast promiscuous\n", vf);
+
+       vmolr |= IXGBE_VMOLR_MPE;
+
+       IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
+
+       return 0;
+}
+
+static int
+ixgbe_disable_vf_mc_promisc(struct rte_eth_dev *dev, uint32_t vf)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       uint32_t vmolr;
+
+       vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+
+       RTE_LOG(INFO, PMD, "VF %u: disabling multicast promiscuous\n", vf);
+
+       vmolr &= ~IXGBE_VMOLR_MPE;
+
+       IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
+
+       return 0;
+}
+
 static int
 ixgbe_vf_reset(struct rte_eth_dev *dev, uint16_t vf, uint32_t *msgbuf)
 {
@@ -423,6 +455,9 @@ ixgbe_vf_reset(struct rte_eth_dev *dev, uint16_t vf, uint32_t *msgbuf)
 
        hw->mac.ops.set_rar(hw, rar_entry, vf_mac, vf, IXGBE_RAH_AV);
 
+       /* Disable multicast promiscuous at reset */
+       ixgbe_disable_vf_mc_promisc(dev, vf);
+
        /* reply to reset with ack and vf mac address */
        msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK;
        rte_memcpy(new_mac, vf_mac, ETHER_ADDR_LEN);
@@ -445,7 +480,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);
        }
@@ -469,6 +504,9 @@ ixgbe_vf_set_multicast(struct rte_eth_dev *dev, __rte_unused uint32_t vf, uint32
        uint32_t reg_val;
        int i;
 
+       /* Disable multicast promiscuous first */
+       ixgbe_disable_vf_mc_promisc(dev, vf);
+
        /* only so many hash values supported */
        nb_entries = RTE_MIN(nb_entries, IXGBE_MAX_VF_MC_ENTRIES);
 
@@ -506,7 +544,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
@@ -520,7 +558,8 @@ ixgbe_set_vf_lpe(struct rte_eth_dev *dev, __rte_unused uint32_t vf, uint32_t *ms
        /* X540 and X550 support jumbo frames in IOV mode */
        if (hw->mac.type != ixgbe_mac_X540 &&
                hw->mac.type != ixgbe_mac_X550 &&
-               hw->mac.type != ixgbe_mac_X550EM_x)
+               hw->mac.type != ixgbe_mac_X550EM_x &&
+               hw->mac.type != ixgbe_mac_X550EM_a)
                return -1;
 
        if ((max_frame < ETHER_MIN_LEN) || (max_frame > ETHER_MAX_JUMBO_FRAME_LEN))
@@ -546,6 +585,7 @@ ixgbe_negotiate_vf_api(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf)
        switch (api_version) {
        case ixgbe_mbox_api_10:
        case ixgbe_mbox_api_11:
+       case ixgbe_mbox_api_12:
                vfinfo[vf].api_version = (uint8_t)api_version;
                return 0;
        default:
@@ -569,6 +609,7 @@ ixgbe_get_vf_queues(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf)
        switch (vfinfo[vf].api_version) {
        case ixgbe_mbox_api_20:
        case ixgbe_mbox_api_11:
+       case ixgbe_mbox_api_12:
                break;
        default:
                return -1;
@@ -589,6 +630,26 @@ ixgbe_get_vf_queues(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf)
        return 0;
 }
 
+static int
+ixgbe_set_vf_mc_promisc(struct rte_eth_dev *dev, uint32_t vf, uint32_t *msgbuf)
+{
+       struct ixgbe_vf_info *vfinfo =
+               *(IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private));
+       bool enable = !!msgbuf[1];      /* msgbuf contains the flag to enable */
+
+       switch (vfinfo[vf].api_version) {
+       case ixgbe_mbox_api_12:
+               break;
+       default:
+               return -1;
+       }
+
+       if (enable)
+               return ixgbe_enable_vf_mc_promisc(dev, vf);
+       else
+               return ixgbe_disable_vf_mc_promisc(dev, vf);
+}
+
 static int
 ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
 {
@@ -616,6 +677,7 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
        /* perform VF reset */
        if (msgbuf[0] == IXGBE_VF_RESET) {
                int ret = ixgbe_vf_reset(dev, vf, msgbuf);
+
                vfinfo[vf].clear_to_send = true;
                return ret;
        }
@@ -641,6 +703,9 @@ ixgbe_rcv_msg_from_vf(struct rte_eth_dev *dev, uint16_t vf)
                retval = ixgbe_get_vf_queues(dev, vf, msgbuf);
                msg_size = IXGBE_VF_GET_QUEUE_MSG_SIZE;
                break;
+       case IXGBE_VF_UPDATE_XCAST_MODE:
+               retval = ixgbe_set_vf_mc_promisc(dev, vf, msgbuf);
+               break;
        default:
                PMD_DRV_LOG(DEBUG, "Unhandled Msg %8.8x", (unsigned)msgbuf[0]);
                retval = IXGBE_ERR_MBX;