drivers/net: fix RSS hash offload flag if no RSS
[dpdk.git] / drivers / net / liquidio / lio_ethdev.c
index d13ab06..ad4a51e 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright(c) 2017 Cavium, Inc
  */
 
+#include <rte_string_fns.h>
 #include <rte_ethdev_driver.h>
 #include <rte_ethdev_pci.h>
 #include <rte_cycles.h>
@@ -242,17 +243,18 @@ lio_dev_xstats_get_names(struct rte_eth_dev *eth_dev,
 }
 
 /* Reset hw stats for the port */
-static void
+static int
 lio_dev_xstats_reset(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
        struct lio_dev_ctrl_cmd ctrl_cmd;
        struct lio_ctrl_pkt ctrl_pkt;
+       int ret;
 
        if (!lio_dev->intf_open) {
                lio_dev_err(lio_dev, "Port %d down\n",
                            lio_dev->port_id);
-               return;
+               return -EINVAL;
        }
 
        /* flush added to prevent cmd failure
@@ -269,19 +271,21 @@ lio_dev_xstats_reset(struct rte_eth_dev *eth_dev)
        ctrl_pkt.ncmd.s.cmd = LIO_CMD_CLEAR_STATS;
        ctrl_pkt.ctrl_cmd = &ctrl_cmd;
 
-       if (lio_send_ctrl_pkt(lio_dev, &ctrl_pkt)) {
+       ret = lio_send_ctrl_pkt(lio_dev, &ctrl_pkt);
+       if (ret != 0) {
                lio_dev_err(lio_dev, "Failed to send clear stats command\n");
-               return;
+               return ret;
        }
 
-       if (lio_wait_for_ctrl_cmd(lio_dev, &ctrl_cmd)) {
+       ret = lio_wait_for_ctrl_cmd(lio_dev, &ctrl_cmd);
+       if (ret != 0) {
                lio_dev_err(lio_dev, "Clear stats command timed out\n");
-               return;
+               return ret;
        }
 
        /* clear stored per queue stats */
-       RTE_FUNC_PTR_OR_RET(*eth_dev->dev_ops->stats_reset);
-       (*eth_dev->dev_ops->stats_reset)(eth_dev);
+       RTE_FUNC_PTR_OR_ERR_RET(*eth_dev->dev_ops->stats_reset, 0);
+       return (*eth_dev->dev_ops->stats_reset)(eth_dev);
 }
 
 /* Retrieve the device statistics (# packets in/out, # bytes in/out, etc */
@@ -337,7 +341,7 @@ lio_dev_stats_get(struct rte_eth_dev *eth_dev,
        return 0;
 }
 
-static void
+static int
 lio_dev_stats_reset(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -364,9 +368,11 @@ lio_dev_stats_reset(struct rte_eth_dev *eth_dev)
                        memset(oq_stats, 0, sizeof(struct lio_droq_stats));
                }
        }
+
+       return 0;
 }
 
-static void
+static int
 lio_dev_info_get(struct rte_eth_dev *eth_dev,
                 struct rte_eth_dev_info *devinfo)
 {
@@ -392,6 +398,7 @@ lio_dev_info_get(struct rte_eth_dev *eth_dev,
                devinfo->speed_capa = ETH_LINK_SPEED_10G;
                lio_dev_err(lio_dev,
                            "Unknown CN23XX subsystem device id. Setting 10G as default link speed.\n");
+               return -EINVAL;
        }
 
        devinfo->max_rx_queues = lio_dev->max_rx_queues;
@@ -405,7 +412,8 @@ lio_dev_info_get(struct rte_eth_dev *eth_dev,
        devinfo->rx_offload_capa = (DEV_RX_OFFLOAD_IPV4_CKSUM           |
                                    DEV_RX_OFFLOAD_UDP_CKSUM            |
                                    DEV_RX_OFFLOAD_TCP_CKSUM            |
-                                   DEV_RX_OFFLOAD_VLAN_STRIP);
+                                   DEV_RX_OFFLOAD_VLAN_STRIP           |
+                                   DEV_RX_OFFLOAD_RSS_HASH);
        devinfo->tx_offload_capa = (DEV_TX_OFFLOAD_IPV4_CKSUM           |
                                    DEV_TX_OFFLOAD_UDP_CKSUM            |
                                    DEV_TX_OFFLOAD_TCP_CKSUM            |
@@ -422,6 +430,7 @@ lio_dev_info_get(struct rte_eth_dev *eth_dev,
                                           ETH_RSS_NONFRAG_IPV6_TCP     |
                                           ETH_RSS_IPV6_EX              |
                                           ETH_RSS_IPV6_TCP_EX);
+       return 0;
 }
 
 static int
@@ -429,7 +438,7 @@ lio_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
        uint16_t pf_mtu = lio_dev->linfo.link.s.mtu;
-       uint32_t frame_len = mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+       uint32_t frame_len = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
        struct lio_dev_ctrl_cmd ctrl_cmd;
        struct lio_ctrl_pkt ctrl_pkt;
 
@@ -444,9 +453,9 @@ lio_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
        /* check if VF MTU is within allowed range.
         * New value should not exceed PF MTU.
         */
-       if ((mtu < ETHER_MIN_MTU) || (mtu > pf_mtu)) {
+       if (mtu < RTE_ETHER_MIN_MTU || mtu > pf_mtu) {
                lio_dev_err(lio_dev, "VF MTU should be >= %d and <= %d\n",
-                           ETHER_MIN_MTU, pf_mtu);
+                           RTE_ETHER_MIN_MTU, pf_mtu);
                return -EINVAL;
        }
 
@@ -475,7 +484,7 @@ lio_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
                return -1;
        }
 
