New upstream version 17.11.3
[deb_dpdk.git] / drivers / net / szedata2 / rte_eth_szedata2.c
index 54212b7..88f5fb8 100644 (file)
@@ -53,6 +53,7 @@
 #include <rte_atomic.h>
 
 #include "rte_eth_szedata2.h"
+#include "szedata2_iobuf.h"
 
 #define RTE_ETH_SZEDATA2_MAX_RX_QUEUES 32
 #define RTE_ETH_SZEDATA2_MAX_TX_QUEUES 32
 #define RTE_SZE2_PACKET_HEADER_SIZE_ALIGNED 8
 
 #define RTE_SZEDATA2_DRIVER_NAME net_szedata2
-#define RTE_SZEDATA2_PCI_DRIVER_NAME "rte_szedata2_pmd"
 
 #define SZEDATA2_DEV_PATH_FMT "/dev/szedataII%u"
 
 struct szedata2_rx_queue {
        struct szedata *sze;
        uint8_t rx_channel;
-       uint8_t in_port;
+       uint16_t in_port;
        struct rte_mempool *mb_pool;
        volatile uint64_t rx_pkts;
        volatile uint64_t rx_bytes;
@@ -682,7 +682,7 @@ eth_szedata2_tx(void *queue,
        uint32_t hwpkt_len;
        uint32_t unlock_size;
        uint32_t rem_len;
-       uint8_t mbuf_segs;
+       uint16_t mbuf_segs;
        uint16_t pkt_left = nb_pkts;
 
        if (sze_q->sze == NULL || nb_pkts == 0)
@@ -1032,7 +1032,7 @@ eth_dev_info(struct rte_eth_dev *dev,
                struct rte_eth_dev_info *dev_info)
 {
        struct pmd_internals *internals = dev->data->dev_private;
-       dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device);
+       dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        dev_info->if_index = 0;
        dev_info->max_mac_addrs = 1;
        dev_info->max_rx_pktlen = (uint32_t)-1;
@@ -1042,7 +1042,7 @@ eth_dev_info(struct rte_eth_dev *dev,
        dev_info->speed_capa = ETH_LINK_SPEED_100G;
 }
 
-static void
+static int
 eth_stats_get(struct rte_eth_dev *dev,
                struct rte_eth_stats *stats)
 {
@@ -1054,22 +1054,29 @@ eth_stats_get(struct rte_eth_dev *dev,
        uint64_t tx_err_total = 0;
        uint64_t rx_total_bytes = 0;
        uint64_t tx_total_bytes = 0;
-       const struct pmd_internals *internals = dev->data->dev_private;
 
-       for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS && i < nb_rx; i++) {
-               stats->q_ipackets[i] = internals->rx_queue[i].rx_pkts;
-               stats->q_ibytes[i] = internals->rx_queue[i].rx_bytes;
-               rx_total += stats->q_ipackets[i];
-               rx_total_bytes += stats->q_ibytes[i];
+       for (i = 0; i < nb_rx; i++) {
+               struct szedata2_rx_queue *rxq = dev->data->rx_queues[i];
+
+               if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+                       stats->q_ipackets[i] = rxq->rx_pkts;
+                       stats->q_ibytes[i] = rxq->rx_bytes;
+               }
+               rx_total += rxq->rx_pkts;
+               rx_total_bytes += rxq->rx_bytes;
        }
 
-       for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS && i < nb_tx; i++) {
-               stats->q_opackets[i] = internals->tx_queue[i].tx_pkts;
-               stats->q_obytes[i] = internals->tx_queue[i].tx_bytes;
-               stats->q_errors[i] = internals->tx_queue[i].err_pkts;
-               tx_total += stats->q_opackets[i];
-               tx_total_bytes += stats->q_obytes[i];
-               tx_err_total += stats->q_errors[i];
+       for (i = 0; i < nb_tx; i++) {
+               struct szedata2_tx_queue *txq = dev->data->tx_queues[i];
+
+               if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+                       stats->q_opackets[i] = txq->tx_pkts;
+                       stats->q_obytes[i] = txq->tx_bytes;
+                       stats->q_errors[i] = txq->err_pkts;
+               }
+               tx_total += txq->tx_pkts;
+               tx_total_bytes += txq->tx_bytes;
+               tx_err_total += txq->err_pkts;
        }
 
        stats->ipackets = rx_total;
@@ -1077,6 +1084,8 @@ eth_stats_get(struct rte_eth_dev *dev,
        stats->ibytes = rx_total_bytes;
        stats->obytes = tx_total_bytes;
        stats->oerrors = tx_err_total;
+
+       return 0;
 }
 
 static void
@@ -1140,6 +1149,33 @@ eth_dev_close(struct rte_eth_dev *dev)
        dev->data->nb_tx_queues = 0;
 }
 
+/**
+ * Function takes value from first IBUF status register.
+ * Values in IBUF and OBUF should be same.
+ *
+ * @param internals
+ *     Pointer to device private structure.
+ * @return
+ *     Link speed constant.
+ */
+static inline enum szedata2_link_speed
+get_link_speed(const struct pmd_internals *internals)
+{
+       const volatile struct szedata2_ibuf *ibuf =
+               ibuf_ptr_by_index(internals->pci_rsc, 0);
+       uint32_t speed = (szedata2_read32(&ibuf->ibuf_st) & 0x70) >> 4;
+       switch (speed) {
+       case 0x03:
+               return SZEDATA2_LINK_SPEED_10G;
+       case 0x04:
+               return SZEDATA2_LINK_SPEED_40G;
+       case 0x05:
+               return SZEDATA2_LINK_SPEED_100G;
+       default:
+               return SZEDATA2_LINK_SPEED_DEFAULT;
+       }
+}
+
 static int
 eth_link_update(struct rte_eth_dev *dev,
                int wait_to_complete __rte_unused)
@@ -1149,11 +1185,11 @@ eth_link_update(struct rte_eth_dev *dev,
        struct rte_eth_link *dev_link = &dev->data->dev_link;
        struct pmd_internals *internals = (struct pmd_internals *)
                dev->data->dev_private;
-       volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_ibuf *);
+       const volatile struct szedata2_ibuf *ibuf;
+       uint32_t i;
+       bool link_is_up = false;
 
-       switch (cgmii_link_speed(ibuf)) {
+       switch (get_link_speed(internals)) {
        case SZEDATA2_LINK_SPEED_10G:
                link.link_speed = ETH_SPEED_NUM_10G;
                break;
@@ -1171,10 +1207,21 @@ eth_link_update(struct rte_eth_dev *dev,
        /* szedata2 uses only full duplex */
        link.link_duplex = ETH_LINK_FULL_DUPLEX;
 
-       link.link_status = (cgmii_ibuf_is_enabled(ibuf) &&
-                       cgmii_ibuf_is_link_up(ibuf)) ? ETH_LINK_UP : ETH_LINK_DOWN;
+       for (i = 0; i < szedata2_ibuf_count; i++) {
+               ibuf = ibuf_ptr_by_index(internals->pci_rsc, i);
+               /*
+                * Link is considered up if at least one ibuf is enabled
+                * and up.
+                */
+               if (ibuf_is_enabled(ibuf) && ibuf_is_link_up(ibuf)) {
+                       link_is_up = true;
+                       break;
+               }
+       }
+
+       link.link_status = (link_is_up) ? ETH_LINK_UP : ETH_LINK_DOWN;
 
-       link.link_autoneg = ETH_LINK_SPEED_FIXED;
+       link.link_autoneg = ETH_LINK_FIXED;
 
        rte_atomic64_cmpset((uint64_t *)dev_link, *(uint64_t *)dev_link,
                        *(uint64_t *)link_ptr);
@@ -1187,15 +1234,12 @@ eth_dev_set_link_up(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = (struct pmd_internals *)
                dev->data->dev_private;
-       volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_ibuf *);
-       volatile struct szedata2_cgmii_obuf *obuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_OBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_obuf *);
-
-       cgmii_ibuf_enable(ibuf);
-       cgmii_obuf_enable(obuf);
+       uint32_t i;
+
+       for (i = 0; i < szedata2_ibuf_count; i++)
+               ibuf_enable(ibuf_ptr_by_index(internals->pci_rsc, i));
+       for (i = 0; i < szedata2_obuf_count; i++)
+               obuf_enable(obuf_ptr_by_index(internals->pci_rsc, i));
        return 0;
 }
 
@@ -1204,15 +1248,12 @@ eth_dev_set_link_down(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = (struct pmd_internals *)
                dev->data->dev_private;
-       volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_ibuf *);
-       volatile struct szedata2_cgmii_obuf *obuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_OBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_obuf *);
-
-       cgmii_ibuf_disable(ibuf);
-       cgmii_obuf_disable(obuf);
+       uint32_t i;
+
+       for (i = 0; i < szedata2_ibuf_count; i++)
+               ibuf_disable(ibuf_ptr_by_index(internals->pci_rsc, i));
+       for (i = 0; i < szedata2_obuf_count; i++)
+               obuf_disable(obuf_ptr_by_index(internals->pci_rsc, i));
        return 0;
 }
 
