mpipe: fix link initialization ordering
[dpdk.git] / drivers / net / e1000 / igb_ethdev.c
index 88995b0..2581995 100644 (file)
@@ -78,7 +78,7 @@
 #define IGB_8_BIT_MASK   UINT8_MAX
 
 /* Additional timesync values. */
-#define E1000_CYCLECOUNTER_MASK      0xffffffffffffffff
+#define E1000_CYCLECOUNTER_MASK      0xffffffffffffffffULL
 #define E1000_ETQF_FILTER_1588       3
 #define IGB_82576_TSYNC_SHIFT        16
 #define E1000_INCPERIOD_82576        (1 << E1000_TIMINCA_16NS_SHIFT)
@@ -125,7 +125,9 @@ static int  eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int eth_igb_vlan_filter_set(struct rte_eth_dev *dev,
                uint16_t vlan_id, int on);
-static void eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid_id);
+static int eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+                                enum rte_vlan_type vlan_type,
+                                uint16_t tpid_id);
 static void eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask);
 
 static void igb_vlan_hw_filter_enable(struct rte_eth_dev *dev);
@@ -647,8 +649,6 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev)
 
        pci_dev = eth_dev->pci_dev;
 
-       rte_eth_copy_pci_info(eth_dev, pci_dev);
-
        eth_dev->dev_ops = &eth_igb_ops;
        eth_dev->rx_pkt_burst = &eth_igb_recv_pkts;
        eth_dev->tx_pkt_burst = &eth_igb_xmit_pkts;
@@ -662,6 +662,8 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev)
                return 0;
        }
 
+       rte_eth_copy_pci_info(eth_dev, pci_dev);
+
        hw->hw_addr= (void *)pci_dev->mem_resource[0].addr;
 
        igb_identify_hardware(eth_dev);
@@ -791,7 +793,7 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev)
 err_late:
        igb_hw_control_release(hw);
 
-       return (error);
+       return error;
 }
 
 static int
@@ -846,6 +848,7 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev)
        struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
        int diag;
+       struct ether_addr *perm_addr = (struct ether_addr *)hw->mac.perm_addr;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -898,6 +901,26 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev)
                return -ENOMEM;
        }
 
+       /* Generate a random MAC address, if none was assigned by PF. */
+       if (is_zero_ether_addr(perm_addr)) {
+               eth_random_addr(perm_addr->addr_bytes);
+               diag = e1000_rar_set(hw, perm_addr->addr_bytes, 0);
+               if (diag) {
+                       rte_free(eth_dev->data->mac_addrs);
+                       eth_dev->data->mac_addrs = NULL;
+                       return diag;
+               }
+               PMD_INIT_LOG(INFO, "\tVF MAC address not assigned by Host PF");
+               PMD_INIT_LOG(INFO, "\tAssign randomly generated MAC address "
+                            "%02x:%02x:%02x:%02x:%02x:%02x",
+                            perm_addr->addr_bytes[0],
+                            perm_addr->addr_bytes[1],
+                            perm_addr->addr_bytes[2],
+                            perm_addr->addr_bytes[3],
+                            perm_addr->addr_bytes[4],
+                            perm_addr->addr_bytes[5]);
+       }
+
        /* Copy the permanent MAC address */
        ether_addr_copy((struct ether_addr *) hw->mac.perm_addr,
                        &eth_dev->data->mac_addrs[0]);
@@ -989,7 +1012,7 @@ rte_igbvf_pmd_init(const char *name __rte_unused, const char *params __rte_unuse
        PMD_INIT_FUNC_TRACE();
 
        rte_eth_driver_register(&rte_igbvf_pmd);
-       return (0);
+       return 0;
 }
 
 static int
