net/mlx5/linux: fix firmware version
[dpdk.git] / drivers / raw / ifpga / base / ifpga_fme.c
index 87fa596..43c7b9c 100644 (file)
@@ -7,6 +7,7 @@
 #include "opae_intel_max10.h"
 #include "opae_i2c.h"
 #include "opae_at24_eeprom.h"
+#include "ifpga_sec_mgr.h"
 
 #define PWR_THRESHOLD_MAX       0x7F
 
@@ -100,6 +101,24 @@ static int fme_hdr_get_ports_num(struct ifpga_fme_hw *fme, u64 *ports_num)
        return 0;
 }
 
+static int fme_hdr_get_port_type(struct ifpga_fme_hw *fme, u64 *port_type)
+{
+       struct feature_fme_header *fme_hdr
+               = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
+       struct feature_fme_port pt;
+       u32 port = (u32)((*port_type >> 32) & 0xffffffff);
+
+       pt.csr = readq(&fme_hdr->port[port]);
+       if (!pt.port_implemented)
+               return -ENODEV;
+       if (pt.afu_access_control)
+               *port_type |= 0x1;
+       else
+               *port_type &= ~0x1;
+
+       return 0;
+}
+
 static int fme_hdr_get_cache_size(struct ifpga_fme_hw *fme, u64 *cache_size)
 {
        struct feature_fme_header *fme_hdr
@@ -178,6 +197,8 @@ fme_hdr_get_prop(struct ifpga_feature *feature, struct feature_prop *prop)
                return fme_hdr_get_bitstream_id(fme, &prop->data);
        case FME_HDR_PROP_BITSTREAM_METADATA:
                return fme_hdr_get_bitstream_metadata(fme, &prop->data);
+       case FME_HDR_PROP_PORT_TYPE:
+               return fme_hdr_get_port_type(fme, &prop->data);
        }
 
        return -ENOENT;
@@ -787,8 +808,22 @@ static const char *board_type_to_string(u32 type)
        return "unknown";
 }
 
