net/e1000: move em PCI device ids to the driver
[dpdk.git] / drivers / net / e1000 / em_ethdev.c
index 1f0a7f4..ad104ed 100644 (file)
@@ -137,11 +137,38 @@ static enum e1000_fc_mode em_fc_setting = e1000_fc_full;
  * The set of PCI devices this driver supports
  */
 static const struct rte_pci_id pci_id_em_map[] = {
-
-#define RTE_PCI_DEV_ID_DECL_EM(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
-#include "rte_pci_dev_ids.h"
-
-{0},
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82540EM) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82545EM_COPPER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82545EM_FIBER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82546EB_COPPER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82546EB_FIBER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82546EB_QUAD_COPPER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_COPPER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_FIBER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_SERDES) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_SERDES_DUAL) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_SERDES_QUAD) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_QUAD_COPPER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571PT_QUAD_COPPER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_QUAD_FIBER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82571EB_QUAD_COPPER_LP) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82572EI_COPPER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82572EI_FIBER) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82572EI_SERDES) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82572EI) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82573L) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82574L) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82574LA) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_82583V) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_LPT_I217_LM) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_LPT_I217_V) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_LPTLP_I218_LM) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_LPTLP_I218_V) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_I218_LM2) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_I218_V2) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_I218_LM3) },
+       { RTE_PCI_DEVICE(E1000_INTEL_VENDOR_ID, E1000_DEV_ID_PCH_I218_V3) },
+       { .vendor_id = 0, /* sentinel */ },
 };
 
 static const struct eth_dev_ops eth_em_ops = {
@@ -538,6 +565,9 @@ eth_em_start(struct rte_eth_dev *dev)
        struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
        int ret, mask;
        uint32_t intr_vector = 0;
+       uint32_t *speeds;
+       int num_speeds;
+       bool autoneg;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -612,67 +642,58 @@ eth_em_start(struct rte_eth_dev *dev)
        E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
 
        /* Setup link speed and duplex */
-       switch (dev->data->dev_conf.link_speed) {
-       case ETH_LINK_SPEED_AUTONEG:
-               if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-                       hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
-               else if (dev->data->dev_conf.link_duplex ==
-                                       ETH_LINK_HALF_DUPLEX)
-                       hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
-               else if (dev->data->dev_conf.link_duplex ==
-                                       ETH_LINK_FULL_DUPLEX)
-                       hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
-               else
-                       goto error_invalid_config;
-               break;
-       case ETH_LINK_SPEED_10:
-               if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-                       hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
-               else if (dev->data->dev_conf.link_duplex ==
-                                       ETH_LINK_HALF_DUPLEX)
-                       hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
-               else if (dev->data->dev_conf.link_duplex ==
-                                       ETH_LINK_FULL_DUPLEX)
-                       hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
-               else
-                       goto error_invalid_config;
-               break;
-       case ETH_LINK_SPEED_100:
-               if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
-                       hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
-               else if (dev->data->dev_conf.link_duplex ==
-                                       ETH_LINK_HALF_DUPLEX)
-                       hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
-               else if (dev->data->dev_conf.link_duplex ==
-                                       ETH_LINK_FULL_DUPLEX)
-                       hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
-               else
+       speeds = &dev->data->dev_conf.link_speeds;
+       if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+               hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+       } else {
+               num_speeds = 0;
+               autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;
+
+               /* Reset */
+               hw->phy.autoneg_advertised = 0;
+
+               if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+                               ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+                               ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
+                       num_speeds = -1;
                        goto error_invalid_config;
-               break;
-       case ETH_LINK_SPEED_1000:
-               if ((dev->data->dev_conf.link_duplex ==
-                               ETH_LINK_AUTONEG_DUPLEX) ||
-                       (dev->data->dev_conf.link_duplex ==
-                                       ETH_LINK_FULL_DUPLEX))
-                       hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
-               else
+               }
+               if (*speeds & ETH_LINK_SPEED_10M_HD) {
+                       hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+                       num_speeds++;
+               }
+               if (*speeds & ETH_LINK_SPEED_10M) {
+                       hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+                       num_speeds++;
+               }
+               if (*speeds & ETH_LINK_SPEED_100M_HD) {
+                       hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+                       num_speeds++;
+               }
+               if (*speeds & ETH_LINK_SPEED_100M) {
+                       hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+                       num_speeds++;
+               }
+               if (*speeds & ETH_LINK_SPEED_1G) {
+                       hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+                       num_speeds++;
+               }
+               if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
                        goto error_invalid_config;
-               break;
-       case ETH_LINK_SPEED_10000:
-       default:
-               goto error_invalid_config;
        }
+
        e1000_setup_link(hw);
 
        if (rte_intr_allow_others(intr_handle)) {
                /* check if lsc interrupt is enabled */
-               if (dev->data->dev_conf.intr_conf.lsc != 0)
+               if (dev->data->dev_conf.intr_conf.lsc != 0) {
                        ret = eth_em_interrupt_setup(dev);
                        if (ret) {
                                PMD_INIT_LOG(ERR, "Unable to setup interrupts");
                                em_dev_clear_queues(dev);
                                return ret;
                        }
+               }
        } else {
                rte_intr_callback_unregister(intr_handle,
                                                eth_em_interrupt_handler,
@@ -694,9 +715,8 @@ eth_em_start(struct rte_eth_dev *dev)
        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);
+       PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+                    dev->data->dev_conf.link_speeds, dev->data->port_id);
        em_dev_clear_queues(dev);
        return -EINVAL;
 }
@@ -1054,6 +1074,10 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                .nb_min = E1000_MIN_RING_DESC,
                .nb_align = EM_TXD_ALIGN,
        };
+
+       dev_info->speed_capa = ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
+                       ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
+                       ETH_LINK_SPEED_1G;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -1101,14 +1125,21 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
        old = link;
 
        /* Now we check if a transition has happened */
-       if (link_check && (link.link_status == 0)) {
-               hw->mac.ops.get_link_up_info(hw, &link.link_speed,
-                       &link.link_duplex);
-               link.link_status = 1;
-       } else if (!link_check && (link.link_status == 1)) {
+       if (link_check && (link.link_status == ETH_LINK_DOWN)) {
+               uint16_t duplex, speed;
+               hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+               link.link_duplex = (duplex == FULL_DUPLEX) ?
+                               ETH_LINK_FULL_DUPLEX :
+                               ETH_LINK_HALF_DUPLEX;
+               link.link_speed = speed;
+               link.link_status = ETH_LINK_UP;
+               link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+                               ETH_LINK_SPEED_FIXED);
+       } else if (!link_check && (link.link_status == ETH_LINK_UP)) {
                link.link_speed = 0;
-               link.link_duplex = 0;
-               link.link_status = 0;
+               link.link_duplex = ETH_LINK_HALF_DUPLEX;
+               link.link_status = ETH_LINK_DOWN;
+               link.link_autoneg = ETH_LINK_SPEED_FIXED;
        }
        rte_em_dev_atomic_write_link_status(dev, &link);
 
@@ -1773,4 +1804,5 @@ struct rte_driver em_pmd_drv = {
        .init = rte_em_pmd_init,
 };
 
-PMD_REGISTER_DRIVER(em_pmd_drv);
+PMD_REGISTER_DRIVER(em_pmd_drv, em);
+DRIVER_REGISTER_PCI_TABLE(em, pci_id_em_map);