@@ -1292,10 +1333,12 @@ eth_promiscuous_enable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = (struct pmd_internals *)
                dev->data->dev_private;
-       volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_ibuf *);
-       cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_PROMISC);
+       uint32_t i;
+
+       for (i = 0; i < szedata2_ibuf_count; i++) {
+               ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
+                               SZEDATA2_MAC_CHMODE_PROMISC);
+       }
 }
 
 static void
@@ -1303,10 +1346,12 @@ eth_promiscuous_disable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = (struct pmd_internals *)
                dev->data->dev_private;
-       volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_ibuf *);
-       cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_ONLY_VALID);
+       uint32_t i;
+
+       for (i = 0; i < szedata2_ibuf_count; i++) {
+               ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
+                               SZEDATA2_MAC_CHMODE_ONLY_VALID);
+       }
 }
 
 static void
@@ -1314,10 +1359,12 @@ eth_allmulticast_enable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = (struct pmd_internals *)
                dev->data->dev_private;
-       volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_ibuf *);
-       cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_ALL_MULTICAST);
+       uint32_t i;
+
+       for (i = 0; i < szedata2_ibuf_count; i++) {
+               ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
+                               SZEDATA2_MAC_CHMODE_ALL_MULTICAST);
+       }
 }
 
 static void
@@ -1325,10 +1372,12 @@ eth_allmulticast_disable(struct rte_eth_dev *dev)
 {
        struct pmd_internals *internals = (struct pmd_internals *)
                dev->data->dev_private;
-       volatile struct szedata2_cgmii_ibuf *ibuf = SZEDATA2_PCI_RESOURCE_PTR(
-                       internals->pci_rsc, SZEDATA2_CGMII_IBUF_BASE_OFF,
-                       volatile struct szedata2_cgmii_ibuf *);
-       cgmii_ibuf_mac_mode_write(ibuf, SZEDATA2_MAC_CHMODE_ONLY_VALID);
+       uint32_t i;
+
+       for (i = 0; i < szedata2_ibuf_count; i++) {
+               ibuf_mac_mode_write(ibuf_ptr_by_index(internals->pci_rsc, i),
+                               SZEDATA2_MAC_CHMODE_ONLY_VALID);
+       }
 }
 
 static const struct eth_dev_ops ops = {
@@ -1375,9 +1424,9 @@ get_szedata2_index(const struct rte_pci_addr *pcislot_addr, uint32_t *index)
        FILE *fd;
        char pcislot_path[PATH_MAX];
        uint32_t domain;
-       uint32_t bus;
-       uint32_t devid;
-       uint32_t function;
+       uint8_t bus;
+       uint8_t devid;
+       uint8_t function;
 
        dir = opendir("/sys/class/combo");
        if (dir == NULL)
@@ -1402,7 +1451,7 @@ get_szedata2_index(const struct rte_pci_addr *pcislot_addr, uint32_t *index)
                if (fd == NULL)
                        continue;
 
-               ret = fscanf(fd, "%4" PRIx16 ":%2" PRIx8 ":%2" PRIx8 ".%" PRIx8,
+               ret = fscanf(fd, "%8" SCNx32 ":%2" SCNx8 ":%2" SCNx8 ".%" SCNx8,
                                &domain, &bus, &devid, &function);
                fclose(fd);
                if (ret != 4)
@@ -1431,7 +1480,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev)
        struct szedata *szedata_temp;
        int ret;
        uint32_t szedata2_index;
-       struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+       struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_pci_addr *pci_addr = &pci_dev->addr;
        struct rte_mem_resource *pci_rsc =
                &pci_dev->mem_resource[PCI_RESOURCE_NUMBER];
@@ -1498,7 +1547,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev)
                return -EINVAL;
        }
        snprintf(rsc_filename, PATH_MAX,
-               "%s/" PCI_PRI_FMT "/resource%u", pci_get_sysfs_path(),
+               "%s/" PCI_PRI_FMT "/resource%u", rte_pci_get_sysfs_path(),
                pci_addr->domain, pci_addr->bus,
                pci_addr->devid, pci_addr->function, PCI_RESOURCE_NUMBER);
        fd = open(rsc_filename, O_RDWR);
@@ -1511,7 +1560,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev)
                        pci_dev->mem_resource[PCI_RESOURCE_NUMBER].len,
                        PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        close(fd);
-       if (pci_resource_ptr == NULL) {
+       if (pci_resource_ptr == MAP_FAILED) {
                RTE_LOG(ERR, PMD, "Could not mmap file %s (fd = %d)\n",
                                rsc_filename, fd);
                return -EINVAL;
@@ -1554,7 +1603,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev)
 static int
 rte_szedata2_eth_dev_uninit(struct rte_eth_dev *dev)
 {
-       struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device);
+       struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_pci_addr *pci_addr = &pci_dev->addr;
 
        rte_free(dev->data->mac_addrs);