diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index f875dcfb80be..bb31e82ef61d 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -10,8 +10,9 @@ $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSAIREDIS_DBG) endif $(DOCKER_SYNCD_BRCM_RPC)_FILES += $(DSSERVE) $(BCMCMD) -$(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BRCM) +$(DOCKER_SYNCD_BRCM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) +SONIC_STRETCH_DOCKERS += $(DOCKER_SYNCD_BRCM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM_RPC) endif diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index ab2bed9f5b77..29727dbb2260 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -1,27 +1,18 @@ # docker image for brcm syncd -DOCKER_SYNCD_BRCM = docker-syncd-brcm.gz -$(DOCKER_SYNCD_BRCM)_PATH = $(PLATFORM_PATH)/docker-syncd-brcm -$(DOCKER_SYNCD_BRCM)_DEPENDS += $(SYNCD) -ifeq ($(INSTALL_DEBUG_TOOLS), y) -$(DOCKER_SYNCD_BRCM)_DEPENDS += $(SYNCD_DBG) \ +DOCKER_SYNCD_PLATFORM_CODE = brcm +include $(PLATFORM_PATH)/../template/docker-syncd-base.mk + +$(DOCKER_SYNCD_BASE)_DEPENDS += $(SYNCD) +$(DOCKER_SYNCD_BASE)_FILES += $(DSSERVE) $(BCMCMD) + +$(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSWSSCOMMON_DBG) \ $(LIBSAIMETADATA_DBG) \ $(LIBSAIREDIS_DBG) -endif -$(DOCKER_SYNCD_BRCM)_FILES += $(DSSERVE) $(BCMCMD) -$(DOCKER_SYNCD_BRCM)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) -SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM) -ifneq ($(ENABLE_SYNCD_RPC),y) -SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_BRCM) -endif -$(DOCKER_SYNCD_BRCM)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_BRCM)_RUN_OPT += --net=host --privileged -t -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_SYNCD_BRCM)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd -$(DOCKER_SYNCD_BRCM)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd -$(DOCKER_SYNCD_BRCM)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 78c296d96d92..328f698fdb6d 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index e129409f8960..eaf7afba0a21 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.3.5.4m-1_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.3/libsaibcm_3.3.5.4m-1_amd64.deb?sv=2015-04-05&sr=b&sig=5al8VoedFxE3anjfi4BwLLX2YqU%2BByafkZgEY85TnN8%3D&se=2032-12-17T20%3A59%3A24Z&sp=r" +BRCM_SAI = libsaibcm_3.5.2.1_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5s/libsaibcm_3.5.2.1_amd64.deb?sv=2015-04-05&sr=b&sig=VsOGePXPU9TtxXxQTkLfM%2FIzW6BL8q6RxP6QputuuEU%3D&se=2156-03-28T05%3A37%3A02Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.3.5.4m-1_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.5.2.1_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.3/libsaibcm-dev_3.3.5.4m-1_amd64.deb?sv=2015-04-05&sr=b&sig=ROLknrDMqOGeGfOXu8%2BUVl8yKKDyxsq3swiUtR7n63A%3D&se=2032-12-17T20%3A58%3A59Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5s/libsaibcm-dev_3.5.2.1_amd64.deb?sv=2015-04-05&sr=b&sig=3pWbROLKK5ZuVcAra%2BYo1pk4B0k1P3C76wVw4KiqOtY%3D&se=2156-03-28T05%3A35%3A35Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index bfc05e330e03..9c8956f5e3e0 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -148,6 +148,28 @@ typedef struct ibde_s { */ int (*get_cmic_ver)(int d, uint32 *ver); + /* + * Probe available devices. + * Return value : + * 0: success to probe available devices + * -1: error happens during probe + */ + int (*probe)(void); + + /* + * I2C operations on the Device, assuming it is connected by I2C to the CPU. + */ + /* Read from the internal device Address space using I2C */ + int (*i2c_device_read)( + int dev, /* The device ID to access */ + uint32 addr, /* The address to access in the internal device address space */ + uint32 *value);/* the value to be read. */ + /* Write to the internal device Address space using I2C */ + int (*i2c_device_write)( + int dev, /* The device ID to access */ + uint32 addr, /* The address to access in the internal device address space */ + uint32 value); /* the value to be written. */ + } ibde_t; diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index f66e382e4d8f..76f3e47a8de5 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -46,6 +46,7 @@ #define KCOM_M_HW_INIT 4 /* H/W initialized */ #define KCOM_M_ETH_HW_CONFIG 5 /* ETH HW config*/ #define KCOM_M_DETACH 6 /* Detach kernel module */ +#define KCOM_M_REPROBE 7 /* Reprobe device */ #define KCOM_M_NETIF_CREATE 11 /* Create network interface */ #define KCOM_M_NETIF_DESTROY 12 /* Destroy network interface */ #define KCOM_M_NETIF_LIST 13 /* Get list of network interface IDs */ @@ -59,7 +60,7 @@ #define KCOM_M_DBGPKT_GET 42 /* Get debug packet function info */ #define KCOM_M_WB_CLEANUP 51 /* Clean up for warmbooting */ -#define KCOM_VERSION 9 /* Protocol version */ +#define KCOM_VERSION 10 /* Protocol version */ /* * Message status codes @@ -305,7 +306,7 @@ typedef struct kcom_eth_hw_config_s { uint8 chan; uint32 flags; uint32 value; - } kcom_eth_hw_config_t; +} kcom_eth_hw_config_t; /* * Message types @@ -379,6 +380,14 @@ typedef struct kcom_msg_detach_s { uint32 flags; } kcom_msg_detach_t; +/* + * Reprobe switch device. + */ +typedef struct kcom_msg_reprobe_s { + kcom_msg_hdr_t hdr; + uint32 flags; +} kcom_msg_reprobe_t; + /* * Enable/Disable debugging packet function. */ @@ -498,6 +507,7 @@ typedef union kcom_msg_s { kcom_msg_hw_init_t hw_init; kcom_msg_eth_hw_config_t eth_hw_config; kcom_msg_detach_t detach; + kcom_msg_reprobe_t reprobe; kcom_msg_netif_create_t netif_create; kcom_msg_netif_destroy_t netif_destroy; kcom_msg_netif_list_t netif_list; diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index c1b350f217a5..cb072a78cbd7 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -1238,6 +1238,15 @@ #define BCM56980_DEVICE_ID 0xb980 #define BCM56980_A0_REV_ID 1 +#define BCM56980_B0_REV_ID 0x11 +#define BCM56981_DEVICE_ID 0xb981 +#define BCM56981_A0_REV_ID 1 +#define BCM56982_DEVICE_ID 0xb982 +#define BCM56982_A0_REV_ID 1 +#define BCM56983_DEVICE_ID 0xb983 +#define BCM56983_A0_REV_ID 1 +#define BCM56984_DEVICE_ID 0xb984 +#define BCM56984_A0_REV_ID 1 #define BCM56968_DEVICE_ID 0xb968 #define BCM56968_A0_REV_ID 1 @@ -1289,15 +1298,20 @@ #define BCM56670_DEVICE_ID 0xb670 #define BCM56670_A0_REV_ID 1 +#define BCM56670_B0_REV_ID 0x11 #define BCM56671_DEVICE_ID 0xb671 #define BCM56671_A0_REV_ID 1 +#define BCM56671_B0_REV_ID 0x11 #define BCM56672_DEVICE_ID 0xb672 #define BCM56672_A0_REV_ID 1 +#define BCM56672_B0_REV_ID 0x11 #define BCM56675_DEVICE_ID 0xb675 #define BCM56675_A0_REV_ID 1 +#define BCM56675_B0_REV_ID 0x11 + #define BCM56565_DEVICE_ID 0xb565 #define BCM56565_A0_REV_ID 1 @@ -1317,12 +1331,19 @@ #define BCM56760_DEVICE_ID 0xb760 #define BCM56760_A0_REV_ID 1 +#define BCM56760_A1_REV_ID 2 #define BCM56760_B0_REV_ID 0x11 #define BCM56761_DEVICE_ID 0xb761 #define BCM56761_A0_REV_ID 1 #define BCM56761_B0_REV_ID 0x11 +#define BCM56761_DEVICE_ID 0xb761 +#define BCM56761_A0_REV_ID 1 +#define BCM56761_A1_REV_ID 2 +#define BCM56761_B0_REV_ID 0x11 +#define BCM56761_B1_REV_ID 0x12 + #define BCM56762_DEVICE_ID 0xb762 #define BCM56762_A0_REV_ID 1 #define BCM56762_B0_REV_ID 0x11 @@ -1347,6 +1368,11 @@ #define BCM56068_A0_REV_ID 1 #define BCM56068_B0_REV_ID 0x11 +#define BCM56068_DEVICE_ID 0xb068 +#define BCM56068_A0_REV_ID 1 +#define BCM56068_B0_REV_ID 0x11 +#define BCM56068_B1_REV_ID 0x12 + #define BCM56069_DEVICE_ID 0xb069 #define BCM56069_A0_REV_ID 1 #define BCM56069_B0_REV_ID 0x11 @@ -1400,6 +1426,42 @@ #define BCM56873_DEVICE_ID 0xb873 #define BCM56873_A0_REV_ID 1 +#define BCM56370_DEVICE_ID 0xb370 +#define BCM56370_A0_REV_ID 1 + +#define BCM56371_DEVICE_ID 0xb371 +#define BCM56371_A0_REV_ID 1 + +#define BCM56372_DEVICE_ID 0xb372 +#define BCM56372_A0_REV_ID 1 + +#define BCM56374_DEVICE_ID 0xb374 +#define BCM56374_A0_REV_ID 1 + +#define BCM56375_DEVICE_ID 0xb375 +#define BCM56375_A0_REV_ID 1 + +#define BCM56376_DEVICE_ID 0xb376 +#define BCM56376_A0_REV_ID 1 + +#define BCM56377_DEVICE_ID 0xb377 +#define BCM56377_A0_REV_ID 1 + +#define BCM56577_DEVICE_ID 0xb577 +#define BCM56577_A0_REV_ID 1 + +#define BCM56578_DEVICE_ID 0xb578 +#define BCM56578_A0_REV_ID 1 + +#define BCM56579_DEVICE_ID 0xb579 +#define BCM56579_A0_REV_ID 1 + +#define BCM56770_DEVICE_ID 0xb770 +#define BCM56770_A0_REV_ID 1 + +#define BCM56771_DEVICE_ID 0xb771 +#define BCM56771_A0_REV_ID 1 + #define BCM53540_DEVICE_ID 0x8540 #define BCM53540_A0_REV_ID 1 #define BCM53547_DEVICE_ID 0x8547 @@ -1718,6 +1780,7 @@ #define DNXC_B0_REV_ID 0x0011 #define BCM88790_DEVICE_ID 0x8790 #define BCM88790_A0_REV_ID DNXC_A0_REV_ID +#define BCM88790_B0_REV_ID DNXC_B0_REV_ID #define BCM88791_DEVICE_ID 0x8791 #define BCM88792_DEVICE_ID 0x8792 #define BCM88793_DEVICE_ID 0x8793 diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto index cd5e8fbca195..947c20e74f93 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gto +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gto @@ -86,15 +86,19 @@ endif endif ifdef DPP_CHIPS -CFLAGS += -DDUNE_BCM -D__DUNE_GTO_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ -D__DUNE_LINUX_BCM_CPU_PCP_DMA__ +CFLAGS += -DDUNE_BCM -D__DUNE_LINUX_BCM_CPU_PCP_DMA__ CFGFLAGS += -DSOC_CM_FUNCTION endif ifdef DFE_CHIPS -CFLAGS += -DDUNE_BCM -D__DUNE_GTO_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ +CFLAGS += -DDUNE_BCM CFGFLAGS += -DSOC_CM_FUNCTION endif +ifdef SAND_CHIPS +CFLAGS += -D__DUNE_GTO_BCM_CPU__ -D__DUNE_LINUX_BCM_CPU_PCIE__ +endif + ifdef SHADOW_PLX CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE -DSHADOW_SVK endif diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c index e26d35332cc8..1a04b2b52e9b 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux-kernel-bde.c @@ -94,6 +94,8 @@ LKM_MOD_PARAM(nodevices, "i", int, 0); MODULE_PARM_DESC(nodevices, "Ignore all recognized devices (default no)"); +int msixcnt = 1; + /* * This usually is defined at /usr/include/linux/pci_ids.h * But this ID is newer. @@ -366,6 +368,12 @@ static int robo_switch = 0; #define VALID_DEVICE(_n) ((_n >= 0) && (_n < _ndevices)) +#if defined(IPROC_CMICD) && defined(CONFIG_OF) +#define ICFG_CHIP_ID_REG 0x10236000 +#define IHOST_CMICX_MAX_INTRS 128 +static uint32 iproc_cmicx_irqs[IHOST_CMICX_MAX_INTRS]; +#endif + /* CPU MMIO area used with CPU cards provided on demo boards */ #if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT)) && (defined(__DUNE_WRX_BCM_CPU__) || defined(__DUNE_GTO_BCM_CPU__)) static void *cpu_address = NULL; @@ -696,9 +704,9 @@ iproc_cmicd_get_irqres(ibde_dev_t bde_dev, struct resource *res_irq) #include #include -extern void iproc_platform_driver_register(struct platform_driver *drv); +extern int iproc_platform_driver_register(struct platform_driver *drv); extern void iproc_platform_driver_unregister(struct platform_driver *drv); -extern void iproc_platform_device_register(struct platform_device *drv); +extern int iproc_platform_device_register(struct platform_device *drv); extern void iproc_platform_device_unregister(struct platform_device *drv); extern struct resource * @@ -711,13 +719,14 @@ iproc_platform_get_resource(struct platform_device *dev, unsigned int type, #define IPROC_CMICD_INT 194 #define IPROC_CMICD_COMPATIBLE "brcm,iproc-cmicd" +#define IPROC_CMICX_COMPATIBLE "brcm,iproc-cmicx" static int iproc_cmicd_probe(struct platform_device *pldev) { bde_ctrl_t *ctrl; uint32 size, dev_rev_id; - struct resource *memres, *irqres; + struct resource *memres, *irqres; #ifdef CONFIG_OF if (debug >= 1) { gprintk("iproc_cmicd_probe %s\n", pldev->dev.of_node ? "with device node":""); @@ -725,7 +734,7 @@ iproc_cmicd_probe(struct platform_device *pldev) #endif memres = iproc_platform_get_resource(pldev, IORESOURCE_MEM, 0); if (memres == NULL) { - gprintk("Unable to retrieve iProc CMIC resources"); + gprintk("Unable to retrieve iProc CMIC resources"); return -1; } size = memres->end - memres->start + 1; @@ -739,32 +748,62 @@ iproc_cmicd_probe(struct platform_device *pldev) /* Map CMIC block in the AXI memory space into CPU address space */ ctrl->bde_dev.base_address = (sal_vaddr_t)IOREMAP(memres->start, size); if (!ctrl->bde_dev.base_address) { - gprintk("Error mapping iProc CMIC registers"); + gprintk("Error mapping iProc CMIC registers"); return -1; } ctrl->phys_address = memres->start; - /* Read switch device ID from CMIC */ - dev_rev_id = *((uint32_t*)(ctrl->bde_dev.base_address + 0x10224)); +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + uint32 *icfg_chip_id; + icfg_chip_id = (uint32 *)IOREMAP(ICFG_CHIP_ID_REG, 2 * sizeof(uint32)); + if (icfg_chip_id == NULL) { + gprintk("Error mapping ICFG_CHIP_ID_REG\n"); + return -1; + } + ctrl->bde_dev.device = readl(icfg_chip_id) & 0xffff; + ctrl->bde_dev.rev = readl(icfg_chip_id+1) & 0xff; + iounmap(icfg_chip_id); + } else +#endif + { + /* Read switch device ID from CMIC */ + dev_rev_id = *((uint32 *)(ctrl->bde_dev.base_address + 0x10224)); #if defined(BCM_CMICM_SUPPORT) && defined(BE_HOST) - ctrl->bde_dev.device = ( (((dev_rev_id >> 16) & 0xff) << 8) | - ((dev_rev_id >> 24) & 0xff)); - ctrl->bde_dev.rev = (dev_rev_id >> 8) & 0xff ; + ctrl->bde_dev.device = ( (((dev_rev_id >> 16) & 0xff) << 8) | + ((dev_rev_id >> 24) & 0xff)); + ctrl->bde_dev.rev = (dev_rev_id >> 8) & 0xff ; #else - ctrl->bde_dev.device = dev_rev_id & 0xffff; - ctrl->bde_dev.rev = (dev_rev_id >> 16) & 0xff; + ctrl->bde_dev.device = dev_rev_id & 0xffff; + ctrl->bde_dev.rev = (dev_rev_id >> 16) & 0xff; #endif + } #ifdef CONFIG_OF if (!pldev->dev.of_node) #endif { /* Assign locally if not available from device node */ - iproc_cmicd_get_irqres(ctrl->bde_dev, &pldev->resource[0]); + iproc_cmicd_get_irqres(ctrl->bde_dev, &pldev->resource[0]); } - irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, 0); - ctrl->iLine = irqres->start; +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + int i; + for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, i); + iproc_cmicx_irqs[i] = irqres->start; + if (debug >= 1) { + gprintk("iproc_cmicx_irqs[%d] = %d\n", i, iproc_cmicx_irqs[i]); + } + } + ctrl->iLine = iproc_cmicx_irqs[0]; + } else +#endif + { + irqres = iproc_platform_get_resource(pldev, IORESOURCE_IRQ, 0); + ctrl->iLine = irqres->start; + } ctrl->isr = NULL; ctrl ->isr_data = NULL; @@ -785,14 +824,15 @@ iproc_cmicd_remove(struct platform_device *pldev) } #ifdef CONFIG_OF static const struct of_device_id iproc_cmicd_of_match[] = { - { .compatible = "brcm,iproc-cmicd" }, + { .compatible = IPROC_CMICD_COMPATIBLE }, + { .compatible = IPROC_CMICX_COMPATIBLE }, {}, }; MODULE_DEVICE_TABLE(of, iproc_cmicd_of_match); #endif static char iproc_cmicd_string[] = "bcmiproc-cmicd"; -static struct platform_driver iproc_cmicd_driver = +static struct platform_driver iproc_cmicd_driver = { .probe = iproc_cmicd_probe, .remove = iproc_cmicd_remove, @@ -995,10 +1035,10 @@ iproc_cmicd_get_memregion(struct resource *res_mem) iounmap(erom_base); if (debug >= 1) { - gprintk("CMICD info by %s: cmicd_mem.start=%x, cmicd_mem.end=%x\n", + gprintk("CMICD info by %s: cmicd_mem.start=%lx, cmicd_mem.end=%lx\n", found_cmicd_dev ? "EROM" : "Default", - iproc_cmicd_resources[IPROC_CMICD_RES_MEM].start, - iproc_cmicd_resources[IPROC_CMICD_RES_MEM].end); + (unsigned long)iproc_cmicd_resources[IPROC_CMICD_RES_MEM].start, + (unsigned long)iproc_cmicd_resources[IPROC_CMICD_RES_MEM].end); } } #endif /* IPROC_CMICD */ @@ -1382,6 +1422,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56672_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56675_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56568_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56670_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56760_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56761_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56762_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1546,8 +1587,24 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56832_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56836_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56870_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM56980_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56370_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56371_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56372_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56374_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56375_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56376_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56377_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56577_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56578_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56579_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56873_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56770_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56771_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56980_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56981_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56982_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56983_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56984_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53540_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53547_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM53548_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1981,6 +2038,7 @@ _pci_msix_table_size(struct pci_dev *dev) if (nr_entries < 0) { nr_entries = 0; } + pci_disable_msix(dev); kfree(entries); } } @@ -1996,45 +2054,56 @@ _pci_msix_table_size(struct pci_dev *dev) static int _msi_connect(bde_ctrl_t *ctrl) { - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) int ret; if (ctrl->use_msi == PCI_USE_INT_MSIX) { int i; - ret = _pci_msix_table_size(ctrl->pci_device); + ret = _pci_msix_table_size(ctrl->pci_device); if (ret == 0) { /* MSI-X failed */ gprintk("MSI-X not supported.\n"); goto er_intx; } - ctrl->entries = kcalloc(ret, sizeof(struct msix_entry)*ret, GFP_KERNEL); + ctrl->entries = kcalloc(ret, sizeof(struct msix_entry), GFP_KERNEL); if (!ctrl->entries) { goto er_intx; } - /* We need only that much interrupt vecotrs */ - ctrl->msix_cnt = ret/4; + /* Only one vector is mapped by default */ + /* May be more in future, can be controlled using module param */ + ctrl->msix_cnt = msixcnt; if (unlikely(debug > 1)) gprintk("MSIX Table size = %d\n", ctrl->msix_cnt); for (i = 0; i < ctrl->msix_cnt; i++) ctrl->entries[i].entry = i; - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) + ret = pci_enable_msix_range(ctrl->pci_device, + ctrl->entries, ctrl->msix_cnt, ctrl->msix_cnt); +#else ret = pci_enable_msix(ctrl->pci_device, ctrl->entries, ctrl->msix_cnt); +#endif if (ret > 0) { /* Not enough vectors available , Retry MSI-X */ gprintk("Retrying with MSI-X interrupts = %d\n", ret); ctrl->msix_cnt = ret; + msixcnt = ret; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) + ret = pci_enable_msix_range(ctrl->pci_device, + ctrl->entries, ctrl->msix_cnt, ctrl->msix_cnt); +#else ret = pci_enable_msix(ctrl->pci_device, ctrl->entries, ctrl->msix_cnt); +#endif if (ret != 0) goto er_intx_free; } else if (ret < 0) { /* Error */ goto er_intx_free; } else { - gprintk("Enabled MSI-X interrupts = %d\n", ctrl->msix_cnt); + gprintk("Enabled MSI-X interrupts = %d\n", ctrl->msix_cnt); + return 0; } } #endif @@ -2049,7 +2118,7 @@ _msi_connect(bde_ctrl_t *ctrl) } } else { /* failed */ - gprintk("Not MSI/MSIC interrupt.\n"); + gprintk("Not MSI/MSIX interrupt.\n"); goto er_intx; } return 0; @@ -2068,9 +2137,12 @@ _msi_disconnect(bde_ctrl_t *ctrl) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi == PCI_USE_INT_MSIX) { - pci_disable_msix(ctrl->pci_device); - kfree(ctrl->entries); - ctrl->msix_cnt = 0; + if (ctrl->msix_cnt) { + pci_disable_msix(ctrl->pci_device); + kfree(ctrl->entries); + ctrl->entries = NULL; + ctrl->msix_cnt = 0; + } } #endif if (ctrl->use_msi == PCI_USE_INT_MSI) { @@ -2085,16 +2157,30 @@ _msi_disconnect(bde_ctrl_t *ctrl) static void -config_pci_intr_type(bde_ctrl_t *ctrl) +config_pci_intr_type(struct pci_dev *dev, bde_ctrl_t *ctrl, int iproc) { - #ifdef CONFIG_PCI_MSI int ret; + shbde_iproc_config_t icfg; + /* Each device follows global policy by default */ ctrl->use_msi = use_msi; + if (unlikely(debug > 1)) gprintk("%s: msi = %d\n", __func__, ctrl->use_msi); + /* Check IPROC version for MSIX support */ + if (iproc && ctrl->bde_dev.base_address1 && + (ctrl->use_msi == PCI_USE_INT_MSIX)) { + if (shbde_pci_iproc_version_get(&ctrl->shbde, dev, &icfg.iproc_ver, + &icfg.cmic_ver, &icfg.cmic_rev)) { + if (icfg.iproc_ver < 0xe) { + gprintk("%s: MSI-X not supported, using MSI.\n", __func__); + ctrl->use_msi = PCI_USE_INT_MSI; + } + } + } + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi == PCI_USE_INT_MSIX) { /* check for support MSIX vector */ @@ -2108,10 +2194,10 @@ config_pci_intr_type(bde_ctrl_t *ctrl) if (ctrl->use_msi == PCI_USE_INT_MSI) { /* check for support MSI vector */ - ret = pci_enable_msi(ctrl->pci_device); + ret = pci_enable_msi(ctrl->pci_device); if (ret < 0) { ctrl->use_msi = PCI_USE_INT_INTX; - gprintk("%s: Failed to enable MSI\n", __func__); + gprintk("%s: Failed to enable MSI, using INTx.\n", __func__); } else { pci_disable_msi(ctrl->pci_device); } @@ -2268,7 +2354,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) return 0; } if (_switch_ndevices >= LINUX_BDE_MAX_SWITCH_DEVICES) { - return 0;; + return 0; } if (rescan) { @@ -2550,22 +2636,8 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) } } - /* Each device follows global policy by default */ - ctrl->use_msi = use_msi; - - /* Check is MSI is properly supported in kernel for this device */ - if (ctrl->use_msi) { - if (pci_enable_msi(ctrl->pci_device) == 0) { - /* Release MSI resources until interrupt_connect is called */ - pci_disable_msi(ctrl->pci_device); - } else { - gprintk("Could not enable MSI interrupts\n"); - ctrl->use_msi = 0; - } - } - /* configure interrupt type */ - config_pci_intr_type(ctrl); + config_pci_intr_type(dev, ctrl, iproc); /* Configure iProc PCI-AXI bridge */ if (iproc && ctrl->bde_dev.base_address1) { @@ -2580,7 +2652,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) &icfg->cmic_ver, &icfg->cmic_rev); shbde_iproc_config_init(icfg, ctrl->bde_dev.device, ctrl->bde_dev.rev); - if (debug >=2) { + if (debug >= 2) { gprintk("iproc version = %x dma_hi_bits = %x\n", icfg->iproc_ver, icfg->dma_hi_bits); } icfg->use_msi = ctrl->use_msi; @@ -2734,22 +2806,22 @@ _pci_remove(struct pci_dev* dev) if (ctrl->use_msi >= PCI_USE_INT_MSIX) { int i; for (i = 0; i < ctrl->msix_cnt; i++) - free_irq(ctrl->entries[i].vector, ctrl->pci_device); + free_irq(ctrl->entries[i].vector, ctrl); } else #endif { - free_irq(ctrl->iLine, ctrl); + free_irq(ctrl->iLine, ctrl); } } #ifdef CONFIG_PCI_MSI _msi_disconnect(ctrl); #endif - ctrl->isr = NULL; - ctrl->isr_data = NULL; - ctrl->isr2 = NULL; - ctrl->isr2_data = NULL; - } + ctrl->isr = NULL; + ctrl->isr_data = NULL; + ctrl->isr2 = NULL; + ctrl->isr2_data = NULL; +} static struct pci_driver _device_driver = { probe: _pci_probe, @@ -3641,8 +3713,12 @@ _gmac_dev_create(void) static int _init(void) { - #ifdef IPROC_CMICD +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + iproc_platform_driver_register(&iproc_cmicd_driver); + } else +#endif if (iproc_has_cmicd()) { iproc_cmicd_get_memregion(&iproc_cmicd_resources[IPROC_CMICD_RES_MEM]); iproc_platform_driver_register(&iproc_cmicd_driver); @@ -3651,8 +3727,8 @@ _init(void) #endif { /* Register platform device if no device node in dtb */ - iproc_platform_device_register(&iproc_cmicd_pdev); - } + iproc_platform_device_register(&iproc_cmicd_pdev); + } } #endif /* IPROC_CMICD */ @@ -3662,7 +3738,7 @@ _init(void) /* Register our goodies */ _device_driver.name = LINUX_KERNEL_BDE_NAME; -#if defined(BCM_ROBO_SUPPORT) +#if defined(BCM_ROBO_SUPPORT) #if defined(IPROC_CMICD) if (_gmac_dev_create()) { return -ENODEV; @@ -3771,6 +3847,11 @@ _cleanup(void) _dma_cleanup(); #ifdef IPROC_CMICD +#ifdef CONFIG_OF + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + iproc_platform_driver_unregister(&iproc_cmicd_driver); + } else +#endif if (iproc_has_cmicd()) { #ifdef CONFIG_OF if (!of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE)) @@ -4251,14 +4332,18 @@ _interrupt_connect(int d, if (ctrl->use_msi == PCI_USE_INT_MSIX) { int i; for (i = 0; i < ctrl->msix_cnt; i++) { - ret = request_irq(ctrl->entries[i].vector, _isr, - irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); + if (unlikely(debug >= 1)) { + gprintk("%s(%d):device# = %d, irq = %d\n", + __func__, __LINE__, d, ctrl->entries[i].vector); + } + ret = request_irq(ctrl->entries[i].vector, _isr, 0, + LINUX_KERNEL_BDE_NAME, ctrl); if (ret < 0) break; } if (ret < 0) { while (i >= 0) - free_irq(ctrl->entries[i--].vector, ctrl->pci_device); + free_irq(ctrl->entries[i--].vector, ctrl); goto err_disable_msi; } @@ -4266,15 +4351,39 @@ _interrupt_connect(int d, else #endif { - ret = request_irq(ctrl->iLine, _isr, irq_flags, +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + int i, j; + for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (unlikely(debug >= 1)) + gprintk("%s(%d):device# = %d, request_irq(%d)\n", + __func__, __LINE__, d, iproc_cmicx_irqs[i]); + ret = request_irq(iproc_cmicx_irqs[i], _isr, + irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); + if (ret < 0) { + gprintk("request_irq(%d) failed(%d)\n", iproc_cmicx_irqs[i], ret); + break; + } + } + if (ret < 0) { + for (j = 0; j < i; j++) { + free_irq(iproc_cmicx_irqs[j], ctrl); + } + goto err_disable_msi; + } + } else +#endif + { + ret = request_irq(ctrl->iLine, _isr, irq_flags, LINUX_KERNEL_BDE_NAME, ctrl); - if (ret < 0) - goto err_disable_msi; + if (ret < 0) + goto err_disable_msi; - if (unlikely(debug >= 1)) - gprintk("%s(%d):device# = %d, irq_flags = %lu, irq = %d\n", + if (unlikely(debug >= 1)) + gprintk("%s(%d):device# = %d, irq_flags = %lu, irq = %d\n", __func__, __LINE__, d, irq_flags, ctrl->pci_device ? ctrl->pci_device->irq : ctrl->iLine); + } } } return 0; @@ -4292,7 +4401,7 @@ _interrupt_connect(int d, ctrl->isr2_data = NULL; return -1; - } +} static int _interrupt_disconnect(int d) @@ -4353,13 +4462,30 @@ _interrupt_disconnect(int d) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi >= PCI_USE_INT_MSIX) { int i; - for (i = 0; i < ctrl->msix_cnt; i++) - free_irq(ctrl->entries[i].vector, ctrl->pci_device); + for (i = 0; i < ctrl->msix_cnt; i++) { + if (unlikely(debug > 1)) { + gprintk("%s(%d):device# = %d, irq = %d\n", + __func__, __LINE__, d, ctrl->entries[i].vector); + } + free_irq(ctrl->entries[i].vector, ctrl); + } } else +#endif +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { + int i; + for (i = 0; i < IHOST_CMICX_MAX_INTRS; i++) { + if (unlikely(debug > 1)) { + gprintk("%s(%d):device# = %d, free_irq(%d)\n", + __func__, __LINE__, d, iproc_cmicx_irqs[i]); + } + free_irq(iproc_cmicx_irqs[i], ctrl); + } + } else #endif { - free_irq(ctrl->iLine, ctrl); + free_irq(ctrl->iLine, ctrl); } #ifdef CONFIG_PCI_MSI if (ctrl->use_msi >= PCI_USE_INT_MSI) { diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c index 7fc9fd166bbd..6c7c9bb95056 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.c @@ -30,6 +30,9 @@ #include "linux-user-bde.h" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) +#include +#endif #ifdef KEYSTONE #include #endif @@ -75,21 +78,56 @@ MODULE_LICENSE("GPL"); /* CMICX defines */ #define INTC_INTR_REG_NUM (8) -#define INTC_INTR_ENABLE_REG0 (0x180130f0) -#define INTC_INTR_STATUS_REG0 (0x18013190) -#define INTC_INTR_RAW_STATUS_REG0 (0x18013140) +/* +TODO:HX5 +The INTR base address values are changed for HX5, +hence making new #defines so runtime decisions can +be made. +*/ + +#define INTC_INTR_ENABLE_REG0 (0x180130f0) +#define INTC_INTR_STATUS_REG0 (0x18013190) +#define INTC_INTR_RAW_STATUS_REG0 (0x18013140) #define INTC_INTR_ENABLE_BASE (INTC_INTR_ENABLE_REG0) #define INTC_INTR_STATUS_BASE (INTC_INTR_STATUS_REG0) #define INTC_INTR_RAW_STATUS_BASE (INTC_INTR_RAW_STATUS_REG0) -#define INTC_PDMA_INTR_REG_IND 4 +#define HX5_INTC_INTR_ENABLE_REG0 (0x102310f0) +#define HX5_INTC_INTR_STATUS_REG0 (0x10231190) +#define HX5_INTC_INTR_RAW_STATUS_REG0 (0x10231140) + +#define HX5_INTC_INTR_ENABLE_BASE (HX5_INTC_INTR_ENABLE_REG0) +#define HX5_INTC_INTR_STATUS_BASE (HX5_INTC_INTR_STATUS_REG0) +#define HX5_INTC_INTR_RAW_STATUS_BASE (HX5_INTC_INTR_RAW_STATUS_REG0) + +#define IOREMAP(addr, size) ioremap_nocache(addr, size) + +#define HX5_IHOST_GICD_ISENABLERN_0 (0x10781100) +#define HX5_IHOST_GICD_ISENABLERN_1 (0x10781104) +#define HX5_IHOST_GICD_ICENABLERN_1 (0x10781184) +#define HX5_IHOST_GICD_ICENABLERN_8 (0x107811a0) +/* Offset between ISENABLERN_1 and ICENABLERN_1 in 4-bytes */ +#define HX5_IHOST_IRQ_MASK_OFFSET 0x20 +#define HX5_IHOST_INTR_MAP_NUM (HX5_IHOST_GICD_ICENABLERN_8 - HX5_IHOST_GICD_ISENABLERN_0) +#define HX5_IHOST_INTR_STATUS_MAP_NUM (INTC_INTR_REG_NUM * (sizeof(uint32))) +#define IRQ_BIT(intr) (intr % (sizeof(uint32)*8)) +#define IRQ_MASK_INDEX(intr) (intr / (sizeof(uint32)*8)) +#define HX5_CHIP_INTR_LOW_PRIORITY 119 +#define INTR_LOW_PRIORITY_BITPOS (1 << IRQ_BIT(HX5_CHIP_INTR_LOW_PRIORITY)) +#define INTC_LOW_PRIORITY_INTR_REG_IND IRQ_MASK_INDEX(HX5_CHIP_INTR_LOW_PRIORITY) +#define INTC_PDMA_INTR_REG_IND 4 #define READ_INTC_INTR(d, reg, v) \ - (v = user_bde->iproc_read(d, reg)) + (v = user_bde->iproc_read(d, reg)) #define WRITE_INTC_INTR(d, reg, v) \ (user_bde->iproc_write(d, reg, v)) +#define IHOST_READ_INTR(d, reg, v) \ + (v = readl((reg))) +#define IHOST_WRITE_INTR(d, reg, v) \ + (writel((v), (reg))) + /* Allow override of default CMICm CMC */ #ifndef BDE_CMICM_PCIE_CMC #define BDE_CMICM_PCIE_CMC 0 @@ -103,6 +141,9 @@ MODULE_LICENSE("GPL"); /* Defines used to distinguish CMICe from CMICm */ #define CMICE_DEV_REV_ID (0x178 / sizeof(uint32)) +static uint32 *ihost_intr_status_base = NULL; +static uint32 *ihost_intr_enable_base = NULL; + static ibde_t *user_bde = NULL; typedef void (*isr_f)(void *); @@ -225,27 +266,68 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) int d, ind; uint32 stat, iena, mask, fmask; bde_inst_resource_t *res; + uint32 intc_intr_status_base = 0, intc_intr_enable_base = 0; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); res = &_bde_inst_resource[ctrl->inst]; lkbde_irq_mask_get(d, &mask, &fmask); + if ((ctrl->dev_type & BDE_SWITCH_DEV_TYPE) && + ((user_bde->get_dev(d)->device == BCM56370_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56371_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56372_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56374_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56375_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56376_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56377_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56577_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56578_DEVICE_ID) || + (user_bde->get_dev(d)->device == BCM56579_DEVICE_ID))) { + intc_intr_status_base = HX5_INTC_INTR_STATUS_BASE; + intc_intr_enable_base = HX5_INTC_INTR_ENABLE_BASE; + } else { + intc_intr_status_base = INTC_INTR_STATUS_BASE; + intc_intr_enable_base = INTC_INTR_ENABLE_BASE; + } if (fmask) { - READ_INTC_INTR(d, INTC_INTR_STATUS_BASE + 4 * INTC_PDMA_INTR_REG_IND, stat); - READ_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * INTC_PDMA_INTR_REG_IND, iena); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + IHOST_READ_INTR(d, ihost_intr_status_base + INTC_PDMA_INTR_REG_IND, stat); + IHOST_READ_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND, iena); + } else { + READ_INTC_INTR(d, intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); + READ_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); + } if (stat & iena) { - WRITE_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * INTC_PDMA_INTR_REG_IND, 0); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_PDMA_INTR_REG_IND + + HX5_IHOST_IRQ_MASK_OFFSET, ~0); + } else { + WRITE_INTC_INTR(d, intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, 0); + } + for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { if (ind == INTC_PDMA_INTR_REG_IND) { continue; } - READ_INTC_INTR(d, INTC_INTR_STATUS_BASE + 4 * ind, stat); - READ_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * ind, iena); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + continue; + } + IHOST_READ_INTR(d, ihost_intr_status_base + ind, stat); + IHOST_READ_INTR(d, ihost_intr_enable_base + ind, iena); + if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + stat &= INTR_LOW_PRIORITY_BITPOS; + } + } else { + READ_INTC_INTR(d, intc_intr_status_base + 4 * ind, stat); + READ_INTC_INTR(d, intc_intr_enable_base + 4 * ind, iena); + } if (stat & iena) { break; } } + if (ind >= INTC_INTR_REG_NUM) { return; } @@ -260,7 +342,20 @@ _cmicx_interrupt(bde_ctrl_t *ctrl) if (fmask && ind == INTC_PDMA_INTR_REG_IND) { continue; } - WRITE_INTC_INTR(d, INTC_INTR_ENABLE_BASE + 4 * ind, 0); + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + if (ind < INTC_LOW_PRIORITY_INTR_REG_IND) { + continue; + } + if (ind == INTC_LOW_PRIORITY_INTR_REG_IND) { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + INTC_LOW_PRIORITY_INTR_REG_IND + + HX5_IHOST_IRQ_MASK_OFFSET, INTR_LOW_PRIORITY_BITPOS); + } else { + IHOST_WRITE_INTR(d, ihost_intr_enable_base + ind + + HX5_IHOST_IRQ_MASK_OFFSET, ~0); + } + } else { + WRITE_INTC_INTR(d, intc_intr_enable_base + 4*ind, 0); + } } /* Notify */ @@ -750,6 +845,12 @@ _devices_init(int d) uint32 ver; uint16 device_id_mask = 0xFFF0; uint16 device_id; + int state = 0; + + (void)lkbde_dev_state_get(d, &state); + if (state == BDE_DEV_STATE_REMOVED) { + return; + } ctrl = &_devices[d]; /* Initialize our control info */ @@ -849,6 +950,31 @@ _devices_init(int d) case BCM88952_DEVICE_ID: ctrl->isr = (isr_f)_cmicd_cmc0_interrupt; break; + case BCM88790_DEVICE_ID: + ctrl->isr = (isr_f)_cmicx_interrupt; + break; + case BCM56370_DEVICE_ID: + case BCM56371_DEVICE_ID: + case BCM56372_DEVICE_ID: + case BCM56374_DEVICE_ID: + case BCM56375_DEVICE_ID: + case BCM56376_DEVICE_ID: + case BCM56377_DEVICE_ID: + case BCM56577_DEVICE_ID: + case BCM56578_DEVICE_ID: + case BCM56579_DEVICE_ID: + ctrl->isr = (isr_f)_cmicx_interrupt; + if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { + if (!ihost_intr_enable_base) { + ihost_intr_enable_base = (uint32_t *)IOREMAP(HX5_IHOST_GICD_ISENABLERN_1, + HX5_IHOST_INTR_MAP_NUM); + } + if (!ihost_intr_status_base) { + ihost_intr_status_base = (uint32_t *)IOREMAP(HX5_INTC_INTR_RAW_STATUS_REG0, + HX5_IHOST_INTR_STATUS_MAP_NUM); + } + } + break; default: /* Get CMIC version */ if (user_bde->get_cmic_ver(d, &ver) != 0) { @@ -876,7 +1002,7 @@ _devices_init(int d) } break; } - /*All Ramon devices from 0x8790 to 0x879F*/ + /* All Ramon devices from 0x8790 to 0x879F */ if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) { ctrl->isr = (isr_f)_cmicx_interrupt; } @@ -928,10 +1054,14 @@ _init(void) init_waitqueue_head(&res->intr_wq); atomic_set(&res->intr, 0); + ihost_intr_enable_base = NULL; + ihost_intr_status_base = NULL; + for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { res->inst_id |= (1 << i); _devices_init(i); } + return 0; } @@ -961,6 +1091,16 @@ _cleanup(void) linux_bde_destroy(user_bde); user_bde = NULL; } + + if (ihost_intr_enable_base) { + iounmap(ihost_intr_enable_base); + ihost_intr_enable_base = NULL; + } + if (ihost_intr_status_base) { + iounmap(ihost_intr_status_base); + ihost_intr_status_base = NULL; + } + return 0; } @@ -1088,6 +1228,7 @@ static int _device_reprobe(void) { int i; + for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { if (_devices[i].devid == 0) { _devices_init(i); @@ -1167,7 +1308,8 @@ _ioctl(unsigned int cmd, unsigned long arg) ssize_t size; const ibde_dev_t *bde_dev; int inst_id; - bde_inst_resource_t *res; + bde_inst_resource_t *res; + uint32_t *mapaddr; if (copy_from_user(&io, (void *)arg, sizeof(io))) { return -EFAULT; @@ -1396,9 +1538,22 @@ _ioctl(unsigned int cmd, unsigned long arg) } break; case LUBDE_IPROC_READ_REG: - io.d1 = user_bde->iproc_read(io.dev, io.d0); - if (io.d1 == -1) { - io.rc = LUBDE_FAIL; + if (!VALID_DEVICE(io.dev)) { + return -EINVAL; + } + if (_devices[io.dev].dev_type & BDE_AXI_DEV_TYPE) { + mapaddr = IOREMAP(io.d0, sizeof(uint32_t)); + if (mapaddr == NULL) { + io.rc = LUBDE_FAIL; + return -1; + } + io.d1 = readl(mapaddr); + iounmap(mapaddr); + } else { + io.d1 = user_bde->iproc_read(io.dev, io.d0); + if (io.d1 == -1) { + io.rc = LUBDE_FAIL; + } } break; case LUBDE_IPROC_WRITE_REG: @@ -1412,6 +1567,9 @@ _ioctl(unsigned int cmd, unsigned long arg) case LUBDE_GET_DEVICE_STATE: io.rc = lkbde_dev_state_get(io.dev, &io.d0); break; + case LUBDE_REPROBE: + io.rc = _device_reprobe(); + break; default: gprintk("Error: Invalid ioctl (%08x)\n", cmd); io.rc = LUBDE_FAIL; diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h index 621973b7a7f5..535ccac9fad9 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/user/kernel/linux-user-bde.h @@ -81,6 +81,7 @@ typedef struct { #define LUBDE_IPROC_WRITE_REG _IO(LUBDE_MAGIC, 28) #define LUBDE_ATTACH_INSTANCE _IO(LUBDE_MAGIC, 29) #define LUBDE_GET_DEVICE_STATE _IO(LUBDE_MAGIC, 30) +#define LUBDE_REPROBE _IO(LUBDE_MAGIC, 31) #define LUBDE_SEM_OP_CREATE 1 #define LUBDE_SEM_OP_DESTROY 2 @@ -93,9 +94,10 @@ typedef struct { /* * Version history - * 1:add LUBDE_GET_DEVICE_STATE to support PCI hot plug + * 1: add LUBDE_GET_DEVICE_STATE to support PCI hot plug + * 2: add LUBDE_REPROBE to support reprobe available devices */ -#define KBDE_VERSION 1 +#define KBDE_VERSION 2 /* This is the signal that will be used diff --git a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c index d1e95725c5f7..e1bdcc4db0da 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c +++ b/platform/broadcom/saibcm-modules/systems/bde/shared/shbde_iproc.c @@ -40,6 +40,8 @@ #define BAR0_PAXB_OARR_2_UPPER 0x2d64 #define BAR0_DMU_PCU_PCIE_SLAVE_RESET_MODE 0x7024 +#define PAXB_0_FUNC0_IMAP1_3 0x2d88 + /* Force byte pointer for offset adjustments */ #define ROFFS(_ptr, _offset) ((unsigned char*)(_ptr) + (_offset)) @@ -47,6 +49,7 @@ #define PAXB_CONFIG_IND_ADDRr_PROTOCOL_LAYERf_MASK 0x3 #define PAXB_CONFIG_IND_ADDRr_ADDRESSf_SHFT 0 #define PAXB_CONFIG_IND_ADDRr_ADDRESSf_MASK 0x7ff +#define PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT 20 /* Register value set/get by field */ #define REG_FIELD_SET(_r, _f, _r_val, _f_val) \ @@ -273,17 +276,25 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs, reg = ROFFS(iproc_regs, BAR0_PAXB_PCIE_EP_AXI_CONFIG); iproc32_write(shbde, reg, 0x0); if(icfg->cmic_ver < 4) { /* Non-CMICX */ - reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2); - iproc32_write(shbde, reg, 0x1); - reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2_UPPER); - iproc32_write(shbde, reg, icfg->dma_hi_bits); - - /* Configure MSI interrupt page */ - if (icfg->use_msi) { - reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_FUNC0_MSI_PAGE); - data = iproc32_read(shbde, reg); - iproc32_write(shbde, reg, data | 0x1); + reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2); + iproc32_write(shbde, reg, 0x1); + reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_2_UPPER); + iproc32_write(shbde, reg, icfg->dma_hi_bits); + /* Configure MSI interrupt page */ + if (icfg->use_msi) { + reg = ROFFS(iproc_regs, BAR0_PAXB_OARR_FUNC0_MSI_PAGE); + data = iproc32_read(shbde, reg); + iproc32_write(shbde, reg, data | 0x1); + } } + /* Configure MSIX interrupt page, only need for iproc ver == 0x10 */ + if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) { + unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1; + reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3); + data = iproc32_read(shbde, reg); + data &= mask; + data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT; + iproc32_write(shbde, reg, data); } return pci_num; } @@ -315,7 +326,8 @@ shbde_iproc_pci_read(shbde_hal_t *shbde, void *iproc_regs, /* Sub-window size is 0x1000 (4K) */ subwin_base = (addr & ~0xfff); - if((icfg->cmic_ver >= 4) && (subwin_base == 0x18013000)) { + if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { @@ -361,7 +373,8 @@ shbde_iproc_pci_write(shbde_hal_t *shbde, void *iproc_regs, /* Sub-window size is 0x1000 (4K) */ subwin_base = (addr & ~0xfff); - if((icfg->cmic_ver >= 4) && (subwin_base == 0x18013000)) { + if((icfg->cmic_ver >= 4) && + ((subwin_base == 0x10231000) || (subwin_base == 0x18013000))) { /* Route the INTC block access through IMAP0_6 */ reg = ROFFS(iproc_regs, 0x6000 + (addr & 0xfff)); } else { diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c index 801f5d3e406c..6767090ec7bb 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/bcm-knet/bcm-knet.c @@ -301,6 +301,13 @@ static int use_proxy = 0; #endif /* Compatibility */ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)) +#define NETDEV_UPDATE_TRANS_START_TIME(dev) dev->trans_start = jiffies +#else +#define NETDEV_UPDATE_TRANS_START_TIME(dev) netif_trans_update(dev) +#endif + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) #define skb_copy_to_linear_data(_skb, _pkt, _len) \ eth_copy_and_sum(_skb, _pkt, _len, 0) @@ -505,6 +512,7 @@ typedef struct bkn_switch_info_s { uint32_t rcpu_sig; /* RCPU signature */ uint64_t halt_addr[NUM_DMA_CHAN]; /* DMA halt address */ uint32_t cdma_channels; /* Active channels for Continuous DMA mode */ + uint32_t poll_channels; /* Channels for polling */ uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ @@ -536,7 +544,6 @@ typedef struct bkn_switch_info_s { int dirty; /* Index of next Rx DCB to complete */ int running; /* Rx DMA is active */ int api_active; /* BCM Rx API is active */ - int api_wait; /* Wait BCM Rx API resources */ int chain_complete; /* All DCBs in chain processed */ int sync_err; /* Chain done with incomplete DCBs (debug) */ int sync_retry; /* Total retry times for sync error (debug) */ @@ -684,7 +691,7 @@ typedef struct bkn_pkt_dnx_s { #endif /* defined(CMIC_SOFT_BYTE_SWAP) */ -#define MEMORY_BARRIER mb() +#define MEMORY_BARRIER smp_mb() /* Default random MAC address has Broadcom OUI with local admin bit set */ static u8 bkn_dev_mac[6] = { 0x02, 0x10, 0x18, 0x00, 0x00, 0x00 }; @@ -1753,7 +1760,6 @@ bkn_clean_rx_dcbs(bkn_switch_info_t *sinfo, int chan) } sinfo->rx[chan].running = 0; sinfo->rx[chan].api_active = 0; - sinfo->rx[chan].api_wait = 0; DBG_DCB_RX(("Cleaned Rx%d DCBs (%d %d).\n", chan, sinfo->rx[chan].cur, sinfo->rx[chan].dirty)); } @@ -1959,7 +1965,7 @@ bkn_api_rx_restart(bkn_switch_info_t *sinfo, int chan) sinfo->rx[chan].chain_complete = 0; start_dma = 1; if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && - sinfo->rx[chan].api_wait) { + sinfo->rx[chan].api_active) { /* HW is running already, so we just move to the next chain */ start_dma = 0; } @@ -1972,7 +1978,6 @@ bkn_api_rx_restart(bkn_switch_info_t *sinfo, int chan) dev_dma_chan_clear(sinfo, XGS_DMA_RX_CHAN + chan); dev_irq_mask_enable(sinfo, XGS_DMA_RX_CHAN + chan, 1); dev_dma_chan_start(sinfo, XGS_DMA_RX_CHAN + chan, dcb_chain->dcb_dma); - sinfo->rx[chan].api_wait = 1; } list_del(&dcb_chain->list); @@ -1992,10 +1997,6 @@ bkn_api_rx_chain_done(bkn_switch_info_t *sinfo, int chan) sinfo->rx[chan].api_dcb_chain = NULL; } bkn_api_rx_restart(sinfo, chan); - if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan) && - sinfo->rx[chan].api_dcb_chain == NULL) { - sinfo->rx[chan].api_active = 0; - } } static int @@ -2053,6 +2054,7 @@ bkn_api_rx_copy_from_skb(bkn_switch_info_t *sinfo, } } dcb[sinfo->dcb_wsize-1] = dcb_stat | SOC_DCB_KNET_DONE; + MEMORY_BARRIER; dcb_chain->dcb_cur++; @@ -2062,6 +2064,7 @@ bkn_api_rx_copy_from_skb(bkn_switch_info_t *sinfo, (sinfo->cmic_type != 'x' && dcb[1] & (1 << 18))) { /* Get the next chain if reload done */ dcb[sinfo->dcb_wsize-1] |= 1 << 31 | SOC_DCB_KNET_DONE; + MEMORY_BARRIER; bkn_api_rx_chain_done(sinfo, chan); dcb_chain = sinfo->rx[chan].api_dcb_chain; if (dcb_chain == NULL) { @@ -2090,7 +2093,7 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) struct sk_buff *skb; bkn_desc_info_t *desc; uint32_t *dcb; - uint32_t encap_size = sinfo->cmic_type == 'x' ? RCPU_HDR_SIZE : RCPU_RX_ENCAP_SIZE; + uint32_t resv_size = sinfo->cmic_type == 'x' ? RCPU_HDR_SIZE : RCPU_RX_ENCAP_SIZE; int prev; if (sinfo->rx[chan].use_rx_skb == 0) { @@ -2107,11 +2110,11 @@ bkn_rx_refill(bkn_switch_info_t *sinfo, int chan) while (sinfo->rx[chan].free < MAX_RX_DCBS) { desc = &sinfo->rx[chan].desc[sinfo->rx[chan].cur]; if (desc->skb == NULL) { - skb = dev_alloc_skb(rx_buffer_size + encap_size); + skb = dev_alloc_skb(rx_buffer_size + RCPU_RX_ENCAP_SIZE); if (skb == NULL) { break; } - skb_reserve(skb, encap_size); + skb_reserve(skb, resv_size); desc->skb = skb; } else { DBG_DCB_RX(("Refill Rx%d SKB in DCB %d recycled.\n", @@ -3198,11 +3201,7 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) case KCOM_DEST_T_API: DBG_FLTR(("Send to Rx API\n")); sinfo->rx[chan].pkts_f_api++; - if (bkn_api_rx_copy_from_skb(sinfo, chan, desc) < 0) { - /* Suspend SKB Rx due to no API resources */ - sinfo->rx[chan].api_wait = 1; - return dcbs_done; - } + bkn_api_rx_copy_from_skb(sinfo, chan, desc); break; case KCOM_DEST_T_NETIF: priv = bkn_netif_lookup(sinfo, filter->kf.dest_id); @@ -3408,10 +3407,6 @@ bkn_rx_desc_done(bkn_switch_info_t *sinfo, int chan) static void bkn_rx_chain_done(bkn_switch_info_t *sinfo, int chan) { - if (sinfo->rx[chan].use_rx_skb && sinfo->rx[chan].api_wait) { - return; - } - DBG_IRQ(("Rx%d chain done\n", chan)); if (sinfo->rx[chan].chain_complete == 0) { @@ -3809,6 +3804,7 @@ static int xgs_do_dma(bkn_switch_info_t *sinfo, int budget) { int rx_dcbs_done = 0, tx_dcbs_done = 0; + int chan_done, budget_chans = 0; uint32_t dma_stat; int chan; @@ -3817,7 +3813,28 @@ xgs_do_dma(bkn_switch_info_t *sinfo, int budget) for (chan = 0; chan < sinfo->rx_chans; chan++) { if (dma_stat & DS_DESC_DONE_TST(XGS_DMA_RX_CHAN + chan)) { xgs_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); - rx_dcbs_done += bkn_do_rx(sinfo, chan, budget - rx_dcbs_done); + sinfo->poll_channels |= 1 << chan; + } + } + if (!sinfo->poll_channels) { + sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; + budget_chans = budget / sinfo->rx_chans; + } else { + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + budget_chans++; + } + } + budget_chans = budget / budget_chans; + } + + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + chan_done = bkn_do_rx(sinfo, chan, budget_chans); + rx_dcbs_done += chan_done; + if (chan_done < budget_chans) { + sinfo->poll_channels &= ~(1 << chan); + } bkn_rx_desc_done(sinfo, chan); } @@ -3833,13 +3850,14 @@ xgs_do_dma(bkn_switch_info_t *sinfo, int budget) bkn_tx_chain_done(sinfo, tx_dcbs_done); } - return rx_dcbs_done; + return sinfo->poll_channels ? budget : rx_dcbs_done; } static int xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) { int rx_dcbs_done = 0, tx_dcbs_done = 0; + int chan_done, budget_chans = 0; uint32_t dma_stat, irq_stat = 0; int chan; @@ -3854,7 +3872,28 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) if (dma_stat & (0x10 << (XGS_DMA_RX_CHAN + chan)) || irq_stat & (0x08000000 << (XGS_DMA_RX_CHAN + chan))) { xgsm_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); - rx_dcbs_done += bkn_do_rx(sinfo, chan, budget - rx_dcbs_done); + sinfo->poll_channels |= 1 << chan; + } + } + if (!sinfo->poll_channels) { + sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; + budget_chans = budget / sinfo->rx_chans; + } else { + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + budget_chans++; + } + } + budget_chans = budget / budget_chans; + } + + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + chan_done = bkn_do_rx(sinfo, chan, budget_chans); + rx_dcbs_done += chan_done; + if (chan_done < budget_chans) { + sinfo->poll_channels &= ~(1 << chan); + } bkn_rx_desc_done(sinfo, chan); } @@ -3879,22 +3918,45 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) bkn_tx_chain_done(sinfo, tx_dcbs_done); } - return rx_dcbs_done; + return sinfo->poll_channels ? budget : rx_dcbs_done; } static int xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) { int rx_dcbs_done = 0, tx_dcbs_done = 0; + int chan_done, budget_chans = 0; uint32_t irq_stat; int chan; DEV_READ32(sinfo, CMICX_IRQ_STATr, &irq_stat); + for (chan = 0; chan < sinfo->rx_chans; chan++) { if ((irq_stat & CMICX_DS_CMC_CTRLD_INT(XGS_DMA_RX_CHAN + chan)) || (irq_stat & CMICX_DS_CMC_DESC_DONE(XGS_DMA_RX_CHAN + chan))) { xgsx_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); - rx_dcbs_done += bkn_do_rx(sinfo, chan, budget - rx_dcbs_done); + sinfo->poll_channels |= 1 << chan; + } + } + if (!sinfo->poll_channels) { + sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; + budget_chans = budget / sinfo->rx_chans; + } else { + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + budget_chans++; + } + } + budget_chans = budget / budget_chans; + } + + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (1 << chan & sinfo->poll_channels) { + chan_done = bkn_do_rx(sinfo, chan, budget_chans); + rx_dcbs_done += chan_done; + if (chan_done < budget_chans) { + sinfo->poll_channels &= ~(1 << chan); + } bkn_rx_desc_done(sinfo, chan); } @@ -3919,7 +3981,7 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) bkn_tx_chain_done(sinfo, tx_dcbs_done); } - return rx_dcbs_done; + return sinfo->poll_channels ? budget : rx_dcbs_done; } static int @@ -4400,10 +4462,12 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb_any(skb); skb = new_skb; pktdata = skb->data; + rcpulen = 0; } else { /* Add tag to RCPU header space */ DBG_SKB(("Expand into unused RCPU header\n")); - pktdata = &skb->data[rcpulen - 4]; + rcpulen -= 4; + pktdata = &skb->data[rcpulen]; for (idx = 0; idx < 12; idx++) { pktdata[idx] = pktdata[idx + 4]; } @@ -4418,7 +4482,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } else { if (sinfo->cmic_type == 'x' && priv->port >= 0) { if (skb_header_cloned(skb) || skb_headroom(skb) < hdrlen + 4 || - ((unsigned long)skb->data % 4)) { + (sinfo->dcb_type == 36 && (unsigned long)skb->data % 4)) { /* Current SKB cannot be modified */ DBG_SKB(("Realloc Tx SKB\n")); new_skb = dev_alloc_skb(pktlen + hdrlen + 4); @@ -4502,6 +4566,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&sinfo->lock, flags); return 0; } + /* skb_padto may update the skb->data pointer */ + pktdata = &skb->data[rcpulen]; DBG_SKB(("Packet padded to %d bytes\n", pktlen)); } @@ -4696,7 +4762,6 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) * bit0 -bit15 of dcb[1] is used to save requested byte count */ if ((skb->len + 4) <= SOC_DCB_KNET_COUNT_MASK) { - pktdata = skb->data; pktlen = skb->len + 4; if (pktlen < (64 + taglen + hdrlen)) { pktlen = (64 + taglen + hdrlen); @@ -4710,6 +4775,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } DBG_SKB(("Packet padded to %d bytes after tx callback\n", pktlen)); } + pktdata = skb->data; } else { DBG_WARN(("Tx drop: size of pkt (%d) is out of range(%d)\n", pktlen, SOC_DCB_KNET_COUNT_MASK)); @@ -4785,11 +4851,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) bkn_suspend_tx(sinfo); } -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,0)) - dev->trans_start = jiffies; -#else - netif_trans_update(dev); -#endif + NETDEV_UPDATE_TRANS_START_TIME(dev); + spin_unlock_irqrestore(&sinfo->lock, flags); return 0; @@ -5491,14 +5554,12 @@ bkn_seq_dma_show(struct seq_file *s, void *v) seq_printf(s, "Rx%d DCB info (unit %d):\n" " api: %d\n" - " wait: %d\n" " dirty: %d\n" " cur: %d\n" " free: %d\n" " run: %d\n", chan, iter->dev_no, sinfo->rx[chan].api_active, - sinfo->rx[chan].api_wait, sinfo->rx[chan].dirty, sinfo->rx[chan].cur, sinfo->rx[chan].free, @@ -6127,6 +6188,7 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) if (sinfo->cmic_type == 'x') { dcb_chain_end->dcb_mem[woffset + 1] = DMA_TO_BUS_HI(dcb_chain->dcb_dma >> 32); } + MEMORY_BARRIER; } sinfo->tx.api_dcb_chain_end = dcb_chain; if (sinfo->tx.api_active) { @@ -6181,6 +6243,7 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) if (sinfo->cmic_type == 'x') { dcb_chain_end->dcb_mem[woffset + 1] = DMA_TO_BUS_HI(dcb_chain->dcb_dma >> 32); } + MEMORY_BARRIER; } sinfo->rx[chan].api_dcb_chain_end = dcb_chain; if (!sinfo->rx[chan].use_rx_skb) { @@ -6194,18 +6257,6 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) if (sinfo->rx[chan].api_active == 0) { bkn_api_rx_restart(sinfo, chan); - /* Resume SKB Rx due to refilled API resources */ - if (sinfo->rx[chan].use_rx_skb && sinfo->rx[chan].api_wait) { - sinfo->rx[chan].api_wait = 0; - if (CDMA_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { - bkn_do_skb_rx(sinfo, chan, 1); - } else { - bkn_do_skb_rx(sinfo, chan, MAX_RX_DCBS); - if (sinfo->rx[chan].chain_complete) { - bkn_rx_chain_done(sinfo, chan); - } - } - } } spin_unlock_irqrestore(&sinfo->lock, flags); @@ -6272,7 +6323,7 @@ bkn_knet_dev_reprobe(void) for (i = 0; i < kernel_bde->num_devices(BDE_ALL_DEVICES); i++) { sinfo = bkn_sinfo_from_unit(i); - if (sinfo == NULL ) { + if (sinfo == NULL) { /* New device found after re-probe. */ if (bkn_knet_dev_init(i) < 0) { return -1; @@ -6289,7 +6340,7 @@ bkn_knet_dev_reprobe(void) /* Assign the inst_id and evt_idx */ static int -bkn_knet_dev_inst_set(kcom_msg_version_t *kmsg) +bkn_knet_dev_inst_set(kcom_msg_reprobe_t *kmsg) { bkn_switch_info_t *sinfo; int d = kmsg->hdr.unit; @@ -6333,13 +6384,6 @@ bkn_knet_dev_inst_set(kcom_msg_version_t *kmsg) static int bkn_knet_version(kcom_msg_version_t *kmsg, int len) { - /* Support pci hot plug and multiple instance */ - if ((bkn_knet_dev_reprobe() < 0) || - (bkn_knet_dev_inst_set(kmsg) < 0)) { - kmsg->hdr.status = KCOM_E_RESOURCE; - return sizeof(kcom_msg_version_t); - } - kmsg->hdr.type = KCOM_MSG_TYPE_RSP; kmsg->version = KCOM_VERSION; kmsg->netif_max = KCOM_NETIF_MAX; @@ -6496,6 +6540,21 @@ bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) return sizeof(kcom_msg_detach_t); } +static int +bkn_knet_reprobe(kcom_msg_reprobe_t *kmsg, int len) +{ + kmsg->hdr.type = KCOM_MSG_TYPE_RSP; + + /* Support pci hot plug and multiple instance */ + if ((bkn_knet_dev_reprobe() < 0) || + (bkn_knet_dev_inst_set(kmsg) < 0)) { + kmsg->hdr.status = KCOM_E_RESOURCE; + return sizeof(kcom_msg_reprobe_t); + } + + return sizeof(kcom_msg_reprobe_t); +} + static int bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) { @@ -7007,7 +7066,6 @@ bkn_knet_wb_cleanup(kcom_msg_wb_cleanup_t *kmsg, int len) } sinfo->rx[chan].api_dcb_chain_end = NULL; sinfo->rx[chan].api_active = 0; - sinfo->rx[chan].api_wait = 0; } spin_unlock_irqrestore(&sinfo->lock, flags); @@ -7055,6 +7113,11 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) /* Detach kernel module */ len = bkn_knet_detach(&kmsg->detach, len); break; + case KCOM_M_REPROBE: + DBG_CMD(("KCOM_M_REPROBE\n")); + /* Reprobe device */ + len = bkn_knet_reprobe(&kmsg->reprobe, len); + break; case KCOM_M_NETIF_CREATE: DBG_CMD(("KCOM_M_NETIF_CREATE\n")); /* Create network interface */ @@ -7174,8 +7237,7 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) } DBG_INST(("%s dev %d evt_idx %d\n",__FUNCTION__, dev_evt, sinfo->evt_idx)); - evt = &_bkn_evt[sinfo->evt_idx]; - dev_no = last_dev_no = dev_evt; + dev_no = last_dev_no; while (1) { dev_no++; sinfo = bkn_sinfo_from_unit(dev_no); @@ -7204,6 +7266,7 @@ bkn_get_next_dma_event(kcom_msg_dma_info_t *kmsg) } if (dev_no == last_dev_no) { + evt = &_bkn_evt[sinfo->evt_idx]; DBG_INST(("wait queue index %d\n",sinfo->evt_idx)); wait_event_interruptible(evt->evt_wq, evt->evt_wq_get != evt->evt_wq_put); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h index d1977076850b..a48cb540adaf 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/lkm.h @@ -62,6 +62,9 @@ #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) +#include +#endif #include #include diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 20d84aedcb49..4d1e8edd9d5f 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -2,12 +2,12 @@ MLNX_FW_BASE_URL = $(MLNX_SDK_BASE_URL) -MLNX_SPC_FW_VERSION = 13.1910.0920 +MLNX_SPC_FW_VERSION = 13.2000.1140 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.1961.0006 +MLNX_SPC2_FW_VERSION = 29.2000.1140 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) SONIC_ONLINE_FILES += $(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 44cf272957cb..eba727499a59 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.13.7-master +MLNX_SAI_VERSION = SAIRel1.14.0-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 40eea3c069ef..ed2f0d276577 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 40eea3c069efa6defd2ed3b4990543b15ce85ee5 +Subproject commit ed2f0d2765773bde8ee2d3ae552c96edd1d4859e diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index d818a724cc83..1d209fd5a3db 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ -MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/3c8bb2e4f1292484bdf097ae90ec0a2ef9b41b2b/sdk -MLNX_SDK_VERSION = 4.3.0136 +MLNX_SDK_BASE_URL = https://github.com/Mellanox/SAI-Implementation/raw/e7da154ddf8447c04b852195f43c83802c6934c9/sdk +MLNX_SDK_VERSION = 4.3.1104 MLNX_SDK_ISSU_VERSION = 100 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index e8cb8796592c..1b0d609c6f9a 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit e8cb8796592c83f669d73d5587be60afc54eb4f6 +Subproject commit 1b0d609c6f9acd1cb868898f019eaade071c85ee