ethdev: make device operations struct private
[dpdk.git] / drivers / net / i40e / i40e_ethdev.c
index f9a8e71..80efd06 100644 (file)
@@ -48,6 +48,8 @@
 #define ETH_I40E_VF_MSG_CFG            "vf_msg_cfg"
 
 #define I40E_CLEAR_PXE_WAIT_MS     200
+#define I40E_VSI_TSR_QINQ_STRIP                0x4010
+#define I40E_VSI_TSR(_i)       (0x00050800 + ((_i) * 4))
 
 /* Maximun number of capability elements */
 #define I40E_MAX_CAP_ELE_NUM       128
@@ -302,7 +304,6 @@ static int i40e_dev_init_vlan(struct rte_eth_dev *dev);
 static int i40e_veb_release(struct i40e_veb *veb);
 static struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf,
                                                struct i40e_vsi *vsi);
-static int i40e_pf_config_mq_rx(struct i40e_pf *pf);
 static int i40e_vsi_config_double_vlan(struct i40e_vsi *vsi, int on);
 static inline int i40e_find_all_mac_for_vlan(struct i40e_vsi *vsi,
                                             struct i40e_macvlan_filter *mv_f,
@@ -398,6 +399,7 @@ static void i40e_ethertype_filter_restore(struct i40e_pf *pf);
 static void i40e_tunnel_filter_restore(struct i40e_pf *pf);
 static void i40e_filter_restore(struct i40e_pf *pf);
 static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev);
+static int i40e_pf_config_rss(struct i40e_pf *pf);
 
 static const char *const valid_keys[] = {
        ETH_I40E_FLOATING_VEB_ARG,
@@ -472,10 +474,6 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
        .rx_queue_intr_enable         = i40e_dev_rx_queue_intr_enable,
        .rx_queue_intr_disable        = i40e_dev_rx_queue_intr_disable,
        .rx_queue_release             = i40e_dev_rx_queue_release,
-       .rx_queue_count               = i40e_dev_rx_queue_count,
-       .rx_descriptor_done           = i40e_dev_rx_descriptor_done,
-       .rx_descriptor_status         = i40e_dev_rx_descriptor_status,
-       .tx_descriptor_status         = i40e_dev_tx_descriptor_status,
        .tx_queue_setup               = i40e_dev_tx_queue_setup,
        .tx_queue_release             = i40e_dev_tx_queue_release,
        .dev_led_on                   = i40e_dev_led_on,
@@ -1446,6 +1444,10 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused)
        PMD_INIT_FUNC_TRACE();
 
        dev->dev_ops = &i40e_eth_dev_ops;
+       dev->rx_queue_count = i40e_dev_rx_queue_count;
+       dev->rx_descriptor_done = i40e_dev_rx_descriptor_done;
+       dev->rx_descriptor_status = i40e_dev_rx_descriptor_status;
+       dev->tx_descriptor_status = i40e_dev_tx_descriptor_status;
        dev->rx_pkt_burst = i40e_recv_pkts;
        dev->tx_pkt_burst = i40e_xmit_pkts;
        dev->tx_pkt_prepare = i40e_prep_pkts;
@@ -1870,7 +1872,7 @@ i40e_fdir_memory_cleanup(struct i40e_pf *pf)
        if (fdir_info->hash_table)
                rte_hash_free(fdir_info->hash_table);
        if (fdir_info->fdir_flow_pool.bitmap)
-               rte_bitmap_free(fdir_info->fdir_flow_pool.bitmap);
+               rte_free(fdir_info->fdir_flow_pool.bitmap);
        if (fdir_info->fdir_flow_pool.pool)
                rte_free(fdir_info->fdir_flow_pool.pool);
        if (fdir_info->fdir_filter_array)
