ethdev: use constants for link state
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index 82c1882..8bcd0d8 100644 (file)
@@ -185,6 +185,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
                                             uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
                               struct rte_eth_dev_info *dev_info);
+static const uint32_t *ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
                                 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -467,6 +468,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .xstats_reset         = ixgbe_dev_xstats_reset,
        .queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
        .dev_infos_get        = ixgbe_dev_info_get,
+       .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
        .mtu_set              = ixgbe_dev_mtu_set,
        .vlan_filter_set      = ixgbe_vlan_filter_set,
        .vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -557,6 +559,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
        .allmulticast_enable  = ixgbevf_dev_allmulticast_enable,
        .allmulticast_disable = ixgbevf_dev_allmulticast_disable,
        .dev_infos_get        = ixgbevf_dev_info_get,
+       .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
        .mtu_set              = ixgbevf_dev_set_mtu,
        .vlan_filter_set      = ixgbevf_vlan_filter_set,
        .vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -1788,7 +1791,8 @@ ixgbe_vlan_hw_extend_enable(struct rte_eth_dev *dev)
 
        /* Clear pooling mode of PFVTCTL. It's required by X550. */
        if (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) {
                ctrl = IXGBE_READ_REG(hw, IXGBE_VT_CTL);
                ctrl &= ~IXGBE_VT_CTL_POOLING_MODE_MASK;
                IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, ctrl);
@@ -1861,8 +1865,9 @@ static int
 ixgbe_check_mq_mode(struct rte_eth_dev *dev)
 {
        struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint16_t nb_rx_q = dev->data->nb_rx_queues;
-       uint16_t nb_tx_q = dev->data->nb_rx_queues;
+       uint16_t nb_tx_q = dev->data->nb_tx_queues;
 
        if (RTE_ETH_DEV_SRIOV(dev).active != 0) {
                /* check multi-queue mode */
@@ -1917,11 +1922,18 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
                if ((nb_rx_q > RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool) ||
                    (nb_tx_q > RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool)) {
                        PMD_INIT_LOG(ERR, "SRIOV is active,"
-                                       " queue number must less equal to %d.",
+                                       " nb_rx_q=%d nb_tx_q=%d queue number"
+                                       " must be less than or equal to %d.",
+                                       nb_rx_q, nb_tx_q,
                                        RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool);
                        return -EINVAL;
                }
        } else {
+               if (dev_conf->rxmode.mq_mode == ETH_MQ_RX_VMDQ_DCB_RSS) {
+                       PMD_INIT_LOG(ERR, "VMDQ+DCB+RSS mq_mode is"
+                                         " not supported.");
+                       return -EINVAL;
+               }
                /* check configuration for vmdb+dcb mode */
                if (dev_conf->rxmode.mq_mode == ETH_MQ_RX_VMDQ_DCB) {
                        const struct rte_eth_vmdq_dcb_conf *conf;
@@ -1995,6 +2007,21 @@ ixgbe_check_mq_mode(struct rte_eth_dev *dev)
                                return -EINVAL;
                        }
                }
+
+               /*
+                * When DCB/VT is off, maximum number of queues changes,
+                * except for 82598EB, which remains constant.
+                */
+               if (dev_conf->txmode.mq_mode == ETH_MQ_TX_NONE &&
+                               hw->mac.type != ixgbe_mac_82598EB) {
+                       if (nb_tx_q > IXGBE_NONE_MODE_TX_NB_QUEUES) {
+                               PMD_INIT_LOG(ERR,
+                                            "Neither VT nor DCB are enabled, "
+                                            "nb_tx_q > %d.",
+                                            IXGBE_NONE_MODE_TX_NB_QUEUES);
+                               return -EINVAL;
+                       }
+               }
        }
        return 0;
 }
@@ -2104,6 +2131,11 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
             !RTE_ETH_DEV_SRIOV(dev).active) &&
            dev->data->dev_conf.intr_conf.rxq != 0) {
                intr_vector = dev->data->nb_rx_queues;
+               if (intr_vector > IXGBE_MAX_INTR_QUEUE_NUM) {
+                       PMD_INIT_LOG(ERR, "At most %d intr queues supported",
+                                       IXGBE_MAX_INTR_QUEUE_NUM);
+                       return -ENOTSUP;
+               }
                if (rte_intr_efd_enable(intr_handle, intr_vector))
                        return -1;
        }
@@ -2639,7 +2671,6 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
                          hw_stats->rlec +
                          hw_stats->ruc +
                          hw_stats->roc +
