[broadom]: Upgrade broadcom SAI to 3.7.3.2
[Broadcom] : update saibcm-modules to sdk 6.5.16 [Broadcom SAI] : upgrade Broadcom SAI to 3.7.3.2
This commit is contained in:
parent
4458efbd71
commit
9c4c36e1b5
@ -1,3 +1,4 @@
|
||||
{% from "dockers/dockerfile-macros.j2" import install_debian_packages %}
|
||||
FROM docker-config-engine-stretch
|
||||
|
||||
ARG docker_container_name
|
||||
@ -14,10 +15,8 @@ debs/{{ deb }}{{' '}}
|
||||
{%- endfor -%}
|
||||
debs/
|
||||
|
||||
RUN dpkg -i \
|
||||
{% for deb in docker_syncd_brcm_debs.split(' ') -%}
|
||||
debs/{{ deb }}{{' '}}
|
||||
{%- endfor %}
|
||||
# Install locally-built Debian packages and implicitly install their dependencies
|
||||
{{ install_debian_packages(docker_syncd_brcm_debs.split(' ')) }}
|
||||
|
||||
## TODO: add kmod into Depends
|
||||
RUN apt-get install -yf kmod
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Broadcom SAI modules
|
||||
|
||||
KVERSION = 4.9.0-9-2-amd64
|
||||
BRCM_OPENNSL_KERNEL_VERSION = 3.4.1.11-1
|
||||
BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1
|
||||
|
||||
BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb
|
||||
$(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules
|
||||
|
@ -1,9 +1,9 @@
|
||||
BRCM_SAI = libsaibcm_3.5.3.1m-25_amd64.deb
|
||||
$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=zo83IKnlT7goymXwynW8%2Fx6rR2eIh0AiIS%2BSrSMUhRE%3D&se=2033-07-21T18%3A50%3A27Z&sp=r"
|
||||
BRCM_SAI = libsaibcm_3.7.3.3_amd64.deb
|
||||
$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=Y66VSRUEl4PDf5kHRo%2FS3DBBE9tONSyCzNJvi8IP9n8%3D&se=2033-08-25T01%3A22%3A08Z&sp=r"
|
||||
|
||||
BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1m-25_amd64.deb
|
||||
BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3_amd64.deb
|
||||
$(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV)))
|
||||
$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=tQmkCIy2mnb9rH7B9oXFUZDwijMGXWnVtta2CNTMbFM%3D&se=2033-07-21T18%3A50%3A47Z&sp=r"
|
||||
$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=6%2BWzgFL845H9lKE0COsN53P4MO4UWfSo0z%2FmUMFbYVk%3D&se=2033-08-25T01%3A21%3A50Z&sp=r"
|
||||
|
||||
SONIC_ONLINE_DEBS += $(BRCM_SAI)
|
||||
$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI)
|
||||
$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI)
|
@ -1,3 +1,24 @@
|
||||
opennsl (3.7.3.3-1) unstable; urgency=medium
|
||||
|
||||
* Port Broadcom SAI 3.7.3.3
|
||||
* Cherry-pick change from master branch, 3.7.3.3-1
|
||||
|
||||
-- Judy Joseph <jujoseph@microsoft.com> Fri, 2 Dec 2019 15:32:47 +0000
|
||||
|
||||
opennsl (3.7.3.2-1) unstable; urgency=medium
|
||||
|
||||
* Port Broadcom SAI 3.7.3.2
|
||||
* Cherry-pick change from master branch, 3.7.3.2-1
|
||||
|
||||
-- Judy Joseph <jujoseph@microsoft.com> Fri, 12 Nov 2019 15:22:47 +0000
|
||||
|
||||
opennsl (3.7.3.1-1) unstable; urgency=medium
|
||||
|
||||
* Port Broadcom SAI 3.7.3.1
|
||||
* Cherry-pick change from master branch, 3.7.3.1-1
|
||||
|
||||
-- Judy Joseph <jujoseph@microsoft.com> Fri, 19 Sep 2019 13:11:47 +0000
|
||||
|
||||
opennsl (3.4.1.11-1) unstable; urgency=medium
|
||||
|
||||
* Port Broadcom SAI 3.4.1.11
|
||||
|
@ -32,14 +32,38 @@ function create_devices()
|
||||
# level logs
|
||||
function load_kernel_modules()
|
||||
{
|
||||
modprobe linux-kernel-bde dmasize=32M maxpayload=128 debug=4 dma_debug=1
|
||||
. /host/machine.conf
|
||||
|
||||
if [ -n "$aboot_platform" ]; then
|
||||
platform=$aboot_platform
|
||||
elif [ -n "$onie_platform" ]; then
|
||||
platform=$onie_platform
|
||||
else
|
||||
platform="unknown"
|
||||
fi
|
||||
|
||||
# Set the default configuration for dmasize and usemsi parameters
|
||||
dmasize=32M
|
||||
usemsi=0
|
||||
|
||||
# Source the platform env file
|
||||
env_file="/usr/share/sonic/device/$platform/platform_env.conf"
|
||||
source $env_file
|
||||
|
||||
modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi
|
||||
modprobe linux-user-bde
|
||||
|
||||
# Using insmod with absolute path for psample to make sure bcm psample is loaded.
|
||||
# There is a different psample.ko module getting created at net/psample/psample.ko
|
||||
insmod /lib/modules/$(uname -r)/extra/psample.ko
|
||||
|
||||
modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020
|
||||
modprobe linux-knet-cb
|
||||
}
|
||||
|
||||
function remove_kernel_modules()
|
||||
{
|
||||
rmmod psample.ko
|
||||
rmmod linux-knet-cb
|
||||
rmmod linux-bcm-knet
|
||||
rmmod linux-user-bde
|
||||
|
@ -2,4 +2,5 @@ systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-9-
|
||||
systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-9-2-amd64/extra
|
||||
systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-9-2-amd64/extra
|
||||
systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-9-2-amd64/extra
|
||||
systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-9-2-amd64/extra
|
||||
systemd/opennsl-modules.service lib/systemd/system
|
||||
|
@ -60,7 +60,7 @@ kdist_config: prep-deb-files
|
||||
kdist_clean: clean
|
||||
dh_testdir
|
||||
dh_clean
|
||||
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
|
||||
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
|
||||
# rm -f driver/*.o driver/*.ko
|
||||
#
|
||||
### end KERNEL SETUP
|
||||
@ -78,7 +78,7 @@ build-arch-stamp:
|
||||
dh_testdir
|
||||
|
||||
# Add here command to compile/build the package.
|
||||
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6
|
||||
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6
|
||||
|
||||
touch $@
|
||||
|
||||
@ -103,7 +103,7 @@ clean:
|
||||
rm -f build-arch-stamp build-indep-stamp configure-stamp
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
|
||||
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
|
||||
|
||||
dh_clean
|
||||
|
||||
|
@ -148,14 +148,6 @@ typedef struct ibde_s {
|
||||
*/
|
||||
int (*get_cmic_ver)(int d, uint32 *ver);
|
||||
|
||||
/*
|
||||
* Probe available devices.
|
||||
* Return value :
|
||||
* 0: success to probe available devices
|
||||
* -1: error happens during probe
|
||||
*/
|
||||
int (*probe)(void);
|
||||
|
||||
/*
|
||||
* I2C operations on the Device, assuming it is connected by I2C to the CPU.
|
||||
*/
|
||||
|
@ -121,6 +121,13 @@ typedef struct kcom_msg_hdr_s {
|
||||
|
||||
#define KCOM_NETIF_NAME_MAX 16
|
||||
|
||||
/*
|
||||
* Max size of Sand System Headers
|
||||
* For DNX, Module Header(20B) + PTCH(2B) + ITMH(5B)
|
||||
* For DPP, PTCH(2B) + ITMH(4B)
|
||||
*/
|
||||
#define KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX 27
|
||||
|
||||
typedef struct kcom_netif_s {
|
||||
uint16 id;
|
||||
uint8 type;
|
||||
@ -133,6 +140,8 @@ typedef struct kcom_netif_s {
|
||||
uint8 macaddr[6];
|
||||
uint8 ptch[2];
|
||||
uint8 itmh[4];
|
||||
uint8 system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX];
|
||||
uint8 system_headers_size;
|
||||
char name[KCOM_NETIF_NAME_MAX];
|
||||
} kcom_netif_t;
|
||||
|
||||
@ -216,6 +225,13 @@ typedef struct kcom_filter_s {
|
||||
uint8 b[KCOM_FILTER_BYTES_MAX];
|
||||
uint32 w[KCOM_FILTER_WORDS_MAX];
|
||||
} mask;
|
||||
/** Information to parse Dune system headers */
|
||||
uint32 ftmh_lb_key_ext_size;
|
||||
uint32 ftmh_stacking_ext_size;
|
||||
uint32 pph_base_size;
|
||||
uint32 pph_lif_ext_size[8];
|
||||
uint8 udh_enable;
|
||||
uint32 udh_length_type[4];
|
||||
} kcom_filter_t;
|
||||
|
||||
/*
|
||||
@ -470,8 +486,7 @@ typedef struct kcom_msg_filter_destroy_s {
|
||||
* Get list of currently defined packet filters.
|
||||
*/
|
||||
#ifndef KCOM_FILTER_MAX
|
||||
/* SAI_FIXUP - Increased the filters to 1024 from 128 */
|
||||
#define KCOM_FILTER_MAX 1024
|
||||
#define KCOM_FILTER_MAX 128
|
||||
#endif
|
||||
|
||||
typedef struct kcom_msg_filter_list_s {
|
||||
|
@ -14,7 +14,7 @@
|
||||
* version 2 (GPLv2) along with this source code.
|
||||
*/
|
||||
/*
|
||||
* Copyright: (c) 2018 Broadcom.
|
||||
* Copyright: (c) 2019 Broadcom.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
@ -835,31 +835,6 @@
|
||||
#define BCM56746_A0_REV_ID 1
|
||||
#define BCM56746_A1_REV_ID 2
|
||||
|
||||
#define BCM88230_DEVICE_ID 0x0230
|
||||
#define BCM88230_A0_REV_ID 1
|
||||
#define BCM88230_B0_REV_ID 0x11
|
||||
#define BCM88230_C0_REV_ID 0x21
|
||||
#define BCM88231_DEVICE_ID 0x0231
|
||||
#define BCM88231_A0_REV_ID 1
|
||||
#define BCM88231_B0_REV_ID 0x11
|
||||
#define BCM88231_C0_REV_ID 0x21
|
||||
#define BCM88235_DEVICE_ID 0x0235
|
||||
#define BCM88235_A0_REV_ID 1
|
||||
#define BCM88235_B0_REV_ID 0x11
|
||||
#define BCM88235_C0_REV_ID 0x21
|
||||
#define BCM88236_DEVICE_ID 0x0236
|
||||
#define BCM88236_A0_REV_ID 1
|
||||
#define BCM88236_B0_REV_ID 0x11
|
||||
#define BCM88236_C0_REV_ID 0x21
|
||||
#define BCM88239_DEVICE_ID 0x0239
|
||||
#define BCM88239_A0_REV_ID 1
|
||||
#define BCM88239_B0_REV_ID 0x11
|
||||
#define BCM88239_C0_REV_ID 0x21
|
||||
#define BCM56613_DEVICE_ID 0xb613
|
||||
#define BCM56613_A0_REV_ID 1
|
||||
#define BCM56613_B0_REV_ID 0x11
|
||||
#define BCM56613_C0_REV_ID 0x21
|
||||
|
||||
#define BCM88732_DEVICE_ID 0x0732
|
||||
#define BCM88732_A0_REV_ID 1
|
||||
#define BCM88732_A1_REV_ID 2
|
||||
@ -1243,10 +1218,13 @@
|
||||
#define BCM56981_A0_REV_ID 1
|
||||
#define BCM56982_DEVICE_ID 0xb982
|
||||
#define BCM56982_A0_REV_ID 1
|
||||
#define BCM56982_B0_REV_ID 0x11
|
||||
#define BCM56983_DEVICE_ID 0xb983
|
||||
#define BCM56983_A0_REV_ID 1
|
||||
#define BCM56983_B0_REV_ID 0x11
|
||||
#define BCM56984_DEVICE_ID 0xb984
|
||||
#define BCM56984_A0_REV_ID 1
|
||||
#define BCM56984_B0_REV_ID 0x11
|
||||
|
||||
#define BCM56968_DEVICE_ID 0xb968
|
||||
#define BCM56968_A0_REV_ID 1
|
||||
@ -1428,33 +1406,43 @@
|
||||
|
||||
#define BCM56370_DEVICE_ID 0xb370
|
||||
#define BCM56370_A0_REV_ID 1
|
||||
#define BCM56370_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56371_DEVICE_ID 0xb371
|
||||
#define BCM56371_A0_REV_ID 1
|
||||
#define BCM56371_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56372_DEVICE_ID 0xb372
|
||||
#define BCM56372_A0_REV_ID 1
|
||||
#define BCM56372_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56374_DEVICE_ID 0xb374
|
||||
#define BCM56374_A0_REV_ID 1
|
||||
#define BCM56374_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56375_DEVICE_ID 0xb375
|
||||
#define BCM56375_A0_REV_ID 1
|
||||
#define BCM56375_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56376_DEVICE_ID 0xb376
|
||||
#define BCM56376_A0_REV_ID 1
|
||||
#define BCM56376_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56377_DEVICE_ID 0xb377
|
||||
#define BCM56377_A0_REV_ID 1
|
||||
#define BCM56377_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56577_DEVICE_ID 0xb577
|
||||
#define BCM56577_A0_REV_ID 1
|
||||
#define BCM56577_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56578_DEVICE_ID 0xb578
|
||||
#define BCM56578_A0_REV_ID 1
|
||||
#define BCM56578_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56579_DEVICE_ID 0xb579
|
||||
#define BCM56579_A0_REV_ID 1
|
||||
#define BCM56579_A1_REV_ID 0x02
|
||||
|
||||
#define BCM56770_DEVICE_ID 0xb770
|
||||
#define BCM56770_A0_REV_ID 1
|
||||
@ -1488,247 +1476,6 @@
|
||||
|
||||
#define BROADCOM_PHYID_HIGH 0x0040
|
||||
|
||||
#define BCM5338_PHYID_LOW 0x62b0
|
||||
#define BCM5338_A0_REV_ID 0
|
||||
#define BCM5338_A1_REV_ID 1
|
||||
#define BCM5338_B0_REV_ID 3
|
||||
|
||||
#define BCM5324_PHYID_LOW 0xbc20
|
||||
#define BCM5324_PHYID_HIGH 0x143
|
||||
#define BCM5324_A1_PHYID_HIGH 0x153
|
||||
#define BCM5324_DEVICE_ID 0xbc20
|
||||
#define BCM5324_A0_REV_ID 0
|
||||
#define BCM5324_A1_REV_ID 1
|
||||
#define BCM5324_A2_REV_ID 2
|
||||
|
||||
#define BCM5380_PHYID_LOW 0x6250
|
||||
#define BCM5380_A0_REV_ID 0
|
||||
|
||||
#define BCM5388_PHYID_LOW 0x6288
|
||||
#define BCM5388_A0_REV_ID 0
|
||||
|
||||
#define BCM5396_PHYID_LOW 0xbd70
|
||||
#define BCM5396_PHYID_HIGH 0x143
|
||||
#define BCM5396_DEVICE_ID 0x96
|
||||
#define BCM5396_A0_REV_ID 0
|
||||
|
||||
#define BCM5389_PHYID_LOW 0xbd70
|
||||
#define BCM5389_PHYID_HIGH 0x143
|
||||
#define BCM5389_DEVICE_ID 0x89
|
||||
#define BCM5389_A0_REV_ID 0
|
||||
#define BCM5389_A1_DEVICE_ID 0x86
|
||||
#define BCM5389_A1_REV_ID 1
|
||||
|
||||
#define BCM5398_PHYID_LOW 0xbcd0
|
||||
#define BCM5398_PHYID_HIGH 0x0143
|
||||
#define BCM5398_DEVICE_ID 0x98
|
||||
#define BCM5398_A0_REV_ID 0
|
||||
|
||||
#define BCM5325_PHYID_LOW 0xbc30
|
||||
#define BCM5325_PHYID_HIGH 0x143
|
||||
#define BCM5325_DEVICE_ID 0xbc30
|
||||
#define BCM5325_A0_REV_ID 0
|
||||
#define BCM5325_A1_REV_ID 1
|
||||
|
||||
#define BCM5348_PHYID_LOW 0xbe40
|
||||
#define BCM5348_PHYID_HIGH 0x0143
|
||||
#define BCM5348_DEVICE_ID 0x48
|
||||
#define BCM5348_A0_REV_ID 0
|
||||
#define BCM5348_A1_REV_ID 1
|
||||
|
||||
#define BCM5397_PHYID_LOW 0xbcd0
|
||||
#define BCM5397_PHYID_HIGH 0x0143
|
||||
#define BCM5397_DEVICE_ID 0x97
|
||||
#define BCM5397_A0_REV_ID 0
|
||||
|
||||
#define BCM5347_PHYID_LOW 0xbe40
|
||||
#define BCM5347_PHYID_HIGH 0x0143
|
||||
#define BCM5347_DEVICE_ID 0x47
|
||||
#define BCM5347_A0_REV_ID 0
|
||||
|
||||
#define BCM5395_PHYID_LOW 0xbcf0
|
||||
#define BCM5395_PHYID_HIGH 0x0143
|
||||
#define BCM5395_DEVICE_ID 0xbcf0
|
||||
#define BCM5395_A0_REV_ID 0
|
||||
|
||||
#define BCM53242_PHYID_LOW 0xbf10
|
||||
#define BCM53242_PHYID_HIGH 0x0143
|
||||
#define BCM53242_DEVICE_ID 0xbf10
|
||||
#define BCM53242_A0_REV_ID 0
|
||||
#define BCM53242_B0_REV_ID 4
|
||||
#define BCM53242_B1_REV_ID 5
|
||||
|
||||
#define BCM53262_PHYID_LOW 0xbf20
|
||||
#define BCM53262_PHYID_HIGH 0x0143
|
||||
#define BCM53262_DEVICE_ID 0xbf20
|
||||
#define BCM53262_A0_REV_ID 0
|
||||
#define BCM53262_B0_REV_ID 4
|
||||
#define BCM53262_B1_REV_ID 5
|
||||
|
||||
#define BCM53115_PHYID_LOW 0xbf80
|
||||
#define BCM53115_PHYID_HIGH 0x0143
|
||||
#define BCM53115_DEVICE_ID 0xbf80
|
||||
#define BCM53115_A0_REV_ID 0
|
||||
#define BCM53115_A1_REV_ID 1
|
||||
#define BCM53115_B0_REV_ID 2
|
||||
#define BCM53115_B1_REV_ID 3
|
||||
#define BCM53115_C0_REV_ID 8
|
||||
|
||||
#define BCM53118_PHYID_LOW 0xbfe0
|
||||
#define BCM53118_PHYID_HIGH 0x0143
|
||||
#define BCM53118_DEVICE_ID 0xbfe0
|
||||
#define BCM53118_A0_REV_ID 0
|
||||
|
||||
#define BCM53118_B0_REV_ID 4
|
||||
#define BCM53118_B1_REV_ID 5
|
||||
|
||||
#define BCM53280_PHYID_LOW 0x5e90
|
||||
#define BCM53280_PHYID_HIGH 0x0362
|
||||
#define BCM53280_DEVICE_ID (0x4 | BCM53280_PHYID_LOW)
|
||||
#define BCM53280_A0_REV_ID 0
|
||||
#define BCM53280_B0_REV_ID 0x4
|
||||
#define BCM53280_B1_REV_ID 0x5
|
||||
#define BCM53280_B2_REV_ID 0x6
|
||||
#define BCM53286_DEVICE_ID (0x4 | BCM53280_PHYID_LOW)
|
||||
#define BCM53288_DEVICE_ID (0xc | BCM53280_PHYID_LOW)
|
||||
#define BCM53284_DEVICE_ID (0x7 | BCM53280_PHYID_LOW)
|
||||
#define BCM53283_DEVICE_ID (0x6 | BCM53280_PHYID_LOW)
|
||||
#define BCM53282_DEVICE_ID (0x5 | BCM53280_PHYID_LOW)
|
||||
#define BCM53101_PHYID_LOW 0x5ed0
|
||||
#define BCM53101_PHYID_HIGH 0x0362
|
||||
#define BCM53101_DEVICE_ID 0x5ed0
|
||||
#define BCM53101_A0_REV_ID 0
|
||||
#define BCM53101_B0_REV_ID 4
|
||||
|
||||
#define BCM53125_PHYID_LOW 0x5f20
|
||||
#define BCM53125_PHYID_HIGH 0x0362
|
||||
#define BCM53125_DEVICE_ID 0x5f20
|
||||
#define BCM53125_A0_REV_ID 0
|
||||
#define BCM53125_B0_REV_ID 0x4
|
||||
#define BCM53125_MODEL_ID 0x53125
|
||||
|
||||
#define BCM53134_PHYID_LOW 0x5350
|
||||
#define BCM53134_PHYID_HIGH 0xAE02
|
||||
#define BCM53134_DEVICE_ID 0x5350
|
||||
#define BCM53134_A0_REV_ID 0x0
|
||||
#define BCM53134_B0_REV_ID 0x1
|
||||
#define BCM53134_B1_REV_ID 0x2
|
||||
#define BCM53134_A0_MODEL_ID 0x5035
|
||||
#define BCM53134_B0_MODEL_ID 0x5075
|
||||
|
||||
#define BCM53128_PHYID_LOW 0x5e10
|
||||
#define BCM53128_PHYID_HIGH 0x0362
|
||||
#define BCM53128_DEVICE_ID 0x5e10
|
||||
#define BCM53128_A0_REV_ID 0
|
||||
#define BCM53128_B0_REV_ID 0x4
|
||||
#define BCM53128_MODEL_ID 0x53128
|
||||
|
||||
#define BCM53600_PHYID_LOW 0x5f40
|
||||
#define BCM53600_PHYID_HIGH 0x0362
|
||||
#define BCM53600_DEVICE_ID (0x3 | BCM53600_PHYID_LOW)
|
||||
#define BCM53600_A0_REV_ID 0
|
||||
#define BCM53602_DEVICE_ID (0x1 | BCM53600_PHYID_LOW)
|
||||
#define BCM53603_DEVICE_ID (0x2 | BCM53600_PHYID_LOW)
|
||||
#define BCM53604_DEVICE_ID (0x3 | BCM53600_PHYID_LOW)
|
||||
#define BCM53606_DEVICE_ID (0x7 | BCM53600_PHYID_LOW)
|
||||
|
||||
#define BCM89500_PHYID_LOW 0x5d30
|
||||
#define BCM89500_PHYID_HIGH 0x0362
|
||||
#define BCM89500_DEVICE_ID 0x9500
|
||||
#define BCM89501_DEVICE_ID 0x9501
|
||||
#define BCM89200_DEVICE_ID 0x9200
|
||||
#define BCM89500_A0_REV_ID 0
|
||||
#define BCM89500_B0_REV_ID 0x4
|
||||
#define BCM89500_MODEL_ID 0x89500
|
||||
|
||||
#define BCM53010_PHYID_LOW 0x8760
|
||||
#define BCM53010_PHYID_HIGH 0x600d
|
||||
#define BCM53010_DEVICE_ID 0x3010
|
||||
#define BCM53011_DEVICE_ID 0x3011
|
||||
#define BCM53012_DEVICE_ID 0x3012
|
||||
#define BCM53010_A0_REV_ID 0
|
||||
#define BCM53010_A2_REV_ID 0x2
|
||||
#define BCM53010_MODEL_ID 0x53010
|
||||
|
||||
#define BCM53018_PHYID_LOW 0x87c0
|
||||
#define BCM53018_PHYID_HIGH 0x600d
|
||||
#define BCM53017_DEVICE_ID 0x3016
|
||||
#define BCM53018_DEVICE_ID 0x3018
|
||||
#define BCM53019_DEVICE_ID 0x3019
|
||||
#define BCM53018_A0_REV_ID 0
|
||||
#define BCM53018_MODEL_ID 0x53016
|
||||
|
||||
#define BCM53020_PHYID_LOW 0x87f0
|
||||
#define BCM53020_PHYID_HIGH 0x600d
|
||||
#define BCM53020_DEVICE_ID 0x8022
|
||||
#define BCM53022_DEVICE_ID 0x8022
|
||||
#define BCM53023_DEVICE_ID 0x8023
|
||||
#define BCM53025_DEVICE_ID 0x8025
|
||||
#define BCM58625_DEVICE_ID 0x8625
|
||||
#define BCM58622_DEVICE_ID 0x8622
|
||||
#define BCM58623_DEVICE_ID 0x8623
|
||||
#define BCM58525_DEVICE_ID 0x8525
|
||||
#define BCM58522_DEVICE_ID 0x8522
|
||||
#define BCM53020_A0_REV_ID 0
|
||||
#define BCM53020_MODEL_ID 0x3025
|
||||
|
||||
#define BCM4713_DEVICE_ID 0x4713
|
||||
#define BCM4713_A0_REV_ID 0
|
||||
#define BCM4713_A9_REV_ID 9
|
||||
|
||||
#define BCM53000_GMAC_DEVICE_ID 0x4715
|
||||
#define BCM53000_A0_REV_ID 0
|
||||
|
||||
#define BCM53010_GMAC_DEVICE_ID 0x4715
|
||||
|
||||
#define BCM53000PCIE_DEVICE_ID 0x5300
|
||||
|
||||
#define SANDBURST_VENDOR_ID 0x17ba
|
||||
#define BME3200_DEVICE_ID 0x0280
|
||||
#define BME3200_A0_REV_ID 0x0000
|
||||
#define BME3200_B0_REV_ID 0x0001
|
||||
#define BM9600_DEVICE_ID 0x0480
|
||||
#define BM9600_A0_REV_ID 0x0000
|
||||
#define BM9600_B0_REV_ID 0x0010
|
||||
#define QE2000_DEVICE_ID 0x0300
|
||||
#define QE2000_A1_REV_ID 0x0001
|
||||
#define QE2000_A2_REV_ID 0x0002
|
||||
#define QE2000_A3_REV_ID 0x0003
|
||||
#define QE2000_A4_REV_ID 0x0004
|
||||
#define BCM88020_DEVICE_ID 0x0380
|
||||
#define BCM88020_A0_REV_ID 0x0000
|
||||
#define BCM88020_A1_REV_ID 0x0001
|
||||
#define BCM88020_A2_REV_ID 0x0002
|
||||
#define BCM88025_DEVICE_ID 0x0580
|
||||
#define BCM88025_A0_REV_ID 0x0000
|
||||
#define BCM88030_DEVICE_ID 0x0038
|
||||
#define BCM88030_A0_REV_ID 0x0001
|
||||
#define BCM88030_A1_REV_ID 0x0002
|
||||
#define BCM88030_B0_REV_ID 0x0011
|
||||
#define BCM88030_B1_REV_ID 0x0012
|
||||
#define BCM88034_DEVICE_ID 0x0034
|
||||
#define BCM88034_A0_REV_ID (BCM88030_A0_REV_ID)
|
||||
#define BCM88034_A1_REV_ID (BCM88030_A1_REV_ID)
|
||||
#define BCM88034_B0_REV_ID (BCM88030_B0_REV_ID)
|
||||
#define BCM88034_B1_REV_ID (BCM88030_B1_REV_ID)
|
||||
#define BCM88039_DEVICE_ID 0x0039
|
||||
#define BCM88039_A0_REV_ID (BCM88030_A0_REV_ID)
|
||||
#define BCM88039_A1_REV_ID (BCM88030_A1_REV_ID)
|
||||
#define BCM88039_B0_REV_ID (BCM88030_B0_REV_ID)
|
||||
#define BCM88039_B1_REV_ID (BCM88030_B1_REV_ID)
|
||||
#define BCM88130_DEVICE_ID 0x0480
|
||||
#define BCM88130_A0_REV_ID 0x0000
|
||||
#define BCM88130_A1_REV_ID 0x0001
|
||||
#define BCM88130_B0_REV_ID 0x0010
|
||||
#define PLX_VENDOR_ID 0x10b5
|
||||
#define PLX9656_DEVICE_ID 0x9656
|
||||
#define PLX9656_REV_ID 0x0000
|
||||
#define PLX9056_DEVICE_ID 0x9056
|
||||
#define PLX9056_REV_ID 0x0000
|
||||
|
||||
#define TK371X_DEVICE_ID 0x8600
|
||||
#define TK371X_A0_REV_ID 0x0
|
||||
|
||||
#define GEDI_DEVICE_ID 0xa100
|
||||
#define GEDI_REV_ID 0x0001
|
||||
#define ARAD_DEVICE_ID 0x8650
|
||||
@ -1778,6 +1525,7 @@
|
||||
#define DNXC_A0_REV_ID 0x0001
|
||||
#define DNXC_A1_REV_ID 0x0002
|
||||
#define DNXC_B0_REV_ID 0x0011
|
||||
#define DNXC_B1_REV_ID 0x0012
|
||||
#define BCM88790_DEVICE_ID 0x8790
|
||||
#define BCM88790_A0_REV_ID DNXC_A0_REV_ID
|
||||
#define BCM88790_B0_REV_ID DNXC_B0_REV_ID
|
||||
@ -1933,9 +1681,34 @@
|
||||
#define BCM88381_A0_REV_ID JERICHO_PLUS_A0_REV_ID
|
||||
|
||||
#define JERICHO_2_DEVICE_ID 0x8690
|
||||
#define JERICHO_2_A0_REV_ID 0x0001
|
||||
#define JERICHO_2_A0_REV_ID DNXC_A0_REV_ID
|
||||
#define JERICHO_2_B0_REV_ID DNXC_B0_REV_ID
|
||||
#define JERICHO_2_B1_REV_ID DNXC_B1_REV_ID
|
||||
#define BCM88690_DEVICE_ID JERICHO_2_DEVICE_ID
|
||||
#define BCM88690_A0_REV_ID JERICHO_2_A0_REV_ID
|
||||
#define BCM88690_B0_REV_ID JERICHO_2_B0_REV_ID
|
||||
#define BCM88690_B1_REV_ID JERICHO_2_B1_REV_ID
|
||||
#define BCM88691_DEVICE_ID 0x8691
|
||||
#define BCM88692_DEVICE_ID 0x8692
|
||||
#define BCM88693_DEVICE_ID 0x8693
|
||||
#define BCM88694_DEVICE_ID 0x8694
|
||||
#define BCM88695_DEVICE_ID 0x8695
|
||||
#define BCM88696_DEVICE_ID 0x8696
|
||||
#define BCM88697_DEVICE_ID 0x8697
|
||||
#define BCM88698_DEVICE_ID 0x8698
|
||||
#define BCM88699_DEVICE_ID 0x8699
|
||||
#define BCM8869A_DEVICE_ID 0x869A
|
||||
#define BCM8869B_DEVICE_ID 0x869B
|
||||
#define BCM8869C_DEVICE_ID 0x869C
|
||||
#define BCM8869D_DEVICE_ID 0x869D
|
||||
#define BCM8869E_DEVICE_ID 0x869E
|
||||
#define BCM8869F_DEVICE_ID 0x869F
|
||||
#define BCM_JR2_DEVID_MASK 0xFFF0
|
||||
|
||||
#define J2C_DEVICE_ID 0x8800
|
||||
#define J2C_A0_REV_ID DNXC_A0_REV_ID
|
||||
#define BCM88800_DEVICE_ID J2C_DEVICE_ID
|
||||
#define BCM88800_A0_REV_ID J2C_A0_REV_ID
|
||||
|
||||
#define QAX_DEVICE_ID 0x8470
|
||||
#define QAX_A0_REV_ID 0x0001
|
||||
@ -1964,6 +1737,7 @@
|
||||
#define BCM88270_A1_REV_ID QUX_A1_REV_ID
|
||||
#define BCM88272_DEVICE_ID 0x8272
|
||||
#define BCM88273_DEVICE_ID 0x8273
|
||||
#define BCM88274_DEVICE_ID 0x8274
|
||||
#define BCM88278_DEVICE_ID 0x8278
|
||||
#define BCM88279_DEVICE_ID 0x8279
|
||||
|
||||
@ -2045,5 +1819,8 @@
|
||||
#define ACP_PCI_VENDOR_ID 0x10ee
|
||||
#define ACP_PCI_DEVICE_ID 0x7011
|
||||
#define ACP_PCI_REV_ID 0x0001
|
||||
|
||||
#define PLX9056_DEVICE_ID 0x9056
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -54,12 +54,7 @@ endif
|
||||
-include ${SDK}/make/Make.local
|
||||
|
||||
ifdef ALL_CHIPS
|
||||
ROBO_CHIPS = 1
|
||||
ESW_CHIPS = 1
|
||||
else
|
||||
ifndef ROBO_CHIPS
|
||||
ESW_CHIPS = 1
|
||||
endif
|
||||
endif # ALL_CHIPS
|
||||
|
||||
#
|
||||
@ -166,7 +161,7 @@ CFLAGS += ${INCFLAGS}
|
||||
CXXFLAGS += ${INCFLAGS}
|
||||
CPPFLAGS += ${INCFLAGS}
|
||||
|
||||
CFLAGS += -DSAI_FIXUP -DBCM_PORT_DEFAULT_DISABLE -DBCM_VLAN_NO_DEFAULT_ETHER -DBCM_VLAN_NO_DEFAULT_CPU -DBCM_WARM_BOOT_SUPPORT -DSAL_CONFIG_FILE_DISABLE -DSAL_THREAD_NAME_PRINT_DISABLE -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=256 -DALPM_ENABLE -DOPENNSL_PHY_ROUTINES -DTH2_CPU_POOL_SETUP -DINCLUDE_L3 -DSAI_ONLY -DPRINT_TO_SYSLOG -D_SHR_PBMP_WIDTH=256 -DINCLUDE_DIAG_SHELL -DSTATIC=static -DLOG_TEST -DLOG_SAI -D_GNU_SOURCE
|
||||
CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1024
|
||||
|
||||
#
|
||||
# Debug #ifdef control
|
||||
|
@ -74,12 +74,6 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\
|
||||
KFLAG_INCLD = $(TOOLCHAIN_BIN_DIR)/../lib/gcc/$(TARGET_ARCHITECTURE)/4.6.4/include
|
||||
|
||||
ifdef BROADCOM_SVK
|
||||
ifdef BCM_BME3200_B0
|
||||
PLX_PCI2LBUS=1
|
||||
endif
|
||||
ifdef BCM_BM9600_B0
|
||||
PLX_PCI2LBUS=1
|
||||
endif
|
||||
ifeq ($PLX_PCI2LBUS, 1)
|
||||
CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE
|
||||
endif
|
||||
|
@ -224,12 +224,6 @@ endif
|
||||
endif
|
||||
|
||||
ifdef BROADCOM_SVK
|
||||
ifdef BCM_BME3200_B0
|
||||
PLX_PCI2LBUS=1
|
||||
endif
|
||||
ifdef BCM_BM9600_B0
|
||||
PLX_PCI2LBUS=1
|
||||
endif
|
||||
ifeq ($PLX_PCI2LBUS, 1)
|
||||
CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE
|
||||
endif
|
||||
|
@ -27,11 +27,11 @@ endif
|
||||
# TARGET_ARCHITECTURE Compiler for target architecture
|
||||
# KERNDIR Kernel directory for iPROC-CMICd devices
|
||||
ifeq (BE,$(ENDIAN_MODE))
|
||||
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc-be/XLDK
|
||||
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32
|
||||
TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi
|
||||
KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux
|
||||
else
|
||||
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc/XLDK
|
||||
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50/XLDK32
|
||||
TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi
|
||||
KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux
|
||||
endif
|
||||
@ -60,6 +60,8 @@ CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0
|
||||
ENDIAN = LE_HOST=1
|
||||
endif
|
||||
|
||||
CFLAGS += -fno-aggressive-loop-optimizations
|
||||
|
||||
CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD
|
||||
CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\"
|
||||
|
||||
@ -80,7 +82,7 @@ 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)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.3/include
|
||||
KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.4/include
|
||||
|
||||
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
|
||||
|
@ -71,7 +71,7 @@ $(KMODULE):
|
||||
rm -f *.o *.ko .*.cmd
|
||||
rm -fr .tmp_versions
|
||||
ln -s $(LIBDIR)/$(MODULE) $(PRE_COMPILED_OBJ)_shipped
|
||||
echo "suppress warning" > .$(PRE_COMPILED_OBJ).cmd
|
||||
if [ ! -f $(KERNBLDDIR)/NO_SUPRESS ]; then echo "# suppress warning" > .$(PRE_COMPILED_OBJ).cmd; fi
|
||||
$(MAKE) -C $(KERNBLDDIR) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
|
||||
if [ ! -f Module.symvers ]; then echo "old kernel (pre-2.6.17)" > Module.symvers; fi
|
||||
cp -f $(KMODULE) $(LIBDIR)
|
||||
|
@ -22,7 +22,7 @@ ENDIAN = LE_HOST=1
|
||||
CFGFLAGS += -D$(ENDIAN)
|
||||
CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\"
|
||||
ifeq (,$(findstring -DSAL_BDE_DMA_MEM_DEFAULT,$(CFGFLAGS)))
|
||||
CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32
|
||||
CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=16
|
||||
endif
|
||||
|
||||
# Extra variables.
|
||||
|
@ -48,4 +48,4 @@ AUTOCONF = $(KERNDIR)/include/linux/autoconf.h
|
||||
endif
|
||||
|
||||
# gcc system include path
|
||||
SYSINC = $(shell gcc -print-search-dirs | grep install | cut -c 10-)include
|
||||
SYSINC = $(shell $(CC) -print-search-dirs | grep install | cut -c 10-)include
|
||||
|
@ -43,4 +43,3 @@ KFLAGS += -I$(KERNDIR_COMMON)/include -I$(KERNDIR_COMMON)/include/uapi -I$(KERND
|
||||
endif
|
||||
|
||||
include ${SDK}/make/Makefile.linux-x86-common-2_6
|
||||
|
||||
|
@ -222,7 +222,7 @@ extern int lkbde_dev_instid_set(int d, uint32 instid);
|
||||
extern int lkbde_irq_mask_set(int d, uint32 addr, uint32 mask, uint32 fmask);
|
||||
extern int lkbde_irq_mask_get(int d, uint32 *mask, uint32 *fmask);
|
||||
|
||||
#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT))
|
||||
#ifdef BCM_SAND_SUPPORT
|
||||
extern int lkbde_cpu_write(int d, uint32 addr, uint32 *buf);
|
||||
extern int lkbde_cpu_read(int d, uint32 addr, uint32 *buf);
|
||||
extern int lkbde_cpu_pci_register(int d);
|
||||
@ -241,15 +241,12 @@ extern int lkbde_cpu_pci_register(int d);
|
||||
*/
|
||||
#define LKBDE_IPROC_REG 0x4000
|
||||
|
||||
#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
|
||||
#ifdef BCM_SAND_SUPPORT
|
||||
#include <linux/version.h>
|
||||
#if defined(__DUNE_LINUX_BCM_CPU_PCIE__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
|
||||
#ifndef _SIMPLE_MEMORY_ALLOCATION_
|
||||
#define _SIMPLE_MEMORY_ALLOCATION_ 1
|
||||
#endif
|
||||
#ifndef USE_LINUX_BDE_MMAP
|
||||
#define USE_LINUX_BDE_MMAP 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -271,13 +268,9 @@ extern int lkbde_cpu_pci_register(int d);
|
||||
#define _SIMPLE_MEMORY_ALLOCATION_ 9 /* compile in the allocation method, but do not use it by default */
|
||||
#endif
|
||||
|
||||
/* By default we use our private mmap only if /dev/mem mmap has restrictions */
|
||||
/* By default we use our private mmap for DMA pool */
|
||||
#ifndef USE_LINUX_BDE_MMAP
|
||||
#ifdef CONFIG_STRICT_DEVMEM
|
||||
#define USE_LINUX_BDE_MMAP 1
|
||||
#else
|
||||
#define USE_LINUX_BDE_MMAP 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -58,7 +58,7 @@
|
||||
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
|
||||
#endif
|
||||
|
||||
extern void _dma_init(int robo_switch, int dev_index);
|
||||
extern void _dma_init(int dev_index);
|
||||
extern int _dma_cleanup(void);
|
||||
extern void _dma_pprint(void);
|
||||
extern uint32_t *_salloc(int d, int size, const char *name);
|
||||
@ -68,7 +68,7 @@ extern int _sflush(int d, void *ptr, int length);
|
||||
extern sal_paddr_t _l2p(int d, void *vaddr);
|
||||
extern void *_p2l(int d, sal_paddr_t paddr);
|
||||
extern int _dma_pool_allocated(void);
|
||||
extern int _dma_range_valid(unsigned long phys_addr, unsigned long size);
|
||||
extern int _dma_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
@ -33,33 +33,11 @@ LIBS = $(LIBDIR)/libkern.a
|
||||
|
||||
BDE = linux-kernel-bde.o
|
||||
|
||||
ifdef ROBO_CHIPS
|
||||
CFLAGS += -I$(ET_ROBO) -I${SDK}/include/shared/et
|
||||
ET_ROBO = ${SDK}/systems/drv/et
|
||||
endif
|
||||
|
||||
# need to add vpath sources
|
||||
VPATH = ../shared $(ET_ROBO)
|
||||
VPATH = ../shared
|
||||
|
||||
# Add the srcs to be found by vpath
|
||||
LSRCS += mpool.c
|
||||
ifdef ROBO_CHIPS
|
||||
platformsplt = $(subst -, , ${platform}) # change hyphens to spaces
|
||||
platformbase = $(word 1,${platformsplt})
|
||||
|
||||
ifeq ($(platformbase), keystone)
|
||||
LSRCS += etc_robo_spi.c aiutils.c
|
||||
else
|
||||
ifeq ($(platformbase), keystone_le)
|
||||
LSRCS += etc_robo_spi.c aiutils.c
|
||||
else
|
||||
ifeq ($(platformbase), iproc)
|
||||
LSRCS += robo_srab.c robo_spi.c aiutils.c
|
||||
endif
|
||||
endif
|
||||
endif # platformbase
|
||||
|
||||
endif # ROBO_CHIPS
|
||||
|
||||
# Add shared BDE sources
|
||||
VPATH += ../../shared
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -85,10 +85,25 @@
|
||||
|
||||
#if _SIMPLE_MEMORY_ALLOCATION_ == 1
|
||||
#define ALLOC_METHOD_DEFAULT ALLOC_TYPE_API
|
||||
#if defined(__arm__)
|
||||
#define USE_DMA_MMAP_COHERENT
|
||||
#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x))
|
||||
#elif defined(__aarch64__ )
|
||||
#define USE_DMA_MMAP_COHERENT
|
||||
#define _PGPROT_NONCACHED(x) x = pgprot_writecombine((x))
|
||||
#endif
|
||||
#else
|
||||
#define ALLOC_METHOD_DEFAULT ALLOC_TYPE_CHUNK
|
||||
#endif
|
||||
|
||||
#ifndef _PGPROT_NONCACHED
|
||||
#ifdef REMAP_DMA_NONCACHED
|
||||
#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x))
|
||||
#else
|
||||
#define _PGPROT_NONCACHED(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
|
||||
#include <linux/slab.h>
|
||||
#define virt_to_bus virt_to_phys
|
||||
@ -101,6 +116,12 @@
|
||||
#define VIRT_TO_PAGE(p) virt_to_page((p))
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
|
||||
#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p))
|
||||
#else
|
||||
#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((p))
|
||||
#endif
|
||||
|
||||
#ifndef KMALLOC_MAX_SIZE
|
||||
#define KMALLOC_MAX_SIZE (1UL << (MAX_ORDER - 1 + PAGE_SHIFT))
|
||||
#endif
|
||||
@ -170,7 +191,6 @@ MODULE_PARM_DESC(himemaddr,
|
||||
#else
|
||||
#define DMA_MEM_DEFAULT (8 * ONE_MB)
|
||||
#endif
|
||||
#define DMA_MEM_DEFAULT_ROBO (4 * ONE_MB)
|
||||
|
||||
/* We try to assemble a contiguous segment from chunks of this size */
|
||||
#define DMA_BLOCK_SIZE (512 * ONE_KB)
|
||||
@ -203,6 +223,7 @@ static unsigned long _himemaddr = 0;
|
||||
static int _use_dma_mapping = 0;
|
||||
static LIST_HEAD(_dma_seg);
|
||||
|
||||
#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)
|
||||
|
||||
@ -545,7 +566,7 @@ _pgcleanup(void)
|
||||
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(0), _dma_mem_size, _dma_vbase, _dma_pbase);
|
||||
dma_free_coherent(DMA_DEV(DMA_DEV_INDEX), _dma_mem_size, _dma_vbase, _dma_pbase);
|
||||
}
|
||||
break;
|
||||
#endif /* _SIMPLE_MEMORY_ALLOCATION_ */
|
||||
@ -554,7 +575,7 @@ _pgcleanup(void)
|
||||
struct list_head *pos, *tmp;
|
||||
int i, ndevices;
|
||||
if (_use_dma_mapping) {
|
||||
ndevices = BDE_NUM_DEVICES(BDE_ALL_DEVICES);
|
||||
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);
|
||||
}
|
||||
@ -591,7 +612,6 @@ static void
|
||||
_alloc_mpool(size_t size)
|
||||
{
|
||||
unsigned long pbase = 0;
|
||||
|
||||
#if defined(__arm__) && !defined(CONFIG_HIGHMEM)
|
||||
if (_use_himem) {
|
||||
gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n");
|
||||
@ -614,6 +634,9 @@ _alloc_mpool(size_t size)
|
||||
_dma_vbase = IOREMAP(_dma_pbase, size);
|
||||
} 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: {
|
||||
@ -624,8 +647,9 @@ _alloc_mpool(size_t size)
|
||||
/* get a memory allocation from the kernel */
|
||||
{
|
||||
dma_addr_t dma_handle;
|
||||
if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(0), alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) {
|
||||
gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)alloc_size);
|
||||
if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX),
|
||||
alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) {
|
||||
gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size);
|
||||
return;
|
||||
}
|
||||
_cpu_pbase = pbase = dma_handle;
|
||||
@ -643,14 +667,14 @@ _alloc_mpool(size_t size)
|
||||
case ALLOC_TYPE_CHUNK:
|
||||
_dma_vbase = _pgalloc(size);
|
||||
if (!_dma_vbase) {
|
||||
gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)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 (DMA_DEV(0)) {
|
||||
pbase = dma_map_single(DMA_DEV(0), _dma_vbase, size, DMA_BIDIRECTIONAL);
|
||||
if (dma_mapping_error(DMA_DEV(0), pbase)) {
|
||||
if (DMA_DEV(DMA_DEV_INDEX)) {
|
||||
pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL);
|
||||
if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) {
|
||||
gprintk("Failed to map memory at %p\n", _dma_vbase);
|
||||
_pgcleanup();
|
||||
_dma_vbase = NULL;
|
||||
@ -659,7 +683,6 @@ _alloc_mpool(size_t size)
|
||||
}
|
||||
_use_dma_mapping = 1;
|
||||
} else {
|
||||
/* Device has not been probed. */
|
||||
pbase = _cpu_pbase;
|
||||
}
|
||||
break;
|
||||
@ -719,15 +742,21 @@ _dma_cleanup(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _dma_init(int robo_switch, int dev_index)
|
||||
void _dma_init(int dev_index)
|
||||
{
|
||||
unsigned long pbase;
|
||||
|
||||
if (dev_index > 0) {
|
||||
if ((_use_dma_mapping == 1) && DMA_DEV(dev_index) && _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 (dma_mapping_error(DMA_DEV(dev_index), pbase)) {
|
||||
if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) {
|
||||
gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase);
|
||||
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);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -745,10 +774,6 @@ void _dma_init(int robo_switch, int dev_index)
|
||||
gprintk("dmasize must be a power of 2 (1M, 2M, 4M, 8M etc.)\n");
|
||||
_dma_mem_size = 0;
|
||||
}
|
||||
} else {
|
||||
if(robo_switch){
|
||||
_dma_mem_size = DMA_MEM_DEFAULT_ROBO;
|
||||
}
|
||||
}
|
||||
|
||||
if (himem) {
|
||||
@ -775,42 +800,54 @@ void _dma_init(int robo_switch, int dev_index)
|
||||
_alloc_mpool(_dma_mem_size);
|
||||
if (_dma_vbase == NULL) {
|
||||
gprintk("no DMA memory available\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
mpool_init();
|
||||
_dma_pool = mpool_create(_dma_vbase, _dma_mem_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_LINUX_BDE_MMAP
|
||||
/*
|
||||
* Function: _dma_range_valid
|
||||
* Some kernels are configured to prevent mapping of kernel RAM memory
|
||||
* into user space via the /dev/mem device.
|
||||
*
|
||||
* Purpose:
|
||||
* Check if DMA address range is valid.
|
||||
* Parameters:
|
||||
* phys_addr - start physical address
|
||||
* size - range size
|
||||
* Returns:
|
||||
* 0 : not valid
|
||||
* 1 : valid
|
||||
* The function below provides a backdoor to mapping the DMA pool to
|
||||
* user space via the BDE device file.
|
||||
*/
|
||||
int
|
||||
_dma_range_valid(unsigned long phys_addr, unsigned long size)
|
||||
int _dma_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long pool_start = _cpu_pbase;
|
||||
unsigned long pool_end = pool_start + _dma_mem_size;
|
||||
unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
|
||||
if (phys_addr < pool_start || (phys_addr + size) > pool_end) {
|
||||
if (phys_addr < (unsigned long )_cpu_pbase ||
|
||||
(phys_addr + size) > ((unsigned long )_cpu_pbase + _dma_mem_size)) {
|
||||
gprintk("range 0x%lx-0x%lx outside DMA pool 0x%lx-0x%lx\n",
|
||||
phys_addr, phys_addr + size, pool_start, pool_end);
|
||||
return 0;
|
||||
phys_addr, phys_addr + size, (unsigned long )_cpu_pbase,
|
||||
(unsigned long )_cpu_pbase + _dma_mem_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#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 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
_PGPROT_NONCACHED(vma->vm_page_prot);
|
||||
|
||||
if (remap_pfn_range(vma,
|
||||
vma->vm_start,
|
||||
vma->vm_pgoff,
|
||||
size,
|
||||
vma->vm_page_prot)) {
|
||||
gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n",
|
||||
phys_addr, phys_addr + size, vma->vm_start,vma->vm_end);
|
||||
return -EAGAIN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: _dma_pool_allocated
|
||||
*
|
||||
|
@ -70,12 +70,31 @@ static sal_sem_t _mpool_lock;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MPOOL_BUF_SIZE 1024
|
||||
#define MPOOL_BUF_ALLOC_COUNT_MAX 16
|
||||
|
||||
typedef struct mpool_mem_s {
|
||||
unsigned char *address;
|
||||
int size;
|
||||
struct mpool_mem_s *prev;
|
||||
struct mpool_mem_s *next;
|
||||
} mpool_mem_t;
|
||||
|
||||
static int _buf_alloc_count;
|
||||
static mpool_mem_t *mpool_buf[MPOOL_BUF_ALLOC_COUNT_MAX];
|
||||
static mpool_mem_t *free_list;
|
||||
|
||||
#define ALLOC_INIT_MPOOL_BUF(ptr) \
|
||||
ptr = MALLOC((sizeof(mpool_mem_t) * MPOOL_BUF_SIZE)); \
|
||||
if (ptr) { \
|
||||
int i; \
|
||||
for (i = 0; i < MPOOL_BUF_SIZE - 1; i++) { \
|
||||
ptr[i].next = &ptr[i+1]; \
|
||||
} \
|
||||
ptr[MPOOL_BUF_SIZE - 1].next = NULL; \
|
||||
free_list = &ptr[0]; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: mpool_init
|
||||
*
|
||||
@ -116,6 +135,10 @@ mpool_alloc(mpool_handle_t pool, int size)
|
||||
|
||||
MPOOL_LOCK();
|
||||
|
||||
if (size < BCM_CACHE_LINE_BYTES) {
|
||||
size = BCM_CACHE_LINE_BYTES;
|
||||
}
|
||||
|
||||
mod = size & (BCM_CACHE_LINE_BYTES - 1);
|
||||
if (mod != 0 ) {
|
||||
size += (BCM_CACHE_LINE_BYTES - mod);
|
||||
@ -131,21 +154,37 @@ mpool_alloc(mpool_handle_t pool, int size)
|
||||
MPOOL_UNLOCK();
|
||||
return NULL;
|
||||
}
|
||||
newptr = MALLOC(sizeof(mpool_mem_t));
|
||||
if (!newptr) {
|
||||
MPOOL_UNLOCK();
|
||||
return NULL;
|
||||
|
||||
if (!free_list) {
|
||||
if (_buf_alloc_count == MPOOL_BUF_ALLOC_COUNT_MAX) {
|
||||
MPOOL_UNLOCK();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]);
|
||||
|
||||
if (mpool_buf[_buf_alloc_count] == NULL) {
|
||||
MPOOL_UNLOCK();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_buf_alloc_count++;
|
||||
}
|
||||
|
||||
newptr = free_list;
|
||||
free_list = free_list->next;
|
||||
|
||||
newptr->address = ptr->address + ptr->size;
|
||||
newptr->size = size;
|
||||
newptr->next = ptr->next;
|
||||
newptr->prev = ptr;
|
||||
ptr->next->prev = newptr;
|
||||
ptr->next = newptr;
|
||||
#ifdef TRACK_DMA_USAGE
|
||||
_dma_mem_used += size;
|
||||
#endif
|
||||
MPOOL_UNLOCK();
|
||||
|
||||
MPOOL_UNLOCK();
|
||||
return newptr->address;
|
||||
}
|
||||
|
||||
@ -165,25 +204,29 @@ void
|
||||
mpool_free(mpool_handle_t pool, void *addr)
|
||||
{
|
||||
unsigned char *address = (unsigned char *)addr;
|
||||
mpool_mem_t *ptr = pool, *prev = NULL;
|
||||
mpool_mem_t *head = pool, *ptr = NULL;
|
||||
|
||||
MPOOL_LOCK();
|
||||
|
||||
while (ptr && ptr->next) {
|
||||
if (ptr->next->address == address) {
|
||||
|
||||
if (!(head && head->prev)) {
|
||||
MPOOL_UNLOCK();
|
||||
return;
|
||||
}
|
||||
|
||||
ptr = head->prev->prev;
|
||||
|
||||
while (ptr && (ptr != head)) {
|
||||
if (ptr->address == address) {
|
||||
#ifdef TRACK_DMA_USAGE
|
||||
_dma_mem_used -= ptr->next->size;
|
||||
_dma_mem_used -= ptr->size;
|
||||
#endif
|
||||
ptr->prev->next = ptr->next;
|
||||
ptr->next->prev = ptr->prev;
|
||||
ptr->next = free_list;
|
||||
free_list = ptr;
|
||||
break;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
if (ptr && ptr->next) {
|
||||
prev = ptr;
|
||||
ptr = ptr->next;
|
||||
prev->next = ptr->next;
|
||||
FREE(ptr);
|
||||
ptr = ptr->prev;
|
||||
}
|
||||
|
||||
MPOOL_UNLOCK();
|
||||
@ -208,34 +251,45 @@ mpool_create(void *base_ptr, int size)
|
||||
{
|
||||
mpool_mem_t *head, *tail;
|
||||
int mod = (int)(((unsigned long)base_ptr) & (BCM_CACHE_LINE_BYTES - 1));
|
||||
int i;
|
||||
|
||||
MPOOL_LOCK();
|
||||
|
||||
for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) {
|
||||
mpool_buf[i] = NULL;
|
||||
}
|
||||
|
||||
_buf_alloc_count = 0;
|
||||
|
||||
ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]);
|
||||
|
||||
if (mpool_buf[_buf_alloc_count] == NULL) {
|
||||
MPOOL_UNLOCK();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_buf_alloc_count++;
|
||||
|
||||
if (mod) {
|
||||
base_ptr = (char*)base_ptr + (BCM_CACHE_LINE_BYTES - mod);
|
||||
size -= (BCM_CACHE_LINE_BYTES - mod);
|
||||
}
|
||||
size &= ~(BCM_CACHE_LINE_BYTES - 1);
|
||||
|
||||
|
||||
head = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t));
|
||||
if (head == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tail = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t));
|
||||
if (tail == NULL) {
|
||||
FREE(head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
head = free_list;
|
||||
free_list = free_list->next;
|
||||
tail = free_list;
|
||||
free_list = free_list->next;
|
||||
|
||||
head->size = tail->size = 0;
|
||||
head->address = base_ptr;
|
||||
tail->address = head->address + size;
|
||||
head->prev = tail;
|
||||
head->next = tail;
|
||||
tail->prev = head;
|
||||
tail->next = NULL;
|
||||
|
||||
MPOOL_UNLOCK();
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
@ -252,13 +306,20 @@ mpool_create(void *base_ptr, int size)
|
||||
int
|
||||
mpool_destroy(mpool_handle_t pool)
|
||||
{
|
||||
mpool_mem_t *ptr, *next;
|
||||
|
||||
int i;
|
||||
|
||||
MPOOL_LOCK();
|
||||
|
||||
for (ptr = pool; ptr; ptr = next) {
|
||||
next = ptr->next;
|
||||
FREE(ptr);
|
||||
if ((mpool_mem_t *)pool != mpool_buf[0]) {
|
||||
MPOOL_UNLOCK();
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) {
|
||||
if (mpool_buf[i]) {
|
||||
FREE(mpool_buf[i]);
|
||||
mpool_buf[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MPOOL_UNLOCK();
|
||||
@ -285,7 +346,7 @@ mpool_usage(mpool_handle_t pool)
|
||||
MPOOL_LOCK();
|
||||
|
||||
for (ptr = pool; ptr; ptr = ptr->next) {
|
||||
usage += ptr->size;
|
||||
usage += ptr->size;
|
||||
}
|
||||
|
||||
MPOOL_UNLOCK();
|
||||
|
@ -33,9 +33,6 @@
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
|
||||
#include <linux/uaccess.h>
|
||||
#endif
|
||||
#ifdef KEYSTONE
|
||||
#include <shared/et/bcmdevs.h>
|
||||
#endif
|
||||
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
@ -676,124 +673,10 @@ _bcm88750_interrupt(bde_ctrl_t *ctrl)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
_qe2k_interrupt(bde_ctrl_t *ctrl)
|
||||
{
|
||||
bde_inst_resource_t *res;
|
||||
|
||||
res = &_bde_inst_resource[ctrl->inst];
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x20/sizeof(uint32));
|
||||
|
||||
atomic_set(&res->intr, 1);
|
||||
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
|
||||
wake_up(&res->intr_wq);
|
||||
#else
|
||||
wake_up_interruptible(&res->intr_wq);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
_fe2k_interrupt(bde_ctrl_t *ctrl)
|
||||
{
|
||||
bde_inst_resource_t *res;
|
||||
|
||||
res = &_bde_inst_resource[ctrl->inst];
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x18/sizeof(uint32)); /* PC_INTERRUPT_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PC_ERROR0_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_ERROR1_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PC_UNIT_MASK */
|
||||
|
||||
atomic_set(&res->intr, 1);
|
||||
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
|
||||
wake_up(&res->intr_wq);
|
||||
#else
|
||||
wake_up_interruptible(&res->intr_wq);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
_fe2kxt_interrupt(bde_ctrl_t *ctrl)
|
||||
{
|
||||
bde_inst_resource_t *res;
|
||||
|
||||
res = &_bde_inst_resource[ctrl->inst];
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_INTERRUPT_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x38/sizeof(uint32)); /* PC_ERROR0_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x40/sizeof(uint32)); /* PC_ERROR1_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x50/sizeof(uint32)); /* PC_UNIT_MASK */
|
||||
|
||||
atomic_set(&res->intr, 1);
|
||||
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
|
||||
wake_up(&res->intr_wq);
|
||||
#else
|
||||
wake_up_interruptible(&res->intr_wq);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
_bme3200_interrupt(bde_ctrl_t *ctrl)
|
||||
{
|
||||
bde_inst_resource_t *res;
|
||||
|
||||
res = &_bde_inst_resource[ctrl->inst];
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_PT_ERROR0 */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_PT_ERROR1 */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x64/sizeof(uint32)); /* PI_PT_ERROR2 */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x6c/sizeof(uint32)); /* PI_PT_ERROR3 */
|
||||
|
||||
atomic_set(&res->intr, 1);
|
||||
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
|
||||
wake_up(&res->intr_wq);
|
||||
#else
|
||||
wake_up_interruptible(&res->intr_wq);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_bm9600_interrupt(bde_ctrl_t *ctrl)
|
||||
{
|
||||
bde_inst_resource_t *res;
|
||||
|
||||
res = &_bde_inst_resource[ctrl->inst];
|
||||
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_INTERRUPT_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0xc/sizeof(uint32)); /* PI_UNIT_INTERRUPT0_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x14/sizeof(uint32)); /* PI_UNIT_INTERRUPT1_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x1c/sizeof(uint32)); /* PI_UNIT_INTERRUPT2_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PI_UNIT_INTERRUPT3_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PI_UNIT_INTERRUPT4_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PI_UNIT_INTERRUPT5_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x3c/sizeof(uint32)); /* PI_UNIT_INTERRUPT6_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x44/sizeof(uint32)); /* PI_UNIT_INTERRUPT7_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x4c/sizeof(uint32)); /* PI_UNIT_INTERRUPT8_MASK */
|
||||
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_UNIT_INTERRUPT9_MASK */
|
||||
|
||||
atomic_set(&res->intr, 1);
|
||||
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
|
||||
wake_up(&res->intr_wq);
|
||||
#else
|
||||
wake_up_interruptible(&res->intr_wq);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The actual interrupt handler of ethernet devices */
|
||||
static void
|
||||
_ether_interrupt(bde_ctrl_t *ctrl)
|
||||
{
|
||||
#ifdef KEYSTONE
|
||||
/*
|
||||
* Since the two GMAC cores are sharing the same IRQ.
|
||||
* Add the checking to handle the interrupt events.
|
||||
*/
|
||||
if ((ctrl->devid == BCM53000_GMAC_ID)) {
|
||||
if ((readl(ctrl->ba + 0x020/4) & readl(ctrl->ba + 0x024/4)) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SSOC_WRITEL(0, ctrl->ba + 0x024/4);
|
||||
|
||||
atomic_set(&_ether_interrupt_has_taken_place, 1);
|
||||
@ -813,11 +696,6 @@ static struct _intr_mode_s {
|
||||
{ (isr_f)_cmicm_interrupt, "CMICm" },
|
||||
{ (isr_f)_cmicd_interrupt, "CMICd" },
|
||||
{ (isr_f)_cmicd_cmc0_interrupt, "CMICd CMC0" },
|
||||
{ (isr_f)_qe2k_interrupt, "QE2K" },
|
||||
{ (isr_f)_fe2k_interrupt, "FE2K" },
|
||||
{ (isr_f)_fe2kxt_interrupt, "FE2KXT" },
|
||||
{ (isr_f)_bme3200_interrupt, "BME3200" },
|
||||
{ (isr_f)_bm9600_interrupt, "BM9600" },
|
||||
{ (isr_f)_bcm88750_interrupt, "BCM88750" },
|
||||
{ (isr_f)_cmicx_interrupt, "CMICx" },
|
||||
{ NULL, NULL }
|
||||
@ -845,7 +723,7 @@ _devices_init(int d)
|
||||
uint32 ver;
|
||||
uint16 device_id_mask = 0xFFF0;
|
||||
uint16 device_id;
|
||||
int state = 0;
|
||||
uint32 state = 0;
|
||||
|
||||
(void)lkbde_dev_state_get(d, &state);
|
||||
if (state == BDE_DEV_STATE_REMOVED) {
|
||||
@ -864,21 +742,6 @@ _devices_init(int d)
|
||||
}
|
||||
if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) {
|
||||
switch (user_bde->get_dev(d)->device) {
|
||||
case QE2000_DEVICE_ID:
|
||||
ctrl->isr = (isr_f)_qe2k_interrupt;
|
||||
break;
|
||||
case BCM88020_DEVICE_ID:
|
||||
ctrl->isr = (isr_f)_fe2k_interrupt;
|
||||
break;
|
||||
case BCM88025_DEVICE_ID:
|
||||
ctrl->isr = (isr_f)_fe2kxt_interrupt;
|
||||
break;
|
||||
case BME3200_DEVICE_ID:
|
||||
ctrl->isr = (isr_f)_bme3200_interrupt;
|
||||
break;
|
||||
case BM9600_DEVICE_ID:
|
||||
ctrl->isr = (isr_f)_bm9600_interrupt;
|
||||
break;
|
||||
case BCM88750_DEVICE_ID:
|
||||
case BCM88753_DEVICE_ID:
|
||||
case BCM88754_DEVICE_ID:
|
||||
@ -920,7 +783,7 @@ _devices_init(int d)
|
||||
case BCM88380_DEVICE_ID:
|
||||
case BCM88381_DEVICE_ID:
|
||||
case BCM88680_DEVICE_ID:
|
||||
case BCM88690_DEVICE_ID:
|
||||
case BCM88800_DEVICE_ID:
|
||||
case BCM88770_DEVICE_ID:
|
||||
case BCM88773_DEVICE_ID:
|
||||
case BCM88774_DEVICE_ID:
|
||||
@ -938,6 +801,7 @@ _devices_init(int d)
|
||||
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:
|
||||
@ -1002,7 +866,15 @@ _devices_init(int d)
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* All Ramon devices from 0x8790 to 0x879F */
|
||||
|
||||
#ifdef BCM_DNX_SUPPORT
|
||||
/*All Jericho 2 devices from 0x8690 to 0x869F*/
|
||||
if (SOC_IS_JERICHO_2_TYPE(user_bde->get_dev(d)->device)) {
|
||||
ctrl->isr = (isr_f)_cmicx_interrupt;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*All Ramon devices from 0x8790 to 0x879F*/
|
||||
if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) {
|
||||
ctrl->isr = (isr_f)_cmicx_interrupt;
|
||||
}
|
||||
@ -1456,30 +1328,9 @@ _ioctl(unsigned int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
case LUBDE_USLEEP:
|
||||
sal_usleep(io.d0);
|
||||
break;
|
||||
case LUBDE_UDELAY:
|
||||
sal_udelay(io.d0);
|
||||
break;
|
||||
case LUBDE_SEM_OP:
|
||||
switch (io.d0) {
|
||||
case LUBDE_SEM_OP_CREATE:
|
||||
io.p0 = (bde_kernel_addr_t)sal_sem_create("", io.d1, io.d2);
|
||||
break;
|
||||
case LUBDE_SEM_OP_DESTROY:
|
||||
sal_sem_destroy((sal_sem_t)io.p0);
|
||||
break;
|
||||
case LUBDE_SEM_OP_TAKE:
|
||||
io.rc = sal_sem_take((sal_sem_t)io.p0, io.d2);
|
||||
break;
|
||||
case LUBDE_SEM_OP_GIVE:
|
||||
io.rc = sal_sem_give((sal_sem_t)io.p0);
|
||||
break;
|
||||
default:
|
||||
io.rc = LUBDE_FAIL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
return -EINVAL;
|
||||
case LUBDE_WRITE_IRQ_MASK:
|
||||
io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0);
|
||||
break;
|
||||
@ -1499,7 +1350,7 @@ _ioctl(unsigned int cmd, unsigned long arg)
|
||||
case LUBDE_WRITE_REG_16BIT_BUS:
|
||||
io.rc = user_bde->write(io.dev, io.d0, io.d1);
|
||||
break;
|
||||
#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT))
|
||||
#ifdef BCM_SAND_SUPPORT
|
||||
case LUBDE_CPU_WRITE_REG:
|
||||
{
|
||||
if (lkbde_cpu_write(io.dev, io.d0, (uint32*)io.dx.buf) == -1) {
|
||||
|
@ -30,6 +30,8 @@
|
||||
#define BAR0_PAXB_CONFIG_IND_ADDR 0x2120
|
||||
#define BAR0_PAXB_CONFIG_IND_DATA 0x2124
|
||||
|
||||
#define PAXB_0_CMICD_TO_PCIE_INTR_EN 0x2380
|
||||
|
||||
#define BAR0_PAXB_IMAP0_0 (0x2c00)
|
||||
#define BAR0_PAXB_IMAP0_1 (0x2c04)
|
||||
#define BAR0_PAXB_IMAP0_2 (0x2c08)
|
||||
@ -287,7 +289,8 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs,
|
||||
iproc32_write(shbde, reg, data | 0x1);
|
||||
}
|
||||
}
|
||||
/* Configure MSIX interrupt page, only need for iproc ver == 0x10 */
|
||||
|
||||
/* Configure MSIX interrupt page, only need for iproc ver == 0x10 */
|
||||
if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) {
|
||||
unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1;
|
||||
reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3);
|
||||
@ -296,6 +299,17 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs,
|
||||
data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT;
|
||||
iproc32_write(shbde, reg, data);
|
||||
}
|
||||
|
||||
/* Disable INTx interrupt if MSI/MSIX is selected */
|
||||
reg = ROFFS(iproc_regs, PAXB_0_CMICD_TO_PCIE_INTR_EN);
|
||||
data = iproc32_read(shbde, reg);
|
||||
if (icfg->use_msi) {
|
||||
data &= ~0x1;
|
||||
} else {
|
||||
data |= 0x1;
|
||||
}
|
||||
iproc32_write(shbde, reg, data);
|
||||
|
||||
return pci_num;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,14 +39,17 @@ typedef struct {
|
||||
* Call-back interfaces for other Linux kernel drivers.
|
||||
*/
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <kcom.h>
|
||||
|
||||
typedef struct {
|
||||
uint32 netif_user_data;
|
||||
uint32 filter_user_data;
|
||||
uint16 dcb_type;
|
||||
int port;
|
||||
} knet_skb_cb_t;
|
||||
|
||||
#define KNET_SKB_CB(__skb) ((knet_skb_cb_t *)&((__skb)->cb[0]))
|
||||
#define KNET_SKB_CB(_skb) ((knet_skb_cb_t *)_skb->cb)
|
||||
|
||||
typedef struct sk_buff *
|
||||
(*knet_skb_cb_f)(struct sk_buff *skb, int dev_no, void *meta);
|
||||
@ -55,6 +58,21 @@ typedef int
|
||||
(*knet_filter_cb_f)(uint8_t *pkt, int size, int dev_no, void *meta,
|
||||
int chan, kcom_filter_t *filter);
|
||||
|
||||
typedef int
|
||||
(*knet_hw_tstamp_enable_cb_f)(int dev_no, int port);
|
||||
|
||||
typedef int
|
||||
(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int port, uint8_t *pkt, uint64_t *ts);
|
||||
|
||||
typedef int
|
||||
(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, struct sk_buff *skb, uint32_t **md);
|
||||
|
||||
typedef int
|
||||
(*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no);
|
||||
|
||||
typedef int
|
||||
(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, uint64_t *ts);
|
||||
|
||||
extern int
|
||||
bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb);
|
||||
|
||||
@ -73,6 +91,68 @@ bkn_filter_cb_register(knet_filter_cb_f filter_cb);
|
||||
extern int
|
||||
bkn_filter_cb_unregister(knet_filter_cb_f filter_cb);
|
||||
|
||||
#endif
|
||||
extern int
|
||||
bkn_hw_tstamp_enable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_enable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_disable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_disable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_tx_time_get_cb_register(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_tx_time_get_cb_unregister(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_tx_meta_get_cb_register(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_tx_meta_get_cb_unregister(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb);
|
||||
|
||||
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_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb);
|
||||
|
||||
extern int
|
||||
bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb);
|
||||
|
||||
typedef struct {
|
||||
uint8 cmic_type;
|
||||
uint8 dcb_type;
|
||||
uint8 dcb_size;
|
||||
uint8 pkt_hdr_size;
|
||||
uint32 cdma_channels;
|
||||
} knet_hw_info_t;
|
||||
|
||||
extern int
|
||||
bkn_hw_info_get(int unit, knet_hw_info_t *hw_info);
|
||||
|
||||
typedef int
|
||||
(*knet_netif_cb_f)(int unit, kcom_netif_t *netif, struct net_device *dev);
|
||||
|
||||
extern int
|
||||
bkn_netif_create_cb_register(knet_netif_cb_f netif_cb);
|
||||
|
||||
extern int
|
||||
bkn_netif_create_cb_unregister(knet_netif_cb_f netif_cb);
|
||||
|
||||
extern int
|
||||
bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb);
|
||||
|
||||
extern int
|
||||
bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __LINUX_BCM_KNET_H__ */
|
||||
|
@ -0,0 +1,24 @@
|
||||
#ifndef __NET_PSAMPLE_H
|
||||
#define __NET_PSAMPLE_H
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <uapi/linux/psample.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
struct psample_group {
|
||||
struct list_head list;
|
||||
struct net *net;
|
||||
u32 group_num;
|
||||
u32 refcount;
|
||||
u32 seq;
|
||||
};
|
||||
|
||||
extern struct psample_group *psample_group_get(struct net *net, u32 group_num);
|
||||
extern void psample_group_put(struct psample_group *group);
|
||||
|
||||
extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
|
||||
u32 trunc_size, int in_ifindex, int out_ifindex,
|
||||
u32 sample_rate);
|
||||
|
||||
#endif /* __NET_PSAMPLE_H */
|
@ -0,0 +1,35 @@
|
||||
#ifndef __UAPI_PSAMPLE_H
|
||||
#define __UAPI_PSAMPLE_H
|
||||
|
||||
enum {
|
||||
/* sampled packet metadata */
|
||||
PSAMPLE_ATTR_IIFINDEX,
|
||||
PSAMPLE_ATTR_OIFINDEX,
|
||||
PSAMPLE_ATTR_ORIGSIZE,
|
||||
PSAMPLE_ATTR_SAMPLE_GROUP,
|
||||
PSAMPLE_ATTR_GROUP_SEQ,
|
||||
PSAMPLE_ATTR_SAMPLE_RATE,
|
||||
PSAMPLE_ATTR_DATA,
|
||||
|
||||
/* commands attributes */
|
||||
PSAMPLE_ATTR_GROUP_REFCOUNT,
|
||||
|
||||
__PSAMPLE_ATTR_MAX
|
||||
};
|
||||
|
||||
enum psample_command {
|
||||
PSAMPLE_CMD_SAMPLE,
|
||||
PSAMPLE_CMD_GET_GROUP,
|
||||
PSAMPLE_CMD_NEW_GROUP,
|
||||
PSAMPLE_CMD_DEL_GROUP,
|
||||
};
|
||||
|
||||
/* Can be overridden at runtime by module option */
|
||||
#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
|
||||
|
||||
#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
|
||||
#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
|
||||
#define PSAMPLE_GENL_NAME "psample"
|
||||
#define PSAMPLE_GENL_VERSION 1
|
||||
|
||||
#endif
|
@ -36,7 +36,9 @@ KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko
|
||||
build: $(MODULE) $(KMODULE)
|
||||
endif
|
||||
|
||||
KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers
|
||||
ifeq ($(BUILD_PSAMPLE),1)
|
||||
KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers
|
||||
endif
|
||||
|
||||
# BCM Network Device
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017 Broadcom
|
||||
* Copyright 2017-2019 Broadcom
|
||||
*
|
||||
* 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
|
||||
@ -45,17 +45,20 @@
|
||||
#include <bcm-knet.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
/* Enable sflow sampling using psample */
|
||||
#ifdef PSAMPLE_SUPPORT
|
||||
#include "psample-cb.h"
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom Linux KNET Call-Back Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
static int debug;
|
||||
int debug;
|
||||
LKM_MOD_PARAM(debug, "i", int, 0);
|
||||
MODULE_PARM_DESC(debug,
|
||||
"Debug level (default 0)");
|
||||
|
||||
|
||||
/* Module Information */
|
||||
#define MODULE_MAJOR 121
|
||||
#define MODULE_NAME "linux-knet-cb"
|
||||
@ -63,8 +66,10 @@ MODULE_PARM_DESC(debug,
|
||||
/* set KNET_CB_DEBUG for debug info */
|
||||
#define KNET_CB_DEBUG
|
||||
|
||||
#define FILTER_TAG_STRIP 0
|
||||
#define FILTER_TAG_KEEP 1
|
||||
/* These below need to match incoming enum values */
|
||||
#define FILTER_TAG_STRIP 0
|
||||
#define FILTER_TAG_KEEP 1
|
||||
#define FILTER_TAG_ORIGINAL 2
|
||||
|
||||
/* Maintain tag strip statistics */
|
||||
struct strip_stats_s {
|
||||
@ -105,7 +110,7 @@ strip_vlan_tag(struct sk_buff *skb)
|
||||
*
|
||||
* DCB type 14: word 12, bits 10.11
|
||||
* DCB type 19, 20, 21, 22, 30: word 12, bits 10..11
|
||||
* DCB type 23, 29: word 13, bits 0..1
|
||||
* DCB type 23, 29: word 13, bits 0..1
|
||||
* DCB type 31, 34, 37: word 13, bits 0..1
|
||||
* DCB type 26, 32, 33, 35: word 13, bits 0..1
|
||||
*
|
||||
@ -150,7 +155,7 @@ get_tag_status(int dcb_type, void *meta)
|
||||
{
|
||||
/* untested */
|
||||
/* TH3 only parses outer tag. */
|
||||
const int tag_map[4] = { 0, 2, -1, -1 };
|
||||
const int tag_map[4] = { 0, 2, -1, -1 };
|
||||
tag_status = tag_map[(dcb[9] >> 13) & 0x3];
|
||||
}
|
||||
break;
|
||||
@ -162,7 +167,7 @@ get_tag_status(int dcb_type, void *meta)
|
||||
if (debug & 0x1) {
|
||||
gprintk("%s; DCB Type: %d; tag status: %d\n", __func__, dcb_type, tag_status);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return tag_status;
|
||||
}
|
||||
|
||||
@ -183,12 +188,12 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta)
|
||||
if (debug & 0x1) {
|
||||
gprintk("%s Enter; netif Flags: %08X filter_flags %08X \n",
|
||||
__func__, netif_flags, filter_flags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* KNET implements this already */
|
||||
if (filter_flags == FILTER_TAG_KEEP)
|
||||
{
|
||||
{
|
||||
strip_stats.skipped++;
|
||||
return skb;
|
||||
}
|
||||
@ -217,8 +222,17 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta)
|
||||
return skb;
|
||||
}
|
||||
|
||||
if (filter_flags == FILTER_TAG_ORIGINAL)
|
||||
{
|
||||
/* If untagged or single inner, strip the extra tag that knet
|
||||
keep tag will add. */
|
||||
if (tag_status < 2)
|
||||
{
|
||||
strip_tag = 1;
|
||||
}
|
||||
}
|
||||
strip_stats.checked++;
|
||||
|
||||
|
||||
if (strip_tag) {
|
||||
#ifdef KNET_CB_DEBUG
|
||||
if (debug & 0x1) {
|
||||
@ -235,7 +249,6 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
@ -250,16 +263,50 @@ strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta)
|
||||
/* Filter callback not used */
|
||||
static int
|
||||
strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta,
|
||||
int chan, kcom_filter_t *kf)
|
||||
int chan, kcom_filter_t *kf)
|
||||
{
|
||||
/* Pass through for now */
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
return strip_tag_filter_cb (pkt, size, dev_no, meta, chan, kf);
|
||||
}
|
||||
|
||||
static int
|
||||
knet_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
|
||||
{
|
||||
int retv = 0;
|
||||
#ifdef PSAMPLE_SUPPORT
|
||||
retv = psample_netif_create_cb(unit, netif, dev);
|
||||
#endif
|
||||
return retv;
|
||||
}
|
||||
|
||||
static int
|
||||
knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
|
||||
{
|
||||
int retv = 0;
|
||||
#ifdef PSAMPLE_SUPPORT
|
||||
retv = psample_netif_destroy_cb(unit, netif, dev);
|
||||
#endif
|
||||
return retv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get statistics.
|
||||
* % cat /proc/linux-knet-cb
|
||||
*/
|
||||
|
||||
static int
|
||||
_pprint(void)
|
||||
{
|
||||
@ -275,19 +322,40 @@ static int
|
||||
_cleanup(void)
|
||||
{
|
||||
bkn_rx_skb_cb_unregister(strip_tag_rx_cb);
|
||||
bkn_tx_skb_cb_unregister(strip_tag_tx_cb);
|
||||
bkn_filter_cb_unregister(strip_tag_filter_cb);
|
||||
/* strip_tag_tx_cb is currently a no-op, so no need to unregister */
|
||||
if (0)
|
||||
{
|
||||
bkn_tx_skb_cb_unregister(strip_tag_tx_cb);
|
||||
}
|
||||
|
||||
bkn_filter_cb_unregister(knet_filter_cb);
|
||||
bkn_netif_create_cb_unregister(knet_netif_create_cb);
|
||||
bkn_netif_destroy_cb_unregister(knet_netif_destroy_cb);
|
||||
|
||||
#ifdef PSAMPLE_SUPPORT
|
||||
psample_cleanup();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_init(void)
|
||||
{
|
||||
bkn_rx_skb_cb_register(strip_tag_rx_cb);
|
||||
bkn_tx_skb_cb_register(strip_tag_tx_cb);
|
||||
bkn_filter_cb_register(strip_tag_filter_cb);
|
||||
|
||||
bkn_rx_skb_cb_register(strip_tag_rx_cb);
|
||||
/* strip_tag_tx_cb is currently a no-op, so no need to register */
|
||||
if (0)
|
||||
{
|
||||
bkn_tx_skb_cb_register(strip_tag_tx_cb);
|
||||
}
|
||||
|
||||
#ifdef PSAMPLE_SUPPORT
|
||||
psample_init();
|
||||
#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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,875 @@
|
||||
/*
|
||||
* Copyright 2017-2019 Broadcom
|
||||
*
|
||||
* 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 (the "GPL").
|
||||
*
|
||||
* 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 version 2 (GPLv2) for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 (GPLv2) along with this source code.
|
||||
*/
|
||||
/*
|
||||
* $Id: psample_cb.c $
|
||||
* $Copyright: (c) 2019 Broadcom Corp.
|
||||
* All Rights Reserved.$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for call-back functions for Linux KNET driver.
|
||||
*
|
||||
* This code is used to integrate packet sampling KNET callback to
|
||||
* the psample infra for sending sampled pkts to userspace sflow
|
||||
* applications such as Host Sflow (https://github.com/sflow/host-sflow)
|
||||
* using genetlink interfaces.
|
||||
*
|
||||
* The module can be built from the standard Linux user mode target
|
||||
* directories using the following command (assuming bash), e.g.
|
||||
*
|
||||
* cd $SDK/systems/linux/user/<target>
|
||||
* make BUILD_KNET_CB=1
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gmodule.h> /* Must be included first */
|
||||
#include <kcom.h>
|
||||
#include <bcm-knet.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/psample.h>
|
||||
#include "psample-cb.h"
|
||||
|
||||
#define PSAMPLE_CB_DBG
|
||||
#ifdef PSAMPLE_CB_DBG
|
||||
extern int debug;
|
||||
#define PSAMPLE_CB_DBG_PRINT(...) \
|
||||
if (debug & 0x1) { \
|
||||
gprintk(__VA_ARGS__); \
|
||||
}
|
||||
#else
|
||||
#define PSAMPLE_CB_DBG_PRINT(...)
|
||||
#endif
|
||||
|
||||
/* HIGIG2 header fields */
|
||||
#define SOC_HIGIG_SOP (0xfb)
|
||||
#define SOC_HIGIG_START(x) ((x[0] >> 24) & 0xff)
|
||||
#define SOC_HIGIG_DSTPORT(x) ((x[1] >> 11) & 0x1f)
|
||||
#define SOC_HIGIG_SRCPORT(x) ((x[1] >> 16) & 0x1f)
|
||||
#define SOC_HIGIG2_SOP (0xfb) //0xfc - TODO: how can we differentiate between Higig and higig2?
|
||||
#define SOC_HIGIG2_START(x) ((x[0] >> 24) & 0xff)
|
||||
#define SOC_HIGIG2_DSTPORT(x) ((x[0] >> 0) & 0xff)
|
||||
#define SOC_HIGIG2_SRCPORT(x) ((x[1] >> 16) & 0xff)
|
||||
#define SOC_DCB32_HG_OFFSET (6)
|
||||
|
||||
#define FCS_SZ 4
|
||||
#define PSAMPLE_NLA_PADDING 4
|
||||
|
||||
#define PSAMPLE_RATE_DFLT 1
|
||||
#define PSAMPLE_SIZE_DFLT 128
|
||||
static int psample_size = PSAMPLE_SIZE_DFLT;
|
||||
LKM_MOD_PARAM(psample_size, "i", int, 0);
|
||||
MODULE_PARM_DESC(psample_size,
|
||||
"psample pkt size (default 128 bytes)");
|
||||
|
||||
/* driver proc entry root */
|
||||
static struct proc_dir_entry *psample_proc_root = NULL;
|
||||
|
||||
/* psample general info */
|
||||
typedef struct {
|
||||
struct list_head netif_list;
|
||||
knet_hw_info_t hw;
|
||||
struct net *netns;
|
||||
spinlock_t lock;
|
||||
} psample_info_t;
|
||||
static psample_info_t g_psample_info = {{0}};
|
||||
|
||||
/* Maintain sampled pkt statistics */
|
||||
typedef struct psample_stats_s {
|
||||
unsigned long pkts_f_psample_cb;
|
||||
unsigned long pkts_f_psample_mod;
|
||||
unsigned long pkts_f_handled;
|
||||
unsigned long pkts_f_pass_through;
|
||||
unsigned long pkts_d_no_group;
|
||||
unsigned long pkts_d_sampling_disabled;
|
||||
unsigned long pkts_d_no_skb;
|
||||
unsigned long pkts_d_not_ready;
|
||||
unsigned long pkts_d_metadata;
|
||||
unsigned long pkts_d_meta_srcport;
|
||||
unsigned long pkts_d_meta_dstport;
|
||||
unsigned long pkts_d_invalid_size;
|
||||
} psample_stats_t;
|
||||
static psample_stats_t g_psample_stats = {0};
|
||||
|
||||
typedef struct psample_meta_s {
|
||||
int trunc_size;
|
||||
int src_ifindex;
|
||||
int dst_ifindex;
|
||||
int sample_rate;
|
||||
} psample_meta_t;
|
||||
|
||||
|
||||
static psample_netif_t*
|
||||
psample_netif_lookup_by_port(int unit, int port)
|
||||
{
|
||||
struct list_head *list;
|
||||
psample_netif_t *psample_netif = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
/* look for port from list of available net_devices */
|
||||
spin_lock_irqsave(&g_psample_info.lock, flags);
|
||||
list_for_each(list, &g_psample_info.netif_list) {
|
||||
psample_netif = (psample_netif_t*)list;
|
||||
if (psample_netif->port == port) {
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
return psample_netif;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
psample_info_get (int unit, psample_info_t *psample_info)
|
||||
{
|
||||
int rv = 0;
|
||||
if (!psample_info) {
|
||||
gprintk("%s: psample_info is NULL\n", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* get hw info */
|
||||
rv = bkn_hw_info_get(unit, &psample_info->hw);
|
||||
if (rv < 0) {
|
||||
gprintk("%s: failed to get hw info\n", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
PSAMPLE_CB_DBG_PRINT("%s: DCB type %d\n",
|
||||
__func__, psample_info->hw.dcb_type);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
psample_meta_srcport_get(uint8_t *pkt, void *pkt_meta)
|
||||
{
|
||||
int srcport = 0;
|
||||
uint32_t *metadata = (uint32_t*)pkt_meta;
|
||||
|
||||
switch(g_psample_info.hw.dcb_type) {
|
||||
case 36: /* TD3 */
|
||||
case 38: /* TH3 */
|
||||
break;
|
||||
case 32: /* TH1/TH2 */
|
||||
case 26: /* TD2 */
|
||||
case 23: /* HX4 */
|
||||
metadata += SOC_DCB32_HG_OFFSET;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP)
|
||||
{
|
||||
srcport = SOC_HIGIG2_SRCPORT(metadata);
|
||||
}
|
||||
else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP)
|
||||
{
|
||||
srcport = SOC_HIGIG_SRCPORT(metadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__,
|
||||
SOC_HIGIG_START(metadata), metadata[0]);
|
||||
return -1;
|
||||
}
|
||||
return srcport;
|
||||
}
|
||||
|
||||
static int
|
||||
psample_meta_dstport_get(uint8_t *pkt, void *pkt_meta)
|
||||
{
|
||||
int dstport = 0;
|
||||
uint32_t *metadata = (uint32_t*)pkt_meta;
|
||||
|
||||
switch(g_psample_info.hw.dcb_type) {
|
||||
case 36: /* TD3 */
|
||||
case 38: /* TH3 */
|
||||
break;
|
||||
case 32: /* TH1/TH2 */
|
||||
case 26: /* TD2 */
|
||||
case 23: /* HX4 */
|
||||
metadata += SOC_DCB32_HG_OFFSET;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP)
|
||||
{
|
||||
dstport = SOC_HIGIG2_DSTPORT(metadata);
|
||||
}
|
||||
else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP)
|
||||
{
|
||||
dstport = SOC_HIGIG_DSTPORT(metadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__,
|
||||
SOC_HIGIG_START(metadata), metadata[0]);
|
||||
return (-1);
|
||||
}
|
||||
return dstport;
|
||||
}
|
||||
|
||||
static int
|
||||
psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta)
|
||||
{
|
||||
uint32_t *metadata = (uint32_t*)pkt_meta;
|
||||
uint32_t reason = 0;
|
||||
uint32_t reason_hi = 0;
|
||||
uint32_t sample_rx_reason_mask = 0;
|
||||
|
||||
/* Sample Pkt reason code (bcmRxReasonSampleSource) */
|
||||
switch(g_psample_info.hw.dcb_type) {
|
||||
case 36: /* TD3 */
|
||||
case 38: /* TH3 */
|
||||
reason_hi = *(metadata + 4);
|
||||
reason = *(metadata + 5);
|
||||
sample_rx_reason_mask = (1 << 3);
|
||||
break;
|
||||
case 32: /* TH1/TH2 */
|
||||
case 26: /* TD2 */
|
||||
case 23: /* HX4 */
|
||||
default:
|
||||
reason_hi = *(metadata + 2);
|
||||
reason = *(metadata + 3);
|
||||
sample_rx_reason_mask = (1 << 5);
|
||||
break;
|
||||
}
|
||||
|
||||
PSAMPLE_CB_DBG_PRINT("%s: DCB%d sample_rx_reason_mask: 0x%08x, reason: 0x%08x, reason_hi: 0x%08x\n",
|
||||
__func__, g_psample_info.hw.dcb_type, sample_rx_reason_mask, reason, reason_hi);
|
||||
|
||||
/* Check if only sample reason code is set.
|
||||
* If only sample reason code, then consume pkt.
|
||||
* If other reason codes exist, then pkt should be
|
||||
* passed through to Linux network stack.
|
||||
*/
|
||||
if ((reason & ~sample_rx_reason_mask) || reason_hi) {
|
||||
return 0; /* multiple reasons set, pass through */
|
||||
}
|
||||
|
||||
/* only sample rx reason set, consume pkt */
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_meta)
|
||||
{
|
||||
int srcport, dstport;
|
||||
int src_ifindex = 0;
|
||||
int dst_ifindex = 0;
|
||||
int sample_rate = PSAMPLE_RATE_DFLT;
|
||||
int sample_size = PSAMPLE_SIZE_DFLT;
|
||||
psample_netif_t *psample_netif = NULL;
|
||||
|
||||
#ifdef PSAMPLE_CB_DBG
|
||||
if (debug & 0x1) {
|
||||
int i=0;
|
||||
uint8_t *meta = (uint8_t*)pkt_meta;
|
||||
PSAMPLE_CB_DBG_PRINT("%s: psample pkt metadata\n", __func__);
|
||||
for (i=0; i<64; i+=16) {
|
||||
PSAMPLE_CB_DBG_PRINT("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
meta[i+0], meta[i+1], meta[i+2], meta[i+3], meta[i+4], meta[i+5], meta[i+6], meta[i+7],
|
||||
meta[i+8], meta[i+9], meta[i+10], meta[i+11], meta[i+12], meta[i+13], meta[i+14], meta[i+15]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* parse pkt metadata for src and dst ports */
|
||||
srcport = psample_meta_srcport_get(pkt, pkt_meta);
|
||||
dstport = psample_meta_dstport_get(pkt, pkt_meta);
|
||||
if ((srcport == -1) || (dstport == -1)) {
|
||||
gprintk("%s: invalid srcport %d or dstport %d\n", __func__, srcport, dstport);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* find src port netif (no need to lookup CPU port) */
|
||||
if (srcport != 0) {
|
||||
if ((psample_netif = psample_netif_lookup_by_port(unit, srcport))) {
|
||||
src_ifindex = psample_netif->dev->ifindex;
|
||||
sample_rate = psample_netif->sample_rate;
|
||||
sample_size = psample_netif->sample_size;
|
||||
} else {
|
||||
g_psample_stats.pkts_d_meta_srcport++;
|
||||
PSAMPLE_CB_DBG_PRINT("%s: could not find srcport(%d)\n", __func__, srcport);
|
||||
}
|
||||
}
|
||||
|
||||
/* find dst port netif (no need to lookup CPU port) */
|
||||
if (dstport != 0) {
|
||||
if ((psample_netif = psample_netif_lookup_by_port(unit, dstport))) {
|
||||
dst_ifindex = psample_netif->dev->ifindex;
|
||||
} else {
|
||||
g_psample_stats.pkts_d_meta_dstport++;
|
||||
PSAMPLE_CB_DBG_PRINT("%s: could not find dstport(%d)\n", __func__, dstport);
|
||||
}
|
||||
}
|
||||
|
||||
PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex %d, dst_ifindex %d, trunc_size %d, sample_rate %d\n",
|
||||
__func__, srcport, dstport, src_ifindex, dst_ifindex, sample_size, sample_rate);
|
||||
|
||||
sflow_meta->src_ifindex = src_ifindex;
|
||||
sflow_meta->dst_ifindex = dst_ifindex;
|
||||
sflow_meta->trunc_size = sample_size;
|
||||
sflow_meta->sample_rate = sample_rate;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta,
|
||||
int chan, kcom_filter_t *kf)
|
||||
{
|
||||
struct psample_group *group;
|
||||
psample_meta_t meta;
|
||||
struct sk_buff skb;
|
||||
int rv = 0;
|
||||
static int info_get = 0;
|
||||
|
||||
if (!info_get) {
|
||||
rv = psample_info_get (dev_no, &g_psample_info);
|
||||
if (rv < 0) {
|
||||
gprintk("%s: failed to get psample info\n", __func__);
|
||||
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
|
||||
}
|
||||
info_get = 1;
|
||||
}
|
||||
|
||||
PSAMPLE_CB_DBG_PRINT("%s: pkt size %d, kf->dest_id %d, kf->cb_user_data %d\n",
|
||||
__func__, size, kf->dest_id, kf->cb_user_data);
|
||||
g_psample_stats.pkts_f_psample_cb++;
|
||||
|
||||
/* get psample group info. psample genetlink group ID passed in kf->dest_id */
|
||||
group = psample_group_get(g_psample_info.netns, kf->dest_id);
|
||||
if (!group) {
|
||||
gprintk("%s: Could not find psample genetlink group %d\n", __func__, kf->cb_user_data);
|
||||
g_psample_stats.pkts_d_no_group++;
|
||||
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
|
||||
}
|
||||
|
||||
/* get psample metadata */
|
||||
rv = psample_meta_get(dev_no, pkt, pkt_meta, &meta);
|
||||
if (rv < 0) {
|
||||
gprintk("%s: Could not parse pkt metadata\n", __func__);
|
||||
g_psample_stats.pkts_d_metadata++;
|
||||
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
|
||||
}
|
||||
|
||||
/* Adjust original pkt size to remove 4B FCS */
|
||||
if (size < FCS_SZ) {
|
||||
g_psample_stats.pkts_d_invalid_size++;
|
||||
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
|
||||
} else {
|
||||
size -= FCS_SZ;
|
||||
}
|
||||
|
||||
/* Account for padding in libnl used by psample */
|
||||
if (meta.trunc_size >= size) {
|
||||
meta.trunc_size = size - PSAMPLE_NLA_PADDING;
|
||||
}
|
||||
|
||||
PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx %d, dst_ifdx %d, sample_rate %d\n",
|
||||
__func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate);
|
||||
|
||||
/* drop if configured sample rate is 0 */
|
||||
if (meta.sample_rate > 0) {
|
||||
/* setup skb to point to pkt */
|
||||
memset(&skb, 0, sizeof(struct sk_buff));
|
||||
skb.len = size;
|
||||
skb.data = pkt;
|
||||
|
||||
psample_sample_packet(group,
|
||||
&skb,
|
||||
meta.trunc_size,
|
||||
meta.src_ifindex,
|
||||
meta.dst_ifindex,
|
||||
meta.sample_rate);
|
||||
|
||||
g_psample_stats.pkts_f_psample_mod++;
|
||||
} else {
|
||||
g_psample_stats.pkts_d_sampling_disabled++;
|
||||
}
|
||||
|
||||
PSAMPLE_FILTER_CB_PKT_HANDLED:
|
||||
/* if sample reason only, consume pkt. else pass through */
|
||||
rv = psample_meta_sample_reason(pkt, pkt_meta);
|
||||
if (rv) {
|
||||
g_psample_stats.pkts_f_handled++;
|
||||
} else {
|
||||
g_psample_stats.pkts_f_pass_through++;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
|
||||
{
|
||||
int found;
|
||||
struct list_head *list;
|
||||
psample_netif_t *psample_netif, *lpsample_netif;
|
||||
unsigned long flags;
|
||||
|
||||
if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_KERNEL)) == NULL) {
|
||||
gprintk("%s: failed to alloc psample mem for netif '%s'\n",
|
||||
__func__, dev->name);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&g_psample_info.lock, flags);
|
||||
|
||||
psample_netif->dev = dev;
|
||||
psample_netif->id = netif->id;
|
||||
psample_netif->port = netif->port;
|
||||
psample_netif->vlan = netif->vlan;
|
||||
psample_netif->qnum = netif->qnum;
|
||||
psample_netif->sample_rate = PSAMPLE_RATE_DFLT;
|
||||
psample_netif->sample_size = PSAMPLE_SIZE_DFLT;
|
||||
|
||||
/* insert netif sorted by ID similar to bkn_knet_netif_create() */
|
||||
found = 0;
|
||||
list_for_each(list, &g_psample_info.netif_list) {
|
||||
lpsample_netif = (psample_netif_t*)list;
|
||||
if (netif->id < lpsample_netif->id) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
/* Replace previously removed interface */
|
||||
list_add_tail(&psample_netif->list, &lpsample_netif->list);
|
||||
} else {
|
||||
/* No holes - add to end of list */
|
||||
list_add_tail(&psample_netif->list, &g_psample_info.netif_list);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
|
||||
PSAMPLE_CB_DBG_PRINT("%s: added psample netif '%s'\n", __func__, dev->name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
|
||||
{
|
||||
int found;
|
||||
struct list_head *list;
|
||||
psample_netif_t *psample_netif;
|
||||
unsigned long flags;
|
||||
|
||||
if (!netif || !dev) {
|
||||
gprintk("%s: netif or net_device is NULL\n", __func__);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&g_psample_info.lock, flags);
|
||||
|
||||
list_for_each(list, &g_psample_info.netif_list) {
|
||||
psample_netif = (psample_netif_t*)list;
|
||||
if (netif->id == psample_netif->id) {
|
||||
found = 1;
|
||||
list_del(&psample_netif->list);
|
||||
PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name);
|
||||
kfree(psample_netif);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
|
||||
if (!found) {
|
||||
gprintk("%s: netif ID %d not found!\n", __func__, netif->id);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* psample rate Proc Read Entry
|
||||
*/
|
||||
static int
|
||||
psample_proc_rate_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct list_head *list;
|
||||
psample_netif_t *psample_netif;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&g_psample_info.lock, flags);
|
||||
|
||||
list_for_each(list, &g_psample_info.netif_list) {
|
||||
psample_netif = (psample_netif_t*)list;
|
||||
seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_rate);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
psample_proc_rate_open(struct inode * inode, struct file * file)
|
||||
{
|
||||
return single_open(file, psample_proc_rate_show, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* psample rate Proc Write Entry
|
||||
*
|
||||
* Syntax:
|
||||
* <netif>=<pkt sample rate>
|
||||
*
|
||||
* Where <netif> is a virtual network interface name.
|
||||
*
|
||||
* Examples:
|
||||
* eth4=1000
|
||||
*/
|
||||
static ssize_t
|
||||
psample_proc_rate_write(struct file *file, const char *buf,
|
||||
size_t count, loff_t *loff)
|
||||
{
|
||||
int found;
|
||||
struct list_head *list;
|
||||
psample_netif_t *psample_netif;
|
||||
char sample_str[40], *ptr, *newline;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
if (count > sizeof(sample_str)) {
|
||||
count = sizeof(sample_str) - 1;
|
||||
sample_str[count] = '\0';
|
||||
}
|
||||
if (copy_from_user(sample_str, buf, count)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
sample_str[count] = 0;
|
||||
newline = strchr(sample_str, '\n');
|
||||
if (newline) {
|
||||
/* Chop off the trailing newline */
|
||||
*newline = '\0';
|
||||
}
|
||||
|
||||
if ((ptr = strchr(sample_str, '=')) == NULL &&
|
||||
(ptr = strchr(sample_str, ':')) == NULL) {
|
||||
gprintk("Error: Pkt sample rate syntax not recognized: '%s'\n", sample_str);
|
||||
return count;
|
||||
}
|
||||
*ptr++ = 0;
|
||||
|
||||
spin_lock_irqsave(&g_psample_info.lock, flags);
|
||||
|
||||
found = 0;
|
||||
list_for_each(list, &g_psample_info.netif_list) {
|
||||
psample_netif = (psample_netif_t*)list;
|
||||
if (strcmp(psample_netif->dev->name, sample_str) == 0) {
|
||||
psample_netif->sample_rate = simple_strtol(ptr, NULL, 10);
|
||||
// TODO MLI@BRCM - check valid sample rate
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
|
||||
if (!found) {
|
||||
gprintk("Warning: Failed setting psample rate on unknown network interface: '%s'\n", sample_str);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
struct file_operations psample_proc_rate_file_ops = {
|
||||
owner: THIS_MODULE,
|
||||
open: psample_proc_rate_open,
|
||||
read: seq_read,
|
||||
llseek: seq_lseek,
|
||||
write: psample_proc_rate_write,
|
||||
release: single_release,
|
||||
};
|
||||
|
||||
/*
|
||||
* psample size Proc Read Entry
|
||||
*/
|
||||
static int
|
||||
psample_proc_size_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct list_head *list;
|
||||
psample_netif_t *psample_netif;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&g_psample_info.lock, flags);
|
||||
|
||||
list_for_each(list, &g_psample_info.netif_list) {
|
||||
psample_netif = (psample_netif_t*)list;
|
||||
seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_size);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
psample_proc_size_open(struct inode * inode, struct file * file)
|
||||
{
|
||||
return single_open(file, psample_proc_size_show, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* psample size Proc Write Entry
|
||||
*
|
||||
* Syntax:
|
||||
* <netif>=<pkt sample size in bytes>
|
||||
*
|
||||
* Where <netif> is a virtual network interface name.
|
||||
*
|
||||
* Examples:
|
||||
* eth4=128
|
||||
*/
|
||||
static ssize_t
|
||||
psample_proc_size_write(struct file *file, const char *buf,
|
||||
size_t count, loff_t *loff)
|
||||
{
|
||||
int found;
|
||||
struct list_head *list;
|
||||
psample_netif_t *psample_netif;
|
||||
char sample_str[40], *ptr, *newline;
|
||||
unsigned long flags;
|
||||
|
||||
if (count > sizeof(sample_str)) {
|
||||
count = sizeof(sample_str) - 1;
|
||||
sample_str[count] = '\0';
|
||||
}
|
||||
if (copy_from_user(sample_str, buf, count)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
sample_str[count] = 0;
|
||||
newline = strchr(sample_str, '\n');
|
||||
if (newline) {
|
||||
/* Chop off the trailing newline */
|
||||
*newline = '\0';
|
||||
}
|
||||
|
||||
if ((ptr = strchr(sample_str, '=')) == NULL &&
|
||||
(ptr = strchr(sample_str, ':')) == NULL) {
|
||||
gprintk("Error: Pkt sample size syntax not recognized: '%s'\n", sample_str);
|
||||
return count;
|
||||
}
|
||||
*ptr++ = 0;
|
||||
|
||||
spin_lock_irqsave(&g_psample_info.lock, flags);
|
||||
|
||||
found = 0;
|
||||
list_for_each(list, &g_psample_info.netif_list) {
|
||||
psample_netif = (psample_netif_t*)list;
|
||||
if (strcmp(psample_netif->dev->name, sample_str) == 0) {
|
||||
psample_netif->sample_size = simple_strtol(ptr, NULL, 10);
|
||||
// TODO MLI@BRCM - check valid sample size
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_psample_info.lock, flags);
|
||||
|
||||
if (!found) {
|
||||
gprintk("Warning: Failed setting psample size on unknown network interface: '%s'\n", sample_str);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
struct file_operations psample_proc_size_file_ops = {
|
||||
owner: THIS_MODULE,
|
||||
open: psample_proc_size_open,
|
||||
read: seq_read,
|
||||
llseek: seq_lseek,
|
||||
write: psample_proc_size_write,
|
||||
release: single_release,
|
||||
};
|
||||
|
||||
/*
|
||||
* psample debug Proc Read Entry
|
||||
*/
|
||||
static int
|
||||
psample_proc_debug_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "BCM KNET %s Callback Config\n", PSAMPLE_CB_NAME);
|
||||
seq_printf(m, " debug: 0x%x\n", debug);
|
||||
seq_printf(m, " cmic_type: %d\n", g_psample_info.hw.cmic_type);
|
||||
seq_printf(m, " dcb_type: %d\n", g_psample_info.hw.dcb_type);
|
||||
seq_printf(m, " dcb_size: %d\n", g_psample_info.hw.dcb_size);
|
||||
seq_printf(m, " pkt_hdr_size: %d\n", g_psample_info.hw.pkt_hdr_size);
|
||||
seq_printf(m, " cdma_channels: %d\n", g_psample_info.hw.cdma_channels);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
psample_proc_debug_open(struct inode * inode, struct file * file)
|
||||
{
|
||||
return single_open(file, psample_proc_debug_show, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* psample debug Proc Write Entry
|
||||
*
|
||||
* Syntax:
|
||||
* debug=<mask>
|
||||
*
|
||||
* Where <mask> corresponds to the debug module parameter.
|
||||
*
|
||||
* Examples:
|
||||
* debug=0x1
|
||||
*/
|
||||
static ssize_t
|
||||
psample_proc_debug_write(struct file *file, const char *buf,
|
||||
size_t count, loff_t *loff)
|
||||
{
|
||||
char debug_str[40];
|
||||
char *ptr;
|
||||
|
||||
if (count > sizeof(debug_str)) {
|
||||
count = sizeof(debug_str) - 1;
|
||||
debug_str[count] = '\0';
|
||||
}
|
||||
if (copy_from_user(debug_str, buf, count)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if ((ptr = strstr(debug_str, "debug=")) != NULL) {
|
||||
ptr += 6;
|
||||
debug = simple_strtol(ptr, NULL, 0);
|
||||
} else {
|
||||
gprintk("Warning: unknown configuration setting\n");
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
struct file_operations psample_proc_debug_file_ops = {
|
||||
owner: THIS_MODULE,
|
||||
open: psample_proc_debug_open,
|
||||
read: seq_read,
|
||||
llseek: seq_lseek,
|
||||
write: psample_proc_debug_write,
|
||||
release: single_release,
|
||||
};
|
||||
|
||||
static int
|
||||
psample_proc_stats_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_printf(m, "BCM KNET %s Callback Stats\n", PSAMPLE_CB_NAME);
|
||||
seq_printf(m, " DCB type %d\n", g_psample_info.hw.dcb_type);
|
||||
seq_printf(m, " pkts filter psample cb %10lu\n", g_psample_stats.pkts_f_psample_cb);
|
||||
seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod);
|
||||
seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled);
|
||||
seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through);
|
||||
seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group);
|
||||
seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled);
|
||||
seq_printf(m, " pkts drop no skb %10lu\n", g_psample_stats.pkts_d_no_skb);
|
||||
seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready);
|
||||
seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata);
|
||||
seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport);
|
||||
seq_printf(m, " pkts with invalid dst port %10lu\n", g_psample_stats.pkts_d_meta_dstport);
|
||||
seq_printf(m, " pkts with invalid orig pkt sz %10lu\n", g_psample_stats.pkts_d_invalid_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
psample_proc_stats_open(struct inode * inode, struct file * file)
|
||||
{
|
||||
return single_open(file, psample_proc_stats_show, NULL);
|
||||
}
|
||||
|
||||
struct file_operations psample_proc_stats_file_ops = {
|
||||
owner: THIS_MODULE,
|
||||
open: psample_proc_stats_open,
|
||||
read: seq_read,
|
||||
llseek: seq_lseek,
|
||||
write: NULL,
|
||||
release: single_release,
|
||||
};
|
||||
|
||||
int psample_cleanup(void)
|
||||
{
|
||||
remove_proc_entry("stats", psample_proc_root);
|
||||
remove_proc_entry("rate", psample_proc_root);
|
||||
remove_proc_entry("size", psample_proc_root);
|
||||
remove_proc_entry("debug", psample_proc_root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int psample_init(void)
|
||||
{
|
||||
#define PROCFS_MAX_PATH 1024
|
||||
char psample_procfs_path[PROCFS_MAX_PATH];
|
||||
struct proc_dir_entry *entry;
|
||||
|
||||
/* create procfs for psample */
|
||||
snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb");
|
||||
proc_mkdir(psample_procfs_path, NULL);
|
||||
snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME);
|
||||
psample_proc_root = proc_mkdir(psample_procfs_path, NULL);
|
||||
|
||||
/* create procfs for psample stats */
|
||||
PROC_CREATE(entry, "stats", 0666, psample_proc_root, &psample_proc_stats_file_ops);
|
||||
if (entry == NULL) {
|
||||
gprintk("%s: Unable to create procfs entry '/procfs/%s/stats'\n", __func__, psample_procfs_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create procfs for setting sample rates */
|
||||
PROC_CREATE(entry, "rate", 0666, psample_proc_root, &psample_proc_rate_file_ops);
|
||||
if (entry == NULL) {
|
||||
gprintk("%s: Unable to create procfs entry '/procfs/%s/rate'\n", __func__, psample_procfs_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create procfs for setting sample size */
|
||||
PROC_CREATE(entry, "size", 0666, psample_proc_root, &psample_proc_size_file_ops);
|
||||
if (entry == NULL) {
|
||||
gprintk("%s: Unable to create procfs entry '/procfs/%s/size'\n", __func__, psample_procfs_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create procfs for debug log */
|
||||
PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops);
|
||||
if (entry == NULL) {
|
||||
gprintk("%s: Unable to create procfs entry '/procfs/%s/debug'\n", __func__, psample_procfs_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* clear data structs */
|
||||
memset(&g_psample_stats, 0, sizeof(psample_stats_t));
|
||||
memset(&g_psample_info, 0, sizeof(psample_info_t));
|
||||
|
||||
/* setup psample_info struct */
|
||||
INIT_LIST_HEAD(&g_psample_info.netif_list);
|
||||
spin_lock_init(&g_psample_info.lock);
|
||||
|
||||
/* get net namespace */
|
||||
g_psample_info.netns = get_net_ns_by_pid(current->pid);
|
||||
if (!g_psample_info.netns) {
|
||||
gprintk("%s: Could not get network namespace for pid %d\n", __func__, current->pid);
|
||||
return (-1);
|
||||
}
|
||||
PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__,
|
||||
current->pid, g_psample_info.netns, psample_size);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2017 Broadcom
|
||||
*
|
||||
* 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 (the "GPL").
|
||||
*
|
||||
* 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 version 2 (GPLv2) for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 (GPLv2) along with this source code.
|
||||
*/
|
||||
/*
|
||||
* $Id: psample_cb.h $
|
||||
* $Copyright: (c) 2019 Broadcom Corp.
|
||||
* All Rights Reserved.$
|
||||
*/
|
||||
#ifndef __PSAMPLE_CB_H__
|
||||
#define __PSAMPLE_CB_H__
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <kcom.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#define PSAMPLE_CB_NAME "psample"
|
||||
|
||||
extern int
|
||||
psample_init(void);
|
||||
|
||||
extern int
|
||||
psample_cleanup(void);
|
||||
|
||||
extern int
|
||||
psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta,
|
||||
int chan, kcom_filter_t *kf);
|
||||
|
||||
/* psample data per interface */
|
||||
typedef struct {
|
||||
struct list_head list;
|
||||
struct net_device *dev;
|
||||
uint16 id;
|
||||
uint8 port;
|
||||
uint16 vlan;
|
||||
uint16 qnum;
|
||||
uint32 sample_rate;
|
||||
uint32 sample_size;
|
||||
} psample_netif_t;
|
||||
|
||||
extern int
|
||||
psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev);
|
||||
|
||||
extern int
|
||||
psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev);
|
||||
|
||||
#endif /* __PSAMPLE_CB_H__ */
|
@ -0,0 +1,64 @@
|
||||
#
|
||||
# Copyright 2017 Broadcom
|
||||
#
|
||||
# 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 (the "GPL").
|
||||
#
|
||||
# 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 version 2 (GPLv2) for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# version 2 (GPLv2) along with this source code.
|
||||
#
|
||||
# -*- Makefile -*-
|
||||
# $Id: Makefile,v 1.3 Broadcom SDK $
|
||||
# $Copyright: (c) 2005 Broadcom Corp.
|
||||
# All Rights Reserved.$
|
||||
#
|
||||
LOCALDIR = systems/linux/kernel/modules/psample
|
||||
|
||||
include ${SDK}/make/Make.config
|
||||
|
||||
LIBS = $(LIBDIR)/libkern.a
|
||||
|
||||
ifeq ($(kernel_version),2_4)
|
||||
MODULE = $(LIBDIR)/psample.o
|
||||
else
|
||||
KERNEL_MODULE_DIR = kernel_module
|
||||
|
||||
THIS_MOD_NAME := psample
|
||||
MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o
|
||||
KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko
|
||||
|
||||
build: $(MODULE) $(KMODULE)
|
||||
endif
|
||||
|
||||
KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers
|
||||
|
||||
# BCM Network Device
|
||||
|
||||
$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS)
|
||||
$(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@
|
||||
ifneq ($(kernel_version),2_4)
|
||||
$(KMODULE): $(MODULE)
|
||||
rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
||||
mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR)
|
||||
cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile
|
||||
cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers
|
||||
MOD_NAME=$(THIS_MOD_NAME) $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko
|
||||
endif
|
||||
|
||||
# Make.depend is before clean:: so that Make.depend's clean:: runs first.
|
||||
|
||||
include ${SDK}/make/Make.depend
|
||||
|
||||
clean::
|
||||
$(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o
|
||||
$(RM) $(BOBJS) $(MODULE)
|
||||
|
||||
ifneq ($(kernel_version),2_4)
|
||||
.PHONY: build
|
||||
endif
|
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* net/psample/psample.c - Netlink channel for packet sampling
|
||||
* Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
#include <net/psample.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#define PSAMPLE_MAX_PACKET_SIZE 0xffff
|
||||
|
||||
static LIST_HEAD(psample_groups_list);
|
||||
static DEFINE_SPINLOCK(psample_groups_lock);
|
||||
|
||||
/* multicast groups */
|
||||
enum psample_nl_multicast_groups {
|
||||
PSAMPLE_NL_MCGRP_CONFIG,
|
||||
PSAMPLE_NL_MCGRP_SAMPLE,
|
||||
};
|
||||
|
||||
static const struct genl_multicast_group psample_nl_mcgrps[] = {
|
||||
[PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
|
||||
[PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME },
|
||||
};
|
||||
|
||||
static struct genl_family psample_nl_family __ro_after_init;
|
||||
|
||||
static int psample_group_nl_fill(struct sk_buff *msg,
|
||||
struct psample_group *group,
|
||||
enum psample_command cmd, u32 portid, u32 seq,
|
||||
int flags)
|
||||
{
|
||||
void *hdr;
|
||||
int ret;
|
||||
|
||||
hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd);
|
||||
if (!hdr)
|
||||
return -EMSGSIZE;
|
||||
|
||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
genlmsg_cancel(msg, hdr);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg,
|
||||
struct netlink_callback *cb)
|
||||
{
|
||||
struct psample_group *group;
|
||||
int start = cb->args[0];
|
||||
int idx = 0;
|
||||
int err;
|
||||
|
||||
spin_lock(&psample_groups_lock);
|
||||
list_for_each_entry(group, &psample_groups_list, list) {
|
||||
if (!net_eq(group->net, sock_net(msg->sk)))
|
||||
continue;
|
||||
if (idx < start) {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP,
|
||||
NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, NLM_F_MULTI);
|
||||
if (err)
|
||||
break;
|
||||
idx++;
|
||||
}
|
||||
|
||||
spin_unlock(&psample_groups_lock);
|
||||
cb->args[0] = idx;
|
||||
return msg->len;
|
||||
}
|
||||
|
||||
static const struct genl_ops psample_nl_ops[] = {
|
||||
{
|
||||
.cmd = PSAMPLE_CMD_GET_GROUP,
|
||||
.dumpit = psample_nl_cmd_get_group_dumpit,
|
||||
/* can be retrieved by unprivileged users */
|
||||
}
|
||||
};
|
||||
|
||||
static struct genl_family psample_nl_family __ro_after_init = {
|
||||
.name = PSAMPLE_GENL_NAME,
|
||||
.version = PSAMPLE_GENL_VERSION,
|
||||
.maxattr = PSAMPLE_ATTR_MAX,
|
||||
.netnsok = true,
|
||||
.module = THIS_MODULE,
|
||||
.mcgrps = psample_nl_mcgrps,
|
||||
.ops = psample_nl_ops,
|
||||
.n_ops = ARRAY_SIZE(psample_nl_ops),
|
||||
.n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps),
|
||||
};
|
||||
|
||||
static void psample_group_notify(struct psample_group *group,
|
||||
enum psample_command cmd)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
int err;
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI);
|
||||
if (!err)
|
||||
genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0,
|
||||
PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC);
|
||||
else
|
||||
nlmsg_free(msg);
|
||||
}
|
||||
|
||||
static struct psample_group *psample_group_create(struct net *net,
|
||||
u32 group_num)
|
||||
{
|
||||
struct psample_group *group;
|
||||
|
||||
group = kzalloc(sizeof(*group), GFP_ATOMIC);
|
||||
if (!group)
|
||||
return NULL;
|
||||
|
||||
group->net = net;
|
||||
group->group_num = group_num;
|
||||
list_add_tail(&group->list, &psample_groups_list);
|
||||
|
||||
psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP);
|
||||
return group;
|
||||
}
|
||||
|
||||
static void psample_group_destroy(struct psample_group *group)
|
||||
{
|
||||
psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP);
|
||||
list_del(&group->list);
|
||||
kfree(group);
|
||||
}
|
||||
|
||||
static struct psample_group *
|
||||
psample_group_lookup(struct net *net, u32 group_num)
|
||||
{
|
||||
struct psample_group *group;
|
||||
|
||||
list_for_each_entry(group, &psample_groups_list, list)
|
||||
if ((group->group_num == group_num) && (group->net == net))
|
||||
return group;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct psample_group *psample_group_get(struct net *net, u32 group_num)
|
||||
{
|
||||
struct psample_group *group;
|
||||
|
||||
spin_lock(&psample_groups_lock);
|
||||
|
||||
group = psample_group_lookup(net, group_num);
|
||||
if (!group) {
|
||||
group = psample_group_create(net, group_num);
|
||||
if (!group)
|
||||
goto out;
|
||||
}
|
||||
group->refcount++;
|
||||
|
||||
out:
|
||||
spin_unlock(&psample_groups_lock);
|
||||
return group;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(psample_group_get);
|
||||
|
||||
void psample_group_put(struct psample_group *group)
|
||||
{
|
||||
spin_lock(&psample_groups_lock);
|
||||
|
||||
if (--group->refcount == 0)
|
||||
psample_group_destroy(group);
|
||||
|
||||
spin_unlock(&psample_groups_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(psample_group_put);
|
||||
|
||||
void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
|
||||
u32 trunc_size, int in_ifindex, int out_ifindex,
|
||||
u32 sample_rate)
|
||||
{
|
||||
struct sk_buff *nl_skb;
|
||||
int data_len;
|
||||
int meta_len;
|
||||
void *data;
|
||||
int ret;
|
||||
|
||||
meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) +
|
||||
(out_ifindex ? nla_total_size(sizeof(u16)) : 0) +
|
||||
nla_total_size(sizeof(u32)) + /* sample_rate */
|
||||
nla_total_size(sizeof(u32)) + /* orig_size */
|
||||
nla_total_size(sizeof(u32)) + /* group_num */
|
||||
nla_total_size(sizeof(u32)); /* seq */
|
||||
|
||||
data_len = min(skb->len, trunc_size);
|
||||
if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE)
|
||||
data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN
|
||||
- NLA_ALIGNTO;
|
||||
|
||||
nl_skb = genlmsg_new(meta_len + data_len, GFP_ATOMIC);
|
||||
if (unlikely(!nl_skb))
|
||||
return;
|
||||
|
||||
data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0,
|
||||
PSAMPLE_CMD_SAMPLE);
|
||||
if (unlikely(!data))
|
||||
goto error;
|
||||
|
||||
if (in_ifindex) {
|
||||
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex);
|
||||
if (unlikely(ret < 0))
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (out_ifindex) {
|
||||
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex);
|
||||
if (unlikely(ret < 0))
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate);
|
||||
if (unlikely(ret < 0))
|
||||
goto error;
|
||||
|
||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len);
|
||||
if (unlikely(ret < 0))
|
||||
goto error;
|
||||
|
||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
|
||||
if (unlikely(ret < 0))
|
||||
goto error;
|
||||
|
||||
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++);
|
||||
if (unlikely(ret < 0))
|
||||
goto error;
|
||||
|
||||
if (data_len) {
|
||||
int nla_len = nla_total_size(data_len);
|
||||
struct nlattr *nla;
|
||||
|
||||
nla = (struct nlattr *)skb_put(nl_skb, nla_len);
|
||||
nla->nla_type = PSAMPLE_ATTR_DATA;
|
||||
nla->nla_len = nla_attr_size(data_len);
|
||||
|
||||
if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
|
||||
goto error;
|
||||
}
|
||||
|
||||
genlmsg_end(nl_skb, data);
|
||||
genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0,
|
||||
PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC);
|
||||
|
||||
return;
|
||||
error:
|
||||
pr_err_ratelimited("Could not create psample log message\n");
|
||||
nlmsg_free(nl_skb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(psample_sample_packet);
|
||||
|
||||
static int __init psample_module_init(void)
|
||||
{
|
||||
return genl_register_family(&psample_nl_family);
|
||||
}
|
||||
|
||||
static void __exit psample_module_exit(void)
|
||||
{
|
||||
genl_unregister_family(&psample_nl_family);
|
||||
}
|
||||
|
||||
module_init(psample_module_init);
|
||||
module_exit(psample_module_exit);
|
||||
|
||||
MODULE_AUTHOR("Yotam Gigi <yotamg@mellanox.com>");
|
||||
MODULE_DESCRIPTION("netlink channel for packet sampling");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -91,6 +91,9 @@ KNET_CB := $(DEST_DIR)/$(KNET_CB_LOCAL)
|
||||
BCM_KNET_LOCAL :=linux-bcm-knet.$(KOBJ)
|
||||
BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL)
|
||||
|
||||
PSAMPLE_LOCAL := psample.$(KOBJ)
|
||||
PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL)
|
||||
|
||||
ifeq (,$(findstring DELIVER,$(MAKECMDGOALS)))
|
||||
.DEFAULT_GOAL := all
|
||||
all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE)
|
||||
@ -126,6 +129,15 @@ all_targets +=$(LOCAL_TARGETS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef BUILD_PSAMPLE
|
||||
all_targets += $(PSAMPLE)
|
||||
ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT
|
||||
ifeq ($(NO_LOCAL_TARGETS),)
|
||||
LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL))
|
||||
all_targets +=$(LOCAL_TARGETS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include
|
||||
COND_KNET_LIBS = libuser.$(libext)
|
||||
endif
|
||||
@ -159,6 +171,10 @@ kernel_modules:
|
||||
ifeq ($(BUILD_KNET),1)
|
||||
$(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
||||
subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
||||
ifdef BUILD_PSAMPLE
|
||||
$(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
||||
subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
||||
endif
|
||||
ifdef BUILD_KNET_CB
|
||||
$(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
|
||||
subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
|
||||
@ -178,6 +194,10 @@ $(BCM_KNET): $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
|
||||
$(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
|
||||
$(OBJCOPY) --strip-debug $< $@
|
||||
|
||||
$(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ)
|
||||
$(OBJCOPY) --strip-debug $< $@
|
||||
|
||||
|
||||
ifeq ($(NO_LOCAL_TARGETS),)
|
||||
$(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ))))
|
||||
endif
|
||||
@ -194,6 +214,7 @@ clean::
|
||||
$(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ)
|
||||
$(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
|
||||
$(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
|
||||
$(RM) $(KERN_BLDROOT)/psample.$(KOBJ)
|
||||
$(RM) $(LOCAL_TARGETS)
|
||||
|
||||
distclean:: clean
|
||||
|
@ -44,7 +44,7 @@ endif
|
||||
|
||||
export SDK
|
||||
|
||||
override kernel_version=4_4
|
||||
override kernel_version=4_14
|
||||
platform=iproc
|
||||
|
||||
IPROC_BUILD=1
|
||||
|
@ -291,7 +291,9 @@ RUN apt-get update && apt-get install -y \
|
||||
automake1.11 \
|
||||
libselinux1-dev \
|
||||
# For kdump-tools
|
||||
liblzo2-dev
|
||||
liblzo2-dev \
|
||||
# For SAI3.7
|
||||
libprotobuf-dev
|
||||
|
||||
## Config dpkg
|
||||
## install the configuration file if it’s currently missing
|
||||
|
Loading…
Reference in New Issue
Block a user