+static const char *board_major_to_string(u32 major)
+{
+       switch (major) {
+       case VISTA_CREEK:
+               return "VISTA_CREEK";
+       case RUSH_CREEK:
+               return "RUSH_CREEK";
+       case DARBY_CREEK:
+               return "DARBY_CREEK";
+       }
+
+       return "unknown";
+}
+
 static int board_type_to_info(u32 type,
-               struct ifpga_fme_board_info *info)
+               struct opae_board_info *info)
 {
        switch (type) {
        case VC_8_10G:
@@ -825,22 +860,47 @@ static int board_type_to_info(u32 type,
 static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 {
        struct fme_bitstream_id id;
+       struct ifpga_hw *hw;
        u32 val;
 
+       hw = fme->parent;
+       if (!hw)
+               return -ENODEV;
+
        if (fme_hdr_get_bitstream_id(fme, &id.id))
                return -EINVAL;
 
+       fme->board_info.major = id.major;
+       fme->board_info.minor = id.minor;
        fme->board_info.type = id.interface;
-       fme->board_info.build_hash = id.hash;
-       fme->board_info.debug_version = id.debug;
-       fme->board_info.major_version = id.major;
-       fme->board_info.minor_version = id.minor;
+       fme->board_info.fvl_bypass = id.fvl_bypass;
+       fme->board_info.mac_lightweight = id.mac_lightweight;
+       fme->board_info.lightweight = id.lightweiht;
+       fme->board_info.disaggregate = id.disagregate;
+       fme->board_info.seu = id.seu;
+       fme->board_info.ptp = id.ptp;
+
+       dev_info(fme, "found: PCI dev: %02x:%02x:%x board: %s type: %s\n",
+                       hw->pci_data->bus,
+                       hw->pci_data->devid,
+                       hw->pci_data->function,
+                       board_major_to_string(fme->board_info.major),
+                       board_type_to_string(fme->board_info.type));
+
+       dev_info(fme, "support feature:\n"
+                       "fvl_bypass:%s\n"
+                       "mac_lightweight:%s\n"
+                       "lightweight:%s\n"
+                       "disaggregate:%s\n"
+                       "seu:%s\n"
+                       "ptp1588:%s\n",
+                       check_support(fme->board_info.fvl_bypass),
+                       check_support(fme->board_info.mac_lightweight),
+                       check_support(fme->board_info.lightweight),
+                       check_support(fme->board_info.disaggregate),
+                       check_support(fme->board_info.seu),
+                       check_support(fme->board_info.ptp));
 
-       dev_info(fme, "board type: %s major_version:%u minor_version:%u build_hash:%u\n",
-                       board_type_to_string(fme->board_info.type),
-                       fme->board_info.major_version,
-                       fme->board_info.minor_version,
-                       fme->board_info.build_hash);
 
        if (board_type_to_info(fme->board_info.type, &fme->board_info))
                return -EINVAL;
@@ -851,13 +911,17 @@ static int fme_get_board_interface(struct ifpga_fme_hw *fme)
                        fme->board_info.nums_of_fvl,
                        fme->board_info.ports_per_fvl);
 
-       if (max10_sys_read(MAX10_BUILD_VER, &val))
+       if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
+               return -EINVAL;
+       fme->board_info.boot_page = val & 0x7;
+
+       if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
                return -EINVAL;
-       fme->board_info.max10_version = val & 0xffffff;
+       fme->board_info.max10_version = val;
 
-       if (max10_sys_read(NIOS2_FW_VERSION, &val))
+       if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
                return -EINVAL;
-       fme->board_info.nios_fw_version = val & 0xffffff;
+       fme->board_info.nios_fw_version = val;
 
        dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
                fme->board_info.max10_version,
@@ -866,12 +930,12 @@ static int fme_get_board_interface(struct ifpga_fme_hw *fme)
        return 0;
 }
 
-static int spi_self_checking(void)
+static int spi_self_checking(struct intel_max10_device *dev)
 {
        u32 val;
        int ret;
 
-       ret = max10_sys_read(MAX10_TEST_REG, &val);
+       ret = max10_sys_read(dev, MAX10_TEST_REG, &val);
        if (ret)
                return -EIO;
 
@@ -880,6 +944,25 @@ static int spi_self_checking(void)
        return 0;
 }
 
+static void init_spi_share_data(struct ifpga_fme_hw *fme,
+                               struct altera_spi_device *spi)
+{
+       struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent;
+       opae_share_data *sd = NULL;
+
+       if (hw && hw->adapter && hw->adapter->shm.ptr) {
+               dev_info(NULL, "transfer share data to spi\n");
+               sd = (opae_share_data *)hw->adapter->shm.ptr;
+               spi->mutex = &sd->spi_mutex;
+               spi->dtb_sz_ptr = &sd->dtb_size;
+               spi->dtb = sd->dtb;
+       } else {
+               spi->mutex = NULL;
+               spi->dtb_sz_ptr = NULL;
+               spi->dtb = NULL;
+       }
+}
+
 static int fme_spi_init(struct ifpga_feature *feature)
 {
        struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
@@ -896,6 +979,7 @@ static int fme_spi_init(struct ifpga_feature *feature)
        spi_master = altera_spi_alloc(feature->addr, TYPE_SPI);
        if (!spi_master)
                return -ENODEV;
+       init_spi_share_data(fme, spi_master);
 
        altera_spi_init(spi_master);
 
@@ -909,7 +993,7 @@ static int fme_spi_init(struct ifpga_feature *feature)
        fme->max10_dev = max10;
 
        /* SPI self test */
-       if (spi_self_checking()) {
+       if (spi_self_checking(max10)) {
                ret = -EIO;
                goto max10_fail;
        }
@@ -939,20 +1023,58 @@ struct ifpga_feature_ops fme_spi_master_ops = {
 static int nios_spi_wait_init_done(struct altera_spi_device *dev)
 {
        u32 val = 0;
-       unsigned long timeout = msecs_to_timer_cycles(10000);
+       unsigned long timeout = rte_get_timer_cycles() +
+                       msecs_to_timer_cycles(10000);
        unsigned long ticks;
+       int major_version;
+       int fecmode = FEC_MODE_NO;
 
+       if (spi_reg_read(dev, NIOS_VERSION, &val))
+               return -EIO;
+
+       major_version =
+               (val & NIOS_VERSION_MAJOR) >> NIOS_VERSION_MAJOR_SHIFT;
+       dev_info(dev, "A10 NIOS FW version %d\n", major_version);
+
+       if (major_version >= 3) {
+               /* read NIOS_INIT to check if PKVL INIT done or not */
+               if (spi_reg_read(dev, NIOS_INIT, &val))
+                       return -EIO;
+
+               dev_debug(dev, "read NIOS_INIT: 0x%x\n", val);
+
+               /* check if PKVLs are initialized already */
+               if (val & NIOS_INIT_DONE || val & NIOS_INIT_START)
+                       goto nios_init_done;
+
+               /* start to config the default FEC mode */
+               val = fecmode | NIOS_INIT_START;
+
+               if (spi_reg_write(dev, NIOS_INIT, val))
+                       return -EIO;
+       }
+
+nios_init_done:
        do {
-               if (spi_reg_read(dev, NIOS_SPI_INIT_DONE, &val))
+               if (spi_reg_read(dev, NIOS_INIT, &val))
                        return -EIO;
-               if (val)
+               if (val & NIOS_INIT_DONE)
                        break;
 
                ticks = rte_get_timer_cycles();
                if (time_after(ticks, timeout))
                        return -ETIMEDOUT;
                msleep(100);
-       } while (!val);
+       } while (1);
+
+       /* get the fecmode */
+       if (spi_reg_read(dev, NIOS_INIT, &val))
+               return -EIO;
+       dev_debug(dev, "read NIOS_INIT: 0x%x\n", val);
+       fecmode = (val & REQ_FEC_MODE) >> REQ_FEC_MODE_SHIFT;
+       dev_info(dev, "fecmode: 0x%x, %s\n", fecmode,
+                       (fecmode == FEC_MODE_KR) ? "kr" :
+                       ((fecmode == FEC_MODE_RS) ? "rs" : "no"));
 
        return 0;
 }
@@ -961,23 +1083,20 @@ static int nios_spi_check_error(struct altera_spi_device *dev)
 {
        u32 value = 0;
 
-       if (spi_reg_read(dev, NIOS_SPI_INIT_STS0, &value))
+       if (spi_reg_read(dev, PKVL_A_MODE_STS, &value))
                return -EIO;
 
-       dev_debug(dev, "SPI init status0 0x%x\n", value);
+       dev_debug(dev, "PKVL A Mode Status 0x%x\n", value);
 
-       /* Error code: 0xFFF0 to 0xFFFC */
-       if (value >= 0xFFF0 && value <= 0xFFFC)
+       if (value >= 0x100)
                return -EINVAL;
 
-       value = 0;
-       if (spi_reg_read(dev, NIOS_SPI_INIT_STS1, &value))
+       if (spi_reg_read(dev, PKVL_B_MODE_STS, &value))
                return -EIO;
 
-       dev_debug(dev, "SPI init status1 0x%x\n", value);
+       dev_debug(dev, "PKVL B Mode Status 0x%x\n", value);
 
-       /* Error code: 0xFFF0 to 0xFFFC */
-       if (value >= 0xFFF0 && value <= 0xFFFC)
+       if (value >= 0x100)
                return -EINVAL;
 
        return 0;
@@ -988,8 +1107,18 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
        struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
        struct altera_spi_device *spi_master;
        struct intel_max10_device *max10;
+       struct ifpga_hw *hw;
+       struct opae_manager *mgr;
        int ret = 0;
 
+       hw = fme->parent;
+       if (!hw)
+               return -ENODEV;
+
+       mgr = hw->adapter->mgr;
+       if (!mgr)
+               return -ENODEV;
+
        dev_info(fme, "FME SPI Master (NIOS) Init.\n");
        dev_debug(fme, "FME SPI base addr %p.\n",
                        feature->addr);
@@ -999,14 +1128,20 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
        spi_master = altera_spi_alloc(feature->addr, TYPE_NIOS_SPI);
        if (!spi_master)
                return -ENODEV;
+       init_spi_share_data(fme, spi_master);
 
        /**
         * 1. wait A10 NIOS initial finished and
         * release the SPI master to Host
         */
+       if (spi_master->mutex)
+               pthread_mutex_lock(spi_master->mutex);
+
        ret = nios_spi_wait_init_done(spi_master);
        if (ret != 0) {
                dev_err(fme, "FME NIOS_SPI init fail\n");
+               if (spi_master->mutex)
+                       pthread_mutex_unlock(spi_master->mutex);
                goto release_dev;
        }
 
@@ -1016,6 +1151,9 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
        if (nios_spi_check_error(spi_master))
                dev_info(fme, "NIOS_SPI INIT done, but found some error\n");
 
+       if (spi_master->mutex)
+               pthread_mutex_unlock(spi_master->mutex);
+
        /* 3. init the spi master*/
        altera_spi_init(spi_master);
 
@@ -1027,13 +1165,23 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
                goto release_dev;
        }
 
+       fme->max10_dev = max10;
+
+       max10->bus = hw->pci_data->bus;
+
        fme_get_board_interface(fme);
 
-       fme->max10_dev = max10;
+       mgr->sensor_list = &max10->opae_sensor_list;
 
        /* SPI self test */
-       if (spi_self_checking())
+       if (spi_self_checking(max10))
+               goto spi_fail;
+
+       ret = init_sec_mgr(fme);
+       if (ret) {
+               dev_err(fme, "security manager init fail\n");
                goto spi_fail;
+       }
 
        return ret;
 
@@ -1048,6 +1196,7 @@ static void fme_nios_spi_uinit(struct ifpga_feature *feature)
 {
        struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
 
+       release_sec_mgr(fme);
        if (fme->max10_dev)
                intel_max10_device_remove(fme->max10_dev);
 }
@@ -1090,6 +1239,25 @@ static int i2c_mac_rom_test(struct altera_i2c_dev *dev)
        return 0;
 }
 
+static void init_i2c_mutex(struct ifpga_fme_hw *fme)
+{
+       struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent;
+       struct altera_i2c_dev *i2c_dev;
+       opae_share_data *sd = NULL;
+
+       if (fme->i2c_master) {
+               i2c_dev = (struct altera_i2c_dev *)fme->i2c_master;
+               if (hw && hw->adapter && hw->adapter->shm.ptr) {
+                       dev_info(NULL, "use multi-process mutex in i2c\n");
+                       sd = (opae_share_data *)hw->adapter->shm.ptr;
+                       i2c_dev->mutex = &sd->i2c_mutex;
+               } else {
+                       dev_info(NULL, "use multi-thread mutex in i2c\n");
+                       i2c_dev->mutex = &i2c_dev->lock;
+               }
+       }
+}
+
 static int fme_i2c_init(struct ifpga_feature *feature)
 {
        struct feature_fme_i2c *i2c;
@@ -1103,6 +1271,8 @@ static int fme_i2c_init(struct ifpga_feature *feature)
        if (!fme->i2c_master)
                return -ENODEV;
 
+       init_i2c_mutex(fme);
+
        /* MAC ROM self test */
        i2c_mac_rom_test(fme->i2c_master);
 
@@ -1291,7 +1461,7 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
        if (!dev)
                return -ENODEV;
 
-       if (max10_sys_read(PKVL_LINK_STATUS, &val)) {
+       if (max10_sys_read(dev, PKVL_LINK_STATUS, &val)) {
                dev_err(dev, "%s: read pkvl status fail\n", __func__);
                return -EINVAL;
        }
@@ -1319,7 +1489,7 @@ int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
        if (!dev)
                return -ENODEV;
 
-       if (max10_sys_read(sensor->value_reg, value)) {
+       if (max10_sys_read(dev, sensor->value_reg, value)) {
                dev_err(dev, "%s: read sensor value register 0x%x fail\n",
                                __func__, sensor->value_reg);
                return -EINVAL;