-                         total_missed_rx +
                          hw_stats->illerrc +
                          hw_stats->errbc +
                          hw_stats->rfc +
@@ -2850,9 +2881,19 @@ static void
 ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
 
        dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
        dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
+       if (RTE_ETH_DEV_SRIOV(dev).active == 0) {
+               /*
+                * When DCB/VT is off, maximum number of queues changes,
+                * except for 82598EB, which remains constant.
+                */
+               if (dev_conf->txmode.mq_mode == ETH_MQ_TX_NONE &&
+                               hw->mac.type != ixgbe_mac_82598EB)
+                       dev_info->max_tx_queues = IXGBE_NONE_MODE_TX_NB_QUEUES;
+       }
        dev_info->min_rx_bufsize = 1024; /* cf BSIZEPACKET in SRRCTL register */
        dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS register */
        dev_info->max_mac_addrs = hw->mac.num_rar_entries;
@@ -2879,7 +2920,8 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TCP_LRO;
 
        if (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)
                dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM;
 
        dev_info->tx_offload_capa =
@@ -2891,7 +2933,8 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                DEV_TX_OFFLOAD_TCP_TSO;
 
        if (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)
                dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
 
        dev_info->default_rxconf = (struct rte_eth_rxconf) {
@@ -2924,6 +2967,39 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static const uint32_t *
+ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+       static const uint32_t ptypes[] = {
+               /* For non-vec functions,
+                * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+                * for vec functions,
+                * refers to _recv_raw_pkts_vec().
+                */
+               RTE_PTYPE_L2_ETHER,
+               RTE_PTYPE_L3_IPV4,
+               RTE_PTYPE_L3_IPV4_EXT,
+               RTE_PTYPE_L3_IPV6,
+               RTE_PTYPE_L3_IPV6_EXT,
+               RTE_PTYPE_L4_SCTP,
+               RTE_PTYPE_L4_TCP,
+               RTE_PTYPE_L4_UDP,
+               RTE_PTYPE_TUNNEL_IP,
+               RTE_PTYPE_INNER_L3_IPV6,
+               RTE_PTYPE_INNER_L3_IPV6_EXT,
+               RTE_PTYPE_INNER_L4_TCP,
+               RTE_PTYPE_INNER_L4_UDP,
+               RTE_PTYPE_UNKNOWN
+       };
+
+       if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+           dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+           dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+           dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc)
+               return ptypes;
+       return NULL;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
                     struct rte_eth_dev_info *dev_info)
@@ -2988,7 +3064,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
        int link_up;
        int diag;
 
-       link.link_status = 0;
+       link.link_status = ETH_LINK_DOWN;
        link.link_speed = 0;
        link.link_duplex = 0;
        memset(&old, 0, sizeof(old));
@@ -3017,7 +3093,7 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
                        return -1;
                return 0;
        }
-       link.link_status = 1;
+       link.link_status = ETH_LINK_UP;
        link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
        switch (link_speed) {
@@ -3697,11 +3773,11 @@ ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev,
                          struct rte_eth_rss_reta_entry64 *reta_conf,
                          uint16_t reta_size)
 {
-       uint8_t i, j, mask;
+       uint16_t i, sp_reta_size;
+       uint8_t j, mask;
        uint32_t reta, r;
        uint16_t idx, shift;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint16_t sp_reta_size;
        uint32_t reta_reg;
 
        PMD_INIT_FUNC_TRACE();
@@ -3751,11 +3827,11 @@ ixgbe_dev_rss_reta_query(struct rte_eth_dev *dev,
                         struct rte_eth_rss_reta_entry64 *reta_conf,
                         uint16_t reta_size)
 {
-       uint8_t i, j, mask;
+       uint16_t i, sp_reta_size;
+       uint8_t j, mask;
        uint32_t reta;
        uint16_t idx, shift;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint16_t sp_reta_size;
        uint32_t reta_reg;
 
        PMD_INIT_FUNC_TRACE();
@@ -4031,8 +4107,12 @@ ixgbevf_dev_close(struct rte_eth_dev *dev)
 
        ixgbe_dev_free_queues(dev);
 
-       /* reprogram the RAR[0] in case user changed it. */
-       ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+       /**
+        * Remove the VF MAC address ro ensure
+        * that the VF traffic goes to the PF
+        * after stop, close and detach of the VF
+        **/
+       ixgbevf_remove_mac_addr(dev, 0);
 }
 
 static void ixgbevf_set_vfta_all(struct rte_eth_dev *dev, bool on)
@@ -4367,10 +4447,11 @@ ixgbe_set_pool_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
        if (ixgbe_vmdq_mode_check(hw) < 0)
                return -ENOTSUP;
        for (pool_idx = 0; pool_idx < ETH_64_POOLS; pool_idx++) {
-               if (pool_mask & ((uint64_t)(1ULL << pool_idx)))
+               if (pool_mask & ((uint64_t)(1ULL << pool_idx))) {
                        ret = hw->mac.ops.set_vfta(hw,vlan,pool_idx,vlan_on);
                        if (ret < 0)
                                return ret;
+               }
        }
 
        return ret;
@@ -4990,7 +5071,8 @@ ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 
 #define MAC_TYPE_FILTER_SUP(type)    do {\
        if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540 &&\
-               (type) != ixgbe_mac_X550)\
+               (type) != ixgbe_mac_X550 && (type) != ixgbe_mac_X550EM_x &&\
+               (type) != ixgbe_mac_X550EM_a)\
                return -ENOTSUP;\
 } while (0)
 
