net/ixgbe: allow setting 2.5G and 5G speeds on X550
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index fa1315e..cd5894f 100644 (file)
@@ -2066,19 +2066,22 @@ ixgbe_vlan_hw_strip_config(struct rte_eth_dev *dev)
 static int
 ixgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
+       struct rte_eth_rxmode *rxmode;
+       rxmode = &dev->data->dev_conf.rxmode;
+
        if (mask & ETH_VLAN_STRIP_MASK) {
                ixgbe_vlan_hw_strip_config(dev);
        }
 
        if (mask & ETH_VLAN_FILTER_MASK) {
-               if (dev->data->dev_conf.rxmode.hw_vlan_filter)
+               if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
                        ixgbe_vlan_hw_filter_enable(dev);
                else
                        ixgbe_vlan_hw_filter_disable(dev);
        }
 
        if (mask & ETH_VLAN_EXTEND_MASK) {
-               if (dev->data->dev_conf.rxmode.hw_vlan_extend)
+               if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND)
                        ixgbe_vlan_hw_extend_enable(dev);
                else
                        ixgbe_vlan_hw_extend_disable(dev);
@@ -2293,6 +2296,9 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
                IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
        struct ixgbe_adapter *adapter =
                (struct ixgbe_adapter *)dev->data->dev_private;
+       struct rte_eth_dev_info dev_info;
+       uint64_t rx_offloads;
+       uint64_t tx_offloads;
        int ret;
 
        PMD_INIT_FUNC_TRACE();
@@ -2304,6 +2310,22 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
                return ret;
        }
 
+       ixgbe_dev_info_get(dev, &dev_info);
+       rx_offloads = dev->data->dev_conf.rxmode.offloads;
+       if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
+               PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
+                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
+                           rx_offloads, dev_info.rx_offload_capa);
+               return -ENOTSUP;
+       }
+       tx_offloads = dev->data->dev_conf.txmode.offloads;
+       if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
+               PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
+                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
+                           tx_offloads, dev_info.tx_offload_capa);
+               return -ENOTSUP;
+       }
+
        /* set flag to update link status after init */
        intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 
@@ -2426,6 +2448,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        uint32_t intr_vector = 0;
        int err, link_up = 0, negotiate = 0;
        uint32_t speed = 0;
+       uint32_t allowed_speeds = 0;
        int mask = 0;
        int status;
        uint16_t vf, idx;
@@ -2574,9 +2597,21 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        if (err)
                goto error;
 
+       switch (hw->mac.type) {
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+       case ixgbe_mac_X550EM_a:
+               allowed_speeds = ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+                       ETH_LINK_SPEED_2_5G |  ETH_LINK_SPEED_5G |
+                       ETH_LINK_SPEED_10G;
+               break;
+       default:
+               allowed_speeds = ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+                       ETH_LINK_SPEED_10G;
+       }
+
        link_speeds = &dev->data->dev_conf.link_speeds;
-       if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
-                       ETH_LINK_SPEED_10G)) {
+       if (*link_speeds & ~allowed_speeds) {
                PMD_INIT_LOG(ERR, "Invalid link setting");
                goto error;
        }
@@ -2602,6 +2637,10 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        } else {
                if (*link_speeds & ETH_LINK_SPEED_10G)
                        speed |= IXGBE_LINK_SPEED_10GB_FULL;
+               if (*link_speeds & ETH_LINK_SPEED_5G)
+                       speed |= IXGBE_LINK_SPEED_5GB_FULL;
+               if (*link_speeds & ETH_LINK_SPEED_2_5G)
+                       speed |= IXGBE_LINK_SPEED_2_5GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_1G)
                        speed |= IXGBE_LINK_SPEED_1GB_FULL;
                if (*link_speeds & ETH_LINK_SPEED_100M)
@@ -2612,6 +2651,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        if (err)
                goto error;
 