-       if (frame_len > ETHER_MAX_LEN)
+       if (frame_len > RTE_ETHER_MAX_LEN)
                eth_dev->data->dev_conf.rxmode.offloads |=
                        DEV_RX_OFFLOAD_JUMBO_FRAME;
        else
@@ -958,8 +967,12 @@ lio_dev_link_update(struct rte_eth_dev *eth_dev,
 /**
  * \brief Net device enable, disable allmulticast
  * @param eth_dev Pointer to the structure rte_eth_dev
+ *
+ * @return
+ *  On success return 0
+ *  On failure return negative errno
  */
-static void
+static int
 lio_change_dev_flag(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -984,14 +997,18 @@ lio_change_dev_flag(struct rte_eth_dev *eth_dev)
 
        if (lio_send_ctrl_pkt(lio_dev, &ctrl_pkt)) {
                lio_dev_err(lio_dev, "Failed to send change flag message\n");
-               return;
+               return -EAGAIN;
        }
 
-       if (lio_wait_for_ctrl_cmd(lio_dev, &ctrl_cmd))
+       if (lio_wait_for_ctrl_cmd(lio_dev, &ctrl_cmd)) {
                lio_dev_err(lio_dev, "Change dev flag command timed out\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
 }
 
-static void
+static int
 lio_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -999,20 +1016,20 @@ lio_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
        if (strcmp(lio_dev->firmware_version, LIO_VF_TRUST_MIN_VERSION) < 0) {
                lio_dev_err(lio_dev, "Require firmware version >= %s\n",
                            LIO_VF_TRUST_MIN_VERSION);
-               return;
+               return -EAGAIN;
        }
 
        if (!lio_dev->intf_open) {
                lio_dev_err(lio_dev, "Port %d down, can't enable promiscuous\n",
                            lio_dev->port_id);
-               return;
+               return -EAGAIN;
        }
 
        lio_dev->ifflags |= LIO_IFFLAG_PROMISC;
-       lio_change_dev_flag(eth_dev);
+       return lio_change_dev_flag(eth_dev);
 }
 
-static void
+static int
 lio_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -1020,20 +1037,20 @@ lio_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
        if (strcmp(lio_dev->firmware_version, LIO_VF_TRUST_MIN_VERSION) < 0) {
                lio_dev_err(lio_dev, "Require firmware version >= %s\n",
                            LIO_VF_TRUST_MIN_VERSION);
-               return;
+               return -EAGAIN;
        }
 
        if (!lio_dev->intf_open) {
                lio_dev_err(lio_dev, "Port %d down, can't disable promiscuous\n",
                            lio_dev->port_id);
-               return;
+               return -EAGAIN;
        }
 
        lio_dev->ifflags &= ~LIO_IFFLAG_PROMISC;
-       lio_change_dev_flag(eth_dev);
+       return lio_change_dev_flag(eth_dev);
 }
 
-static void
+static int
 lio_dev_allmulticast_enable(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -1041,14 +1058,14 @@ lio_dev_allmulticast_enable(struct rte_eth_dev *eth_dev)
        if (!lio_dev->intf_open) {
                lio_dev_err(lio_dev, "Port %d down, can't enable multicast\n",
                            lio_dev->port_id);
-               return;
+               return -EAGAIN;
        }
 
        lio_dev->ifflags |= LIO_IFFLAG_ALLMULTI;
-       lio_change_dev_flag(eth_dev);
+       return lio_change_dev_flag(eth_dev);
 }
 
-static void
+static int
 lio_dev_allmulticast_disable(struct rte_eth_dev *eth_dev)
 {
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
@@ -1056,11 +1073,11 @@ lio_dev_allmulticast_disable(struct rte_eth_dev *eth_dev)
        if (!lio_dev->intf_open) {
                lio_dev_err(lio_dev, "Port %d down, can't disable multicast\n",
                            lio_dev->port_id);
-               return;
+               return -EAGAIN;
        }
 
        lio_dev->ifflags &= ~LIO_IFFLAG_ALLMULTI;
-       lio_change_dev_flag(eth_dev);
+       return lio_change_dev_flag(eth_dev);
 }
 
 static void
@@ -1428,9 +1445,9 @@ lio_dev_start(struct rte_eth_dev *eth_dev)
                goto dev_mtu_set_error;
        }
 