@@ -1954,8 +1956,6 @@ i40e_dev_configure(struct rte_eth_dev *dev)
                goto err;
 
        /* VMDQ setup.
-        *  Needs to move VMDQ setting out of i40e_pf_config_mq_rx() as VMDQ and
-        *  RSS setting have different requirements.
         *  General PMD driver call sequence are NIC init, configure,
         *  rx/tx_queue_setup and dev_start. In rx/tx_queue_setup() function, it
         *  will try to lookup the VSI that specific queue belongs to if VMDQ
@@ -3014,7 +3014,10 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link,
                link->link_speed = ETH_SPEED_NUM_40G;
                break;
        default:
-               link->link_speed = ETH_SPEED_NUM_NONE;
+               if (link->link_status)
+                       link->link_speed = ETH_SPEED_NUM_UNKNOWN;
+               else
+                       link->link_speed = ETH_SPEED_NUM_NONE;
                break;
        }
 }
@@ -3981,6 +3984,39 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
        return ret;
 }
 
+/* Configure outer vlan stripping on or off in QinQ mode */
+static int
+i40e_vsi_config_outer_vlan_stripping(struct i40e_vsi *vsi, bool on)
+{
+       struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+       int ret = I40E_SUCCESS;
+       uint32_t reg;
+
+       if (vsi->vsi_id >= I40E_MAX_NUM_VSIS) {
+               PMD_DRV_LOG(ERR, "VSI ID exceeds the maximum");
+               return -EINVAL;
+       }
+
+       /* Configure for outer VLAN RX stripping */
+       reg = I40E_READ_REG(hw, I40E_VSI_TSR(vsi->vsi_id));
+
+       if (on)
+               reg |= I40E_VSI_TSR_QINQ_STRIP;
+       else
+               reg &= ~I40E_VSI_TSR_QINQ_STRIP;
+
+       ret = i40e_aq_debug_write_register(hw,
+                                                  I40E_VSI_TSR(vsi->vsi_id),
+                                                  reg, NULL);
+       if (ret < 0) {
+               PMD_DRV_LOG(ERR, "Failed to update VSI_TSR[%d]",
+                                   vsi->vsi_id);
+               return I40E_ERR_CONFIG;
+       }
+
+       return ret;
+}
+
 static int
 i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
@@ -4017,6 +4053,14 @@ i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
                        i40e_vsi_config_double_vlan(vsi, FALSE);
        }
 
+       if (mask & ETH_QINQ_STRIP_MASK) {
+               /* Enable or disable outer VLAN stripping */
+               if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP)
+                       i40e_vsi_config_outer_vlan_stripping(vsi, TRUE);
+               else
+                       i40e_vsi_config_outer_vlan_stripping(vsi, FALSE);
+       }
+
        return 0;
 }
 
@@ -6195,6 +6239,7 @@ i40e_dev_init_vlan(struct rte_eth_dev *dev)
 
        /* Apply vlan offload setting */
        mask = ETH_VLAN_STRIP_MASK |
+              ETH_QINQ_STRIP_MASK |
               ETH_VLAN_FILTER_MASK |
               ETH_VLAN_EXTEND_MASK;
        ret = i40e_vlan_offload_set(dev, mask);
@@ -6495,7 +6540,7 @@ i40e_dev_rx_init(struct i40e_pf *pf)
        uint16_t i;
        struct i40e_rx_queue *rxq;
 
-       i40e_pf_config_mq_rx(pf);
+       i40e_pf_config_rss(pf);
        for (i = 0; i < data->nb_rx_queues; i++) {
                rxq = data->rx_queues[i];
                if (!rxq || !rxq->q_set)
@@ -9001,6 +9046,7 @@ i40e_pf_calc_configured_queues_num(struct i40e_pf *pf)
 static int
 i40e_pf_config_rss(struct i40e_pf *pf)
 {
+       enum rte_eth_rx_mq_mode mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode;
        struct i40e_hw *hw = I40E_PF_TO_HW(pf);
        struct rte_eth_rss_conf rss_conf;
        uint32_t i, lut = 0;
@@ -9039,7 +9085,8 @@ i40e_pf_config_rss(struct i40e_pf *pf)
        }
 
        rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf;
-       if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) {
+       if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0 ||
+           !(mq_mode & ETH_MQ_RX_RSS_FLAG)) {
                i40e_pf_disable_rss(pf);
                return 0;
        }
@@ -9212,21 +9259,6 @@ i40e_tunnel_filter_handle(struct rte_eth_dev *dev,
        return ret;
 }
 
-static int
-i40e_pf_config_mq_rx(struct i40e_pf *pf)
-{
-       int ret = 0;
-       enum rte_eth_rx_mq_mode mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode;
-
-       /* RSS setup */
-       if (mq_mode & ETH_MQ_RX_RSS_FLAG)
-               ret = i40e_pf_config_rss(pf);
-       else
-               i40e_pf_disable_rss(pf);
-
-       return ret;
-}
-
 /* Get the symmetric hash enable configurations per port */
 static void
 i40e_get_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t *enable)
@@ -10889,7 +10921,6 @@ i40e_configure_registers(struct i40e_hw *hw)
        }
 }
 
-#define I40E_VSI_TSR(_i)            (0x00050800 + ((_i) * 4))
 #define I40E_VSI_TSR_QINQ_CONFIG    0xc030
 #define I40E_VSI_L2TAGSTXVALID(_i)  (0x00042800 + ((_i) * 4))
 #define I40E_VSI_L2TAGSTXVALID_QINQ 0xab