+       ixgbe_dev_link_update(dev, 0);
+
 skip_link_setup:
 
        if (rte_intr_allow_others(intr_handle)) {
@@ -3571,7 +3612,6 @@ 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->pci_dev = pci_dev;
        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) {
@@ -3593,54 +3633,11 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        else
                dev_info->max_vmdq_pools = ETH_64_POOLS;
        dev_info->vmdq_queue_num = dev_info->max_rx_queues;
-       dev_info->rx_offload_capa =
-               DEV_RX_OFFLOAD_VLAN_STRIP |
-               DEV_RX_OFFLOAD_IPV4_CKSUM |
-               DEV_RX_OFFLOAD_UDP_CKSUM  |
-               DEV_RX_OFFLOAD_TCP_CKSUM  |
-               DEV_RX_OFFLOAD_CRC_STRIP;
-
-       /*
-        * RSC is only supported by 82599 and x540 PF devices in a non-SR-IOV
-        * mode.
-        */
-       if ((hw->mac.type == ixgbe_mac_82599EB ||
-            hw->mac.type == ixgbe_mac_X540) &&
-           !RTE_ETH_DEV_SRIOV(dev).active)
-               dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_TCP_LRO;
-
-       if (hw->mac.type == ixgbe_mac_82599EB ||
-           hw->mac.type == ixgbe_mac_X540)
-               dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_MACSEC_STRIP;
-
-       if (hw->mac.type == ixgbe_mac_X550 ||
-           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 =
-               DEV_TX_OFFLOAD_VLAN_INSERT |
-               DEV_TX_OFFLOAD_IPV4_CKSUM  |
-               DEV_TX_OFFLOAD_UDP_CKSUM   |
-               DEV_TX_OFFLOAD_TCP_CKSUM   |
-               DEV_TX_OFFLOAD_SCTP_CKSUM  |
-               DEV_TX_OFFLOAD_TCP_TSO;
-
-       if (hw->mac.type == ixgbe_mac_82599EB ||
-           hw->mac.type == ixgbe_mac_X540)
-               dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_MACSEC_INSERT;
-
-       if (hw->mac.type == ixgbe_mac_X550 ||
-           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;
-
-#ifdef RTE_LIBRTE_SECURITY
-       if (dev->security_ctx) {
-               dev_info->rx_offload_capa |= DEV_RX_OFFLOAD_SECURITY;
-               dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_SECURITY;
-       }
-#endif
+       dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev);
+       dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) |
+                                    dev_info->rx_queue_offload_capa);
+       dev_info->tx_queue_offload_capa = ixgbe_get_tx_queue_offloads(dev);
+       dev_info->tx_offload_capa = ixgbe_get_tx_port_offloads(dev);
 
        dev_info->default_rxconf = (struct rte_eth_rxconf) {
                .rx_thresh = {
@@ -3650,6 +3647,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                },
                .rx_free_thresh = IXGBE_DEFAULT_RX_FREE_THRESH,
                .rx_drop_en = 0,
+               .offloads = 0,
        };
 
        dev_info->default_txconf = (struct rte_eth_txconf) {
@@ -3661,7 +3659,9 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                .tx_free_thresh = IXGBE_DEFAULT_TX_FREE_THRESH,
                .tx_rs_thresh = IXGBE_DEFAULT_TX_RSBIT_THRESH,
                .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
-                               ETH_TXQ_FLAGS_NOOFFLOADS,
+                            ETH_TXQ_FLAGS_NOOFFLOADS |
+                            ETH_TXQ_FLAGS_IGNORE,
+               .offloads = 0,
        };
 
        dev_info->rx_desc_lim = rx_desc_lim;
@@ -3730,7 +3730,6 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-       dev_info->pci_dev = pci_dev;
        dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
        dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
        dev_info->min_rx_bufsize = 1024; /* cf BSIZEPACKET in SRRCTL reg */
@@ -3742,17 +3741,11 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
                dev_info->max_vmdq_pools = ETH_16_POOLS;
        else
                dev_info->max_vmdq_pools = ETH_64_POOLS;
-       dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP |
-                               DEV_RX_OFFLOAD_IPV4_CKSUM |
-                               DEV_RX_OFFLOAD_UDP_CKSUM  |
-                               DEV_RX_OFFLOAD_TCP_CKSUM  |
-                               DEV_RX_OFFLOAD_CRC_STRIP;
-       dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
-                               DEV_TX_OFFLOAD_IPV4_CKSUM  |
-                               DEV_TX_OFFLOAD_UDP_CKSUM   |
-                               DEV_TX_OFFLOAD_TCP_CKSUM   |
-                               DEV_TX_OFFLOAD_SCTP_CKSUM  |
-                               DEV_TX_OFFLOAD_TCP_TSO;
+       dev_info->rx_queue_offload_capa = ixgbe_get_rx_queue_offloads(dev);
+       dev_info->rx_offload_capa = (ixgbe_get_rx_port_offloads(dev) |
+                                    dev_info->rx_queue_offload_capa);
+       dev_info->tx_queue_offload_capa = ixgbe_get_tx_queue_offloads(dev);
+       dev_info->tx_offload_capa = ixgbe_get_tx_port_offloads(dev);
 
        dev_info->default_rxconf = (struct rte_eth_rxconf) {
                .rx_thresh = {
@@ -3762,6 +3755,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
                },
                .rx_free_thresh = IXGBE_DEFAULT_RX_FREE_THRESH,
                .rx_drop_en = 0,
+               .offloads = 0,
        };
 
        dev_info->default_txconf = (struct rte_eth_txconf) {
@@ -3773,7 +3767,9 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
                .tx_free_thresh = IXGBE_DEFAULT_TX_FREE_THRESH,
                .tx_rs_thresh = IXGBE_DEFAULT_TX_RSBIT_THRESH,
                .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
-                               ETH_TXQ_FLAGS_NOOFFLOADS,
+                            ETH_TXQ_FLAGS_NOOFFLOADS |
+                            ETH_TXQ_FLAGS_IGNORE,
+               .offloads = 0,
        };
 
        dev_info->rx_desc_lim = rx_desc_lim;