-       mtu = (uint16_t)(frame_len - ETHER_HDR_LEN - ETHER_CRC_LEN);
-       if (mtu < ETHER_MIN_MTU)
-               mtu = ETHER_MIN_MTU;
+       mtu = (uint16_t)(frame_len - RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN);
+       if (mtu < RTE_ETHER_MIN_MTU)
+               mtu = RTE_ETHER_MIN_MTU;
 
        if (eth_dev->data->mtu != mtu) {
                ret = lio_dev_mtu_set(eth_dev, mtu);
@@ -1711,7 +1728,7 @@ lio_dev_configure(struct rte_eth_dev *eth_dev)
        struct lio_device *lio_dev = LIO_DEV(eth_dev);
        uint16_t timeout = LIO_MAX_CMD_TIMEOUT;
        int retval, num_iqueues, num_oqueues;
-       uint8_t mac[ETHER_ADDR_LEN], i;
+       uint8_t mac[RTE_ETHER_ADDR_LEN], i;
        struct lio_if_cfg_resp *resp;
        struct lio_soft_command *sc;
        union lio_if_cfg if_cfg;
@@ -1719,6 +1736,10 @@ lio_dev_configure(struct rte_eth_dev *eth_dev)
 
        PMD_INIT_FUNC_TRACE();
 
+       if (eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
+               eth_dev->data->dev_conf.rxmode.offloads |=
+                       DEV_RX_OFFLOAD_RSS_HASH;
+
        /* Inform firmware about change in number of queues to use.
         * Disable IO queues and reset registers for re-configuration.
         */
@@ -1781,8 +1802,8 @@ lio_dev_configure(struct rte_eth_dev *eth_dev)
                goto nic_config_fail;
        }
 
-       snprintf(lio_dev->firmware_version, LIO_FW_VERSION_LENGTH, "%s",
-                resp->cfg_info.lio_firmware_version);
+       strlcpy(lio_dev->firmware_version,
+               resp->cfg_info.lio_firmware_version, LIO_FW_VERSION_LENGTH);
 
        lio_swap_8B_data((uint64_t *)(&resp->cfg_info),
                         sizeof(struct octeon_if_cfg_info) >> 3);
@@ -1829,12 +1850,13 @@ lio_dev_configure(struct rte_eth_dev *eth_dev)
 
        /* 64-bit swap required on LE machines */
        lio_swap_8B_data(&lio_dev->linfo.hw_addr, 1);
-       for (i = 0; i < ETHER_ADDR_LEN; i++)
+       for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
                mac[i] = *((uint8_t *)(((uint8_t *)&lio_dev->linfo.hw_addr) +
                                       2 + i));
 
        /* Copy the permanent MAC address */
-       ether_addr_copy((struct ether_addr *)mac, &eth_dev->data->mac_addrs[0]);
+       rte_ether_addr_copy((struct rte_ether_addr *)mac,
+                       &eth_dev->data->mac_addrs[0]);
 
        /* enable firmware checksum support for tunnel packets */
        lio_enable_hw_tunnel_rx_checksum(eth_dev);
@@ -2088,7 +2110,7 @@ lio_eth_dev_init(struct rte_eth_dev *eth_dev)
        }
 
        eth_dev->dev_ops = &liovf_eth_dev_ops;
-       eth_dev->data->mac_addrs = rte_zmalloc("lio", ETHER_ADDR_LEN, 0);
+       eth_dev->data->mac_addrs = rte_zmalloc("lio", RTE_ETHER_ADDR_LEN, 0);
        if (eth_dev->data->mac_addrs == NULL) {
                lio_dev_err(lio_dev,
                            "MAC addresses memory allocation failed\n");