New upstream version 16.11.5
[deb_dpdk.git] / drivers / net / e1000 / igb_ethdev.c
index be2600d..5108ff3 100644 (file)
@@ -129,7 +129,7 @@ static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
                                struct rte_eth_fc_conf *fc_conf);
 static int  eth_igb_flow_ctrl_set(struct rte_eth_dev *dev,
                                struct rte_eth_fc_conf *fc_conf);
-static int eth_igb_lsc_interrupt_setup(struct rte_eth_dev *dev);
+static int eth_igb_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on);
 static int eth_igb_rxq_interrupt_setup(struct rte_eth_dev *dev);
 static int eth_igb_interrupt_get_status(struct rte_eth_dev *dev);
 static int eth_igb_interrupt_action(struct rte_eth_dev *dev);
@@ -1121,7 +1121,7 @@ igb_check_mq_mode(struct rte_eth_dev *dev)
        enum rte_eth_rx_mq_mode rx_mq_mode = dev->data->dev_conf.rxmode.mq_mode;
        enum rte_eth_tx_mq_mode tx_mq_mode = dev->data->dev_conf.txmode.mq_mode;
        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 ((rx_mq_mode & ETH_MQ_RX_DCB_FLAG) ||
            tx_mq_mode == ETH_MQ_TX_DCB ||
@@ -1381,7 +1381,9 @@ eth_igb_start(struct rte_eth_dev *dev)
        if (rte_intr_allow_others(intr_handle)) {
                /* check if lsc interrupt is enabled */
                if (dev->data->dev_conf.intr_conf.lsc != 0)
-                       eth_igb_lsc_interrupt_setup(dev);
+                       eth_igb_lsc_interrupt_setup(dev, TRUE);
+               else
+                       eth_igb_lsc_interrupt_setup(dev, FALSE);
        } else {
                rte_intr_callback_unregister(intr_handle,
                                             eth_igb_interrupt_handler,
@@ -2224,7 +2226,7 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
                link.link_speed = 0;
                link.link_duplex = ETH_LINK_HALF_DUPLEX;
                link.link_status = ETH_LINK_DOWN;
-               link.link_autoneg = ETH_LINK_SPEED_FIXED;
+               link.link_autoneg = ETH_LINK_FIXED;
        }
        rte_igb_dev_atomic_write_link_status(dev, &link);
 
@@ -2543,18 +2545,23 @@ eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask)
  *
  * @param dev
  *  Pointer to struct rte_eth_dev.
+ * @param on
+ *  Enable or Disable
  *
  * @return
  *  - On success, zero.
  *  - On failure, a negative value.
  */
 static int
-eth_igb_lsc_interrupt_setup(struct rte_eth_dev *dev)
+eth_igb_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on)
 {
        struct e1000_interrupt *intr =
                E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
 
-       intr->mask |= E1000_ICR_LSC;
+       if (on)
+               intr->mask |= E1000_ICR_LSC;
+       else
+               intr->mask &= ~E1000_ICR_LSC;
 
        return 0;
 }
@@ -2750,12 +2757,17 @@ void igbvf_mbx_process(struct rte_eth_dev *dev)
        struct e1000_mbx_info *mbx = &hw->mbx;
        u32 in_msg = 0;
 
-       if (mbx->ops.read(hw, &in_msg, 1, 0))
-               return;
+       /* peek the message first */
+       in_msg = E1000_READ_REG(hw, E1000_VMBMEM(0));
 
        /* PF reset VF event */
-       if (in_msg == E1000_PF_CONTROL_MSG)
-               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET, NULL);
+       if (in_msg == E1000_PF_CONTROL_MSG) {
+               /* dummy mbx read to ack pf */
+               if (mbx->ops.read(hw, &in_msg, 1, 0))
+                       return;
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+                                             NULL);
+       }
 }
 
 static int
@@ -3078,7 +3090,8 @@ igbvf_dev_start(struct rte_eth_dev *dev)
        }
 
        /* check and configure queue intr-vector mapping */
-       if (dev->data->dev_conf.intr_conf.rxq != 0) {
+       if (rte_intr_cap_multiple(intr_handle) &&
+           dev->data->dev_conf.intr_conf.rxq) {
                intr_vector = dev->data->nb_rx_queues;
                ret = rte_intr_efd_enable(intr_handle, intr_vector);
                if (ret)
@@ -3736,10 +3749,6 @@ eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
        }
 
        wufc = E1000_READ_REG(hw, E1000_WUFC);
-       if (flex_filter->index < E1000_MAX_FHFT)
-               reg_off = E1000_FHFT(flex_filter->index);
-       else
-               reg_off = E1000_FHFT_EXT(flex_filter->index - E1000_MAX_FHFT);
 
        if (add) {
                if (eth_igb_flex_filter_lookup(&filter_info->flex_list,
@@ -3769,6 +3778,11 @@ eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
                        return -ENOSYS;
                }
 
+               if (flex_filter->index < E1000_MAX_FHFT)
+                       reg_off = E1000_FHFT(flex_filter->index);
+               else
+                       reg_off = E1000_FHFT_EXT(flex_filter->index - E1000_MAX_FHFT);
+
                E1000_WRITE_REG(hw, E1000_WUFC, wufc | E1000_WUFC_FLEX_HQ |
                                (E1000_WUFC_FLX0 << flex_filter->index));
                queueing = filter->len |
@@ -3797,6 +3811,11 @@ eth_igb_add_del_flex_filter(struct rte_eth_dev *dev,
                        return -ENOENT;
                }
 
+               if (it->index < E1000_MAX_FHFT)
+                       reg_off = E1000_FHFT(it->index);
+               else
+                       reg_off = E1000_FHFT_EXT(it->index - E1000_MAX_FHFT);
+
                for (i = 0; i < E1000_FHFT_SIZE_IN_DWD; i++)
                        E1000_WRITE_REG(hw, reg_off + i * sizeof(uint32_t), 0);
                E1000_WRITE_REG(hw, E1000_WUFC, wufc &
@@ -3826,7 +3845,7 @@ eth_igb_get_flex_filter(struct rte_eth_dev *dev,
        flex_filter.filter_info.priority = filter->priority;
        memcpy(flex_filter.filter_info.dwords, filter->bytes, filter->len);
        memcpy(flex_filter.filter_info.mask, filter->mask,
-                       RTE_ALIGN(filter->len, sizeof(char)) / sizeof(char));
+                       RTE_ALIGN(filter->len, CHAR_BIT) / CHAR_BIT);
 
        it = eth_igb_flex_filter_lookup(&filter_info->flex_list,
                                &flex_filter.filter_info);
@@ -5082,7 +5101,13 @@ eth_igb_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
        struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint32_t mask = 1 << queue_id;
+       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       uint32_t vec = E1000_MISC_VEC_ID;
+
+       if (rte_intr_allow_others(intr_handle))
+               vec = E1000_RX_VEC_START;
+
+       uint32_t mask = 1 << (queue_id + vec);
 
        E1000_WRITE_REG(hw, E1000_EIMC, mask);
        E1000_WRITE_FLUSH(hw);
@@ -5095,7 +5120,13 @@ eth_igb_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
        struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint32_t mask = 1 << queue_id;
+       struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+       uint32_t vec = E1000_MISC_VEC_ID;
+
+       if (rte_intr_allow_others(intr_handle))
+               vec = E1000_RX_VEC_START;
+
+       uint32_t mask = 1 << (queue_id + vec);
        uint32_t regval;
 
        regval = E1000_READ_REG(hw, E1000_EIMS);