@@ -3809,7 +3805,7 @@ ixgbevf_check_link(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
        /* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
         * before the link status is correct
         */
-       if (mac->type == ixgbe_mac_82599_vf) {
+       if (mac->type == ixgbe_mac_82599_vf && wait_to_complete) {
                int i;
 
                for (i = 0; i < 5; i++) {
@@ -4845,10 +4841,12 @@ ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 
        /* switch to jumbo mode if needed */
        if (frame_size > ETHER_MAX_LEN) {
-               dev->data->dev_conf.rxmode.jumbo_frame = 1;
+               dev->data->dev_conf.rxmode.offloads |=
+                       DEV_RX_OFFLOAD_JUMBO_FRAME;
                hlreg0 |= IXGBE_HLREG0_JUMBOEN;
        } else {
-               dev->data->dev_conf.rxmode.jumbo_frame = 0;
+               dev->data->dev_conf.rxmode.offloads &=
+                       ~DEV_RX_OFFLOAD_JUMBO_FRAME;
                hlreg0 &= ~IXGBE_HLREG0_JUMBOEN;
        }
        IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
@@ -4897,23 +4895,42 @@ ixgbevf_dev_configure(struct rte_eth_dev *dev)
        struct rte_eth_conf *conf = &dev->data->dev_conf;
        struct ixgbe_adapter *adapter =
                        (struct ixgbe_adapter *)dev->data->dev_private;
+       struct rte_eth_dev_info dev_info;
+       uint64_t rx_offloads;
+       uint64_t tx_offloads;
 
        PMD_INIT_LOG(DEBUG, "Configured Virtual Function port id: %d",
                     dev->data->port_id);
 
+       ixgbevf_dev_info_get(dev, &dev_info);
+       rx_offloads = dev->data->dev_conf.rxmode.offloads;
+       if ((rx_offloads & dev_info.rx_offload_capa) != rx_offloads) {
+               PMD_DRV_LOG(ERR, "Some Rx offloads are not supported "
+                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
+                           rx_offloads, dev_info.rx_offload_capa);
+               return -ENOTSUP;
+       }
+       tx_offloads = dev->data->dev_conf.txmode.offloads;
+       if ((tx_offloads & dev_info.tx_offload_capa) != tx_offloads) {
+               PMD_DRV_LOG(ERR, "Some Tx offloads are not supported "
+                           "requested 0x%" PRIx64 " supported 0x%" PRIx64,
+                           tx_offloads, dev_info.tx_offload_capa);
+               return -ENOTSUP;
+       }
+
        /*
         * VF has no ability to enable/disable HW CRC
         * Keep the persistent behavior the same as Host PF
         */
 #ifndef RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC
-       if (!conf->rxmode.hw_strip_crc) {
+       if (!(conf->rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP)) {
                PMD_INIT_LOG(NOTICE, "VF can't disable HW CRC Strip");
-               conf->rxmode.hw_strip_crc = 1;
+               conf->rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
        }
 #else
-       if (conf->rxmode.hw_strip_crc) {
+       if (conf->rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP) {
                PMD_INIT_LOG(NOTICE, "VF can't enable HW CRC Strip");
-               conf->rxmode.hw_strip_crc = 0;
+               conf->rxmode.offloads &= ~DEV_RX_OFFLOAD_CRC_STRIP;
        }
 #endif
 
@@ -4975,6 +4992,8 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
 
        ixgbevf_dev_rxtx_start(dev);
 
+       ixgbevf_dev_link_update(dev, 0);
+
        /* check and configure queue intr-vector mapping */
        if (rte_intr_cap_multiple(intr_handle) &&
            dev->data->dev_conf.intr_conf.rxq) {
@@ -5801,6 +5820,7 @@ ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev,
                           uint16_t queue_idx, uint16_t tx_rate)
 {
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_eth_rxmode *rxmode;
        uint32_t rf_dec, rf_int;
        uint32_t bcnrc_val;
        uint16_t link_speed = dev->data->dev_link.link_speed;
@@ -5822,14 +5842,14 @@ ixgbe_set_queue_rate_limit(struct rte_eth_dev *dev,
                bcnrc_val = 0;
        }
 
+       rxmode = &dev->data->dev_conf.rxmode;
        /*
         * Set global transmit compensation time to the MMW_SIZE in RTTBCNRM
         * register. MMW_SIZE=0x014 if 9728-byte jumbo is supported, otherwise
         * set as 0x4.
         */
-       if ((dev->data->dev_conf.rxmode.jumbo_frame == 1) &&
-               (dev->data->dev_conf.rxmode.max_rx_pkt_len >=
-                               IXGBE_MAX_JUMBO_FRAME_SIZE))
+       if ((rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) &&
+           (rxmode->max_rx_pkt_len >= IXGBE_MAX_JUMBO_FRAME_SIZE))
                IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRM,
                        IXGBE_MMW_SIZE_JUMBO_FRAME);
        else
@@ -6176,7 +6196,7 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
        /* refuse mtu that requires the support of scattered packets when this
         * feature has not been enabled before.
         */
-       if (!rx_conf->enable_scatter &&
+       if (!(rx_conf->offloads & DEV_RX_OFFLOAD_SCATTER) &&
            (max_frame + 2 * IXGBE_VLAN_TAG_SIZE >
             dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM))
                return -EINVAL;