@@ -5751,6 +5833,8 @@ ixgbe_read_systime_cyclecounter(struct rte_eth_dev *dev)
 
        switch (hw->mac.type) {
        case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
                /* SYSTIMEL stores ns and SYSTIMEH stores seconds. */
                systime_cycles = (uint64_t)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
                systime_cycles += (uint64_t)IXGBE_READ_REG(hw, IXGBE_SYSTIMH)
@@ -5773,6 +5857,8 @@ ixgbe_read_rx_tstamp_cyclecounter(struct rte_eth_dev *dev)
 
        switch (hw->mac.type) {
        case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
                /* RXSTMPL stores ns and RXSTMPH stores seconds. */
                rx_tstamp_cycles = (uint64_t)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
                rx_tstamp_cycles += (uint64_t)IXGBE_READ_REG(hw, IXGBE_RXSTMPH)
@@ -5796,6 +5882,8 @@ ixgbe_read_tx_tstamp_cyclecounter(struct rte_eth_dev *dev)
 
        switch (hw->mac.type) {
        case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
                /* TXSTMPL stores ns and TXSTMPH stores seconds. */
                tx_tstamp_cycles = (uint64_t)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
                tx_tstamp_cycles += (uint64_t)IXGBE_READ_REG(hw, IXGBE_TXSTMPH)
@@ -5844,6 +5932,8 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
 
        switch (hw->mac.type) {
        case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
                /* Independent of link speed. */
                incval = 1;
                /* Cycles read will be interpreted as ns. */
@@ -6317,7 +6407,8 @@ ixgbe_update_e_tag_eth_type(struct ixgbe_hw *hw,
        uint32_t etag_etype;
 
        if (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 -ENOTSUP;
        }
 
@@ -6361,7 +6452,8 @@ ixgbe_e_tag_enable(struct ixgbe_hw *hw)
        uint32_t etag_etype;
 
        if (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 -ENOTSUP;
        }
 
@@ -6401,7 +6493,8 @@ ixgbe_e_tag_disable(struct ixgbe_hw *hw)
        uint32_t etag_etype;
 
        if (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 -ENOTSUP;
        }
 
@@ -6444,7 +6537,8 @@ ixgbe_e_tag_filter_del(struct rte_eth_dev *dev,
        uint32_t rar_low, rar_high;
 
        if (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 -ENOTSUP;
        }
 
@@ -6479,7 +6573,8 @@ ixgbe_e_tag_filter_add(struct rte_eth_dev *dev,
        uint32_t rar_low, rar_high;
 
        if (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 -ENOTSUP;
        }
 
@@ -6598,7 +6693,8 @@ ixgbe_e_tag_forwarding_en_dis(struct rte_eth_dev *dev, bool en)
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        if (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 -ENOTSUP;
        }
 
@@ -6671,7 +6767,8 @@ ixgbe_e_tag_insertion_en_dis(struct rte_eth_dev *dev,
        }
 
        if (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 -ENOTSUP;
        }
 
@@ -6741,7 +6838,8 @@ ixgbe_e_tag_stripping_en_dis(struct rte_eth_dev *dev,
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        if (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 -ENOTSUP;
        }
 
@@ -6914,7 +7012,8 @@ ixgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        if (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 -ENOTSUP;
        }
 
@@ -6950,7 +7049,8 @@ ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        if (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 -ENOTSUP;
        }