mlx5: add Rx CRC stripping configuration
[dpdk.git] / drivers / net / ixgbe / ixgbe_pf.c
index caed137..b854c72 100644 (file)
@@ -55,6 +55,7 @@
 #define IXGBE_MAX_VFTA     (128)
 #define IXGBE_VF_MSG_SIZE_DEFAULT 1
 #define IXGBE_VF_GET_QUEUE_MSG_SIZE 5
+#define IXGBE_ETHERTYPE_FLOW_CTRL 0x8808
 
 static inline uint16_t
 dev_num_vf(struct rte_eth_dev *eth_dev)
@@ -144,6 +145,69 @@ void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev)
        return;
 }
 
+void ixgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
+{
+       struct ixgbe_vf_info **vfinfo;
+       uint16_t vf_num;
+
+       PMD_INIT_FUNC_TRACE();
+
+       vfinfo = IXGBE_DEV_PRIVATE_TO_P_VFDATA(eth_dev->data->dev_private);
+
+       RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
+       RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = 0;
+       RTE_ETH_DEV_SRIOV(eth_dev).def_vmdq_idx = 0;
+       RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx = 0;
+
+       vf_num = dev_num_vf(eth_dev);
+       if (vf_num == 0)
+               return;
+
+       rte_free(*vfinfo);
+       *vfinfo = NULL;
+}
+
+static void
+ixgbe_add_tx_flow_control_drop_filter(struct rte_eth_dev *eth_dev)
+{
+       struct ixgbe_hw *hw =
+               IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
+       struct ixgbe_filter_info *filter_info =
+               IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
+       uint16_t vf_num;
+       int i;
+
+       if (!hw->mac.ops.set_ethertype_anti_spoofing) {
+               RTE_LOG(INFO, PMD, "ether type anti-spoofing is not"
+                       " supported.\n");
+               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;
+               }
+       }
+       if (i == IXGBE_MAX_ETQF_FILTERS) {
+               RTE_LOG(ERR, PMD, "Cannot find an unused ether type filter"
+                       " entity for flow control.\n");
+               return;
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_ETQF(i),
+                       (IXGBE_ETQF_FILTER_EN |
+                       IXGBE_ETQF_TX_ANTISPOOF |
+                       IXGBE_ETHERTYPE_FLOW_CTRL));
+
+       vf_num = dev_num_vf(eth_dev);
+       for (i = 0; i < vf_num; i++)
+               hw->mac.ops.set_ethertype_anti_spoofing(hw, true, i);
+}
+
 int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
 {
        uint32_t vtctl, fcrth;
@@ -222,7 +286,7 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
         * enable vlan filtering and allow all vlan tags through
         */
         vlanctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
-        vlanctrl |= IXGBE_VLNCTRL_VFE ; /* enable vlan filters */
+        vlanctrl |= IXGBE_VLNCTRL_VFE; /* enable vlan filters */
         IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlanctrl);
 
         /* VFTA - enable all vlan filters */
@@ -240,6 +304,8 @@ int ixgbe_pf_host_configure(struct rte_eth_dev *eth_dev)
                IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth);
        }
 
+       ixgbe_add_tx_flow_control_drop_filter(eth_dev);
+
        return 0;
 }
 
@@ -343,6 +409,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)
 {
@@ -357,6 +457,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);
@@ -403,6 +506,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);
 
@@ -454,7 +560,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))
@@ -480,6 +587,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:
@@ -503,6 +611,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;
@@ -523,6 +632,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)
 {
@@ -575,6 +704,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;