@@ -1101,6 +1124,9 @@ eth_igb_start(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
+       /* disable uio/vfio intr/eventfd mapping */
+       rte_intr_disable(intr_handle);
+
        /* Power up the phy. Needed to make the link go Up */
        e1000_power_up_phy(hw);
 
@@ -1122,7 +1148,7 @@ eth_igb_start(struct rte_eth_dev *dev)
        /* Initialize the hardware */
        if (igb_hardware_init(hw)) {
                PMD_INIT_LOG(ERR, "Unable to initialize the hardware");
-               return (-EIO);
+               return -EIO;
        }
        adapter->stopped = 0;
 
@@ -1265,14 +1291,14 @@ eth_igb_start(struct rte_eth_dev *dev)
 
        PMD_INIT_LOG(DEBUG, "<<");
 
-       return (0);
+       return 0;
 
 error_invalid_config:
        PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
                     dev->data->dev_conf.link_speed,
                     dev->data->dev_conf.link_duplex, dev->data->port_id);
        igb_dev_clear_queues(dev);
-       return (-EINVAL);
+       return -EINVAL;
 }
 
 /*********************************************************************
@@ -1465,13 +1491,13 @@ igb_hardware_init(struct e1000_hw *hw)
 
        diag = e1000_init_hw(hw);
        if (diag < 0)
-               return (diag);
+               return diag;
 
        E1000_WRITE_REG(hw, E1000_VET, ETHER_TYPE_VLAN << 16 | ETHER_TYPE_VLAN);
        e1000_get_phy_info(hw);
        e1000_check_for_link(hw);
 
-       return (0);
+       return 0;
 }
 
 /* This function is based on igb_update_stats_counters() in igb/if_igb.c */
