From c7a707749d854aab34eb3406b01f5c2b5ec5c06b Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Tue, 19 Oct 2021 06:17:00 +0000 Subject: [PATCH 1/8] Updated libsaibcm to 6.0 code --- platform/broadcom/sai.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index e8d7ed2cb5e3..10d4467e8dc9 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,12 +1,12 @@ -BRCM_SAI = libsaibcm_5.0.0.8_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm_5.0.0.8_amd64.deb?sv=2015-04-05&sr=b&sig=T%2FPesnOIeN9802mClMpgk8XFQbqjFAgCnJbbNHxijHo%3D&se=2035-05-13T21%3A34%3A26Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_5.0.0.8_amd64.deb +BRCM_SAI = libsaibcm_6.0.0.10_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-18T20%3A10%3A37Z&se=2030-10-19T20%3A10%3A00Z&sr=b&sp=r&sig=4pIluTLBmfOizMOlk93%2F73hrYH%2B0wnPizinxzgdZeuw%3D" +BRCM_SAI_DEV = libsaibcm-dev_6.0.0.10_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm-dev_5.0.0.8_amd64.deb?sv=2015-04-05&sr=b&sig=X33hZLhRI3L6f4a5JFSlhJvoaTj%2B3zrmNBM9IzIA%2Bj4%3D&se=2035-05-13T21%3A35%3A58Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm-dev_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-18T20%3A33%3A23Z&se=2030-10-19T20%3A33%3A00Z&sr=b&sp=r&sig=22zGsALAPStYDs42Ryegtf23zUvy9Hc0F9%2F6FOIdEn0%3D" # SAI module for DNX Asic family -BRCM_DNX_SAI = libsaibcm_dnx_5.0.0.8_amd64.deb -$(BRCM_DNX_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm_dnx_5.0.0.8_amd64.deb?sv=2015-04-05&sr=b&sig=uy0OW6ZhWjYntalZunEIIzHUztkOyI7TS3F73Sla9vY%3D&se=2035-05-13T21%3A37%3A06Z&sp=r" +BRCM_DNX_SAI = libsaibcm_dnx_6.0.0.10_amd64.deb +$(BRCM_DNX_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm_dnx_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-19T05%3A15%3A02Z&se=2030-10-20T05%3A15%3A00Z&sr=b&sp=r&sig=tibPfsZy32BbX%2F7IM4Hhy%2FBRh35yY5F7q9xJA7HaNe4%3D" SONIC_ONLINE_DEBS += $(BRCM_SAI) SONIC_ONLINE_DEBS += $(BRCM_DNX_SAI) From 0e47e0af8c2ffae667a1f7eadc3912265e6da6c3 Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Wed, 20 Oct 2021 16:05:20 +0000 Subject: [PATCH 2/8] Updated libsaibcm with compilation fix --- platform/broadcom/sai.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 10d4467e8dc9..a0a4a2c46582 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,12 +1,12 @@ BRCM_SAI = libsaibcm_6.0.0.10_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-18T20%3A10%3A37Z&se=2030-10-19T20%3A10%3A00Z&sr=b&sp=r&sig=4pIluTLBmfOizMOlk93%2F73hrYH%2B0wnPizinxzgdZeuw%3D" +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-20T15%3A46%3A03Z&se=2030-10-21T15%3A46%3A00Z&sr=b&sp=r&sig=zhosphas9cBuH%2B7mLC%2ByarQPQSIe2LY%2FXOATIW96cVY%3D" BRCM_SAI_DEV = libsaibcm-dev_6.0.0.10_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm-dev_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-18T20%3A33%3A23Z&se=2030-10-19T20%3A33%3A00Z&sr=b&sp=r&sig=22zGsALAPStYDs42Ryegtf23zUvy9Hc0F9%2F6FOIdEn0%3D" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm-dev_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-20T15%3A47%3A11Z&se=2030-10-21T15%3A47%3A00Z&sr=b&sp=r&sig=pKZxnQKw%2BY6CzAd8swa5yZDduKIrQw7TWyChT5tkqlk%3D" # SAI module for DNX Asic family BRCM_DNX_SAI = libsaibcm_dnx_6.0.0.10_amd64.deb -$(BRCM_DNX_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm_dnx_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-19T05%3A15%3A02Z&se=2030-10-20T05%3A15%3A00Z&sr=b&sp=r&sig=tibPfsZy32BbX%2F7IM4Hhy%2FBRh35yY5F7q9xJA7HaNe4%3D" +$(BRCM_DNX_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/6.0/master/libsaibcm_dnx_6.0.0.10_amd64.deb?sv=2020-08-04&st=2021-10-20T15%3A48%3A05Z&se=2030-10-21T15%3A48%3A00Z&sr=b&sp=r&sig=1sqJI5dLLrci9iu%2FPhNWZJzj0nf5lmcRrAUkASOQVjo%3D" SONIC_ONLINE_DEBS += $(BRCM_SAI) SONIC_ONLINE_DEBS += $(BRCM_DNX_SAI) From b033d77388fb76055dcea273fd7753a6161c19cf Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Fri, 22 Oct 2021 05:50:32 +0000 Subject: [PATCH 3/8] Update SAI GPL modules to 6.5.23 --- .../broadcom/saibcm-modules/include/ibde.h | 3 + .../broadcom/saibcm-modules/include/kcom.h | 31 +- .../saibcm-modules/include/soc/devids.h | 97 +- .../broadcom/saibcm-modules/make/Make.config | 5 - .../saibcm-modules/make/Makefile.linux-gts | 58 +- .../saibcm-modules/make/Makefile.linux-iproc | 30 +- .../make/Makefile.linux-iproc_64 | 24 +- .../make/Makefile.linux-kernel-2_6 | 5 + .../saibcm-modules/make/Makefile.linux-slk | 12 +- .../Makefile.linux-x86-smp_generic_64-2_6 | 10 +- .../saibcm-modules/make/Makefile.linux-xlr | 58 +- .../broadcom/saibcm-modules/sdklt/Makefile | 2 +- .../bcm56780_a0/bcm56780_a0_pdma_attach.c | 2 +- .../bcm56880_a0/bcm56880_a0_pdma_attach.c | 2 +- .../bcm56990_a0/bcm56990_a0_pdma_attach.c | 2 +- .../bcm56990_b0/bcm56990_b0_pdma_attach.c | 2 +- .../bcm56995_a0/bcm56995_a0_pdma_attach.c | 38 + .../bcm56996_a0/bcm56996_a0_pdma_attach.c | 2 +- .../bcm56996_b0/bcm56996_b0_pdma_attach.c | 38 + .../bcm56998_a0/bcm56998_a0_pdma_attach.c | 38 + .../bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c | 13 +- .../hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c | 67 +- .../bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c | 42 +- .../hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c | 63 +- .../bcmcnet/include/bcmcnet/bcmcnet_cmicd.h | 2 +- .../bcmcnet/include/bcmcnet/bcmcnet_cmicx.h | 2 +- .../bcmcnet/include/bcmcnet/bcmcnet_core.h | 35 +- .../bcmcnet/include/bcmcnet/bcmcnet_dev.h | 2 +- .../include/bcmcnet/bcmcnet_internal.h | 12 +- .../bcmcnet/include/bcmcnet/bcmcnet_rxtx.h | 11 +- .../bcmcnet/include/bcmcnet/bcmcnet_types.h | 46 +- .../sdklt/bcmcnet/main/bcmcnet_core.c | 89 +- .../sdklt/bcmcnet/main/bcmcnet_dev.c | 65 +- .../sdklt/bcmcnet/main/bcmcnet_rxtx.c | 16 +- .../bcmdrd/include/bcmdrd/bcmdrd_devlist.h | 123 +- .../sdklt/bcmdrd/include/bcmdrd_config.h | 4 +- .../bcmdrd/include/bcmdrd_config_chips.h | 214 ++- .../saibcm-modules/sdklt/linux/bde/Kbuild | 3 +- .../saibcm-modules/sdklt/linux/bde/Makefile | 2 +- .../saibcm-modules/sdklt/linux/bde/ngbde.h | 50 +- .../sdklt/linux/bde/ngbde_dma.c | 2 +- .../sdklt/linux/bde/ngbde_iio.c | 51 +- .../sdklt/linux/bde/ngbde_intr.c | 45 +- .../sdklt/linux/bde/ngbde_ioctl.c | 10 +- .../sdklt/linux/bde/ngbde_iproc_probe.c | 2 +- .../sdklt/linux/bde/ngbde_kapi.c | 200 ++- .../sdklt/linux/bde/ngbde_main.c | 9 +- .../sdklt/linux/bde/ngbde_paxb.c | 94 ++ .../sdklt/linux/bde/ngbde_pci_probe.c | 7 +- .../sdklt/linux/bde/ngbde_pgmem.c | 2 +- .../sdklt/linux/bde/ngbde_pio.c | 2 +- .../sdklt/linux/bde/ngbde_procfs.c | 2 +- .../sdklt/linux/bde/ngbde_swdev.c | 2 +- .../sdklt/linux/include/lkm/lkm.h | 2 +- .../sdklt/linux/include/lkm/ngbde_ioctl.h | 19 +- .../sdklt/linux/include/lkm/ngbde_kapi.h | 190 ++- .../sdklt/linux/include/lkm/ngedk_ioctl.h | 183 +++ .../sdklt/linux/include/lkm/ngknet_dev.h | 14 +- .../sdklt/linux/include/lkm/ngknet_ioctl.h | 2 +- .../saibcm-modules/sdklt/linux/knet/Kbuild | 2 +- .../saibcm-modules/sdklt/linux/knet/Makefile | 5 +- .../sdklt/linux/knet/ngknet_buff.c | 10 +- .../sdklt/linux/knet/ngknet_buff.h | 2 +- .../sdklt/linux/knet/ngknet_callback.c | 56 +- .../sdklt/linux/knet/ngknet_callback.h | 69 +- .../sdklt/linux/knet/ngknet_dep.h | 9 +- .../sdklt/linux/knet/ngknet_extra.c | 49 +- .../sdklt/linux/knet/ngknet_extra.h | 2 +- .../sdklt/linux/knet/ngknet_linux.c | 2 +- .../sdklt/linux/knet/ngknet_linux.h | 2 +- .../sdklt/linux/knet/ngknet_main.c | 173 ++- .../sdklt/linux/knet/ngknet_main.h | 17 +- .../sdklt/linux/knet/ngknet_procfs.c | 5 +- .../sdklt/linux/knet/ngknet_procfs.h | 2 +- .../sdklt/linux/knet/ngknet_ptp.c | 2 +- .../sdklt/linux/knet/ngknet_ptp.h | 2 +- .../saibcm-modules/sdklt/linux/knetcb/Kbuild | 22 +- .../sdklt/linux/knetcb/Makefile | 20 +- .../sdklt/linux/knetcb/ngknetcb_main.c | 33 +- .../sdklt/linux/knetcb/psample-cb.c | 13 +- .../broadcom/saibcm-modules/sdklt/make/lkm.mk | 41 +- .../sdklt/shr/include/shr/shr_error.h | 2 +- .../systems/bde/linux/include/linux_dma.h | 3 +- .../bde/linux/kernel/linux-kernel-bde.c | 130 +- .../systems/bde/linux/kernel/linux_dma.c | 392 +++-- .../bde/linux/user/kernel/linux-user-bde.c | 79 +- .../linux/kernel/modules/bcm-knet/bcm-knet.c | 1286 +++++++++++++---- .../linux/kernel/modules/include/bcm-knet.h | 9 + .../linux/kernel/modules/knet-cb/knet-cb.c | 46 +- .../systems/linux/user/common/Makefile | 48 +- .../systems/linux/user/gts/Makefile | 3 +- .../systems/linux/user/iproc/Makefile | 2 +- .../systems/linux/user/iproc_64/Makefile | 2 +- .../systems/linux/user/xlr/Makefile | 3 +- 94 files changed, 3603 insertions(+), 1098 deletions(-) create mode 100644 platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56995_a0/bcm56995_a0_pdma_attach.c create mode 100644 platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_b0/bcm56996_b0_pdma_attach.c create mode 100644 platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56998_a0/bcm56998_a0_pdma_attach.c create mode 100644 platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_paxb.c create mode 100644 platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngedk_ioctl.h diff --git a/platform/broadcom/saibcm-modules/include/ibde.h b/platform/broadcom/saibcm-modules/include/ibde.h index fb9d13d1d5fe..1716a18f39ca 100644 --- a/platform/broadcom/saibcm-modules/include/ibde.h +++ b/platform/broadcom/saibcm-modules/include/ibde.h @@ -87,6 +87,8 @@ typedef struct ibde_s { #define BDE_I2C_DEV_TYPE SAL_I2C_DEV_TYPE /* I2C device */ #define BDE_AXI_DEV_TYPE SAL_AXI_DEV_TYPE /* AXI device */ #define BDE_EMMI_DEV_TYPE SAL_EMMI_DEV_TYPE /* EMMI device */ +#define BDE_COMPOSITE_DEV_TYPE SAL_COMPOSITE_DEV_TYPE /* Composite device, composed of sub-devices with buses */ +#define BDE_USER_DEV_TYPE SAL_USER_DEV_TYPE /* The user implements his own method of access to the device */ #define BDE_DEV_BUS_ALT SAL_DEV_BUS_ALT /* Alternate Access */ #define BDE_DEV_BUS_MSI SAL_DEV_BUS_MSI /* Message-signaled interrupts */ @@ -104,6 +106,7 @@ typedef struct ibde_s { #define BDE_128K_REG_SPACE 0x40000000 /* Map 128K (v 64K) */ #define BDE_320K_REG_SPACE 0x80000000 /* Map 256K+64K */ + /* Bus supports only 16bit reads */ #define BDE_DEV_BUS_RD_16BIT SAL_DEV_BUS_RD_16BIT diff --git a/platform/broadcom/saibcm-modules/include/kcom.h b/platform/broadcom/saibcm-modules/include/kcom.h index 5129400ca8cd..4771033c6b04 100644 --- a/platform/broadcom/saibcm-modules/include/kcom.h +++ b/platform/broadcom/saibcm-modules/include/kcom.h @@ -58,6 +58,7 @@ #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_HW_INFO 8 /* Send the HW info to kernel module */ #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 */ @@ -72,7 +73,7 @@ #define KCOM_M_WB_CLEANUP 51 /* Clean up for warmbooting */ #define KCOM_M_CLOCK_CMD 52 /* Clock Commands */ -#define KCOM_VERSION 12 /* Protocol version */ +#define KCOM_VERSION 13 /* Protocol version */ /* * Message status codes @@ -299,7 +300,7 @@ typedef struct kcom_dma_info_s { void *p; uint8 b[8]; } cookie; - } kcom_dma_info_t; +} kcom_dma_info_t; /* Default channel configuration */ #define KCOM_DMA_TX_CHAN 0 @@ -331,6 +332,18 @@ typedef struct kcom_eth_hw_config_s { uint32 value; } kcom_eth_hw_config_t; +#ifndef KCOM_HW_INFO_OAMP_PORT_MAX +#define KCOM_HW_INFO_OAMP_PORT_MAX 4 +#endif + +/* + * Send the OAMP information to Kernel module. + */ +typedef struct kcom_oamp_info_s { + uint32 oamp_port_number; + uint32 oamp_ports[KCOM_HW_INFO_OAMP_PORT_MAX]; +} kcom_oamp_info_t; + /* * Message types */ @@ -421,6 +434,11 @@ typedef struct kcom_msg_hw_init_s { uint8 no_skip_udh_check; uint8 system_headers_mode; uint8 udh_enable; + /* + * Bitmap of DMA channels reserved for the user mode network driver. + * These channels cannot be used by the kernel network driver (KNET). + */ + uint32 unet_channels; } kcom_msg_hw_init_t; /* @@ -554,6 +572,14 @@ typedef struct kcom_msg_dma_info_s { kcom_dma_info_t dma_info; } kcom_msg_dma_info_t; +/* + * HW info + */ +typedef struct kcom_msg_hw_info_s { + kcom_msg_hdr_t hdr; + kcom_oamp_info_t oamp_info; +} kcom_msg_hw_info_t; + /* * All messages (e.g. for generic receive) */ @@ -564,6 +590,7 @@ typedef union kcom_msg_s { kcom_msg_hw_reset_t hw_reset; kcom_msg_hw_init_t hw_init; kcom_msg_eth_hw_config_t eth_hw_config; + kcom_msg_hw_info_t hw_info; kcom_msg_detach_t detach; kcom_msg_reprobe_t reprobe; kcom_msg_netif_create_t netif_create; diff --git a/platform/broadcom/saibcm-modules/include/soc/devids.h b/platform/broadcom/saibcm-modules/include/soc/devids.h index 89fabac44537..0347f84710dd 100644 --- a/platform/broadcom/saibcm-modules/include/soc/devids.h +++ b/platform/broadcom/saibcm-modules/include/soc/devids.h @@ -25,7 +25,7 @@ * https://www.broadcom.com/products/ethernet-connectivity/software/opennsa */ /* - * Copyright: (c) 2020 Broadcom. + * Copyright: (c) 2021 Broadcom. * All Rights Reserved. */ @@ -846,13 +846,6 @@ #define BCM56746_A0_REV_ID 1 #define BCM56746_A1_REV_ID 2 -#define BCM88732_DEVICE_ID 0x0732 -#define BCM88732_A0_REV_ID 1 -#define BCM88732_A1_REV_ID 2 -#define BCM88732_A2_REV_ID 4 -#define BCM88732_B0_REV_ID 0x11 -#define BCM88732_B1_REV_ID 0x12 -#define BCM88732_B2_REV_ID 0x13 #define BCM56640_DEVICE_ID 0xb640 #define BCM56640_A0_REV_ID 1 @@ -1526,6 +1519,8 @@ #define BCM56472_A0_REV_ID 1 #define BCM56475_DEVICE_ID 0xb475 #define BCM56475_A0_REV_ID 1 +#define BCM56474_DEVICE_ID 0xb474 +#define BCM56474_A0_REV_ID 1 #define BCM53540_DEVICE_ID 0x8540 @@ -1560,10 +1555,6 @@ #define ARAD_A0_REV_ID 0x0000 #define ARAD_B0_REV_ID 0x0011 #define ARAD_B1_REV_ID 0x0012 -#define BCM88650_DEVICE_ID ARAD_DEVICE_ID -#define BCM88650_A0_REV_ID ARAD_A0_REV_ID -#define BCM88650_B0_REV_ID ARAD_B0_REV_ID -#define BCM88650_B1_REV_ID ARAD_B1_REV_ID #define BCM88770_DEVICE_ID 0x8770 #define BCM88770_A1_REV_ID 0x0002 #define BCM88773_DEVICE_ID 0x8773 @@ -1814,8 +1805,10 @@ #define J2P_DEVICE_ID 0x8850 #define J2P_A0_REV_ID DNXC_A0_REV_ID +#define J2P_A1_REV_ID DNXC_A1_REV_ID #define BCM88850_DEVICE_ID J2P_DEVICE_ID #define BCM88850_A0_REV_ID J2P_A0_REV_ID +#define BCM88850_A1_REV_ID J2P_A1_REV_ID #define BCM88851_DEVICE_ID 0x8851 #define BCM88852_DEVICE_ID 0x8852 #define BCM88853_DEVICE_ID 0x8853 @@ -1832,6 +1825,23 @@ #define BCM8885E_DEVICE_ID 0x885E #define BCM8885F_DEVICE_ID 0x885F +#define BCM88840_DEVICE_ID 0x8840 +#define BCM88841_DEVICE_ID 0x8841 +#define BCM88842_DEVICE_ID 0x8842 +#define BCM88843_DEVICE_ID 0x8843 +#define BCM88844_DEVICE_ID 0x8844 +#define BCM88845_DEVICE_ID 0x8845 +#define BCM88846_DEVICE_ID 0x8846 +#define BCM88847_DEVICE_ID 0x8847 +#define BCM88848_DEVICE_ID 0x8848 +#define BCM88849_DEVICE_ID 0x8849 +#define BCM8884A_DEVICE_ID 0x884A +#define BCM8884B_DEVICE_ID 0x884B +#define BCM8884C_DEVICE_ID 0x884C +#define BCM8884D_DEVICE_ID 0x884D +#define BCM8884E_DEVICE_ID 0x884E +#define BCM8884F_DEVICE_ID 0x884F + #define Q2A_DEVICE_ID 0x8480 #define Q2A_A0_REV_ID DNXC_A0_REV_ID @@ -1875,6 +1885,24 @@ #define BCM8828E_DEVICE_ID 0x828E #define BCM8828F_DEVICE_ID 0x828F +#define Q2N_DEVICE_ID 0x8290 +#define BCM88290_DEVICE_ID Q2N_DEVICE_ID +#define BCM88291_DEVICE_ID 0x8291 +#define BCM88292_DEVICE_ID 0x8292 +#define BCM88293_DEVICE_ID 0x8293 +#define BCM88294_DEVICE_ID 0x8294 +#define BCM88295_DEVICE_ID 0x8295 +#define BCM88296_DEVICE_ID 0x8296 +#define BCM88297_DEVICE_ID 0x8297 +#define BCM88298_DEVICE_ID 0x8298 +#define BCM88299_DEVICE_ID 0x8299 +#define BCM8829A_DEVICE_ID 0x829A +#define BCM8829B_DEVICE_ID 0x829B +#define BCM8829C_DEVICE_ID 0x829C +#define BCM8829D_DEVICE_ID 0x829D +#define BCM8829E_DEVICE_ID 0x829E +#define BCM8829F_DEVICE_ID 0x829F + #define QAX_DEVICE_ID 0x8470 #define QAX_A0_REV_ID 0x0001 #define QAX_B0_REV_ID 0x0011 @@ -1887,8 +1915,9 @@ #define BCM88474H_DEVICE_ID 0x847B #define BCM88476_DEVICE_ID 0x8476 #define BCM88477_DEVICE_ID 0x8477 - - + +#define BCM88479_DEVICE_ID 0x8479 + #define BCM88470_A0_REV_ID QAX_A0_REV_ID @@ -1908,11 +1937,6 @@ #define BCM88278_DEVICE_ID 0x8278 #define BCM88279_DEVICE_ID 0x8279 -#define FLAIR_DEVICE_ID 0xF000 -#define FLAIR_A0_REV_ID 0x0001 -#define BCM8206_DEVICE_ID FLAIR_DEVICE_ID -#define BCM8206_A0_REV_ID FLAIR_A0_REV_ID - #define BCM88360_DEVICE_ID 0x8360 #define BCM88360_A0_REV_ID ARADPLUS_A0_REV_ID #define BCM88361_DEVICE_ID 0x8361 @@ -1949,10 +1973,6 @@ #define BCM88551_B1_REV_ID ARAD_B1_REV_ID #define BCM88552_DEVICE_ID 0x8552 #define BCM88552_B1_REV_ID ARAD_B1_REV_ID -#define BCM88651_DEVICE_ID 0x8651 -#define BCM88651_B1_REV_ID ARAD_B1_REV_ID -#define BCM88654_DEVICE_ID 0x8654 -#define BCM88654_B1_REV_ID ARAD_B1_REV_ID #define BCM88772_DEVICE_ID 0x8772 #define BCM88952_DEVICE_ID 0x8952 @@ -1969,7 +1989,6 @@ #define PLX9056_DEVICE_ID 0x9056 -#ifdef BCM_LTSW_SUPPORT #define BCM56880_DEVICE_ID 0xb880 #define BCM56880_A0_REV_ID 0x0001 #define BCM56880_B0_REV_ID 0x0011 @@ -1979,9 +1998,6 @@ #define BCM56883_DEVICE_ID 0xb883 #define BCM56883_A0_REV_ID 0x0001 #define BCM56883_B0_REV_ID 0x0011 -#define BCM56889_DEVICE_ID 0xb889 -#define BCM56889_A0_REV_ID 0x0001 -#define BCM56889_B0_REV_ID 0x0011 #define BCM56780_DEVICE_ID 0xb780 #define BCM56780_A0_REV_ID 0x0001 @@ -1989,8 +2005,12 @@ #define BCM56782_A0_REV_ID 0x0001 #define BCM56784_DEVICE_ID 0xb784 #define BCM56784_A0_REV_ID 0x0001 +#define BCM56785_DEVICE_ID 0xb785 +#define BCM56785_A0_REV_ID 0x0001 #define BCM56786_DEVICE_ID 0xb786 #define BCM56786_A0_REV_ID 0x0001 +#define BCM56787_DEVICE_ID 0xb787 +#define BCM56787_A0_REV_ID 0x0001 #define BCM56788_DEVICE_ID 0xb788 #define BCM56788_A0_REV_ID 0x0001 #define BCM56789_DEVICE_ID 0xb789 @@ -1998,14 +2018,35 @@ #define BCM56990_DEVICE_ID 0xb990 #define BCM56990_A0_REV_ID 0x0001 + +#ifndef BCM56990_DEVICE_ID +#define BCM56990_DEVICE_ID 0xb990 +#define BCM56990_A0_REV_ID 0x0001 +#endif #define BCM56990_B0_REV_ID 0x0011 +#define BCM56991_DEVICE_ID 0xb991 +#define BCM56991_B0_REV_ID 0x0011 #define BCM56992_DEVICE_ID 0xb992 #define BCM56992_B0_REV_ID 0x0011 +#define BCM56995_DEVICE_ID 0xb995 +#define BCM56995_A0_REV_ID 0x0001 + #define BCM56996_DEVICE_ID 0xb996 #define BCM56996_A0_REV_ID 0x0001 #define BCM56997_DEVICE_ID 0xb997 #define BCM56997_A0_REV_ID 0x0001 -#endif + +#ifndef BCM56996_DEVICE_ID +#define BCM56996_DEVICE_ID 0xb996 +#define BCM56996_A0_REV_ID 0x0001 +#define BCM56997_DEVICE_ID 0xb997 +#endif +#define BCM56996_B0_REV_ID 0x0011 +#define BCM56997_B0_REV_ID 0x0011 + +#define BCM56998_DEVICE_ID 0xb998 +#define BCM56998_A0_REV_ID 0x0001 + #endif diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config index f5b04b0cdf9e..88bf1740ea0b 100644 --- a/platform/broadcom/saibcm-modules/make/Make.config +++ b/platform/broadcom/saibcm-modules/make/Make.config @@ -172,11 +172,6 @@ CFLAGS += ${INCFLAGS} CXXFLAGS += ${INCFLAGS} CPPFLAGS += ${INCFLAGS} -CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1025 -UKCOM_NETIF_MAX -DKCOM_NETIF_MAX=1056 - -# Flag to enable multi instance support -CFLAGS += -DBCM_INSTANCE_SUPPORT - # # Debug #ifdef control # diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-gts b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts index 726dfdf505bd..609b49c2094a 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-gts +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-gts @@ -34,7 +34,6 @@ # Most of this was taken from target x86-smp_generic_64-2_6. # - ############################################################################# # this segment is custom and not sourced from any existing makefile # # (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # @@ -46,11 +45,11 @@ #endif # some basic path variables for tools and kernel source, etc # -export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-54 TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux # Target machine for EDK-Host defconfig TARGET_MACHINE ?= x86_64 -KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux # set up cross compile prefix, tools dir variables. # export CROSS_COMPILE := x86_64-broadcom-linux-gnu- @@ -70,17 +69,19 @@ export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PAT export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) # set up SYSINC path # -export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_DIR)/bin/$(CROSS_COMPILE)gcc -dumpversion) +export SYSINC := $(TOOLCHAIN_DIR)/lib/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include +# Glibc 2.27 or later version doesn't support SVID libm error handling. +# Building tcl 8.3.3 with the new toolchain will occur errors. +export TCL840 := 1 -# CFLAGS/CFGFLAGS # +# Common CFLAGS CFLAGS += -DUSE_LINUX_BDE_MMAP=1 #CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT CFLAGS += -Wno-error=unused-value -CFLAGS += -Wno-error=unused-but-set-variable -CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=unused-function CFLAGS += -Wno-error=cpp -CFLAGS += -Wno-error=aggressive-loop-optimizations CFLAGS += -Wno-error=array-bounds CFLAGS += -Wno-error=strict-overflow CFLAGS += -L$(TOOLCHAIN_DIR)/lib @@ -88,13 +89,46 @@ CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 #CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # #CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # +# Compiler-specific CFLAGS +ifeq (1,$(USE_CLANG)) # CLANG-specific CFLAGS +CFLAGS += -Wno-strlcpy-strlcat-size +CFLAGS += -Wno-strncat-size +else # GCC-specific CFLAGS +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=sizeof-pointer-div #SDK-233830 +CFLAGS += -Wno-error=memset-elt-size #SDK-232626 +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 8)" "1" + CFLAGS += -Wno-stringop-overflow + CFLAGS += -Wno-stringop-truncation + CFLAGS += -Wno-error=restrict +endif +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 9)" "1" + CFLAGS += -Wno-address-of-packed-member +endif +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \== 10)" "1" + #There might be a bug in GCC10 that cannot detect initialization correctly. + CFLAGS += -Wno-error=uninitialized + CFLAGS += -Wno-error=format-overflow + CFLAGS += -fcommon +endif +endif # Compiler-specific CFLAGS + #XLDK-568 fix inline references CFGFLAGS += -fgnu89-inline +#XLR-54 +CFLAGS += -Wno-unused-variable #SDK-232993 +CFLAGS += -Wno-deprecated-declarations #SDK-233174 + +#CFLAGS += -Wno-unused-function +#CFLAGS += -Wno-aggressive-loop-optimizations +#CFLAGS += -Wno-maybe-uninitialized # set up KFLAGS appropriately. # ifeq (,$(KFLAGS)) -KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -Os -mno-sse -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack endif @@ -103,6 +137,7 @@ endif ###################################################################### CFGFLAGS += -DLONGS_ARE_64BITS CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ @@ -155,6 +190,11 @@ export SYSTEM_INTERFACE export EXTRA_SYSTEM_INTERFACES endif +ifneq (, $(EDKHOST)) +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 +endif + ifneq ($(targetplat),user) # By default we exclude -Werror from x86 kernel builds BCM_CFLAGS = -Wall diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc index fa4911185aa8..183f7f274203 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc @@ -41,11 +41,11 @@ ifeq (BE,$(ENDIAN_MODE)) #While BE mode is supported, it's use is very limited. We had a specific customer #request for BE support but don't currently mainstream it. So a 5.1.0 version #has not been built. Continue using 5.0.3 for any BE support -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32 +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk61-be/XLDK32 TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux else -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK32 +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk61/XLDK32 TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux endif @@ -61,6 +61,7 @@ LD_LIBRARY_PATH=$(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib export TOOLCHAIN_BIN_DIR LD_LIBRARY_PATH CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) +CROSS_GCC_VER_MAJOR := $(shell echo $(CROSS_GCC_VER) | cut -f1 -d.) # Default Linux include directory ifeq (,$(LINUX_INCLUDE)) @@ -79,13 +80,29 @@ CFLAGS += -fno-aggressive-loop-optimizations CFLAGS += -Wno-error=maybe-uninitialized CFLAGS += -Wno-error=array-bounds CFLAGS += -fgnu89-inline -ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" - CFLAGS += -Wno-error=bool-operation +ifeq "$(shell expr $(CROSS_GCC_VER_MAJOR) \>= 8)" "1" + CFLAGS += -Wno-stringop-overflow + CFLAGS += -Wno-stringop-truncation + CFLAGS += -Wno-error=restrict +endif +ifeq "$(shell expr $(CROSS_GCC_VER_MAJOR) \>= 9)" "1" + CFLAGS += -Wno-address-of-packed-member +endif +ifeq "$(shell expr $(CROSS_GCC_VER_MAJOR) \== 10)" "1" + #There might be a bug in GCC10 that cannot detect initialization correctly. + CFLAGS += -Wno-error=uninitialized + CFLAGS += -Wno-error=format-overflow + CFLAGS += -fcommon endif CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" +#XLR-54 +CFLAGS += -Wno-error=memset-elt-size #SDK-232626 +CFLAGS += -Wno-error=unused-function +CFLAGS += -Wno-error=unused-variable +CFLAGS += -Wno-error=unused-const-variable ARCH = arm KBUILD_VERBOSE = 1 @@ -108,6 +125,11 @@ KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/in ifeq (,$(KFLAGS)) KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls KFLAGS += -I$(LINUX_INCLUDE)/uapi -I$(LINUX_INCLUDE)/generated/uapi -I$(KERNDIR)/arch/arm/include/uapi -I$(KERNDIR)/arch/arm/include/generated/uapi + +ifeq "$(shell expr $(CROSS_GCC_VER_MAJOR) \== 10)" "1" + # WAR: Disable the following optimizations because they will fail the installation of kernel modules + KFLAGS += -fno-expensive-optimizations -fno-gcse +endif endif ifneq ($(targetplat),user) diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 index 247da7386370..121ccc2f3ac4 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-iproc_64 @@ -40,11 +40,11 @@ endif ifeq (BE,$(ENDIAN_MODE)) #We've never actually built a 64 BE executable. Just here for any future #customer requirements. -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51-be/XLDK64 +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk61-be/XLDK64 TARGET_ARCHITECTURE ?= aarch64_be-broadcom-linux-uclibc KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux else -TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk51/XLDK64 +TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk61/XLDK64 TARGET_ARCHITECTURE ?= aarch64-broadcom-linux-uclibc KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux endif @@ -78,12 +78,24 @@ CFLAGS += -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS CFLAGS += -DPHYS_ADDRS_ARE_64BITS CFLAGS += -fno-aggressive-loop-optimizations -fno-strict-overflow CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=unused-function CFLAGS += -Wno-error=array-bounds +CFLAGS += -Wno-error=format-overflow CFLAGS += -fgnu89-inline -ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 7)" "1" - CFLAGS += -Wno-error=bool-operation +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 8)" "1" + CFLAGS += -Wno-stringop-overflow + CFLAGS += -Wno-stringop-truncation + CFLAGS += -Wno-error=restrict +endif +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 9)" "1" + CFLAGS += -Wno-address-of-packed-member +endif +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \== 10)" "1" + #There might be a bug in GCC10 that cannot detect initialization correctly. + CFLAGS += -Wno-error=uninitialized + CFLAGS += -Wno-error=format-overflow + CFLAGS += -fcommon endif - CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\" @@ -109,7 +121,7 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ KFLAG_INCLD ?= $(LD_LIBRARY_PATH)/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include ifeq (,$(KFLAGS)) -KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mcmodel=large +KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mcmodel=large endif ifneq ($(targetplat),user) diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 index 08461e4c4b7c..431bf808f044 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-kernel-2_6 @@ -40,6 +40,11 @@ FEATURE_EXCLUDE_LIST = $(sort $(_FEATURE_EXCLUDE_LIST)) # Conditionally Replaces DEFAULT var ifeq ($(origin CC),default) CC = $(LSRUN) $(CROSS_COMPILE)gcc +else +# If using CLANG then revert the CC to default gcc tool +ifeq ($(USE_CLANG),1) +CC = $(LSRUN) $(CROSS_COMPILE)gcc +endif endif ifeq ($(origin CXX),default) diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-slk b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk index 656835019a05..de6322fceb74 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-slk +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-slk @@ -131,7 +131,9 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -KFLAG_INCLD = $(TOOLCHAIN_BASE_DIR)/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.2/include +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_BIN_DIR)/$(CROSS_COMPILE)gcc -dumpversion) + +KFLAG_INCLD = $(TOOLCHAIN_BASE_DIR)/lib/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include ifeq (,$(KFLAGS)) KFLAGS := -D__LINUX_ARM_ARCH__=8 -D__KERNEL__ -DPTRS_ARE_64BITS -DLONGS_ARE_64BITS -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm64/include -I$(KERNDIR)/arch/arm64/include/generated -I$(KERNDIR)/arch/arm64/include/generated/asm -I$(KERNDIR)/include/uapi -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/arch/arm64/include/uapi -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -fno-pic -pipe -ffreestanding -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign @@ -156,6 +158,14 @@ endif export SYSTEM_INTERFACE endif +ifneq (, $(EDKHOST)) +ifeq (BE,$(ENDIAN_MODE)) +OPENSRC_BUILD ?= linaro_arm64_be +else +OPENSRC_BUILD ?= linaro_arm64_le +endif +endif + ifneq ($(targetplat),user) include ${SDK}/make/Makefile.linux-kernel-3_6 endif diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 index 9df0bee5a774..2f6b54f1b994 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 @@ -39,11 +39,6 @@ ifeq (,$(KFLAGS)) KFLAGS := -nostdinc -isystem $(SYSINC) -I$(KERNDIR)/include -I$(KERNDIR)/arch/x86/include -include $(AUTOCONF) -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -Os -m64 -mtune=generic -mno-red-zone -fno-pie -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-stack-protector -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign endif -ifeq ($(LINUX_MAKE_SHARED_LIB), 1) - KFLAGS += -fPIC -mcmodel=small -else - KFLAGS += -fno-pie -mcmodel=kernel -endif LINUX_UAPI = $(LINUX_INCLUDE)/uapi ifneq (,$(shell ls $(LINUX_UAPI) 2>/dev/null)) @@ -69,4 +64,9 @@ endif export SYSTEM_INTERFACE endif +ifneq (, $(EDKHOST)) +# Default open source target build +OPENSRC_BUILD ?= x86_64 +endif + include ${SDK}/make/Makefile.linux-x86-common-2_6 diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr index 726dfdf505bd..609b49c2094a 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-xlr @@ -34,7 +34,6 @@ # Most of this was taken from target x86-smp_generic_64-2_6. # - ############################################################################# # this segment is custom and not sourced from any existing makefile # # (base thanks to http:confluence.broadcom.com/display/NTSWSW/X86+System) # @@ -46,11 +45,11 @@ #endif # some basic path variables for tools and kernel source, etc # -export XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-419 +XLR_TOOLS_BASE = /projects/ntsw-tools/linux/xlr-54 TOOLCHAIN_DIR = $(XLR_TOOLS_BASE)/buildroot/host/usr +KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux # Target machine for EDK-Host defconfig TARGET_MACHINE ?= x86_64 -KERNDIR = $(XLR_TOOLS_BASE)/kernel/linux # set up cross compile prefix, tools dir variables. # export CROSS_COMPILE := x86_64-broadcom-linux-gnu- @@ -70,17 +69,19 @@ export LIBRARY_PATH := $(TOOLCHAIN_DIR)/lib:$(TOOLCHAIN_DIR)/lib64:$(LIBRARY_PAT export PATH := $(TOOLCHAIN_DIR)/bin:$(KERNDIR):$(PATH) # set up SYSINC path # -export SYSINC := $(XLR_TOOLS_BASE)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/5.4.0/include +CROSS_GCC_VER ?= $(shell $(TOOLCHAIN_DIR)/bin/$(CROSS_COMPILE)gcc -dumpversion) +export SYSINC := $(TOOLCHAIN_DIR)/lib/gcc/$(TARGET_ARCHITECTURE)/$(CROSS_GCC_VER)/include +# Glibc 2.27 or later version doesn't support SVID libm error handling. +# Building tcl 8.3.3 with the new toolchain will occur errors. +export TCL840 := 1 -# CFLAGS/CFGFLAGS # +# Common CFLAGS CFLAGS += -DUSE_LINUX_BDE_MMAP=1 #CFLAGS += -DBDE_LINUX_USE_MSI_INTERRUPT CFLAGS += -Wno-error=unused-value -CFLAGS += -Wno-error=unused-but-set-variable -CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=unused-function CFLAGS += -Wno-error=cpp -CFLAGS += -Wno-error=aggressive-loop-optimizations CFLAGS += -Wno-error=array-bounds CFLAGS += -Wno-error=strict-overflow CFLAGS += -L$(TOOLCHAIN_DIR)/lib @@ -88,13 +89,46 @@ CFLAGS += -L$(TOOLCHAIN_DIR)/lib64 #CFLAGS += -Wl,--rpath=/lib64 # may need to set rpath and dynamic-linker path here (and possibly in KLFAGS below) in the future, # #CFLAGS += -Wl,--dynamic-linker=/lib64/ld-linux-x86-64.so.2 # if we want to build the target executable to be used with shared libs # +# Compiler-specific CFLAGS +ifeq (1,$(USE_CLANG)) # CLANG-specific CFLAGS +CFLAGS += -Wno-strlcpy-strlcat-size +CFLAGS += -Wno-strncat-size +else # GCC-specific CFLAGS +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=aggressive-loop-optimizations +CFLAGS += -Wno-error=sizeof-pointer-div #SDK-233830 +CFLAGS += -Wno-error=memset-elt-size #SDK-232626 +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 8)" "1" + CFLAGS += -Wno-stringop-overflow + CFLAGS += -Wno-stringop-truncation + CFLAGS += -Wno-error=restrict +endif +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \>= 9)" "1" + CFLAGS += -Wno-address-of-packed-member +endif +ifeq "$(shell expr `echo $(CROSS_GCC_VER) | cut -f1 -d.` \== 10)" "1" + #There might be a bug in GCC10 that cannot detect initialization correctly. + CFLAGS += -Wno-error=uninitialized + CFLAGS += -Wno-error=format-overflow + CFLAGS += -fcommon +endif +endif # Compiler-specific CFLAGS + #XLDK-568 fix inline references CFGFLAGS += -fgnu89-inline +#XLR-54 +CFLAGS += -Wno-unused-variable #SDK-232993 +CFLAGS += -Wno-deprecated-declarations #SDK-233174 + +#CFLAGS += -Wno-unused-function +#CFLAGS += -Wno-aggressive-loop-optimizations +#CFLAGS += -Wno-maybe-uninitialized # set up KFLAGS appropriately. # ifeq (,$(KFLAGS)) -KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -O2 -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -Wframe-larger-than=1024 -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack +KFLAGS := -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib64 -I$(KERNDIR) -lc -nostdinc -isystem $(SYSINC) -Iinclude -I$(KERNDIR)/arch/x86/include -I$(KERNDIR)/arch/x86/include/generated -I$(KERNDIR)/arch/x86/include/generated/uapi -I$(KERNDIR)/arch/x86/include/uapi -I$(KERNDIR)/include -I$(KERNDIR)/include/generated -I$(KERNDIR)/include/generated/uapi -I$(KERNDIR)/include/uapi -include $(KERNDIR)/include/generated/autoconf.h -D__KERNEL__ -DNDEBUG -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Wno-format-security -fno-delete-null-pointer-checks -Os -mno-sse -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -Wdeclaration-after-statement -Wno-pointer-sign -fno-dwarf2-cfi-asm -fconserve-stack endif @@ -103,6 +137,7 @@ endif ###################################################################### CFGFLAGS += -DLONGS_ARE_64BITS CFGFLAGS += -DPTRS_ARE_64BITS +CFGFLAGS += -DPHYS_ADDRS_ARE_64BITS CFGFLAGS += -DSAL_SPL_LOCK_ON_IRQ @@ -155,6 +190,11 @@ export SYSTEM_INTERFACE export EXTRA_SYSTEM_INTERFACES endif +ifneq (, $(EDKHOST)) +# Default open source target build +OPENSRC_BUILD ?= fed21-x86_64 +endif + ifneq ($(targetplat),user) # By default we exclude -Werror from x86 kernel builds BCM_CFLAGS = -Wall diff --git a/platform/broadcom/saibcm-modules/sdklt/Makefile b/platform/broadcom/saibcm-modules/sdklt/Makefile index d6f358c55283..83a77ebcd1e0 100644 --- a/platform/broadcom/saibcm-modules/sdklt/Makefile +++ b/platform/broadcom/saibcm-modules/sdklt/Makefile @@ -1,5 +1,5 @@ # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56780_a0/bcm56780_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56780_a0/bcm56780_a0_pdma_attach.c index e06dcb68bfc8..dfdb504d87c6 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56780_a0/bcm56780_a0_pdma_attach.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56780_a0/bcm56780_a0_pdma_attach.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56880_a0/bcm56880_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56880_a0/bcm56880_a0_pdma_attach.c index 9a2152e99ac0..9dc9195cc209 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56880_a0/bcm56880_a0_pdma_attach.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56880_a0/bcm56880_a0_pdma_attach.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_a0/bcm56990_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_a0/bcm56990_a0_pdma_attach.c index 7827ef25de3d..2e02369c958b 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_a0/bcm56990_a0_pdma_attach.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_a0/bcm56990_a0_pdma_attach.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_b0/bcm56990_b0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_b0/bcm56990_b0_pdma_attach.c index e34ae1f0b45c..1acf4b41bffd 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_b0/bcm56990_b0_pdma_attach.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56990_b0/bcm56990_b0_pdma_attach.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56995_a0/bcm56995_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56995_a0/bcm56995_a0_pdma_attach.c new file mode 100644 index 000000000000..08419f1d3a1e --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56995_a0/bcm56995_a0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56995_a0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56995_a0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56995_a0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_a0/bcm56996_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_a0/bcm56996_a0_pdma_attach.c index aab5822f68b7..2fca51ce9788 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_a0/bcm56996_a0_pdma_attach.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_a0/bcm56996_a0_pdma_attach.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_b0/bcm56996_b0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_b0/bcm56996_b0_pdma_attach.c new file mode 100644 index 000000000000..06e22a8a28a0 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56996_b0/bcm56996_b0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56996_b0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56996_b0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56996_b0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56998_a0/bcm56998_a0_pdma_attach.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56998_a0/bcm56998_a0_pdma_attach.c new file mode 100644 index 000000000000..1c5e0b2846a5 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/chip/bcm56998_a0/bcm56998_a0_pdma_attach.c @@ -0,0 +1,38 @@ +/*! \file bcm56998_a0_pdma_attach.c + * + * Initialize PDMA driver resources. + * + */ +/* + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include +#include +#include + +int +bcm56998_a0_cnet_pdma_attach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_attach(dev); +} + +int +bcm56998_a0_cnet_pdma_detach(struct pdma_dev *dev) +{ + return bcmcnet_cmicx_pdma_driver_detach(dev); +} + diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c index 83ce4d11b97f..e1eac2488497 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_hw.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -88,6 +88,17 @@ cmicd_pdma_hw_init(struct pdma_hw *hw) hw->dev->mode = DEV_MODE_UNET; } + /* + * FIXME: SDKLT-27954 SDKLT-27956 + * + * credit release is invoked by cmic_edb_credit_refresh() in + * bcmtm_internal_port_up(). + * + * But, bcmtm_internal_port_up() is missed in bcm56960_a0. + * + * Need to remove credit release once all CMICd chipsets are fixed. + */ + /* Release credits to EP. Only do this once when HW is initialized. */ hw->hdls.reg_rd32(hw, CMICD_EPINTF_RELEASE_CREDITS, &val); if (!val) { diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c index c4a10e160db9..711a037510dc 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicd/bcmcnet_cmicd_pdma_rxtx.c @@ -38,7 +38,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -354,17 +354,26 @@ cmicd_pdma_rx_ring_refill(struct pdma_hw *hw, struct pdma_rx_queue *rxq) int unused = cmicd_pdma_rx_ring_unused(rxq); dma_addr_t addr; uint32_t halt; + int retry; int rv; for (halt = rxq->halt; halt < rxq->halt + unused; halt++) { pbuf = &rxq->pbuf[halt % rxq->nb_desc]; /* Allocate a new pktbuf */ if (!bm->rx_buf_avail(dev, rxq, pbuf)) { - rv = bm->rx_buf_alloc(dev, rxq, pbuf); - if (SHR_FAILURE(rv)) { - rxq->halt = halt % rxq->nb_desc; + retry = 5000000; + do { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_SUCCESS(rv)) { + break; + } rxq->stats.nomems++; - goto fail; + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Fatal error: Rx buffer has not been allocated for 5 seconds\n"); + rxq->halt = halt % rxq->nb_desc; + return rv; } } /* Setup the new descriptor */ @@ -385,11 +394,6 @@ cmicd_pdma_rx_ring_refill(struct pdma_hw *hw, struct pdma_rx_queue *rxq) sal_spinlock_unlock(rxq->lock); return SHR_E_NONE; - -fail: - CNET_PR("RX: Failed to allocate mem\n"); - - return SHR_E_MEMORY; } /*! @@ -413,6 +417,7 @@ cmicd_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg dma_addr_t addr; uint32_t stat, curr; int len, done = 0; + int retry; int rv; curr = rxq->curr; @@ -438,7 +443,7 @@ cmicd_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg pkh = bm->rx_buf_get(dev, rxq, pbuf, len); if (!pkh) { rxq->stats.nomems++; - goto fail; + return SHR_E_MEMORY; } /* Setup packet header */ @@ -446,7 +451,7 @@ cmicd_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg pkh->meta_len = pbuf->adj; pkh->queue_id = rxq->queue_id; pkh->attrs = CMICD_DESC_STAT_FLAGS(stat); - sal_memcpy(&pbuf->pkb->data, &ring[curr].md, sizeof(struct rx_metadata)); + sal_memcpy(pkh + 1, &ring[curr].md, sizeof(struct rx_metadata)); /* Send up the packet */ rv = dev->pkt_recv(dev, rxq->queue_id, (void *)pbuf->skb); @@ -484,10 +489,18 @@ cmicd_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg /* Setup the new descriptor */ if (!(rxq->state & PDMA_RX_BATCH_REFILL)) { if (!bm->rx_buf_avail(dev, rxq, pbuf)) { - rv = bm->rx_buf_alloc(dev, rxq, pbuf); - if (SHR_FAILURE(rv)) { + retry = 5000000; + do { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_SUCCESS(rv)) { + break; + } rxq->stats.nomems++; - goto fail; + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Fatal error: Rx buffer has not been allocated for 5 seconds\n"); + return done; } } bm->rx_buf_dma(dev, rxq, pbuf, &addr); @@ -553,11 +566,6 @@ cmicd_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg } } - return done; - -fail: - CNET_PR("RX: Failed to allocate mem\n"); - return done; } @@ -663,7 +671,9 @@ cmicd_pdma_tx_ring_clean(struct pdma_hw *hw, struct pdma_tx_queue *txq, int budg /* Resume Tx if any */ sal_spinlock_lock(txq->lock); - if (cmicd_pdma_tx_ring_unused(txq) && txq->state & PDMA_TX_QUEUE_XOFF) { + if (txq->state & PDMA_TX_QUEUE_XOFF && + txq->state & PDMA_TX_QUEUE_ACTIVE && + cmicd_pdma_tx_ring_unused(txq)) { txq->state &= ~PDMA_TX_QUEUE_XOFF; sal_spinlock_unlock(txq->lock); if (dev->tx_resume) { @@ -803,14 +813,14 @@ cmicd_pdma_pkt_xmit(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf) int retry = 5000000; int rv; - if (!(txq->state & PDMA_TX_QUEUE_ACTIVE)) { - return SHR_E_UNAVAIL; - } - if (dev->tx_suspend) { sal_spinlock_lock(txq->mutex); } else { - sal_sem_take(txq->sem, SAL_SEM_FOREVER); + rv = sal_sem_take(txq->sem, BCMCNET_TX_RSRC_WAIT_USEC); + if (rv == -1) { + CNET_PR("Timeout waiting for Tx resources\n"); + return SHR_E_TIMEOUT; + } } /* Check Tx resource */ @@ -856,7 +866,7 @@ cmicd_pdma_pkt_xmit(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf) flags |= pkh->attrs & PDMA_TX_PURGE_PKT ? CMICD_DESC_TX_PURGE_PKT : 0; cmicd_tx_desc_config(&ring[curr], addr, pbuf->len, flags); if (pkh->meta_len) { - sal_memcpy(&ring[curr].md, &pbuf->pkb->data, sizeof(ring->md.data)); + sal_memcpy(&ring[curr].md, pkh + 1, sizeof(ring->md.data)); } } @@ -923,7 +933,8 @@ cmicd_pdma_pkt_xmit(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf) /* In polling mode, must wait till the ring is available */ do { cmicd_pdma_tx_ring_clean(hw, txq, txq->free_thresh); - if (!(txq->state & PDMA_TX_QUEUE_XOFF)) { + if (!(txq->state & PDMA_TX_QUEUE_XOFF) || + !(txq->state & PDMA_TX_QUEUE_ACTIVE)) { break; } sal_usleep(1); diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c index 6dc77c4b7c04..471e65f70682 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_hw.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -103,36 +103,6 @@ cmicx_pdma_intr_disable(struct pdma_hw *hw, int cmc, int chan, uint32_t mask) hw->dev->ctrl.grp[cmc].irq_mask = irq_mask; } -/*! - * Release Packet DMA credits to EP. - */ -static int -cmicx_pdma_credits_release(struct pdma_hw *hw) -{ - int credits; - uint32_t val; - - /* - * Since only 6 bits of iproc_cmic_to_ep_credits[5:0] are being used, - * so we have to set the max credits value twice in order to release - * 64 credits to EP. - * Only do this once when HW is initialized. - */ - hw->hdls.reg_rd32(hw, CMICX_EPINTF_RELEASE_CREDITS, &val); - if (!val) { - credits = 63; - hw->hdls.reg_wr32(hw, CMICX_EPINTF_MAX_CREDITS, (0x1 << 8) | credits); - hw->hdls.reg_wr32(hw, CMICX_EPINTF_RELEASE_CREDITS, 1); - - hw->hdls.reg_wr32(hw, CMICX_EPINTF_RELEASE_CREDITS, 0); - credits = 1; - hw->hdls.reg_wr32(hw, CMICX_EPINTF_MAX_CREDITS, (0x1 << 8) | credits); - hw->hdls.reg_wr32(hw, CMICX_EPINTF_RELEASE_CREDITS, 1); - } - - return SHR_E_NONE; -} - /*! * Initialize HW */ @@ -148,9 +118,6 @@ cmicx_pdma_hw_init(struct pdma_hw *hw) hw->dev->mode = DEV_MODE_UNET; } - /* Release Packet DMA credits to EP. */ - cmicx_pdma_credits_release(hw); - hw->info.name = CMICX_DEV_NAME; hw->info.dev_id = hw->dev->dev_id; hw->info.num_cmcs = CMICX_PDMA_CMC_MAX; @@ -240,12 +207,13 @@ cmicx_pdma_hw_config(struct pdma_hw *hw) hw->hdls.reg_wr32(hw, CMICX_PDMA_CTRL(grp, que), val); } + hw->hdls.reg_rd32(hw, CMICX_TOP_CONFIG, &val); if (ip_if_hdr_endian == 1) { - hw->hdls.reg_rd32(hw, CMICX_TOP_CONFIG, &val); val |= 0x80; - hw->hdls.reg_wr32(hw, CMICX_TOP_CONFIG, val); + } else { + val &= ~0x80; } - + hw->hdls.reg_wr32(hw, CMICX_TOP_CONFIG, val); return SHR_E_NONE; } diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c index 651728465d56..9ea7489b5471 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/hmi/cmicx/bcmcnet_cmicx_pdma_rxtx.c @@ -38,7 +38,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -394,17 +394,26 @@ cmicx_pdma_rx_ring_refill(struct pdma_hw *hw, struct pdma_rx_queue *rxq) int unused = cmicx_pdma_rx_ring_unused(rxq); dma_addr_t addr; uint32_t halt; + int retry; int rv; for (halt = rxq->halt; halt < rxq->halt + unused; halt++) { pbuf = &rxq->pbuf[halt % rxq->nb_desc]; /* Allocate a new pktbuf */ if (!bm->rx_buf_avail(dev, rxq, pbuf)) { - rv = bm->rx_buf_alloc(dev, rxq, pbuf); - if (SHR_FAILURE(rv)) { - rxq->halt = halt % rxq->nb_desc; + retry = 5000000; + do { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_SUCCESS(rv)) { + break; + } rxq->stats.nomems++; - goto fail; + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Fatal error: Rx buffer has not been allocated for 5 seconds\n"); + rxq->halt = halt % rxq->nb_desc; + return rv; } } /* Setup the new descriptor */ @@ -425,11 +434,6 @@ cmicx_pdma_rx_ring_refill(struct pdma_hw *hw, struct pdma_rx_queue *rxq) sal_spinlock_unlock(rxq->lock); return SHR_E_NONE; - -fail: - CNET_PR("RX: Failed to allocate mem\n"); - - return SHR_E_MEMORY; } /*! @@ -453,6 +457,7 @@ cmicx_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg dma_addr_t addr; uint32_t stat, curr; int len, done = 0; + int retry; int rv; curr = rxq->curr; @@ -478,7 +483,7 @@ cmicx_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg pkh = bm->rx_buf_get(dev, rxq, pbuf, len); if (!pkh) { rxq->stats.nomems++; - goto fail; + return SHR_E_MEMORY; } /* Setup packet header */ @@ -520,10 +525,18 @@ cmicx_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg /* Setup the new descriptor */ if (!(rxq->state & PDMA_RX_BATCH_REFILL)) { if (!bm->rx_buf_avail(dev, rxq, pbuf)) { - rv = bm->rx_buf_alloc(dev, rxq, pbuf); - if (SHR_FAILURE(rv)) { + retry = 5000000; + do { + rv = bm->rx_buf_alloc(dev, rxq, pbuf); + if (SHR_SUCCESS(rv)) { + break; + } rxq->stats.nomems++; - goto fail; + sal_usleep(1); + } while (retry--); + if (retry <= 0) { + CNET_PR("Fatal error: Rx buffer has not been allocated for 5 seconds\n"); + return done; } } bm->rx_buf_dma(dev, rxq, pbuf, &addr); @@ -589,11 +602,6 @@ cmicx_pdma_rx_ring_clean(struct pdma_hw *hw, struct pdma_rx_queue *rxq, int budg } } - return done; - -fail: - CNET_PR("RX: Failed to allocate mem\n"); - return done; } @@ -699,7 +707,9 @@ cmicx_pdma_tx_ring_clean(struct pdma_hw *hw, struct pdma_tx_queue *txq, int budg /* Resume Tx if any */ sal_spinlock_lock(txq->lock); - if (cmicx_pdma_tx_ring_unused(txq) && txq->state & PDMA_TX_QUEUE_XOFF) { + if (txq->state & PDMA_TX_QUEUE_XOFF && + txq->state & PDMA_TX_QUEUE_ACTIVE && + cmicx_pdma_tx_ring_unused(txq)) { txq->state &= ~PDMA_TX_QUEUE_XOFF; sal_spinlock_unlock(txq->lock); if (dev->tx_resume) { @@ -839,14 +849,14 @@ cmicx_pdma_pkt_xmit(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf) int retry = 5000000; int rv; - if (!(txq->state & PDMA_TX_QUEUE_ACTIVE)) { - return SHR_E_UNAVAIL; - } - if (dev->tx_suspend) { sal_spinlock_lock(txq->mutex); } else { - sal_sem_take(txq->sem, SAL_SEM_FOREVER); + rv = sal_sem_take(txq->sem, BCMCNET_TX_RSRC_WAIT_USEC); + if (rv == -1) { + CNET_PR("Timeout waiting for Tx resources\n"); + return SHR_E_TIMEOUT; + } } /* Check Tx resource */ @@ -955,7 +965,8 @@ cmicx_pdma_pkt_xmit(struct pdma_hw *hw, struct pdma_tx_queue *txq, void *buf) /* In polling mode, must wait till the ring is available */ do { cmicx_pdma_tx_ring_clean(hw, txq, txq->free_thresh); - if (!(txq->state & PDMA_TX_QUEUE_XOFF)) { + if (!(txq->state & PDMA_TX_QUEUE_XOFF) || + !(txq->state & PDMA_TX_QUEUE_ACTIVE)) { break; } sal_usleep(1); diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicd.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicd.h index ef9717923e70..3e6ccd035c0f 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicd.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicd.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicx.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicx.h index a8657c8b46a9..9d5369784776 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicx.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_cmicx.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_core.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_core.h index 13db809dda36..e421afd0f35a 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_core.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_core.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -66,8 +66,10 @@ struct pkt_hdr { #define PDMA_TX_BIND_QUE (1 << 3) /*! Tx cookded header */ #define PDMA_TX_HDR_COOKED (1 << 4) + /*! Tx no pad */ +#define PDMA_TX_NO_PAD (1 << 5) /*! Tx to HNET */ -#define PDMA_TX_TO_HNET (1 << 5) +#define PDMA_TX_TO_HNET (1 << 6) /*! Rx to VNET */ #define PDMA_RX_TO_VNET (1 << 10) /*! Rx strip vlan tag */ @@ -208,16 +210,16 @@ struct dev_ctrl { struct queue_group grp[NUM_GRP_MAX]; /*! Pointers to Rx queues */ - void *rx_queue[NUM_QUE_MAX]; + void *rx_queue[NUM_Q_MAX]; /*! Pointers to Tx queues */ - void *tx_queue[NUM_QUE_MAX]; + void *tx_queue[NUM_Q_MAX]; /*! Pointers to virtual Rx queues */ - void *vnet_rxq[NUM_QUE_MAX]; + void *vnet_rxq[NUM_Q_MAX]; /*! Pointers to virtual Tx queues */ - void *vnet_txq[NUM_QUE_MAX]; + void *vnet_txq[NUM_Q_MAX]; /*! Pointer to buffer manager */ void *buf_mngr; @@ -742,10 +744,10 @@ typedef void (*sys_tx_resume_f)(struct pdma_dev *dev, int queue); * \param [in] group Channel group number. * \param [in] chan Channel number. * \param [in] reg Interrupt enable register. - * \param [in] mask Interrupt mask. + * \param [in] val Interrupt enable register value. */ typedef void (*sys_intr_unmask_f)(struct pdma_dev *dev, int group, int chan, - uint32_t reg, uint32_t mask); + uint32_t reg, uint32_t val); /*! * Disable interrupts. @@ -753,11 +755,11 @@ typedef void (*sys_intr_unmask_f)(struct pdma_dev *dev, int group, int chan, * \param [in] dev Pointer to device structure. * \param [in] group Channel group number. * \param [in] chan Channel number. - * \param [in] reg Interrupt enable register. - * \param [in] mask Interrupt mask. + * \param [in] reg Interrupt disable register. + * \param [in] val Interrupt disable register value. */ typedef void (*sys_intr_mask_f)(struct pdma_dev *dev, int group, int chan, - uint32_t reg, uint32_t mask); + uint32_t reg, uint32_t val); /*! * Wait for notification from the other side. @@ -893,6 +895,8 @@ struct pdma_dev { #define PDMA_DESC_PREFETCH (1 << 4) /*! VNET is docked */ #define PDMA_VNET_DOCKED (1 << 5) + /*! Abort PDMA mode for suspend and resume */ +#define PDMA_ABORT (1 << 6) /*! Device mode */ dev_mode_t mode; @@ -900,6 +904,9 @@ struct pdma_dev { /*! Device is started */ int started; + /*! Device is started but suspended */ + int suspended; + /*! Device is initialized and HMI driver is attached */ int attached; }; @@ -1261,10 +1268,10 @@ bcmcnet_group_intr_ack(struct pdma_dev *dev, int group); * \param [in] dev Device structure point. * \param [in] group Group number. * - * \retval SHR_E_NONE No errors. - * \retval SHR_E_XXXX Operation failed. + * \retval true Interrupt is active. + * \retval false Interrupt is not active. */ -extern int +extern bool bcmcnet_group_intr_check(struct pdma_dev *dev, int group); /*! diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_dev.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_dev.h index bc3367b34fae..aa1d47876b95 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_dev.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_dev.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_internal.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_internal.h index e4b2051a34bc..f3602e07c098 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_internal.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_internal.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -31,6 +31,9 @@ /*! CMICX name */ #define CMICX_DEV_NAME "cmicx" +/*! CMICR name */ +#define CMICR_DEV_NAME "cmicr" + /*! * \brief Allocate descriptor ring buffer. * @@ -83,10 +86,11 @@ typedef void (*rx_buf_dma_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, * \param [in] rxq Pointer to Rx queue struture. * \param [in] pbuf Pointer to packet buffer structure. * - * \retval Ture Buffer is available or FALSE. + * \retval true Buffer is available. + * \retval false Buffer is not available. */ -typedef int (*rx_buf_avail_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, - struct pdma_rx_buf *pbuf); +typedef bool (*rx_buf_avail_f)(struct pdma_dev *dev, struct pdma_rx_queue *rxq, + struct pdma_rx_buf *pbuf); /*! * \brief Get Rx packet buffer. diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_rxtx.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_rxtx.h index eb5834d895b0..197378108c35 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_rxtx.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_rxtx.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -23,10 +23,15 @@ #ifndef BCMCNET_RXTX_H #define BCMCNET_RXTX_H -/*! Default descriptor number in each ring */ +/*! Default timeout value (us) to wait for Tx resource. */ +#ifndef BCMCNET_TX_RSRC_WAIT_USEC +#define BCMCNET_TX_RSRC_WAIT_USEC 1000000 +#endif + +/*! Default descriptor number in each ring. */ #define NUM_RING_DESC 64 -/*! Maximum number of packets to be handled in one poll call */ +/*! Maximum number of packets to be handled in one poll call. */ #define NUM_RXTX_BUDGET 64 /*! diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_types.h b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_types.h index 42bd9240828b..8992634097c5 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_types.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/include/bcmcnet/bcmcnet_types.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -32,10 +32,10 @@ #define NUM_GRP_MAX 4 /*! Maximum number of queues supported each group */ -#define NUM_Q_PER_GRP 8 +#define NUM_Q_PER_GRP 16 /*! Maximum number of queues supported each device */ -#define NUM_QUE_MAX (NUM_GRP_MAX * NUM_Q_PER_GRP) +#define NUM_Q_MAX (NUM_GRP_MAX * NUM_Q_PER_GRP) /*! Maximum length of jumbo frame */ #define JUMBO_FRAME_LEN_MAX 0xffff @@ -113,13 +113,13 @@ typedef struct bcmcnet_dev_info { uint32_t nb_desc_dflt; /*! Rx buffer size per queue */ - uint32_t rx_buf_size[NUM_QUE_MAX]; + uint32_t rx_buf_size[NUM_Q_MAX]; /*! Number of Rx descriptors per queue */ - uint32_t nb_rx_desc[NUM_QUE_MAX]; + uint32_t nb_rx_desc[NUM_Q_MAX]; /*! Number of Tx descriptors per queue */ - uint32_t nb_tx_desc[NUM_QUE_MAX]; + uint32_t nb_tx_desc[NUM_Q_MAX]; } bcmcnet_dev_info_t; /*! @@ -169,43 +169,43 @@ typedef struct bcmcnet_dev_stats { uint64_t intrs; /*! Number of successfully received packets per queue */ - uint64_t rxq_packets[NUM_QUE_MAX]; + uint64_t rxq_packets[NUM_Q_MAX]; /*! Number of successfully received bytes per queue */ - uint64_t rxq_bytes[NUM_QUE_MAX]; + uint64_t rxq_bytes[NUM_Q_MAX]; /*! Number of dropped packets per queue */ - uint64_t rxq_dropped[NUM_QUE_MAX]; + uint64_t rxq_dropped[NUM_Q_MAX]; /*! Number of erroneous received packets per queue */ - uint64_t rxq_errors[NUM_QUE_MAX]; + uint64_t rxq_errors[NUM_Q_MAX]; /*! Number of error head packets per queue */ - uint64_t rxq_head_errors[NUM_QUE_MAX]; + uint64_t rxq_head_errors[NUM_Q_MAX]; /*! Number of error data packets per queue */ - uint64_t rxq_data_errors[NUM_QUE_MAX]; + uint64_t rxq_data_errors[NUM_Q_MAX]; /*! Number of error cell packets per queue */ - uint64_t rxq_cell_errors[NUM_QUE_MAX]; + uint64_t rxq_cell_errors[NUM_Q_MAX]; /*! Number of RX pktbuf allocation failures per queue */ - uint64_t rxq_nomems[NUM_QUE_MAX]; + uint64_t rxq_nomems[NUM_Q_MAX]; /*! Number of successfully transmitted bytes per queue */ - uint64_t txq_packets[NUM_QUE_MAX]; + uint64_t txq_packets[NUM_Q_MAX]; /*! Number of successfully transmitted bytes per queue */ - uint64_t txq_bytes[NUM_QUE_MAX]; + uint64_t txq_bytes[NUM_Q_MAX]; /*! Number of dropped packets per queue */ - uint64_t txq_dropped[NUM_QUE_MAX]; + uint64_t txq_dropped[NUM_Q_MAX]; /*! Number of failed transmitted packets per queue */ - uint64_t txq_errors[NUM_QUE_MAX]; + uint64_t txq_errors[NUM_Q_MAX]; /*! Number of suspended transmission per queue */ - uint64_t txq_xoffs[NUM_QUE_MAX]; + uint64_t txq_xoffs[NUM_Q_MAX]; } bcmcnet_dev_stats_t; /*! @@ -247,16 +247,16 @@ typedef enum dev_mode_e { */ typedef struct vnet_sync_s { /*! Rx ring address */ - uint64_t rx_ring_addr[NUM_QUE_MAX]; + uint64_t rx_ring_addr[NUM_Q_MAX]; /*! Rx ring size */ - uint32_t rx_ring_size[NUM_QUE_MAX]; + uint32_t rx_ring_size[NUM_Q_MAX]; /*! Tx ring address */ - uint64_t tx_ring_addr[NUM_QUE_MAX]; + uint64_t tx_ring_addr[NUM_Q_MAX]; /*! Tx ring size */ - uint32_t tx_ring_size[NUM_QUE_MAX]; + uint32_t tx_ring_size[NUM_Q_MAX]; } vnet_sync_t; #endif /* BCMCNET_TYPES_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_core.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_core.c index ef4aca7da49e..fec920a935c1 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_core.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_core.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -151,11 +151,33 @@ bcmcnet_pdma_dev_stop(struct pdma_dev *dev) int bcmcnet_pdma_dev_suspend(struct pdma_dev *dev) { + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + int rv; + if (!dev->attached) { return SHR_E_UNAVAIL; } - return dev->ops->dev_suspend(dev); + rv = dev->ops->dev_suspend(dev); + if (SHR_FAILURE(rv)) { + return rv; + } + + dev->suspended = true; + + if (dev->flags & PDMA_ABORT) { + /* Abort all the Tx queues */ + for (qi = 0; qi < ctrl->nb_txq; qi++) { + dev->ops->tx_queue_stop(dev, qi); + } + /* Abort all the Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + dev->ops->rx_queue_stop(dev, qi);; + } + } + + return SHR_E_NONE; } /*! @@ -164,11 +186,46 @@ bcmcnet_pdma_dev_suspend(struct pdma_dev *dev) int bcmcnet_pdma_dev_resume(struct pdma_dev *dev) { + struct dev_ctrl *ctrl = &dev->ctrl; + uint32_t qi; + int rv; + if (!dev->attached) { return SHR_E_UNAVAIL; } - return dev->ops->dev_resume(dev); + if (dev->flags & PDMA_ABORT) { + /* + * H/W configuration of Packet DMA is gone in the FFB apply phase, + * so we need to program it again. + */ + dev->ops->dev_config(dev, ctrl->bm_rxq, ctrl->bm_txq); + + /* Restart all the Rx queues */ + for (qi = 0; qi < ctrl->nb_rxq; qi++) { + dev->ops->rx_queue_release(dev, qi); + dev->ops->rx_queue_setup(dev, qi); + dev->ops->rx_queue_intr_enable(dev, qi); + dev->ops->rx_queue_start(dev, qi); + } + /* Restart all the Tx queues */ + for (qi = 0; qi < ctrl->nb_txq; qi++) { + dev->ops->tx_queue_release(dev, qi); + dev->ops->tx_queue_setup(dev, qi); + dev->ops->tx_queue_intr_enable(dev, qi); + dev->ops->tx_queue_start(dev, qi); + } + dev->flags &= ~PDMA_ABORT; + } + + rv = dev->ops->dev_resume(dev); + if (SHR_FAILURE(rv)) { + return rv; + } + + dev->suspended = false; + + return rv; } /*! @@ -614,7 +671,7 @@ bcmcnet_group_intr_ack(struct pdma_dev *dev, int group) /*! * Check interrupt for a queue group */ -int +bool bcmcnet_group_intr_check(struct pdma_dev *dev, int group) { struct dev_ctrl *ctrl = &dev->ctrl; @@ -623,14 +680,14 @@ bcmcnet_group_intr_check(struct pdma_dev *dev, int group) int i; if (!dev->ops) { - return SHR_E_INTERNAL; + return false; } for (i = 0; i < dev->grp_queues; i++) { if (1 << i & grp->bm_rxq) { dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); if (dev->ops->rx_queue_intr_check(dev, queue)) { - return TRUE; + return true; } } } @@ -639,12 +696,12 @@ bcmcnet_group_intr_check(struct pdma_dev *dev, int group) if (1 << i & grp->bm_txq) { dev->ops->dev_pq_to_lq(dev, i + group * dev->grp_queues, &queue, &dir); if (dev->ops->tx_queue_intr_check(dev, queue)) { - return TRUE; + return true; } } } - return FALSE; + return false; } /*! @@ -653,6 +710,10 @@ bcmcnet_group_intr_check(struct pdma_dev *dev, int group) int bcmcnet_rx_queue_poll(struct pdma_dev *dev, int queue, int budget) { + if (dev->started == 0) { + return SHR_E_NONE; + } + if (!dev->ops || !dev->ops->rx_queue_poll) { return SHR_E_INTERNAL; } @@ -666,6 +727,10 @@ bcmcnet_rx_queue_poll(struct pdma_dev *dev, int queue, int budget) int bcmcnet_tx_queue_poll(struct pdma_dev *dev, int queue, int budget) { + if (dev->started == 0) { + return SHR_E_NONE; + } + if (!dev->ops || !dev->ops->tx_queue_poll) { return SHR_E_INTERNAL; } @@ -679,6 +744,10 @@ bcmcnet_tx_queue_poll(struct pdma_dev *dev, int queue, int budget) int bcmcnet_queue_poll(struct pdma_dev *dev, struct intr_handle *hdl, int budget) { + if (dev->started == 0) { + return SHR_E_NONE; + } + if (hdl->dir == PDMA_Q_RX) { return bcmcnet_rx_queue_poll(dev, hdl->queue, budget); } else { @@ -692,6 +761,10 @@ bcmcnet_queue_poll(struct pdma_dev *dev, struct intr_handle *hdl, int budget) int bcmcnet_group_poll(struct pdma_dev *dev, int group, int budget) { + if (dev->started == 0) { + return SHR_E_NONE; + } + if (!dev->ops || !dev->ops->group_poll) { return SHR_E_INTERNAL; } diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_dev.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_dev.c index 1f39515a7a62..7b0344e83c30 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_dev.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_dev.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -110,6 +110,9 @@ bcn_tx_queues_free(struct pdma_dev *dev) if (!txq) { continue; } + if (txq->sem) { + sal_sem_destroy(txq->sem); + } sal_free(txq); ctrl->grp[gi].tx_queue[qi] = NULL; if (dev->mode == DEV_MODE_HNET && ctrl->grp[gi].vnet_txq[qi]) { @@ -140,6 +143,10 @@ bcn_tx_queues_alloc(struct pdma_dev *dev) txq->group_id = gi; txq->chan_id = qi + gi * dev->grp_queues; txq->ctrl = ctrl; + txq->sem = sal_sem_create("bcmcnetTxMutexSem", SAL_SEM_BINARY, 0); + if (!txq->sem) { + goto error; + } ctrl->grp[gi].tx_queue[qi] = txq; if (dev->mode == DEV_MODE_HNET) { vtxq = sal_alloc(sizeof(*vtxq), "bcmcnetVnetTxQueue"); @@ -610,6 +617,10 @@ bcmcnet_pdma_lq_to_pq(struct pdma_dev *dev, int queue, int dir, int *chan) struct pdma_rx_queue *rxq = NULL; struct pdma_tx_queue *txq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + if (dir == PDMA_Q_RX) { rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; if (rxq->state & PDMA_RX_QUEUE_USED) { @@ -664,8 +675,13 @@ bcmcnet_pdma_rx_queue_start(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; rxq->state |= PDMA_RX_QUEUE_ACTIVE; + rxq->state &= ~PDMA_RX_QUEUE_XOFF; return hw->hdls.chan_start(hw, rxq->chan_id); } @@ -680,8 +696,13 @@ bcmcnet_pdma_rx_queue_stop(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; rxq->state &= ~PDMA_RX_QUEUE_ACTIVE; + rxq->state |= PDMA_RX_QUEUE_XOFF; return hw->hdls.chan_stop(hw, rxq->chan_id); } @@ -696,8 +717,13 @@ bcmcnet_pdma_tx_queue_start(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_tx_queue *txq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; txq->state |= PDMA_TX_QUEUE_ACTIVE; + txq->state &= ~PDMA_TX_QUEUE_XOFF; return dev->flags & PDMA_CHAIN_MODE ? SHR_E_NONE : hw->hdls.chan_start(hw, txq->chan_id); @@ -713,8 +739,13 @@ bcmcnet_pdma_tx_queue_stop(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_tx_queue *txq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; txq->state &= ~PDMA_TX_QUEUE_ACTIVE; + txq->state |= PDMA_TX_QUEUE_XOFF; return hw->hdls.chan_stop(hw, txq->chan_id); } @@ -729,6 +760,10 @@ bcmcnet_pdma_rx_queue_intr_enable(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; return hw->hdls.chan_intr_enable(hw, rxq->chan_id); @@ -744,6 +779,10 @@ bcmcnet_pdma_rx_queue_intr_disable(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; return hw->hdls.chan_intr_disable(hw, rxq->chan_id); @@ -759,6 +798,10 @@ bcmcnet_pdma_rx_queue_intr_ack(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; return hw->hdls.chan_clear(hw, rxq->chan_id); @@ -774,6 +817,10 @@ bcmcnet_pdma_rx_queue_intr_query(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; return hw->hdls.chan_intr_query(hw, rxq->chan_id); @@ -789,6 +836,10 @@ bcmcnet_pdma_rx_queue_intr_check(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; + if ((uint32_t)queue >= NUM_Q_MAX) { + return SHR_E_PARAM; + } + rxq = (struct pdma_rx_queue *)ctrl->rx_queue[queue]; return hw->hdls.chan_intr_check(hw, rxq->chan_id); @@ -987,7 +1038,8 @@ bcmcnet_pdma_rx_queue_int_coalesce(struct pdma_dev *dev, int queue, int count, i struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; - if ((uint32_t)queue >= ctrl->nb_rxq) { + if ((uint32_t)queue >= NUM_Q_MAX || + (uint32_t)queue >= ctrl->nb_rxq) { return SHR_E_PARAM; } @@ -1008,7 +1060,8 @@ bcmcnet_pdma_tx_queue_int_coalesce(struct pdma_dev *dev, int queue, int count, i struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_tx_queue *txq = NULL; - if ((uint32_t)queue >= ctrl->nb_txq) { + if ((uint32_t)queue >= NUM_Q_MAX || + (uint32_t)queue >= ctrl->nb_txq) { return SHR_E_PARAM; } @@ -1029,7 +1082,8 @@ bcmcnet_pdma_rx_queue_reg_dump(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_rx_queue *rxq = NULL; - if ((uint32_t)queue >= ctrl->nb_rxq) { + if ((uint32_t)queue >= NUM_Q_MAX || + (uint32_t)queue >= ctrl->nb_rxq) { return SHR_E_PARAM; } @@ -1048,7 +1102,8 @@ bcmcnet_pdma_tx_queue_reg_dump(struct pdma_dev *dev, int queue) struct pdma_hw *hw = (struct pdma_hw *)ctrl->hw; struct pdma_tx_queue *txq = NULL; - if ((uint32_t)queue >= ctrl->nb_txq) { + if ((uint32_t)queue >= NUM_Q_MAX || + (uint32_t)queue >= ctrl->nb_txq) { return SHR_E_PARAM; } diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_rxtx.c b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_rxtx.c index cfabe9d95d56..41504949876b 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_rxtx.c +++ b/platform/broadcom/saibcm-modules/sdklt/bcmcnet/main/bcmcnet_rxtx.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -97,11 +97,6 @@ bcn_tx_ring_free(struct pdma_tx_queue *txq) struct dev_ctrl *ctrl = txq->ctrl; struct pdma_buf_mngr *bm = (struct pdma_buf_mngr *)ctrl->buf_mngr; - if (txq->sem) { - sal_sem_destroy(txq->sem); - txq->sem = NULL; - } - if (txq->mutex) { sal_spinlock_destroy(txq->mutex); txq->mutex = NULL; @@ -158,11 +153,6 @@ bcn_tx_ring_alloc(struct pdma_tx_queue *txq) goto cleanup; } - txq->sem = sal_sem_create("bcmcnetTxMutexSem", SAL_SEM_BINARY, 0); - if (!txq->sem) { - goto cleanup; - } - return SHR_E_NONE; cleanup: @@ -546,8 +536,8 @@ bcmcnet_pdma_tx_queue_xmit(struct pdma_dev *dev, int queue, void *buf) struct pdma_tx_queue *txq = NULL; txq = (struct pdma_tx_queue *)ctrl->tx_queue[queue]; - if (!txq || !(txq->state & PDMA_TX_QUEUE_ACTIVE)) { - return SHR_E_UNAVAIL; + if (!txq || (!(txq->state & PDMA_TX_QUEUE_ACTIVE) && !dev->suspended)) { + return SHR_E_DISABLED; } return hw->dops.pkt_xmit(hw, txq, buf); diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd/bcmdrd_devlist.h b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd/bcmdrd_devlist.h index 675b9426ea01..4a2384760820 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd/bcmdrd_devlist.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd/bcmdrd_devlist.h @@ -4,7 +4,7 @@ * Edits to this file will be lost when it is regenerated. * Tool: INTERNAL/drd/instpkgs.pl * - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -52,11 +52,21 @@ #define BCM56784_DEVICE_ID 0xb784 #define BCM56784_REV_A0 0x01 +/* BCM56785 */ +#define BCM56785_VENDOR_ID 0x14e4 +#define BCM56785_DEVICE_ID 0xb785 +#define BCM56785_REV_A0 0x01 + /* BCM56786 */ #define BCM56786_VENDOR_ID 0x14e4 #define BCM56786_DEVICE_ID 0xb786 #define BCM56786_REV_A0 0x01 +/* BCM56787 */ +#define BCM56787_VENDOR_ID 0x14e4 +#define BCM56787_DEVICE_ID 0xb787 +#define BCM56787_REV_A0 0x01 + /* BCM56788 */ #define BCM56788_VENDOR_ID 0x14e4 #define BCM56788_DEVICE_ID 0xb788 @@ -85,32 +95,43 @@ #define BCM56883_REV_A0 0x01 #define BCM56883_REV_B0 0x11 -/* BCM56889 */ -#define BCM56889_VENDOR_ID 0x14e4 -#define BCM56889_DEVICE_ID 0xb889 -#define BCM56889_REV_A0 0x01 -#define BCM56889_REV_B0 0x11 - /* BCM56990 */ #define BCM56990_VENDOR_ID 0x14e4 #define BCM56990_DEVICE_ID 0xb990 #define BCM56990_REV_A0 0x01 #define BCM56990_REV_B0 0x11 +/* BCM56991 */ +#define BCM56991_VENDOR_ID 0x14e4 +#define BCM56991_DEVICE_ID 0xb991 +#define BCM56991_REV_B0 0x11 + /* BCM56992 */ #define BCM56992_VENDOR_ID 0x14e4 #define BCM56992_DEVICE_ID 0xb992 #define BCM56992_REV_B0 0x11 +/* BCM56995 */ +#define BCM56995_VENDOR_ID 0x14e4 +#define BCM56995_DEVICE_ID 0xb995 +#define BCM56995_REV_A0 0x01 + /* BCM56996 */ #define BCM56996_VENDOR_ID 0x14e4 #define BCM56996_DEVICE_ID 0xb996 #define BCM56996_REV_A0 0x01 +#define BCM56996_REV_B0 0x11 /* BCM56997 */ #define BCM56997_VENDOR_ID 0x14e4 #define BCM56997_DEVICE_ID 0xb997 #define BCM56997_REV_A0 0x01 +#define BCM56997_REV_B0 0x11 + +/* BCM56998 */ +#define BCM56998_VENDOR_ID 0x14e4 +#define BCM56998_DEVICE_ID 0xb998 +#define BCM56998_REV_A0 0x01 /* * End of Supported Devices and Revisions @@ -173,6 +194,16 @@ BCMDRD_DEVLIST_ENTRY(BCM56784, BCM56784_VENDOR_ID, BCM56784_DEVICE_ID, BCM56784_ #endif #endif +#if BCMDRD_CONFIG_INCLUDE_BCM56785_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56785, BCM56785_VENDOR_ID, BCM56785_DEVICE_ID, BCM56785_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56785_a0, bcm56785_a0, \ + "Trident4-X9", "BCM56780", \ + "5.6 Tb/s 96x50G-PAM4/32x35G-NRZ Programmable Switch w/SmartToR", 0, 0) +#endif +#endif + #if BCMDRD_CONFIG_INCLUDE_BCM56786_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) #ifdef BCMDRD_DEVLIST_INCLUDE_ALL BCMDRD_DEVLIST_ENTRY(BCM56786, BCM56786_VENDOR_ID, BCM56786_DEVICE_ID, BCM56786_REV_A0, \ @@ -183,13 +214,23 @@ BCMDRD_DEVLIST_ENTRY(BCM56786, BCM56786_VENDOR_ID, BCM56786_DEVICE_ID, BCM56786_ #endif #endif +#if BCMDRD_CONFIG_INCLUDE_BCM56787_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56787, BCM56787_VENDOR_ID, BCM56787_DEVICE_ID, BCM56787_REV_A0, \ + 0, 0, \ + bcm56780_a0, bcm56787_a0, bcm56787_a0, \ + "Trident4-X9", "BCM56780", \ + "5.6 Tb/s 96x50G-PAM4/32x35G-NRZ Programmable Switch w/MACsec w/SmartToR", 0, 0) +#endif +#endif + #if BCMDRD_CONFIG_INCLUDE_BCM56788_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) #ifdef BCMDRD_DEVLIST_INCLUDE_ALL BCMDRD_DEVLIST_ENTRY(BCM56788, BCM56788_VENDOR_ID, BCM56788_DEVICE_ID, BCM56788_REV_A0, \ 0, 0, \ bcm56780_a0, bcm56788_a0, bcm56788_a0, \ "Trident4-X9", "BCM56780", \ - "8 Tb/s 160x50G-PAM4 Programmable Switch w/MACsec w/MTop", 0, 0) + "8 Tb/s 160x50G-PAM4 Programmable Switch w/MACsec w/SmartToR", 0, 0) #endif #endif @@ -199,7 +240,7 @@ BCMDRD_DEVLIST_ENTRY(BCM56789, BCM56789_VENDOR_ID, BCM56789_DEVICE_ID, BCM56789_ 0, 0, \ bcm56780_a0, bcm56789_a0, bcm56789_a0, \ "Trident4-X9", "BCM56780", \ - "8 Tb/s 160x50G-PAM4 Programmable Switch w/MTop", 0, 0) + "8 Tb/s 160x50G-PAM4 Programmable Switch w/SmartToR", 0, 0) #endif #endif @@ -261,26 +302,6 @@ BCMDRD_DEVLIST_ENTRY(BCM56883, BCM56883_VENDOR_ID, BCM56883_DEVICE_ID, BCM56883_ #endif #endif -#if BCMDRD_CONFIG_INCLUDE_BCM56889_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) -#ifdef BCMDRD_DEVLIST_INCLUDE_ALL -BCMDRD_DEVLIST_ENTRY(BCM56889, BCM56889_VENDOR_ID, BCM56889_DEVICE_ID, BCM56889_REV_A0, \ - 0, 0, \ - bcm56880_a0, bcm56889_a0, bcm56889_a0, \ - "Trident4", "BCM56880", \ - "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) -#endif -#endif - -#if BCMDRD_CONFIG_INCLUDE_BCM56889_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) -#ifdef BCMDRD_DEVLIST_INCLUDE_ALL -BCMDRD_DEVLIST_ENTRY(BCM56889, BCM56889_VENDOR_ID, BCM56889_DEVICE_ID, BCM56889_REV_B0, \ - 0, 0, \ - bcm56880_a0, bcm56889_a0, bcm56889_b0, \ - "Trident4", "BCM56880", \ - "12.8 Tb/s Switch Fabric 128x100G/64x200G/32x400G Multilayer Switch", 0, 0) -#endif -#endif - #if BCMDRD_CONFIG_INCLUDE_BCM56990_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) BCMDRD_DEVLIST_ENTRY(BCM56990, BCM56990_VENDOR_ID, BCM56990_DEVICE_ID, BCM56990_REV_A0, \ 0, 0, \ @@ -297,6 +318,16 @@ BCMDRD_DEVLIST_ENTRY(BCM56990, BCM56990_VENDOR_ID, BCM56990_DEVICE_ID, BCM56990_ "25.6 Tbps Multilayer Switch", 0, 0) #endif +#if BCMDRD_CONFIG_INCLUDE_BCM56991_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56991, BCM56991_VENDOR_ID, BCM56991_DEVICE_ID, BCM56991_REV_B0, \ + 0, 0, \ + bcm56990_b0, bcm56991_b0, bcm56991_b0, \ + "Tomahawk4", "BCM56990", \ + "25.6 Tbps Multilayer Switch", 0, 0) +#endif +#endif + #if BCMDRD_CONFIG_INCLUDE_BCM56992_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) #ifdef BCMDRD_DEVLIST_INCLUDE_ALL BCMDRD_DEVLIST_ENTRY(BCM56992, BCM56992_VENDOR_ID, BCM56992_DEVICE_ID, BCM56992_REV_B0, \ @@ -307,6 +338,14 @@ BCMDRD_DEVLIST_ENTRY(BCM56992, BCM56992_VENDOR_ID, BCM56992_DEVICE_ID, BCM56992_ #endif #endif +#if BCMDRD_CONFIG_INCLUDE_BCM56995_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56995, BCM56995_VENDOR_ID, BCM56995_DEVICE_ID, BCM56995_REV_A0, \ + 0, 0, \ + bcm56995_a0, bcm56995_a0, bcm56995_a0, \ + "Tomahawk4D", "BCM56995", \ + "25.6 Tbps Multilayer Switch", 0, 0) +#endif + #if BCMDRD_CONFIG_INCLUDE_BCM56996_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) BCMDRD_DEVLIST_ENTRY(BCM56996, BCM56996_VENDOR_ID, BCM56996_DEVICE_ID, BCM56996_REV_A0, \ 0, 0, \ @@ -315,6 +354,14 @@ BCMDRD_DEVLIST_ENTRY(BCM56996, BCM56996_VENDOR_ID, BCM56996_DEVICE_ID, BCM56996_ "25.6 Tbps Multilayer Switch", 0, 0) #endif +#if BCMDRD_CONFIG_INCLUDE_BCM56996_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56996, BCM56996_VENDOR_ID, BCM56996_DEVICE_ID, BCM56996_REV_B0, \ + 0, 0, \ + bcm56996_b0, bcm56996_b0, bcm56996_b0, \ + "Tomahawk4G", "BCM56996", \ + "25.6 Tbps Multilayer Switch", 0, 0) +#endif + #if BCMDRD_CONFIG_INCLUDE_BCM56997_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) #ifdef BCMDRD_DEVLIST_INCLUDE_ALL BCMDRD_DEVLIST_ENTRY(BCM56997, BCM56997_VENDOR_ID, BCM56997_DEVICE_ID, BCM56997_REV_A0, \ @@ -325,6 +372,24 @@ BCMDRD_DEVLIST_ENTRY(BCM56997, BCM56997_VENDOR_ID, BCM56997_DEVICE_ID, BCM56997_ #endif #endif +#if BCMDRD_CONFIG_INCLUDE_BCM56997_B0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +#ifdef BCMDRD_DEVLIST_INCLUDE_ALL +BCMDRD_DEVLIST_ENTRY(BCM56997, BCM56997_VENDOR_ID, BCM56997_DEVICE_ID, BCM56997_REV_B0, \ + 0, 0, \ + bcm56996_b0, bcm56997_b0, bcm56997_b0, \ + "Tomahawk4G", "BCM56996", \ + "12.8 Tbps Multilayer Switch", 0, 0) +#endif +#endif + +#if BCMDRD_CONFIG_INCLUDE_BCM56998_A0 == 1 || defined(BCMDRD_DEVLIST_OVERRIDE) +BCMDRD_DEVLIST_ENTRY(BCM56998, BCM56998_VENDOR_ID, BCM56998_DEVICE_ID, BCM56998_REV_A0, \ + 0, 0, \ + bcm56998_a0, bcm56998_a0, bcm56998_a0, \ + "Tomahawk4GT", "BCM56998", \ + "12.8 Tbps Multilayer Switch", 0, 0) +#endif + /* End BCMDRD_DEVLIST_ENTRY Macros */ #ifdef BCMDRD_DEVLIST_INCLUDE_ALL diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config.h b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config.h index 68e5a0891098..42b1d5619aee 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config.h @@ -1,5 +1,5 @@ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -67,7 +67,7 @@ /* Maximum number of ports per chip supported */ #ifndef BCMDRD_CONFIG_MAX_PORTS -#define BCMDRD_CONFIG_MAX_PORTS 576 +#define BCMDRD_CONFIG_MAX_PORTS 848 #endif /* Maximum number of SCHAN polls */ diff --git a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config_chips.h b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config_chips.h index 5b45879c90e9..41fb6c64a141 100644 --- a/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config_chips.h +++ b/platform/broadcom/saibcm-modules/sdklt/bcmdrd/include/bcmdrd_config_chips.h @@ -4,7 +4,7 @@ * Edits to this file will be lost when it is regenerated. * Tool: INTERNAL/drd/instpkgs.pl * - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -130,6 +130,34 @@ #endif +/* + * BCM56785 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56785 +#define BCMDRD_CONFIG_INCLUDE_BCM56785 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56785_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56785_Ax BCMDRD_CONFIG_INCLUDE_BCM56785 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56785_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56785_A0 BCMDRD_CONFIG_INCLUDE_BCM56785_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56785_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED 1 +#endif +#endif + + /* * BCM56786 */ @@ -158,6 +186,34 @@ #endif +/* + * BCM56787 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56787 +#define BCMDRD_CONFIG_INCLUDE_BCM56787 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56787_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56787_Ax BCMDRD_CONFIG_INCLUDE_BCM56787 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56787_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56787_A0 BCMDRD_CONFIG_INCLUDE_BCM56787_Ax +#endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56787_A0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56780_A0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56780_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56780_A0_IMPLIED 1 +#endif +#endif + + /* * BCM56788 */ @@ -331,66 +387,53 @@ /* - * BCM56889 + * BCM56990 */ /* Sets the default include state if it was not given */ -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889 -#define BCMDRD_CONFIG_INCLUDE_BCM56889 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990 +#define BCMDRD_CONFIG_INCLUDE_BCM56990 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT #endif /* Resolve revision dependencies */ -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_Ax -#define BCMDRD_CONFIG_INCLUDE_BCM56889_Ax BCMDRD_CONFIG_INCLUDE_BCM56889 -#endif -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_A0 -#define BCMDRD_CONFIG_INCLUDE_BCM56889_A0 BCMDRD_CONFIG_INCLUDE_BCM56889_Ax -#endif -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_Bx -#define BCMDRD_CONFIG_INCLUDE_BCM56889_Bx BCMDRD_CONFIG_INCLUDE_BCM56889 -#endif -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56889_B0 -#define BCMDRD_CONFIG_INCLUDE_BCM56889_B0 BCMDRD_CONFIG_INCLUDE_BCM56889_Bx -#endif -/* Resolve all interchip dependencies */ -#if BCMDRD_CONFIG_INCLUDE_BCM56889_A0 == 1 -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 -#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT -#endif -#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 -#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 -#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 -#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56990_Ax BCMDRD_CONFIG_INCLUDE_BCM56990 #endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_A0 BCMDRD_CONFIG_INCLUDE_BCM56990_Ax #endif -#if BCMDRD_CONFIG_INCLUDE_BCM56889_B0 == 1 -#if BCMDRD_CONFIG_INCLUDE_BCM56880_A0 != 1 -#undef BCMDRD_CONFIG_INCLUDE_BCM56880_A0 -#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0 1 -#define BCMDRD_CONFIG_INCLUDE_BCM56880_A0_IMPLIED 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56990_Bx BCMDRD_CONFIG_INCLUDE_BCM56990 #endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0 BCMDRD_CONFIG_INCLUDE_BCM56990_Bx #endif /* - * BCM56990 + * BCM56991 */ /* Sets the default include state if it was not given */ -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990 -#define BCMDRD_CONFIG_INCLUDE_BCM56990 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56991 +#define BCMDRD_CONFIG_INCLUDE_BCM56991 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT #endif /* Resolve revision dependencies */ -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_Ax -#define BCMDRD_CONFIG_INCLUDE_BCM56990_Ax BCMDRD_CONFIG_INCLUDE_BCM56990 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56991_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56991_Bx BCMDRD_CONFIG_INCLUDE_BCM56991 #endif -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_A0 -#define BCMDRD_CONFIG_INCLUDE_BCM56990_A0 BCMDRD_CONFIG_INCLUDE_BCM56990_Ax -#endif -#ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_Bx -#define BCMDRD_CONFIG_INCLUDE_BCM56990_Bx BCMDRD_CONFIG_INCLUDE_BCM56990 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56991_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56991_B0 BCMDRD_CONFIG_INCLUDE_BCM56991_Bx #endif +/* Resolve all interchip dependencies */ +#if BCMDRD_CONFIG_INCLUDE_BCM56991_B0 == 1 #ifndef BCMDRD_CONFIG_INCLUDE_BCM56990_B0 -#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0 BCMDRD_CONFIG_INCLUDE_BCM56990_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56990_B0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56990_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56990_B0_IMPLIED 1 +#endif #endif @@ -422,6 +465,23 @@ #endif +/* + * BCM56995 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56995 +#define BCMDRD_CONFIG_INCLUDE_BCM56995 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56995_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56995_Ax BCMDRD_CONFIG_INCLUDE_BCM56995 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56995_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56995_A0 BCMDRD_CONFIG_INCLUDE_BCM56995_Ax +#endif + + /* * BCM56996 */ @@ -437,6 +497,12 @@ #ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_A0 #define BCMDRD_CONFIG_INCLUDE_BCM56996_A0 BCMDRD_CONFIG_INCLUDE_BCM56996_Ax #endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56996_Bx BCMDRD_CONFIG_INCLUDE_BCM56996 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_B0 BCMDRD_CONFIG_INCLUDE_BCM56996_Bx +#endif /* @@ -454,6 +520,12 @@ #ifndef BCMDRD_CONFIG_INCLUDE_BCM56997_A0 #define BCMDRD_CONFIG_INCLUDE_BCM56997_A0 BCMDRD_CONFIG_INCLUDE_BCM56997_Ax #endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56997_Bx +#define BCMDRD_CONFIG_INCLUDE_BCM56997_Bx BCMDRD_CONFIG_INCLUDE_BCM56997 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56997_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56997_B0 BCMDRD_CONFIG_INCLUDE_BCM56997_Bx +#endif /* Resolve all interchip dependencies */ #if BCMDRD_CONFIG_INCLUDE_BCM56997_A0 == 1 #ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_A0 @@ -465,6 +537,33 @@ #define BCMDRD_CONFIG_INCLUDE_BCM56996_A0_IMPLIED 1 #endif #endif +#if BCMDRD_CONFIG_INCLUDE_BCM56997_B0 == 1 +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56996_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_B0 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +#if BCMDRD_CONFIG_INCLUDE_BCM56996_B0 != 1 +#undef BCMDRD_CONFIG_INCLUDE_BCM56996_B0 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_B0 1 +#define BCMDRD_CONFIG_INCLUDE_BCM56996_B0_IMPLIED 1 +#endif +#endif + + +/* + * BCM56998 + */ + +/* Sets the default include state if it was not given */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56998 +#define BCMDRD_CONFIG_INCLUDE_BCM56998 BCMDRD_CONFIG_INCLUDE_CHIP_DEFAULT +#endif +/* Resolve revision dependencies */ +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56998_Ax +#define BCMDRD_CONFIG_INCLUDE_BCM56998_Ax BCMDRD_CONFIG_INCLUDE_BCM56998 +#endif +#ifndef BCMDRD_CONFIG_INCLUDE_BCM56998_A0 +#define BCMDRD_CONFIG_INCLUDE_BCM56998_A0 BCMDRD_CONFIG_INCLUDE_BCM56998_Ax +#endif #endif /* BCMDRD_CONFIG_CHIPS_H */ @@ -486,9 +585,15 @@ CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56782_A0) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56784) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56784_Ax) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56784_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56785) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56785_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56785_A0) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56786) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56786_Ax) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56786_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56787) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56787_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56787_A0) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56788) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56788_Ax) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56788_A0) @@ -513,11 +618,6 @@ CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_Ax) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_A0) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_Bx) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56883_B0) -CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889) -CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_Ax) -CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_A0) -CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_Bx) -CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56889_B0) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_Ax) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_A0) @@ -529,17 +629,39 @@ CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_A0_IMPLIED) #ifdef BCMDRD_CONFIG_INCLUDE_BCM56990_B0_IMPLIED CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56990_B0_IMPLIED) #endif +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56991) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56991_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56991_B0) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56992) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56992_Bx) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56992_B0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56995) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56995_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56995_A0) +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56995_A0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56995_A0_IMPLIED) +#endif CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_Ax) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_B0) #ifdef BCMDRD_CONFIG_INCLUDE_BCM56996_A0_IMPLIED CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_A0_IMPLIED) #endif +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56996_B0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56996_B0_IMPLIED) +#endif CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997_Ax) CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997_A0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997_Bx) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56997_B0) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56998) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56998_Ax) +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56998_A0) +#ifdef BCMDRD_CONFIG_INCLUDE_BCM56998_A0_IMPLIED +CONFIG_OPTION(BCMDRD_CONFIG_INCLUDE_BCM56998_A0_IMPLIED) +#endif #undef CONFIG_OPTION #endif /* #ifdef CONFIG_OPTION */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Kbuild index 76581c02eed2..928ecdf49b7c 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/Kbuild +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Kbuild @@ -2,7 +2,7 @@ # # Linux kernel BDE module. # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or @@ -31,6 +31,7 @@ linux_ngbde-y := ngbde_main.o \ ngbde_procfs.o \ ngbde_pio.o \ ngbde_iio.o \ + ngbde_paxb.o \ ngbde_dma.o \ ngbde_intr.o \ ngbde_pgmem.o \ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Makefile index 590f4132306f..a20346e4b50b 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/Makefile +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/Makefile @@ -2,7 +2,7 @@ # # Linux kernel BDE module. # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde.h b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde.h index 56e925f7098d..ad1f71031cbe 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -116,9 +116,15 @@ typedef struct ngbde_irq_reg_s { /*! Interrupt status register corresponding to the mask register. */ uint32_t status_reg; + /*! Interrupt status register is a bitwise AND of mask and raw status. */ + bool status_is_masked; + /*! Shared interrupt mask register. */ uint32_t mask_reg; + /*! Mask register is of type "write 1 to clear". */ + bool mask_w1tc; + /*! Mask identifying the register bits owned by the kernel mode driver. */ uint32_t kmask; @@ -213,6 +219,12 @@ typedef struct ngbde_intr_ctrl_s { /*! Context for primary interrupt handler. */ void *isr_data; + /*! Secondary interrupt handler. */ + ngbde_isr_f isr2_func; + + /*! Context for secondary interrupt handler. */ + void *isr2_data; + } ngbde_intr_ctrl_t; /*! Convenience macro for 1 kilobyte. */ @@ -366,6 +378,13 @@ struct ngbde_dev_s { /*! DMA memory pools. */ struct ngbde_dmapool_s dmapool[NGBDE_NUM_DMAPOOL_MAX]; + + /*! KNET handler. */ + knet_func_f knet_func; + + /*! Context for KNET handler. */ + void *knet_data; + }; /*! @@ -817,6 +836,35 @@ ngbde_paxb_unmap(void *devh); extern void ngbde_paxb_cleanup(void); +/*! + * \brief Write a memory-mapped PCI bridge register. + * + * Write a 32-bit register using I/O memory previously mapped via \ref + * ngbde_paxb_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] offs Register address offset. + * \param [in] val Value to write to register. + * + * \return Nothing. + */ +extern void +ngbde_paxb_write32(void *devh, uint32_t offs, uint32_t val); + +/*! + * \brief Read a memory-mapped PCI bridge register. + * + * Read a 32-bit register using I/O memory previously mapped via \ref + * ngbde_paxb_map. + * + * \param [in] devh Device handle (\ref ngbde_dev_s). + * \param [in] offs Register address offset. + * + * \return Value read from register. + */ +extern uint32_t +ngbde_paxb_read32(void *devh, uint32_t offs); + /*! * \brief Probe for Broadcom switch devices on IPROC internal bus. * diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_dma.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_dma.c index 9cc2b191f48c..848664af046e 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_dma.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_dma.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iio.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iio.c index e97f1fcea730..b4ff12b67aaf 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iio.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iio.c @@ -5,7 +5,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -92,52 +92,3 @@ ngbde_iio_read32(void *devh, uint32_t offs) } return 0; } - -void * -ngbde_paxb_map(void *devh, phys_addr_t addr, phys_addr_t size) -{ - struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; - - if (sd->paxb_mem) { - if (addr == sd->paxb_win.addr && size == sd->paxb_win.size) { - /* Already mapped */ - return sd->paxb_mem; - } - iounmap(sd->paxb_mem); - } - - sd->paxb_mem = ioremap_nocache(addr, size); - - if (sd->paxb_mem) { - /* Save mapped resources */ - sd->paxb_win.addr = addr; - sd->paxb_win.size = size; - } - - return sd->paxb_mem; -} - -void -ngbde_paxb_unmap(void *devh) -{ - struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; - - if (sd->paxb_mem) { - iounmap(sd->paxb_mem); - sd->paxb_mem = NULL; - } -} - -void -ngbde_paxb_cleanup(void) -{ - struct ngbde_dev_s *swdev, *sd; - unsigned int num_swdev, idx; - - ngbde_swdev_get_all(&swdev, &num_swdev); - - for (idx = 0; idx < num_swdev; idx++) { - sd = ngbde_swdev_get(idx); - ngbde_paxb_unmap(sd); - } -} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_intr.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_intr.c index acec7da100f7..bc343a7e223e 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_intr.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_intr.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -96,9 +96,12 @@ ngbde_user_isr(ngbde_intr_ctrl_t *ic) kmask = ir->kmask; stat = NGBDE_IOREAD32(&ic->iomem[ir->status_reg]); - mask = NGBDE_IOREAD32(&ic->iomem[ir->mask_reg]); - - if (stat & mask & ~kmask) { + if (!ir->status_is_masked) { + /* Get enabled interrupts by applying mask register */ + mask = NGBDE_IOREAD32(&ic->iomem[ir->mask_reg]); + stat &= mask; + } + if (stat & ~kmask) { active_interrupts = 1; break; } @@ -119,7 +122,13 @@ ngbde_user_isr(ngbde_intr_ctrl_t *ic) if (kmask == 0xffffffff) { /* Kernel driver owns all interrupts in this register */ continue; - } else if (kmask) { + } + if (ir->mask_w1tc) { + /* Clear all interrupt bits which are not in kmask */ + NGBDE_IOWRITE32(~kmask, &ic->iomem[ir->mask_reg]); + continue; + } + if (kmask) { /* Synchronized write */ struct ngbde_dev_s *sd = ngbde_swdev_get(ic->kdev); if (ngbde_intr_shared_write32(sd, ic, ir->mask_reg, 0, ~kmask) < 0) { @@ -159,6 +168,25 @@ ngbde_kernel_isr(ngbde_intr_ctrl_t *ic) return 0; } +/*! + * \brief Interrupt handler for kernel driver. + * + * Typically used by the EDK driver. + * + * \param [in] ic Interrupt control information. + * + * \retval 1 One or more kernel mode interrupts occurred. + * \retval 0 No kernel mode interrupts occurred. + */ +static int +ngbde_kernel_isr2(ngbde_intr_ctrl_t *ic) +{ + if (ic->isr2_func) { + return ic->isr2_func(ic->isr2_data); + } + return 0; +} + /*! * \brief Acknowledge interrupt * @@ -174,9 +202,9 @@ ngbde_intr_ack(ngbde_intr_ctrl_t *ic) if (sd->use_msi) { if (ar->flags & NGBDE_INTR_ACK_F_PAXB) { - NGBDE_IOWRITE32(ar->ack_val, &sd->paxb_mem[ar->ack_reg]); + ngbde_paxb_write32(sd, ar->ack_reg, ar->ack_val); } else { - NGBDE_IOWRITE32(ar->ack_val, &sd->pio_mem[ar->ack_reg]); + ngbde_pio_write32(sd, ar->ack_reg, ar->ack_val); } } @@ -203,6 +231,9 @@ ngbde_isr(int irq_num, void *data) ngbde_intr_ack(ic); + if (ngbde_kernel_isr2(ic)) { + rv = IRQ_HANDLED; + } if (ngbde_user_isr(ic)) { rv = IRQ_HANDLED; } diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_ioctl.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_ioctl.c index ccd0b7ee01d0..4eeeb2438306 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_ioctl.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_ioctl.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -157,6 +157,14 @@ ngbde_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ireg.status_reg = ioc.op.irq_reg_add.status_reg; ireg.mask_reg = ioc.op.irq_reg_add.mask_reg; ireg.kmask = ioc.op.irq_reg_add.kmask; + ireg.status_is_masked = false; + if (ioc.op.irq_reg_add.flags & NGBDE_DEV_IRQ_REG_F_MASKED) { + ireg.status_is_masked = true; + } + ireg.mask_w1tc = false; + if (ioc.op.irq_reg_add.flags & NGBDE_DEV_IRQ_REG_F_W1TC) { + ireg.mask_w1tc = true; + } if (ngbde_intr_reg_add(ioc.devid, irq_num, &ireg) < 0) { printk(KERN_WARNING "%s: Unable to add interrupt register\n", diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iproc_probe.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iproc_probe.c index 63b02a4075a3..6cacb5b0f484 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iproc_probe.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_iproc_probe.c @@ -8,7 +8,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_kapi.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_kapi.c index 340e7b057d44..7775100d952b 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_kapi.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_kapi.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -108,6 +108,24 @@ ngbde_kapi_dma_virt_to_bus(int kdev, void *vaddr) EXPORT_SYMBOL(ngbde_kapi_dma_virt_to_bus); /*! \endcond */ +void * +ngbde_kapi_dma_alloc(size_t size) +{ + return ngbde_pgmem_alloc(size, GFP_KERNEL | GFP_DMA32); +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_dma_alloc); +/*! \endcond */ + +int +ngbde_kapi_dma_free(void *ptr) +{ + return ngbde_pgmem_free(ptr); +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_dma_free); +/*! \endcond */ + void ngbde_kapi_pio_write32(int kdev, uint32_t offs, uint32_t val) { @@ -154,6 +172,98 @@ ngbde_kapi_pio_membase(int kdev) EXPORT_SYMBOL(ngbde_kapi_pio_membase); /*! \endcond */ +void +ngbde_kapi_iio_write32(int kdev, uint32_t offs, uint32_t val) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (sd) { + return ngbde_iio_write32(sd, offs, val); + } +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_iio_write32); +/*! \endcond */ + +uint32_t +ngbde_kapi_iio_read32(int kdev, uint32_t offs) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (sd) { + return ngbde_iio_read32(sd, offs); + } + + return (uint32_t)-1; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_iio_read32); +/*! \endcond */ + +void * +ngbde_kapi_iio_membase(int kdev) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return NULL; + } + + return sd->iio_mem; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_iio_membase); +/*! \endcond */ + +void +ngbde_kapi_paxb_write32(int kdev, uint32_t offs, uint32_t val) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (sd) { + return ngbde_paxb_write32(sd, offs, val); + } +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_paxb_write32); +/*! \endcond */ + +uint32_t +ngbde_kapi_paxb_read32(int kdev, uint32_t offs) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (sd) { + return ngbde_paxb_read32(sd, offs); + } + + return (uint32_t)-1; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_paxb_read32); +/*! \endcond */ + +void * +ngbde_kapi_paxb_membase(int kdev) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return NULL; + } + + return sd->paxb_mem; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_paxb_membase); +/*! \endcond */ + int ngbde_kapi_intr_connect(int kdev, unsigned int irq_num, int (*isr_func)(void *), void *isr_data) @@ -205,6 +315,57 @@ ngbde_kapi_intr_disconnect(int kdev, unsigned int irq_num) EXPORT_SYMBOL(ngbde_kapi_intr_disconnect); /*! \endcond */ +int +ngbde_kapi_intr2_connect(int kdev, unsigned int irq_num, + int (*isr_func)(void *), void *isr_data) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + ic->isr2_func = isr_func; + ic->isr2_data = isr_data; + + return 0; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_intr2_connect); +/*! \endcond */ + +int +ngbde_kapi_intr2_disconnect(int kdev, unsigned int irq_num) +{ + struct ngbde_dev_s *sd; + struct ngbde_intr_ctrl_s *ic; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + + if (irq_num >= NGBDE_NUM_IRQS_MAX) { + return -1; + } + + ic = &sd->intr_ctrl[irq_num]; + ic->isr2_func = NULL; + ic->isr2_data = NULL; + + return 0; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_intr2_disconnect); +/*! \endcond */ + int ngbde_kapi_intr_mask_write(int kdev, unsigned int irq_num, uint32_t status_reg, uint32_t mask_val) @@ -214,3 +375,40 @@ ngbde_kapi_intr_mask_write(int kdev, unsigned int irq_num, /*! \cond */ EXPORT_SYMBOL(ngbde_kapi_intr_mask_write); /*! \endcond */ + +int +ngbde_kapi_knet_connect(int kdev, knet_func_f knet_func, void *knet_data) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + sd->knet_func = knet_func; + sd->knet_data = knet_data; + + return 0; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_knet_connect); +/*! \endcond */ + +int +ngbde_kapi_knet_disconnect(int kdev) +{ + struct ngbde_dev_s *sd; + + sd = ngbde_swdev_get(kdev); + if (!sd) { + return -1; + } + sd->knet_func = NULL; + sd->knet_data = NULL; + + return 0; +} +/*! \cond */ +EXPORT_SYMBOL(ngbde_kapi_knet_disconnect); +/*! \endcond */ + diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_main.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_main.c index 5ce48ebc5134..697412cf5b97 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_main.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_main.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -240,7 +240,7 @@ static struct file_operations fops = { * \return Nothing. */ void __exit -cleanup_module(void) +ngbde_exit_module(void) { ngbde_intr_cleanup(); ngbde_iio_cleanup(); @@ -260,7 +260,7 @@ cleanup_module(void) * \return Nothing. */ int __init -init_module(void) +ngbde_init_module(void) { int rv; @@ -295,3 +295,6 @@ init_module(void) printk(KERN_INFO "Broadcom NGBDE loaded successfully\n"); return 0; } + +module_exit(ngbde_exit_module); +module_init(ngbde_init_module); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_paxb.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_paxb.c new file mode 100644 index 000000000000..e7b582d94106 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_paxb.c @@ -0,0 +1,94 @@ +/*! \file ngbde_paxb.c + * + * API for managing and accessing memory-mapped I/O for PCI-AXI bridge + * registers. + * + */ +/* + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#include + +void * +ngbde_paxb_map(void *devh, phys_addr_t addr, phys_addr_t size) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->paxb_mem) { + if (addr == sd->paxb_win.addr && size == sd->paxb_win.size) { + /* Already mapped */ + return sd->paxb_mem; + } + iounmap(sd->paxb_mem); + } + + sd->paxb_mem = ioremap_nocache(addr, size); + + if (sd->paxb_mem) { + /* Save mapped resources */ + sd->paxb_win.addr = addr; + sd->paxb_win.size = size; + } + + return sd->paxb_mem; +} + +void +ngbde_paxb_unmap(void *devh) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->paxb_mem) { + iounmap(sd->paxb_mem); + sd->paxb_mem = NULL; + } +} + +void +ngbde_paxb_cleanup(void) +{ + struct ngbde_dev_s *swdev, *sd; + unsigned int num_swdev, idx; + + ngbde_swdev_get_all(&swdev, &num_swdev); + + for (idx = 0; idx < num_swdev; idx++) { + sd = ngbde_swdev_get(idx); + ngbde_paxb_unmap(sd); + } +} + +void +ngbde_paxb_write32(void *devh, uint32_t offs, uint32_t val) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->paxb_mem) { + NGBDE_IOWRITE32(val, sd->paxb_mem + offs); + } +} + +uint32_t +ngbde_paxb_read32(void *devh, uint32_t offs) +{ + struct ngbde_dev_s *sd = (struct ngbde_dev_s *)devh; + + if (sd->paxb_mem) { + return NGBDE_IOREAD32(sd->paxb_mem + offs); + } + return 0; +} diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pci_probe.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pci_probe.c index 37da39cd38a7..f444f04fa9f5 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pci_probe.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pci_probe.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -52,6 +52,7 @@ static struct pci_device_id pci_id_table[] = { { BROADCOM_VENDOR_ID, 0xb684, PCI_ANY_ID, PCI_ANY_ID }, { 0, 0, 0, 0 } }; +MODULE_DEVICE_TABLE(pci, pci_id_table); static int pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent) @@ -169,6 +170,10 @@ pci_remove(struct pci_dev* pci_dev) ngbde_swdev_get_all(&swdev, &num_swdev); for (idx = 0; idx < num_swdev; idx++) { + if (swdev[idx].knet_func) { + swdev[idx].knet_func(idx, NGBDE_EVENT_DEV_REMOVE, + swdev->knet_data); + } if (swdev[idx].bus_no == bus_no && swdev[idx].slot_no == slot_no) { if (swdev[idx].inactive) { diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pgmem.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pgmem.c index e473f0c545cb..1283b66e1e19 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pgmem.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pgmem.c @@ -31,7 +31,7 @@ * likely these requests are to succeed. */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pio.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pio.c index cab094a2feca..92b79e79ccba 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pio.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_pio.c @@ -5,7 +5,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_procfs.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_procfs.c index f99339a5b0dc..121dbd0ddf57 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_procfs.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_procfs.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_swdev.c b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_swdev.c index 60d328ad2526..b8d67382f450 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_swdev.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/bde/ngbde_swdev.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/lkm.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/lkm.h index c0ba0a319767..f35550922fed 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/lkm.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/lkm.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_ioctl.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_ioctl.h index b90486ce06f2..84088fb391f7 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_ioctl.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_ioctl.h @@ -9,7 +9,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -225,6 +225,21 @@ struct ngbde_ioc_intr_ctrl_s { __u32 cmd; }; +/*! + * \name Interrupt register access flags. + * \anchor NGBDE_DEV_IRQ_REG_F_xxx + */ + +/*! \{ */ + +/*! IRQ register is of type "write 1 to clear". */ +#define NGBDE_DEV_IRQ_REG_F_W1TC (1 << 0) + +/*! IRQ status register is a bitwise AND of mask and raw status. */ +#define NGBDE_DEV_IRQ_REG_F_MASKED (1 << 1) + +/*! \} */ + /*! Add interrupt register information. */ struct ngbde_ioc_irq_reg_add_s { @@ -240,7 +255,7 @@ struct ngbde_ioc_irq_reg_add_s { /*! Interrupt mask for interrupts handled by the kernel. */ __u32 kmask; - /*! Reserved for future use. */ + /*! Flags for special handling (\ref NGBDE_DEV_IRQ_REG_F_xxx). */ __u32 flags; }; diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_kapi.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_kapi.h index 142aa63b572c..2d908da1f544 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_kapi.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngbde_kapi.h @@ -6,7 +6,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -32,6 +32,21 @@ #define NGBDE_NUM_SWDEV_MAX 16 #endif +/*! Device has been removed. */ +#define NGBDE_EVENT_DEV_REMOVE 1 + +/*! + * \brief KNET handler. + * + * The KNET handler with the Linux kernel. + * + * \param [in] kdev Switch device number. + * \param [in] event PCI event, see NGBDE_EVENT_xxx for event definitions. + * \param [in] data KNET handler context. + * + */ +typedef int (*knet_func_f)(int kdev, int event, void *data); + /*! * \brief Get Linux PCI device handle for a switch device. * @@ -64,7 +79,7 @@ ngbde_kapi_dma_dev_get(int kdev); * * \return Virtual kernel address or NULL on error. */ -void * +extern void * ngbde_kapi_dma_bus_to_virt(int kdev, dma_addr_t baddr); /*! @@ -79,11 +94,46 @@ ngbde_kapi_dma_bus_to_virt(int kdev, dma_addr_t baddr); * * \return Physical DMA bus address for this device or 0 on error. */ -dma_addr_t +extern dma_addr_t ngbde_kapi_dma_virt_to_bus(int kdev, void *vaddr); /*! - * \brief Write a memory-mapped register from kernel driver. + * \brief Allocate physically continguous memory. + * + * This function can be used to allocate a large physically contiguous + * block of memory suitable for DMA operations. + * + * Use the kernel API dma_map_single to map the memory to a physical + * device. A suitable DMA device for this operation can be obtained + * via \ref ngbde_kapi_dma_dev_get. + * + * Memory should be freed via \ref ngbde_kapi_dma_free. + * + * \param [in] size Number of bytes to allocate. + * + * \return Pointer to allocated memory or NULL on error. + */ +extern void * +ngbde_kapi_dma_alloc(size_t size); + +/*! + * \brief Free physically continguous memory. + * + * Free memory previously allocated via \ref ngbde_kapi_dma_alloc. + * + * If the memory has been used for DMA operation, then it must first + * be unmapped via the kernel API dma_unmap_single. + * + * \param [in] ptr Pointer to memory to be freed. + * + * \retval 0 No errors. + * \retval -1 Invalid memory pointer. + */ +extern int +ngbde_kapi_dma_free(void *ptr); + +/*! + * \brief Write a memory-mapped register in kernel driver. * * \param [in] kdev Device number. * \param [in] offs Register address offset. @@ -95,7 +145,7 @@ extern void ngbde_kapi_pio_write32(int kdev, uint32_t offs, uint32_t val); /*! - * \brief Read a memory-mapped register from kernel driver. + * \brief Read a memory-mapped register in kernel driver. * * \param [in] kdev Device number. * \param [in] offs Register address offset. @@ -106,9 +156,9 @@ extern uint32_t ngbde_kapi_pio_read32(int kdev, uint32_t offs); /*! - * \brief Get base address fo memory-mapped I/O memory. + * \brief Get base address of memory-mapped I/O memory. * - * The lgical base address returned can be used with ioread32, etc. + * The logical base address returned can be used with ioread32, etc. * * \param [in] kdev Device number. * @@ -117,11 +167,81 @@ ngbde_kapi_pio_read32(int kdev, uint32_t offs); extern void * ngbde_kapi_pio_membase(int kdev); +/*! + * \brief Write a memory-mapped interrupt controller register. + * + * \param [in] kdev Device number. + * \param [in] offs Register address offset. + * \param [in] val Value to write to register. + * + * \return Nothing. + */ +extern void +ngbde_kapi_iio_write32(int kdev, uint32_t offs, uint32_t val); + +/*! + * \brief Read a memory-mapped interrupt controller register. + * + * \param [in] kdev Device number. + * \param [in] offs Register address offset. + * + * \return Value read from register. + */ +extern uint32_t +ngbde_kapi_iio_read32(int kdev, uint32_t offs); + +/*! + * \brief Get base address of memory-mapped interrupt controller memory. + * + * The logical base address returned can be used with ioread32, etc. + * + * \param [in] kdev Device number. + * + * \return Logical base address or NULL if unavailable. + */ +extern void * +ngbde_kapi_iio_membase(int kdev); + +/*! + * \brief Write a memory-mapped PCI bridge register. + * + * \param [in] kdev Device number. + * \param [in] offs Register address offset. + * \param [in] val Value to write to register. + * + * \return Nothing. + */ +extern void +ngbde_kapi_paxb_write32(int kdev, uint32_t offs, uint32_t val); + +/*! + * \brief Read a memory-mapped PCI bridge register. + * + * \param [in] kdev Device number. + * \param [in] offs Register address offset. + * + * \return Value read from register. + */ +extern uint32_t +ngbde_kapi_paxb_read32(int kdev, uint32_t offs); + +/*! + * \brief Get base address of memory-mapped PCI bridge memory. + * + * The logical base address returned can be used with ioread32, etc. + * + * \param [in] kdev Device number. + * + * \return Logical base address or NULL if unavailable. + */ +extern void * +ngbde_kapi_paxb_membase(int kdev); + /*! * \brief Install kernel mode interrupt handler. * * \param [in] kdev Device number. - * \param [in] irq_num MSI interrupt number. + * \param [in] irq_num Interrupt number (MSI vector). * \param [in] isr_func Interrupt handler function. * \param [in] isr_data Interrupt handler context. * @@ -135,13 +255,41 @@ ngbde_kapi_intr_connect(int kdev, unsigned int irq_num, * \brief Uninstall kernel mode interrupt handler. * * \param [in] kdev Device number. - * \param [in] irq_num MSI interrupt number. + * \param [in] irq_num Interrupt number (MSI vector). * * \retval 0 No errors */ extern int ngbde_kapi_intr_disconnect(int kdev, unsigned int irq_num); +/*! + * \brief Install secondary interrupt handler. + * + * Optionally allow a different process to handle one or more user + * mode interrupts. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * \param [in] isr_func Interrupt handler function. + * \param [in] isr_data Interrupt handler context. + * + * \retval 0 No errors + */ +extern int +ngbde_kapi_intr2_connect(int kdev, unsigned int irq_num, + int (*isr_func)(void *), void *isr_data); + +/*! + * \brief Uninstall secondary interrupt handler. + * + * \param [in] kdev Device number. + * \param [in] irq_num Interrupt number (MSI vector). + * + * \retval 0 No errors + */ +extern int +ngbde_kapi_intr2_disconnect(int kdev, unsigned int irq_num); + /*! * \brief Write shared interrupt mask register. * @@ -166,4 +314,28 @@ extern int ngbde_kapi_intr_mask_write(int kdev, unsigned int irq_num, uint32_t status_reg, uint32_t mask_val); +/*! + * \brief Install KNET callback handler. + * + * Register a callback function to handle BDE events on KNET. + * + * \param [in] kdev Device number. + * \param [in] knet_func KNET callback function. + * \param [in] knet_data Context of KNET callback function. + * + * \retval 0 No errors + */ +extern int +ngbde_kapi_knet_connect(int kdev, knet_func_f knet_func, void *knet_data); + +/*! + * \brief Uninstall KNET callback handler. + * + * \param [in] kdev Device number. + * + * \retval 0 No errors + */ +extern int +ngbde_kapi_knet_disconnect(int kdev); + #endif /* NGBDE_KAPI_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngedk_ioctl.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngedk_ioctl.h new file mode 100644 index 000000000000..7a4c7b5d24a1 --- /dev/null +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngedk_ioctl.h @@ -0,0 +1,183 @@ +/*! \file ngedk_ioctl.h + * + * NGEDK device I/O control definitions. + * + * This file is intended for use in both kernel mode and user mode. + * + * IMPORTANT! + * All shared structures must be properly 64-bit aligned. + * + */ +/* + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. + * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * A copy of the GNU General Public License version 2 (GPLv2) can + * be found in the LICENSES folder.$ + */ + +#ifndef NGEDK_IOCTL_H +#define NGEDK_IOCTL_H + +#include +#include + +/*! Module information */ +#define NGEDK_MODULE_NAME "linux_ngedk" +#define NGEDK_MODULE_MAJOR 119 + +/*! Must be updated if backward compatibility is broken. */ +#define NGEDK_IOC_VERSION 1 + +/*! LUEDK IOCTL command magic. */ +#define NGEDK_IOC_MAGIC 'L' + +/*! Maximum number of mHosts supported per switch device. */ +#ifndef MCS_NUM_UC +#define MCS_NUM_UC 4 +#endif + +/*! + * \name IOCTL commands for the NGEDK kernel module. + * \anchor NGEDK_IOC_xxx + * + * Note that we use __u64 for the IOCTL parameter size because + * sizeof(void *) is different between 32-bit and 64-bit code, and we + * need a 32-bit user mode application to generate the same IOCTL + * command codes as a 64-bit kernel when using the _IOW macro. + */ + +/*! \{ */ + +/*! Get kernel module information. */ +#define NGEDK_IOC_MOD_INFO _IOW(NGEDK_IOC_MAGIC, 0, __u64) + +/*! Attach EDK instance. */ +#define NGEDK_IOC_ATTACH_INST _IOW(NGEDK_IOC_MAGIC, 1, __u64) + +/*! Get EDK DMA memory information. */ +#define NGEDK_IOC_GET_DMA_INFO _IOW(NGEDK_IOC_MAGIC, 2, __u64) + +/*! Enable EDK interrupts in this unit. */ +#define NGEDK_IOC_INTR_ENABLE _IOW(NGEDK_IOC_MAGIC, 3, __u64) + +/*! Disable EDK interrupts in this unit. */ +#define NGEDK_IOC_INTR_DISABLE _IOW(NGEDK_IOC_MAGIC, 4, __u64) + +/*! Set Interrupt registers and mask values used by the EDK. */ +#define NGEDK_IOC_INTR_SET _IOW(NGEDK_IOC_MAGIC, 5, __u64) + +/*! Wait for an EDK interrupt. */ +#define NGEDK_IOC_INTR_WAIT _IOW(NGEDK_IOC_MAGIC, 6, __u64) + +/*! Handle EDK software interrupt. */ +#define NGEDK_IOC_SW_INTR _IOW(NGEDK_IOC_MAGIC, 7, __u64) + +/*! \} */ + +/*! IOCTL command return code for success. */ +#define NGEDK_IOC_SUCCESS 0 + +/*! IOCTL command return code for failure. */ +#define NGEDK_IOC_FAIL ((__u32)-1) + +/*! Kernel module information. */ +struct ngedk_ioc_mod_info_s { + + /*! IOCTL version used by kernel module. */ + __u16 version; +}; + +/*! Attach EDK Instance */ +struct ngedk_ioc_attach_inst_s { + + /*! HostRAM size for this instance. */ + __u32 size_mb; +}; + +/*! Get EDK DMA information */ +struct ngedk_ioc_dma_info_s { + + /*! Virtual address */ + __u64 vaddr; + + /*! Physical address */ + __u64 paddr; + + /*! Bus address as maped by IOMMU */ + __u64 baddr; + + /*! DMA pool size */ + __u32 size; +}; + +/* Set details of interrupts handled by EDK */ +struct ngedk_ioc_intr_s { + + /*! Active cores */ + __u32 active_bmp; + + /*! Timer interrupts status offset */ + __u32 timer_intrc_stat_reg; + + /*! Timer interrupts enable offset */ + __u32 timer_intrc_enable_reg; + + /*! Timer interrupts mask */ + __u32 timer_intrc_mask_val; + + /*! Bitmap of cores that triggered SW interrupt. */ + __u32 sw_intr_cores; +}; + +/*! IOCTL operation data. */ +struct ngedk_ioc_sw_intr_s { + + /*! mHost core number corresponding to this SW interrupt */ + __u32 uc; + +}; + +/*! IOCTL operation data. */ +union ngedk_ioc_op_s { + + /*! Get kernel module information. */ + struct ngedk_ioc_mod_info_s mod_info; + + /*! Attach EDK Instance */ + struct ngedk_ioc_attach_inst_s attach_inst; + + /*! EDK DMA information */ + struct ngedk_ioc_dma_info_s dma_info; + + /*! EDK Interrupt setting */ + struct ngedk_ioc_intr_s edk_intr; + + /*! EDK software interrupt */ + struct ngedk_ioc_sw_intr_s sw_intr; +}; + +/*! IOCTL command message. */ +typedef struct ngedk_ioc_cmd_s { + + /*! Device handle. */ + __u32 devid; + + /*! Return code (0 means success). */ + __u32 rc; + + /*! IOCTL operation. */ + union ngedk_ioc_op_s op; + +} ngedk_ioc_cmd_t; + +#endif /* NGEDK_IOCTL_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_dev.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_dev.h index 74d3d5b350b0..baef36109a4b 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_dev.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_dev.h @@ -9,7 +9,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -168,6 +168,9 @@ typedef struct ngknet_netif_s { * NGKNET_FILTER_DEST_T_VNET * Packet is sent to VNET in user space. * + * NGKNET_FILTER_DEST_T_CB + * Packet is sent to kernel filter call-back function for further filtering. + * * Filter flags: * * NGKNET_FILTER_F_ANY_DATA @@ -198,8 +201,8 @@ typedef struct ngknet_netif_s { #define NGKNET_FILTER_DEST_T_NETIF 1 /*! Send packet to VNET */ #define NGKNET_FILTER_DEST_T_VNET 2 -/*! Send packet to kernel callback function (BCMPKT_DEST_T_CALLBACK) */ -#define NGKNET_FILTER_DEST_T_CB 3 +/*! Send packet to kernel filter call-back function */ +#define NGKNET_FILTER_DEST_T_CB 3 /*! Match any data */ #define NGKNET_FILTER_F_ANY_DATA (1U << 0) @@ -291,6 +294,9 @@ typedef struct ngknet_dev_cfg_s { /*! Device type string */ char type_str[NGKNET_DEV_NAME_MAX]; + /*! Variant string */ + char var_str[NGKNET_DEV_NAME_MAX]; + /*! Device ID */ uint32_t dev_id; @@ -403,6 +409,8 @@ struct ngknet_rcpu_hdr { #define RCPU_FLAG_MODHDR (1 << 2) /*! RCPU bind queue flag */ #define RCPU_FLAG_BIND_QUE (1 << 3) +/*! RCPU no pad flag */ +#define RCPU_FLAG_NO_PAD (1 << 4) #endif /* NGKNET_DEV_H */ diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_ioctl.h b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_ioctl.h index 6da52c778191..42533787f927 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_ioctl.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/include/lkm/ngknet_ioctl.h @@ -9,7 +9,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Kbuild index fe5d5c5bfefc..1f543b8e2ccf 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/Kbuild +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Kbuild @@ -2,7 +2,7 @@ # # Linux KNET module. # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Makefile index 785b81fadb17..2142857ad387 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/Makefile +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/Makefile @@ -2,7 +2,7 @@ # # Linux KNET module. # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or @@ -75,9 +75,12 @@ mklinks: -ln -s $(SRCIDIR)/bcmcnet_rxtx.h $(DSTIDIR) $(R) -ln -s $(SRCIDIR)/bcmcnet_cmicd.h $(DSTIDIR) $(R) -ln -s $(SRCIDIR)/bcmcnet_cmicx.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_cmicr.h $(DSTIDIR) $(R) + -ln -s $(SRCIDIR)/bcmcnet_cmicr_acc.h $(DSTIDIR) $(R) -ln -s $(CNETDIR)/chip/*/*attach.c $(KNETDIR) $(R) -ln -s $(CNETDIR)/hmi/cmicd/*.c $(KNETDIR) $(R) -ln -s $(CNETDIR)/hmi/cmicx/*.c $(KNETDIR) $(R) + -ln -s $(CNETDIR)/hmi/cmicr/*.c $(KNETDIR) $(R) -ln -s $(CNETDIR)/main/bcmcnet_core.c $(KNETDIR) $(R) -ln -s $(CNETDIR)/main/bcmcnet_dev.c $(KNETDIR) $(R) -ln -s $(CNETDIR)/main/bcmcnet_rxtx.c $(KNETDIR) $(R) diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.c index 750fff69caf3..5d92ed016b49 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -109,7 +109,7 @@ bcmcnet_rx_buf_dma(struct pdma_dev *dev, struct pdma_rx_queue *rxq, /*! * Check Rx buffer */ -static int +static bool bcmcnet_rx_buf_avail(struct pdma_dev *dev, struct pdma_rx_queue *rxq, struct pdma_rx_buf *pbuf) { @@ -117,7 +117,7 @@ bcmcnet_rx_buf_avail(struct pdma_dev *dev, struct pdma_rx_queue *rxq, pbuf->skb = NULL; } - return pbuf->dma != 0; + return (pbuf->dma != 0); } /*! @@ -184,6 +184,10 @@ bcmcnet_rx_buf_put(struct pdma_dev *dev, struct pdma_rx_queue *rxq, dev_kfree_skb_any(pbuf->skb); } else { skb = pbuf->skb; + if (pbuf->pkb != (struct pkt_buf *)skb->data) { + dev_kfree_skb_any(skb); + return SHR_E_NONE; + } dma = dma_map_single(kdev->dev, &pbuf->pkb->data + pbuf->adj, rxq->buf_size, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(kdev->dev, dma))) { diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.h index 54768e826917..948815c48304 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_buff.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.c index 21512a51fbd2..8f4ea5aa3f8f 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -34,14 +34,30 @@ ngknet_callback_control_get(struct ngknet_callback_ctrl **cbc) /*! * Call-back interfaces for other Linux kernel drivers. - * - * The Rx call-back allows an external module to modify packet contents - * before it is handed off to the Linux network stack. - * - * The Tx call-back allows an external module to modify packet contents - * before it is injected into the switch. */ +int +ngknet_dev_init_cb_register(ngknet_dev_init_cb_f dev_init_cb) +{ + if (callback_ctrl.dev_init_cb != NULL) { + return -1; + } + callback_ctrl.dev_init_cb = dev_init_cb; + + return 0; +} + +int +ngknet_dev_init_cb_unregister(ngknet_dev_init_cb_f dev_init_cb) +{ + if (dev_init_cb == NULL || callback_ctrl.dev_init_cb != dev_init_cb) { + return -1; + } + callback_ctrl.dev_init_cb = NULL; + + return 0; +} + int ngknet_rx_cb_register(ngknet_rx_cb_f rx_cb) { @@ -86,6 +102,28 @@ ngknet_tx_cb_unregister(ngknet_tx_cb_f tx_cb) return 0; } +int +ngknet_filter_cb_register(ngknet_filter_cb_f filter_cb) +{ + if (callback_ctrl.filter_cb != NULL) { + return -1; + } + callback_ctrl.filter_cb = filter_cb; + + return 0; +} + +int +ngknet_filter_cb_unregister(ngknet_filter_cb_f filter_cb) +{ + if (filter_cb == NULL || callback_ctrl.filter_cb != filter_cb) { + return -1; + } + callback_ctrl.filter_cb = NULL; + + return 0; +} + int ngknet_ptp_rx_config_set_cb_register(ngknet_ptp_config_set_cb_f ptp_rx_config_set_cb) { @@ -291,10 +329,14 @@ ngknet_netif_destroy_cb_unregister(ngknet_netif_cb_f netif_cb) return 0; } +EXPORT_SYMBOL(ngknet_dev_init_cb_register); +EXPORT_SYMBOL(ngknet_dev_init_cb_unregister); EXPORT_SYMBOL(ngknet_rx_cb_register); EXPORT_SYMBOL(ngknet_rx_cb_unregister); EXPORT_SYMBOL(ngknet_tx_cb_register); EXPORT_SYMBOL(ngknet_tx_cb_unregister); +EXPORT_SYMBOL(ngknet_filter_cb_register); +EXPORT_SYMBOL(ngknet_filter_cb_unregister); EXPORT_SYMBOL(ngknet_ptp_rx_config_set_cb_register); EXPORT_SYMBOL(ngknet_ptp_rx_config_set_cb_unregister); EXPORT_SYMBOL(ngknet_ptp_tx_config_set_cb_register); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.h index 54583adffa36..abc78aa1874f 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_callback.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -53,13 +53,14 @@ struct ngknet_callback_desc { /*! Packet data length */ int pkt_len; - - /*! Matched callback filter */ - struct ngknet_filter_s *filt_cb; }; #define NGKNET_SKB_CB(_skb) ((struct ngknet_callback_desc *)_skb->cb) +/*! TX/RX callback init */ +typedef void +(*ngknet_dev_init_cb_f)(const struct ngknet_dev *dev); + /*! Handle Rx packet */ typedef struct sk_buff * (*ngknet_rx_cb_f)(struct sk_buff *skb); @@ -68,6 +69,10 @@ typedef struct sk_buff * typedef struct sk_buff * (*ngknet_tx_cb_f)(struct sk_buff *skb); +/*! Handle Filter callback */ +typedef struct sk_buff * +(*ngknet_filter_cb_f)(struct sk_buff *skb, ngknet_filter_t **filt); + /*! PTP Rx/Tx config set */ typedef int (*ngknet_ptp_config_set_cb_f)(struct ngknet_private *priv, int *value); @@ -96,12 +101,18 @@ typedef int * \brief NGKNET callback control. */ struct ngknet_callback_ctrl { + /*! Handle TX/RX callback initialization. */ + ngknet_dev_init_cb_f dev_init_cb; + /*! Handle Rx packet */ ngknet_rx_cb_f rx_cb; /*! Handle Tx packet */ ngknet_tx_cb_f tx_cb; + /*! Handle filter callback */ + ngknet_filter_cb_f filter_cb; + /*! PTP Rx config set */ ngknet_ptp_config_set_cb_f ptp_rx_config_set_cb; @@ -140,6 +151,36 @@ struct ngknet_callback_ctrl { extern int ngknet_callback_control_get(struct ngknet_callback_ctrl **cbc); +/*! + * \brief Register TX/RX callback device initialization callback function. + * + * The device initialization callback allows an external module to + * perform device-specific initialization in preparation for Tx and Rx + * packet processing. + * + * \param [in] dev_init_cb TX/RX callback device initialization callback + * function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_dev_init_cb_register(ngknet_dev_init_cb_f dev_init_cb); + +/*! + * \brief Unegister TX/RX callback device initialization callback function. + * + * The device initialization callback allows an external module to + * perform device-specific initialization in preparation for Tx and Rx + * packet processing. + * + * \param [in] dev_init_cb TX/RX callback device initialization callback + * function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_dev_init_cb_unregister(ngknet_dev_init_cb_f dev_init_cb); + /*! * \brief Register Rx callback. * @@ -180,6 +221,26 @@ ngknet_tx_cb_register(ngknet_tx_cb_f tx_cb); extern int ngknet_tx_cb_unregister(ngknet_tx_cb_f tx_cb); +/*! + * \brief Register filter callback. + * + * \param [in] filter_cb Filter callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_filter_cb_register(ngknet_filter_cb_f filter_cb); + +/*! + * \brief Unregister filter callback. + * + * \param [in] filter_cb Filter callback function. + * + * \retval SHR_E_NONE No errors. + */ +extern int +ngknet_filter_cb_unregister(ngknet_filter_cb_f filter_cb); + /*! * \brief Register PTP Rx config set callback. * diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_dep.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_dep.h index 919dd6450340..4590a7a6f402 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_dep.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_dep.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -26,13 +26,6 @@ #include #include -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - /*! Memorry barrier */ #define MEMORY_BARRIER smp_mb() diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.c index 00fdb3da8849..2124cd16f6fd 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -50,6 +50,9 @@ #include "ngknet_extra.h" #include "ngknet_callback.h" +/*! Defalut Rx tick for Rx rate limit control. */ +#define NGKNET_EXTRA_RATE_LIMIT_DEFAULT_RX_TICK 10 + static struct ngknet_rl_ctrl rl_ctrl; int @@ -72,7 +75,7 @@ ngknet_filter_create(struct ngknet_dev *dev, ngknet_filter_t *filter) case NGKNET_FILTER_DEST_T_NULL: case NGKNET_FILTER_DEST_T_NETIF: case NGKNET_FILTER_DEST_T_VNET: - case NGKNET_FILTER_DEST_T_CB: /* SDKLT-26907: support NGKNET_FILTER_DEST_T_CB */ + case NGKNET_FILTER_DEST_T_CB: break; default: return SHR_E_UNAVAIL; @@ -260,10 +263,13 @@ ngknet_rx_pkt_filter(struct ngknet_dev *dev, struct sk_buff *skb, struct net_dev unsigned long flags; int wsize; int chan_id; - int idx, match = 0, match_cb = 0; + int rv, idx, match = 0, match_cb = 0; - bcmcnet_pdma_dev_queue_to_chan(&dev->pdma_dev, pkb->pkh.queue_id, - PDMA_Q_RX, &chan_id); + rv = bcmcnet_pdma_dev_queue_to_chan(&dev->pdma_dev, pkb->pkh.queue_id, + PDMA_Q_RX, &chan_id); + if (SHR_FAILURE(rv)) { + return rv; + } spin_lock_irqsave(&dev->lock, flags); @@ -317,6 +323,26 @@ ngknet_rx_pkt_filter(struct ngknet_dev *dev, struct sk_buff *skb, struct net_dev if (match) { fc->hits++; + if (filt->dest_type == NGKNET_FILTER_DEST_T_CB) { + struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); + struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; + if (!dev->cbc->filter_cb) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_UNAVAIL; + } + cbd->dev_no = dev->dev_no; + cbd->dev_id = dev->pdma_dev.dev_id; + cbd->type_str = dev->type_str; + cbd->pmd = skb->data + PKT_HDR_SIZE; + cbd->pmd_len = pkh->meta_len; + cbd->pkt_len = pkh->data_len; + cbd->filt = filt; + skb = dev->cbc->filter_cb(skb, &filt); + if (!skb || !filt) { + spin_unlock_irqrestore(&dev->lock, flags); + return SHR_E_UNAVAIL; + } + } switch (filt->dest_type) { case NGKNET_FILTER_DEST_T_NETIF: if (filt->dest_id == 0) { @@ -369,8 +395,8 @@ ngknet_rx_pkt_filter(struct ngknet_dev *dev, struct sk_buff *skb, struct net_dev NGKNET_SKB_CB(skb)->filt = filt; /* Add callback filter if matched */ - if (match_cb) { - NGKNET_SKB_CB(skb)->filt_cb = filt_cb; + if (priv) { + priv->filt_cb = match_cb? filt_cb : NULL; } } @@ -431,7 +457,7 @@ void ngknet_rx_rate_limit_init(struct ngknet_dev *devs) { sal_memset(&rl_ctrl, 0, sizeof(rl_ctrl)); - rl_ctrl.rx_ticks = 10; + rl_ctrl.rx_ticks = NGKNET_EXTRA_RATE_LIMIT_DEFAULT_RX_TICK; setup_timer(&rl_ctrl.timer, ngknet_rl_process, (timer_context_t)&rl_ctrl); spin_lock_init(&rl_ctrl.lock); rl_ctrl.devs = devs; @@ -480,6 +506,13 @@ ngknet_rx_rate_limit(struct ngknet_dev *dev, int limit) { unsigned long flags; + /* To support lower rate, we should use smaller tick (larger interval). */ + if (limit < 1000) { + rl_ctrl.rx_ticks = (limit + 99) / 100; + } else { + rl_ctrl.rx_ticks = NGKNET_EXTRA_RATE_LIMIT_DEFAULT_RX_TICK; + } + spin_lock_irqsave(&rl_ctrl.lock, flags); if ((++rl_ctrl.rx_pkts + rl_ctrl.rx_overruns > limit / rl_ctrl.rx_ticks) && !rl_ctrl.dev_paused[dev->dev_no] && rl_ctrl.dev_active[dev->dev_no]) { diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.h index 27dea9e368e7..f9ef71f118d9 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_extra.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c index 0162ae5b96c1..7f925af8fde4 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.h index 686aac8f5571..94847dc71b67 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_linux.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.c index b8af31d85ff2..ec56bd6066a1 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -193,7 +193,7 @@ struct ngknet_intr_handle { int napi_pending; }; -static struct ngknet_intr_handle priv_hdl[NUM_PDMA_DEV_MAX][NUM_QUE_MAX]; +static struct ngknet_intr_handle priv_hdl[NUM_PDMA_DEV_MAX][NUM_Q_MAX]; /*! * Dump packet content for debug @@ -236,23 +236,40 @@ ngknet_pkt_stats(struct pdma_dev *pdev, int dir) static struct timeval tv0[2], tv1[2]; static uint32_t pkts[2] = {0}, prts[2] = {0}; static uint64_t intrs = 0; + uint32_t iv_time; + uint32_t pps; + uint32_t boudary; + + if (rx_rate_limit == -1 || rx_rate_limit >= 100000) { + /* Dump every 100K packets */ + boudary = 100000; + } else if (rx_rate_limit >= 10000) { + /* Dump every 10K packets */ + boudary = 10000; + } else { + /* Dump every 1K packets */ + boudary = 1000; + } if (pkts[dir] == 0) { kal_time_val_get(&tv0[dir]); intrs = pdev->stats.intrs; } - if (++pkts[dir] >= 100000) { - uint32_t iv_time; - uint32_t pps; + if (++pkts[dir] >= boudary) { kal_time_val_get(&tv1[dir]); iv_time = (tv1[dir].tv_sec - tv0[dir].tv_sec) * 1000000 + (tv1[dir].tv_usec - tv0[dir].tv_usec); - pps = 100000 * 1000 / (iv_time / 1000); + pps = boudary * 1000 / (iv_time / 1000); prts[dir]++; - if (pps <= 100000 || prts[dir] * 100000 >= pps) { - printk(KERN_CRIT "%s -- limit: %d pps, 100K pkts time: %d usec, rate: %d pps, intrs: %llu\n", + /* pdev->stats.intrs is reset and re-count from 0. */ + if (intrs > pdev->stats.intrs) { + intrs = 0; + } + if (pps <= boudary || prts[dir] * boudary >= pps) { + printk(KERN_CRIT "%s - limit: %d pps, %dK pkts time: %d usec, " + "rate: %d pps, intrs: %llu\n", dir == PDMA_Q_RX ? "Rx" : "Tx", - dir == PDMA_Q_RX ? rx_rate_limit : -1, + dir == PDMA_Q_RX ? rx_rate_limit : -1, (boudary / 1000), iv_time, pps, pdev->stats.intrs - intrs); prts[dir] = 0; } @@ -357,12 +374,15 @@ ngknet_rx_frame_process(struct net_device *ndev, struct sk_buff **oskb) skb_pull(skb, PKT_HDR_SIZE + meta_len); } + /* Check to ensure ngknet_callback_desc struct fits in sk_buff->cb */ + BUILD_BUG_ON(sizeof(struct ngknet_callback_desc) > sizeof(skb->cb)); + /* Optional callback handle */ if (dev->cbc->rx_cb) { struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); cbd->dev_no = dev->dev_no; cbd->dev_id = dev->pdma_dev.dev_id; - cbd->type_str = drv_ops[dev->pdma_dev.dev_type]->drv_desc; + cbd->type_str = dev->type_str; cbd->priv = priv; if (priv->flags & NGKNET_NETIF_F_RCPU_ENCAP) { cbd->pmd = skb->data + PKT_HDR_SIZE; @@ -409,7 +429,7 @@ ngknet_netif_recv(struct net_device *ndev, struct sk_buff *skb) struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; struct napi_struct *napi = NULL; uint16_t proto; - int chan, gi, qi; + int chan_id, gi, qi, skb_len; int rv; /* Handle one incoming packet */ @@ -449,19 +469,26 @@ ngknet_netif_recv(struct net_device *ndev, struct sk_buff *skb) skb_record_rx_queue(skb, pkh->queue_id); - bcmcnet_pdma_dev_queue_to_chan(pdev, pkh->queue_id, PDMA_Q_RX, &chan); - gi = chan / pdev->grp_queues; + rv = bcmcnet_pdma_dev_queue_to_chan(pdev, pkh->queue_id, PDMA_Q_RX, &chan_id); + if (SHR_FAILURE(rv)) { + return rv; + } + + gi = chan_id / pdev->grp_queues; if (pdev->flags & PDMA_GROUP_INTR) { napi = (struct napi_struct *)pdev->ctrl.grp[gi].intr_hdl[0].priv; } else { qi = pkh->queue_id; napi = (struct napi_struct *)pdev->ctrl.grp[gi].intr_hdl[qi].priv; } + + /* FIXME: File CSP on KASAN warning on use-after-free in ngknet_netif_recv */ + skb_len = skb->len; napi_gro_receive(napi, skb); /* Update accounting */ priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; + priv->stats.rx_bytes += skb_len; /* Rate limit */ if (rx_rate_limit >= 0) { @@ -500,6 +527,8 @@ ngknet_frame_recv(struct pdma_dev *pdev, int queue, void *buf) ngknet_pkt_dump(skb->data, skb->len); } + DBG_NDEV(("Valid virtual network devices: %ld.\n", (long)dev->vdev[0])); + /* Go through the filters */ rv = ngknet_rx_pkt_filter(dev, skb, &ndev, &mndev, &mskb); if (SHR_FAILURE(rv) || !ndev) { @@ -640,7 +669,7 @@ ngknet_tx_frame_process(struct net_device *ndev, struct sk_buff **oskb) struct pkt_hdr *pkh = (struct pkt_hdr *)skb->data; struct sk_buff *nskb = NULL; char *data = NULL; - uint32_t copy_len, meta_len, data_len, pkt_len, tag_len; + uint32_t copy_len, meta_len, data_len, pkt_len, tag_len, pad_len; uint16_t tpid; /* Set up packet header */ @@ -649,13 +678,13 @@ ngknet_tx_frame_process(struct net_device *ndev, struct sk_buff **oskb) data_len = pkh->attrs & PDMA_TX_HDR_COOKED ? pkh->data_len - ETH_FCS_LEN : ntohs(rch->data_len); pkt_len = PKT_HDR_SIZE + rch->meta_len + data_len; - if (skb->len != pkt_len || skb->len < (PKT_HDR_SIZE + 14)) { - DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); - return SHR_E_FAIL; + if (skb->len != pkt_len || skb->len < (PKT_HDR_SIZE + ETH_HLEN)) { + DBG_WARN(("Tx drop: Invalid packet length\n")); + return SHR_E_PARAM; } if (dev->rcpu_ctrl.pkt_sig && dev->rcpu_ctrl.pkt_sig != ntohs(rch->pkt_sig)) { - DBG_WARN(("Tx drop: Invalid RCPU signature\n")); - return SHR_E_FAIL; + DBG_WARN(("Tx drop: Invalid packet signature\n")); + return SHR_E_PARAM; } if (pkh->attrs & PDMA_TX_HDR_COOKED) { /* Resumed packet */ @@ -676,6 +705,9 @@ ngknet_tx_frame_process(struct net_device *ndev, struct sk_buff **oskb) if (rch->flags & RCPU_FLAG_BIND_QUE) { pkh->attrs |= PDMA_TX_BIND_QUE; } + if (rch->flags & RCPU_FLAG_NO_PAD) { + pkh->attrs |= PDMA_TX_NO_PAD; + } } else { /* Non-RCPU encapsulation packet */ data_len = pkh->data_len - ETH_FCS_LEN; @@ -756,7 +788,7 @@ ngknet_tx_frame_process(struct net_device *ndev, struct sk_buff **oskb) struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); cbd->dev_no = dev->dev_no; cbd->dev_id = dev->pdma_dev.dev_id; - cbd->type_str = drv_ops[dev->pdma_dev.dev_type]->drv_desc; + cbd->type_str = dev->type_str; cbd->priv = priv; cbd->pmd = skb->data + PKT_HDR_SIZE; cbd->pmd_len = pkh->meta_len; @@ -773,9 +805,10 @@ ngknet_tx_frame_process(struct net_device *ndev, struct sk_buff **oskb) } /* Pad packet if needed */ - if (pkh->data_len < (64 + tag_len)) { - pkh->data_len = 64 + tag_len; - if (skb_padto(skb, PKT_HDR_SIZE + pkh->meta_len + pkh->data_len - ETH_FCS_LEN)) { + pad_len = ETH_ZLEN + ETH_FCS_LEN + tag_len; + if (pkh->data_len < pad_len && !(pkh->attrs & PDMA_TX_NO_PAD)) { + pkh->data_len = pad_len; + if (skb_padto(skb, PKT_HDR_SIZE + pkh->meta_len + pkh->data_len)) { if (!nskb) { *oskb = NULL; } @@ -847,10 +880,13 @@ ngknet_tx_resume(struct pdma_dev *pdev, int queue) */ static void ngknet_intr_enable(struct pdma_dev *pdev, int cmc, int chan, - uint32_t reg, uint32_t mask) + uint32_t reg, uint32_t val) { - pdev->ctrl.grp[cmc].irq_mask |= mask; - ngbde_kapi_intr_mask_write(pdev->unit, 0, reg, pdev->ctrl.grp[cmc].irq_mask); + if (val) { + ngbde_kapi_iio_write32(pdev->unit, reg, val); + } else { + ngbde_kapi_intr_mask_write(pdev->unit, 0, reg, pdev->ctrl.grp[cmc].irq_mask); + } } /*! @@ -858,10 +894,13 @@ ngknet_intr_enable(struct pdma_dev *pdev, int cmc, int chan, */ static void ngknet_intr_disable(struct pdma_dev *pdev, int cmc, int chan, - uint32_t reg, uint32_t mask) + uint32_t reg, uint32_t val) { - pdev->ctrl.grp[cmc].irq_mask &= ~mask; - ngbde_kapi_intr_mask_write(pdev->unit, 0, reg, pdev->ctrl.grp[cmc].irq_mask); + if (val) { + ngbde_kapi_iio_write32(pdev->unit, reg, val); + } else { + ngbde_kapi_intr_mask_write(pdev->unit, 0, reg, pdev->ctrl.grp[cmc].irq_mask); + } } /*! @@ -1277,23 +1316,22 @@ ngknet_start_xmit(struct sk_buff *skb, struct net_device *ndev) rv = pdev->pkt_xmit(pdev, queue, skb); - if (rv == SHR_E_UNAVAIL) { - DBG_WARN(("Tx drop: DMA device not ready\n")); - priv->stats.tx_dropped++; - if (skb != bskb) { - dev_kfree_skb_any(skb); - } - dev_kfree_skb_any(bskb); - return NETDEV_TX_OK; - } - if (rv == SHR_E_BUSY) { - DBG_WARN(("Tx suspend: No DMA resources\n")); + DBG_WARN(("Tx suspend: DMA device is busy and temporarily " + "unavailable.\n")); priv->stats.tx_fifo_errors++; if (skb != bskb) { dev_kfree_skb_any(skb); } return NETDEV_TX_BUSY; + } else if (rv != SHR_E_NONE) { + DBG_WARN(("Tx drop: DMA device not ready or not supported.\n")); + priv->stats.tx_dropped++; + if (skb != bskb) { + dev_kfree_skb_any(skb); + } + dev_kfree_skb_any(bskb); + return NETDEV_TX_OK; } else { if (skb != bskb) { dev_kfree_skb_any(bskb); @@ -1351,7 +1389,7 @@ ngknet_change_mtu(struct net_device *ndev, int new_mtu) { int frame_size = new_mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; - if (frame_size < 68 || frame_size > rx_buffer_size) { + if (frame_size < (ETH_ZLEN + ETH_FCS_LEN) || frame_size > rx_buffer_size) { return -EINVAL; } @@ -1536,7 +1574,7 @@ ngknet_ndev_init(ngknet_netif_t *netif, struct net_device **nd) return SHR_E_PARAM; } - ndev = alloc_etherdev_mq(sizeof(struct ngknet_private), NUM_QUE_MAX); + ndev = alloc_etherdev_mq(sizeof(struct ngknet_private), NUM_Q_MAX); if (!ndev) { DBG_WARN(("Error allocating network device.\n")); return SHR_E_MEMORY; @@ -1596,6 +1634,22 @@ ngknet_ndev_init(ngknet_netif_t *netif, struct net_device **nd) return SHR_E_NONE; } +static int +ngknet_dev_remove(int dn); + +static int +ngknet_bde_event_handler(int kdev, int event, void *data) +{ + DBG_VERB(("%s: callback from BDE with kdev(%d) event(%d).\n", + __FUNCTION__, kdev, event)); + + if (event == NGBDE_EVENT_DEV_REMOVE) { + ngknet_dev_remove(kdev); + } + + return SHR_E_NONE; +} + /*! * \brief Initialize Packet DMA device. * @@ -1678,6 +1732,9 @@ ngknet_dev_info_get(int dn) } dev->dev_no = dn; + strlcpy(dev->type_str, + drv_ops[dev->pdma_dev.dev_type]->drv_desc, + sizeof(dev->type_str)); return SHR_E_NONE; } @@ -1730,6 +1787,11 @@ ngknet_dev_probe(int dn, ngknet_netif_t *netif) } } + if (netif->chan >= NUM_Q_MAX) { + DBG_WARN(("Exceed max number of queues : %d.\n", netif->chan)); + return SHR_E_PARAM; + } + rv = ngknet_ndev_init(netif, &ndev); if (SHR_FAILURE(rv)) { bcmcnet_pdma_dev_cleanup(pdev); @@ -1810,6 +1872,9 @@ ngknet_dev_probe(int dn, ngknet_netif_t *netif) DBG_NDEV(("MAC: %pM\n", ndev->dev_addr)); DBG_NDEV(("Running with NAPI enabled\n")); + /* Register handler for BDE events. */ + ngbde_kapi_knet_connect(dn, ngknet_bde_event_handler, dev); + return SHR_E_NONE; } @@ -1835,6 +1900,7 @@ ngknet_dev_remove(int dn) int rv; if (!(dev->flags & NGKNET_DEV_ACTIVE)) { + ngbde_kapi_knet_disconnect(dn); return SHR_E_NONE; } @@ -1873,7 +1939,7 @@ ngknet_dev_remove(int dn) unregister_netdev(ndev); free_netdev(ndev); - for (qi = 0; qi < NUM_QUE_MAX; qi++) { + for (qi = 0; qi < NUM_Q_MAX; qi++) { dev->bdev[qi] = NULL; } @@ -1899,6 +1965,7 @@ ngknet_dev_remove(int dn) if (SHR_FAILURE(rv)) { DBG_WARN(("Detach DMA driver failed.\n")); } + ngbde_kapi_knet_disconnect(dn); return rv; } @@ -1937,6 +2004,11 @@ ngknet_netif_create(struct ngknet_dev *dev, ngknet_netif_t *netif) } } + if (netif->chan >= NUM_Q_MAX) { + DBG_WARN(("Exceed max number of queues : %d.\n", netif->chan)); + return SHR_E_PARAM; + } + rv = ngknet_ndev_init(netif, &ndev); if (SHR_FAILURE(rv)) { return rv; @@ -2262,6 +2334,7 @@ ngknet_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } if (!strcasecmp(dev_cfg->type_str, drv_ops[dt]->drv_desc)) { pdev->dev_type = dt; + strlcpy(dev->var_str, dev_cfg->var_str, sizeof(dev->var_str)); break; } } @@ -2288,6 +2361,10 @@ ngknet_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (SHR_FAILURE((int)ioc.rc)) { break; } + if (dev->cbc->dev_init_cb) { + dev->cbc->dev_init_cb(dev); + } + if (kal_copy_to_user((void *)(unsigned long)ioc.op.data.buf, dev_cfg, ioc.op.data.len, sizeof(*dev_cfg))) { return -EFAULT; @@ -2380,7 +2457,13 @@ ngknet_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (rx_rate_limit >= 0) { ngknet_rx_rate_limit_stop(dev); } - ioc.rc = bcmcnet_pdma_dev_suspend(pdev); + if (ioc.iarg[0]) { + /* Graceful suspend */ + ioc.rc = bcmcnet_pdma_dev_suspend(pdev); + } else { + pdev->flags |= PDMA_ABORT; + ioc.rc = bcmcnet_pdma_dev_suspend(pdev); + } break; case NGKNET_DEV_RESUME: DBG_CMD(("NGKNET_DEV_RESUME\n")); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.h index fb38f1b9abc3..71ea0fb84fdf 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_main.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -68,6 +68,12 @@ * Device description */ struct ngknet_dev { + /*! Device type string */ + char type_str[NGKNET_DEV_NAME_MAX]; + + /*! Device type string */ + char var_str[NGKNET_DEV_NAME_MAX]; + /*! Base address for PCI register access */ volatile void *base_addr; @@ -86,11 +92,11 @@ struct ngknet_dev { /*! Device number (from BDE) */ int dev_no; - /*! Vitual network devices, 0 is reserved */ + /*! Virtual network devices, 0 is reserved for valid number of devices. */ struct net_device *vdev[NUM_VDEV_MAX + 1]; - /*! Vitual network devices bound to queue */ - struct net_device *bdev[NUM_QUE_MAX]; + /*! Virtual network devices bound to queue */ + struct net_device *bdev[NUM_Q_MAX]; /*! Filter list */ struct list_head filt_list; @@ -191,6 +197,9 @@ struct ngknet_private { /*! HW timestamp Tx type */ int hwts_tx_type; + + /*! Matched callback filter */ + struct ngknet_filter_s *filt_cb; }; /*! diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.c index 85edaa26abb9..8dd4df902f6f 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or @@ -380,6 +380,9 @@ proc_pkt_stats_show(struct seq_file *m, void *v) } seq_printf(m, "rx_dropped: %llu\n", (unsigned long long)stats->rx_dropped); seq_printf(m, "rx_errors: %llu\n", (unsigned long long)stats->rx_errors); + seq_printf(m, "rx_head_errors: %llu\n", (unsigned long long)stats->rx_head_errors); + seq_printf(m, "rx_data_errors: %llu\n", (unsigned long long)stats->rx_data_errors); + seq_printf(m, "rx_cell_errors: %llu\n", (unsigned long long)stats->rx_cell_errors); seq_printf(m, "rx_nomems: %llu\n", (unsigned long long)stats->rx_nomems); seq_printf(m, "tx_packets: %llu\n", (unsigned long long)stats->tx_packets); seq_printf(m, "tx_bytes: %llu\n", (unsigned long long)stats->tx_bytes); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.h index 3c1938121ebb..99e1ce93c48d 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_procfs.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.c b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.c index 13579208eab0..75e22bc43f17 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.c @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.h b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.h index 86dcb6c4904a..e881c77b5273 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.h +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knet/ngknet_ptp.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Kbuild b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Kbuild index 2ce66edb3c63..6a60777e9c48 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Kbuild +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Kbuild @@ -2,7 +2,7 @@ # # Linux KNET Callback module. # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or @@ -24,13 +24,17 @@ endif obj-m := linux_ngknetcb.o -ccflags-y := $(LKM_CFLAGS) \ - -I$(SDK)/shr/include \ - -I$(SDK)/bcmdrd/include \ - -I$(SDK)/linux/include \ - -I$(SDK)/linux/knet/include \ - -I$(SDK)/linux/knet \ - $(PSAMPLE_CFLAGS) +ccflags-y := $(KNETCB_CPPFLAGS) $(LKM_CFLAGS) \ + $(SDK_PMD_KFLAGS) \ + -I$(SDK)/shr/include \ + -I$(SDK)/bcmdrd/include \ + -I$(SDK)/bcmltd/include \ + -I$(SDK)/bcmlrd/include \ + -I$(SDK)/linux/include \ + -I$(SDK)/linux/knet/include \ + -I$(SDK)/linux/knetcb \ + -I$(SDK)/linux/knet \ + $(PSAMPLE_CFLAGS) -linux_ngknetcb-y := ngknetcb_main.o \ +linux_ngknetcb-y := $(SDK_PMD_KOBJS) ngknetcb_main.o \ $(PSAMPLE_CB_OBJS) diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Makefile b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Makefile index e2acfed49d6c..4698183db035 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Makefile +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/Makefile @@ -2,7 +2,7 @@ # # Linux KNET Callback module. # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or @@ -18,6 +18,24 @@ # be found in the LICENSES folder.$ # +ifdef KPMD + +BCMPKTDIR = $(SDK)/bcmpkt +KPMDDIR = $(SDK)/linux/knetcb +SHRDIR = $(SDK)/shr + +.PHONY: mklinks rmlinks + +knetcb: mklinks + $(MAKE) all + +# SDK make helper for stand-alone PMD kernel module +include $(SDK)/make/kpmd.mk + +distclean: rmlinks + +endif #KPMD + include Kbuild ifeq ($(KERNELRELEASE),) diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/ngknetcb_main.c b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/ngknetcb_main.c index aa248dafce52..80e5f635733d 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/ngknetcb_main.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/ngknetcb_main.c @@ -73,20 +73,23 @@ strip_vlan_tag(struct sk_buff *skb) * -1 = Unsupported type */ static int -get_tag_status(uint32_t dev_type, void *meta) +get_tag_status(uint32_t dev_type, uint32_t variant, void *meta) { uint32_t *valptr; uint32_t fd_index; uint32_t outer_l2_hdr; int tag_status = -1; + uint32_t match_id_minbit = 1; + uint32_t outer_tag_match = 0x10; if ((dev_type == 0xb880) || (dev_type == 0xb780)) { /* Field BCM_PKTIO_RXPMD_MATCH_ID_LO has tag status in RX PMD */ fd_index = 2; valptr = (uint32_t *)meta; - outer_l2_hdr = (valptr[fd_index] >> ((dev_type == 0xb780) ? 2 : 1) & 0xFF); - + match_id_minbit = (dev_type == 0xb780) ? 2 : 1; + outer_l2_hdr = (valptr[fd_index] >> match_id_minbit & 0xFF); + outer_tag_match = ((dev_type == 0xb780 && variant == 1) ? 0x8 : 0x10); if (outer_l2_hdr & 0x1) { #ifdef KNET_CB_DEBUG if (debug & 0x1) { @@ -102,7 +105,7 @@ get_tag_status(uint32_t dev_type, void *meta) #endif tag_status = 0; } - if (outer_l2_hdr & 0x10) { + if (outer_l2_hdr & outer_tag_match) { #ifdef KNET_CB_DEBUG if (debug & 0x1) { printk(" Outer Tagged\n"); @@ -122,7 +125,7 @@ get_tag_status(uint32_t dev_type, void *meta) #ifdef KNET_CB_DEBUG if (debug & 0x1) { printk(" Inner Tagged\n"); - } + } #endif tag_status = 1; } @@ -188,7 +191,7 @@ dump_buffer(uint8_t * data, int size) buffer_ptr = buffer; printk(KERN_INFO "%04X %s\n", addr, buffer); addr = i + 1; - } + } } } @@ -205,9 +208,9 @@ static void show_mac(uint8_t *pkt) { if (debug & 0x1) { - printk("DMAC=%02X:%02X:%02X:%02X:%02X:%02X\n", - pkt[0], pkt[1], pkt[2], pkt[3], pkt[4], pkt[5]); - } + printk("DMAC=%02X:%02X:%02X:%02X:%02X:%02X\n", + pkt[0], pkt[1], pkt[2], pkt[3], pkt[4], pkt[5]); +} } #endif @@ -231,10 +234,10 @@ strip_tag_rx_cb(struct sk_buff *skb) cbd->dev_no, cbd->dev_id, cbd->type_str, rcpu_mode ? "yes" : "no"); printk(KERN_INFO " pkt_len=%4d; pmd_len=%2d; SKB len: %4d\n", cbd->pkt_len, cbd->pmd_len, skb->len); - if (cbd->filt) { + if (cbd->filt) { printk(KERN_INFO "Filter user data: 0x%08x\n", *(uint32_t *) cbd->filt->user_data); - } + } printk(KERN_INFO "Before SKB (%d bytes):\n", skb->len); dump_buffer(skb->data, skb->len); printk("rx_cb for dev %d: id 0x%x, %s\n", cbd->dev_no, cbd->dev_id, cbd->type_str); @@ -256,7 +259,7 @@ strip_tag_rx_cb(struct sk_buff *skb) if ((!rcpu_mode) && (cbd->filt)) { if (FILTER_TAG_ORIGINAL == cbd->filt->user_data[0]) { - tag_status = get_tag_status(cbd->dev_id, (void *)cbd->pmd); + tag_status = get_tag_status(cbd->dev_id, cbd->filt->user_data[1],(void *)cbd->pmd); if (tag_status < 0) { strip_stats.skipped++; goto _strip_tag_rx_cb_exit; @@ -267,6 +270,10 @@ strip_tag_rx_cb(struct sk_buff *skb) strip_vlan_tag(skb); } } + if (FILTER_TAG_STRIP == cbd->filt->user_data[0]) { + strip_stats.stripped++; + strip_vlan_tag(skb); + } } _strip_tag_rx_cb_exit: #ifdef KNET_CB_DEBUG @@ -288,7 +295,7 @@ strip_tag_tx_cb(struct sk_buff *skb) struct ngknet_callback_desc *cbd = NGKNET_SKB_CB(skb); if (debug & 0x1) { - printk("tx_cb for dev %d: %s\n", cbd->dev_no, cbd->type_str); + printk("tx_cb for dev %d: %s\n", cbd->dev_no, cbd->type_str); } show_pmd(cbd->pmd, cbd->pmd_len); show_mac(cbd->pmd + cbd->pmd_len); diff --git a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c index be34430218d3..1b0d305d7104 100644 --- a/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c +++ b/platform/broadcom/saibcm-modules/sdklt/linux/knetcb/psample-cb.c @@ -302,7 +302,7 @@ psample_rx_cb(struct sk_buff *skb) cbd = NGKNET_SKB_CB(skb); netif = cbd->priv; filt_src = cbd->filt; - filt = cbd->filt_cb; + filt = netif->filt_cb; if (!cbd || !netif || !filt_src) { printk("%s: cbd(0x%p) or priv(0x%p) or filter src(0x%p) is NULL\n", @@ -429,8 +429,9 @@ psample_rx_cb(struct sk_buff *skb) PSAMPLE_FILTER_CB_PKT_HANDLED: /* if sample reason only, consume pkt. else pass through */ rv = psample_meta_sample_reason(skb->data, cbd->pmd); - if (rv) { + if (PSAMPLE_PKT_HANDLED == rv) { g_psample_stats.pkts_f_handled++; + dev_kfree_skb_any(skb); return NULL; } g_psample_stats.pkts_f_pass_through++; @@ -462,8 +463,12 @@ psample_netif_create_cb(struct net_device *dev) psample_netif->dev = dev; psample_netif->id = netif->id; - /* FIXME: port is not saved in ngknet_private, need to get from metadata?? */ - //psample_netif->port = netif->port; + /*Application has encoded the port in netif user data 0 & 1 */ + if (netif->type == NGKNET_NETIF_T_PORT) + { + psample_netif->port = netif->user_data[0]; + psample_netif->port |= netif->user_data[1] << 8; + } psample_netif->vlan = netif->vlan; psample_netif->sample_rate = PSAMPLE_RATE_DFLT; psample_netif->sample_size = PSAMPLE_SIZE_DFLT; diff --git a/platform/broadcom/saibcm-modules/sdklt/make/lkm.mk b/platform/broadcom/saibcm-modules/sdklt/make/lkm.mk index c3d2a4d40b50..803154e54c68 100644 --- a/platform/broadcom/saibcm-modules/sdklt/make/lkm.mk +++ b/platform/broadcom/saibcm-modules/sdklt/make/lkm.mk @@ -1,5 +1,5 @@ # -# $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. +# $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. # The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. # # This program is free software; you can redistribute it and/or @@ -35,42 +35,39 @@ ifneq ($(LKM_BLDDIR),) # Note that the KBUILD_OUTPUT variable cannot be used to redirect the # output as we want it. # -MDIR = $(LKM_BLDDIR) -MSRCS = $(patsubst %.o,%.c,$($(MOD_NAME)-y)) +MDIR := $(LKM_BLDDIR) +MSRCS := $(patsubst %.o,%.c,$($(MOD_NAME)-y)) MSRCS += Makefile Kbuild -BSRCS = $(addprefix $(PWD)/,$(MSRCS)) +BSRCS := $(addprefix $(PWD)/,$(MSRCS)) else # # Build in current directory by default. # -MDIR = $(PWD) +MDIR := $(PWD) endif -all: +all: mlinks $(Q)echo Building kernel module $(MOD_NAME) -ifneq ($(LKM_BLDDIR),) -ifneq ($(LKM_BLDDIR),$(PWD)) - $(Q)mkdir -p $(MDIR) - (cd $(MDIR); \ - rm -rf *.c Makefile Kbuild; \ - for f in $(BSRCS); do \ - ln -s $$f; \ - done) -endif -endif $(MAKE) -C $(KDIR) M=$(MDIR) -clean:: +clean:: mlinks $(Q)echo Cleaning kernel module $(MOD_NAME) $(MAKE) -C $(KDIR) M=$(MDIR) clean -ifneq ($(LKM_BLDDIR),) -ifneq ($(LKM_BLDDIR),$(PWD)) -# Remove all files except for Makefile (needed by 'make clean') - rm -f $(LKM_BLDDIR)/*[cdors] +ifneq ($(MDIR),$(PWD)) + rm -rf $(MDIR) endif + +mlinks: +ifneq ($(MDIR),$(PWD)) + $(Q)mkdir -p $(MDIR) + (cd $(MDIR); \ + rm -rf $(MSRCS); \ + for f in $(BSRCS); do \ + ln -s $$f; \ + done) endif -.PHONY: all clean +.PHONY: all mlinks clean # Standard documentation targets -include $(SDK)/make/doc.mk diff --git a/platform/broadcom/saibcm-modules/sdklt/shr/include/shr/shr_error.h b/platform/broadcom/saibcm-modules/sdklt/shr/include/shr/shr_error.h index 1924d600de53..a51dc11392b2 100644 --- a/platform/broadcom/saibcm-modules/sdklt/shr/include/shr/shr_error.h +++ b/platform/broadcom/saibcm-modules/sdklt/shr/include/shr/shr_error.h @@ -4,7 +4,7 @@ * */ /* - * $Copyright: Copyright 2018-2020 Broadcom. All rights reserved. + * $Copyright: Copyright 2018-2021 Broadcom. All rights reserved. * The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries. * * This program is free software; you can redistribute it and/or diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h index 23eb3fa33e9e..28fb6b5870e6 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/include/linux_dma.h @@ -69,7 +69,8 @@ #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) #endif -extern void _dma_init(int dev_index); +extern void _dma_init(void); +extern void _dma_per_device_init(int dev_index); extern int _dma_cleanup(void); extern void _dma_pprint(struct seq_file *m); extern uint32_t *_salloc(int d, int size, const char *name); 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 9029b3b51477..b7c422e04e8b 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 @@ -33,16 +33,15 @@ #define MEMCPY memcpy #ifdef CONFIG_X86_64 -#if (defined(__GNUC__) && (__GNUC__ == 8)) +#if (defined(__GNUC__) && (__GNUC__ >= 8)) /* - * Prevent gcc 8.1.10 using a compiler inline memcpy even if using -fno-builtin or - * -fno-builtin-memcpy . - * __inline_memcpy and __memcpy are kernel functions that may be used instead, - * for either an inline or non-inline implementations of the function + * Prevent gcc from using a compiler builtin memcpy even if using -fno-builtin or + * -fno-builtin-memcpy. + * Use __memcpy kernel function in x86 Linux instead. */ #undef MEMCPY #define MEMCPY __memcpy -#endif /* (defined(__GNUC__) && (__GNUC__ == 8)) */ +#endif /* (defined(__GNUC__) && (__GNUC__ >= 8)) */ #endif /* CONFIG_X86_64 */ @@ -344,7 +343,7 @@ typedef struct bde_ctrl_s { static bde_ctrl_t _devices[LINUX_BDE_MAX_DEVICES]; -/* information stored per SDK instance, curently the devices it manages */ +/* information stored per SDK instance, currently the devices it manages */ typedef struct { linux_bde_device_bitmap_t devices; /* The devices controlled by this instance */ } lkbde_inst_info_t; @@ -469,6 +468,7 @@ static uint32_t _read(int d, uint32_t addr); #ifdef BCM_ICS #else +#ifdef CONFIG_PCI /* Used to determine overall memory limits across all devices */ static uint32_t _pci_mem_start = 0xFFFFFFFF; static uint32_t _pci_mem_end = 0; @@ -476,6 +476,7 @@ static uint32_t _pci_mem_end = 0; /* Used to control MSI interrupts */ static int use_msi = 0; #endif +#endif #ifdef BCM_PLX9656_LOCAL_BUS @@ -517,6 +518,9 @@ static void _bde_add_device(void) { int add_switch_device = 0; + if (_ndevices >= LINUX_BDE_MAX_DEVICES) { + gprintk("Error: added too many devices\n"); + } if (_devices[_ndevices].dev_type & BDE_SWITCH_DEV_TYPE) { _switch_ndevices++; add_switch_device = 1; @@ -552,7 +556,7 @@ _bde_add_device(void) _devices[i] = tmp_dev; } - _dma_init(_switch_ndevices-1); + _dma_per_device_init(_switch_ndevices-1); } /* Initialize device locks */ @@ -759,6 +763,9 @@ iproc_cmicd_probe(struct platform_device *pldev) } else { gprintk("Error mapping ihost GICD registers\n"); } + if (dma_set_mask_and_coherent(&pldev->dev, DMA_BIT_MASK(64))) { + gprintk("Unable to set 64-bit dma mask\n"); + } } else #endif { @@ -905,24 +912,15 @@ static int iproc_has_cmicd(void) { void *iproc_cca_base; - uint32 cca_cid; /* Read ChipcommonA chip id register to identify current SOC */ iproc_cca_base = IOREMAP(IPROC_CHIPCOMMONA_BASE, 0x3000); if (iproc_cca_base == NULL) { - gprintk("iproc_has_cmicd: ioremap of ChipcommonA registers failed"); + gprintk("iproc_has_cmicd: ioremap of ChipcommonA registers failed"); return 0; } - cca_cid = readl((uint32 *)iproc_cca_base); - cca_cid &= 0xffff; iounmap(iproc_cca_base); - /* Only allowed accessing CMICD module if the SOC has it */ - switch (cca_cid) { - default: - break; - } - /* Device has CMIC */ return 1; } @@ -1095,6 +1093,7 @@ _ics_bde_create(void) #else /* !BCM_ICS */ +#ifdef CONFIG_PCI extern struct pci_bus *pci_find_bus(int domain, int busnr); /* @@ -1251,7 +1250,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56321_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56132_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56134_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88732_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56140_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56142_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56143_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1462,7 +1460,6 @@ static const struct pci_device_id _id_table[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, PCI_ANY_ID, PCI_ANY_ID }, { BCM53000_VENDOR_ID, BCM53000PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #ifdef BCM_PETRA_SUPPORT - { BROADCOM_VENDOR_ID, BCM88650_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88350_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88351_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88450_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1470,8 +1467,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88550_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88551_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88552_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88651_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88654_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { PCP_PCI_VENDOR_ID, PCP_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { ACP_PCI_VENDOR_ID, ACP_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88660_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1500,6 +1495,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88474H_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88476_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88477_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88479_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88270_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1511,8 +1507,6 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM88278_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88279_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM8206_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, - { BROADCOM_VENDOR_ID, BCM88376_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88376M_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88377_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1620,6 +1614,22 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM8828D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8828E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8828F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88290_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88291_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88292_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88293_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88294_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88295_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88296_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88297_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88298_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88299_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8829A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8829B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8829C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8829D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8829E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8829F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88850_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88851_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM88852_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1636,6 +1646,22 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM8885D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8885E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM8885F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88840_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88841_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88842_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88843_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88844_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88845_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88846_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88847_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88848_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM88849_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8884A_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8884B_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8884C_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8884D_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8884E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM8884F_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, #endif /* BCM_DNX_SUPPORT */ #ifdef BCM_DFE_SUPPORT { BROADCOM_VENDOR_ID, BCM88770_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, @@ -1719,6 +1745,7 @@ static const struct pci_device_id _id_table[] = { { BROADCOM_VENDOR_ID, BCM56471_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56472_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { BROADCOM_VENDOR_ID, BCM56475_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, + { BROADCOM_VENDOR_ID, BCM56474_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID }, { 0, 0, 0, 0 } };; @@ -2724,7 +2751,7 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) bar_len = pci_resource_len(dev, 0); ctrl->bde_dev.base_address1 = (sal_vaddr_t)IOREMAP(paddr, bar_len); ctrl->iowin[1].addr = paddr; - ctrl->iowin[1].size = bar_len; + ctrl->iowin[1].size = PAGE_ALIGN(bar_len); if (debug >= 3) { gprintk("BAR 0: kernel addr:0x%lx phys addr:0x%lx length:%lx\n", (unsigned long)ctrl->bde_dev.base_address1, (unsigned long)paddr, (unsigned long)bar_len); @@ -2804,6 +2831,10 @@ _pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) (unsigned long)ctrl->bde_dev.base_address, (unsigned long)ctrl->bde_dev.base_address1); } + if (rescan) { /* map IOMMU for re-probed devices */ + _dma_per_device_init(rescan_idx); + } + if (add_dev) { _bde_add_device(); } @@ -2856,6 +2887,7 @@ _pci_remove(struct pci_dev* dev) /* Free our interrupt handler, if we have one */ if (ctrl->isr || ctrl->isr2) { +#ifdef CONFIG_PCI_MSI #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi >= PCI_USE_INT_MSIX) { int i; @@ -2863,6 +2895,7 @@ _pci_remove(struct pci_dev* dev) free_irq(ctrl->entries[i].vector, ctrl); } else +#endif #endif { free_irq(ctrl->iLine, ctrl); @@ -2884,6 +2917,7 @@ static struct pci_driver _device_driver = { .id_table = _id_table, /* The rest are dynamic */ }; +#endif /* CONFIG_PCI */ static void _spi_device_setup(void) { @@ -2939,10 +2973,8 @@ map_local_bus(uint64_t addr, uint32_t size) #ifdef BCM_PLX9656_LOCAL_BUS -#if 1 #define DEV_REG_BASE_OFFSET PL0_OFFSET /* Polaris register base */ #define DEV_REG_DEVID 0 /* Device ID is first register */ -#endif /* * The difference at map_local_bus2: @@ -2974,9 +3006,7 @@ map_local_bus2(bde_ctrl_t *plx_ctrl, uint32_t dev_base, uint32_t size) ctrl->iowin[0].addr = plx_ctrl->iowin[0].addr + (resource_size_t)dev_base; ctrl->iowin[0].size = size; -#if 1 addr = (uint8_t *)ctrl->bde_dev.base_address + PL0_REVISION_REG; -#endif dev_rev_id = readl(addr); ctrl->bde_dev.device = dev_rev_id >> 16; ctrl->bde_dev.rev = (dev_rev_id & 0xFF); @@ -3019,9 +3049,7 @@ probe_plx_local_bus(void) addr = (uint8_t *)plx_ctrl.bde_dev.base_address + CPLD_OFFSET + CPLD_RESET_REG; writel(CPLD_RESET_NONE, addr); #endif -#if 1 ctrl = map_local_bus2(&plx_ctrl, PL0_OFFSET, PL0_SIZE); -#endif if (ctrl == 0) return -1; @@ -3038,6 +3066,7 @@ probe_plx_local_bus(void) + /* * Generic module functions */ @@ -3057,12 +3086,17 @@ static int _init(void) { unsigned i; + + /* allocate and init the DMA buffer pool */ + _dma_init(); #ifdef IPROC_CMICD +#ifdef CONFIG_PCI /* * Adjust the PCI driver name to prevent our device file from * getting removed when the module is unloaded. */ _device_driver.name = LINUX_KERNEL_BDE_NAME ".iproc"; +#endif #ifdef CONFIG_OF if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { iproc_platform_driver_register(&iproc_cmicd_driver); @@ -3070,6 +3104,7 @@ _init(void) #endif if (iproc_has_cmicd()) { iproc_cmicd_get_memregion(&iproc_cmicd_resources[IPROC_CMICD_RES_MEM]); + /* PCIe device will be added here */ iproc_platform_driver_register(&iproc_cmicd_driver); #ifdef CONFIG_OF if (!of_find_compatible_node(NULL, NULL, IPROC_CMICD_COMPATIBLE)) @@ -3085,6 +3120,7 @@ _init(void) _ics_bde_create(); #else /* PCI */ +#ifdef CONFIG_PCI /* Configure MSI interrupt support */ use_msi = usemsi; @@ -3113,16 +3149,23 @@ _init(void) if (unlikely(debug >= 1)) gprintk("%s(%d):use_msi = %d\n", __func__, __LINE__, use_msi); +#endif /* CONFIG_PCI */ + if (spi_devid) { _spi_device_setup(); } else { +#ifdef CONFIG_PCI + /* PCIe devices will be probed here */ if (pci_register_driver(&_device_driver) < 0) { return -ENODEV; } +#endif } +#ifdef CONFIG_PCI /* Note: PCI-PCI bridge uses results from pci_register_driver */ p2p_bridge(); +#endif #ifdef BCM_METROCORE_LOCAL_BUS if (probe_metrocore_local_bus()) { @@ -3159,6 +3202,7 @@ _init(void) } } + for (i = 0; i < LINUX_BDE_MAX_DEVICES; ++i) { _devices[i].inst_id = BDE_DEV_INST_ID_INVALID; } @@ -3219,7 +3263,9 @@ _cleanup(void) #ifdef BCM_ICS #else +#ifdef CONFIG_PCI pci_unregister_driver(&_device_driver); +#endif #endif /* BCM_ICS */ return 0; } @@ -3265,6 +3311,7 @@ _pprint(struct seq_file *m) pprintf(m, "\t%d (?) : ", i); } + if (ctrl->dev_state == BDE_DEV_STATE_REMOVED) { pprintf(m, "PCI device 0x%x:0x%x:%d REMOVED\n", ctrl->pci_device->vendor, @@ -3308,16 +3355,15 @@ _pprint(struct seq_file *m) ctrl->bde_dev.rev); } if (debug >= 1) { - pprintf(m, "\t\timask:imask2:fmask 0x%x:0x%x:0x%x\n", + pprintf(m, "\t\timask:imask2:fmask 0x%x:0x%x:0x%x unique_id=0x%x inst_id ", ctrl->imask, ctrl->imask2, - ctrl->fmask); - } - if (debug >= 1) { + ctrl->fmask, + ctrl->bde_dev.dev_unique_id); if (ctrl->inst_id == BDE_DEV_INST_ID_INVALID) { - pprintf(m, "\t\tinst_id INVALID\n"); + pprintf(m, "INVALID\n"); } else { - pprintf(m, "\t\tinst_id %u%s\n", + pprintf(m, "%u%s\n", ctrl->inst_id, ctrl->inst_id < LINUX_BDE_MAX_DEVICES ? "":"(Illegal)"); } @@ -3674,7 +3720,6 @@ _interrupt_connect(int d, if(ret != 0) goto msi_exit; } -#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi == PCI_USE_INT_MSIX) { int i; @@ -3696,6 +3741,7 @@ _interrupt_connect(int d, } } else +#endif #endif { #if defined(IPROC_CMICD) && defined(CONFIG_OF) @@ -3812,6 +3858,7 @@ _interrupt_disconnect(int d) } if (isr_active) { +#ifdef CONFIG_PCI_MSI #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,84)) if (ctrl->use_msi >= PCI_USE_INT_MSIX) { int i; @@ -3825,6 +3872,7 @@ _interrupt_disconnect(int d) } else #endif +#endif #if defined(IPROC_CMICD) && defined(CONFIG_OF) if (of_find_compatible_node(NULL, NULL, IPROC_CMICX_COMPATIBLE)) { int i; @@ -4060,7 +4108,6 @@ lkbde_cpu_pci_register(int d) case BCM88772_DEVICE_ID: case BCM88952_DEVICE_ID: case ACP_PCI_DEVICE_ID: - case BCM88650_DEVICE_ID: case BCM88670_DEVICE_ID: case BCM88671_DEVICE_ID: @@ -4102,6 +4149,7 @@ lkbde_cpu_pci_register(int d) case BCM88474H_DEVICE_ID: case BCM88476_DEVICE_ID: case BCM88477_DEVICE_ID: + case BCM88479_DEVICE_ID: case BCM88270_DEVICE_ID: case BCM88271_DEVICE_ID: case BCM88272_DEVICE_ID: @@ -4109,7 +4157,6 @@ lkbde_cpu_pci_register(int d) case BCM88274_DEVICE_ID: case BCM88276_DEVICE_ID: case BCM88278_DEVICE_ID: - case BCM8206_DEVICE_ID: case BCM88350_DEVICE_ID: case BCM88351_DEVICE_ID: case BCM88450_DEVICE_ID: @@ -4117,8 +4164,6 @@ lkbde_cpu_pci_register(int d) case BCM88550_DEVICE_ID: case BCM88551_DEVICE_ID: case BCM88552_DEVICE_ID: - case BCM88651_DEVICE_ID: - case BCM88654_DEVICE_ID: case BCM88660_DEVICE_ID: case BCM88360_DEVICE_ID: case BCM88361_DEVICE_ID: @@ -4154,6 +4199,7 @@ lkbde_cpu_pci_register(int d) case J2C_2ND_DEVICE_ID: case Q2A_DEVICE_ID: case Q2U_DEVICE_ID: + case Q2N_DEVICE_ID: case J2P_DEVICE_ID: #endif #ifdef BCM_DNXF_SUPPORT diff --git a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c index 52711964a533..bf08039ddbae 100644 --- a/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c +++ b/platform/broadcom/saibcm-modules/systems/bde/linux/kernel/linux_dma.c @@ -89,6 +89,7 @@ /* allocation types/methods for the DMA memory pool */ #define ALLOC_TYPE_CHUNK 0 /* use small allocations and join them */ #define ALLOC_TYPE_API 1 /* use one allocation */ +#define ALLOC_TYPE_HIMEM 2 /* use high memory */ #if _SIMPLE_MEMORY_ALLOCATION_ #include @@ -167,6 +168,47 @@ static int mem_flags = GFP_ATOMIC | GFP_DMA; #endif #endif +#ifdef IPROC_CMICD +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,13,0) +#ifndef COHERENT_ALLOC_USE_DMA_TO_PHYS +#define COHERENT_ALLOC_USE_DMA_TO_PHYS 1 +#endif +#else +#ifndef COHERENT_ALLOC_PHYS_IS_DMA_ADDR +#define COHERENT_ALLOC_PHYS_IS_DMA_ADDR 1 +#endif +#endif +#endif /* IPROC_CMICD */ + +/* + * Macros that can be used by the build to control the technique of + * setting the physical address for dma_alloc_coherent() + */ +#ifndef COHERENT_ALLOC_USE_DMA_TO_PHYS +#define COHERENT_ALLOC_USE_DMA_TO_PHYS 0 +#endif +#ifndef COHERENT_ALLOC_PHYS_IS_DMA_ADDR +#define COHERENT_ALLOC_PHYS_IS_DMA_ADDR 0 +#endif + +#if COHERENT_ALLOC_USE_DMA_TO_PHYS +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,16,0)) +#include +#else +#include +#endif +#endif + +/* Macro to get the host physical address when using dma_alloc_coherent() */ +#if COHERENT_ALLOC_USE_DMA_TO_PHYS +#define HOST_PHYS_ADDR(_dev, _dma_a, _kvirt_a) \ + ((_dev) ? dma_to_phys((_dev), (_dma_a)) : virt_to_phys(_kvirt_a)) +#elif COHERENT_ALLOC_PHYS_IS_DMA_ADDR +#define HOST_PHYS_ADDR(_dev, _dma_a, _kvirt_a) (_dma_a) +#else +#define HOST_PHYS_ADDR(_dev, _dma_a, _kvirt_a) (virt_to_phys(_kvirt_a)) +#endif + /* Debug output */ static int dma_debug = 0; module_param(dma_debug, int, 0); @@ -238,19 +280,42 @@ typedef struct _dma_segment { static unsigned int _dma_mem_size = DMA_MEM_DEFAULT; static mpool_handle_t _dma_pool = NULL; +/* kernel virtual address of the DMA buffer pool */ static void __iomem *_dma_vbase = NULL; -/* cpu physical address for mmap */ +/* CPU physical address of the DMA buffer pool, used for mmap */ static phys_addr_t _cpu_pbase = 0; /* - * DMA bus address, it is either identical to cpu physical address - * or another address(IOVA) translated by IOMMU. + * DMA buffer poool PCIe bus address, it is either identical to the CPU + * physical address or another address(IOVA) translated by IOMMU. */ static phys_addr_t _dma_pbase = 0; + +/* states of the DMA pool: */ + +/* not initialized */ +#define DNA_POOL_INVALID 0 +/* initialized and not yet mapped */ +#define DMA_POOL_INITIALIZED 1 +/* initialized and mapped */ +#define DMA_POOL_MAPPED 2 +/* initialization failed */ +#define DMA_POOL_FAILED 3 + +/* Was the DMA buffer pool allocation attempted? */ +static int _dma_pool_alloc_state = DNA_POOL_INVALID; + static int _use_himem = 0; static unsigned long _himemaddr = 0; +/* None-zero if the DMA buffer pool is not mapped to the bus address by the + allocation, and needs to be mapped per device. */ static int _use_dma_mapping = 0; static LIST_HEAD(_dma_seg); +extern int nodevices; +#if _SIMPLE_MEMORY_ALLOCATION_ +static struct device *_dma_alloc_coherent_device = NULL; +#endif /* _SIMPLE_MEMORY_ALLOCATION_ */ + #define DMA_DEV_INDEX 0 /* Device index to allocate memory pool */ #define DMA_DEV(n) lkbde_get_dma_dev(n) #define BDE_NUM_DEVICES(t) lkbde_get_num_devices(t) @@ -707,7 +772,7 @@ _edk_vm_is_valid(struct file *filp, struct vm_area_struct *vma) * Function: _mpool_free * * Purpose: - * Free all memory allocated by _mpool_alloc + * Free the DMA buffer pool and stop using it. * Parameters: * None * Returns: @@ -716,26 +781,45 @@ _edk_vm_is_valid(struct file *filp, struct vm_area_struct *vma) static void _mpool_free(void) { + if (dma_debug >= 1) { + gprintk("Freeing DMA buffer pool kernel_virt:0x%lx size:0x%x dmaalloc:%d ndevices=%d\n", + (unsigned long)_dma_vbase, _dma_mem_size, dmaalloc, BDE_NUM_DEVICES(BDE_SWITCH_DEVICES)); + } + + /* unmap bus address for all devices */ + /* TODO SDK-235729 skip removed devices */ + if (_use_dma_mapping) { + int i, ndevices; + ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); + for (i = 0; i < ndevices && DMA_DEV(i); i ++) { + dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, DMA_BIDIRECTIONAL); + } + _use_dma_mapping = 0; + } + +#ifndef REMAP_DMA_NONCACHED + if (_use_himem) +#endif + { + iounmap(_dma_vbase); + } + switch (dmaalloc) { #if _SIMPLE_MEMORY_ALLOCATION_ case ALLOC_TYPE_API: if (_dma_vbase) { - if (dma_debug >= 1) gprintk("freeing v=%p p=0x%lx size=0x%lx\n", _dma_vbase,(unsigned long) _dma_pbase, (unsigned long)_dma_mem_size); - dma_free_coherent(DMA_DEV(DMA_DEV_INDEX), _dma_mem_size, _dma_vbase, _dma_pbase); + if (dma_debug >= 1) gprintk("freeing v=0x%lx p=0x%lx size=0x%lx\n", (unsigned long)_dma_vbase,(unsigned long) _dma_pbase, (unsigned long)_dma_mem_size); + if (_dma_alloc_coherent_device != NULL) { + dma_free_coherent(_dma_alloc_coherent_device, _dma_mem_size, _dma_vbase, _dma_pbase); + _dma_alloc_coherent_device = NULL; + } } break; #endif /* _SIMPLE_MEMORY_ALLOCATION_ */ case ALLOC_TYPE_CHUNK: { struct list_head *pos, *tmp; - int i, ndevices; - if (_use_dma_mapping) { - ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); - for (i = 0; i < ndevices && DMA_DEV(i); i ++) { - dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, DMA_BIDIRECTIONAL); - } - _use_dma_mapping = 0; - } + list_for_each_safe(pos, tmp, &_dma_seg) { dma_segment_t *dseg = list_entry(pos, dma_segment_t, list); list_del(&dseg->list); @@ -744,9 +828,15 @@ _mpool_free(void) break; } + case ALLOC_TYPE_HIMEM: + break; + default: - gprintk("DMA memory allocation method dmaalloc=%d is not supported\n", dmaalloc); + gprintk("_mpool_free:DMA memory allocation method dmaalloc=%d is not supported\n", dmaalloc); } + _dma_vbase = NULL; + _cpu_pbase = 0; + _dma_pbase = 0; } /* @@ -759,6 +849,8 @@ _mpool_free(void) * Returns: * Nothing. * Notes: + * The DMA buffer pool is allocated if the selected memory allocation + * method does not also map it to PCIe bus addresses. * If set up to use high memory, we simply map the memory into * kernel space. * It is assumed there is only one pool. @@ -767,15 +859,10 @@ static void _mpool_alloc(size_t size) { unsigned long pbase = 0; - struct device *dev = DMA_DEV(DMA_DEV_INDEX); - int dma64_support = 0; -#if defined(IPROC_CMICD) && defined(CONFIG_OF) - if (of_find_compatible_node(NULL, NULL, "brcm,iproc-cmicx")) { - dma64_support = 1; + if (dma_debug >= 1) { + gprintk("Allocating DMA memory using method dmaalloc=%d\n", dmaalloc); } -#endif - #if defined(__arm__) && !defined(CONFIG_HIGHMEM) if (_use_himem) { gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n"); @@ -783,62 +870,34 @@ _mpool_alloc(size_t size) } #endif + if (size == 0) return; + if (_use_himem) { /* Use high memory for DMA */ if (_himemaddr) { pbase = _himemaddr; } else { - pbase = virt_to_bus(high_memory); - } - if (((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { - gprintk("DMA in high memory at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size); - return; + pbase = virt_to_phys(high_memory); } _cpu_pbase = pbase; - if (dev) { - /* Use dma_map_single to obtain DMA bus address or I/O virtual address, if - IOMMU is present. */ - pbase = dma_map_single(dev, bus_to_virt(_cpu_pbase), size, DMA_BIDIRECTIONAL); - if (BDE_DMA_MAPPING_ERROR(dev, pbase)) { - gprintk("Error !! Failed to map memory at phys base 0x%lx\n", - (unsigned long)_cpu_pbase); - _cpu_pbase = 0; - return; - } - _use_dma_mapping = 1; - } else { - pbase = _cpu_pbase; - } - _dma_pbase = pbase; - _dma_vbase = IOREMAP(_dma_pbase, size); + _dma_vbase = phys_to_virt(pbase); + _use_dma_mapping = 1; } else { - /* Get DMA memory from kernel */ - if (dma_debug >= 1) { - gprintk("Allocating DMA memory using method dmaalloc=%d\n", dmaalloc); - } switch (dmaalloc) { #if _SIMPLE_MEMORY_ALLOCATION_ case ALLOC_TYPE_API: { - size_t alloc_size = size; /* size of memory allocated in current iteration */ - if (alloc_size > DMA_MAX_ALLOC_SIZE) { - alloc_size = DMA_MAX_ALLOC_SIZE; + /* The allocation will be performed together with the mapping to the first device */ + if (size > DMA_MAX_ALLOC_SIZE) { + gprintk("Will allocate 0x%lx bytes instead of 0x%lx bytes.\n", + (unsigned long)DMA_MAX_ALLOC_SIZE, (unsigned long)size); + _dma_mem_size = DMA_MAX_ALLOC_SIZE; } - /* get a memory allocation from the kernel */ - { - dma_addr_t dma_handle; - _dma_vbase = dma_alloc_coherent(dev, alloc_size, &dma_handle, GFP_KERNEL); - if (!_dma_vbase || !dma_handle) { - gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size); - return; - } - _cpu_pbase = pbase = dma_handle; - } - - if (alloc_size != size) { - gprintk("allocated 0x%lx bytes instead of 0x%lx bytes.\n", - (unsigned long)alloc_size, (unsigned long)size); + if (nodevices == 1) { + /* With no devices, allocate immediately mapping to the null device */ + _dma_pool_alloc_state = DMA_POOL_INITIALIZED; + _dma_per_device_init(0); + return; } - size = _dma_mem_size = alloc_size; break; } #endif /* _SIMPLE_MEMORY_ALLOCATION_ */ @@ -849,20 +908,8 @@ _mpool_alloc(size_t size) gprintk("Failed to allocate memory pool of size 0x%lx\n", (unsigned long)size); return; } - _cpu_pbase = virt_to_bus(_dma_vbase); - /* Use dma_map_single to obtain DMA bus address or IOVA if IOMMU is present. */ - if (dev) { - pbase = dma_map_single(dev, _dma_vbase, size, DMA_BIDIRECTIONAL); - if (BDE_DMA_MAPPING_ERROR(dev, pbase)) { - gprintk("Failed to map memory at %p\n", _dma_vbase); - _mpool_free(); - _dma_vbase = NULL; - return; - } - _use_dma_mapping = 1; - } else { - pbase = _cpu_pbase; - } + _cpu_pbase = virt_to_phys(_dma_vbase); + _use_dma_mapping = 1; break; default: _dma_vbase = NULL; @@ -870,24 +917,12 @@ _mpool_alloc(size_t size) return; } - _dma_pbase = pbase; - - if (!dma64_support && ((pbase + (size - 1)) >> 16) > DMA_BIT_MASK(16)) { - gprintk("DMA memory allocated at 0x%lx size 0x%lx is beyond the 4GB limit and not supported.\n", pbase, (unsigned long)size); - _mpool_free(); - _dma_vbase = NULL; - _dma_pbase = 0; - return; - } + } -#ifdef REMAP_DMA_NONCACHED - _dma_vbase = IOREMAP(_dma_pbase, size); -#endif - if (dma_debug >= 1) { - gprintk("_use_dma_mapping:%d _dma_vbase:%p _dma_pbase:%lx _cpu_pbase:%lx allocated:%lx dmaalloc:%d, dma64_support:%d\n", - _use_dma_mapping, _dma_vbase, (unsigned long)_dma_pbase, - (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc, dma64_support); - } + _dma_pool_alloc_state = DMA_POOL_INITIALIZED; + if (_use_dma_mapping && dma_debug >= 1) { + gprintk("DMA buffer pool before mapping kernel_virt:0x%lx physical:0x%lx size:0x%lx dmaalloc:%d\n", + (unsigned long)_dma_vbase, (unsigned long)_cpu_pbase, (unsigned long)size, dmaalloc); } } @@ -909,51 +944,139 @@ _dma_cleanup(void) #endif if (_dma_vbase) { mpool_destroy(_dma_pool); - if (_use_himem) { - int i, ndevices; - iounmap(_dma_vbase); - if (_use_dma_mapping) { - ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES); - for (i = 0; i < ndevices && DMA_DEV(i); i ++) { - dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, - DMA_BIDIRECTIONAL); - } - _use_dma_mapping = 0; - } - } else { -#ifdef REMAP_DMA_NONCACHED - iounmap(_dma_vbase); -#endif - _mpool_free(); - } - _dma_vbase = NULL; - _dma_pbase = 0; - _cpu_pbase = 0; + _mpool_free(); } + /* In case support will be added to re-allocate the DMA buffer pool */ + _dma_pool_alloc_state = DNA_POOL_INVALID; return 0; } -void _dma_init(int dev_index) +/* + * DMA initialization for a device. Called later than _dma_init(). + * Perform the IOMMU mapping for the specified device. + */ +void _dma_per_device_init(int dev_index) { - unsigned long pbase; + dma_addr_t dma_addr; + struct device *dev; + int performed_initial_pool_mapping = 0; + int dma64_support = 0; + + if (dma_debug >= 2) { + gprintk("_dma_per_device_init dev_index:%d _use_dma_mapping:%d kernel_virt:0x%lx physical:0x%lx size:0x%x dmaalloc:%d\n", + dev_index, _use_dma_mapping, (unsigned long)_dma_vbase, + (unsigned long)_cpu_pbase, _dma_mem_size, dmaalloc); + } +#if _SIMPLE_MEMORY_ALLOCATION_ + if (nodevices == 1 && _dma_pool_alloc_state == DMA_POOL_INITIALIZED && dmaalloc == ALLOC_TYPE_API) { + dev = NULL; /* Map to a null device */ + } else +#endif /* _SIMPLE_MEMORY_ALLOCATION_ */ + if ( dev_index < 0 || (dev = DMA_DEV(dev_index)) == NULL) { + return; + } + +#if _SIMPLE_MEMORY_ALLOCATION_ + if (_dma_pool_alloc_state == DMA_POOL_INITIALIZED && dmaalloc == ALLOC_TYPE_API) { + /* allocate the DMA buffer pool and map it to the device, uses CMA */ + _dma_vbase = dma_alloc_coherent(dev, _dma_mem_size, &dma_addr, GFP_KERNEL); + if (!_dma_vbase) { + _dma_pool_alloc_state = DMA_POOL_FAILED; + gprintk("Failed to allocate coherent memory pool of size 0x%x\n", _dma_mem_size); + return; + } + _dma_alloc_coherent_device = dev; + performed_initial_pool_mapping = 1; + /* Set the host physical address of the DMA buffer pool */ + _cpu_pbase = HOST_PHYS_ADDR(dev, dma_addr, _dma_vbase); - if (dev_index > DMA_DEV_INDEX) { - if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) { - pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL); - if (BDE_DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) { - gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase); + } else +#endif /* _SIMPLE_MEMORY_ALLOCATION_ */ + + /* IF the DMA buffer pool required mapping to the device, perform it */ + if (_use_dma_mapping && _dma_vbase && (_dma_pool_alloc_state == DMA_POOL_INITIALIZED || + _dma_pool_alloc_state == DMA_POOL_MAPPED)) { + /* Map RAM virtual address space for DMA usage and obtain DMA bus address or IOVA if iommu is present. */ + dma_addr = dma_map_single(dev, _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL); + if (BDE_DMA_MAPPING_ERROR(dev, dma_addr)) { + gprintk("Failed to map DMA buffer pool for device %d at kernel_virt:0x%lx\n", dev_index, (unsigned long)_dma_vbase); + if (_dma_pool_alloc_state == DMA_POOL_INITIALIZED) { + _mpool_free(); + _dma_pool_alloc_state = DMA_POOL_FAILED; + } return; } - if (pbase != (unsigned long)_dma_pbase) { - /* Bus address/IOVA must be identical for all devices. */ - gprintk("Device %d has different pbase: %lx (should be %lx)\n", - dev_index, pbase, (unsigned long)_dma_pbase); + if (_dma_pool_alloc_state == DMA_POOL_INITIALIZED) { + performed_initial_pool_mapping = 1; + } else { + if (dma_addr != (dma_addr_t)_dma_pbase) { + /* Bus address/IOVA must be identical for all devices. */ + gprintk("Device %d has different PCIe bus address:0x%lx (should be 0x%lx)\n", + dev_index, (unsigned long)dma_addr, (unsigned long)_dma_pbase); + } + return; } + } + + + /* On the first mapping of the DMA buffer pool, check the mapped address and mark it as mapped */ + if (performed_initial_pool_mapping) { +#if defined(IPROC_CMICD) && defined(CONFIG_OF) + if (of_find_compatible_node(NULL, NULL, "brcm,iproc-cmicx")) { + dma64_support = 1; + } +#endif + + if (!dma64_support && ((dma_addr + (_dma_mem_size - 1)) >> 16) > DMA_BIT_MASK(16)) { + gprintk("DMA memory allocated at dma_bus:0x%lx size 0x%x is beyond the 4GB limit and not supported.\n", (unsigned long)dma_addr, _dma_mem_size); + _mpool_free(); + _dma_pool_alloc_state = DMA_POOL_FAILED; + return; } + _dma_pbase = dma_addr; + _dma_pool_alloc_state = DMA_POOL_MAPPED; + +#ifndef REMAP_DMA_NONCACHED + if (_use_himem) +#endif + { + if (dma_debug >= 2) { + gprintk("remapping DMA buffer pool from physical:0x%lx original kernel_virt:0x%lx\n", + (unsigned long)_dma_pbase, (unsigned long)_dma_vbase); + } + _dma_vbase = IOREMAP(_dma_pbase, _dma_mem_size); + } + + if (dma_debug >= 1) { + gprintk("Mapped DMA buffer pool _use_dma_mapping:%d kernel_virt:0x%lx dma_bus:0x%lx physical:0x%lx size:0x%x dmaalloc:%d, dma64_support:%d\n", + _use_dma_mapping, (unsigned long)_dma_vbase, (unsigned long)_dma_pbase, + (unsigned long)_cpu_pbase, _dma_mem_size, dmaalloc, dma64_support); + } + + /* DMA buffer pool initialization */ + mpool_init(); + _dma_pool = mpool_create(_dma_vbase, _dma_mem_size); + } + return; +} + +/* + * If this is the first time the function is called, * allocate the DMA + * buffer pool. + * Use kernel module arguments for pool size and allocation methods. + */ +void _dma_init(void) +{ + /* + * If DMA buffer pool allocation was already attempted and failed, + * do not attempt again. + */ + if (_dma_pool_alloc_state != DNA_POOL_INVALID || _dma_vbase != NULL) { return; } + _dma_pool_alloc_state = DMA_POOL_FAILED; - /* DMA Setup */ + /* dmasize, himem and himemaddr kernel module argument parsing */ if (dmasize) { if ((dmasize[strlen(dmasize)-1] & ~0x20) == 'M') { _dma_mem_size = simple_strtoul(dmasize, NULL, 0); @@ -970,6 +1093,7 @@ void _dma_init(int dev_index) if (himem) { if ((himem[0] & ~0x20) == 'Y' || himem[0] == '1') { _use_himem = 1; + dmaalloc = ALLOC_TYPE_HIMEM; } else if ((himem[0] & ~0x20) == 'N' || himem[0] == '0') { _use_himem = 0; } @@ -987,13 +1111,12 @@ void _dma_init(int dev_index) } } + /* DMA buffer pool allocation and initialization that can be done without mapping to DMA */ if (_dma_mem_size) { + /* Allocate the DMA buffer pool */ _mpool_alloc(_dma_mem_size); - if (_dma_vbase == NULL) { + if (_dma_pool_alloc_state != DMA_POOL_INITIALIZED) { gprintk("no DMA memory available\n"); - } else { - mpool_init(); - _dma_pool = mpool_create(_dma_vbase, _dma_mem_size); } } } @@ -1028,7 +1151,7 @@ int _dma_mmap(struct file *filp, struct vm_area_struct *vma) #ifdef USE_DMA_MMAP_COHERENT if (dmaalloc == ALLOC_TYPE_API) { vma->vm_pgoff = 0; - return dma_mmap_coherent(DMA_DEV(DMA_DEV_INDEX), vma, (void *)_dma_vbase, phys_addr, size); + return dma_mmap_coherent(_dma_alloc_coherent_device, vma, (void *)_dma_vbase, phys_addr, size); } #endif @@ -1073,6 +1196,7 @@ _l2p(int d, void *vaddr) } return 0; } + /* TODO will not work with IOMMU */ return ((sal_paddr_t)virt_to_bus(vaddr)); } @@ -1088,6 +1212,7 @@ _p2l(int d, sal_paddr_t paddr) } return (void *)(vaddr + (sal_vaddr_t)(paddr - _dma_pbase)); } + /* TODO will not work with IOMMU */ return bus_to_virt(paddr); } @@ -1179,7 +1304,6 @@ lkbde_get_dma_info(phys_addr_t* cpu_pbase, phys_addr_t* dma_pbase, ssize_t* size if (_dma_mem_size == 0) { _dma_mem_size = DMA_MEM_DEFAULT; } - _mpool_alloc(_dma_mem_size); } *cpu_pbase = _cpu_pbase; *dma_pbase = _dma_pbase; 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 4e6186e2d80d..8447e223332c 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 @@ -385,7 +385,7 @@ static int _cmicx_edk_interrupt_check(bde_ctrl_t *ctrl, int d) { bde_inst_resource_t *res; - uint32 stat, mask = 0, bitmap = 0; + uint32 stat, mask = 0, bitmap = 0, reg; int idx; res = &_bde_inst_resource[ctrl->inst]; @@ -403,14 +403,36 @@ _cmicx_edk_interrupt_check(bde_ctrl_t *ctrl, int d) } bitmap = (bitmap >> 1); } - if (mask) + if (mask) { + /* Explicitly reading status to clear the interrupt status on read + * as it is clear that it is EDK's interrupt */ + IPROC_READ(d, ctrl->intr_regs.intc_intr_raw_status_base + + (res->edk_irqs.sw_intr_intrc_offset * 4), stat); + if (stat == res->edk_irqs.sw_intr_intrc_mask) { + IPROC_READ(d, ctrl->intr_regs.intc_intr_status_base + + (res->edk_irqs.sw_intr_intrc_offset * 4), stat); + } + /* Disable SWI and return */ + reg = ctrl->intr_regs.intc_intr_enable_base + + (res->edk_irqs.sw_intr_intrc_offset * 4); + IPROC_READ(d, reg, stat); + stat &= ~res->edk_irqs.sw_intr_intrc_mask; + IPROC_WRITE(d, reg, stat); return 1; + } } - /* EDK uses timer interrupt as watchdog to indicate the the firmware has crashed */ + /* EDK uses timer interrupt as watchdog to indicate the + * firmware has crashed */ IPROC_READ(d, ctrl->intr_regs.intc_intr_raw_status_base + (res->edk_irqs.timer_intrc_offset * 4), stat); if (stat & res->edk_irqs.timer_intrc_mask) { + /* Disable WD timer interrupt and return */ + reg = ctrl->intr_regs.intc_intr_enable_base + + (res->edk_irqs.timer_intrc_offset * 4); + IPROC_READ(d, reg, stat); + stat &= ~res->edk_irqs.timer_intrc_mask; + IPROC_WRITE(d, reg, stat); return 1; } return 0; @@ -422,9 +444,20 @@ _cmicx_interrupt_prepare(bde_ctrl_t *ctrl) { int d, ind, ret = 0; uint32 stat, iena, mask, fmask; + uint32 intrs = 0; d = (((uint8 *)ctrl - (uint8 *)_devices) / sizeof (bde_ctrl_t)); +#ifdef BDE_EDK_SUPPORT + /* Check for interrupts meant for EDK and return without wasting time */ + if (ctrl->edk_irq_enabled) { + ret = _cmicx_edk_interrupt_check(ctrl, d); + if (ret) { + return ret; + } + } +#endif + if (ctrl->dev_type & BDE_PCI_DEV_TYPE) { IPROC_READ(d, ctrl->intr_regs.intc_intr_clear_mode_0, stat); /* Clear MSI interrupts immediately to prevent spurious interrupts */ @@ -444,7 +477,8 @@ _cmicx_interrupt_prepare(bde_ctrl_t *ctrl) IPROC_READ(d, ctrl->intr_regs.intc_intr_status_base + 4 * INTC_PDMA_INTR_REG_IND, stat); IPROC_READ(d, ctrl->intr_regs.intc_intr_enable_base + 4 * INTC_PDMA_INTR_REG_IND, iena); } - if (stat & iena) { + intrs = stat & iena; + if (intrs && (intrs == (intrs & fmask))) { 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); @@ -488,13 +522,9 @@ _cmicx_interrupt_prepare(bde_ctrl_t *ctrl) * So as to avoid getting new interrupts until the user level driver * enumerates the interrupts to be serviced */ -#ifdef BDE_EDK_SUPPORT - if (ctrl->edk_irq_enabled) - ret = _cmicx_edk_interrupt_check(ctrl, d); -#endif for (ind = 0; ind < INTC_INTR_REG_NUM; ind++) { - if (fmask && ind == INTC_PDMA_INTR_REG_IND) { + if (fmask && (intrs == (intrs & fmask)) && ind == INTC_PDMA_INTR_REG_IND) { continue; } if (ctrl->dev_type & BDE_AXI_DEV_TYPE) { @@ -1005,13 +1035,13 @@ _devices_init(int d) case BCM88474H_DEVICE_ID: case BCM88476_DEVICE_ID: case BCM88477_DEVICE_ID: + case BCM88479_DEVICE_ID: case BCM88270_DEVICE_ID: case BCM88272_DEVICE_ID: case BCM88273_DEVICE_ID: case BCM88274_DEVICE_ID: case BCM88278_DEVICE_ID: case BCM88279_DEVICE_ID: - case BCM8206_DEVICE_ID: case BCM88950_DEVICE_ID: case BCM88953_DEVICE_ID: case BCM88954_DEVICE_ID: @@ -1092,6 +1122,7 @@ _devices_init(int d) case J2C_2ND_DEVICE_ID: case Q2A_DEVICE_ID: case Q2U_DEVICE_ID: + case Q2N_DEVICE_ID: case J2P_DEVICE_ID: #endif #ifdef BCM_DNXF_SUPPORT @@ -1303,13 +1334,16 @@ _dma_resource_get(unsigned inst_id, phys_addr_t *cpu_pbase, phys_addr_t *dma_pba unsigned int dma_size = 0, dma_offset = 0; bde_inst_resource_t *res; + spin_lock(&bde_resource_lock); if (inst_id >= user_bde->num_devices(BDE_ALL_DEVICES)) { gprintk("ERROR: requested DMA resources for an instance number out of range: %u\n", inst_id); + spin_unlock(&bde_resource_lock); return -1; } res = &_bde_inst_resource[inst_id]; dma_size = res->dma_size; dma_offset = res->dma_offset; + spin_unlock(&bde_resource_lock); *cpu_pbase = _dma_pool.cpu_pbase + dma_offset * ONE_MB; *dma_pbase = _dma_pool.dma_pbase + dma_offset * ONE_MB; @@ -1339,7 +1373,7 @@ _instance_validate(unsigned int inst_id, unsigned int dmasize, linux_bde_device_ } if (res->is_active == 0) { - /* FIXME SDK-225233 check that the devices are not used by another active instance */ + /* FIXME SDK-250746 check that the devices are not used by another active instance */ return LUBDE_SUCCESS; } @@ -1432,7 +1466,6 @@ _instance_attach(unsigned int inst_id, unsigned int dma_size, linux_bde_device_b res->is_active = 1; res->dma_offset = dma_offset; res->dma_size = dma_size; -#ifdef SAI_FIXUP /* SDK-240875 */ /* skip instance 0, WQ for instance 0 has been initialized in user_bde init, see _init() */ if (inst_id != 0) { init_waitqueue_head(&res->intr_wq); @@ -1440,8 +1473,7 @@ _instance_attach(unsigned int inst_id, unsigned int dma_size, linux_bde_device_b atomic_set(&res->intr, 0); atomic_set(&res->edk_intr, 0); } -#endif - memcpy(*lkbde_get_inst_devs(inst_id), inst_devices, sizeof(linux_bde_device_bitmap_t)); /* SDK-225233 */ + memcpy(*lkbde_get_inst_devs(inst_id), inst_devices, sizeof(linux_bde_device_bitmap_t)); /* store the resource/instance index in _bde_inst_resource for every device in the instance */ for (i = 0; i < user_bde->num_devices(BDE_ALL_DEVICES); i++) { @@ -1597,6 +1629,18 @@ _ioctl(unsigned int cmd, unsigned long arg) if (!VALID_DEVICE(io.dev)) { return -EINVAL; } + /* + * Disable interrupt in case already enabled + * This is to handle the use case where userspace + * application gets killed abruptly. + */ + if (_devices[io.dev].enabled) { + if (debug >= 1) { + gprintk("Interrupts already enabled, disable to cleanup\n"); + } + user_bde->interrupt_disconnect(io.dev); + _devices[io.dev].enabled = 0; + } if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) { if (_devices[io.dev].isr && !_devices[io.dev].enabled) { user_bde->interrupt_connect(io.dev, @@ -1757,7 +1801,12 @@ _ioctl(unsigned int cmd, unsigned long arg) case LUBDE_SEM_OP: return -EINVAL; case LUBDE_WRITE_IRQ_MASK: - io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0); + /* CMICx device */ + if (_devices[io.dev].isr == (isr_f)_cmicx_interrupt) { + io.rc = lkbde_irq_mask_set(io.dev + LKBDE_IPROC_REG, io.d0, io.d1, 0); + } else { + io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0); + } break; case LUBDE_SPI_READ_REG: if (user_bde->spi_read(io.dev, io.d0, io.dx.buf, io.d1) == -1) { 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 43edc056beff..8e63025a6dd3 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 @@ -163,6 +163,13 @@ LKM_MOD_PARAM(basedev_suspend, "i", int, 0); MODULE_PARM_DESC(basedev_suspend, "Pause traffic till base device is up (enabled by default in NAPI mode)"); +static int mirror_local = 1; +LKM_MOD_PARAM(mirror_local, "i", int, 0); +MODULE_PARM_DESC(mirror_local, +"Encapasulate packets based on mirror_to interface configuration, e.g. " +"encapsulate non-RCPU packets when mirrored to an RCPU interface " +"(default 1)."); + /* * Force to add one layer of VLAN tag to untagged packets on Dune devices */ @@ -195,7 +202,6 @@ LKM_MOD_PARAM(ft_vid, "i", int, 0); MODULE_PARM_DESC(ft_vid, "VLAN ID (VID) indicates the VLAN to which a frame belongs (default 0)"); - /* Debug levels */ #define DBG_LVL_VERB 0x1 #define DBG_LVL_DCB 0x2 @@ -524,6 +530,7 @@ static inline void bkn_skb_tx_timestamp(struct sk_buff *skb) #define RCPU_TX_META_SIZE 32 #define RCPU_TX_ENCAP_SIZE (RCPU_HDR_SIZE + RCPU_TX_META_SIZE) #define RCPU_RX_META_SIZE 64 +#define RCPU_RX_META_SIZE_MAX 256 #define RCPU_RX_ENCAP_SIZE (RCPU_HDR_SIZE + RCPU_RX_META_SIZE) #define PKT_TX_HDR_SIZE 16 @@ -582,13 +589,15 @@ typedef struct bkn_switch_info_s { uint32_t rxticks; /* Rx rate control debug counter */ uint32_t interrupts; /* Total number of interrupts */ spinlock_t lock; /* Main lock for device */ + int cfg_api_locked; /* Block configuration API when main lock is + temporary released for calling kernel APIs. */ int dev_no; /* Device number (from BDE) */ int cpu_no; /* Cpu number. 1 for iHost(AXI),0 for others */ int dcb_type; /* DCB type */ int dcb_wsize; /* DCB size (in 32-bit words) */ int pkt_hdr_size; /* Packet header size */ - uint32_t ftmh_lb_key_ext_size; /* FTMH LB-Key Extension existence/size */ - uint32_t ftmh_stacking_ext_size; /* FTMH Stacking extension existence/size */ + uint32_t ftmh_lb_key_ext_size; /* FTMH LB-Key Extension existence/size */ + uint32_t ftmh_stacking_ext_size;/* FTMH Stacking extension existence/size */ uint32_t pph_base_size; /* Size of PPH base */ uint32_t pph_lif_ext_size[8]; /* Size of PPH Lif extension header */ uint32_t udh_length_type[4]; /* Size of UDH header per type */ @@ -597,6 +606,8 @@ typedef struct bkn_switch_info_s { uint8_t no_skip_udh_check; /* Indicates UDH won't be skipped */ uint8_t system_headers_mode; /* Indicates system header mode */ uint8_t udh_enable; /* Indicates UDH existence */ + uint8_t oamp_port_number; /* Indicates number of OAMP system port number */ + uint32_t oamp_ports[KCOM_HW_INFO_OAMP_PORT_MAX]; /* OAMP system port array */ int rx_chans; /* Number of Rx channels */ uint32_t dma_hi; /* DMA higher address */ uint32_t cmic_type; /* CMIC type (CMICe or CMICm) */ @@ -604,7 +615,8 @@ typedef struct bkn_switch_info_s { uint32_t napi_poll_mode; /* NAPI is in polling mode */ uint32_t napi_not_done; /* NAPI poll did not process all packets */ uint32_t napi_poll_again; /* Used if DCB chain is restarted */ - uint32_t tx_yield; /* Tx schedule for Continuous DMA and Non-NAPI mode */ + uint32_t tx_yield; /* Tx schedule for Continuous DMA and Non-NAPI + mode. */ void *dcb_mem; /* Logical pointer to DCB memory */ uint64_t dcb_dma; /* Physical bus address for DCB memory */ int dcb_mem_size; /* Total size of allocated DCB memory */ @@ -613,6 +625,7 @@ typedef struct bkn_switch_info_s { 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 unet_channels; /* User network channels */ uint32_t inst_id; /* Instance id of this device */ int evt_idx; /* Event queue index for this device*/ int basedev_suspended; /* Base device suspended */ @@ -685,8 +698,10 @@ typedef struct bkn_switch_info_s { /* ITMH */ #define BKN_DNX_ITMH_SIZE 5 /* Modlue Header */ -#define BKN_DNX_MODULE_HEADER_SIZE 20 +#define BKN_DNX_MODULE_HEADER_SIZE 16 /* FTMH */ +#define BKN_DNX_FTMH_TC_MSB 14 +#define BKN_DNX_FTMH_TC_NOF_BITS 3 #define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_MSB 17 #define BKN_DNX_FTMH_SRC_SYS_PORT_AGGREGATE_NOF_BITS 16 #define BKN_DNX_FTMH_PP_DSP_MSB 33 @@ -711,6 +726,16 @@ typedef struct bkn_switch_info_s { #define BKN_DNX_FTMH_TM_DST_EXT_SIZE 3 #define BKN_DNX_FTMH_FLOW_ID_EXT_SIZE 3 #define BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE 6 +#define BKN_DNX_SYSPORTS_PER_DEVICE_MASK 0x3FF +/*ASE*/ +#define BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_MSB 0 +#define BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_NOF_BITS 4 +#define BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_DM_1588 2 +#define BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_DM_NTP 3 +#define BKN_DNX_FTMH_ASE_TYPE_MSB 47 +#define BKN_DNX_FTMH_ASE_TYPE_NOF_BITS 1 +#define BKN_DNX_FTMH_ASE_TYPE_OAM 0 + /* TSH */ #define BKN_DNX_TSH_SIZE 4 /* PPH */ @@ -768,6 +793,9 @@ typedef struct bkn_switch_info_s { #define BKN_DNX_UDH_DATA_TYPE_3_NOF_BITS 2 #define BKN_DNX_UDH_BASE_SIZE 1 +/* TOD SECOND header */ +#define BKN_DNX_TOD_SECOND_SIZE 4 + #define BKN_DPP_HDR_MAX_SIZE 40 /* PTCH_2 */ #define BKN_DPP_PTCH_2_SIZE 2 @@ -787,6 +815,8 @@ typedef struct bkn_switch_info_s { #define BKN_DPP_FTMH_TC_NOF_BITS 3 #define BKN_DPP_FTMH_SRC_SYS_PORT_MSB 17 #define BKN_DPP_FTMH_SRC_SYS_PORT_NOF_BITS 16 +#define BKN_DPP_FTMH_PP_DSP_MSB 33 +#define BKN_DPP_FTMH_PP_DSP_NOF_BITS 8 #define BKN_DPP_FTMH_EXT_DSP_EXIST_MSB 68 #define BKN_DPP_FTMH_EXT_DSP_EXIST_NOF_BITS 1 #define BKN_DPP_FTMH_EXT_MSB 45 @@ -927,11 +957,13 @@ typedef struct bkn_priv_s { uint32_t vlan; uint32_t flags; uint32_t cb_user_data; - uint8_t system_headers[27]; + uint8_t system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX]; uint32_t system_headers_size; int tx_hwts; /* HW timestamp for Tx */ int rx_hwts; /* HW timestamp for Rx */ int phys_port; + u32 ptp_stats_tx; + u32 ptp_stats_rx; struct ethtool_link_settings link_settings; } bkn_priv_t; @@ -979,6 +1011,7 @@ static knet_hw_tstamp_tx_time_get_cb_f knet_hw_tstamp_tx_time_get_cb = NULL; static knet_hw_tstamp_tx_meta_get_cb_f knet_hw_tstamp_tx_meta_get_cb = NULL; static knet_hw_tstamp_ptp_clock_index_cb_f knet_hw_tstamp_ptp_clock_index_cb = NULL; static knet_hw_tstamp_rx_time_upscale_cb_f knet_hw_tstamp_rx_time_upscale_cb = NULL; +static knet_hw_tstamp_rx_pre_process_cb_f knet_hw_tstamp_rx_pre_process_cb = NULL; static knet_hw_tstamp_ioctl_cmd_cb_f knet_hw_tstamp_ioctl_cmd_cb = NULL; static knet_netif_cb_f knet_netif_create_cb = NULL; static knet_netif_cb_f knet_netif_destroy_cb = NULL; @@ -1073,6 +1106,9 @@ bkn_sleep(int clicks) #define DEV_IS_CMIC(_sinfo) ((_sinfo)->cmic_type != 0) #define CDMA_CH(_d, _ch) ((_d)->cdma_channels & (1 << (_ch))) +/* Unet channel */ +#define UNET_CH(_d, _ch) ((_d)->unet_channels & (1 << (_ch))) + /* * DMA_STAT: control bits * @@ -1123,6 +1159,15 @@ bkn_sleep(int clicks) #define CMICX_DC_CMC_CTRLD_INT (0x00000080) #define CMICX_DC_CMC_CONTINUOUS (0x00000100) +/* Minimum packet header size for protect underflow. */ +#define CMICX_PKT_HDR_SIZE_MIN 8 +/* CMICX minimum packet header size for protect underflow. */ +#define CMICX_DCB_SIZE_MIN 16 +/* Minimum packet header size for protect underflow. */ +#define DCB_SIZE_MIN 20 +/* Maximum packet raw data size for filter validation. */ +#define KNET_FILTER_RAW_MAX 256 + /* * Per-channel operations. * These are the basis for the TX/RX functions @@ -1606,28 +1651,49 @@ xgsx_dma_chan_abort(bkn_switch_info_t *sinfo, int chan, int polls) return -1; } +static inline void +xgsx_irq_fmask_get(bkn_switch_info_t *sinfo, uint32_t *fmask) +{ + int chan, bits = 4, base = 0; + + if (fmask == NULL) { + return; + } + + *fmask = CMICX_TXRX_IRQ_MASK; + + for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + *fmask &= ~(((0x1 << bits) - 1) << ((XGS_DMA_RX_CHAN + chan) * bits + base)); + } + } + return; +} + static inline void xgsx_irq_mask_set(bkn_switch_info_t *sinfo, uint32_t mask) { uint32_t irq_mask_reg = CMICX_IRQ_ENABr; uint32_t irq_mask, irq_fmask, disable_mask; + uint32_t fmask = CMICX_TXRX_IRQ_MASK; if (sinfo->napi_poll_mode) { mask = 0; } + xgsx_irq_fmask_get(sinfo, &fmask); if (sinfo->cpu_no == 1) { lkbde_irq_mask_get(sinfo->dev_no, &irq_mask, &irq_fmask); disable_mask = ~mask & (irq_mask & irq_fmask); if (disable_mask) { lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, - IHOST_GIC_GIC400_GICD_ICENABLERN_5r, disable_mask, CMICX_TXRX_IRQ_MASK); + IHOST_GIC_GIC400_GICD_ICENABLERN_5r, disable_mask, fmask); } irq_mask_reg = IHOST_GIC_GIC400_GICD_ISENABLERN_5r; } lkbde_irq_mask_set(sinfo->dev_no | LKBDE_ISR2_DEV | LKBDE_IPROC_REG, - irq_mask_reg, mask, CMICX_TXRX_IRQ_MASK); + irq_mask_reg, mask, fmask); } static inline void @@ -2385,6 +2451,9 @@ bkn_dma_init(bkn_switch_info_t *sinfo) } for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } dev_dma_chan_init(sinfo, XGS_DMA_RX_CHAN + chan, 0); bkn_rx_refill(sinfo, chan); bkn_rx_restart(sinfo, chan); @@ -2457,13 +2526,16 @@ bkn_dma_abort(bkn_switch_info_t *sinfo) bkn_dma_abort_tx(sinfo); for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } bkn_dma_abort_rx(sinfo, chan); } return 0; } -static int +static inline int device_is_dpp(bkn_switch_info_t *sinfo) { int is_dpp = 0; @@ -2472,7 +2544,7 @@ device_is_dpp(bkn_switch_info_t *sinfo) return is_dpp; } -static int +static inline int device_is_dnx(bkn_switch_info_t *sinfo) { int is_dnx = 0; @@ -2482,15 +2554,16 @@ device_is_dnx(bkn_switch_info_t *sinfo) } /* is DPP or is DNX*/ -static int +static inline int device_is_sand(bkn_switch_info_t *sinfo) { - int is_sand = 0; + int is_dpp = 0; + int is_dnx = 0; - if (device_is_dpp(sinfo) || device_is_dnx(sinfo)) { - is_sand = 1; - } - return is_sand; + is_dpp = (sinfo->dcb_type == 28) ? 1 : 0; + is_dnx = (sinfo->dcb_type == 39) ? 1 : 0; + + return (is_dpp | is_dnx); } static bkn_filter_t * @@ -2507,6 +2580,9 @@ bkn_match_rx_pkt(bkn_switch_info_t *sinfo, uint8_t *pkt, int pktlen, list_for_each(list, &sinfo->rxpf_list) { filter = (bkn_filter_t *)list; kf = &filter->kf; + if (kf->pkt_data_offset + kf->pkt_data_size > pktlen) { + continue; + } memcpy(&scratch.data.b[0], &oob[kf->oob_data_offset], kf->oob_data_size); memcpy(&scratch.data.b[kf->oob_data_size], @@ -2620,20 +2696,21 @@ bkn_netif_lookup(bkn_switch_info_t *sinfo, int id) static int bkn_hw_tstamp_rx_set(bkn_switch_info_t *sinfo, int phys_port, struct sk_buff *skb, uint32 *meta) { - struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + int ret = -1; uint64_t ts = 0; + struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); if (knet_hw_tstamp_rx_time_upscale_cb) { - if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, phys_port, skb, meta, &ts) < 0) { - return -1; + if (knet_hw_tstamp_rx_time_upscale_cb(sinfo->dev_no, phys_port, skb, meta, &ts) >= 0) { + ret = 0; } } memset(shhwtstamps, 0, sizeof(*shhwtstamps)); shhwtstamps->hwtstamp = ns_to_ktime(ts); - return 0; + return ret; } static int @@ -2645,9 +2722,12 @@ bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta, in /* Add and clear RCPU encapsulation */ if (device_is_sand(sinfo)) { - psize = RCPU_RX_ENCAP_SIZE; + /* + * len is the length of Dune system headers + */ + psize = RCPU_HDR_SIZE + len; skb_push(skb, psize); - memset(skb->data, 0, RCPU_RX_ENCAP_SIZE); + memset(skb->data, 0, psize); } else if (sinfo->cmic_type == 'x') { psize = RCPU_HDR_SIZE + sinfo->pkt_hdr_size; skb_push(skb, psize); @@ -2677,13 +2757,17 @@ bkn_add_rcpu_encap(bkn_switch_info_t *sinfo, struct sk_buff *skb, void *meta, in skb->data[21] = RCPU_F_MODHDR; skb->data[24] = pktlen >> 8; skb->data[25] = pktlen & 0xff; + if (device_is_sand(sinfo)) { + /* RCPU.meta_len records length of Dune system headers */ + skb->data[28] = len & 0xff; + } /* Meta data */ dmeta = (uint32_t *)&skb->data[RCPU_HDR_SIZE]; if (device_is_sand(sinfo)) { - /* Copy at most 64 bytes system headers */ - len = len > RCPU_RX_META_SIZE ? RCPU_RX_META_SIZE : len; + /* Copy at most 256 bytes system headers */ + len = len > RCPU_RX_META_SIZE_MAX ? RCPU_RX_META_SIZE_MAX : len; memcpy(&skb->data[RCPU_HDR_SIZE], (uint8_t *)meta, len); } else { smeta = sinfo->cmic_type == 'x' ? (uint32_t *)meta : (uint32_t *)meta + 2; @@ -3133,7 +3217,8 @@ bkn_dnx_packet_parse_ftmh( uint32_t buf_len, bkn_dune_system_header_info_t *packet_info, uint8_t *is_tsh_en, - uint8_t *is_inter_hdr_en) + uint8_t *is_inter_hdr_en, + uint8_t *is_oam_dm_tod_second_en) { uint32_t fld_val; uint32_t pkt_offset = packet_info->system_header_size; @@ -3236,6 +3321,23 @@ bkn_dnx_packet_parse_ftmh( /* FTMH Application Specific Extension */ if (app_specific_ext_size > 0) { + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_FTMH_ASE_TYPE_MSB, + BKN_DNX_FTMH_ASE_TYPE_NOF_BITS, + &fld_val); + if (fld_val == BKN_DNX_FTMH_ASE_TYPE_OAM) { + /* ASE: OAM_SUB_TYPE */ + bkn_bitstream_get_field( + &buf[pkt_offset], + BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_MSB, + BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_NOF_BITS, + &fld_val); + if ((fld_val == BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_DM_1588) || + (fld_val == BKN_DNX_FTMH_ASE_OAM_SUB_TYPE_DM_NTP)) { + *is_oam_dm_tod_second_en = TRUE; + } + } pkt_offset += BKN_DNX_FTMH_APP_SPECIFIC_EXT_SIZE; DBG_DUNE(("FTMH Application Specific Extension(6-%u) is present\n", pkt_offset)); } @@ -3425,17 +3527,20 @@ bkn_dnx_packet_header_parse( uint32_t buff_len, bkn_dune_system_header_info_t *packet_info) { + uint8_t is_oam_dm_tod_second_en = FALSE; uint8_t is_inter_hdr_en = FALSE; uint8_t is_tsh_en = FALSE; uint8_t is_oamp_punted = FALSE; uint8_t is_trapped = FALSE; + uint8_t idx = 0; if ((sinfo == NULL) || (buff == NULL) || (packet_info == NULL)) { return -1; } /* FTMH */ - bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, + &is_tsh_en, &is_inter_hdr_en, &is_oam_dm_tod_second_en); /* Time-Stamp */ if (is_tsh_en == TRUE) @@ -3445,10 +3550,12 @@ bkn_dnx_packet_header_parse( } /* Check if packet was punted to CPU by OAMP */ - if ((packet_info->ftmh.source_sys_port_aggregate == 232) - || (packet_info->ftmh.source_sys_port_aggregate == 233)) + for (idx = 0; idx < sinfo->oamp_port_number; idx++) { - is_oamp_punted = TRUE; + if (packet_info->ftmh.source_sys_port_aggregate == sinfo->oamp_ports[idx]) + { + is_oamp_punted = TRUE; + } } /* Internal */ @@ -3456,16 +3563,24 @@ bkn_dnx_packet_header_parse( { bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); } + /* OAM DMM/DMR TOD second header */ + if (is_oam_dm_tod_second_en == TRUE) + { + packet_info->system_header_size += BKN_DNX_TOD_SECOND_SIZE; + DBG_DUNE(("TOD second Header(4-%u) is present\n", packet_info->system_header_size)); + } if (is_oamp_punted) { + is_oam_dm_tod_second_en = FALSE; is_inter_hdr_en = FALSE; is_tsh_en = FALSE; is_oamp_punted = FALSE; is_trapped = FALSE; /* FTMH */ - bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, &is_tsh_en, &is_inter_hdr_en); + bkn_dnx_packet_parse_ftmh(sinfo, buff, buff_len, packet_info, + &is_tsh_en, &is_inter_hdr_en, &is_oam_dm_tod_second_en); /* Time-Stamp */ if (is_tsh_en == TRUE) { @@ -3477,13 +3592,17 @@ bkn_dnx_packet_header_parse( { bkn_dnx_packet_parse_internal(sinfo, buff, buff_len, packet_info, is_oamp_punted, &is_trapped); } + if (is_oam_dm_tod_second_en == TRUE) + { + /* DO NOT have 4Bytes TOD second header. */ + } } DBG_DUNE(("Total length of headers is %u\n", packet_info->system_header_size)); return 0; } - + static int bkn_packet_header_parse(bkn_switch_info_t *sinfo, uint8_t *buf, uint32_t buf_len, bkn_dune_system_header_info_t *packet_info) { @@ -3514,14 +3633,14 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) bkn_dcb_chain_t *dcb_chain; struct sk_buff *skb; bkn_filter_t cbf; - bkn_filter_t *filter; + bkn_filter_t *filter = NULL; uint32_t err_woff; - uint32_t *dcb, *meta; + uint32_t *dcb, *meta, *match_data; uint8_t *pkt; uint64_t pkt_dma; int drop_api; int ethertype; - int pktlen; + int pktlen, pkt_hdr_size; int idx; int dcbs_done = 0; bkn_dune_system_header_info_t packet_info; @@ -3568,11 +3687,17 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) pkt_dma = dcb[0]; } pkt = (uint8_t *)kernel_bde->p2l(sinfo->dev_no, (sal_paddr_t)pkt_dma); + pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); if (device_is_sand(sinfo)) { err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; meta = (uint32_t *)pkt; + memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); + /* Decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + pkt_hdr_size = packet_info.system_header_size; } else { if (sinfo->cmic_type == 'x') { meta = (uint32_t *)pkt; @@ -3582,71 +3707,81 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) meta = dcb; err_woff = sinfo->dcb_wsize - 1; } + pkt_hdr_size = sinfo->pkt_hdr_size; } - pktlen = dcb[sinfo->dcb_wsize-1] & SOC_DCB_KNET_COUNT_MASK; - bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - - if (device_is_sand(sinfo)) { - memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - /* decode system headers and fill sratch data */ - bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); - bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); - bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); - bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); - bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); - - if (force_tagged) { - uint8_t *eth_hdr = pkt + packet_info.system_header_size; - uint16_t tpid = 0; - - tpid = PKT_U16_GET(eth_hdr, 12); - if (packet_is_untagged(tpid)) { - int raw_packet_len = pktlen - packet_info.system_header_size; - uint32_t vid = 0; - - if ((pktlen + 4) < rx_buffer_size) { - for (idx = (raw_packet_len - 1); idx >= 12; idx--) { - eth_hdr[idx+4] = eth_hdr[idx]; - } - if (ft_vid) { - vid = ft_vid; - } - else if (packet_info.internal.forward_domain) { - vid = packet_info.internal.forward_domain & 0xfff; - } - else { - vid = 1; + /* Minimun size: header_size + MACs + VLAN + ETH_TYPE */ + if (pktlen > pkt_hdr_size + 18) { + if (device_is_sand(sinfo)) { + bkn_bitstream_set_field(sand_scratch_data, 0, 16, + packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, + packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, + packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, + packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, + packet_info.ftmh.action_type); + + if (force_tagged) { + uint8_t *eth_hdr = pkt + pkt_hdr_size; + uint16_t tpid = 0; + + tpid = PKT_U16_GET(eth_hdr, 12); + if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - pkt_hdr_size; + uint32_t vid = 0; + + if ((pktlen + 4) < rx_buffer_size) { + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & + 0xfff; + } + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", + vid)); + + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | + ((ft_cfi & 0x1) << 4) | + ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; + /* Reset packet length in DCB */ + pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; + dcb[sinfo->dcb_wsize-1] |= pktlen & + SOC_DCB_KNET_COUNT_MASK; } - DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); - - eth_hdr[12] = (ft_tpid >> 8) & 0xff; - eth_hdr[13] = ft_tpid & 0xff; - eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; - eth_hdr[15] = vid & 0xff; - /* reset packet length in DCB */ - pktlen += 4; - bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } - } - if (device_is_sand(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, pkt + packet_info.system_header_size, - pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); - } else { - filter = bkn_match_rx_pkt(sinfo, pkt + sinfo->pkt_hdr_size, - pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); - } - if ((dcb[sinfo->dcb_wsize-1] & 0xf0000) != 0x30000) { - /* Fragment or error */ - if (filter && filter->kf.mask.w[err_woff] == 0) { - /* Drop unless DCB status is part of filter */ - filter = NULL; + if (device_is_sand(sinfo)) { + match_data = sand_scratch_data; + } else { + match_data = meta; + } + filter = bkn_match_rx_pkt(sinfo, pkt + pkt_hdr_size, + pktlen - pkt_hdr_size, match_data, + chan, &cbf); + + if ((dcb[sinfo->dcb_wsize-1] & 0xf0000) != 0x30000) { + /* Fragment or error */ + if (filter && filter->kf.mask.w[err_woff] == 0) { + /* Drop unless DCB status is part of filter */ + filter = NULL; + } } } drop_api = 1; @@ -3667,21 +3802,25 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) break; } - if (device_is_sand(sinfo)) { - pkt += packet_info.system_header_size; - pktlen -= packet_info.system_header_size; - } else if (sinfo->cmic_type == 'x') { - pkt += sinfo->pkt_hdr_size; - pktlen -= sinfo->pkt_hdr_size; - } + pkt += pkt_hdr_size; + pktlen -= pkt_hdr_size; /* Add 2 bytes for IP header alignment (see below) */ - skb = dev_alloc_skb(pktlen + RCPU_RX_ENCAP_SIZE + 2); - if (skb == NULL) { - sinfo->rx[chan].pkts_d_no_skb++; - break; + if (device_is_sand(sinfo)) { + skb = dev_alloc_skb(pktlen + RCPU_HDR_SIZE + pkt_hdr_size + 2); + if (skb == NULL) { + sinfo->rx[chan].pkts_d_no_skb++; + break; + } + skb_reserve(skb, RCPU_HDR_SIZE + pkt_hdr_size); + } else { + skb = dev_alloc_skb(pktlen + RCPU_RX_ENCAP_SIZE + 2); + if (skb == NULL) { + sinfo->rx[chan].pkts_d_no_skb++; + break; + } + skb_reserve(skb, RCPU_RX_ENCAP_SIZE); } - skb_reserve(skb, RCPU_RX_ENCAP_SIZE); DBG_FLTR(("Send to netif %d (%s)\n", priv->id, priv->dev->name)); @@ -3742,7 +3881,8 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; if (device_is_sand(sinfo)) { - skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); + skb = knet_rx_cb(skb, sinfo->dev_no, + sand_scratch_data); } else { skb = knet_rx_cb(skb, sinfo->dev_no, meta); @@ -3760,9 +3900,10 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) } if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); + bkn_add_rcpu_encap(sinfo, skb, meta, pkt_hdr_size); DBG_PDMP(("After add RCPU ENCAP\n")); - bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); + bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, + XGS_DMA_RX_CHAN); } skb->protocol = eth_type_trans(skb, skb->dev); if (filter->kf.dest_proto) { @@ -3771,8 +3912,12 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { bkn_eth_type_update(skb, ethertype); } - DBG_DUNE(("skb protocol 0x%04x\n",skb->protocol)); + DBG_DUNE(("skb protocol 0x%04x\n", skb->protocol)); + /* + * Disable configuration API while the spinlock is released. + */ + sinfo->cfg_api_locked = 1; /* Unlock while calling up network stack */ spin_unlock(&sinfo->lock); if (use_napi) { @@ -3781,6 +3926,8 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) netif_rx(skb); } spin_lock(&sinfo->lock); + /* Re-enable configuration API once spinlock is regained. */ + sinfo->cfg_api_locked = 0; if (filter->kf.mirror_type == KCOM_DEST_T_API || dbg_pkt_enable) { @@ -3817,6 +3964,84 @@ bkn_do_api_rx(bkn_switch_info_t *sinfo, int chan, int budget) return dcbs_done; } +/* + * Process skb to netif. + * Caller need to make sure dest_id is the valid net interface. + */ +static int +bkn_skb_rx_netif_process(bkn_switch_info_t *sinfo, int dest_id, int chan, + struct sk_buff *skb, bkn_filter_t *filter, + uint32 *rx_cb_meta, uint32 *meta, + int pkt_hdr_size, int pktlen, int ethertype) +{ + bkn_priv_t *priv; + + DBG_VERB(("Process SKB to netif %d\n", dest_id)); + priv = bkn_netif_lookup(sinfo, dest_id); + + if ((priv->flags & KCOM_NETIF_F_KEEP_RX_TAG) == 0) { + uint16_t vlan_proto; + + vlan_proto = PKT_U16_GET(skb->data, 12); + if ((filter->kf.flags & KCOM_FILTER_F_STRIP_TAG) == 0) { + /* + * Mark packet as VLAN-tagged, otherwise newer + * kernels will strip the tag. + */ + uint16_t tci = PKT_U16_GET(skb->data, 14); + + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { + bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); + } else { + if (vlan_proto == ETH_P_8021AD) { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021AD, tci); + } else { + bkn_vlan_hwaccel_put_tag + (skb, ETH_P_8021Q, tci); + } + } + } + } + + priv->stats.rx_packets++; + priv->stats.rx_bytes += skb->len; + skb->dev = priv->dev; + + if (knet_rx_cb != NULL) { + KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; + KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; + skb = knet_rx_cb(skb, sinfo->dev_no, rx_cb_meta); + if (skb == NULL) { + /* Consumed by call-back */ + sinfo->rx[chan].pkts_d_callback++; + priv->stats.rx_dropped++; + return -1; + } + } + + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { + bkn_add_rcpu_encap(sinfo, skb, meta, pkt_hdr_size); + DBG_PDMP(("After add RCPU ENCAP\n")); + bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, + XGS_DMA_RX_CHAN); + } + skb->protocol = eth_type_trans(skb, skb->dev); + if (filter->kf.dest_proto) { + skb->protocol = filter->kf.dest_proto; + } + if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { + bkn_eth_type_update(skb, ethertype); + } + DBG_DUNE(("skb protocol 0x%04x\n",skb->protocol)); + if (filter->kf.mirror_type == KCOM_DEST_T_NETIF && + filter->kf.mirror_proto) { + skb->protocol = filter->kf.mirror_proto; + } + + return 0; +} + static int bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) { @@ -3824,17 +4049,21 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) bkn_desc_info_t *desc; struct sk_buff *skb; bkn_filter_t cbf; - bkn_filter_t *filter; + bkn_filter_t *filter = NULL; uint32_t err_woff; - uint32_t *dcb, *meta; - int ethertype; - int pktlen; + uint32_t *dcb, *meta, *match_data; + int pktlen, pkt_hdr_size; + uint8_t skip_hdrlen = 0; + uint8_t eth_offset = 0; int idx; int dcbs_done = 0; bkn_dune_system_header_info_t packet_info = {0}; uint32_t sand_scratch_data[BKN_SAND_SCRATCH_DATA_SIZE] = {0}; - uint8_t sand_system_headers[RCPU_RX_META_SIZE] = {0}; + uint8_t sand_system_headers[RCPU_RX_META_SIZE_MAX] = {0}; uint8_t *pkt = NULL; + bkn_priv_t *mpriv; + struct sk_buff *mskb = NULL; + uint32_t *rx_cb_meta; if (!sinfo->rx[chan].running) { /* Rx not ready */ @@ -3872,11 +4101,39 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) BKN_DMA_FROMDEV); desc->skb_dma = 0; + pktlen = dcb[sinfo->dcb_wsize-1] & 0xffff; + priv = netdev_priv(sinfo->dev); + bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); + if (device_is_sand(sinfo)) { err_woff = BKN_SAND_SCRATCH_DATA_SIZE - 1; sand_scratch_data[err_woff] = dcb[sinfo->dcb_wsize-1]; meta = (uint32_t *)skb->data; pkt = skb->data; + memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); + /* Decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); + pkt_hdr_size = packet_info.system_header_size; + + + if (knet_hw_tstamp_rx_pre_process_cb) { + if ((knet_hw_tstamp_rx_pre_process_cb(sinfo->dev_no, pkt, packet_info.ftmh.source_sys_port_aggregate, NULL)) >= 0) { + skip_hdrlen = pkt_hdr_size; + sand_scratch_data[err_woff] = (pktlen - skip_hdrlen); + + meta = (uint32_t *)(skb->data + skip_hdrlen); + pkt = (skb->data + skip_hdrlen); + memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); + + /* Decode system headers and fill sratch data */ + bkn_packet_header_parse(sinfo, pkt, (uint32_t)(pktlen - skip_hdrlen), &packet_info); + pkt_hdr_size = packet_info.system_header_size; + + knet_hw_tstamp_rx_pre_process_cb(sinfo->dev_no, pkt + pkt_hdr_size, + packet_info.ftmh.source_sys_port_aggregate, (int *)ð_offset); + } + } + } else { if (sinfo->cmic_type == 'x') { meta = (uint32_t *)skb->data; @@ -3886,73 +4143,86 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) meta = dcb; err_woff = sinfo->dcb_wsize - 1; } + pkt_hdr_size = sinfo->pkt_hdr_size; } - pktlen = dcb[sinfo->dcb_wsize-1] & 0xffff; - priv = netdev_priv(sinfo->dev); - bkn_dump_pkt(skb->data, pktlen, XGS_DMA_RX_CHAN); - - if (device_is_sand(sinfo)) { - memset(&packet_info, 0, sizeof(bkn_dune_system_header_info_t)); - /* decode system headers and fill sratch data */ - bkn_packet_header_parse(sinfo, pkt, (uint32_t)pktlen, &packet_info); - bkn_bitstream_set_field(sand_scratch_data, 0, 16, packet_info.internal.trap_id); - bkn_bitstream_set_field(sand_scratch_data, 16, 16, packet_info.internal.trap_qualifier); - bkn_bitstream_set_field(sand_scratch_data, 32, 16, packet_info.ftmh.source_sys_port_aggregate); - bkn_bitstream_set_field(sand_scratch_data, 48, 16, packet_info.internal.forward_domain); - bkn_bitstream_set_field(sand_scratch_data, 64, 2, packet_info.ftmh.action_type); - memcpy(sand_system_headers, pkt, - ((packet_info.system_header_size > RCPU_RX_META_SIZE) ? RCPU_RX_META_SIZE : packet_info.system_header_size)); - meta = (uint32_t *)sand_system_headers; - if (force_tagged) { - uint8_t *eth_hdr = pkt + packet_info.system_header_size; - uint16_t tpid = 0; - - tpid = PKT_U16_GET(eth_hdr, 12); - if (packet_is_untagged(tpid)) { - int raw_packet_len = pktlen - packet_info.system_header_size; - uint32_t vid = 0; - - if ((pktlen + 4) < rx_buffer_size) { - for (idx = (raw_packet_len - 1); idx >= 12; idx--) { - eth_hdr[idx+4] = eth_hdr[idx]; - } - if (ft_vid) { - vid = ft_vid; - } - else if (packet_info.internal.forward_domain) { - vid = packet_info.internal.forward_domain & 0xfff; - } - else { - vid = 1; + /* Minimun size: header_size + MACs + VLAN + ETH_TYPE */ + if (pktlen > pkt_hdr_size + 18) { + if (device_is_sand(sinfo)) { + bkn_bitstream_set_field(sand_scratch_data, 0, 16, + packet_info.internal.trap_id); + bkn_bitstream_set_field(sand_scratch_data, 16, 16, + packet_info.internal.trap_qualifier); + bkn_bitstream_set_field(sand_scratch_data, 32, 16, + packet_info.ftmh.source_sys_port_aggregate); + bkn_bitstream_set_field(sand_scratch_data, 48, 16, + packet_info.internal.forward_domain); + bkn_bitstream_set_field(sand_scratch_data, 64, 2, + packet_info.ftmh.action_type); + memcpy(sand_system_headers, pkt, + ((pkt_hdr_size > RCPU_RX_META_SIZE_MAX) ? + RCPU_RX_META_SIZE_MAX : pkt_hdr_size)); + meta = (uint32_t *)sand_system_headers; + if (force_tagged) { + uint8_t *eth_hdr = pkt + pkt_hdr_size; + uint16_t tpid = 0; + + if (skip_hdrlen > 0) { + eth_hdr += eth_offset; + } + tpid = PKT_U16_GET(eth_hdr, 12); + if (packet_is_untagged(tpid)) { + int raw_packet_len = pktlen - pkt_hdr_size; + uint32_t vid = 0; + + if ((pktlen + 4) < rx_buffer_size) { + for (idx = (raw_packet_len - 1); idx >= 12; idx--) { + eth_hdr[idx+4] = eth_hdr[idx]; + } + if (ft_vid) { + vid = ft_vid; + } + else if (packet_info.internal.forward_domain) { + vid = packet_info.internal.forward_domain & + 0xfff; + } + else { + vid = 1; + } + DBG_DUNE(("add vlan tag (%d) to untagged packets\n", + vid)); + eth_hdr[12] = (ft_tpid >> 8) & 0xff; + eth_hdr[13] = ft_tpid & 0xff; + eth_hdr[14] = (((ft_pri & 0x7) << 5) | + ((ft_cfi & 0x1) << 4) | + ((vid >> 8) & 0xf)) & 0xff; + eth_hdr[15] = vid & 0xff; + /* reset packet length in DCB */ + pktlen += 4; + bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); + dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; + dcb[sinfo->dcb_wsize-1] |= pktlen & + SOC_DCB_KNET_COUNT_MASK; } - DBG_DUNE(("add vlan tag (%d) to untagged packets\n", vid)); - eth_hdr[12] = (ft_tpid >> 8) & 0xff; - eth_hdr[13] = ft_tpid & 0xff; - eth_hdr[14] = (((ft_pri & 0x7) << 5) | ((ft_cfi & 0x1) << 4) | ((vid >> 8) & 0xf)) & 0xff; - eth_hdr[15] = vid & 0xff; - /* reset packet length in DCB */ - pktlen += 4; - bkn_dump_pkt(pkt, pktlen, XGS_DMA_RX_CHAN); - dcb[sinfo->dcb_wsize-1] &= ~SOC_DCB_KNET_COUNT_MASK; - dcb[sinfo->dcb_wsize-1] |= pktlen & SOC_DCB_KNET_COUNT_MASK; } } } - } - if (device_is_sand(sinfo)) { - filter = bkn_match_rx_pkt(sinfo, skb->data + packet_info.system_header_size, - pktlen - packet_info.system_header_size, sand_scratch_data, chan, &cbf); - } else { - filter = bkn_match_rx_pkt(sinfo, skb->data + sinfo->pkt_hdr_size, - pktlen - sinfo->pkt_hdr_size, meta, chan, &cbf); - } - if ((dcb[sinfo->dcb_wsize-1] & 0xf0000) != 0x30000) { - /* Fragment or error */ - priv->stats.rx_errors++; - if (filter && filter->kf.mask.w[err_woff] == 0) { - /* Drop unless DCB status is part of filter */ - filter = NULL; + if (device_is_sand(sinfo)) { + match_data = sand_scratch_data; + } else { + match_data = meta; + } + filter = bkn_match_rx_pkt(sinfo, skb->data + pkt_hdr_size + skip_hdrlen, + pktlen - pkt_hdr_size, match_data, + chan, &cbf); + + if ((dcb[sinfo->dcb_wsize-1] & 0xf0000) != 0x30000) { + /* Fragment or error */ + priv->stats.rx_errors++; + if (filter && filter->kf.mask.w[err_woff] == 0) { + /* Drop unless DCB status is part of filter */ + filter = NULL; + } } } DBG_PKT(("Rx packet (%d bytes).\n", pktlen)); @@ -3967,6 +4237,8 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) case KCOM_DEST_T_NETIF: priv = bkn_netif_lookup(sinfo, filter->kf.dest_id); if (priv) { + int ethertype; + /* Check that software link is up */ if (!netif_carrier_ok(priv->dev)) { sinfo->rx[chan].pkts_d_no_link++; @@ -3976,9 +4248,11 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) priv->id, priv->dev->name)); sinfo->rx[chan].pkts_f_netif++; - if ((filter->kf.mirror_type == KCOM_DEST_T_API) || dbg_pkt_enable) { + if ((filter->kf.mirror_type == KCOM_DEST_T_API) || + dbg_pkt_enable) { sinfo->rx[chan].pkts_m_api++; - bkn_api_rx_copy_from_skb(sinfo, chan, desc, priv->rx_hwts); + bkn_api_rx_copy_from_skb(sinfo, chan, desc, + priv->rx_hwts); } if (device_is_sand(sinfo)) { @@ -3988,17 +4262,18 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) skb_put(skb, pktlen - 4); /* Strip CRC */ } - if (device_is_sand(sinfo)) { - skb_pull(skb, packet_info.system_header_size); - } else if (sinfo->cmic_type == 'x') { - skb_pull(skb, sinfo->pkt_hdr_size); - } + skb_pull(skb, (pkt_hdr_size + skip_hdrlen)); /* Optional SKB updates */ KNET_SKB_CB(skb)->dcb_type = sinfo->dcb_type & 0xFFFF; /* Do Rx timestamping */ if (priv->rx_hwts) { - bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, meta); + if ((bkn_hw_tstamp_rx_set(sinfo, priv->phys_port, skb, + meta)) >= 0) { + + /* Increment ptp rx counters. */ + priv->ptp_stats_rx++; + } } /* Save for RCPU before stripping tag */ @@ -4017,103 +4292,115 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) ((u32*)skb->data)[1] = ((u32*)skb->data)[0]; skb_pull(skb, 4); if (device_is_sand(sinfo)) { - for (idx = packet_info.system_header_size; idx >= 4; idx--) { + for (idx = pkt_hdr_size; idx >= 4; idx--) { pkt[idx] = pkt[idx - 4]; } } else if (sinfo->cmic_type == 'x') { - for (idx = sinfo->pkt_hdr_size / sizeof(uint32_t); idx; idx--) { + for (idx = pkt_hdr_size / sizeof(uint32_t); + idx; idx--) { meta[idx] = meta[idx - 1]; } meta++; } } - } else { - /* - * Mark packet as VLAN-tagged, otherwise newer - * kernels will strip the tag. - */ - uint16_t tci = PKT_U16_GET(skb->data, 14); + } + } + if (device_is_sand(sinfo)) { + rx_cb_meta = sand_scratch_data; + } else { + rx_cb_meta = meta; + } - if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_vlan_hwaccel_put_tag(skb, ETH_P_8021Q, tci); - } else { - if (vlan_proto == ETH_P_8021AD) { - bkn_vlan_hwaccel_put_tag - (skb, ETH_P_8021AD, tci); - } else { - bkn_vlan_hwaccel_put_tag - (skb, ETH_P_8021Q, tci); + if (mirror_local) { + /* Clone skb before processing netif specific config. */ + if (filter->kf.mirror_type == KCOM_DEST_T_NETIF) { + mpriv = bkn_netif_lookup(sinfo, filter->kf.mirror_id); + /* Clone skb for mirror_to netinf */ + if (mpriv && netif_carrier_ok(mpriv->dev)) { + mskb = skb_clone(skb, GFP_ATOMIC); + if (mskb == NULL) { + sinfo->rx[chan].pkts_d_no_skb++; } } } } - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len; - skb->dev = priv->dev; - - if (knet_rx_cb != NULL) { - KNET_SKB_CB(skb)->netif_user_data = priv->cb_user_data; - KNET_SKB_CB(skb)->filter_user_data = filter->kf.cb_user_data; - if (device_is_sand(sinfo)) { - skb = knet_rx_cb(skb, sinfo->dev_no, sand_scratch_data); - } - else { - skb = knet_rx_cb(skb, sinfo->dev_no, meta); - } - if (skb == NULL) { - /* Consumed by call-back */ - sinfo->rx[chan].pkts_d_callback++; - priv->stats.rx_dropped++; - desc->skb = NULL; - break; - } + /* Process original netif specific config. */ + if (bkn_skb_rx_netif_process(sinfo, filter->kf.dest_id, + chan, skb, filter, rx_cb_meta, + meta, pkt_hdr_size, pktlen, + ethertype)) { + desc->skb = NULL; + break; } - if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_add_rcpu_encap(sinfo, skb, meta, packet_info.system_header_size); - DBG_PDMP(("After add RCPU ENCAP\n")); - bkn_dump_pkt(skb->data, pktlen + RCPU_RX_ENCAP_SIZE, XGS_DMA_RX_CHAN); - } - skb->protocol = eth_type_trans(skb, skb->dev); - if (filter->kf.dest_proto) { - skb->protocol = filter->kf.dest_proto; - } - if (priv->flags & KCOM_NETIF_F_RCPU_ENCAP) { - bkn_eth_type_update(skb, ethertype); - } - DBG_DUNE(("skb protocol 0x%04x\n",skb->protocol)); - - if (filter->kf.mirror_type == KCOM_DEST_T_NETIF) { - bkn_priv_t *mpriv; - struct sk_buff *mskb; - mpriv = bkn_netif_lookup(sinfo, filter->kf.mirror_id); - if (mpriv && netif_carrier_ok(mpriv->dev)) { - mskb = skb_clone(skb, GFP_ATOMIC); - if (mskb == NULL) { - sinfo->rx[chan].pkts_d_no_skb++; - } else { - sinfo->rx[chan].pkts_m_netif++; - mpriv->stats.rx_packets++; - mpriv->stats.rx_bytes += mskb->len; - skb->dev = mpriv->dev; - if (filter->kf.mirror_proto) { - skb->protocol = filter->kf.mirror_proto; - } - /* Unlock while calling up network stack */ - spin_unlock(&sinfo->lock); - if (use_napi) { - netif_receive_skb(mskb); + if (mirror_local) { + if (mskb) { + /* Process mirorr_to netif specific config. */ + if (bkn_skb_rx_netif_process(sinfo, + filter->kf.mirror_id, + chan, mskb, filter, + rx_cb_meta, meta, + pkt_hdr_size, + pktlen, ethertype)){ + desc->skb = NULL; + break; + } + } + } else { + /* + * Clone skb processed with original netif specific + * config. + */ + /* Clone skb for mirror_to netinf */ + if (filter->kf.mirror_type == KCOM_DEST_T_NETIF) { + mpriv = bkn_netif_lookup(sinfo, filter->kf.mirror_id); + if (mpriv && netif_carrier_ok(mpriv->dev)) { + mskb = skb_clone(skb, GFP_ATOMIC); + if (mskb == NULL) { + sinfo->rx[chan].pkts_d_no_skb++; } else { - netif_rx(mskb); + mpriv->stats.rx_packets++; + mpriv->stats.rx_bytes += mskb->len; + mskb->dev = mpriv->dev; + if (filter->kf.mirror_proto) { + mskb->protocol = filter->kf.mirror_proto; + } } - spin_lock(&sinfo->lock); } } } + if (mskb) { + /* Send up to mirror_to netif */ + sinfo->rx[chan].pkts_m_netif++; + /* + * Disable configuration API while the spinlock + * is released. + */ + sinfo->cfg_api_locked = 1; + + /* Unlock while calling up network stack */ + spin_unlock(&sinfo->lock); + if (use_napi) { + netif_receive_skb(mskb); + } else { + netif_rx(mskb); + } + spin_lock(&sinfo->lock); + /* + * Re-enable configuration API once the spinlock + * is regained. + */ + sinfo->cfg_api_locked = 0; + } /* Ensure that we reallocate SKB for this DCB */ desc->skb = NULL; + /* + * Disable configuration API while the spinlock + * is released. + */ + sinfo->cfg_api_locked = 1; /* Unlock while calling up network stack */ spin_unlock(&sinfo->lock); @@ -4123,7 +4410,11 @@ bkn_do_skb_rx(bkn_switch_info_t *sinfo, int chan, int budget) netif_rx(skb); } spin_lock(&sinfo->lock); - + /* + * Re-enable configuration API once the spinlock + * is regained. + */ + sinfo->cfg_api_locked = 0; } else { DBG_FLTR(("Unknown netif %d\n", filter->kf.dest_id)); @@ -4336,7 +4627,7 @@ bkn_hw_tstamp_tx_work(struct work_struct *work) DBG_PTP(("2Step TX Timestamp fetch took long time %lld us\n", ktime_us_delta(now, skb->tstamp))); } -#else +#else DBG_PTP(("2Step TX Timestamp has not been taken for the current skb\n")); #endif } @@ -4375,7 +4666,7 @@ bkn_do_tx(bkn_switch_info_t *sinfo) (bkn_skb_tx_flags(desc->skb) & SKBTX_IN_PROGRESS)) { if (bkn_hw_tstamp_tx_set(sinfo, desc->skb) < 0) { - gprintk("Timestamp has not been taken for the current skb.\n"); + DBG_PTP(("1Step timestamp has not been taken for the current skb.\n")); } bkn_skb_tx_flags(desc->skb) &= ~SKBTX_IN_PROGRESS; } @@ -4649,6 +4940,9 @@ bkn_schedule_napi_poll(bkn_switch_info_t *sinfo) DBG_NAPI(("Schedule NAPI poll on %s.\n", sinfo->dev->name)); /* Disable interrupts until poll job is complete */ sinfo->napi_poll_mode = 1; + + /* Disable configuration API while the spinlock is released. */ + sinfo->cfg_api_locked = 1; /* Unlock while calling up network stack */ spin_unlock(&sinfo->lock); if (bkn_napi_schedule_prep(sinfo->dev, &sinfo->napi)) { @@ -4659,15 +4953,21 @@ bkn_schedule_napi_poll(bkn_switch_info_t *sinfo) gprintk("Warning: Unable to schedule NAPI - base device not up?\n"); } spin_lock(&sinfo->lock); + /* Re-enable configuration API once spinlock is regained. */ + sinfo->cfg_api_locked = 0; } static void bkn_napi_poll_complete(bkn_switch_info_t *sinfo) { + /* Disable configuration API while the spinlock is released. */ + sinfo->cfg_api_locked = 1; /* Unlock while calling up network stack */ spin_unlock(&sinfo->lock); bkn_napi_complete(sinfo->dev, &sinfo->napi); spin_lock(&sinfo->lock); + /* Re-enable configuration API once spinlock is regained. */ + sinfo->cfg_api_locked = 0; /* Re-enable interrupts */ sinfo->napi_poll_mode = 0; dev_irq_mask_set(sinfo, sinfo->irq_mask); @@ -4680,10 +4980,15 @@ xgs_do_dma(bkn_switch_info_t *sinfo, int budget) int chan_done, budget_chans = 0; uint32_t dma_stat; int chan; + int unet_chans = 0; DEV_READ32(sinfo, CMIC_DMA_STATr, &dma_stat); for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + unet_chans++; + continue; + } if (dma_stat & DS_DESC_DONE_TST(XGS_DMA_RX_CHAN + chan)) { xgs_dma_desc_clear(sinfo, XGS_DMA_RX_CHAN + chan); sinfo->poll_channels |= 1 << chan; @@ -4691,7 +4996,10 @@ xgs_do_dma(bkn_switch_info_t *sinfo, int budget) } if (!sinfo->poll_channels) { sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; - budget_chans = budget / sinfo->rx_chans; + sinfo->poll_channels &= ~(sinfo->unet_channels >> 1); + if (sinfo->rx_chans > unet_chans) { + budget_chans = budget / (sinfo->rx_chans - unet_chans); + } } else { for (chan = 0; chan < sinfo->rx_chans; chan++) { if (1 << chan & sinfo->poll_channels) { @@ -4712,6 +5020,9 @@ xgs_do_dma(bkn_switch_info_t *sinfo, int budget) } if (dma_stat & DS_CHAIN_DONE_TST(XGS_DMA_RX_CHAN + chan)) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } xgs_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); bkn_rx_chain_done(sinfo, chan); } @@ -4733,6 +5044,7 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) int chan_done, budget_chans = 0; uint32_t dma_stat, irq_stat = 0; int chan; + int unet_chans = 0; /* Get Controlled interrupt states for Continuous DMA mode */ if (sinfo->cdma_channels) { @@ -4742,6 +5054,10 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) DEV_READ32(sinfo, CMICM_DMA_STATr, &dma_stat); for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + unet_chans++; + continue; + } 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); @@ -4750,7 +5066,10 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) } if (!sinfo->poll_channels) { sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; - budget_chans = budget / sinfo->rx_chans; + sinfo->poll_channels &= ~(sinfo->unet_channels >> 1); + if (sinfo->rx_chans > unet_chans) { + budget_chans = budget / (sinfo->rx_chans - unet_chans); + } } else { for (chan = 0; chan < sinfo->rx_chans; chan++) { if (1 << chan & sinfo->poll_channels) { @@ -4775,6 +5094,9 @@ xgsm_do_dma(bkn_switch_info_t *sinfo, int budget) } if (dma_stat & (0x1 << (XGS_DMA_RX_CHAN + chan))) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } xgsm_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); bkn_rx_chain_done(sinfo, chan); } @@ -4801,16 +5123,24 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) int chan_done, budget_chans = 0; uint32_t irq_stat, tx_dma_stat, rx_dma_stat[NUM_CMICX_RX_CHAN]; int chan; + int unet_chans = 0; DEV_READ32(sinfo, CMICX_IRQ_STATr, &irq_stat); DEV_READ32(sinfo, CMICX_DMA_STATr + 0x80 * XGS_DMA_TX_CHAN, &tx_dma_stat); for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + unet_chans++; + continue; + } DEV_READ32(sinfo, CMICX_DMA_STATr + 0x80 * (XGS_DMA_RX_CHAN + chan), &rx_dma_stat[chan]); } for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } 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); @@ -4819,14 +5149,19 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) } if (!sinfo->poll_channels) { sinfo->poll_channels = (uint32_t)(1 << sinfo->rx_chans) - 1; - budget_chans = budget / sinfo->rx_chans; + sinfo->poll_channels &= ~(sinfo->unet_channels >> 1); + if (sinfo->rx_chans > unet_chans) { + budget_chans = budget / (sinfo->rx_chans - unet_chans); + } } else { for (chan = 0; chan < sinfo->rx_chans; chan++) { if (1 << chan & sinfo->poll_channels) { budget_chans++; } } - budget_chans = budget / budget_chans; + if (budget_chans) { + budget_chans = budget / budget_chans; + } } for (chan = 0; chan < sinfo->rx_chans; chan++) { @@ -4844,6 +5179,9 @@ xgsx_do_dma(bkn_switch_info_t *sinfo, int budget) } if (rx_dma_stat[chan] & CMICX_DS_CMC_DMA_CHAIN_DONE) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } xgsx_dma_chain_clear(sinfo, XGS_DMA_RX_CHAN + chan); bkn_rx_chain_done(sinfo, chan); } @@ -5044,6 +5382,9 @@ bkn_resume_rx(bkn_switch_info_t *sinfo) /* Resume Rx DMA on all channels */ for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } if (sinfo->rx[chan].use_rx_skb) { cdma_running = 0; bkn_api_rx_restart(sinfo, chan); @@ -5132,17 +5473,26 @@ bkn_set_mac_address(struct net_device *dev, void *addr) static int bkn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - bkn_priv_t *priv = netdev_priv(dev); - bkn_switch_info_t *sinfo = priv->sinfo; + bkn_priv_t *priv; + bkn_switch_info_t *sinfo; struct hwtstamp_config config; + if (!dev) + return -EINVAL; + + priv = netdev_priv(dev); + + if (!priv) + return -EINVAL; + + sinfo = priv->sinfo; + if (cmd == SIOCSHWTSTAMP) { if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) { return -EFAULT; } - if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb || - priv->type != KCOM_NETIF_T_PORT) { + if (!knet_hw_tstamp_enable_cb || !knet_hw_tstamp_disable_cb) { return -ENOSYS; } @@ -5345,6 +5695,8 @@ bkn_hw_tstamp_tx_config(bkn_switch_info_t *sinfo, } switch (sinfo->dcb_type) { + case 28: /* dpp */ + break; case 26: case 32: case 33: @@ -5380,7 +5732,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) uint16_t tpid; uint32_t *metadata; unsigned long flags; - uint32_t cpu_channel = 0; + uint8_t cpu_channel = 0; int headroom, tailroom; DBG_VERB(("Netif Tx: Len=%d priv->id=%d\n", skb->len, priv->id)); @@ -5417,6 +5769,14 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (device_is_sand(sinfo)) { hdrlen = priv->system_headers_size; + + /* Account for extra OAM-TS header. */ + if ((bkn_skb_tx_flags(skb) & SKBTX_HW_TSTAMP) && + (hdrlen > (BKN_DNX_PTCH_2_SIZE))) { + /* T_LOCAL_PORT intf will use PTCH_2 + ITMH */ + hdrlen += BKN_DPP_OTSH_SIZE_BYTE; + } + } else { hdrlen = (sinfo->cmic_type == 'x' ) ? PKT_TX_HDR_SIZE : 0; @@ -5447,8 +5807,8 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if (device_is_sand(sinfo)) { /* Dune devices don't use meta data */ sop = 0; - /* Get CPU channel from rcpu_hdr_t.reserved */ - cpu_channel = (skb->data[28] << 24) | (skb->data[29] << 16) | (skb->data[30] << 8) | (skb->data[31]); + /* Get CPU channel from RCPU.cpu_channel */ + cpu_channel = skb->data[29]; /* System headers are supposed to be set by users in RCPU mode. */ hdrlen = 0; } else if (skb->data[21] & RCPU_F_MODHDR) { @@ -5468,6 +5828,14 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) return 0; } if (sinfo->cmic_type != 'x') { + if (skb->len < (rcpulen + RCPU_TX_META_SIZE + 14)) { + DBG_WARN(("Tx drop: Invalid RCPU encapsulation\n")); + priv->stats.tx_dropped++; + sinfo->tx.pkts_d_rcpu_encap++; + dev_kfree_skb_any(skb); + spin_unlock_irqrestore(&sinfo->lock, flags); + return 0; + } rcpulen += RCPU_TX_META_SIZE; } } @@ -5847,7 +6215,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) if ((priv->port >= 0) && (priv->tx_hwts & HWTSTAMP_TX_ON)) { /* TwoStep Processing of ptp-packets */ KNET_SKB_CB(skb)->port = priv->phys_port; - bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, meta); + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, hdrlen, skb, meta); bkn_skb_tx_flags(skb) |= SKBTX_IN_PROGRESS; bkn_skb_tx_timestamp(skb); @@ -5857,7 +6225,7 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) /* OneStep Processing of ptp-packets */ KNET_SKB_CB(skb)->port = priv->phys_port; KNET_SKB_CB(skb)->ts = 0; - bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, PKT_TX_HDR_SIZE, skb, + bkn_hw_tstamp_tx_config(sinfo, priv->tx_hwts, hdrlen, skb, ((priv->port >= 0) ? meta : NULL)); if (KNET_SKB_CB(skb)->ts != 0) { @@ -5866,6 +6234,9 @@ bkn_tx(struct sk_buff *skb, struct net_device *dev) } } + + /* Increment ptp tx counters. */ + priv->ptp_stats_tx++; } /* Prepare for DMA */ @@ -5954,6 +6325,9 @@ bkn_timer_func(bkn_switch_info_t *sinfo) restart_timer = 0; for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } /* Restart channel if not running */ if (sinfo->rx[chan].running == 0) { bkn_rx_refill(sinfo, chan); @@ -6037,6 +6411,9 @@ bkn_rxtick_func(bkn_switch_info_t *sinfo) /* For debug purposes we maintain a rough actual packet rate */ if (++sinfo->rxticks >= sinfo->rxticks_per_sec) { for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } pkt_diff = sinfo->rx[chan].pkts - sinfo->rx[chan].pkts_ref; cur_jif = jiffies; ticks = cur_jif - sinfo->rx[chan].rate_jif; @@ -6049,6 +6426,9 @@ bkn_rxtick_func(bkn_switch_info_t *sinfo) /* Update tokens for Rx rate control */ for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } if (sinfo->rx[chan].tokens < sinfo->rx[chan].burst_max) { bkn_rx_add_tokens(sinfo, chan); } @@ -6154,6 +6534,8 @@ bkn_create_sinfo(int dev_no) sinfo->inst_id = INVALID_INSTANCE_ID; sinfo->evt_idx = -1; + /* Allow configuration process to get lock. */ + sinfo->cfg_api_locked = 0; spin_lock_init(&sinfo->lock); skb_queue_head_init(&sinfo->tx_ptp_queue); INIT_WORK(&sinfo->tx_ptp_work, bkn_hw_tstamp_tx_work); @@ -6236,10 +6618,21 @@ bkn_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) static int bkn_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) { - bkn_priv_t *priv = netdev_priv(dev); - bkn_switch_info_t *sinfo = priv->sinfo; + bkn_priv_t *priv; + bkn_switch_info_t *sinfo; + + if (!dev) + return -EINVAL; + + priv = netdev_priv(dev); + + if (!priv) + return -EINVAL; + + sinfo = priv->sinfo; switch (sinfo->dcb_type) { + case 28: /* dpp */ case 26: case 32: case 33: @@ -6340,9 +6733,7 @@ bkn_init_ndev(u8 *mac, char *name) if (dev->mtu == 0) { dev->mtu = rx_buffer_size; } - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) - dev->min_mtu = 68; dev->max_mtu = rx_buffer_size; #endif @@ -6519,6 +6910,9 @@ bkn_proc_rate_show(struct seq_file *m, void *v) seq_printf(m, "Rate control (unit %d):\n", unit); for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } seq_printf(m, " Rx%d max rate %8u\n", chan, sinfo->rx[chan].rate_max); seq_printf(m, " Rx%d max burst %8u\n", @@ -6961,6 +7355,7 @@ bkn_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " pkt_hdr_size: %d\n", sinfo->pkt_hdr_size); seq_printf(m, " rx_chans: %d\n", sinfo->rx_chans); seq_printf(m, " cdma_chans: 0x%x\n", sinfo->cdma_channels); + seq_printf(m, " unet_chans: 0x%x\n", sinfo->unet_channels); seq_printf(m, " irq_mask: 0x%x\n", sinfo->irq_mask); seq_printf(m, " dma_events: 0x%x\n", sinfo->dma_events); seq_printf(m, " dcb_dma: 0x%p\n", (void *)(sal_paddr_t)sinfo->dcb_dma); @@ -6969,6 +7364,12 @@ bkn_proc_debug_show(struct seq_file *m, void *v) seq_printf(m, " napi_poll_mode: %d\n", sinfo->napi_poll_mode); seq_printf(m, " inst_id: 0x%x\n", sinfo->inst_id); seq_printf(m, " evt_queue: %d\n", sinfo->evt_idx); + seq_printf(m, " oamp_port_num: %d {%d, %d, %d, %d}\n", + sinfo->oamp_port_number, + sinfo->oamp_ports[0], + sinfo->oamp_ports[1], + sinfo->oamp_ports[2], + sinfo->oamp_ports[3]); unit++; } @@ -7119,6 +7520,7 @@ struct file_operations bkn_proc_stats_file_ops = { release: single_release, }; + /* * Device Debug Statistics Proc Entry */ @@ -7295,6 +7697,116 @@ struct file_operations bkn_proc_dstats_file_ops = { release: single_release, }; +/* + * PTP Statistics Proc Entry + */ +static int +bkn_proc_ptp_stats_show(struct seq_file *m, void *v) +{ + int unit = 0; + struct list_head *list, *dlist; + bkn_switch_info_t *sinfo; + bkn_priv_t *priv; + struct net_device *dev; + int print_hdr_done = 0; + + + list_for_each(list, &_sinfo_list) { + sinfo = (bkn_switch_info_t *)list; + list_for_each(dlist, &sinfo->ndev_list) { + priv = (bkn_priv_t *)dlist; + dev = priv->dev; + if (dev) { + if (priv->tx_hwts || priv->rx_hwts) { + if (!print_hdr_done) { + seq_printf(m, "PTP message stats (unit %d):\n", unit); + seq_printf(m, "=============================\n\n"); + seq_printf(m, " %-10s| %-8s| %-8s| %-8s| %-12s| %-12s\n", + "intf", "tx_hwts", "rx_hwts", "phc_type", "tx_pkts", "rx_pkts"); + seq_printf(m, "======================================================================\n"); + print_hdr_done = 1; + } + seq_printf(m, " %-10s| %8d| %8d| %-8s| %12d| %12d\n", + dev->name, priv->tx_hwts, priv->rx_hwts, + (priv->tx_hwts & HWTSTAMP_TX_ONESTEP_SYNC ? "1-step": "2-step"), + priv->ptp_stats_tx, priv->ptp_stats_rx); + } + } + } + + unit++; + } + return 0; +} + +static int bkn_proc_ptp_stats_open(struct inode * inode, struct file * file) +{ + return single_open(file, bkn_proc_ptp_stats_show, NULL); +} + +/* + * PTP Statistics Proc Write Entry + * + * Where corresponds to the debug module parameter. + * + * Examples: + * clear + */ +static ssize_t +bkn_proc_ptp_stats_write(struct file *file, const char *buf, size_t count, loff_t *loff) +{ + struct list_head *list, *dlist; + bkn_switch_info_t *sinfo; + bkn_priv_t *priv; + struct net_device *dev; + char debug_str[40]; + char *ptr; + int clear_mask; + + if (count > sizeof(debug_str)) { + count = sizeof(debug_str) - 1; + debug_str[count] = '\0'; + } + if (copy_from_user(debug_str, buf, count)) { + return -EFAULT; + } + + clear_mask = 0; + if ((ptr = strstr(debug_str, "clear")) != NULL) { + clear_mask = ~0; + } else { + gprintk("Warning: unknown configuration setting\n"); + } + + if (clear_mask) { + + list_for_each(list, &_sinfo_list) { + sinfo = (bkn_switch_info_t *)list; + list_for_each(dlist, &sinfo->ndev_list) { + priv = (bkn_priv_t *)dlist; + dev = priv->dev; + if (dev) { + priv->ptp_stats_rx = 0; + priv->ptp_stats_tx = 0; + } + } + + } + } + + return count; +} + +struct file_operations bkn_proc_ptp_stats_file_ops = { + owner: THIS_MODULE, + open: bkn_proc_ptp_stats_open, + read: seq_read, + llseek: seq_lseek, + write: bkn_proc_ptp_stats_write, + release: single_release, +}; + + static int bkn_proc_init(void) { @@ -7324,6 +7836,10 @@ bkn_proc_init(void) if (entry == NULL) { return -1; } + PROC_CREATE(entry, "ptp_stats", 0666, bkn_proc_root, &bkn_proc_ptp_stats_file_ops); + if (entry == NULL) { + return -1; + } return 0; } @@ -7337,6 +7853,7 @@ bkn_proc_cleanup(void) remove_proc_entry("debug", bkn_proc_root); remove_proc_entry("stats", bkn_proc_root); remove_proc_entry("dstats", bkn_proc_root); + remove_proc_entry("ptp_stats", bkn_proc_root); return 0; } @@ -7370,6 +7887,11 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } + if (kmsg->dma_info.cnt < 1 || kmsg->dma_info.data.dcb_start == 0) { + kmsg->hdr.status = KCOM_E_PARAM; + return sizeof(kcom_msg_hdr_t); + } + dcb_chain = kmalloc(sizeof(*dcb_chain), GFP_KERNEL); if (dcb_chain == NULL) { gprintk("Fatal error: No memory for dcb_chain\n"); @@ -7435,7 +7957,7 @@ bkn_knet_dma_info(kcom_msg_dma_info_t *kmsg, int len) spin_lock_irqsave(&sinfo->lock, flags); chan = kmsg->dma_info.chan - 1; - if ((chan < 0) || (chan > sinfo->rx_chans)) { + if ((chan < 0) || (chan > sinfo->rx_chans) || UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { gprintk("Invalid RX DMA channel specified: %d\n", kmsg->dma_info.chan); kmsg->hdr.status = KCOM_E_PARAM; @@ -7621,6 +8143,30 @@ bkn_knet_version(kcom_msg_version_t *kmsg, int len) return sizeof(kcom_msg_version_t); } +/* + * Get lock when sinfo->cfg_api_locked is not set. + * This is used for protecting the resource which should not be freed/destroyed + * when KNET functions temporarily release lock for calling outside functions. + */ +static inline void +cfg_api_lock(bkn_switch_info_t *sinfo, unsigned long *flags) +{ + spin_lock_irqsave(&sinfo->lock, *flags); + while (sinfo->cfg_api_locked) { + spin_unlock_irqrestore(&sinfo->lock, *flags); + while (sinfo->cfg_api_locked) { + schedule(); + } + spin_lock_irqsave(&sinfo->lock, *flags); + } +} + +static inline void +cfg_api_unlock(bkn_switch_info_t *sinfo, unsigned long *flags) +{ + spin_unlock_irqrestore(&sinfo->lock, *flags); +} + static int bkn_knet_hw_reset(kcom_msg_hw_reset_t *kmsg, int len) { @@ -7636,7 +8182,7 @@ bkn_knet_hw_reset(kcom_msg_hw_reset_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); if (kmsg->channels == 0) { /* Clean all if no channels specified */ @@ -7650,6 +8196,9 @@ bkn_knet_hw_reset(kcom_msg_hw_reset_t *kmsg, int len) skb_queue_purge(&sinfo->tx_ptp_queue); } for (chan = 0; chan < sinfo->rx_chans; chan++) { + if (UNET_CH(sinfo, XGS_DMA_RX_CHAN + chan)) { + continue; + } if (kmsg->channels & (1 << (XGS_DMA_RX_CHAN + chan))) { bkn_dma_abort_rx(sinfo, chan); bkn_clean_rx_dcbs(sinfo, chan); @@ -7657,7 +8206,7 @@ bkn_knet_hw_reset(kcom_msg_hw_reset_t *kmsg, int len) } } - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); return sizeof(kcom_msg_hdr_t); } @@ -7679,7 +8228,14 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } - spin_lock_irqsave(&sinfo->lock, flags); + if ((kmsg->cmic_type == 'x' && kmsg->dcb_size < CMICX_DCB_SIZE_MIN) || + (kmsg->cmic_type != 'x' && kmsg->dcb_size < DCB_SIZE_MIN) || + (kmsg->dcb_type != 39 && kmsg->cmic_type == 'x' && kmsg->pkt_hdr_size < CMICX_PKT_HDR_SIZE_MIN)) { + kmsg->hdr.status = KCOM_E_PARAM; + return sizeof(kcom_msg_hdr_t); + } + + cfg_api_lock(sinfo, &flags); sinfo->cmic_type = kmsg->cmic_type; sinfo->dcb_type = kmsg->dcb_type; @@ -7695,14 +8251,18 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) sinfo->cmic_type, sinfo->dcb_type, sinfo->dcb_wsize, sinfo->dma_hi, sinfo->pkt_hdr_size)); + /* Config user network channels */ + sinfo->unet_channels = kmsg->unet_channels & ~(~0 << (sinfo->rx_chans + 1)); + /* Config Continuous DMA mode */ sinfo->cdma_channels = kmsg->cdma_channels & ~(~0 << (sinfo->rx_chans + 1)); + sinfo->cdma_channels = sinfo->cdma_channels & ~(sinfo->unet_channels); /* Ensure 32-bit PCI DMA is mapped properly on 64-bit platforms */ dev_type = kernel_bde->get_dev_type(sinfo->dev_no); if (dev_type & BDE_PCI_DEV_TYPE && sinfo->cmic_type != 'x') { if (pci_set_dma_mask(sinfo->pdev, 0xffffffff)) { - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); gprintk("No suitable DMA available for SKBs\n"); kmsg->hdr.status = KCOM_E_RESOURCE; return sizeof(kcom_msg_hdr_t); @@ -7712,7 +8272,7 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) /* First time called we need to allocate DCBs */ if (sinfo->dcb_mem == NULL) { if (bkn_alloc_dcbs(sinfo) < 0) { - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); kmsg->hdr.status = KCOM_E_RESOURCE; return sizeof(kcom_msg_hdr_t); } @@ -7761,7 +8321,57 @@ bkn_knet_hw_init(kcom_msg_hw_init_t *kmsg, int len) bkn_dma_init(sinfo); - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); + + return sizeof(kcom_msg_hdr_t); +} + +static int +bkn_knet_hw_info(kcom_msg_hw_info_t *kmsg, int len) +{ + bkn_switch_info_t *sinfo; + unsigned long flags; + int idx = 0; + + kmsg->hdr.type = KCOM_MSG_TYPE_RSP; + + DBG_KCOM(("HW INFO:-OAMP: %d {%d, %d, %d, %d}\n", + kmsg->oamp_info.oamp_port_number, + kmsg->oamp_info.oamp_ports[0], + kmsg->oamp_info.oamp_ports[1], + kmsg->oamp_info.oamp_ports[2], + kmsg->oamp_info.oamp_ports[3])); + + sinfo = bkn_sinfo_from_unit(kmsg->hdr.unit); + if (sinfo == NULL) { + kmsg->hdr.status = KCOM_E_PARAM; + return sizeof(kcom_msg_hdr_t); + } + + cfg_api_lock(sinfo, &flags); + + if (device_is_sand(sinfo)) { + if (kmsg->oamp_info.oamp_port_number > KCOM_HW_INFO_OAMP_PORT_MAX) + { + cfg_api_unlock(sinfo, &flags); + gprintk("Number of OAMP ports(%d) is greater than the maximum value allowed(%d)\n", + kmsg->oamp_info.oamp_port_number, + KCOM_HW_INFO_OAMP_PORT_MAX); + kmsg->hdr.status = KCOM_E_PARAM; + return sizeof(kcom_msg_hdr_t); + } + sinfo->oamp_port_number = kmsg->oamp_info.oamp_port_number; + for (idx = 0; idx < sinfo->oamp_port_number; idx++) { + sinfo->oamp_ports[idx] = kmsg->oamp_info.oamp_ports[idx]; + } + + for (idx = 0; idx < sinfo->oamp_port_number; idx++) { + DBG_DUNE(("DNX OAMP ports [%d/%d]: %d\n", + idx, sinfo->oamp_port_number, sinfo->oamp_ports[idx])); + } + } + + cfg_api_unlock(sinfo, &flags); return sizeof(kcom_msg_hdr_t); } @@ -7780,7 +8390,7 @@ bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); if (sinfo->evt_idx != -1) { /* Create dummy event to unblock pending IOCTL */ sinfo->dma_events |= KCOM_DMA_INFO_F_TX_DONE; @@ -7788,7 +8398,7 @@ bkn_knet_detach(kcom_msg_detach_t *kmsg, int len) evt->evt_wq_put++; wake_up_interruptible(&evt->evt_wq); } - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); /* Ensure that we return a valid unit number */ kmsg->hdr.unit = sinfo->dev_no; @@ -7838,6 +8448,15 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) kmsg->hdr.status = KCOM_E_PARAM; return sizeof(kcom_msg_hdr_t); } + if (device_is_sand(sinfo) && + kmsg->netif.system_headers_size > KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX) { + DBG_WARN(("The system_headers_size %d is beyond the maximum size %d. n", + kmsg->netif.system_headers_size, + KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX)); + kmsg->hdr.status = KCOM_E_PARAM; + return sizeof(kcom_msg_hdr_t); + } + ma = kmsg->netif.macaddr; if ((ma[0] | ma[1] | ma[2] | ma[3] | ma[4] | ma[5]) == 0) { bkn_dev_mac[5]++; @@ -7855,11 +8474,11 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) /* System headers are prepared at BCM API for Dune headers */ if (device_is_sand(sinfo)) { int idx = 0; - for (idx = 0; idx < KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX; idx++) + priv->system_headers_size = kmsg->netif.system_headers_size; + for (idx = 0; idx < priv->system_headers_size; idx++) { priv->system_headers[idx] = kmsg->netif.system_headers[idx]; } - priv->system_headers_size = kmsg->netif.system_headers_size; } if (priv->type == KCOM_NETIF_T_PORT) { priv->port = kmsg->netif.port; @@ -7953,7 +8572,8 @@ bkn_knet_netif_create(kcom_msg_netif_create_t *kmsg, int len) if (device_is_sand(sinfo)) { int idx = 0; for (idx = 0; idx < priv->system_headers_size; idx++) { - DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, priv->system_headers[idx])); + DBG_DUNE(("System Header[%d]: 0x%02x\n", idx, + priv->system_headers[idx])); } } @@ -7978,7 +8598,7 @@ bkn_knet_netif_destroy(kcom_msg_netif_destroy_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); found = 0; list_for_each(list, &sinfo->ndev_list) { @@ -7990,7 +8610,7 @@ bkn_knet_netif_destroy(kcom_msg_netif_destroy_t *kmsg, int len) } if (!found) { - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); kmsg->hdr.status = KCOM_E_NOT_FOUND; return sizeof(kcom_msg_hdr_t); } @@ -8008,7 +8628,7 @@ bkn_knet_netif_destroy(kcom_msg_netif_destroy_t *kmsg, int len) sinfo->ndevs[priv->id] = NULL; } - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); dev = priv->dev; DBG_VERB(("Removing virtual Ethernet device %s (%d).\n", @@ -8109,6 +8729,7 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) bkn_filter_t *filter, *lfilter; unsigned long flags; int found, id; + int oob_offset_max; kmsg->hdr.type = KCOM_MSG_TYPE_RSP; @@ -8126,6 +8747,25 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } + if (device_is_sand(sinfo)) { + oob_offset_max = BKN_SAND_SCRATCH_DATA_SIZE * 4; + } else if (sinfo->cmic_type == 'x') { + oob_offset_max = sinfo->pkt_hdr_size; + } else { + oob_offset_max = sinfo->dcb_wsize * 4; + } + + /* Validate filter data offsets and sizes. */ + if (kmsg->filter.oob_data_size + + kmsg->filter.pkt_data_size > KCOM_FILTER_BYTES_MAX || + kmsg->filter.oob_data_size + + kmsg->filter.oob_data_offset > oob_offset_max || + kmsg->filter.pkt_data_size + + kmsg->filter.pkt_data_offset > KNET_FILTER_RAW_MAX) { + kmsg->hdr.status = KCOM_E_PARAM; + return sizeof(kcom_msg_hdr_t); + } + spin_lock_irqsave(&sinfo->lock, flags); /* @@ -8182,15 +8822,20 @@ bkn_knet_filter_create(kcom_msg_filter_create_t *kmsg, int len) if (device_is_sand(sinfo)) { int idx, wsize; wsize = BYTES2WORDS(filter->kf.oob_data_size + filter->kf.pkt_data_size); - DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); + DBG_DUNE(("Filter: oob_data_size = %d pkt_data_size=%d wsize %d\n", + filter->kf.oob_data_size, filter->kf.pkt_data_size, wsize)); for (idx = 0; idx < wsize; idx++) { - DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, filter->kf.data.w[idx], filter->kf.mask.w[idx])); + DBG_DUNE(("OOB[%d]: 0x%08x [0x%08x]\n", idx, filter->kf.data.w[idx], + filter->kf.mask.w[idx])); } DBG_DUNE(("DNX system headers parameters:LB_KEY_EXT %d, STK_EXT %d, PPH_BASE %d, LIF_EXT %d %d %d, UDH_ENA %d, %d %d %d %d\n", - sinfo->ftmh_lb_key_ext_size, sinfo->ftmh_stacking_ext_size, sinfo->pph_base_size, - sinfo->pph_lif_ext_size[1],sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], - sinfo->udh_enable, sinfo->udh_length_type[0], sinfo->udh_length_type[1], sinfo->udh_length_type[2], sinfo->udh_length_type[3])); + sinfo->ftmh_lb_key_ext_size, sinfo->ftmh_stacking_ext_size, + sinfo->pph_base_size, sinfo->pph_lif_ext_size[1], + sinfo->pph_lif_ext_size[2], sinfo->pph_lif_ext_size[3], + sinfo->udh_enable, sinfo->udh_length_type[0], + sinfo->udh_length_type[1], sinfo->udh_length_type[2], + sinfo->udh_length_type[3])); } return len; } @@ -8212,7 +8857,7 @@ bkn_knet_filter_destroy(kcom_msg_filter_destroy_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); found = 0; list_for_each(list, &sinfo->rxpf_list) { @@ -8224,14 +8869,14 @@ bkn_knet_filter_destroy(kcom_msg_filter_destroy_t *kmsg, int len) } if (!found) { - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); kmsg->hdr.status = KCOM_E_NOT_FOUND; return sizeof(kcom_msg_hdr_t); } list_del(&filter->list); - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); DBG_VERB(("Removing filter ID %d.\n", filter->kf.id)); kfree(filter); @@ -8346,7 +8991,7 @@ bkn_knet_wb_cleanup(kcom_msg_wb_cleanup_t *kmsg, int len) return sizeof(kcom_msg_hdr_t); } - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); for (chan = 0; chan < sinfo->rx_chans; chan++) { if (sinfo->rx[chan].api_dcb_chain) { @@ -8365,7 +9010,7 @@ bkn_knet_wb_cleanup(kcom_msg_wb_cleanup_t *kmsg, int len) sinfo->rx[chan].api_active = 0; } - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); return sizeof(kcom_msg_hdr_t); } @@ -8405,6 +9050,11 @@ bkn_handle_cmd_req(kcom_msg_t *kmsg, int len) /* Initialize DMA */ len = bkn_knet_hw_init(&kmsg->hw_init, len); break; + case KCOM_M_HW_INFO: + DBG_CMD(("KCOM_M_HW_INFO\n")); + /* Initialize HW info DB */ + len = bkn_knet_hw_info(&kmsg->hw_info, len); + break; case KCOM_M_DETACH: DBG_CMD(("KCOM_M_DETACH\n")); /* Detach kernel module */ @@ -8594,12 +9244,12 @@ _cleanup(void) del_timer_sync(&sinfo->timer); del_timer_sync(&sinfo->rxtick); - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); if (DEV_IS_CMIC(sinfo)) { bkn_dma_abort(sinfo); dev_irq_mask_set(sinfo, 0); } - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); DBG_IRQ(("Unregister ISR.\n")); kernel_bde->interrupt_disconnect(sinfo->dev_no | LKBDE_ISR2_DEV); @@ -8610,10 +9260,10 @@ _cleanup(void) } } - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); bkn_clean_dcbs(sinfo); skb_queue_purge(&sinfo->tx_ptp_queue); - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); } /* Destroy all switch devices */ @@ -8668,11 +9318,11 @@ bkn_knet_dev_reinit(int d) DBG_VERB(("%s dev %d dev_state %d\n",__FUNCTION__, d, dev_state)); if (dev_state == BDE_DEV_STATE_CHANGED) { sinfo = bkn_sinfo_from_unit(d); - spin_lock_irqsave(&sinfo->lock, flags); + cfg_api_lock(sinfo, &flags); sinfo->base_addr = lkbde_get_dev_virt(d); sinfo->dma_dev = lkbde_get_dma_dev(d); sinfo->pdev = lkbde_get_hw_dev(d); - spin_unlock_irqrestore(&sinfo->lock, flags); + cfg_api_unlock(sinfo, &flags); dev_state = 0; lkbde_dev_state_set(d, dev_state); @@ -9170,6 +9820,28 @@ bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f return 0; } +int +bkn_hw_tstamp_rx_pre_process_cb_register(knet_hw_tstamp_rx_pre_process_cb_f hw_tstamp_rx_pre_process_cb) +{ + if (knet_hw_tstamp_rx_pre_process_cb != NULL) { + return -1; + } + knet_hw_tstamp_rx_pre_process_cb = hw_tstamp_rx_pre_process_cb; + return 0; +} + +int +bkn_hw_tstamp_rx_pre_process_cb_unregister(knet_hw_tstamp_rx_pre_process_cb_f hw_tstamp_rx_pre_process_cb) +{ + if (hw_tstamp_rx_pre_process_cb == NULL || + knet_hw_tstamp_rx_pre_process_cb != hw_tstamp_rx_pre_process_cb) { + return -1; + } + knet_hw_tstamp_rx_pre_process_cb = NULL; + return 0; +} + + int bkn_hw_tstamp_ioctl_cmd_cb_register(knet_hw_tstamp_ioctl_cmd_cb_f hw_tstamp_ioctl_cmd_cb) { @@ -9209,6 +9881,8 @@ LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_register); LKM_EXPORT_SYM(bkn_hw_tstamp_ptp_clock_index_cb_unregister); LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_register); LKM_EXPORT_SYM(bkn_hw_tstamp_rx_time_upscale_cb_unregister); +LKM_EXPORT_SYM(bkn_hw_tstamp_rx_pre_process_cb_register); +LKM_EXPORT_SYM(bkn_hw_tstamp_rx_pre_process_cb_unregister); LKM_EXPORT_SYM(bkn_hw_info_get); LKM_EXPORT_SYM(bkn_netif_create_cb_register); LKM_EXPORT_SYM(bkn_netif_create_cb_unregister); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h index 8d710869824f..2f15c83c6b17 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/include/bcm-knet.h @@ -83,6 +83,9 @@ typedef int typedef int (*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no); +typedef int +(*knet_hw_tstamp_rx_pre_process_cb_f)(int dev_no, uint8_t *pkt, uint32_t sspa, int *pkt_offset); + typedef int (*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, int phys_port, struct sk_buff *skb, uint32_t *meta, uint64_t *ts); @@ -137,6 +140,12 @@ bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw extern int bkn_hw_tstamp_ptp_clock_index_cb_unregister(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb); +extern int +bkn_hw_tstamp_rx_pre_process_cb_register(knet_hw_tstamp_rx_pre_process_cb_f hw_tstamp_rx_pre_process_cb); + +extern int +bkn_hw_tstamp_rx_pre_process_cb_unregister(knet_hw_tstamp_rx_pre_process_cb_f hw_tstamp_rx_pre_process_cb); + extern int bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb); diff --git a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c index 650a4ced1d7a..297ef7a1e478 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c +++ b/platform/broadcom/saibcm-modules/systems/linux/kernel/modules/knet-cb/knet-cb.c @@ -328,16 +328,50 @@ strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, return 0; } +#ifdef BCM_DNX_SUPPORT static int knet_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, int chan, kcom_filter_t *kf) { /* check for filter callback handler */ - #ifdef PSAMPLE_SUPPORT +#ifdef PSAMPLE_SUPPORT + if (strncmp(kf->desc, PSAMPLE_CB_NAME, strlen(PSAMPLE_CB_NAME)) == 0) { + return psample_filter_cb (pkt, size, dev_no, meta, chan, kf); + } +#endif + return strip_tag_filter_cb (pkt, size, dev_no, meta, chan, kf); +} + +static int +knet_netif_create_cb(int unit, kcom_netif_t *netif, uint16 spa, struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_create_cb(unit, netif, spa, dev); +#endif + return retv; +} + +static int +knet_netif_destroy_cb(int unit, kcom_netif_t *netif, uint16 spa, struct net_device *dev) +{ + int retv = 0; +#ifdef PSAMPLE_SUPPORT + retv = psample_netif_destroy_cb(unit, netif, spa, dev); +#endif + return retv; +} +#else +static int +knet_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta, + int chan, kcom_filter_t *kf) +{ + /* check for filter callback handler */ +#ifdef PSAMPLE_SUPPORT if (strncmp(kf->desc, PSAMPLE_CB_NAME, KCOM_FILTER_DESC_MAX) == 0) { return psample_filter_cb (pkt, size, dev_no, meta, chan, kf); } - #endif +#endif return strip_tag_filter_cb (pkt, size, dev_no, meta, chan, kf); } @@ -360,6 +394,7 @@ knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev) #endif return retv; } +#endif /* * Get statistics. @@ -395,7 +430,6 @@ _cleanup(void) #ifdef PSAMPLE_SUPPORT psample_cleanup(); #endif - return 0; } @@ -411,11 +445,9 @@ _init(void) bkn_tx_skb_cb_register(strip_tag_tx_cb); } - #ifdef PSAMPLE_SUPPORT +#ifdef PSAMPLE_SUPPORT psample_init(); - #endif - - +#endif bkn_filter_cb_register(knet_filter_cb); bkn_netif_create_cb_register(knet_netif_create_cb); bkn_netif_destroy_cb_register(knet_netif_destroy_cb); diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 8f59a763e314..3dc6425e6ee0 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -105,9 +105,6 @@ BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) PSAMPLE_LOCAL := psample.$(KOBJ) PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) -BCM_LPTP_LOCAL :=linux-bcm-ptp-clock.$(KOBJ) -BCM_LPTP=$(DEST_DIR)/$(BCM_LPTP_LOCAL) - ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -125,12 +122,6 @@ ifndef BUILD_KNET BUILD_KNET = 1 endif -# Remove this when LinuxPTP support becomes optional. -ifndef BUILD_LPTP -BUILD_LPTP = 1 -BUILD_KNETSYNC = 1 -endif - ifeq ($(BUILD_KNET),1) # Kernel network support all_targets += $(BCM_KNET) @@ -152,30 +143,7 @@ endif ifdef BUILD_PSAMPLE all_targets += $(PSAMPLE) ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT - -# KnetSync support -ifdef BUILD_KNETSYNC - -KERNEL_TARGETS += $(BCM_PTP_CLOCK) -LOCAL_KERNEL_TARGETS += $(patsubst %,$(realpath ..)/$(platform)/%,$(BCM_PTP_CLOCK_LOCAL)) - -endif # BUILD_KNETSYNC - -ifeq ($(NO_LOCAL_TARGETS),) - LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) - all_targets +=$(LOCAL_TARGETS) -endif -endif - -ifdef BUILD_LPTP - all_targets += $(BCM_LPTP) - -ifeq ($(NO_LOCAL_TARGETS),) - LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(BCM_LPTP_LOCAL)) - all_targets +=$(LOCAL_TARGETS) endif -endif - ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include COND_KNET_LIBS = libuser.$(libext) endif @@ -200,11 +168,6 @@ CFLAGS += $(ADD_TO_CFLAGS) #SAI_FIXUP CFLAGS:=$(filter-out -fPIC, $(CFLAGS)) -# KnetSync Support -ifdef BUILD_KNETSYNC - knetsync_subdirs = bcm-ptp-clock -endif # BUILD_KNETSYNC - kernel_modules: $(MAKE) -C $(SDK)/systems/bde/linux/kernel kernel_version=$(kernel_version) $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel kernel_version=$(kernel_version) @@ -219,10 +182,6 @@ ifdef BUILD_KNET_CB $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif -ifdef BUILD_LPTP - $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ - subdirs="bcm-ptp-clock" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" -endif endif $(KERNEL_BDE): $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) @@ -241,8 +200,7 @@ $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ -$(BCM_LPTP): $(KERN_BLDROOT)/linux-bcm-ptp-clock.$(KOBJ) - $(OBJCOPY) --strip-debug $< $@ + ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) @@ -252,10 +210,10 @@ clean:: $(MAKE) -C $(SDK)/systems/bde/linux/kernel $@ $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@ $(MAKE) -C $(SDK)/systems/linux/kernel/modules \ - subdirs="shared bcm-knet knet-cb psample bcm-ptp-clock" \ + subdirs="shared bcm-knet knet-cb psample" \ override-target=linux-$(platform) $@ $(RM) $(KERNEL_BDE) $(USER_BDE) - $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) $(BCM_LPTP) + $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) $(RM) $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile index 5acaeab271cc..d02c97e3f906 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/gts/Makefile @@ -62,8 +62,9 @@ endif export SDK -override kernel_version=4_19 +override kernel_version=5_4 platform=gts + LINUX_MAKE_USER=1 export LINKER_RELAX = 1 export ADD_TO_CFLAGS diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile index f10c5c37a082..7f2c7bc6e247 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc/Makefile @@ -55,7 +55,7 @@ endif export SDK -override kernel_version=4_14 +override kernel_version=5_4 platform=iproc IPROC_BUILD=1 diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile index 983b3abbced7..3f0a819d86f0 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/iproc_64/Makefile @@ -55,7 +55,7 @@ endif export SDK -override kernel_version=4_14 +override kernel_version=5_4 platform=iproc_64 IPROC_BUILD=1 diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile index e19eeff4aef2..377cf43ab68b 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/xlr/Makefile @@ -62,8 +62,9 @@ endif export SDK -override kernel_version=4_19 +override kernel_version=5_4 platform=xlr + LINUX_MAKE_USER=1 export LINKER_RELAX = 1 export ADD_TO_CFLAGS From 599797b7ac011a53019b02739416fbbebcb76546 Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Fri, 22 Oct 2021 05:56:23 +0000 Subject: [PATCH 4/8] update Makefiles and default MTU arg already set --- platform/broadcom/saibcm-modules/make/Make.config | 2 ++ .../make/Makefile.linux-x86-smp_generic_64-2_6 | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config index 88bf1740ea0b..b086aa3aa79b 100644 --- a/platform/broadcom/saibcm-modules/make/Make.config +++ b/platform/broadcom/saibcm-modules/make/Make.config @@ -172,6 +172,8 @@ CFLAGS += ${INCFLAGS} CXXFLAGS += ${INCFLAGS} CPPFLAGS += ${INCFLAGS} +CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1024 + # # Debug #ifdef control # diff --git a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 index 2f6b54f1b994..80dd9c97c07a 100644 --- a/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 +++ b/platform/broadcom/saibcm-modules/make/Makefile.linux-x86-smp_generic_64-2_6 @@ -39,6 +39,11 @@ ifeq (,$(KFLAGS)) KFLAGS := -nostdinc -isystem $(SYSINC) -I$(KERNDIR)/include -I$(KERNDIR)/arch/x86/include -include $(AUTOCONF) -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -Os -m64 -mtune=generic -mno-red-zone -fno-pie -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-stack-protector -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign endif +ifeq ($(LINUX_MAKE_SHARED_LIB), 1) + KFLAGS += -fPIC -mcmodel=small +else + KFLAGS += -fno-pie -mcmodel=kernel +endif LINUX_UAPI = $(LINUX_INCLUDE)/uapi ifneq (,$(shell ls $(LINUX_UAPI) 2>/dev/null)) From efcd6cefee77296ca7b2b79bb29ca3fcd3c18102 Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Fri, 22 Oct 2021 06:08:20 +0000 Subject: [PATCH 5/8] update changelog, update makefile to build psample and PTP clock kernel module --- .../broadcom/saibcm-modules/debian/changelog | 6 +++ .../systems/linux/user/common/Makefile | 48 +++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index 58468e30e799..dde38e21f1b1 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,3 +1,9 @@ +opennsl (6.0.0.0) unstable; urgency=medium + + * Update to Broadcom SAI 6.0.0.0 + + -- Vineet Mittal Fri, 21 Oct 2021 18:36:38 +0000 + opennsl (5.0.0.4) unstable; urgency=medium * Update to Broadcom SAI 5.0.0.4 diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 3dc6425e6ee0..8f59a763e314 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -105,6 +105,9 @@ BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL) PSAMPLE_LOCAL := psample.$(KOBJ) PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL) +BCM_LPTP_LOCAL :=linux-bcm-ptp-clock.$(KOBJ) +BCM_LPTP=$(DEST_DIR)/$(BCM_LPTP_LOCAL) + ifeq (,$(findstring DELIVER,$(MAKECMDGOALS))) .DEFAULT_GOAL := all all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE) @@ -122,6 +125,12 @@ ifndef BUILD_KNET BUILD_KNET = 1 endif +# Remove this when LinuxPTP support becomes optional. +ifndef BUILD_LPTP +BUILD_LPTP = 1 +BUILD_KNETSYNC = 1 +endif + ifeq ($(BUILD_KNET),1) # Kernel network support all_targets += $(BCM_KNET) @@ -143,7 +152,30 @@ endif ifdef BUILD_PSAMPLE all_targets += $(PSAMPLE) ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT + +# KnetSync support +ifdef BUILD_KNETSYNC + +KERNEL_TARGETS += $(BCM_PTP_CLOCK) +LOCAL_KERNEL_TARGETS += $(patsubst %,$(realpath ..)/$(platform)/%,$(BCM_PTP_CLOCK_LOCAL)) + +endif # BUILD_KNETSYNC + +ifeq ($(NO_LOCAL_TARGETS),) + LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL)) + all_targets +=$(LOCAL_TARGETS) +endif +endif + +ifdef BUILD_LPTP + all_targets += $(BCM_LPTP) + +ifeq ($(NO_LOCAL_TARGETS),) + LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(BCM_LPTP_LOCAL)) + all_targets +=$(LOCAL_TARGETS) endif +endif + ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include COND_KNET_LIBS = libuser.$(libext) endif @@ -168,6 +200,11 @@ CFLAGS += $(ADD_TO_CFLAGS) #SAI_FIXUP CFLAGS:=$(filter-out -fPIC, $(CFLAGS)) +# KnetSync Support +ifdef BUILD_KNETSYNC + knetsync_subdirs = bcm-ptp-clock +endif # BUILD_KNETSYNC + kernel_modules: $(MAKE) -C $(SDK)/systems/bde/linux/kernel kernel_version=$(kernel_version) $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel kernel_version=$(kernel_version) @@ -182,6 +219,10 @@ ifdef BUILD_KNET_CB $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" endif +ifdef BUILD_LPTP + $(MAKE) -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \ + subdirs="bcm-ptp-clock" override-target=linux-$(platform) CFLAGS="$(CFLAGS)" +endif endif $(KERNEL_BDE): $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) @@ -200,7 +241,8 @@ $(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ) $(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ) $(OBJCOPY) --strip-debug $< $@ - +$(BCM_LPTP): $(KERN_BLDROOT)/linux-bcm-ptp-clock.$(KOBJ) + $(OBJCOPY) --strip-debug $< $@ ifeq ($(NO_LOCAL_TARGETS),) $(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ)))) @@ -210,10 +252,10 @@ clean:: $(MAKE) -C $(SDK)/systems/bde/linux/kernel $@ $(MAKE) -C $(SDK)/systems/bde/linux/user/kernel $@ $(MAKE) -C $(SDK)/systems/linux/kernel/modules \ - subdirs="shared bcm-knet knet-cb psample" \ + subdirs="shared bcm-knet knet-cb psample bcm-ptp-clock" \ override-target=linux-$(platform) $@ $(RM) $(KERNEL_BDE) $(USER_BDE) - $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) + $(RM) $(BCM_KNET) $(KNET_CB) $(PSAMPLE) $(BCM_LPTP) $(RM) $(KERN_BLDROOT)/linux-kernel-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ) $(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ) From 99d7d562e9f51b7fff6859664599c981b310427e Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Fri, 22 Oct 2021 06:12:33 +0000 Subject: [PATCH 6/8] Updated opennsl kernel version --- platform/broadcom/sai-modules.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index cb33b9b46ffe..355805ea6c69 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,6 @@ # Broadcom SAI modules -BRCM_OPENNSL_KERNEL_VERSION = 5.0.0.4 +BRCM_OPENNSL_KERNEL_VERSION = 6.0.0.0 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules @@ -10,7 +10,7 @@ $(BRCM_OPENNSL_KERNEL)_MACHINE = broadcom SONIC_DPKG_DEBS += $(BRCM_OPENNSL_KERNEL) # SAI bcm modules for DNX family ASIC -BRCM_DNX_OPENNSL_KERNEL_VERSION = 5.0.0.4 +BRCM_DNX_OPENNSL_KERNEL_VERSION = 6.0.0.0 BRCM_DNX_OPENNSL_KERNEL = opennsl-modules-dnx_$(BRCM_DNX_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_DNX_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules-dnx From c338d9cd0c1a1337d0e43dbf9fc32cf7a8b2f1a9 Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Fri, 22 Oct 2021 06:35:17 +0000 Subject: [PATCH 7/8] Updated Make.config for saibcm-modules --- platform/broadcom/saibcm-modules/make/Make.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config index b086aa3aa79b..2d4536285a48 100644 --- a/platform/broadcom/saibcm-modules/make/Make.config +++ b/platform/broadcom/saibcm-modules/make/Make.config @@ -172,7 +172,7 @@ CFLAGS += ${INCFLAGS} CXXFLAGS += ${INCFLAGS} CPPFLAGS += ${INCFLAGS} -CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1024 +CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1025 -UKCOM_NETIF_MAX -DKCOM_NETIF_MAX=1056 # # Debug #ifdef control From 31a3b69fb7dd63f39afbd01af1503562f1ff28dd Mon Sep 17 00:00:00 2001 From: Vineet Mittal Date: Sat, 23 Oct 2021 00:12:26 +0000 Subject: [PATCH 8/8] Updated SAI version in changelog and make file --- platform/broadcom/sai-modules.mk | 4 ++-- platform/broadcom/saibcm-modules/debian/changelog | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 355805ea6c69..d4a523c949b5 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,6 @@ # Broadcom SAI modules -BRCM_OPENNSL_KERNEL_VERSION = 6.0.0.0 +BRCM_OPENNSL_KERNEL_VERSION = 6.0.0.10 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules @@ -10,7 +10,7 @@ $(BRCM_OPENNSL_KERNEL)_MACHINE = broadcom SONIC_DPKG_DEBS += $(BRCM_OPENNSL_KERNEL) # SAI bcm modules for DNX family ASIC -BRCM_DNX_OPENNSL_KERNEL_VERSION = 6.0.0.0 +BRCM_DNX_OPENNSL_KERNEL_VERSION = 6.0.0.10 BRCM_DNX_OPENNSL_KERNEL = opennsl-modules-dnx_$(BRCM_DNX_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_DNX_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules-dnx diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index dde38e21f1b1..127dce8af622 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,6 +1,6 @@ -opennsl (6.0.0.0) unstable; urgency=medium +opennsl (6.0.0.10) unstable; urgency=medium - * Update to Broadcom SAI 6.0.0.0 + * Update to Broadcom SAI 6.0.0.10 -- Vineet Mittal Fri, 21 Oct 2021 18:36:38 +0000