@@ -1480,6 +1506,13 @@ igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
 {
        int pause_frames;
 
+       uint64_t old_gprc  = stats->gprc;
+       uint64_t old_gptc  = stats->gptc;
+       uint64_t old_tpr   = stats->tpr;
+       uint64_t old_tpt   = stats->tpt;
+       uint64_t old_rpthc = stats->rpthc;
+       uint64_t old_hgptc = stats->hgptc;
+
        if(hw->phy.media_type == e1000_media_type_copper ||
            (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) {
                stats->symerrs +=
@@ -1521,10 +1554,13 @@ igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
        /* For the 64-bit byte counters the low dword must be read first. */
        /* Both registers clear on the read of the high dword */
 
+       /* Workaround CRC bytes included in size, take away 4 bytes/packet */
        stats->gorc += E1000_READ_REG(hw, E1000_GORCL);
        stats->gorc += ((uint64_t)E1000_READ_REG(hw, E1000_GORCH) << 32);
+       stats->gorc -= (stats->gprc - old_gprc) * ETHER_CRC_LEN;
        stats->gotc += E1000_READ_REG(hw, E1000_GOTCL);
        stats->gotc += ((uint64_t)E1000_READ_REG(hw, E1000_GOTCH) << 32);
+       stats->gotc -= (stats->gptc - old_gptc) * ETHER_CRC_LEN;
 
        stats->rnbc += E1000_READ_REG(hw, E1000_RNBC);
        stats->ruc += E1000_READ_REG(hw, E1000_RUC);
@@ -1532,13 +1568,16 @@ igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
        stats->roc += E1000_READ_REG(hw, E1000_ROC);
        stats->rjc += E1000_READ_REG(hw, E1000_RJC);
 
+       stats->tpr += E1000_READ_REG(hw, E1000_TPR);
+       stats->tpt += E1000_READ_REG(hw, E1000_TPT);
+
        stats->tor += E1000_READ_REG(hw, E1000_TORL);
        stats->tor += ((uint64_t)E1000_READ_REG(hw, E1000_TORH) << 32);
+       stats->tor -= (stats->tpr - old_tpr) * ETHER_CRC_LEN;
        stats->tot += E1000_READ_REG(hw, E1000_TOTL);
        stats->tot += ((uint64_t)E1000_READ_REG(hw, E1000_TOTH) << 32);
+       stats->tot -= (stats->tpt - old_tpt) * ETHER_CRC_LEN;
 
-       stats->tpr += E1000_READ_REG(hw, E1000_TPR);
-       stats->tpt += E1000_READ_REG(hw, E1000_TPT);
        stats->ptc64 += E1000_READ_REG(hw, E1000_PTC64);
        stats->ptc127 += E1000_READ_REG(hw, E1000_PTC127);
        stats->ptc255 += E1000_READ_REG(hw, E1000_PTC255);
@@ -1571,8 +1610,10 @@ igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
        stats->htcbdpc += E1000_READ_REG(hw, E1000_HTCBDPC);
        stats->hgorc += E1000_READ_REG(hw, E1000_HGORCL);
        stats->hgorc += ((uint64_t)E1000_READ_REG(hw, E1000_HGORCH) << 32);
+       stats->hgorc -= (stats->rpthc - old_rpthc) * ETHER_CRC_LEN;
        stats->hgotc += E1000_READ_REG(hw, E1000_HGOTCL);
        stats->hgotc += ((uint64_t)E1000_READ_REG(hw, E1000_HGOTCH) << 32);
+       stats->hgotc -= (stats->hgptc - old_hgptc) * ETHER_CRC_LEN;
        stats->lenerrs += E1000_READ_REG(hw, E1000_LENERRS);
        stats->scvpc += E1000_READ_REG(hw, E1000_SCVPC);
        stats->hrmpc += E1000_READ_REG(hw, E1000_HRMPC);
@@ -2145,15 +2186,28 @@ eth_igb_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
        return 0;
 }
 
-static void
-eth_igb_vlan_tpid_set(struct rte_eth_dev *dev, uint16_t tpid)
+static int
+eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
+                     enum rte_vlan_type vlan_type,
+                     uint16_t tpid)
 {
        struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint32_t reg = ETHER_TYPE_VLAN ;
+       uint32_t reg = ETHER_TYPE_VLAN;
+       int ret = 0;
 
-       reg |= (tpid << 16);
-       E1000_WRITE_REG(hw, E1000_VET, reg);
+       switch (vlan_type) {
+       case ETH_VLAN_TYPE_INNER:
+               reg |= (tpid << 16);
+               E1000_WRITE_REG(hw, E1000_VET, reg);
+               break;
+       default:
+               ret = -EINVAL;
+               PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
+               break;
+       }
+
+       return ret;
 }
 
 static void
@@ -2471,7 +2525,7 @@ eth_igb_led_on(struct rte_eth_dev *dev)
        struct e1000_hw *hw;
 
        hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       return (e1000_led_on(hw) == E1000_SUCCESS ? 0 : -ENOTSUP);
+       return e1000_led_on(hw) == E1000_SUCCESS ? 0 : -ENOTSUP;
 }
 
 static int
@@ -2480,7 +2534,7 @@ eth_igb_led_off(struct rte_eth_dev *dev)
        struct e1000_hw *hw;
 
        hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       return (e1000_led_off(hw) == E1000_SUCCESS ? 0 : -ENOTSUP);
+       return e1000_led_off(hw) == E1000_SUCCESS ? 0 : -ENOTSUP;
 }
 
 static int
@@ -2552,7 +2606,7 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
            (fc_conf->high_water < fc_conf->low_water)) {
                PMD_INIT_LOG(ERR, "e1000 incorrect high/low water value");
                PMD_INIT_LOG(ERR, "high water must <=  0x%x", max_high_water);
-               return (-EINVAL);
+               return -EINVAL;
        }
 
        hw->fc.requested_mode = rte_fcmode_2_e1000_fcmode[fc_conf->mode];
@@ -2582,7 +2636,7 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        }
 
        PMD_INIT_LOG(ERR, "e1000_setup_link_generic = 0x%x", err);
-       return (-EIO);
+       return -EIO;
 }
 
 #define E1000_RAH_POOLSEL_SHIFT      (18)