Compare commits
	
		
			281 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 8004e3f2c6 | ||
|   | d81a8a3e29 | ||
|   | e1b62c85f5 | ||
|   | 8c6668f088 | ||
|   | 455ae024d5 | ||
|   | b1eeb5dd2a | ||
|   | b72b37d6ff | ||
|   | 471baf3f74 | ||
|   | 336aaedc9c | ||
|   | e838957ad9 | ||
|   | 6b128326df | ||
|   | 97e9be4e3a | ||
|   | 85c4d374c2 | ||
|   | 83ce31d3d8 | ||
|   | c280710d7a | ||
|   | 27dddb67c0 | ||
|   | 8623b58c1d | ||
|   | e242125d71 | ||
|   | 84b74bcb0d | ||
|   | 66ba44c9ec | ||
|   | b901563611 | ||
|   | 2152722bd3 | ||
|   | c3337e8f48 | ||
|   | d08a63770c | ||
|   | 022f3898b1 | ||
|   | 5d92949019 | ||
|   | 361b555672 | ||
|   | 1cbde3eb9c | ||
|   | bd3b8480ab | ||
|   | 2777947a75 | ||
|   | 7863a8f302 | ||
|   | daed78ab55 | ||
|   | 8f6debf633 | ||
|   | 72ddeffc09 | ||
|   | 70b73f6470 | ||
|   | 6e2e5d1bf8 | ||
|   | f6f916b3e5 | ||
|   | 0e85ace840 | ||
|   | 45fefa0459 | ||
|   | b0d99e32db | ||
|   | 22fe68643f | ||
|   | 2219b0258d | ||
|   | 0a9147be6a | ||
|   | b9e685eed5 | ||
|   | 8179ac3dc1 | ||
|   | 6962c1e495 | ||
|   | e6a7eacfea | ||
|   | f65330d27d | ||
|   | ab6addc95d | ||
|   | f503bc3d25 | ||
|   | 506bfaa126 | ||
|   | c89437e398 | ||
|   | ea8f7d74ba | ||
|   | 79fd7593a2 | ||
|   | 3d3a933315 | ||
|   | 862a885103 | ||
|   | 05c858ff6a | ||
|   | c1d19b37d5 | ||
|   | dfd8c3bfdc | ||
|   | 69bc68b46b | ||
|   | 5e4533cdd4 | ||
|   | 9d401013fc | ||
|   | e70772311d | ||
|   | cdc2937edd | ||
|   | f024b4c83d | ||
|   | 700f66ae95 | ||
|   | c4a2e5102d | ||
|   | 61df1285ce | ||
|   | 51431de30d | ||
|   | 0880275d5e | ||
|   | b2fba59f10 | ||
|   | a2fe698a40 | ||
|   | dff0b2104d | ||
|   | 3b8db97a52 | ||
|   | 96a87b90ef | ||
|   | a857fc2ded | ||
|   | 31181fa062 | ||
|   | 9628612abe | ||
|   | 1737131c9d | ||
|   | 778243b3b4 | ||
|   | d513f28351 | ||
|   | 6f1a71c2d0 | ||
|   | 491e839262 | ||
|   | 4acc0db480 | ||
|   | 3699327da3 | ||
|   | 45a2c0f309 | ||
|   | e289a4133c | ||
|   | a63edb4691 | ||
|   | 2698157d54 | ||
|   | 952bafa03c | ||
|   | 7e1db8f27c | ||
|   | d32cf52674 | ||
|   | 745292ba10 | ||
|   | 5880dd48d5 | ||
|   | 90f6af5108 | ||
|   | e545808e89 | ||
|   | 59e42f9e3e | ||
|   | 418cf097e7 | ||
|   | 6f677d6848 | ||
|   | c5ed9f4344 | ||
|   | 556f86bbfd | ||
|   | 2d257351f3 | ||
|   | 2a22e41fe4 | ||
|   | f9dec32be7 | ||
|   | 7393ce8d87 | ||
|   | f6de1fa6c6 | ||
|   | 7ac6044632 | ||
|   | 9d1cd9d098 | ||
|   | 4b5c77ca2f | ||
|   | 73bba470a4 | ||
|   | 8bc800aa56 | ||
|   | c948a74158 | ||
|   | 09d63fb0a6 | ||
|   | 564d81e944 | ||
|   | 5e3b21c916 | ||
|   | 2df2b75208 | ||
|   | 09bdc14419 | ||
|   | e058fb3658 | ||
|   | 28dc34f249 | ||
|   | 24967a6c42 | ||
|   | 30815d65d2 | ||
|   | dc2f2a16d3 | ||
|   | c99ceb7030 | ||
|   | 89808e211c | ||
|   | 349714a491 | ||
|   | 0a4a82a431 | ||
|   | 8a83892662 | ||
|   | 0bce1d0db9 | ||
|   | 958411aa61 | ||
|   | 2807f84b62 | ||
|   | 7e4ce0c655 | ||
|   | b7e7d220e7 | ||
|   | df53824f46 | ||
|   | 76d1e8a0c2 | ||
|   | ef9c13fb5d | ||
|   | 41e3f12e00 | ||
|   | f51e2d031e | ||
|   | 95745e26b3 | ||
|   | 65a405382b | ||
|   | a68be42f99 | ||
|   | 8231f67218 | ||
|   | 627bb0b8dc | ||
|   | e6af9c017b | ||
|   | 33e7beeb31 | ||
|   | 687977bfc9 | ||
|   | 6ee6c97ded | ||
|   | aced9de9a4 | ||
|   | 3bbd16da46 | ||
|   | b84f761d91 | ||
|   | f6429577c5 | ||
|   | ef686b7292 | ||
|   | 3dc740257b | ||
|   | a2c22b8776 | ||
|   | d5ff0897cb | ||
|   | 18266fc6c0 | ||
|   | 5e771160b8 | ||
|   | 9c6fb1d67a | ||
|   | 6c1bef833d | ||
|   | 467adaf6c5 | ||
|   | 4382d4ce19 | ||
|   | 97ae9e0ccb | ||
|   | 25fc20db8b | ||
|   | fc39d5fc45 | ||
|   | b463a13881 | ||
|   | fc1dae5be7 | ||
|   | 84aba5796e | ||
|   | 9656f49ea0 | ||
|   | bd0c3988e7 | ||
|   | 2999c342aa | ||
|   | 9de2f4d4ce | ||
|   | 5fe809d718 | ||
|   | e493230e84 | ||
|   | c449130bb2 | ||
|   | 6fa6f74e37 | ||
|   | 2cd234d96b | ||
|   | 85eda6f61e | ||
|   | a0543d8e70 | ||
|   | f63a1caf22 | ||
|   | 40b1e899ba | ||
|   | 5dbac47426 | ||
|   | 5d27e87de7 | ||
|   | 1867f10807 | ||
|   | 7fe1b4a4b2 | ||
|   | 6563e494a0 | ||
|   | e3408d09b0 | ||
|   | b2b1265a1d | ||
|   | 6761961919 | ||
|   | 9591155737 | ||
|   | dc1b578a4c | ||
|   | 40ed8389ef | ||
|   | 7e07320dc4 | ||
|   | 054aecdf0b | ||
|   | e9a7344550 | ||
|   | 4b633affff | ||
|   | cfb72eed69 | ||
|   | 68a5e662c2 | ||
|   | 85294fc5e7 | ||
|   | 152755c9a2 | ||
|   | 82e4b4250d | ||
|   | cf2aa873ea | ||
|   | e6928e6b29 | ||
|   | 3239f56136 | ||
|   | b5ce5217e2 | ||
|   | d3053b1bdc | ||
|   | f053a8ce41 | ||
|   | 412d80cdb7 | ||
|   | f105a9c35c | ||
|   | 4685bf1d2f | ||
|   | 2faceb1a39 | ||
|   | e0505cc018 | ||
|   | 24aefaec62 | ||
|   | aaa34526c4 | ||
|   | 3103bd54c5 | ||
|   | a5c62c933b | ||
|   | ac3b5f00e1 | ||
|   | 15a70d085d | ||
|   | e6e5435c5b | ||
|   | ecfe0f1cc4 | ||
|   | 2d2e615dee | ||
|   | 02aed76968 | ||
|   | 1a6d7a651f | ||
|   | 6ac061f319 | ||
|   | 7268ebb1e4 | ||
|   | c7eb679047 | ||
|   | 9c4fa1bb5b | ||
|   | 6c81f5fac6 | ||
|   | aa0e6fc489 | ||
|   | dad220a00c | ||
|   | 07bd5b7a81 | ||
|   | 4b4de23dfb | ||
|   | ca8b4d684b | ||
|   | 1ff4cd1ff1 | ||
|   | 22a3e65662 | ||
|   | dac25a5f22 | ||
|   | 6c3ca1d1ea | ||
|   | dcdf50956f | ||
|   | 4336cfda12 | ||
|   | 13eb73b278 | ||
|   | 0a637c7f87 | ||
|   | 24f32072d2 | ||
|   | dcfca830a8 | ||
|   | 400601f0e3 | ||
|   | f87a1874ef | ||
|   | 9f2cbcad6d | ||
|   | 4918fe0291 | ||
|   | 2b9d2f6624 | ||
|   | 8de93ce745 | ||
|   | 85cb473f93 | ||
|   | 08db9397c9 | ||
|   | 810ee3b84a | ||
|   | 5183df0dbf | ||
|   | eea538204b | ||
|   | f1803e3492 | ||
|   | 1bfe1ce5c4 | ||
|   | 9ee8c8daf4 | ||
|   | e2ba7a4b47 | ||
|   | 1be6ff6dc0 | ||
|   | e9cb40caa4 | ||
|   | d32bbd7477 | ||
|   | ce3a53c4f6 | ||
|   | 87fb8aea87 | ||
|   | 405840631c | ||
|   | bc3eb970ab | ||
|   | 20f1b7d3f5 | ||
|   | d669be4654 | ||
|   | 62feabecd8 | ||
|   | 9fb3710a8b | ||
|   | e5ace80759 | ||
|   | fbb2186fbd | ||
|   | 72870cc108 | ||
|   | 19a6c4b2b3 | ||
|   | d997712c71 | ||
|   | 9b14c7d3d1 | ||
|   | e33612484a | ||
|   | ef17edae3d | ||
|   | 21762fe9d6 | ||
|   | ab41836321 | ||
|   | 026f08a610 | ||
|   | 1f1f421af6 | ||
|   | 13eeee7b2b | ||
|   | ac1ce25671 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -16,6 +16,7 @@ | ||||
| /overlay | ||||
| /package/feeds | ||||
| /package/openwrt-packages | ||||
| /*.patch | ||||
| key-build* | ||||
| *.orig | ||||
| *.rej | ||||
|   | ||||
| @@ -34,6 +34,10 @@ menu "Global build settings" | ||||
| 		bool "Cryptographically signed package lists" | ||||
| 		default y | ||||
|  | ||||
| 	config SIGNATURE_CHECK | ||||
| 		bool "Enable signature checking in opkg" | ||||
| 		default SIGNED_PACKAGES | ||||
|  | ||||
| 	comment "General build options" | ||||
|  | ||||
| 	config DISPLAY_SUPPORT | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| src-git packages https://git.openwrt.org/feed/packages.git^911bbd6bb4856f1e28ae00af37df62e4fa3529e5 | ||||
| src-git luci https://git.openwrt.org/project/luci.git^6f6641d97de2c85ee5d87beda92ae8437d1dbdf5 | ||||
| src-git routing https://git.openwrt.org/feed/routing.git^ea345d16a6e27c2a8fdf67bf543cc36a5f189131 | ||||
| src-git telephony https://git.openwrt.org/feed/telephony.git^cb939d9677d6e38c428f9f297641d07611edeb04 | ||||
| src-git packages https://git.openwrt.org/feed/packages.git^b0df5d33652220a384593d7b52a8453b022b8f9b | ||||
| src-git luci https://git.openwrt.org/project/luci.git^868abc1a564ca8366bbb018a967923cbdc5ee27a | ||||
| src-git routing https://git.openwrt.org/feed/routing.git^9fa2b249cc286176f07efe343fd9518b383462fc | ||||
| src-git telephony https://git.openwrt.org/feed/telephony.git^8ecbdabc7c5cadbe571eb947f5cd333a5a785010 | ||||
|   | ||||
| @@ -581,7 +581,7 @@ define BuildImage | ||||
| 		$(call Image/Prepare) | ||||
|  | ||||
|     legacy-images-prepare-make: image_prepare | ||||
| 		$(MAKE) legacy-images-prepare | ||||
| 		$(MAKE) legacy-images-prepare BIN_DIR="$(BIN_DIR)" | ||||
|  | ||||
|   else | ||||
|     image_prepare: | ||||
| @@ -605,7 +605,7 @@ define BuildImage | ||||
|  | ||||
|   legacy-images-make: install-images | ||||
| 	$(call Image/mkfs/ubifs/legacy) | ||||
| 	$(MAKE) legacy-images | ||||
| 	$(MAKE) legacy-images BIN_DIR="$(BIN_DIR)" | ||||
|  | ||||
|   install: install-images | ||||
| 	$(call Image/Manifest) | ||||
|   | ||||
| @@ -2,11 +2,11 @@ | ||||
|  | ||||
| LINUX_RELEASE?=1 | ||||
|  | ||||
| LINUX_VERSION-4.9 = .152 | ||||
| LINUX_VERSION-4.14 = .95 | ||||
| LINUX_VERSION-4.9 = .208 | ||||
| LINUX_VERSION-4.14 = .162 | ||||
|  | ||||
| LINUX_KERNEL_HASH-4.9.152 = 90e47b85c09af47eefafe851685ee731538f640b0650a6a9cfa0234436708e39 | ||||
| LINUX_KERNEL_HASH-4.14.95 = ce6729e3fca312520e3cb4f27993852dbb019d94c59c0b35cedab571f9cb58e4 | ||||
| LINUX_KERNEL_HASH-4.9.208 = b7ad1c9841d671d026c55a4c91c77205f8b488ca5f980f838591c68662e0525a | ||||
| LINUX_KERNEL_HASH-4.14.162 = f65170224cd4359ce8b2793b492bd8127abdd0b91350484e001bce13f0c98b4b | ||||
|  | ||||
| remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) | ||||
| sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) | ||||
|   | ||||
| @@ -258,7 +258,11 @@ $(eval $(call nf_add,IPT_DEBUG,CONFIG_NETFILTER_XT_TARGET_TRACE, $(P_XT)xt_TRACE | ||||
| # tproxy | ||||
|  | ||||
| $(eval $(call nf_add,IPT_TPROXY,CONFIG_NETFILTER_XT_MATCH_SOCKET, $(P_XT)xt_socket)) | ||||
| $(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_SOCKET_IPV4, $(P_V4)nf_socket_ipv4, ge 4.10)) | ||||
| $(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_SOCKET_IPV6, $(P_V6)nf_socket_ipv6, ge 4.10)) | ||||
| $(eval $(call nf_add,IPT_TPROXY,CONFIG_NETFILTER_XT_TARGET_TPROXY, $(P_XT)xt_TPROXY)) | ||||
| $(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_TPROXY_IPV4, $(P_V4)nf_tproxy_ipv4, ge 4.18)) | ||||
| $(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_TPROXY_IPV6, $(P_V6)nf_tproxy_ipv6, ge 4.18)) | ||||
|  | ||||
| # led | ||||
| $(eval $(call nf_add,IPT_LED,CONFIG_NETFILTER_XT_TARGET_LED, $(P_XT)xt_LED)) | ||||
|   | ||||
| @@ -141,10 +141,12 @@ $(eval $(call SetupHostCommand,wget,Please install GNU 'wget', \ | ||||
| $(eval $(call SetupHostCommand,perl,Please install Perl 5.x, \ | ||||
| 	perl --version | grep "perl.*v5")) | ||||
|  | ||||
| $(eval $(call CleanupPython3)) | ||||
|  | ||||
| $(eval $(call SetupHostCommand,python,Please install Python 2.x, \ | ||||
| 	python2.7 -V 2>&1 | grep Python, \ | ||||
| 	python2 -V 2>&1 | grep Python, \ | ||||
| 	python -V 2>&1 | grep Python)) | ||||
| 	python2.7 -V 2>&1 | grep 'Python 2.7', \ | ||||
| 	python2 -V 2>&1 | grep 'Python 2', \ | ||||
| 	python -V 2>&1 | grep 'Python 2')) | ||||
|  | ||||
| $(eval $(call SetupHostCommand,git,Please install Git (git-core) >= 1.7.12.2, \ | ||||
| 	git --exec-path | xargs -I % -- grep -q -- --recursive %/git-submodule)) | ||||
|   | ||||
| @@ -66,6 +66,18 @@ define RequireHeader | ||||
|   $$(eval $$(call Require,$(1),$(2))) | ||||
| endef | ||||
|  | ||||
| define CleanupPython3 | ||||
|   define Require/python3-cleanup | ||||
| 	if [ -f "$(STAGING_DIR_HOST)/bin/python" ] && \ | ||||
| 		$(STAGING_DIR_HOST)/bin/python -V 2>&1 | \ | ||||
| 		grep -q 'Python 3'; then \ | ||||
| 			rm $(STAGING_DIR_HOST)/bin/python; \ | ||||
| 	fi | ||||
|   endef | ||||
|  | ||||
|   $$(eval $$(call Require,python3-cleanup)) | ||||
| endef | ||||
|  | ||||
| define QuoteHostCommand | ||||
| '$(subst ','"'"',$(strip $(1)))' | ||||
| endef | ||||
|   | ||||
| @@ -26,13 +26,13 @@ PKG_CONFIG_DEPENDS += \ | ||||
| sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1)))) | ||||
|  | ||||
| VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER)) | ||||
| VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),18.06.2) | ||||
| VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),18.06.6) | ||||
|  | ||||
| VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE)) | ||||
| VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),r7676-cddd7b4c77) | ||||
| VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),r7957-d81a8a3e29) | ||||
|  | ||||
| VERSION_REPO:=$(call qstrip,$(CONFIG_VERSION_REPO)) | ||||
| VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),http://downloads.openwrt.org/releases/18.06.2) | ||||
| VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),http://downloads.openwrt.org/releases/18.06.6) | ||||
|  | ||||
| VERSION_DIST:=$(call qstrip,$(CONFIG_VERSION_DIST)) | ||||
| VERSION_DIST:=$(if $(VERSION_DIST),$(VERSION_DIST),OpenWrt) | ||||
|   | ||||
| @@ -84,8 +84,12 @@ $(curdir)/index: FORCE | ||||
| 		mkdir -p $$d; \ | ||||
| 		cd $$d || continue; \ | ||||
| 		$(SCRIPT_DIR)/ipkg-make-index.sh . 2>&1 > Packages.manifest; \ | ||||
| 		grep -vE '^(Maintainer|LicenseFiles|Source|Require)' Packages.manifest > Packages && \ | ||||
| 			gzip -9nc Packages > Packages.gz; \ | ||||
| 		grep -vE '^(Maintainer|LicenseFiles|Source|Require)' Packages.manifest > Packages; \ | ||||
| 		case "$$(((64 + $$(stat -L -c%s Packages)) % 128))" in 110|111) \ | ||||
| 			$(call ERROR_MESSAGE,WARNING: Applying padding in $$d/Packages to workaround usign SHA-512 bug!); \ | ||||
| 			{ echo ""; echo ""; } >> Packages;; \ | ||||
| 		esac; \ | ||||
| 		gzip -9nc Packages > Packages.gz; \ | ||||
| 	); done | ||||
| ifdef CONFIG_SIGNED_PACKAGES | ||||
| 	@echo Signing package index... | ||||
|   | ||||
| @@ -12,7 +12,7 @@ include $(INCLUDE_DIR)/version.mk | ||||
| include $(INCLUDE_DIR)/feeds.mk | ||||
|  | ||||
| PKG_NAME:=base-files | ||||
| PKG_RELEASE:=194.2 | ||||
| PKG_RELEASE:=194.3 | ||||
| PKG_FLAGS:=nonshared | ||||
|  | ||||
| PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/ | ||||
|   | ||||
| @@ -85,12 +85,16 @@ generate_network() { | ||||
| 		set network.$1.proto='none' | ||||
| 	EOF | ||||
|  | ||||
| 	[ -n "$macaddr" ] && uci -q batch <<-EOF | ||||
| 		delete network.$1_dev | ||||
| 		set network.$1_dev='device' | ||||
| 		set network.$1_dev.name='$ifname' | ||||
| 		set network.$1_dev.macaddr='$macaddr' | ||||
| 	EOF | ||||
| 	if [ -n "$macaddr" ]; then | ||||
| 		for name in $ifname; do | ||||
| 			uci -q batch <<-EOF | ||||
| 				delete network.$1_${name/./_}_dev | ||||
| 				set network.$1_${name/./_}_dev='device' | ||||
| 				set network.$1_${name/./_}_dev.name='$name' | ||||
| 				set network.$1_${name/./_}_dev.macaddr='$macaddr' | ||||
| 			EOF | ||||
| 		done | ||||
| 	fi | ||||
|  | ||||
| 	case "$protocol" in | ||||
| 		static) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ get_mac_binary() { | ||||
| 	local path="$1" | ||||
| 	local offset="$2" | ||||
|  | ||||
| 	if [ -z "$path" ]; then | ||||
| 	if ! [ -e "$path" ]; then | ||||
| 		echo "get_mac_binary: file $path not found!" >&2 | ||||
| 		return | ||||
| 	fi | ||||
|   | ||||
| @@ -481,6 +481,7 @@ _ucidef_set_led_timer() { | ||||
|  | ||||
| 	_ucidef_set_led_common "$1" "$2" "$3" | ||||
|  | ||||
| 	json_add_string type "$trigger_name" | ||||
| 	json_add_string trigger "$trigger_name" | ||||
| 	json_add_int delayon "$delayon" | ||||
| 	json_add_int delayoff "$delayoff" | ||||
|   | ||||
| @@ -183,7 +183,7 @@ if VERSIONOPT | ||||
| 	config VERSION_REPO | ||||
| 		string | ||||
| 		prompt "Release repository" | ||||
| 		default "http://downloads.openwrt.org/releases/18.06.2" | ||||
| 		default "http://downloads.openwrt.org/releases/18.06.6" | ||||
| 		help | ||||
| 			This is the repository address embedded in the image, it defaults | ||||
| 			to the trunk snapshot repo; the url may contain the following placeholders: | ||||
|   | ||||
| @@ -57,7 +57,10 @@ sr3200|\ | ||||
| t830|\ | ||||
| tube2h|\ | ||||
| wam250|\ | ||||
| wndr3700|\ | ||||
| wnr1000-v2|\ | ||||
| wnr2000-v3|\ | ||||
| wnr2200|\ | ||||
| wnr612-v2|\ | ||||
| xd3200) | ||||
| 	ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x10000" "0x10000" | ||||
| 	;; | ||||
| @@ -91,6 +94,12 @@ qihoo-c301) | ||||
| wi2a-ac200i) | ||||
| 	ubootenv_add_uci_config "/dev/mtd4" "0x0" "0x8000" "0x10000" | ||||
| 	;; | ||||
| wndr3700) | ||||
| 	ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x10000" | ||||
| 	;; | ||||
| wndr4300) | ||||
| 	ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x40000" "0x20000" | ||||
| 	;; | ||||
| esac | ||||
|  | ||||
| config_load ubootenv | ||||
|   | ||||
| @@ -12,7 +12,7 @@ PKG_SOURCE_URL:=https://github.com/chunkeey/FritzBox-4040-UBOOT | ||||
| PKG_SOURCE_PROTO:=git | ||||
| PKG_SOURCE_VERSION:=6946ebbaf7b12a4a092d763c8f0c87a25984f103 | ||||
| PKG_SOURCE_DATE:=2017-01-29 | ||||
| PKG_MIRROR_HASH:=5c2394f51a083dca2a2bf9cb36fa717f252112fc792c9eeae64f6383ad08987b | ||||
| PKG_MIRROR_HASH:=4f3f5d9e3f047910d2bbd31325cc622c3dd64662c20ea740b27ac4bef9736a34 | ||||
|  | ||||
| PKG_RELEASE:=1 | ||||
|  | ||||
| @@ -21,11 +21,12 @@ include $(INCLUDE_DIR)/package.mk | ||||
|  | ||||
| define U-Boot/Default | ||||
|   BUILD_TARGET:=ipq40xx | ||||
|   UBOOT_IMAGE:=uboot-fritz4040.bin | ||||
| endef | ||||
|  | ||||
| define U-Boot/fritz4040 | ||||
|   NAME:=FritzBox 4040 | ||||
|   UBOOT_IMAGE:=uboot-fritz4040.bin | ||||
|   BUILD_DEVICES:=avm_fritzbox-4040 | ||||
| endef | ||||
|  | ||||
| UBOOT_CONFIGURE_VARS += USE_PRIVATE_LIBGCC=yes | ||||
| @@ -34,8 +35,8 @@ export DTC | ||||
|  | ||||
| define Build/Configure | ||||
| 	$(Build/Configure/U-Boot) | ||||
| 	$(HOSTCC) -o $(PKG_BUILD_DIR)/fritz/lzma2eva $(PKG_BUILD_DIR)/fritz/src/lzma2eva.c -lz | ||||
| 	$(HOSTCC) -o $(PKG_BUILD_DIR)/fritz/tichksum $(PKG_BUILD_DIR)/fritz/src/tichksum.c | ||||
| 	$(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $(PKG_BUILD_DIR)/fritz/lzma2eva $(PKG_BUILD_DIR)/fritz/src/lzma2eva.c -lz | ||||
| 	$(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $(PKG_BUILD_DIR)/fritz/tichksum $(PKG_BUILD_DIR)/fritz/src/tichksum.c | ||||
| 	ln -sf $(STAGING_DIR_HOST)/bin/lzma $(PKG_BUILD_DIR)/fritz | ||||
| 	ln -sf compiler-gcc5.h $(PKG_BUILD_DIR)/include/linux/compiler-gcc7.h | ||||
| endef | ||||
| @@ -45,6 +46,11 @@ define Build/Compile | ||||
| 	(cd $(PKG_BUILD_DIR); ./fritz/fritzcreator.sh;) | ||||
| endef | ||||
|  | ||||
| define Build/InstallDev | ||||
| 	$(INSTALL_DIR) $(STAGING_DIR_IMAGE) | ||||
| 	$(CP) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(UBOOT_IMAGE) | ||||
| endef | ||||
|  | ||||
| define Package/u-boot/install | ||||
| 	$(Package/u-boot/install/default) | ||||
| 	$(INSTALL_BIN) ./files/upload-to-f4040.sh $(1)/ | ||||
|   | ||||
| @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk | ||||
| include $(INCLUDE_DIR)/kernel.mk | ||||
|  | ||||
| PKG_NAME:=i2c-gpio-custom | ||||
| PKG_RELEASE:=2 | ||||
| PKG_RELEASE:=3 | ||||
|  | ||||
| include $(INCLUDE_DIR)/package.mk | ||||
|  | ||||
|   | ||||
| @@ -51,7 +51,7 @@ | ||||
|  | ||||
| #define DRV_NAME	"i2c-gpio-custom" | ||||
| #define DRV_DESC	"Custom GPIO-based I2C driver" | ||||
| #define DRV_VERSION	"0.1.1" | ||||
| #define DRV_VERSION	"0.1.2" | ||||
|  | ||||
| #define PFX		DRV_NAME ": " | ||||
|  | ||||
| @@ -96,7 +96,7 @@ static void i2c_gpio_custom_cleanup(void) | ||||
|  | ||||
| 	for (i = 0; i < nr_devices; i++) | ||||
| 		if (devices[i]) | ||||
| 			platform_device_put(devices[i]); | ||||
| 			platform_device_unregister(devices[i]); | ||||
| } | ||||
|  | ||||
| static int __init i2c_gpio_custom_add_one(unsigned int id, unsigned int *params) | ||||
|   | ||||
| @@ -554,6 +554,8 @@ define KernelPackage/ipt-tproxy | ||||
|   TITLE:=Transparent proxying support | ||||
|   DEPENDS+=+kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +IPV6:kmod-ip6tables | ||||
|   KCONFIG:= \ | ||||
|   	CONFIG_NF_SOCKET_IPV4 \ | ||||
|   	CONFIG_NF_SOCKET_IPV6 \ | ||||
|   	CONFIG_NETFILTER_XT_MATCH_SOCKET \ | ||||
|   	CONFIG_NETFILTER_XT_TARGET_TPROXY | ||||
|   FILES:= \ | ||||
|   | ||||
| @@ -852,6 +852,7 @@ define KernelPackage/usb-serial-wwan | ||||
|   TITLE:=Support for GSM and CDMA modems | ||||
|   KCONFIG:=CONFIG_USB_SERIAL_WWAN | ||||
|   FILES:=$(LINUX_DIR)/drivers/usb/serial/usb_wwan.ko | ||||
|   HIDDEN:=1 | ||||
|   AUTOLOAD:=$(call AutoProbe,usb_wwan) | ||||
|   $(call AddDepends/usb-serial) | ||||
| endef | ||||
| @@ -865,11 +866,10 @@ $(eval $(call KernelPackage,usb-serial-wwan)) | ||||
|  | ||||
| define KernelPackage/usb-serial-option | ||||
|   TITLE:=Support for Option HSDPA modems | ||||
|   DEPENDS:=+kmod-usb-serial-wwan | ||||
|   KCONFIG:=CONFIG_USB_SERIAL_OPTION | ||||
|   FILES:=$(LINUX_DIR)/drivers/usb/serial/option.ko | ||||
|   AUTOLOAD:=$(call AutoProbe,option) | ||||
|   $(call AddDepends/usb-serial) | ||||
|   $(call AddDepends/usb-serial,+kmod-usb-serial-wwan) | ||||
| endef | ||||
|  | ||||
| define KernelPackage/usb-serial-option/description | ||||
|   | ||||
| @@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk | ||||
| PKG_NAME:=mac80211 | ||||
|  | ||||
| PKG_VERSION:=2017-11-01 | ||||
| PKG_RELEASE:=9 | ||||
| PKG_RELEASE:=10 | ||||
| PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources | ||||
| PKG_HASH:=8437ab7886b988c8152e7a4db30b7f41009e49a3b2cb863edd05da1ecd7eb05a | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,68 @@ | ||||
| From e3c57dd949835419cee8d3b45db38de58bf6ebd5 Mon Sep 17 00:00:00 2001 | ||||
| From: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| Date: Mon, 18 Nov 2019 01:13:37 +0100 | ||||
| Subject: [PATCH] backports: Adapt to changes to skb_get_hash_perturb() | ||||
|  | ||||
| The skb_get_hash_perturb() function now takes a siphash_key_t instead of | ||||
| an u32. This was changed in commit 55667441c84f ("net/flow_dissector: | ||||
| switch to siphash"). Use the correct type in the fq header file | ||||
| depending on the kernel version. | ||||
|  | ||||
| Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||
| --- | ||||
|  include/net/fq.h      | 8 ++++++++ | ||||
|  include/net/fq_impl.h | 8 ++++++++ | ||||
|  2 files changed, 16 insertions(+) | ||||
|  | ||||
| --- a/include/net/fq.h | ||||
| +++ b/include/net/fq.h | ||||
| @@ -70,7 +70,15 @@ struct fq { | ||||
|  	struct list_head backlogs; | ||||
|  	spinlock_t lock; | ||||
|  	u32 flows_cnt; | ||||
| +#if LINUX_VERSION_IS_GEQ(5,3,10) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,19,83, 4,20,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,14,153, 4,15,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,9,200, 4,10,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,4,200, 4,5,0) | ||||
| +	siphash_key_t	perturbation; | ||||
| +#else | ||||
|  	u32 perturbation; | ||||
| +#endif | ||||
|  	u32 limit; | ||||
|  	u32 memory_limit; | ||||
|  	u32 memory_usage; | ||||
| --- a/include/net/fq_impl.h | ||||
| +++ b/include/net/fq_impl.h | ||||
| @@ -118,7 +118,15 @@ static struct fq_flow *fq_flow_classify( | ||||
|   | ||||
|  	lockdep_assert_held(&fq->lock); | ||||
|   | ||||
| +#if LINUX_VERSION_IS_GEQ(5,3,10) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,19,83, 4,20,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,14,153, 4,15,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,9,200, 4,10,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,4,200, 4,5,0) | ||||
| +	hash = skb_get_hash_perturb(skb, &fq->perturbation); | ||||
| +#else | ||||
|  	hash = skb_get_hash_perturb(skb, fq->perturbation); | ||||
| +#endif | ||||
|  	idx = reciprocal_scale(hash, fq->flows_cnt); | ||||
|  	flow = &fq->flows[idx]; | ||||
|   | ||||
| @@ -307,7 +315,15 @@ static int fq_init(struct fq *fq, int fl | ||||
|  	INIT_LIST_HEAD(&fq->backlogs); | ||||
|  	spin_lock_init(&fq->lock); | ||||
|  	fq->flows_cnt = max_t(u32, flows_cnt, 1); | ||||
| +#if LINUX_VERSION_IS_GEQ(5,3,10) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,19,83, 4,20,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,14,153, 4,15,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,9,200, 4,10,0) || \ | ||||
| +    LINUX_VERSION_IN_RANGE(4,4,200, 4,5,0) | ||||
| +	get_random_bytes(&fq->perturbation, sizeof(fq->perturbation)); | ||||
| +#else | ||||
|  	fq->perturbation = prandom_u32(); | ||||
| +#endif | ||||
|  	fq->quantum = 300; | ||||
|  	fq->limit = 8192; | ||||
|  	fq->memory_limit = 16 << 20; /* 16 MBytes */ | ||||
| @@ -0,0 +1,34 @@ | ||||
| From e966a79c2f761a696dec9cfb0e2d4aa977bf78cb Mon Sep 17 00:00:00 2001 | ||||
| From: Colin Ian King <colin.king@canonical.com> | ||||
| Date: Tue, 16 Oct 2018 18:43:42 +0100 | ||||
| Subject: [PATCH] brcmfmac: fix spelling mistake "Retreiving" -> "Retrieving" | ||||
|  | ||||
| Trivial fix to spelling mistake in brcmf_err error message. | ||||
|  | ||||
| Signed-off-by: Colin Ian King <colin.king@canonical.com> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| @@ -214,7 +214,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||
|  	err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, | ||||
|  				       sizeof(ifp->mac_addr)); | ||||
|  	if (err < 0) { | ||||
| -		brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); | ||||
| +		brcmf_err("Retrieving cur_etheraddr failed, %d\n", err); | ||||
|  		goto done; | ||||
|  	} | ||||
|  	memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); | ||||
| @@ -269,7 +269,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||
|  	strcpy(buf, "ver"); | ||||
|  	err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); | ||||
|  	if (err < 0) { | ||||
| -		brcmf_err("Retreiving version information failed, %d\n", | ||||
| +		brcmf_err("Retrieving version information failed, %d\n", | ||||
|  			  err); | ||||
|  		goto done; | ||||
|  	} | ||||
| @@ -0,0 +1,110 @@ | ||||
| From b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b Mon Sep 17 00:00:00 2001 | ||||
| From: Lyude Paul <lyude@redhat.com> | ||||
| Date: Sat, 24 Nov 2018 17:57:05 -0500 | ||||
| Subject: [PATCH] brcmfmac: Fix out of bounds memory access during fw load | ||||
|  | ||||
| I ended up tracking down some rather nasty issues with f2fs (and other | ||||
| filesystem modules) constantly crashing on my kernel down to a | ||||
| combination of out of bounds memory accesses, one of which was coming | ||||
| from brcmfmac during module load: | ||||
|  | ||||
| [   30.891382] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac4356-sdio for chip BCM4356/2 | ||||
| [   30.894437] ================================================================== | ||||
| [   30.901581] BUG: KASAN: global-out-of-bounds in brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac] | ||||
| [   30.909935] Read of size 1 at addr ffff2000024865df by task kworker/6:2/387 | ||||
| [   30.916805] | ||||
| [   30.918261] CPU: 6 PID: 387 Comm: kworker/6:2 Tainted: G           O      4.20.0-rc3Lyude-Test+ #19 | ||||
| [   30.927251] Hardware name: amlogic khadas-vim2/khadas-vim2, BIOS 2018.07-rc2-armbian 09/11/2018 | ||||
| [   30.935964] Workqueue: events brcmf_driver_register [brcmfmac] | ||||
| [   30.941641] Call trace: | ||||
| [   30.944058]  dump_backtrace+0x0/0x3e8 | ||||
| [   30.947676]  show_stack+0x14/0x20 | ||||
| [   30.950968]  dump_stack+0x130/0x1c4 | ||||
| [   30.954406]  print_address_description+0x60/0x25c | ||||
| [   30.959066]  kasan_report+0x1b4/0x368 | ||||
| [   30.962683]  __asan_report_load1_noabort+0x18/0x20 | ||||
| [   30.967547]  brcmf_fw_alloc_request+0x42c/0x480 [brcmfmac] | ||||
| [   30.967639]  brcmf_sdio_probe+0x163c/0x2050 [brcmfmac] | ||||
| [   30.978035]  brcmf_ops_sdio_probe+0x598/0xa08 [brcmfmac] | ||||
| [   30.983254]  sdio_bus_probe+0x190/0x398 | ||||
| [   30.983270]  really_probe+0x2a0/0xa70 | ||||
| [   30.983296]  driver_probe_device+0x1b4/0x2d8 | ||||
| [   30.994901]  __driver_attach+0x200/0x280 | ||||
| [   30.994914]  bus_for_each_dev+0x10c/0x1a8 | ||||
| [   30.994925]  driver_attach+0x38/0x50 | ||||
| [   30.994935]  bus_add_driver+0x330/0x608 | ||||
| [   30.994953]  driver_register+0x140/0x388 | ||||
| [   31.013965]  sdio_register_driver+0x74/0xa0 | ||||
| [   31.014076]  brcmf_sdio_register+0x14/0x60 [brcmfmac] | ||||
| [   31.023177]  brcmf_driver_register+0xc/0x18 [brcmfmac] | ||||
| [   31.023209]  process_one_work+0x654/0x1080 | ||||
| [   31.032266]  worker_thread+0x4f0/0x1308 | ||||
| [   31.032286]  kthread+0x2a8/0x320 | ||||
| [   31.039254]  ret_from_fork+0x10/0x1c | ||||
| [   31.039269] | ||||
| [   31.044226] The buggy address belongs to the variable: | ||||
| [   31.044351]  brcmf_firmware_path+0x11f/0xfffffffffffd3b40 [brcmfmac] | ||||
| [   31.055601] | ||||
| [   31.057031] Memory state around the buggy address: | ||||
| [   31.061800]  ffff200002486480: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 | ||||
| [   31.068983]  ffff200002486500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||||
| [   31.068993] >ffff200002486580: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00 | ||||
| [   31.068999]                                                     ^ | ||||
| [   31.069017]  ffff200002486600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ||||
| [   31.096521]  ffff200002486680: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa | ||||
| [   31.096528] ================================================================== | ||||
| [   31.096533] Disabling lock debugging due to kernel taint | ||||
|  | ||||
| It appears that when trying to determine the length of the string in the | ||||
| alternate firmware path, we make the mistake of not handling the case | ||||
| where the firmware path is empty correctly. Since strlen(mp_path) can | ||||
| return 0, we'll end up accessing mp_path[-1] when the firmware_path | ||||
| isn't provided through the module arguments. | ||||
|  | ||||
| So, fix this by just setting the end char to '\0' by default, and only | ||||
| changing it if we have a non-zero length. Additionally, use strnlen() | ||||
| with BRCMF_FW_ALTPATH_LEN instead of strlen() just to be extra safe. | ||||
|  | ||||
| Fixes: 2baa3aaee27f ("brcmfmac: introduce brcmf_fw_alloc_request() function") | ||||
| Cc: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Cc: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Cc: Franky Lin <franky.lin@broadcom.com> | ||||
| Cc: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Cc: Kalle Valo <kvalo@codeaurora.org> | ||||
| Cc: Arend Van Spriel <arend.vanspriel@broadcom.com> | ||||
| Cc: Himanshu Jha <himanshujha199640@gmail.com> | ||||
| Cc: Dan Haab <dhaab@luxul.com> | ||||
| Cc: Jia-Shyr Chuang <saint.chuang@cypress.com> | ||||
| Cc: Ian Molton <ian@mnementh.co.uk> | ||||
| Cc: <stable@vger.kernel.org> # v4.17+ | ||||
| Signed-off-by: Lyude Paul <lyude@redhat.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c   | 8 ++++++-- | ||||
|  1 file changed, 6 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||
| @@ -633,8 +633,9 @@ brcmf_fw_alloc_request(u32 chip, u32 chi | ||||
|  	struct brcmf_fw_request *fwreq; | ||||
|  	char chipname[12]; | ||||
|  	const char *mp_path; | ||||
| +	size_t mp_path_len; | ||||
|  	u32 i, j; | ||||
| -	char end; | ||||
| +	char end = '\0'; | ||||
|  	size_t reqsz; | ||||
|   | ||||
|  	for (i = 0; i < table_size; i++) { | ||||
| @@ -659,7 +660,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi | ||||
|  		   mapping_table[i].fw_base, chipname); | ||||
|   | ||||
|  	mp_path = brcmf_mp_global.firmware_path; | ||||
| -	end = mp_path[strlen(mp_path) - 1]; | ||||
| +	mp_path_len = strnlen(mp_path, BRCMF_FW_ALTPATH_LEN); | ||||
| +	if (mp_path_len) | ||||
| +		end = mp_path[mp_path_len - 1]; | ||||
| + | ||||
|  	fwreq->n_items = n_fwnames; | ||||
|   | ||||
|  	for (j = 0; j < n_fwnames; j++) { | ||||
| @@ -0,0 +1,68 @@ | ||||
| From 8c892df41500469729e0d662816300196e4f463d Mon Sep 17 00:00:00 2001 | ||||
| From: Stijn Tintel <stijn@linux-ipv6.be> | ||||
| Date: Tue, 4 Dec 2018 20:29:05 +0200 | ||||
| Subject: [PATCH] brcmfmac: fix roamoff=1 modparam | ||||
|  | ||||
| When the update_connect_param callback is set, nl80211 expects the flag | ||||
| WIPHY_FLAG_SUPPORTS_FW_ROAM to be set as well. However, this flag is | ||||
| only set when modparam roamoff=0, while the callback is set | ||||
| unconditionally. Since commit 7f9a3e150ec7 this causes a warning in | ||||
| wiphy_register, which breaks brcmfmac. | ||||
|  | ||||
| Disable the update_connect_param callback when roamoff=0 to fix this. | ||||
|  | ||||
| Fixes: 7f9a3e150ec7 ("nl80211: Update ERP info using NL80211_CMD_UPDATE_CONNECT_PARAMS") | ||||
| Cc: Stable <stable@vger.kernel.org> # 4.19+ | ||||
| Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> | ||||
| Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c   | 11 +++++++++-- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.h   |  2 +- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/core.c   |  2 +- | ||||
|  3 files changed, 11 insertions(+), 4 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -5189,10 +5189,17 @@ static struct cfg80211_ops brcmf_cfg8021 | ||||
|  	.del_pmk = brcmf_cfg80211_del_pmk, | ||||
|  }; | ||||
|   | ||||
| -struct cfg80211_ops *brcmf_cfg80211_get_ops(void) | ||||
| +struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings) | ||||
|  { | ||||
| -	return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), | ||||
| +	struct cfg80211_ops *ops; | ||||
| + | ||||
| +	ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), | ||||
|  		       GFP_KERNEL); | ||||
| + | ||||
| +	if (ops && settings->roamoff) | ||||
| +		ops->update_connect_params = NULL; | ||||
| + | ||||
| +	return ops; | ||||
|  } | ||||
|   | ||||
|  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | ||||
| @@ -404,7 +404,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 | ||||
|  void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); | ||||
|  s32 brcmf_cfg80211_up(struct net_device *ndev); | ||||
|  s32 brcmf_cfg80211_down(struct net_device *ndev); | ||||
| -struct cfg80211_ops *brcmf_cfg80211_get_ops(void); | ||||
| +struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings); | ||||
|  enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); | ||||
|   | ||||
|  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1151,7 +1151,7 @@ int brcmf_attach(struct device *dev, str | ||||
|   | ||||
|  	brcmf_dbg(TRACE, "Enter\n"); | ||||
|   | ||||
| -	ops = brcmf_cfg80211_get_ops(); | ||||
| +	ops = brcmf_cfg80211_get_ops(settings); | ||||
|  	if (!ops) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| @@ -0,0 +1,41 @@ | ||||
| From 861cb5eb467f5e38dce1aabe4e8db379255bd89b Mon Sep 17 00:00:00 2001 | ||||
| From: Stefan Wahren <stefan.wahren@i2se.com> | ||||
| Date: Wed, 12 Dec 2018 20:20:06 +0100 | ||||
| Subject: [PATCH] brcmfmac: Fix access point mode | ||||
|  | ||||
| Since commit 1204aa17f3b4 ("brcmfmac: set WIPHY_FLAG_HAVE_AP_SME flag") | ||||
| the Raspberry Pi 3 A+ (BCM43455) isn't able to operate in AP mode with | ||||
| hostapd (device_ap_sme=1 use_monitor=0): | ||||
|  | ||||
| brcmfmac: brcmf_cfg80211_stop_ap: setting AP mode failed -52 | ||||
|  | ||||
| So add the missing mgmt_stypes for AP mode to fix this. | ||||
|  | ||||
| Fixes: 1204aa17f3b4 ("brcmfmac: set WIPHY_FLAG_HAVE_AP_SME flag") | ||||
| Suggested-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c    | 10 ++++++++++ | ||||
|  1 file changed, 10 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -6303,6 +6303,16 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = | ||||
|  		.tx = 0xffff, | ||||
|  		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) | | ||||
|  		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | ||||
| +	}, | ||||
| +	[NL80211_IFTYPE_AP] = { | ||||
| +		.tx = 0xffff, | ||||
| +		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_DISASSOC >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_AUTH >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_DEAUTH >> 4) | | ||||
| +		      BIT(IEEE80211_STYPE_ACTION >> 4) | ||||
|  	} | ||||
|  }; | ||||
|   | ||||
| @@ -0,0 +1,104 @@ | ||||
| From 5cc898fbcb352b764f8d51c16e10e2eb0056173d Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 6 Feb 2019 12:28:15 +0100 | ||||
| Subject: [PATCH] brcmfmac: modify __brcmf_err() to take bus as a parameter | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| So far __brcmf_err() was using pr_err() which didn't allow identifying | ||||
| device that was affected by an error. It's crucial for systems with more | ||||
| than 1 device supported by brcmfmac (a common case for home routers). | ||||
|  | ||||
| This change allows passing struct brcmf_bus to the __brcmf_err(). That | ||||
| struct has been agreed to be the most common one. It allows accessing | ||||
| struct device easily & using dev_err() printing helper. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/common.c    | 7 +++++-- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 8 +++++--- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/tracepoint.c    | 9 +++++++-- | ||||
|  3 files changed, 17 insertions(+), 7 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| @@ -350,7 +350,7 @@ done: | ||||
|  } | ||||
|   | ||||
|  #ifndef CPTCFG_BRCM_TRACING | ||||
| -void __brcmf_err(const char *func, const char *fmt, ...) | ||||
| +void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...) | ||||
|  { | ||||
|  	struct va_format vaf; | ||||
|  	va_list args; | ||||
| @@ -359,7 +359,10 @@ void __brcmf_err(const char *func, const | ||||
|   | ||||
|  	vaf.fmt = fmt; | ||||
|  	vaf.va = &args; | ||||
| -	pr_err("%s: %pV", func, &vaf); | ||||
| +	if (bus) | ||||
| +		dev_err(bus->dev, "%s: %pV", func, &vaf); | ||||
| +	else | ||||
| +		pr_err("%s: %pV", func, &vaf); | ||||
|   | ||||
|  	va_end(args); | ||||
|  } | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| @@ -45,8 +45,10 @@ | ||||
|  #undef pr_fmt | ||||
|  #define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt | ||||
|   | ||||
| -__printf(2, 3) | ||||
| -void __brcmf_err(const char *func, const char *fmt, ...); | ||||
| +struct brcmf_bus; | ||||
| + | ||||
| +__printf(3, 4) | ||||
| +void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...); | ||||
|  /* Macro for error messages. When debugging / tracing the driver all error | ||||
|   * messages are important to us. | ||||
|   */ | ||||
| @@ -55,7 +57,7 @@ void __brcmf_err(const char *func, const | ||||
|  		if (IS_ENABLED(CPTCFG_BRCMDBG) ||			\ | ||||
|  		    IS_ENABLED(CPTCFG_BRCM_TRACING) ||			\ | ||||
|  		    net_ratelimit())					\ | ||||
| -			__brcmf_err(__func__, fmt, ##__VA_ARGS__);	\ | ||||
| +			__brcmf_err(NULL, __func__, fmt, ##__VA_ARGS__);\ | ||||
|  	} while (0) | ||||
|   | ||||
|  #if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | ||||
| @@ -14,14 +14,16 @@ | ||||
|   * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|   */ | ||||
|   | ||||
| +#include <linux/device.h> | ||||
|  #include <linux/module.h> /* bug in tracepoint.h, it should include this */ | ||||
|   | ||||
|  #ifndef __CHECKER__ | ||||
|  #define CREATE_TRACE_POINTS | ||||
| +#include "bus.h" | ||||
|  #include "tracepoint.h" | ||||
|  #include "debug.h" | ||||
|   | ||||
| -void __brcmf_err(const char *func, const char *fmt, ...) | ||||
| +void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...) | ||||
|  { | ||||
|  	struct va_format vaf = { | ||||
|  		.fmt = fmt, | ||||
| @@ -30,7 +32,10 @@ void __brcmf_err(const char *func, const | ||||
|   | ||||
|  	va_start(args, fmt); | ||||
|  	vaf.va = &args; | ||||
| -	pr_err("%s: %pV", func, &vaf); | ||||
| +	if (bus) | ||||
| +		dev_err(bus->dev, "%s: %pV", func, &vaf); | ||||
| +	else | ||||
| +		pr_err("%s: %pV", func, &vaf); | ||||
|  	trace_brcmf_err(func, &vaf); | ||||
|  	va_end(args); | ||||
|  } | ||||
| @@ -0,0 +1,266 @@ | ||||
| From 8602e62441aba276cafd68034b72162fbc5ca0a6 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 6 Feb 2019 12:28:16 +0100 | ||||
| Subject: [PATCH] brcmfmac: pass bus to the __brcmf_err() in pcie.c | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This enables dev_err() usage (instead of pr_err()) in the __brcmf_err(). | ||||
| It makes error messages more meaningful and is important for debugging | ||||
| errors/bugs on systems with multiple brcmfmac supported devices. | ||||
|  | ||||
| All bus files should follow & get updated similarly (soon). | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/debug.h       |  2 + | ||||
|  .../broadcom/brcm80211/brcmfmac/pcie.c        | 59 +++++++++++-------- | ||||
|  2 files changed, 38 insertions(+), 23 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| @@ -52,6 +52,7 @@ void __brcmf_err(struct brcmf_bus *bus, | ||||
|  /* Macro for error messages. When debugging / tracing the driver all error | ||||
|   * messages are important to us. | ||||
|   */ | ||||
| +#ifndef brcmf_err | ||||
|  #define brcmf_err(fmt, ...)						\ | ||||
|  	do {								\ | ||||
|  		if (IS_ENABLED(CPTCFG_BRCMDBG) ||			\ | ||||
| @@ -59,6 +60,7 @@ void __brcmf_err(struct brcmf_bus *bus, | ||||
|  		    net_ratelimit())					\ | ||||
|  			__brcmf_err(NULL, __func__, fmt, ##__VA_ARGS__);\ | ||||
|  	} while (0) | ||||
| +#endif | ||||
|   | ||||
|  #if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -30,6 +30,15 @@ | ||||
|  #include <brcmu_wifi.h> | ||||
|  #include <brcm_hw_ids.h> | ||||
|   | ||||
| +/* Custom brcmf_err() that takes bus arg and passes it further */ | ||||
| +#define brcmf_err(bus, fmt, ...)					\ | ||||
| +	do {								\ | ||||
| +		if (IS_ENABLED(CPTCFG_BRCMDBG) ||			\ | ||||
| +		    IS_ENABLED(CPTCFG_BRCM_TRACING) ||			\ | ||||
| +		    net_ratelimit())					\ | ||||
| +			__brcmf_err(bus, __func__, fmt, ##__VA_ARGS__);	\ | ||||
| +	} while (0) | ||||
| + | ||||
|  #include "debug.h" | ||||
|  #include "bus.h" | ||||
|  #include "commonring.h" | ||||
| @@ -531,6 +540,7 @@ static void | ||||
|  brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid) | ||||
|  { | ||||
|  	const struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|  	struct brcmf_core *core; | ||||
|  	u32 bar0_win; | ||||
|   | ||||
| @@ -548,7 +558,7 @@ brcmf_pcie_select_core(struct brcmf_pcie | ||||
|  			} | ||||
|  		} | ||||
|  	} else { | ||||
| -		brcmf_err("Unsupported core selected %x\n", coreid); | ||||
| +		brcmf_err(bus, "Unsupported core selected %x\n", coreid); | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| @@ -848,9 +858,8 @@ static irqreturn_t brcmf_pcie_isr_thread | ||||
|   | ||||
|  static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| -	struct pci_dev *pdev; | ||||
| - | ||||
| -	pdev = devinfo->pdev; | ||||
| +	struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|   | ||||
|  	brcmf_pcie_intr_disable(devinfo); | ||||
|   | ||||
| @@ -861,7 +870,7 @@ static int brcmf_pcie_request_irq(struct | ||||
|  				 brcmf_pcie_isr_thread, IRQF_SHARED, | ||||
|  				 "brcmf_pcie_intr", devinfo)) { | ||||
|  		pci_disable_msi(pdev); | ||||
| -		brcmf_err("Failed to request IRQ %d\n", pdev->irq); | ||||
| +		brcmf_err(bus, "Failed to request IRQ %d\n", pdev->irq); | ||||
|  		return -EIO; | ||||
|  	} | ||||
|  	devinfo->irq_allocated = true; | ||||
| @@ -871,15 +880,14 @@ static int brcmf_pcie_request_irq(struct | ||||
|   | ||||
|  static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| -	struct pci_dev *pdev; | ||||
| +	struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|  	u32 status; | ||||
|  	u32 count; | ||||
|   | ||||
|  	if (!devinfo->irq_allocated) | ||||
|  		return; | ||||
|   | ||||
| -	pdev = devinfo->pdev; | ||||
| - | ||||
|  	brcmf_pcie_intr_disable(devinfo); | ||||
|  	free_irq(pdev->irq, devinfo); | ||||
|  	pci_disable_msi(pdev); | ||||
| @@ -891,7 +899,7 @@ static void brcmf_pcie_release_irq(struc | ||||
|  		count++; | ||||
|  	} | ||||
|  	if (devinfo->in_irq) | ||||
| -		brcmf_err("Still in IRQ (processing) !!!\n"); | ||||
| +		brcmf_err(bus, "Still in IRQ (processing) !!!\n"); | ||||
|   | ||||
|  	status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); | ||||
|  	brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); | ||||
| @@ -1102,6 +1110,7 @@ static void brcmf_pcie_release_ringbuffe | ||||
|   | ||||
|  static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	struct brcmf_pcie_ringbuf *ring; | ||||
|  	struct brcmf_pcie_ringbuf *rings; | ||||
|  	u32 d2h_w_idx_ptr; | ||||
| @@ -1254,7 +1263,7 @@ static int brcmf_pcie_init_ringbuffers(s | ||||
|  	return 0; | ||||
|   | ||||
|  fail: | ||||
| -	brcmf_err("Allocating ring buffers failed\n"); | ||||
| +	brcmf_err(bus, "Allocating ring buffers failed\n"); | ||||
|  	brcmf_pcie_release_ringbuffers(devinfo); | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
| @@ -1277,6 +1286,7 @@ brcmf_pcie_release_scratchbuffers(struct | ||||
|   | ||||
|  static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	u64 address; | ||||
|  	u32 addr; | ||||
|   | ||||
| @@ -1316,7 +1326,7 @@ static int brcmf_pcie_init_scratchbuffer | ||||
|  	return 0; | ||||
|   | ||||
|  fail: | ||||
| -	brcmf_err("Allocating scratch buffers failed\n"); | ||||
| +	brcmf_err(bus, "Allocating scratch buffers failed\n"); | ||||
|  	brcmf_pcie_release_scratchbuffers(devinfo); | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
| @@ -1437,6 +1447,7 @@ static int | ||||
|  brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, | ||||
|  			       u32 sharedram_addr) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	struct brcmf_pcie_shared_info *shared; | ||||
|  	u32 addr; | ||||
|   | ||||
| @@ -1448,7 +1459,8 @@ brcmf_pcie_init_share_ram_info(struct br | ||||
|  	brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version); | ||||
|  	if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) || | ||||
|  	    (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) { | ||||
| -		brcmf_err("Unsupported PCIE version %d\n", shared->version); | ||||
| +		brcmf_err(bus, "Unsupported PCIE version %d\n", | ||||
| +			  shared->version); | ||||
|  		return -EINVAL; | ||||
|  	} | ||||
|   | ||||
| @@ -1490,6 +1502,7 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|  					const struct firmware *fw, void *nvram, | ||||
|  					u32 nvram_len) | ||||
|  { | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev); | ||||
|  	u32 sharedram_addr; | ||||
|  	u32 sharedram_addr_written; | ||||
|  	u32 loop_counter; | ||||
| @@ -1544,7 +1557,7 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|  		loop_counter--; | ||||
|  	} | ||||
|  	if (sharedram_addr == sharedram_addr_written) { | ||||
| -		brcmf_err("FW failed to initialize\n"); | ||||
| +		brcmf_err(bus, "FW failed to initialize\n"); | ||||
|  		return -ENODEV; | ||||
|  	} | ||||
|  	brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); | ||||
| @@ -1555,16 +1568,15 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|   | ||||
|  static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo) | ||||
|  { | ||||
| -	struct pci_dev *pdev; | ||||
| +	struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|  	int err; | ||||
|  	phys_addr_t  bar0_addr, bar1_addr; | ||||
|  	ulong bar1_size; | ||||
|   | ||||
| -	pdev = devinfo->pdev; | ||||
| - | ||||
|  	err = pci_enable_device(pdev); | ||||
|  	if (err) { | ||||
| -		brcmf_err("pci_enable_device failed err=%d\n", err); | ||||
| +		brcmf_err(bus, "pci_enable_device failed err=%d\n", err); | ||||
|  		return err; | ||||
|  	} | ||||
|   | ||||
| @@ -1577,7 +1589,7 @@ static int brcmf_pcie_get_resource(struc | ||||
|  	/* read Bar-1 mapped memory range */ | ||||
|  	bar1_size = pci_resource_len(pdev, 2); | ||||
|  	if ((bar1_size == 0) || (bar1_addr == 0)) { | ||||
| -		brcmf_err("BAR1 Not enabled, device size=%ld, addr=%#016llx\n", | ||||
| +		brcmf_err(bus, "BAR1 Not enabled, device size=%ld, addr=%#016llx\n", | ||||
|  			  bar1_size, (unsigned long long)bar1_addr); | ||||
|  		return -EINVAL; | ||||
|  	} | ||||
| @@ -1586,7 +1598,7 @@ static int brcmf_pcie_get_resource(struc | ||||
|  	devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size); | ||||
|   | ||||
|  	if (!devinfo->regs || !devinfo->tcm) { | ||||
| -		brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs, | ||||
| +		brcmf_err(bus, "ioremap() failed (%p,%p)\n", devinfo->regs, | ||||
|  			  devinfo->tcm); | ||||
|  		return -EINVAL; | ||||
|  	} | ||||
| @@ -1873,7 +1885,7 @@ fail_bus: | ||||
|  	kfree(bus->msgbuf); | ||||
|  	kfree(bus); | ||||
|  fail: | ||||
| -	brcmf_err("failed %x:%x\n", pdev->vendor, pdev->device); | ||||
| +	brcmf_err(NULL, "failed %x:%x\n", pdev->vendor, pdev->device); | ||||
|  	brcmf_pcie_release_resource(devinfo); | ||||
|  	if (devinfo->ci) | ||||
|  		brcmf_chip_detach(devinfo->ci); | ||||
| @@ -1947,7 +1959,7 @@ static int brcmf_pcie_pm_enter_D3(struct | ||||
|  	wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed, | ||||
|  			   BRCMF_PCIE_MBDATA_TIMEOUT); | ||||
|  	if (!devinfo->mbdata_completed) { | ||||
| -		brcmf_err("Timeout on response for entering D3 substate\n"); | ||||
| +		brcmf_err(bus, "Timeout on response for entering D3 substate\n"); | ||||
|  		brcmf_bus_change_state(bus, BRCMF_BUS_UP); | ||||
|  		return -EIO; | ||||
|  	} | ||||
| @@ -1993,7 +2005,7 @@ cleanup: | ||||
|   | ||||
|  	err = brcmf_pcie_probe(pdev, NULL); | ||||
|  	if (err) | ||||
| -		brcmf_err("probe after resume failed, err=%d\n", err); | ||||
| +		brcmf_err(bus, "probe after resume failed, err=%d\n", err); | ||||
|   | ||||
|  	return err; | ||||
|  } | ||||
| @@ -2065,7 +2077,8 @@ void brcmf_pcie_register(void) | ||||
|  	brcmf_dbg(PCIE, "Enter\n"); | ||||
|  	err = pci_register_driver(&brcmf_pciedrvr); | ||||
|  	if (err) | ||||
| -		brcmf_err("PCIE driver registration failed, err=%d\n", err); | ||||
| +		brcmf_err(NULL, "PCIE driver registration failed, err=%d\n", | ||||
| +			  err); | ||||
|  } | ||||
|   | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,143 @@ | ||||
| From e665988be29ccea3584528967b432a5cfd801ca4 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 8 Feb 2019 07:42:30 +0100 | ||||
| Subject: [PATCH] brcmfmac: support monitor frames with the hardware/ucode | ||||
|  header | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| So far there were two monitor frame formats: | ||||
| 1) 802.11 frames (with frame (sub)type & all addresses) | ||||
| 2) 802.11 frames with the radiotap header | ||||
|  | ||||
| Testing the latest FullMAC firmwares for 4366b1/4366c0 resulted in | ||||
| discovering a new format being used. It seems (almost?) identical to the | ||||
| one known from ucode used in SoftMAC devices which is most likely the | ||||
| same codebase anyway. | ||||
|  | ||||
| While new firmwares will /announce/ radiotap header support using the | ||||
| "rtap" fw capability string it seems no string was added for the new | ||||
| ucode header format. | ||||
|  | ||||
| All above means that: | ||||
| 1) We need new format support when dealing with a received frame | ||||
| 2) A new feature bit & mapping quirks have to be added manually | ||||
|  | ||||
| As for now only an empty radiotap is being created. Adding support for | ||||
| extracting some info (band, channel, signal, etc.) is planned for the | ||||
| future. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/core.c        | 55 +++++++++++++++++++ | ||||
|  .../broadcom/brcm80211/brcmfmac/feature.c     |  4 ++ | ||||
|  .../broadcom/brcm80211/brcmfmac/feature.h     |  4 +- | ||||
|  3 files changed, 62 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -43,6 +43,36 @@ | ||||
|   | ||||
|  #define BRCMF_BSSIDX_INVALID			-1 | ||||
|   | ||||
| +#define	RXS_PBPRES				BIT(2) | ||||
| + | ||||
| +#define	D11_PHY_HDR_LEN				6 | ||||
| + | ||||
| +struct d11rxhdr_le { | ||||
| +	__le16 RxFrameSize; | ||||
| +	u16 PAD; | ||||
| +	__le16 PhyRxStatus_0; | ||||
| +	__le16 PhyRxStatus_1; | ||||
| +	__le16 PhyRxStatus_2; | ||||
| +	__le16 PhyRxStatus_3; | ||||
| +	__le16 PhyRxStatus_4; | ||||
| +	__le16 PhyRxStatus_5; | ||||
| +	__le16 RxStatus1; | ||||
| +	__le16 RxStatus2; | ||||
| +	__le16 RxTSFTime; | ||||
| +	__le16 RxChan; | ||||
| +	u8 unknown[12]; | ||||
| +} __packed; | ||||
| + | ||||
| +struct wlc_d11rxhdr { | ||||
| +	struct d11rxhdr_le rxhdr; | ||||
| +	__le32 tsf_l; | ||||
| +	s8 rssi; | ||||
| +	s8 rxpwr0; | ||||
| +	s8 rxpwr1; | ||||
| +	s8 do_rssi_ma; | ||||
| +	s8 rxpwr[4]; | ||||
| +} __packed; | ||||
| + | ||||
|  char *brcmf_ifname(struct brcmf_if *ifp) | ||||
|  { | ||||
|  	if (!ifp) | ||||
| @@ -409,6 +439,31 @@ void brcmf_netif_mon_rx(struct brcmf_if | ||||
|  { | ||||
|  	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) { | ||||
|  		/* Do nothing */ | ||||
| +	} else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) { | ||||
| +		struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data; | ||||
| +		struct ieee80211_radiotap_header *radiotap; | ||||
| +		unsigned int offset; | ||||
| +		u16 RxStatus1; | ||||
| + | ||||
| +		RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1); | ||||
| + | ||||
| +		offset = sizeof(struct wlc_d11rxhdr); | ||||
| +		/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU | ||||
| +		 * subframes | ||||
| +		 */ | ||||
| +		if (RxStatus1 & RXS_PBPRES) | ||||
| +			offset += 2; | ||||
| +		offset += D11_PHY_HDR_LEN; | ||||
| + | ||||
| +		skb_pull(skb, offset); | ||||
| + | ||||
| +		/* TODO: use RX header to fill some radiotap data */ | ||||
| +		radiotap = skb_push(skb, sizeof(*radiotap)); | ||||
| +		memset(radiotap, 0, sizeof(*radiotap)); | ||||
| +		radiotap->it_len = cpu_to_le16(sizeof(*radiotap)); | ||||
| + | ||||
| +		/* TODO: 4 bytes with receive status? */ | ||||
| +		skb->len -= 4; | ||||
|  	} else { | ||||
|  		struct ieee80211_radiotap_header *radiotap; | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | ||||
| @@ -103,6 +103,10 @@ static const struct brcmf_feat_fwfeat br | ||||
|  	{ "01-6cb8e269", BIT(BRCMF_FEAT_MONITOR) }, | ||||
|  	/* brcmfmac4366b-pcie.bin from linux-firmware.git commit 52442afee990 */ | ||||
|  	{ "01-c47a91a4", BIT(BRCMF_FEAT_MONITOR) }, | ||||
| +	/* brcmfmac4366b-pcie.bin from linux-firmware.git commit 211de1679a68 */ | ||||
| +	{ "01-801fb449", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) }, | ||||
| +	/* brcmfmac4366c-pcie.bin from linux-firmware.git commit 211de1679a68 */ | ||||
| +	{ "01-d2cbb8fd", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) }, | ||||
|  }; | ||||
|   | ||||
|  static void brcmf_feat_firmware_overrides(struct brcmf_pub *drv) | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | ||||
| @@ -35,6 +35,7 @@ | ||||
|   * FWSUP: Firmware supplicant. | ||||
|   * MONITOR: firmware can pass monitor packets to host. | ||||
|   * MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header | ||||
| + * MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header | ||||
|   */ | ||||
|  #define BRCMF_FEAT_LIST \ | ||||
|  	BRCMF_FEAT_DEF(MBSS) \ | ||||
| @@ -52,7 +53,8 @@ | ||||
|  	BRCMF_FEAT_DEF(GSCAN) \ | ||||
|  	BRCMF_FEAT_DEF(FWSUP) \ | ||||
|  	BRCMF_FEAT_DEF(MONITOR) \ | ||||
| -	BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) | ||||
| +	BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \ | ||||
| +	BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) | ||||
|   | ||||
|  /* | ||||
|   * Quirks: | ||||
| @@ -0,0 +1,67 @@ | ||||
| From c988b78244df8216902e20de536434e2f474a37e Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Fri, 8 Feb 2019 15:24:39 +0100 | ||||
| Subject: [PATCH] brcmfmac: print firmware reported ring status errors | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Firmware is capable of reporting ring status. It's used e.g. to signal | ||||
| some problem with a specific ring setup. This patch adds support for | ||||
| printing ring & error number which may be useful for debugging setup | ||||
| issues. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/msgbuf.c      | 25 +++++++++++++++++++ | ||||
|  1 file changed, 25 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| @@ -134,6 +134,14 @@ struct msgbuf_completion_hdr { | ||||
|  	__le16				flow_ring_id; | ||||
|  }; | ||||
|   | ||||
| +/* Data struct for the MSGBUF_TYPE_RING_STATUS */ | ||||
| +struct msgbuf_ring_status { | ||||
| +	struct msgbuf_common_hdr	msg; | ||||
| +	struct msgbuf_completion_hdr	compl_hdr; | ||||
| +	__le16				write_idx; | ||||
| +	__le32				rsvd0[5]; | ||||
| +}; | ||||
| + | ||||
|  struct msgbuf_rx_event { | ||||
|  	struct msgbuf_common_hdr	msg; | ||||
|  	struct msgbuf_completion_hdr	compl_hdr; | ||||
| @@ -1180,6 +1188,19 @@ brcmf_msgbuf_process_rx_complete(struct | ||||
|  	brcmf_netif_rx(ifp, skb); | ||||
|  } | ||||
|   | ||||
| +static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf, | ||||
| +					     void *buf) | ||||
| +{ | ||||
| +	struct msgbuf_ring_status *ring_status = buf; | ||||
| +	int err; | ||||
| + | ||||
| +	err = le16_to_cpu(ring_status->compl_hdr.status); | ||||
| +	if (err) { | ||||
| +		int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id); | ||||
| + | ||||
| +		brcmf_err("Firmware reported ring %d error: %d\n", ring, err); | ||||
| +	} | ||||
| +} | ||||
|   | ||||
|  static void | ||||
|  brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf, | ||||
| @@ -1241,6 +1262,10 @@ static void brcmf_msgbuf_process_msgtype | ||||
|   | ||||
|  	msg = (struct msgbuf_common_hdr *)buf; | ||||
|  	switch (msg->msgtype) { | ||||
| +	case MSGBUF_TYPE_RING_STATUS: | ||||
| +		brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n"); | ||||
| +		brcmf_msgbuf_process_ring_status(msgbuf, buf); | ||||
| +		break; | ||||
|  	case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT: | ||||
|  		brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n"); | ||||
|  		brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf); | ||||
| @@ -0,0 +1,42 @@ | ||||
| From f4e183293b871c96c0220dcc549d5ca4c72628ad Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 11 Feb 2019 23:04:53 +0100 | ||||
| Subject: [PATCH] brcmfmac: improve code handling bandwidth of firmware | ||||
|  reported channels | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| 1) Use switch to simplify/improve the code & avoid some duplication | ||||
| 2) Add warning for unsupported values | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 ++++++++++--- | ||||
|  1 file changed, 10 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -6036,11 +6036,18 @@ static int brcmf_construct_chaninfo(stru | ||||
|  		/* assuming the chanspecs order is HT20, | ||||
|  		 * HT40 upper, HT40 lower, and VHT80. | ||||
|  		 */ | ||||
| -		if (ch.bw == BRCMU_CHAN_BW_80) { | ||||
| +		switch (ch.bw) { | ||||
| +		case BRCMU_CHAN_BW_80: | ||||
|  			channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; | ||||
| -		} else if (ch.bw == BRCMU_CHAN_BW_40) { | ||||
| +			break; | ||||
| +		case BRCMU_CHAN_BW_40: | ||||
|  			brcmf_update_bw40_channel_flag(channel, &ch); | ||||
| -		} else { | ||||
| +			break; | ||||
| +		default: | ||||
| +			wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n", | ||||
| +				   ch.bw); | ||||
| +			/* fall through */ | ||||
| +		case BRCMU_CHAN_BW_20: | ||||
|  			/* enable the channel and disable other bandwidths | ||||
|  			 * for now as mentioned order assure they are enabled | ||||
|  			 * for subsequent chanspecs. | ||||
| @@ -0,0 +1,30 @@ | ||||
| From 30519cbe339a45bd11a57ca8ece07f4f6a1cda2e Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 11 Feb 2019 23:04:54 +0100 | ||||
| Subject: [PATCH] brcmfmac: support firmware reporting 160 MHz channels | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| So far 160 MHz channels were treated as 20 MHz ones which was breaking | ||||
| support for 40/80 MHz due to the brcmf_construct_chaninfo() logic and | ||||
| its assumptions. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++ | ||||
|  1 file changed, 3 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -6037,6 +6037,9 @@ static int brcmf_construct_chaninfo(stru | ||||
|  		 * HT40 upper, HT40 lower, and VHT80. | ||||
|  		 */ | ||||
|  		switch (ch.bw) { | ||||
| +		case BRCMU_CHAN_BW_160: | ||||
| +			channel->flags &= ~IEEE80211_CHAN_NO_160MHZ; | ||||
| +			break; | ||||
|  		case BRCMU_CHAN_BW_80: | ||||
|  			channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; | ||||
|  			break; | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,38 @@ | ||||
| From e0a8ef4d7b4315bc4c1641fb3f3a7dfdfa6627b8 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Wed, 20 Feb 2019 11:30:47 +0100 | ||||
| Subject: [PATCH] brcmfmac: add basic validation of shared RAM address | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| While experimenting with firmware loading I ended up in a state of | ||||
| firmware reporting shared RAM address 0x04000001. It was causing: | ||||
| [   94.448015] Unable to handle kernel paging request at virtual address cd680001 | ||||
| due to reading out of the mapped memory. | ||||
|  | ||||
| This patch adds some basic validation to avoid kernel crashes due to the | ||||
| unexpected firmware behavior. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -1560,6 +1560,12 @@ static int brcmf_pcie_download_fw_nvram( | ||||
|  		brcmf_err(bus, "FW failed to initialize\n"); | ||||
|  		return -ENODEV; | ||||
|  	} | ||||
| +	if (sharedram_addr < devinfo->ci->rambase || | ||||
| +	    sharedram_addr >= devinfo->ci->rambase + devinfo->ci->ramsize) { | ||||
| +		brcmf_err(bus, "Invalid shared RAM address 0x%08x\n", | ||||
| +			  sharedram_addr); | ||||
| +		return -ENODEV; | ||||
| +	} | ||||
|  	brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); | ||||
|   | ||||
|  	return (brcmf_pcie_init_share_ram_info(devinfo, sharedram_addr)); | ||||
| @@ -0,0 +1,29 @@ | ||||
| From 0c7051610c577b60b01b3b5aec14d6765e177b0d Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Thu, 21 Feb 2019 11:33:24 +0100 | ||||
| Subject: [PATCH] brcmfmac: fix size of the struct msgbuf_ring_status | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This updates host struct to match the in-firmawre definition. It's a | ||||
| cosmetic change as it only applies to the reserved struct space. | ||||
|  | ||||
| Fixes: c988b78244df ("brcmfmac: print firmware reported ring status errors") | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| @@ -139,7 +139,7 @@ struct msgbuf_ring_status { | ||||
|  	struct msgbuf_common_hdr	msg; | ||||
|  	struct msgbuf_completion_hdr	compl_hdr; | ||||
|  	__le16				write_idx; | ||||
| -	__le32				rsvd0[5]; | ||||
| +	__le16				rsvd0[5]; | ||||
|  }; | ||||
|   | ||||
|  struct msgbuf_rx_event { | ||||
| @@ -0,0 +1,69 @@ | ||||
| From c91377495192cda096e52dc09c266b0d05f16d86 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Thu, 21 Feb 2019 11:33:25 +0100 | ||||
| Subject: [PATCH] brcmfmac: print firmware reported general status errors | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Firmware may report general errors using a special message type. Add | ||||
| basic support for it by simply decoding & printing an error number. | ||||
|  | ||||
| A sample situation in which firmware reports a buf error: | ||||
| CONSOLE: 027084.733 no host response IOCTL buffer available..so fail the request | ||||
| will now produce a "Firmware reported general error: 9" on the host. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/msgbuf.c      | 24 +++++++++++++++++++ | ||||
|  1 file changed, 24 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| @@ -134,6 +134,14 @@ struct msgbuf_completion_hdr { | ||||
|  	__le16				flow_ring_id; | ||||
|  }; | ||||
|   | ||||
| +/* Data struct for the MSGBUF_TYPE_GEN_STATUS */ | ||||
| +struct msgbuf_gen_status { | ||||
| +	struct msgbuf_common_hdr	msg; | ||||
| +	struct msgbuf_completion_hdr	compl_hdr; | ||||
| +	__le16				write_idx; | ||||
| +	__le32				rsvd0[3]; | ||||
| +}; | ||||
| + | ||||
|  /* Data struct for the MSGBUF_TYPE_RING_STATUS */ | ||||
|  struct msgbuf_ring_status { | ||||
|  	struct msgbuf_common_hdr	msg; | ||||
| @@ -1194,6 +1202,18 @@ brcmf_msgbuf_process_rx_complete(struct | ||||
|  	brcmf_netif_rx(ifp, skb); | ||||
|  } | ||||
|   | ||||
| +static void brcmf_msgbuf_process_gen_status(struct brcmf_msgbuf *msgbuf, | ||||
| +					    void *buf) | ||||
| +{ | ||||
| +	struct msgbuf_gen_status *gen_status = buf; | ||||
| +	struct brcmf_pub *drvr = msgbuf->drvr; | ||||
| +	int err; | ||||
| + | ||||
| +	err = le16_to_cpu(gen_status->compl_hdr.status); | ||||
| +	if (err) | ||||
| +		bphy_err(drvr, "Firmware reported general error: %d\n", err); | ||||
| +} | ||||
| + | ||||
|  static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf, | ||||
|  					     void *buf) | ||||
|  { | ||||
| @@ -1273,6 +1293,10 @@ static void brcmf_msgbuf_process_msgtype | ||||
|   | ||||
|  	msg = (struct msgbuf_common_hdr *)buf; | ||||
|  	switch (msg->msgtype) { | ||||
| +	case MSGBUF_TYPE_GEN_STATUS: | ||||
| +		brcmf_dbg(MSGBUF, "MSGBUF_TYPE_GEN_STATUS\n"); | ||||
| +		brcmf_msgbuf_process_gen_status(msgbuf, buf); | ||||
| +		break; | ||||
|  	case MSGBUF_TYPE_RING_STATUS: | ||||
|  		brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n"); | ||||
|  		brcmf_msgbuf_process_ring_status(msgbuf, buf); | ||||
| @@ -0,0 +1,272 @@ | ||||
| From: Manikanta Pubbisetty <mpubbise@codeaurora.org> | ||||
| Date: Wed, 11 Jul 2018 00:12:53 +0530 | ||||
| Subject: [PATCH] mac80211: add stop/start logic for software TXQs | ||||
|  | ||||
| Sometimes, it is required to stop the transmissions momentarily and | ||||
| resume it later; stopping the txqs becomes very critical in scenarios where | ||||
| the packet transmission has to be ceased completely. For example, during | ||||
| the hardware restart, during off channel operations, | ||||
| when initiating CSA(upon detecting a radar on the DFS channel), etc. | ||||
|  | ||||
| The TX queue stop/start logic in mac80211 works well in stopping the TX | ||||
| when drivers make use of netdev queues, i.e, when Qdiscs in network layer | ||||
| take care of traffic scheduling. Since the devices implementing | ||||
| wake_tx_queue can run without Qdiscs, packets will be handed to mac80211 | ||||
| directly without queueing them in the netdev queues. | ||||
|  | ||||
| Also, mac80211 does not invoke any of the | ||||
| netif_stop_*/netif_wake_* APIs if wake_tx_queue is implemented. | ||||
| Since the queues are not stopped in this case, transmissions can continue | ||||
| and this will impact negatively on the operation of the wireless device. | ||||
|  | ||||
| For example, | ||||
| During hardware restart, we stop the netdev queues so that packets are | ||||
| not sent to the driver. Since ath10k implements wake_tx_queue, | ||||
| TX queues will not be stopped and packets might reach the hardware while | ||||
| it is restarting; this can make hardware unresponsive and the only | ||||
| possible option for recovery is to reboot the entire system. | ||||
|  | ||||
| There is another problem to this, it is observed that the packets | ||||
| were sent on the DFS channel for a prolonged duration after radar | ||||
| detection impacting the channel closing time. | ||||
|  | ||||
| We can still invoke netif stop/wake APIs when wake_tx_queue is implemented | ||||
| but this could lead to packet drops in network layer; adding stop/start | ||||
| logic for software TXQs in mac80211 instead makes more sense; the change | ||||
| proposed adds the same in mac80211. | ||||
|  | ||||
| Signed-off-by: Manikanta Pubbisetty <mpubbise@codeaurora.org> | ||||
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> | ||||
| --- | ||||
|  | ||||
| --- a/include/net/mac80211.h | ||||
| +++ b/include/net/mac80211.h | ||||
| @@ -1453,6 +1453,8 @@ enum ieee80211_vif_flags { | ||||
|   * @drv_priv: data area for driver use, will always be aligned to | ||||
|   *	sizeof(void \*). | ||||
|   * @txq: the multicast data TX queue (if driver uses the TXQ abstraction) | ||||
| + * @txqs_stopped: per AC flag to indicate that intermediate TXQs are stopped, | ||||
| + *	protected by fq->lock. | ||||
|   */ | ||||
|  struct ieee80211_vif { | ||||
|  	enum nl80211_iftype type; | ||||
| @@ -1477,6 +1479,8 @@ struct ieee80211_vif { | ||||
|   | ||||
|  	unsigned int probe_req_reg; | ||||
|   | ||||
| +	bool txqs_stopped[IEEE80211_NUM_ACS]; | ||||
| + | ||||
|  	/* must be last */ | ||||
|  	u8 drv_priv[0] __aligned(sizeof(void *)); | ||||
|  }; | ||||
| --- a/net/mac80211/ieee80211_i.h | ||||
| +++ b/net/mac80211/ieee80211_i.h | ||||
| @@ -816,6 +816,7 @@ enum txq_info_flags { | ||||
|  	IEEE80211_TXQ_STOP, | ||||
|  	IEEE80211_TXQ_AMPDU, | ||||
|  	IEEE80211_TXQ_NO_AMSDU, | ||||
| +	IEEE80211_TXQ_STOP_NETIF_TX, | ||||
|  }; | ||||
|   | ||||
|  /** | ||||
| @@ -1223,6 +1224,7 @@ struct ieee80211_local { | ||||
|   | ||||
|  	struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; | ||||
|  	struct tasklet_struct tx_pending_tasklet; | ||||
| +	struct tasklet_struct wake_txqs_tasklet; | ||||
|   | ||||
|  	atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES]; | ||||
|   | ||||
| @@ -2037,6 +2039,7 @@ void ieee80211_txq_purge(struct ieee8021 | ||||
|  			 struct txq_info *txqi); | ||||
|  void ieee80211_txq_remove_vlan(struct ieee80211_local *local, | ||||
|  			       struct ieee80211_sub_if_data *sdata); | ||||
| +void ieee80211_wake_txqs(unsigned long data); | ||||
|  void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | ||||
|  			 u16 transaction, u16 auth_alg, u16 status, | ||||
|  			 const u8 *extra, size_t extra_len, const u8 *bssid, | ||||
| --- a/net/mac80211/main.c | ||||
| +++ b/net/mac80211/main.c | ||||
| @@ -671,6 +671,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_ | ||||
|  	tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, | ||||
|  		     (unsigned long)local); | ||||
|   | ||||
| +	if (ops->wake_tx_queue) | ||||
| +		tasklet_init(&local->wake_txqs_tasklet, ieee80211_wake_txqs, | ||||
| +			     (unsigned long)local); | ||||
| + | ||||
|  	tasklet_init(&local->tasklet, | ||||
|  		     ieee80211_tasklet_handler, | ||||
|  		     (unsigned long) local); | ||||
| --- a/net/mac80211/tx.c | ||||
| +++ b/net/mac80211/tx.c | ||||
| @@ -3463,13 +3463,19 @@ struct sk_buff *ieee80211_tx_dequeue(str | ||||
|  	struct ieee80211_tx_info *info; | ||||
|  	struct ieee80211_tx_data tx; | ||||
|  	ieee80211_tx_result r; | ||||
| -	struct ieee80211_vif *vif; | ||||
| +	struct ieee80211_vif *vif = txq->vif; | ||||
|   | ||||
|  	spin_lock_bh(&fq->lock); | ||||
|   | ||||
| -	if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags)) | ||||
| +	if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) || | ||||
| +	    test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags)) | ||||
|  		goto out; | ||||
|   | ||||
| +	if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) { | ||||
| +		set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags); | ||||
| +		goto out; | ||||
| +	} | ||||
| + | ||||
|  	/* Make sure fragments stay together. */ | ||||
|  	skb = __skb_dequeue(&txqi->frags); | ||||
|  	if (skb) | ||||
| @@ -3565,6 +3571,7 @@ begin: | ||||
|  	} | ||||
|   | ||||
|  	IEEE80211_SKB_CB(skb)->control.vif = vif; | ||||
| + | ||||
|  out: | ||||
|  	spin_unlock_bh(&fq->lock); | ||||
|   | ||||
| --- a/net/mac80211/util.c | ||||
| +++ b/net/mac80211/util.c | ||||
| @@ -239,6 +239,99 @@ __le16 ieee80211_ctstoself_duration(stru | ||||
|  } | ||||
|  EXPORT_SYMBOL(ieee80211_ctstoself_duration); | ||||
|   | ||||
| +static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) | ||||
| +{ | ||||
| +	struct ieee80211_local *local = sdata->local; | ||||
| +	struct ieee80211_vif *vif = &sdata->vif; | ||||
| +	struct fq *fq = &local->fq; | ||||
| +	struct ps_data *ps = NULL; | ||||
| +	struct txq_info *txqi; | ||||
| +	struct sta_info *sta; | ||||
| +	int i; | ||||
| + | ||||
| +	spin_lock_bh(&fq->lock); | ||||
| + | ||||
| +	if (sdata->vif.type == NL80211_IFTYPE_AP) | ||||
| +		ps = &sdata->bss->ps; | ||||
| + | ||||
| +	sdata->vif.txqs_stopped[ac] = false; | ||||
| + | ||||
| +	list_for_each_entry_rcu(sta, &local->sta_list, list) { | ||||
| +		if (sdata != sta->sdata) | ||||
| +			continue; | ||||
| + | ||||
| +		for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { | ||||
| +			struct ieee80211_txq *txq = sta->sta.txq[i]; | ||||
| + | ||||
| +			txqi = to_txq_info(txq); | ||||
| + | ||||
| +			if (ac != txq->ac) | ||||
| +				continue; | ||||
| + | ||||
| +			if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, | ||||
| +						&txqi->flags)) | ||||
| +				continue; | ||||
| + | ||||
| +			spin_unlock_bh(&fq->lock); | ||||
| +			drv_wake_tx_queue(local, txqi); | ||||
| +			spin_lock_bh(&fq->lock); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	if (!vif->txq) | ||||
| +		goto out; | ||||
| + | ||||
| +	txqi = to_txq_info(vif->txq); | ||||
| + | ||||
| +	if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) || | ||||
| +	    (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac) | ||||
| +		goto out; | ||||
| + | ||||
| +	spin_unlock_bh(&fq->lock); | ||||
| + | ||||
| +	drv_wake_tx_queue(local, txqi); | ||||
| +	return; | ||||
| +out: | ||||
| +	spin_unlock_bh(&fq->lock); | ||||
| +} | ||||
| + | ||||
| +void ieee80211_wake_txqs(unsigned long data) | ||||
| +{ | ||||
| +	struct ieee80211_local *local = (struct ieee80211_local *)data; | ||||
| +	struct ieee80211_sub_if_data *sdata; | ||||
| +	int n_acs = IEEE80211_NUM_ACS; | ||||
| +	unsigned long flags; | ||||
| +	int i; | ||||
| + | ||||
| +	rcu_read_lock(); | ||||
| +	spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||||
| + | ||||
| +	if (local->hw.queues < IEEE80211_NUM_ACS) | ||||
| +		n_acs = 1; | ||||
| + | ||||
| +	for (i = 0; i < local->hw.queues; i++) { | ||||
| +		if (local->queue_stop_reasons[i]) | ||||
| +			continue; | ||||
| + | ||||
| +		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||||
| +		list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||||
| +			int ac; | ||||
| + | ||||
| +			for (ac = 0; ac < n_acs; ac++) { | ||||
| +				int ac_queue = sdata->vif.hw_queue[ac]; | ||||
| + | ||||
| +				if (ac_queue == i || | ||||
| +				    sdata->vif.cab_queue == i) | ||||
| +					__ieee80211_wake_txqs(sdata, ac); | ||||
| +			} | ||||
| +		} | ||||
| +		spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||||
| +	} | ||||
| + | ||||
| +	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||||
| +	rcu_read_unlock(); | ||||
| +} | ||||
| + | ||||
|  void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) | ||||
|  { | ||||
|  	struct ieee80211_sub_if_data *sdata; | ||||
| @@ -307,6 +400,9 @@ static void __ieee80211_wake_queue(struc | ||||
|  		rcu_read_unlock(); | ||||
|  	} else | ||||
|  		tasklet_schedule(&local->tx_pending_tasklet); | ||||
| + | ||||
| +	if (local->ops->wake_tx_queue) | ||||
| +		tasklet_schedule(&local->wake_txqs_tasklet); | ||||
|  } | ||||
|   | ||||
|  void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | ||||
| @@ -350,9 +446,6 @@ static void __ieee80211_stop_queue(struc | ||||
|  	if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue])) | ||||
|  		return; | ||||
|   | ||||
| -	if (local->ops->wake_tx_queue) | ||||
| -		return; | ||||
| - | ||||
|  	if (local->hw.queues < IEEE80211_NUM_ACS) | ||||
|  		n_acs = 1; | ||||
|   | ||||
| @@ -365,8 +458,15 @@ static void __ieee80211_stop_queue(struc | ||||
|   | ||||
|  		for (ac = 0; ac < n_acs; ac++) { | ||||
|  			if (sdata->vif.hw_queue[ac] == queue || | ||||
| -			    sdata->vif.cab_queue == queue) | ||||
| -				netif_stop_subqueue(sdata->dev, ac); | ||||
| +			    sdata->vif.cab_queue == queue) { | ||||
| +				if (!local->ops->wake_tx_queue) { | ||||
| +					netif_stop_subqueue(sdata->dev, ac); | ||||
| +					continue; | ||||
| +				} | ||||
| +				spin_lock(&local->fq.lock); | ||||
| +				sdata->vif.txqs_stopped[ac] = true; | ||||
| +				spin_unlock(&local->fq.lock); | ||||
| +			} | ||||
|  		} | ||||
|  	} | ||||
|  	rcu_read_unlock(); | ||||
| @@ -0,0 +1,33 @@ | ||||
| From: Felix Fietkau <nbd@nbd.name> | ||||
| Date: Fri, 1 Mar 2019 14:42:56 +0100 | ||||
| Subject: [PATCH] mac80211: do not call driver wake_tx_queue op during reconfig | ||||
|  | ||||
| There are several scenarios in which mac80211 can call drv_wake_tx_queue | ||||
| after ieee80211_restart_hw has been called and has not yet completed. | ||||
| Driver private structs are considered uninitialized until mac80211 has | ||||
| uploaded the vifs, stations and keys again, so using private tx queue | ||||
| data during that time is not safe. | ||||
|  | ||||
| The driver can also not rely on drv_reconfig_complete to figure out when | ||||
| it is safe to accept drv_wake_tx_queue calls again, because it is only | ||||
| called after all tx queues are woken again. | ||||
|  | ||||
| To fix this, bail out early in drv_wake_tx_queue if local->in_reconfig | ||||
| is set. | ||||
|  | ||||
| Cc: stable@vger.kernel.org | ||||
| Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
| --- | ||||
|  | ||||
| --- a/net/mac80211/driver-ops.h | ||||
| +++ b/net/mac80211/driver-ops.h | ||||
| @@ -1162,6 +1162,9 @@ static inline void drv_wake_tx_queue(str | ||||
|  { | ||||
|  	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); | ||||
|   | ||||
| +	if (local->in_reconfig) | ||||
| +		return; | ||||
| + | ||||
|  	if (!check_sdata_in_driver(sdata)) | ||||
|  		return; | ||||
|   | ||||
| @@ -0,0 +1,32 @@ | ||||
| From c9692820710f57c826b2e43a6fb1e4cd307508b0 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Tue, 26 Feb 2019 14:11:16 +0100 | ||||
| Subject: [PATCH] brcmfmac: support repeated brcmf_fw_alloc_request() calls | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| During a normal brcmfmac lifetime brcmf_fw_alloc_request() is called | ||||
| once only during the probe. It's safe to assume provided array is clear. | ||||
|  | ||||
| Further brcmfmac improvements may require calling it multiple times | ||||
| though. This patch allows it by fixing invalid firmware paths like: | ||||
| brcm/brcmfmac4366c-pcie.binbrcm/brcmfmac4366c-pcie.bin | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | ||||
| @@ -668,6 +668,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chi | ||||
|   | ||||
|  	for (j = 0; j < n_fwnames; j++) { | ||||
|  		fwreq->items[j].path = fwnames[j].path; | ||||
| +		fwnames[j].path[0] = '\0'; | ||||
|  		/* check if firmware path is provided by module parameter */ | ||||
|  		if (brcmf_mp_global.firmware_path[0] != '\0') { | ||||
|  			strlcpy(fwnames[j].path, mp_path, | ||||
| @@ -0,0 +1,79 @@ | ||||
| From a2ec87ddbf1637f854ffcfff9d12d392fa30758b Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Tue, 26 Feb 2019 14:11:18 +0100 | ||||
| Subject: [PATCH] brcmfmac: add a function designated for handling firmware | ||||
|  fails | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This improves handling PCIe firmware halts by printing a clear error | ||||
| message and replaces a similar code in the SDIO bus support. | ||||
|  | ||||
| It will also allow further improvements like trying to recover from a | ||||
| firmware crash. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  2 ++ | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/core.c    | 10 ++++++++++ | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/pcie.c    |  2 +- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c    |  4 ++-- | ||||
|  4 files changed, 15 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | ||||
| @@ -252,6 +252,8 @@ void brcmf_detach(struct device *dev); | ||||
|  void brcmf_dev_reset(struct device *dev); | ||||
|  /* Request from bus module to initiate a coredump */ | ||||
|  void brcmf_dev_coredump(struct device *dev); | ||||
| +/* Indication that firmware has halted or crashed */ | ||||
| +void brcmf_fw_crashed(struct device *dev); | ||||
|   | ||||
|  /* Configure the "global" bus state used by upper layers */ | ||||
|  void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1292,6 +1292,16 @@ void brcmf_dev_coredump(struct device *d | ||||
|  		brcmf_dbg(TRACE, "failed to create coredump\n"); | ||||
|  } | ||||
|   | ||||
| +void brcmf_fw_crashed(struct device *dev) | ||||
| +{ | ||||
| +	struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||||
| +	struct brcmf_pub *drvr = bus_if->drvr; | ||||
| + | ||||
| +	bphy_err(drvr, "Firmware has halted or crashed\n"); | ||||
| + | ||||
| +	brcmf_dev_coredump(dev); | ||||
| +} | ||||
| + | ||||
|  void brcmf_detach(struct device *dev) | ||||
|  { | ||||
|  	s32 i; | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -730,7 +730,7 @@ static void brcmf_pcie_handle_mb_data(st | ||||
|  	} | ||||
|  	if (dtoh_mb_data & BRCMF_D2H_DEV_FWHALT) { | ||||
|  		brcmf_dbg(PCIE, "D2H_MB_DATA: FW HALT\n"); | ||||
| -		brcmf_dev_coredump(&devinfo->pdev->dev); | ||||
| +		brcmf_fw_crashed(&devinfo->pdev->dev); | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | ||||
| @@ -1073,8 +1073,8 @@ static u32 brcmf_sdio_hostmail(struct br | ||||
|   | ||||
|  	/* dongle indicates the firmware has halted/crashed */ | ||||
|  	if (hmb_data & HMB_DATA_FWHALT) { | ||||
| -		brcmf_err("mailbox indicates firmware halted\n"); | ||||
| -		brcmf_dev_coredump(&sdiod->func1->dev); | ||||
| +		brcmf_dbg(SDIO, "mailbox indicates firmware halted\n"); | ||||
| +		brcmf_fw_crashed(&sdiod->func1->dev); | ||||
|  	} | ||||
|   | ||||
|  	/* Dongle recomposed rx frames, accept them again */ | ||||
| @@ -0,0 +1,153 @@ | ||||
| From 4684997d9eea29380000e062755aa6d368d789a3 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Tue, 26 Feb 2019 14:11:19 +0100 | ||||
| Subject: [PATCH] brcmfmac: reset PCIe bus on a firmware crash | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This includes bus reset & reloading a firmware. It should be sufficient | ||||
| for a user space to (setup and) use a wireless device again. | ||||
|  | ||||
| Support for reset on USB & SDIO can be added later. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/bus.h         | 10 ++++++ | ||||
|  .../broadcom/brcm80211/brcmfmac/core.c        | 12 +++++++ | ||||
|  .../broadcom/brcm80211/brcmfmac/core.h        |  2 ++ | ||||
|  .../broadcom/brcm80211/brcmfmac/pcie.c        | 35 +++++++++++++++++++ | ||||
|  4 files changed, 59 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | ||||
| @@ -90,6 +90,7 @@ struct brcmf_bus_ops { | ||||
|  	int (*get_memdump)(struct device *dev, void *data, size_t len); | ||||
|  	int (*get_fwname)(struct device *dev, const char *ext, | ||||
|  			  unsigned char *fw_name); | ||||
| +	int (*reset)(struct device *dev); | ||||
|  }; | ||||
|   | ||||
|   | ||||
| @@ -235,6 +236,15 @@ int brcmf_bus_get_fwname(struct brcmf_bu | ||||
|  	return bus->ops->get_fwname(bus->dev, ext, fw_name); | ||||
|  } | ||||
|   | ||||
| +static inline | ||||
| +int brcmf_bus_reset(struct brcmf_bus *bus) | ||||
| +{ | ||||
| +	if (!bus->ops->reset) | ||||
| +		return -EOPNOTSUPP; | ||||
| + | ||||
| +	return bus->ops->reset(bus->dev); | ||||
| +} | ||||
| + | ||||
|  /* | ||||
|   * interface functions from common layer | ||||
|   */ | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1104,6 +1104,14 @@ static int brcmf_revinfo_read(struct seq | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| +static void brcmf_core_bus_reset(struct work_struct *work) | ||||
| +{ | ||||
| +	struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, | ||||
| +					      bus_reset); | ||||
| + | ||||
| +	brcmf_bus_reset(drvr->bus_if); | ||||
| +} | ||||
| + | ||||
|  static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) | ||||
|  { | ||||
|  	int ret = -1; | ||||
| @@ -1175,6 +1183,8 @@ static int brcmf_bus_started(struct brcm | ||||
|  #endif | ||||
|  #endif /* CONFIG_INET */ | ||||
|   | ||||
| +	INIT_WORK(&drvr->bus_reset, brcmf_core_bus_reset); | ||||
| + | ||||
|  	/* populate debugfs */ | ||||
|  	brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); | ||||
|  	brcmf_feat_debugfs_create(drvr); | ||||
| @@ -1300,6 +1310,8 @@ void brcmf_fw_crashed(struct device *dev | ||||
|  	bphy_err(drvr, "Firmware has halted or crashed\n"); | ||||
|   | ||||
|  	brcmf_dev_coredump(dev); | ||||
| + | ||||
| +	schedule_work(&drvr->bus_reset); | ||||
|  } | ||||
|   | ||||
|  void brcmf_detach(struct device *dev) | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | ||||
| @@ -143,6 +143,8 @@ struct brcmf_pub { | ||||
|  	struct notifier_block inet6addr_notifier; | ||||
|  	struct brcmf_mp_device *settings; | ||||
|   | ||||
| +	struct work_struct bus_reset; | ||||
| + | ||||
|  	u8 clmver[BRCMF_DCMD_SMLEN]; | ||||
|  }; | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -345,6 +345,10 @@ static const u32 brcmf_ring_itemsize[BRC | ||||
|  	BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE | ||||
|  }; | ||||
|   | ||||
| +static void brcmf_pcie_setup(struct device *dev, int ret, | ||||
| +			     struct brcmf_fw_request *fwreq); | ||||
| +static struct brcmf_fw_request * | ||||
| +brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo); | ||||
|   | ||||
|  static u32 | ||||
|  brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) | ||||
| @@ -1409,6 +1413,36 @@ int brcmf_pcie_get_fwname(struct device | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| +static int brcmf_pcie_reset(struct device *dev) | ||||
| +{ | ||||
| +	struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||||
| +	struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; | ||||
| +	struct brcmf_pciedev_info *devinfo = buspub->devinfo; | ||||
| +	struct brcmf_fw_request *fwreq; | ||||
| +	int err; | ||||
| + | ||||
| +	brcmf_detach(dev); | ||||
| + | ||||
| +	brcmf_pcie_release_irq(devinfo); | ||||
| +	brcmf_pcie_release_scratchbuffers(devinfo); | ||||
| +	brcmf_pcie_release_ringbuffers(devinfo); | ||||
| +	brcmf_pcie_reset_device(devinfo); | ||||
| + | ||||
| +	fwreq = brcmf_pcie_prepare_fw_request(devinfo); | ||||
| +	if (!fwreq) { | ||||
| +		dev_err(dev, "Failed to prepare FW request\n"); | ||||
| +		return -ENOMEM; | ||||
| +	} | ||||
| + | ||||
| +	err = brcmf_fw_get_firmwares(dev, fwreq, brcmf_pcie_setup); | ||||
| +	if (err) { | ||||
| +		dev_err(dev, "Failed to prepare FW request\n"); | ||||
| +		kfree(fwreq); | ||||
| +	} | ||||
| + | ||||
| +	return err; | ||||
| +} | ||||
| + | ||||
|  static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { | ||||
|  	.txdata = brcmf_pcie_tx, | ||||
|  	.stop = brcmf_pcie_down, | ||||
| @@ -1418,6 +1452,7 @@ static const struct brcmf_bus_ops brcmf_ | ||||
|  	.get_ramsize = brcmf_pcie_get_ramsize, | ||||
|  	.get_memdump = brcmf_pcie_get_memdump, | ||||
|  	.get_fwname = brcmf_pcie_get_fwname, | ||||
| +	.reset = brcmf_pcie_reset, | ||||
|  }; | ||||
|   | ||||
|   | ||||
| @@ -0,0 +1,124 @@ | ||||
| From c80d26e81ef1802f30364b4ad1955c1443a592b9 Mon Sep 17 00:00:00 2001 | ||||
| From: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Date: Mon, 4 Mar 2019 15:42:49 +0000 | ||||
| Subject: [PATCH] brcmfmac: fix WARNING during USB disconnect in case of | ||||
|  unempty psq | ||||
|  | ||||
| brcmu_pkt_buf_free_skb emits WARNING when attempting to free a sk_buff | ||||
| which is part of any queue. After USB disconnect this may have happened | ||||
| when brcmf_fws_hanger_cleanup() is called as per-interface psq was never | ||||
| cleaned when removing the interface. | ||||
| Change brcmf_fws_macdesc_cleanup() in a way that it removes the | ||||
| corresponding packets from hanger table (to avoid double-free when | ||||
| brcmf_fws_hanger_cleanup() is called) and add a call to clean-up the | ||||
| interface specific packet queue. | ||||
|  | ||||
| Below is a WARNING during USB disconnect with Raspberry Pi WiFi dongle | ||||
| running in AP mode. This was reproducible when the interface was | ||||
| transmitting during the disconnect and is fixed with this commit. | ||||
|  | ||||
| ------------[ cut here ]------------ | ||||
| WARNING: CPU: 0 PID: 1171 at drivers/net/wireless/broadcom/brcm80211/brcmutil/utils.c:49 brcmu_pkt_buf_free_skb+0x3c/0x40 | ||||
| Modules linked in: nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc ulpi usbmisc_imx 8250_exar 8250_pci 8250 8250_base libcomposite configfs udc_core | ||||
| CPU: 0 PID: 1171 Comm: kworker/0:0 Not tainted 4.19.23-00075-gde33ed8 #99 | ||||
| Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) | ||||
| Workqueue: usb_hub_wq hub_event | ||||
| [<8010ff84>] (unwind_backtrace) from [<8010bb64>] (show_stack+0x10/0x14) | ||||
| [<8010bb64>] (show_stack) from [<80840278>] (dump_stack+0x88/0x9c) | ||||
| [<80840278>] (dump_stack) from [<8011f5ec>] (__warn+0xfc/0x114) | ||||
| [<8011f5ec>] (__warn) from [<8011f71c>] (warn_slowpath_null+0x40/0x48) | ||||
| [<8011f71c>] (warn_slowpath_null) from [<805a476c>] (brcmu_pkt_buf_free_skb+0x3c/0x40) | ||||
| [<805a476c>] (brcmu_pkt_buf_free_skb) from [<805bb6c4>] (brcmf_fws_cleanup+0x1e4/0x22c) | ||||
| [<805bb6c4>] (brcmf_fws_cleanup) from [<805bc854>] (brcmf_fws_del_interface+0x58/0x68) | ||||
| [<805bc854>] (brcmf_fws_del_interface) from [<805b66ac>] (brcmf_remove_interface+0x40/0x150) | ||||
| [<805b66ac>] (brcmf_remove_interface) from [<805b6870>] (brcmf_detach+0x6c/0xb0) | ||||
| [<805b6870>] (brcmf_detach) from [<805bdbb8>] (brcmf_usb_disconnect+0x30/0x4c) | ||||
| [<805bdbb8>] (brcmf_usb_disconnect) from [<805e5d64>] (usb_unbind_interface+0x5c/0x1e0) | ||||
| [<805e5d64>] (usb_unbind_interface) from [<804aab10>] (device_release_driver_internal+0x154/0x1ec) | ||||
| [<804aab10>] (device_release_driver_internal) from [<804a97f4>] (bus_remove_device+0xcc/0xf8) | ||||
| [<804a97f4>] (bus_remove_device) from [<804a6fc0>] (device_del+0x118/0x308) | ||||
| [<804a6fc0>] (device_del) from [<805e488c>] (usb_disable_device+0xa0/0x1c8) | ||||
| [<805e488c>] (usb_disable_device) from [<805dcf98>] (usb_disconnect+0x70/0x1d8) | ||||
| [<805dcf98>] (usb_disconnect) from [<805ddd84>] (hub_event+0x464/0xf50) | ||||
| [<805ddd84>] (hub_event) from [<80135a70>] (process_one_work+0x138/0x3f8) | ||||
| [<80135a70>] (process_one_work) from [<80135d5c>] (worker_thread+0x2c/0x554) | ||||
| [<80135d5c>] (worker_thread) from [<8013b1a0>] (kthread+0x124/0x154) | ||||
| [<8013b1a0>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c) | ||||
| Exception stack(0xecf8dfb0 to 0xecf8dff8) | ||||
| dfa0:                                     00000000 00000000 00000000 00000000 | ||||
| dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | ||||
| dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 | ||||
| ---[ end trace 38d234018e9e2a90 ]--- | ||||
| ------------[ cut here ]------------ | ||||
|  | ||||
| Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/fwsignal.c    | 42 +++++++++++-------- | ||||
|  1 file changed, 24 insertions(+), 18 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||
| @@ -579,24 +579,6 @@ static bool brcmf_fws_ifidx_match(struct | ||||
|  	return ifidx == *(int *)arg; | ||||
|  } | ||||
|   | ||||
| -static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q, | ||||
| -				int ifidx) | ||||
| -{ | ||||
| -	bool (*matchfn)(struct sk_buff *, void *) = NULL; | ||||
| -	struct sk_buff *skb; | ||||
| -	int prec; | ||||
| - | ||||
| -	if (ifidx != -1) | ||||
| -		matchfn = brcmf_fws_ifidx_match; | ||||
| -	for (prec = 0; prec < q->num_prec; prec++) { | ||||
| -		skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); | ||||
| -		while (skb) { | ||||
| -			brcmu_pkt_buf_free_skb(skb); | ||||
| -			skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); | ||||
| -		} | ||||
| -	} | ||||
| -} | ||||
| - | ||||
|  static void brcmf_fws_hanger_init(struct brcmf_fws_hanger *hanger) | ||||
|  { | ||||
|  	int i; | ||||
| @@ -668,6 +650,28 @@ static inline int brcmf_fws_hanger_poppk | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| +static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q, | ||||
| +				int ifidx) | ||||
| +{ | ||||
| +	bool (*matchfn)(struct sk_buff *, void *) = NULL; | ||||
| +	struct sk_buff *skb; | ||||
| +	int prec; | ||||
| +	u32 hslot; | ||||
| + | ||||
| +	if (ifidx != -1) | ||||
| +		matchfn = brcmf_fws_ifidx_match; | ||||
| +	for (prec = 0; prec < q->num_prec; prec++) { | ||||
| +		skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); | ||||
| +		while (skb) { | ||||
| +			hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); | ||||
| +			brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, | ||||
| +						true); | ||||
| +			brcmu_pkt_buf_free_skb(skb); | ||||
| +			skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); | ||||
| +		} | ||||
| +	} | ||||
| +} | ||||
| + | ||||
|  static int brcmf_fws_hanger_mark_suppressed(struct brcmf_fws_hanger *h, | ||||
|  					    u32 slot_id) | ||||
|  { | ||||
| @@ -2174,6 +2178,8 @@ void brcmf_fws_del_interface(struct brcm | ||||
|  	brcmf_fws_lock(fws); | ||||
|  	ifp->fws_desc = NULL; | ||||
|  	brcmf_dbg(TRACE, "deleting %s\n", entry->name); | ||||
| +	brcmf_fws_macdesc_cleanup(fws, &fws->desc.iface[ifp->ifidx], | ||||
| +				  ifp->ifidx); | ||||
|  	brcmf_fws_macdesc_deinit(entry); | ||||
|  	brcmf_fws_cleanup(fws, ifp->ifidx); | ||||
|  	brcmf_fws_unlock(fws); | ||||
| @@ -0,0 +1,217 @@ | ||||
| From 5cdb0ef6144f47440850553579aa923c20a63f23 Mon Sep 17 00:00:00 2001 | ||||
| From: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Date: Mon, 4 Mar 2019 15:42:52 +0000 | ||||
| Subject: [PATCH] brcmfmac: fix NULL pointer derefence during USB disconnect | ||||
|  | ||||
| In case USB disconnect happens at the moment transmitting workqueue is in | ||||
| progress the underlying interface may be gone causing a NULL pointer | ||||
| dereference. Add synchronization of the workqueue destruction with the | ||||
| detach implementation in core so that the transmitting workqueue is stopped | ||||
| during detach before the interfaces are removed. | ||||
|  | ||||
| Fix following Oops: | ||||
|  | ||||
| Unable to handle kernel NULL pointer dereference at virtual address 00000008 | ||||
| pgd = 9e6a802d | ||||
| [00000008] *pgd=00000000 | ||||
| Internal error: Oops: 5 [#1] PREEMPT SMP ARM | ||||
| Modules linked in: nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle | ||||
| xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 | ||||
| iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether | ||||
| usb_serial_simple usbserial cdc_acm brcmfmac brcmutil smsc95xx usbnet | ||||
| ci_hdrc_imx ci_hdrc ulpi usbmisc_imx 8250_exar 8250_pci 8250 8250_base | ||||
| libcomposite configfs udc_core | ||||
| CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted 4.19.23-00076-g03740aa-dirty #102 | ||||
| Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) | ||||
| Workqueue: brcmf_fws_wq brcmf_fws_dequeue_worker [brcmfmac] | ||||
| PC is at brcmf_txfinalize+0x34/0x90 [brcmfmac] | ||||
| LR is at brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac] | ||||
| pc : [<7f0dee64>]    lr : [<7f0e4140>]    psr: 60010093 | ||||
| sp : ee8abef0  ip : 00000000  fp : edf38000 | ||||
| r10: ffffffed  r9 : edf38970  r8 : edf38004 | ||||
| r7 : edf3e970  r6 : 00000000  r5 : ede69000  r4 : 00000000 | ||||
| r3 : 00000a97  r2 : 00000000  r1 : 0000888e  r0 : ede69000 | ||||
| Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none | ||||
| Control: 10c5387d  Table: 7d03c04a  DAC: 00000051 | ||||
| Process kworker/u8:0 (pid: 7, stack limit = 0x24ec3e04) | ||||
| Stack: (0xee8abef0 to 0xee8ac000) | ||||
| bee0:                                     ede69000 00000000 ed56c3e0 7f0e4140 | ||||
| bf00: 00000001 00000000 edf38004 edf3e99c ed56c3e0 80d03d00 edfea43a edf3e970 | ||||
| bf20: ee809880 ee804200 ee971100 00000000 edf3e974 00000000 ee804200 80135a70 | ||||
| bf40: 80d03d00 ee804218 ee809880 ee809894 ee804200 80d03d00 ee804218 ee8aa000 | ||||
| bf60: 00000088 80135d5c 00000000 ee829f00 ee829dc0 00000000 ee809880 80135d30 | ||||
| bf80: ee829f1c ee873eac 00000000 8013b1a0 ee829dc0 8013b07c 00000000 00000000 | ||||
| bfa0: 00000000 00000000 00000000 801010e8 00000000 00000000 00000000 00000000 | ||||
| bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | ||||
| bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 | ||||
| [<7f0dee64>] (brcmf_txfinalize [brcmfmac]) from [<7f0e4140>] (brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac]) | ||||
| [<7f0e4140>] (brcmf_fws_dequeue_worker [brcmfmac]) from [<80135a70>] (process_one_work+0x138/0x3f8) | ||||
| [<80135a70>] (process_one_work) from [<80135d5c>] (worker_thread+0x2c/0x554) | ||||
| [<80135d5c>] (worker_thread) from [<8013b1a0>] (kthread+0x124/0x154) | ||||
| [<8013b1a0>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c) | ||||
| Exception stack(0xee8abfb0 to 0xee8abff8) | ||||
| bfa0:                                     00000000 00000000 00000000 00000000 | ||||
| bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 | ||||
| bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 | ||||
| Code: e1530001 0a000007 e3560000 e1a00005 (05942008) | ||||
| ---[ end trace 079239dd31c86e90 ]--- | ||||
|  | ||||
| Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c  | 11 +++++++++-- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcdc.h  |  6 ++++-- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c  |  4 +++- | ||||
|  .../broadcom/brcm80211/brcmfmac/fwsignal.c       | 16 ++++++++++++---- | ||||
|  .../broadcom/brcm80211/brcmfmac/fwsignal.h       |  3 ++- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/proto.c | 10 ++++++++-- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/proto.h |  3 ++- | ||||
|  7 files changed, 40 insertions(+), 13 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | ||||
| @@ -490,11 +490,18 @@ fail: | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
|   | ||||
| -void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) | ||||
| +void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) | ||||
| +{ | ||||
| +	struct brcmf_bcdc *bcdc = drvr->proto->pd; | ||||
| + | ||||
| +	brcmf_fws_detach_pre_delif(bcdc->fws); | ||||
| +} | ||||
| + | ||||
| +void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) | ||||
|  { | ||||
|  	struct brcmf_bcdc *bcdc = drvr->proto->pd; | ||||
|   | ||||
|  	drvr->proto->pd = NULL; | ||||
| -	brcmf_fws_detach(bcdc->fws); | ||||
| +	brcmf_fws_detach_post_delif(bcdc->fws); | ||||
|  	kfree(bcdc); | ||||
|  } | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | ||||
| @@ -18,14 +18,16 @@ | ||||
|   | ||||
|  #ifdef CPTCFG_BRCMFMAC_PROTO_BCDC | ||||
|  int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); | ||||
| -void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); | ||||
| +void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr); | ||||
| +void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr); | ||||
|  void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state); | ||||
|  void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp, | ||||
|  				 bool success); | ||||
|  struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr); | ||||
|  #else | ||||
|  static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; } | ||||
| -static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {} | ||||
| +static void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) {}; | ||||
| +static inline void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) {} | ||||
|  #endif | ||||
|   | ||||
|  #endif /* BRCMFMAC_BCDC_H */ | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1340,6 +1340,8 @@ void brcmf_detach(struct device *dev) | ||||
|   | ||||
|  	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); | ||||
|   | ||||
| +	brcmf_proto_detach_pre_delif(drvr); | ||||
| + | ||||
|  	/* make sure primary interface removed last */ | ||||
|  	for (i = BRCMF_MAX_IFS-1; i > -1; i--) | ||||
|  		brcmf_remove_interface(drvr->iflist[i], false); | ||||
| @@ -1349,7 +1351,7 @@ void brcmf_detach(struct device *dev) | ||||
|   | ||||
|  	brcmf_bus_stop(drvr->bus_if); | ||||
|   | ||||
| -	brcmf_proto_detach(drvr); | ||||
| +	brcmf_proto_detach_post_delif(drvr); | ||||
|   | ||||
|  	bus_if->drvr = NULL; | ||||
|  	wiphy_free(drvr->wiphy); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||
| @@ -2416,17 +2416,25 @@ struct brcmf_fws_info *brcmf_fws_attach( | ||||
|  	return fws; | ||||
|   | ||||
|  fail: | ||||
| -	brcmf_fws_detach(fws); | ||||
| +	brcmf_fws_detach_pre_delif(fws); | ||||
| +	brcmf_fws_detach_post_delif(fws); | ||||
|  	return ERR_PTR(rc); | ||||
|  } | ||||
|   | ||||
| -void brcmf_fws_detach(struct brcmf_fws_info *fws) | ||||
| +void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws) | ||||
|  { | ||||
|  	if (!fws) | ||||
|  		return; | ||||
| - | ||||
| -	if (fws->fws_wq) | ||||
| +	if (fws->fws_wq) { | ||||
|  		destroy_workqueue(fws->fws_wq); | ||||
| +		fws->fws_wq = NULL; | ||||
| +	} | ||||
| +} | ||||
| + | ||||
| +void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws) | ||||
| +{ | ||||
| +	if (!fws) | ||||
| +		return; | ||||
|   | ||||
|  	/* cleanup */ | ||||
|  	brcmf_fws_lock(fws); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | ||||
| @@ -19,7 +19,8 @@ | ||||
|  #define FWSIGNAL_H_ | ||||
|   | ||||
|  struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); | ||||
| -void brcmf_fws_detach(struct brcmf_fws_info *fws); | ||||
| +void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws); | ||||
| +void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws); | ||||
|  void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); | ||||
|  bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); | ||||
|  bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | ||||
| @@ -67,16 +67,22 @@ fail: | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
|   | ||||
| -void brcmf_proto_detach(struct brcmf_pub *drvr) | ||||
| +void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr) | ||||
|  { | ||||
|  	brcmf_dbg(TRACE, "Enter\n"); | ||||
|   | ||||
|  	if (drvr->proto) { | ||||
|  		if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) | ||||
| -			brcmf_proto_bcdc_detach(drvr); | ||||
| +			brcmf_proto_bcdc_detach_post_delif(drvr); | ||||
|  		else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) | ||||
|  			brcmf_proto_msgbuf_detach(drvr); | ||||
|  		kfree(drvr->proto); | ||||
|  		drvr->proto = NULL; | ||||
|  	} | ||||
|  } | ||||
| + | ||||
| +void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr) | ||||
| +{ | ||||
| +	if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) | ||||
| +		brcmf_proto_bcdc_detach_pre_delif(drvr); | ||||
| +} | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | ||||
| @@ -54,7 +54,8 @@ struct brcmf_proto { | ||||
|   | ||||
|   | ||||
|  int brcmf_proto_attach(struct brcmf_pub *drvr); | ||||
| -void brcmf_proto_detach(struct brcmf_pub *drvr); | ||||
| +void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr); | ||||
| +void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr); | ||||
|   | ||||
|  static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, | ||||
|  				      struct sk_buff *skb, | ||||
| @@ -0,0 +1,84 @@ | ||||
| From db3b9e2e1d58080d0754bdf9293dabf8c6491b67 Mon Sep 17 00:00:00 2001 | ||||
| From: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Date: Fri, 8 Mar 2019 15:25:04 +0000 | ||||
| Subject: [PATCH] brcmfmac: fix race during disconnect when USB completion is | ||||
|  in progress | ||||
|  | ||||
| It was observed that rarely during USB disconnect happening shortly after | ||||
| connect (before full initialization completes) usb_hub_wq would wait | ||||
| forever for the dev_init_lock to be unlocked. dev_init_lock would remain | ||||
| locked though because of infinite wait during usb_kill_urb: | ||||
|  | ||||
| [ 2730.656472] kworker/0:2     D    0   260      2 0x00000000 | ||||
| [ 2730.660700] Workqueue: events request_firmware_work_func | ||||
| [ 2730.664807] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) | ||||
| [ 2730.670587] [<809dd164>] (schedule) from [<8069af44>] (usb_kill_urb+0xdc/0x114) | ||||
| [ 2730.676815] [<8069af44>] (usb_kill_urb) from [<7f258b50>] (brcmf_usb_free_q+0x34/0xa8 [brcmfmac]) | ||||
| [ 2730.684833] [<7f258b50>] (brcmf_usb_free_q [brcmfmac]) from [<7f2517d4>] (brcmf_detach+0xa0/0xb8 [brcmfmac]) | ||||
| [ 2730.693557] [<7f2517d4>] (brcmf_detach [brcmfmac]) from [<7f251a34>] (brcmf_attach+0xac/0x3d8 [brcmfmac]) | ||||
| [ 2730.702094] [<7f251a34>] (brcmf_attach [brcmfmac]) from [<7f2587ac>] (brcmf_usb_probe_phase2+0x468/0x4a0 [brcmfmac]) | ||||
| [ 2730.711601] [<7f2587ac>] (brcmf_usb_probe_phase2 [brcmfmac]) from [<7f252888>] (brcmf_fw_request_done+0x194/0x220 [brcmfmac]) | ||||
| [ 2730.721795] [<7f252888>] (brcmf_fw_request_done [brcmfmac]) from [<805748e4>] (request_firmware_work_func+0x4c/0x88) | ||||
| [ 2730.731125] [<805748e4>] (request_firmware_work_func) from [<80141474>] (process_one_work+0x228/0x808) | ||||
| [ 2730.739223] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) | ||||
| [ 2730.746105] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) | ||||
| [ 2730.752227] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) | ||||
|  | ||||
| [ 2733.099695] kworker/0:3     D    0  1065      2 0x00000000 | ||||
| [ 2733.103926] Workqueue: usb_hub_wq hub_event | ||||
| [ 2733.106914] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) | ||||
| [ 2733.112693] [<809dd164>] (schedule) from [<809e2a8c>] (schedule_timeout+0x214/0x3e4) | ||||
| [ 2733.119621] [<809e2a8c>] (schedule_timeout) from [<809dde2c>] (wait_for_common+0xc4/0x1c0) | ||||
| [ 2733.126810] [<809dde2c>] (wait_for_common) from [<7f258d00>] (brcmf_usb_disconnect+0x1c/0x4c [brcmfmac]) | ||||
| [ 2733.135206] [<7f258d00>] (brcmf_usb_disconnect [brcmfmac]) from [<8069e0c8>] (usb_unbind_interface+0x5c/0x1e4) | ||||
| [ 2733.143943] [<8069e0c8>] (usb_unbind_interface) from [<8056d3e8>] (device_release_driver_internal+0x164/0x1fc) | ||||
| [ 2733.152769] [<8056d3e8>] (device_release_driver_internal) from [<8056c078>] (bus_remove_device+0xd0/0xfc) | ||||
| [ 2733.161138] [<8056c078>] (bus_remove_device) from [<8056977c>] (device_del+0x11c/0x310) | ||||
| [ 2733.167939] [<8056977c>] (device_del) from [<8069cba8>] (usb_disable_device+0xa0/0x1cc) | ||||
| [ 2733.174743] [<8069cba8>] (usb_disable_device) from [<8069507c>] (usb_disconnect+0x74/0x1dc) | ||||
| [ 2733.181823] [<8069507c>] (usb_disconnect) from [<80695e88>] (hub_event+0x478/0xf88) | ||||
| [ 2733.188278] [<80695e88>] (hub_event) from [<80141474>] (process_one_work+0x228/0x808) | ||||
| [ 2733.194905] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) | ||||
| [ 2733.201724] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) | ||||
| [ 2733.207913] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) | ||||
|  | ||||
| It was traced down to a case where usb_kill_urb would be called on an URB | ||||
| structure containing more or less random data, including large number in | ||||
| its use_count. During the debugging it appeared that in brcmf_usb_free_q() | ||||
| the traversal over URBs' lists is not synchronized with operations on those | ||||
| lists in brcmf_usb_rx_complete() leading to handling | ||||
| brcmf_usbdev_info structure (holding lists' head) as lists' element and in | ||||
| result causing above problem. | ||||
|  | ||||
| Fix it by walking through all URBs during brcmf_cancel_all_urbs using the | ||||
| arrays of requests instead of linked lists. | ||||
|  | ||||
| Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 10 ++++++++-- | ||||
|  1 file changed, 8 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| @@ -684,12 +684,18 @@ static int brcmf_usb_up(struct device *d | ||||
|   | ||||
|  static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo) | ||||
|  { | ||||
| +	int i; | ||||
| + | ||||
|  	if (devinfo->ctl_urb) | ||||
|  		usb_kill_urb(devinfo->ctl_urb); | ||||
|  	if (devinfo->bulk_urb) | ||||
|  		usb_kill_urb(devinfo->bulk_urb); | ||||
| -	brcmf_usb_free_q(&devinfo->tx_postq, true); | ||||
| -	brcmf_usb_free_q(&devinfo->rx_postq, true); | ||||
| +	if (devinfo->tx_reqs) | ||||
| +		for (i = 0; i < devinfo->bus_pub.ntxq; i++) | ||||
| +			usb_kill_urb(devinfo->tx_reqs[i].urb); | ||||
| +	if (devinfo->rx_reqs) | ||||
| +		for (i = 0; i < devinfo->bus_pub.nrxq; i++) | ||||
| +			usb_kill_urb(devinfo->rx_reqs[i].urb); | ||||
|  } | ||||
|   | ||||
|  static void brcmf_usb_down(struct device *dev) | ||||
| @@ -0,0 +1,54 @@ | ||||
| From 2b78e5f5223666d403d4fdb30af4ad65c8da3cdb Mon Sep 17 00:00:00 2001 | ||||
| From: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Date: Fri, 8 Mar 2019 15:25:06 +0000 | ||||
| Subject: [PATCH] brcmfmac: remove pending parameter from brcmf_usb_free_q | ||||
|  | ||||
| brcmf_usb_free_q is no longer called with pending=true thus this boolean | ||||
| parameter is no longer needed. | ||||
|  | ||||
| Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/usb.c    | 15 ++++++--------- | ||||
|  1 file changed, 6 insertions(+), 9 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| @@ -445,9 +445,10 @@ fail: | ||||
|   | ||||
|  } | ||||
|   | ||||
| -static void brcmf_usb_free_q(struct list_head *q, bool pending) | ||||
| +static void brcmf_usb_free_q(struct list_head *q) | ||||
|  { | ||||
|  	struct brcmf_usbreq *req, *next; | ||||
| + | ||||
|  	int i = 0; | ||||
|  	list_for_each_entry_safe(req, next, q, list) { | ||||
|  		if (!req->urb) { | ||||
| @@ -455,12 +456,8 @@ static void brcmf_usb_free_q(struct list | ||||
|  			break; | ||||
|  		} | ||||
|  		i++; | ||||
| -		if (pending) { | ||||
| -			usb_kill_urb(req->urb); | ||||
| -		} else { | ||||
| -			usb_free_urb(req->urb); | ||||
| -			list_del_init(&req->list); | ||||
| -		} | ||||
| +		usb_free_urb(req->urb); | ||||
| +		list_del_init(&req->list); | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| @@ -1031,8 +1028,8 @@ static void brcmf_usb_detach(struct brcm | ||||
|  	brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo); | ||||
|   | ||||
|  	/* free the URBS */ | ||||
| -	brcmf_usb_free_q(&devinfo->rx_freeq, false); | ||||
| -	brcmf_usb_free_q(&devinfo->tx_freeq, false); | ||||
| +	brcmf_usb_free_q(&devinfo->rx_freeq); | ||||
| +	brcmf_usb_free_q(&devinfo->tx_freeq); | ||||
|   | ||||
|  	usb_free_urb(devinfo->ctl_urb); | ||||
|  	usb_free_urb(devinfo->bulk_urb); | ||||
| @@ -0,0 +1,29 @@ | ||||
| From 504f06725d015954a0fcafdf1d90a6795ca8f769 Mon Sep 17 00:00:00 2001 | ||||
| From: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Date: Fri, 8 Mar 2019 15:25:09 +0000 | ||||
| Subject: [PATCH] brcmfmac: remove unused variable i from brcmf_usb_free_q | ||||
|  | ||||
| Variable i is not used so remove it. | ||||
|  | ||||
| Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 2 -- | ||||
|  1 file changed, 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| @@ -449,13 +449,11 @@ static void brcmf_usb_free_q(struct list | ||||
|  { | ||||
|  	struct brcmf_usbreq *req, *next; | ||||
|   | ||||
| -	int i = 0; | ||||
|  	list_for_each_entry_safe(req, next, q, list) { | ||||
|  		if (!req->urb) { | ||||
|  			brcmf_err("bad req\n"); | ||||
|  			break; | ||||
|  		} | ||||
| -		i++; | ||||
|  		usb_free_urb(req->urb); | ||||
|  		list_del_init(&req->list); | ||||
|  	} | ||||
| @@ -0,0 +1,123 @@ | ||||
| From 24d413a31afaee9bbbf79226052c386b01780ce2 Mon Sep 17 00:00:00 2001 | ||||
| From: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Date: Wed, 13 Mar 2019 09:52:01 +0000 | ||||
| Subject: [PATCH] brcmfmac: fix Oops when bringing up interface during USB | ||||
|  disconnect | ||||
|  | ||||
| Fix a race which leads to an Oops with NULL pointer dereference.  The | ||||
| dereference is in brcmf_config_dongle() when cfg_to_ndev() attempts to get | ||||
| net_device structure of interface with index 0 via if2bss mapping. This | ||||
| shouldn't fail because of check for bus being ready in brcmf_netdev_open(), | ||||
| but it's not synchronised with USB disconnect and there is a race: after | ||||
| the check the bus can be marked down and the mapping for interface 0 may be | ||||
| gone. | ||||
|  | ||||
| Solve this by modifying disconnect handling so that the removal of mapping | ||||
| of ifidx to brcmf_if structure happens after netdev removal (which is | ||||
| synchronous with brcmf_netdev_open() thanks to rtln being locked in | ||||
| devinet_ioctl()). This assures brcmf_netdev_open() returns before the | ||||
| mapping is removed during disconnect. | ||||
|  | ||||
| Unable to handle kernel NULL pointer dereference at virtual address 00000008 | ||||
| pgd = bcae2612 | ||||
| [00000008] *pgd=8be73831 | ||||
| Internal error: Oops: 17 [#1] PREEMPT SMP ARM | ||||
| Modules linked in: brcmfmac brcmutil nf_log_ipv4 nf_log_common xt_LOG xt_limit | ||||
| iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 | ||||
| nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis | ||||
| u_ether usb_serial_simple usbserial cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc | ||||
| usbmisc_imx ulpi 8250_exar 8250_pci 8250 8250_base libcomposite configfs | ||||
| udc_core [last unloaded: brcmutil] | ||||
| CPU: 2 PID: 24478 Comm: ifconfig Not tainted 4.19.23-00078-ga62866d-dirty #115 | ||||
| Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) | ||||
| PC is at brcmf_cfg80211_up+0x94/0x29c [brcmfmac] | ||||
| LR is at brcmf_cfg80211_up+0x8c/0x29c [brcmfmac] | ||||
| pc : [<7f26a91c>]    lr : [<7f26a914>]    psr: a0070013 | ||||
| sp : eca99d28  ip : 00000000  fp : ee9c6c00 | ||||
| r10: 00000036  r9 : 00000000  r8 : ece4002c | ||||
| r7 : edb5b800  r6 : 00000000  r5 : 80f08448  r4 : edb5b968 | ||||
| r3 : ffffffff  r2 : 00000000  r1 : 00000002  r0 : 00000000 | ||||
| Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none | ||||
| Control: 10c5387d  Table: 7ca0c04a  DAC: 00000051 | ||||
| Process ifconfig (pid: 24478, stack limit = 0xd9e85a0e) | ||||
| Stack: (0xeca99d28 to 0xeca9a000) | ||||
| 9d20:                   00000000 80f873b0 0000000d 80f08448 eca99d68 50d45f32 | ||||
| 9d40: 7f27de94 ece40000 80f08448 80f08448 7f27de94 ece4002c 00000000 00000036 | ||||
| 9d60: ee9c6c00 7f27262c 00001002 50d45f32 ece40000 00000000 80f08448 80772008 | ||||
| 9d80: 00000001 00001043 00001002 ece40000 00000000 50d45f32 ece40000 00000001 | ||||
| 9da0: 80f08448 00001043 00001002 807723d0 00000000 50d45f32 80f08448 eca99e58 | ||||
| 9dc0: 80f87113 50d45f32 80f08448 ece40000 ece40138 00001002 80f08448 00000000 | ||||
| 9de0: 00000000 80772434 edbd5380 eca99e58 edbd5380 80f08448 ee9c6c0c 80805f70 | ||||
| 9e00: 00000000 ede08e00 00008914 ece40000 00000014 ee9c6c0c 600c0013 00001043 | ||||
| 9e20: 0208a8c0 ffffffff 00000000 50d45f32 eca98000 80f08448 7ee9fc38 00008914 | ||||
| 9e40: 80f68e40 00000051 eca98000 00000036 00000003 80808b9c 6e616c77 00000030 | ||||
| 9e60: 00000000 00000000 00001043 0208a8c0 ffffffff 00000000 80f08448 00000000 | ||||
| 9e80: 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 00000000 50d45f32 | ||||
| 9ea0: eca98000 80f08448 7ee9fc38 50d45f32 00008914 80f08448 7ee9fc38 80f68e40 | ||||
| 9ec0: ed531540 8074721c 00000800 00000001 00000000 6e616c77 00000030 00000000 | ||||
| 9ee0: 00000000 00001002 0208a8c0 ffffffff 00000000 50d45f32 80f08448 7ee9fc38 | ||||
| 9f00: ed531560 ec8fc900 80285a6c 80285138 edb910c0 00000000 ecd91008 ede08e00 | ||||
| 9f20: 80f08448 00000000 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 | ||||
| 9f40: 00000000 50d45f32 00021000 edb91118 edb910c0 80f08448 01b29000 edb91118 | ||||
| 9f60: eca99f7c 50d45f32 00021000 ec8fc900 00000003 ec8fc900 00008914 7ee9fc38 | ||||
| 9f80: eca98000 00000036 00000003 80285a6c 00086364 7ee9fe1c 000000c3 00000036 | ||||
| 9fa0: 801011c4 80101000 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 | ||||
| 9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 | ||||
| 9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc 600c0010 00000003 00000000 00000000 | ||||
| [<7f26a91c>] (brcmf_cfg80211_up [brcmfmac]) from [<7f27262c>] (brcmf_netdev_open+0x74/0xe8 [brcmfmac]) | ||||
| [<7f27262c>] (brcmf_netdev_open [brcmfmac]) from [<80772008>] (__dev_open+0xcc/0x150) | ||||
| [<80772008>] (__dev_open) from [<807723d0>] (__dev_change_flags+0x168/0x1b4) | ||||
| [<807723d0>] (__dev_change_flags) from [<80772434>] (dev_change_flags+0x18/0x48) | ||||
| [<80772434>] (dev_change_flags) from [<80805f70>] (devinet_ioctl+0x67c/0x79c) | ||||
| [<80805f70>] (devinet_ioctl) from [<80808b9c>] (inet_ioctl+0x210/0x3d4) | ||||
| [<80808b9c>] (inet_ioctl) from [<8074721c>] (sock_ioctl+0x350/0x524) | ||||
| [<8074721c>] (sock_ioctl) from [<80285138>] (do_vfs_ioctl+0xb0/0x9b0) | ||||
| [<80285138>] (do_vfs_ioctl) from [<80285a6c>] (ksys_ioctl+0x34/0x5c) | ||||
| [<80285a6c>] (ksys_ioctl) from [<80101000>] (ret_fast_syscall+0x0/0x28) | ||||
| Exception stack(0xeca99fa8 to 0xeca99ff0) | ||||
| 9fa0:                   00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 | ||||
| 9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 | ||||
| 9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc | ||||
| Code: e5970328 eb002021 e1a02006 e3a01002 (e5909008) | ||||
| ---[ end trace 5cbac2333f3ac5df ]--- | ||||
|  | ||||
| Signed-off-by: Piotr Figiel <p.figiel@camlintechnologies.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/core.c    | 10 +++++++--- | ||||
|  1 file changed, 7 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -861,17 +861,17 @@ static void brcmf_del_if(struct brcmf_pu | ||||
|  			 bool rtnl_locked) | ||||
|  { | ||||
|  	struct brcmf_if *ifp; | ||||
| +	int ifidx; | ||||
|   | ||||
|  	ifp = drvr->iflist[bsscfgidx]; | ||||
| -	drvr->iflist[bsscfgidx] = NULL; | ||||
|  	if (!ifp) { | ||||
|  		bphy_err(drvr, "Null interface, bsscfgidx=%d\n", bsscfgidx); | ||||
|  		return; | ||||
|  	} | ||||
|  	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, | ||||
|  		  ifp->ifidx); | ||||
| -	if (drvr->if2bss[ifp->ifidx] == bsscfgidx) | ||||
| -		drvr->if2bss[ifp->ifidx] = BRCMF_BSSIDX_INVALID; | ||||
| +	ifidx = ifp->ifidx; | ||||
| + | ||||
|  	if (ifp->ndev) { | ||||
|  		if (bsscfgidx == 0) { | ||||
|  			if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { | ||||
| @@ -899,6 +899,10 @@ static void brcmf_del_if(struct brcmf_pu | ||||
|  		brcmf_p2p_ifp_removed(ifp, rtnl_locked); | ||||
|  		kfree(ifp); | ||||
|  	} | ||||
| + | ||||
| +	drvr->iflist[bsscfgidx] = NULL; | ||||
| +	if (drvr->if2bss[ifidx] == bsscfgidx) | ||||
| +		drvr->if2bss[ifidx] = BRCMF_BSSIDX_INVALID; | ||||
|  } | ||||
|   | ||||
|  void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked) | ||||
| @@ -0,0 +1,35 @@ | ||||
| From 46953f97224d56a12ccbe9c6acaa84ca0dab2780 Mon Sep 17 00:00:00 2001 | ||||
| From: Kangjie Lu <kjlu@umn.edu> | ||||
| Date: Fri, 15 Mar 2019 12:04:32 -0500 | ||||
| Subject: [PATCH] brcmfmac: fix missing checks for kmemdup | ||||
|  | ||||
| In case kmemdup fails, the fix sets conn_info->req_ie_len and | ||||
| conn_info->resp_ie_len to zero to avoid buffer overflows. | ||||
|  | ||||
| Signed-off-by: Kangjie Lu <kjlu@umn.edu> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++++ | ||||
|  1 file changed, 4 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -5455,6 +5455,8 @@ static s32 brcmf_get_assoc_ies(struct br | ||||
|  		conn_info->req_ie = | ||||
|  		    kmemdup(cfg->extra_buf, conn_info->req_ie_len, | ||||
|  			    GFP_KERNEL); | ||||
| +		if (!conn_info->req_ie) | ||||
| +			conn_info->req_ie_len = 0; | ||||
|  	} else { | ||||
|  		conn_info->req_ie_len = 0; | ||||
|  		conn_info->req_ie = NULL; | ||||
| @@ -5471,6 +5473,8 @@ static s32 brcmf_get_assoc_ies(struct br | ||||
|  		conn_info->resp_ie = | ||||
|  		    kmemdup(cfg->extra_buf, conn_info->resp_ie_len, | ||||
|  			    GFP_KERNEL); | ||||
| +		if (!conn_info->resp_ie) | ||||
| +			conn_info->resp_ie_len = 0; | ||||
|  	} else { | ||||
|  		conn_info->resp_ie_len = 0; | ||||
|  		conn_info->resp_ie = NULL; | ||||
| @@ -0,0 +1,35 @@ | ||||
| From e3062e05e1cfe378bb9b3fa0bef46711372bcf13 Mon Sep 17 00:00:00 2001 | ||||
| From: Ondrej Jirman <megous@megous.com> | ||||
| Date: Sat, 6 Apr 2019 01:45:13 +0200 | ||||
| Subject: [PATCH] brcmfmac: Loading the correct firmware for brcm43456 | ||||
|  | ||||
| SDIO based brcm43456 is currently misdetected as brcm43455 and the wrong | ||||
| firmware name is used. Correct the detection and load the correct | ||||
| firmware file. Chiprev for brcm43456 is "9". | ||||
|  | ||||
| Signed-off-by: Ondrej Jirman <megous@megous.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++- | ||||
|  1 file changed, 3 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | ||||
| @@ -615,6 +615,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-s | ||||
|  /* Note the names are not postfixed with a1 for backward compatibility */ | ||||
|  BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio"); | ||||
|  BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"); | ||||
| +BRCMF_FW_DEF(43456, "brcmfmac43456-sdio"); | ||||
|  BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); | ||||
|  BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); | ||||
|  BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); | ||||
| @@ -634,7 +635,8 @@ static const struct brcmf_firmware_mappi | ||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), | ||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), | ||||
|  	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), | ||||
| -	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), | ||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456), | ||||
| +	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455), | ||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), | ||||
|  	BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), | ||||
|  	BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373) | ||||
| @@ -0,0 +1,41 @@ | ||||
| From a927e8d8ab57e696800e20cf09a72b7dfe3bbebb Mon Sep 17 00:00:00 2001 | ||||
| From: Colin Ian King <colin.king@canonical.com> | ||||
| Date: Tue, 9 Apr 2019 12:43:33 +0100 | ||||
| Subject: [PATCH] brcmfmac: fix leak of mypkt on error return path | ||||
|  | ||||
| Currently if the call to brcmf_sdiod_set_backplane_window fails then | ||||
| error return path leaks mypkt. Fix this by returning by a new | ||||
| error path labelled 'out' that calls brcmu_pkt_buf_free_skb to free | ||||
| mypkt.  Also remove redundant check on err before calling | ||||
| brcmf_sdiod_skbuff_write. | ||||
|  | ||||
| Addresses-Coverity: ("Resource Leak") | ||||
| Fixes: a7c3aa1509e2 ("brcmfmac: Remove brcmf_sdiod_addrprep()") | ||||
| Signed-off-by: Colin Ian King <colin.king@canonical.com> | ||||
| Reviewed-by: Mukesh Ojha <mojha@codeaurora.org> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 +++----- | ||||
|  1 file changed, 3 insertions(+), 5 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | ||||
| @@ -617,15 +617,13 @@ int brcmf_sdiod_send_buf(struct brcmf_sd | ||||
|   | ||||
|  	err = brcmf_sdiod_set_backplane_window(sdiodev, addr); | ||||
|  	if (err) | ||||
| -		return err; | ||||
| +		goto out; | ||||
|   | ||||
|  	addr &= SBSDIO_SB_OFT_ADDR_MASK; | ||||
|  	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; | ||||
|   | ||||
| -	if (!err) | ||||
| -		err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, | ||||
| -					       mypkt); | ||||
| - | ||||
| +	err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, mypkt); | ||||
| +out: | ||||
|  	brcmu_pkt_buf_free_skb(mypkt); | ||||
|   | ||||
|  	return err; | ||||
| @@ -0,0 +1,70 @@ | ||||
| From b1a0ba8f772d7a6dcb5aa3e856f5bd8274989ebe Mon Sep 17 00:00:00 2001 | ||||
| From: Hans de Goede <hdegoede@redhat.com> | ||||
| Date: Mon, 22 Apr 2019 22:41:23 +0200 | ||||
| Subject: [PATCH] brcmfmac: Add DMI nvram filename quirk for ACEPC T8 and T11 | ||||
|  mini PCs | ||||
|  | ||||
| The ACEPC T8 and T11 mini PCs contain quite generic names in the sys_vendor | ||||
| and product_name DMI strings, without this patch brcmfmac will try to load: | ||||
| "brcmfmac43455-sdio.Default string-Default string.txt" as nvram file which | ||||
| is way too generic. | ||||
|  | ||||
| The DMI strings on which we are matching are somewhat generic too, but | ||||
| "To be filled by O.E.M." is less common then "Default string" and the | ||||
| system-sku and bios-version strings are pretty unique. Beside the DMI | ||||
| strings we also check the wifi-module chip-id and revision. I'm confident | ||||
| that the combination of all this is unique. | ||||
|  | ||||
| Both the T8 and T11 use the same wifi-module, this commit adds DMI | ||||
| quirks for both mini PCs pointing to brcmfmac43455-sdio.acepc-t8.txt . | ||||
|  | ||||
| BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1690852 | ||||
| Cc: stable@vger.kernel.org | ||||
| Signed-off-by: Hans de Goede <hdegoede@redhat.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/dmi.c         | 26 +++++++++++++++++++ | ||||
|  1 file changed, 26 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | ||||
| @@ -31,6 +31,10 @@ struct brcmf_dmi_data { | ||||
|   | ||||
|  /* NOTE: Please keep all entries sorted alphabetically */ | ||||
|   | ||||
| +static const struct brcmf_dmi_data acepc_t8_data = { | ||||
| +	BRCM_CC_4345_CHIP_ID, 6, "acepc-t8" | ||||
| +}; | ||||
| + | ||||
|  static const struct brcmf_dmi_data gpd_win_pocket_data = { | ||||
|  	BRCM_CC_4356_CHIP_ID, 2, "gpd-win-pocket" | ||||
|  }; | ||||
| @@ -45,6 +49,28 @@ static const struct brcmf_dmi_data meego | ||||
|   | ||||
|  static const struct dmi_system_id dmi_platform_data[] = { | ||||
|  	{ | ||||
| +		/* ACEPC T8 Cherry Trail Z8350 mini PC */ | ||||
| +		.matches = { | ||||
| +			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."), | ||||
| +			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), | ||||
| +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "T8"), | ||||
| +			/* also match on somewhat unique bios-version */ | ||||
| +			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1.000"), | ||||
| +		}, | ||||
| +		.driver_data = (void *)&acepc_t8_data, | ||||
| +	}, | ||||
| +	{ | ||||
| +		/* ACEPC T11 Cherry Trail Z8350 mini PC, same wifi as the T8 */ | ||||
| +		.matches = { | ||||
| +			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."), | ||||
| +			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), | ||||
| +			DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "T11"), | ||||
| +			/* also match on somewhat unique bios-version */ | ||||
| +			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1.000"), | ||||
| +		}, | ||||
| +		.driver_data = (void *)&acepc_t8_data, | ||||
| +	}, | ||||
| +	{ | ||||
|  		/* Match for the GPDwin which unfortunately uses somewhat | ||||
|  		 * generic dmi strings, which is why we test for 4 strings. | ||||
|  		 * Comparing against 23 other byt/cht boards, board_vendor | ||||
| @@ -0,0 +1,39 @@ | ||||
| From 9ef77fbedad9ea8895cd5d7fb7aee16071f527dc Mon Sep 17 00:00:00 2001 | ||||
| From: Wright Feng <Wright.Feng@cypress.com> | ||||
| Date: Fri, 26 Apr 2019 03:12:32 +0000 | ||||
| Subject: [PATCH] brcmfmac: send mailbox interrupt twice for specific hardware | ||||
|  device | ||||
|  | ||||
| For PCIE wireless device with core revision less than 14, device may miss | ||||
| PCIE to System Backplane Interrupt via PCIEtoSBMailbox. So add sending | ||||
| mail box interrupt twice as a hardware workaround. | ||||
|  | ||||
| Signed-off-by: Wright Feng <wright.feng@cypress.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 7 ++++++- | ||||
|  1 file changed, 6 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -675,6 +675,7 @@ static int | ||||
|  brcmf_pcie_send_mb_data(struct brcmf_pciedev_info *devinfo, u32 htod_mb_data) | ||||
|  { | ||||
|  	struct brcmf_pcie_shared_info *shared; | ||||
| +	struct brcmf_core *core; | ||||
|  	u32 addr; | ||||
|  	u32 cur_htod_mb_data; | ||||
|  	u32 i; | ||||
| @@ -698,7 +699,11 @@ brcmf_pcie_send_mb_data(struct brcmf_pci | ||||
|   | ||||
|  	brcmf_pcie_write_tcm32(devinfo, addr, htod_mb_data); | ||||
|  	pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); | ||||
| -	pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); | ||||
| + | ||||
| +	/* Send mailbox interrupt twice as a hardware workaround */ | ||||
| +	core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2); | ||||
| +	if (core->rev <= 13) | ||||
| +		pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_SBMBX, 1); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
| @@ -0,0 +1,50 @@ | ||||
| From e025da3d7aa4770bb1d1b3b0aa7cc4da1744852d Mon Sep 17 00:00:00 2001 | ||||
| From: Dan Carpenter <dan.carpenter@oracle.com> | ||||
| Date: Wed, 24 Apr 2019 12:52:18 +0300 | ||||
| Subject: [PATCH] brcm80211: potential NULL dereference in | ||||
|  brcmf_cfg80211_vndr_cmds_dcmd_handler() | ||||
|  | ||||
| If "ret_len" is negative then it could lead to a NULL dereference. | ||||
|  | ||||
| The "ret_len" value comes from nl80211_vendor_cmd(), if it's negative | ||||
| then we don't allocate the "dcmd_buf" buffer.  Then we pass "ret_len" to | ||||
| brcmf_fil_cmd_data_set() where it is cast to a very high u32 value. | ||||
| Most of the functions in that call tree check whether the buffer we pass | ||||
| is NULL but there are at least a couple places which don't such as | ||||
| brcmf_dbg_hex_dump() and brcmf_msgbuf_query_dcmd().  We memcpy() to and | ||||
| from the buffer so it would result in a NULL dereference. | ||||
|  | ||||
| The fix is to change the types so that "ret_len" can't be negative.  (If | ||||
| we memcpy() zero bytes to NULL, that's a no-op and doesn't cause an | ||||
| issue). | ||||
|  | ||||
| Fixes: 1bacb0487d0e ("brcmfmac: replace cfg80211 testmode with vendor command") | ||||
| Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | 5 +++-- | ||||
|  1 file changed, 3 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/vendor.c | ||||
| @@ -35,9 +35,10 @@ static int brcmf_cfg80211_vndr_cmds_dcmd | ||||
|  	struct brcmf_if *ifp; | ||||
|  	const struct brcmf_vndr_dcmd_hdr *cmdhdr = data; | ||||
|  	struct sk_buff *reply; | ||||
| -	int ret, payload, ret_len; | ||||
| +	unsigned int payload, ret_len; | ||||
|  	void *dcmd_buf = NULL, *wr_pointer; | ||||
|  	u16 msglen, maxmsglen = PAGE_SIZE - 0x100; | ||||
| +	int ret; | ||||
|   | ||||
|  	if (len < sizeof(*cmdhdr)) { | ||||
|  		brcmf_err("vendor command too short: %d\n", len); | ||||
| @@ -65,7 +66,7 @@ static int brcmf_cfg80211_vndr_cmds_dcmd | ||||
|  			brcmf_err("oversize return buffer %d\n", ret_len); | ||||
|  			ret_len = BRCMF_DCMD_MAXLEN; | ||||
|  		} | ||||
| -		payload = max(ret_len, len) + 1; | ||||
| +		payload = max_t(unsigned int, ret_len, len) + 1; | ||||
|  		dcmd_buf = vzalloc(payload); | ||||
|  		if (NULL == dcmd_buf) | ||||
|  			return -ENOMEM; | ||||
| @@ -0,0 +1,49 @@ | ||||
| From 2d91c8ad068a5cad4d9e7ece8dc811a697c7176a Mon Sep 17 00:00:00 2001 | ||||
| From: Wright Feng <Wright.Feng@cypress.com> | ||||
| Date: Fri, 26 Apr 2019 03:41:46 +0000 | ||||
| Subject: [PATCH] brcmfmac: set txflow request id from 1 to pktids array size | ||||
|  | ||||
| Some PCIE firmwares drop txstatus if pktid is 0 and make packet held in | ||||
| host side and never be released. If that packet type is 802.1x, the | ||||
| pend_8021x_cnt value will be always greater than 0 and show "Timed out | ||||
| waiting for no pending 802.1x packets" error message when sending key to | ||||
| dongle every time. | ||||
|  | ||||
| To be compatible with all firmwares, host should set txflow request id | ||||
| from 1 instead of from 0. | ||||
|  | ||||
| Signed-off-by: Wright Feng <wright.feng@cypress.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 6 +++--- | ||||
|  1 file changed, 3 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| @@ -375,7 +375,7 @@ brcmf_msgbuf_get_pktid(struct device *de | ||||
|  	struct brcmf_msgbuf_pktid *pktid; | ||||
|  	struct sk_buff *skb; | ||||
|   | ||||
| -	if (idx >= pktids->array_size) { | ||||
| +	if (idx < 0 || idx >= pktids->array_size) { | ||||
|  		brcmf_err("Invalid packet id %d (max %d)\n", idx, | ||||
|  			  pktids->array_size); | ||||
|  		return NULL; | ||||
| @@ -747,7 +747,7 @@ static void brcmf_msgbuf_txflow(struct b | ||||
|  		tx_msghdr = (struct msgbuf_tx_msghdr *)ret_ptr; | ||||
|   | ||||
|  		tx_msghdr->msg.msgtype = MSGBUF_TYPE_TX_POST; | ||||
| -		tx_msghdr->msg.request_id = cpu_to_le32(pktid); | ||||
| +		tx_msghdr->msg.request_id = cpu_to_le32(pktid + 1); | ||||
|  		tx_msghdr->msg.ifidx = brcmf_flowring_ifidx_get(flow, flowid); | ||||
|  		tx_msghdr->flags = BRCMF_MSGBUF_PKT_FLAGS_FRAME_802_3; | ||||
|  		tx_msghdr->flags |= (skb->priority & 0x07) << | ||||
| @@ -884,7 +884,7 @@ brcmf_msgbuf_process_txstatus(struct brc | ||||
|  	u16 flowid; | ||||
|   | ||||
|  	tx_status = (struct msgbuf_tx_status *)buf; | ||||
| -	idx = le32_to_cpu(tx_status->msg.request_id); | ||||
| +	idx = le32_to_cpu(tx_status->msg.request_id) - 1; | ||||
|  	flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id); | ||||
|  	flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART; | ||||
|  	skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, | ||||
| @@ -0,0 +1,90 @@ | ||||
| From 47dd82e3d25e85a7c7c4e4b0eac9d297d1e5e2d4 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Sun, 28 Apr 2019 23:38:26 +0200 | ||||
| Subject: [PATCH] brcmfmac: print firmware messages after a firmware crash | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Normally firmware messages are printed with debugging enabled only. It's | ||||
| a good idea as firmware may print a lot of messages that normal users | ||||
| don't need to care about. | ||||
|  | ||||
| However, on firmware crash, it may be very helpful to log all recent | ||||
| messages. There is almost always a backtrace available as well as rought | ||||
| info on the latest actions/state. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/pcie.c        | 24 ++++++++++++++----- | ||||
|  1 file changed, 18 insertions(+), 6 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -764,15 +764,22 @@ static void brcmf_pcie_bus_console_init( | ||||
|  		  console->base_addr, console->buf_addr, console->bufsize); | ||||
|  } | ||||
|   | ||||
| - | ||||
| -static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo) | ||||
| +/** | ||||
| + * brcmf_pcie_bus_console_read - reads firmware messages | ||||
| + * | ||||
| + * @error: specifies if error has occurred (prints messages unconditionally) | ||||
| + */ | ||||
| +static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo, | ||||
| +					bool error) | ||||
|  { | ||||
| +	struct pci_dev *pdev = devinfo->pdev; | ||||
| +	struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev); | ||||
|  	struct brcmf_pcie_console *console; | ||||
|  	u32 addr; | ||||
|  	u8 ch; | ||||
|  	u32 newidx; | ||||
|   | ||||
| -	if (!BRCMF_FWCON_ON()) | ||||
| +	if (!error && !BRCMF_FWCON_ON()) | ||||
|  		return; | ||||
|   | ||||
|  	console = &devinfo->shared.console; | ||||
| @@ -796,7 +803,10 @@ static void brcmf_pcie_bus_console_read( | ||||
|  		} | ||||
|  		if (ch == '\n') { | ||||
|  			console->log_str[console->log_idx] = 0; | ||||
| -			pr_debug("CONSOLE: %s", console->log_str); | ||||
| +			if (error) | ||||
| +				brcmf_err(bus, "CONSOLE: %s", console->log_str); | ||||
| +			else | ||||
| +				pr_debug("CONSOLE: %s", console->log_str); | ||||
|  			console->log_idx = 0; | ||||
|  		} | ||||
|  	} | ||||
| @@ -857,7 +867,7 @@ static irqreturn_t brcmf_pcie_isr_thread | ||||
|  							&devinfo->pdev->dev); | ||||
|  		} | ||||
|  	} | ||||
| -	brcmf_pcie_bus_console_read(devinfo); | ||||
| +	brcmf_pcie_bus_console_read(devinfo, false); | ||||
|  	if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) | ||||
|  		brcmf_pcie_intr_enable(devinfo); | ||||
|  	devinfo->in_irq = false; | ||||
| @@ -1426,6 +1436,8 @@ static int brcmf_pcie_reset(struct devic | ||||
|  	struct brcmf_fw_request *fwreq; | ||||
|  	int err; | ||||
|   | ||||
| +	brcmf_pcie_bus_console_read(devinfo, true); | ||||
| + | ||||
|  	brcmf_detach(dev); | ||||
|   | ||||
|  	brcmf_pcie_release_irq(devinfo); | ||||
| @@ -1818,7 +1830,7 @@ static void brcmf_pcie_setup(struct devi | ||||
|  	if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) | ||||
|  		return; | ||||
|   | ||||
| -	brcmf_pcie_bus_console_read(devinfo); | ||||
| +	brcmf_pcie_bus_console_read(devinfo, false); | ||||
|   | ||||
|  fail: | ||||
|  	device_release_driver(dev); | ||||
| @@ -0,0 +1,26 @@ | ||||
| From bbfab331e3abd9fa8767eea6bf5c4684cdd4b934 Mon Sep 17 00:00:00 2001 | ||||
| From: Neo Jou <neojou@gmail.com> | ||||
| Date: Tue, 21 May 2019 17:12:20 +0800 | ||||
| Subject: [PATCH] brcmfmac: use strlcpy() instead of strcpy() | ||||
|  | ||||
| The function strcpy() is inherently not safe. Though the function | ||||
| works without problems here, it would be better to use other safer | ||||
| function, e.g. strlcpy(), to replace strcpy() still. | ||||
|  | ||||
| Signed-off-by: Neo Jou <neojou@gmail.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| @@ -269,7 +269,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||
|   | ||||
|  	/* query for 'ver' to get version info from firmware */ | ||||
|  	memset(buf, 0, sizeof(buf)); | ||||
| -	strcpy(buf, "ver"); | ||||
| +	strlcpy(buf, "ver", sizeof(buf)); | ||||
|  	err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); | ||||
|  	if (err < 0) { | ||||
|  		bphy_err(drvr, "Retrieving version information failed, %d\n", | ||||
| @@ -0,0 +1,56 @@ | ||||
| From f491645f039420fb7e14283e21b90772571c807c Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 10:45:30 +0200 | ||||
| Subject: [PATCH] brcmfmac: add 160MHz in chandef_to_chanspec() | ||||
|  | ||||
| The function chandef_to_chanspec() was not handling 160MHz bandwidth | ||||
| resulting in wrong encoding of the channel. That resulting in firmware | ||||
| rejecting the provided channel specification. | ||||
|  | ||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 21 ++++++++++++++++++- | ||||
|  1 file changed, 20 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -287,8 +287,26 @@ static u16 chandef_to_chanspec(struct br | ||||
|  		else | ||||
|  			ch_inf.sb = BRCMU_CHAN_SB_UU; | ||||
|  		break; | ||||
| -	case NL80211_CHAN_WIDTH_80P80: | ||||
|  	case NL80211_CHAN_WIDTH_160: | ||||
| +		ch_inf.bw = BRCMU_CHAN_BW_160; | ||||
| +		if (primary_offset == -70) | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_LLL; | ||||
| +		else if (primary_offset == -50) | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_LLU; | ||||
| +		else if (primary_offset == -30) | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_LUL; | ||||
| +		else if (primary_offset == -10) | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_LUU; | ||||
| +		else if (primary_offset == 10) | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_ULL; | ||||
| +		else if (primary_offset == 30) | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_ULU; | ||||
| +		else if (primary_offset == 50) | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_UUL; | ||||
| +		else | ||||
| +			ch_inf.sb = BRCMU_CHAN_SB_UUU; | ||||
| +		break; | ||||
| +	case NL80211_CHAN_WIDTH_80P80: | ||||
|  	case NL80211_CHAN_WIDTH_5: | ||||
|  	case NL80211_CHAN_WIDTH_10: | ||||
|  	default: | ||||
| @@ -307,6 +325,7 @@ static u16 chandef_to_chanspec(struct br | ||||
|  	} | ||||
|  	d11inf->encchspec(&ch_inf); | ||||
|   | ||||
| +	brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec); | ||||
|  	return ch_inf.chspec; | ||||
|  } | ||||
|   | ||||
| @@ -0,0 +1,168 @@ | ||||
| From a84a60ccdd65278485fb495f468a5ab91a75c649 Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 11:05:06 +0200 | ||||
| Subject: [PATCH] Revert "brcmfmac: fix NULL pointer derefence during USB | ||||
|  disconnect" | ||||
|  | ||||
| This reverts commit 5cdb0ef6144f47440850553579aa923c20a63f23. Subsequent | ||||
| changes make rework the driver code fixing the issue differently. | ||||
|  | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c  | 11 ++--------- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/bcdc.h  |  6 ++---- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c  |  4 +--- | ||||
|  .../broadcom/brcm80211/brcmfmac/fwsignal.c       | 16 ++++------------ | ||||
|  .../broadcom/brcm80211/brcmfmac/fwsignal.h       |  3 +-- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/proto.c | 10 ++-------- | ||||
|  .../wireless/broadcom/brcm80211/brcmfmac/proto.h |  3 +-- | ||||
|  7 files changed, 13 insertions(+), 40 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | ||||
| @@ -490,18 +490,11 @@ fail: | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
|   | ||||
| -void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) | ||||
| -{ | ||||
| -	struct brcmf_bcdc *bcdc = drvr->proto->pd; | ||||
| - | ||||
| -	brcmf_fws_detach_pre_delif(bcdc->fws); | ||||
| -} | ||||
| - | ||||
| -void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) | ||||
| +void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) | ||||
|  { | ||||
|  	struct brcmf_bcdc *bcdc = drvr->proto->pd; | ||||
|   | ||||
|  	drvr->proto->pd = NULL; | ||||
| -	brcmf_fws_detach_post_delif(bcdc->fws); | ||||
| +	brcmf_fws_detach(bcdc->fws); | ||||
|  	kfree(bcdc); | ||||
|  } | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | ||||
| @@ -18,16 +18,14 @@ | ||||
|   | ||||
|  #ifdef CPTCFG_BRCMFMAC_PROTO_BCDC | ||||
|  int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); | ||||
| -void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr); | ||||
| -void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr); | ||||
| +void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); | ||||
|  void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state); | ||||
|  void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp, | ||||
|  				 bool success); | ||||
|  struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr); | ||||
|  #else | ||||
|  static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; } | ||||
| -static void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) {}; | ||||
| -static inline void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) {} | ||||
| +static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {} | ||||
|  #endif | ||||
|   | ||||
|  #endif /* BRCMFMAC_BCDC_H */ | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1344,8 +1344,6 @@ void brcmf_detach(struct device *dev) | ||||
|   | ||||
|  	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); | ||||
|   | ||||
| -	brcmf_proto_detach_pre_delif(drvr); | ||||
| - | ||||
|  	/* make sure primary interface removed last */ | ||||
|  	for (i = BRCMF_MAX_IFS-1; i > -1; i--) | ||||
|  		brcmf_remove_interface(drvr->iflist[i], false); | ||||
| @@ -1355,7 +1353,7 @@ void brcmf_detach(struct device *dev) | ||||
|   | ||||
|  	brcmf_bus_stop(drvr->bus_if); | ||||
|   | ||||
| -	brcmf_proto_detach_post_delif(drvr); | ||||
| +	brcmf_proto_detach(drvr); | ||||
|   | ||||
|  	bus_if->drvr = NULL; | ||||
|  	wiphy_free(drvr->wiphy); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | ||||
| @@ -2416,25 +2416,17 @@ struct brcmf_fws_info *brcmf_fws_attach( | ||||
|  	return fws; | ||||
|   | ||||
|  fail: | ||||
| -	brcmf_fws_detach_pre_delif(fws); | ||||
| -	brcmf_fws_detach_post_delif(fws); | ||||
| +	brcmf_fws_detach(fws); | ||||
|  	return ERR_PTR(rc); | ||||
|  } | ||||
|   | ||||
| -void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws) | ||||
| +void brcmf_fws_detach(struct brcmf_fws_info *fws) | ||||
|  { | ||||
|  	if (!fws) | ||||
|  		return; | ||||
| -	if (fws->fws_wq) { | ||||
| -		destroy_workqueue(fws->fws_wq); | ||||
| -		fws->fws_wq = NULL; | ||||
| -	} | ||||
| -} | ||||
|   | ||||
| -void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws) | ||||
| -{ | ||||
| -	if (!fws) | ||||
| -		return; | ||||
| +	if (fws->fws_wq) | ||||
| +		destroy_workqueue(fws->fws_wq); | ||||
|   | ||||
|  	/* cleanup */ | ||||
|  	brcmf_fws_lock(fws); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h | ||||
| @@ -19,8 +19,7 @@ | ||||
|  #define FWSIGNAL_H_ | ||||
|   | ||||
|  struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); | ||||
| -void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws); | ||||
| -void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws); | ||||
| +void brcmf_fws_detach(struct brcmf_fws_info *fws); | ||||
|  void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); | ||||
|  bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); | ||||
|  bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c | ||||
| @@ -67,22 +67,16 @@ fail: | ||||
|  	return -ENOMEM; | ||||
|  } | ||||
|   | ||||
| -void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr) | ||||
| +void brcmf_proto_detach(struct brcmf_pub *drvr) | ||||
|  { | ||||
|  	brcmf_dbg(TRACE, "Enter\n"); | ||||
|   | ||||
|  	if (drvr->proto) { | ||||
|  		if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) | ||||
| -			brcmf_proto_bcdc_detach_post_delif(drvr); | ||||
| +			brcmf_proto_bcdc_detach(drvr); | ||||
|  		else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) | ||||
|  			brcmf_proto_msgbuf_detach(drvr); | ||||
|  		kfree(drvr->proto); | ||||
|  		drvr->proto = NULL; | ||||
|  	} | ||||
|  } | ||||
| - | ||||
| -void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr) | ||||
| -{ | ||||
| -	if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) | ||||
| -		brcmf_proto_bcdc_detach_pre_delif(drvr); | ||||
| -} | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | ||||
| @@ -54,8 +54,7 @@ struct brcmf_proto { | ||||
|   | ||||
|   | ||||
|  int brcmf_proto_attach(struct brcmf_pub *drvr); | ||||
| -void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr); | ||||
| -void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr); | ||||
| +void brcmf_proto_detach(struct brcmf_pub *drvr); | ||||
|   | ||||
|  static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, | ||||
|  				      struct sk_buff *skb, | ||||
| @@ -0,0 +1,67 @@ | ||||
| From 14fcfd1cc0c05ea58f47dd693fdd13f25dfe995e Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 11:05:07 +0200 | ||||
| Subject: [PATCH] brcmfmac: change the order of things in brcmf_detach() | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| When brcmf_detach() from the bus layer upon rmmod we can no longer | ||||
| communicate. Hence we will set the bus state to DOWN and cleanup | ||||
| the event and protocol layer. The network interfaces need to be | ||||
| deleted before brcmf_cfg80211_detach() because the latter does the | ||||
| wiphy_unregister() which issues a warning if there are still network | ||||
| devices linked to the wiphy instance. | ||||
|  | ||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Tested-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/core.c        | 27 ++++++++++--------- | ||||
|  1 file changed, 14 insertions(+), 13 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1337,25 +1337,26 @@ void brcmf_detach(struct device *dev) | ||||
|  	unregister_inet6addr_notifier(&drvr->inet6addr_notifier); | ||||
|  #endif | ||||
|   | ||||
| -	/* stop firmware event handling */ | ||||
| -	brcmf_fweh_detach(drvr); | ||||
| -	if (drvr->config) | ||||
| -		brcmf_p2p_detach(&drvr->config->p2p); | ||||
| - | ||||
|  	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); | ||||
| - | ||||
| -	/* make sure primary interface removed last */ | ||||
| -	for (i = BRCMF_MAX_IFS-1; i > -1; i--) | ||||
| -		brcmf_remove_interface(drvr->iflist[i], false); | ||||
| - | ||||
| -	brcmf_cfg80211_detach(drvr->config); | ||||
| -	drvr->config = NULL; | ||||
| - | ||||
|  	brcmf_bus_stop(drvr->bus_if); | ||||
|   | ||||
| +	brcmf_fweh_detach(drvr); | ||||
|  	brcmf_proto_detach(drvr); | ||||
|   | ||||
| +	/* make sure primary interface removed last */ | ||||
| +	for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { | ||||
| +		if (drvr->iflist[i]) | ||||
| +			brcmf_del_if(drvr, drvr->iflist[i]->bsscfgidx, false); | ||||
| +	} | ||||
| + | ||||
| +	if (drvr->config) { | ||||
| +		brcmf_p2p_detach(&drvr->config->p2p); | ||||
| +		brcmf_cfg80211_detach(drvr->config); | ||||
| +		drvr->config = NULL; | ||||
| +	} | ||||
| + | ||||
|  	bus_if->drvr = NULL; | ||||
| + | ||||
|  	wiphy_free(drvr->wiphy); | ||||
|  } | ||||
|   | ||||
| @@ -0,0 +1,30 @@ | ||||
| From c613085b74941024194e41b200601b9aa6ee388f Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 11:05:08 +0200 | ||||
| Subject: [PATCH] brcmfmac: avoid firmware command in brcmf_netdev_open() when | ||||
|  bus is down | ||||
|  | ||||
| No point in sending a firmware command when bus is down so make it | ||||
| conditional checking the state. | ||||
|  | ||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- | ||||
|  1 file changed, 2 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -589,7 +589,8 @@ static int brcmf_netdev_stop(struct net_ | ||||
|   | ||||
|  	brcmf_cfg80211_down(ndev); | ||||
|   | ||||
| -	brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); | ||||
| +	if (ifp->drvr->bus_if->state == BRCMF_BUS_UP) | ||||
| +		brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); | ||||
|   | ||||
|  	brcmf_net_setcarrier(ifp, false); | ||||
|   | ||||
| @@ -0,0 +1,38 @@ | ||||
| From c33330ac06fe863289643e7a13ecdb6a2502dad7 Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 11:05:09 +0200 | ||||
| Subject: [PATCH] brcmfmac: clear events in brcmf_fweh_detach() will always | ||||
|  fail | ||||
|  | ||||
| Clearing firmware events in brcmf_fweh_detach() is always failing | ||||
| because it is called only upon driver remove and communication | ||||
| with firmware is no longer possible. | ||||
|  | ||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 9 --------- | ||||
|  1 file changed, 9 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | ||||
| @@ -314,16 +314,7 @@ void brcmf_fweh_attach(struct brcmf_pub | ||||
|  void brcmf_fweh_detach(struct brcmf_pub *drvr) | ||||
|  { | ||||
|  	struct brcmf_fweh_info *fweh = &drvr->fweh; | ||||
| -	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); | ||||
| -	s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||||
|   | ||||
| -	if (ifp) { | ||||
| -		/* clear all events */ | ||||
| -		memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); | ||||
| -		(void)brcmf_fil_iovar_data_set(ifp, "event_msgs", | ||||
| -					       eventmask, | ||||
| -					       BRCMF_EVENTING_MASK_LEN); | ||||
| -	} | ||||
|  	/* cancel the worker */ | ||||
|  	cancel_work_sync(&fweh->event_work); | ||||
|  	WARN_ON(!list_empty(&fweh->event_q)); | ||||
| @@ -0,0 +1,79 @@ | ||||
| From 1ac11ae949dd883854f4523ef8e3a32aabfd6256 Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 11:05:10 +0200 | ||||
| Subject: [PATCH] brcmfmac: avoid firmware commands when bus is down | ||||
|  | ||||
| Upon rmmod a few attempts are made to inform firmware, but there is | ||||
| no point as the bus is down and these will fail. Avoid them to keep | ||||
| the logs clean. | ||||
|  | ||||
| Reported-by: Stefan Wahren <stefan.wahren@i2se.com> | ||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c    | 23 +++++++++++-------- | ||||
|  1 file changed, 13 insertions(+), 10 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -1297,17 +1297,21 @@ static void brcmf_link_down(struct brcmf | ||||
|  { | ||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); | ||||
|  	struct brcmf_pub *drvr = cfg->pub; | ||||
| +	bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP; | ||||
|  	s32 err = 0; | ||||
|   | ||||
|  	brcmf_dbg(TRACE, "Enter\n"); | ||||
|   | ||||
|  	if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) { | ||||
| -		brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n "); | ||||
| -		err = brcmf_fil_cmd_data_set(vif->ifp, | ||||
| -					     BRCMF_C_DISASSOC, NULL, 0); | ||||
| -		if (err) { | ||||
| -			bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", err); | ||||
| +		if (bus_up) { | ||||
| +			brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n"); | ||||
| +			err = brcmf_fil_cmd_data_set(vif->ifp, | ||||
| +						     BRCMF_C_DISASSOC, NULL, 0); | ||||
| +			if (err) | ||||
| +				bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", | ||||
| +					 err); | ||||
|  		} | ||||
| + | ||||
|  		if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) || | ||||
|  		    (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) | ||||
|  			cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0, | ||||
| @@ -1317,7 +1321,8 @@ static void brcmf_link_down(struct brcmf | ||||
|  	clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); | ||||
|  	brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); | ||||
|  	if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) { | ||||
| -		brcmf_set_pmk(vif->ifp, NULL, 0); | ||||
| +		if (bus_up) | ||||
| +			brcmf_set_pmk(vif->ifp, NULL, 0); | ||||
|  		vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE; | ||||
|  	} | ||||
|  	brcmf_dbg(TRACE, "Exit\n"); | ||||
| @@ -5006,18 +5011,16 @@ static int brcmf_cfg80211_get_channel(st | ||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||||
|  	struct net_device *ndev = wdev->netdev; | ||||
|  	struct brcmf_pub *drvr = cfg->pub; | ||||
| -	struct brcmf_if *ifp; | ||||
|  	struct brcmu_chan ch; | ||||
|  	enum nl80211_band band = 0; | ||||
|  	enum nl80211_chan_width width = 0; | ||||
|  	u32 chanspec; | ||||
|  	int freq, err; | ||||
|   | ||||
| -	if (!ndev) | ||||
| +	if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP) | ||||
|  		return -ENODEV; | ||||
| -	ifp = netdev_priv(ndev); | ||||
|   | ||||
| -	err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec); | ||||
| +	err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec); | ||||
|  	if (err) { | ||||
|  		bphy_err(drvr, "chanspec failed (%d)\n", err); | ||||
|  		return err; | ||||
| @@ -0,0 +1,33 @@ | ||||
| From e0bfb9601d4812719167cc4124a0d6db1e2f55e4 Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 11:05:11 +0200 | ||||
| Subject: [PATCH] brcmfmac: simply remove flowring if bus is down | ||||
|  | ||||
| When the bus is down, eg. due to rmmod, there is no need to | ||||
| attempt to inform firmware about it. | ||||
|  | ||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 7 +++++++ | ||||
|  1 file changed, 7 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| @@ -1408,6 +1408,13 @@ void brcmf_msgbuf_delete_flowring(struct | ||||
|  	u8 ifidx; | ||||
|  	int err; | ||||
|   | ||||
| +	/* no need to submit if firmware can not be reached */ | ||||
| +	if (drvr->bus_if->state != BRCMF_BUS_UP) { | ||||
| +		brcmf_dbg(MSGBUF, "bus down, flowring will be removed\n"); | ||||
| +		brcmf_msgbuf_remove_flowring(msgbuf, flowid); | ||||
| +		return; | ||||
| +	} | ||||
| + | ||||
|  	commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT]; | ||||
|  	brcmf_commonring_lock(commonring); | ||||
|  	ret_ptr = brcmf_commonring_reserve_for_write(commonring); | ||||
| @@ -0,0 +1,28 @@ | ||||
| From 4b11c915f00caeef3292ed0429acc579b9da762a Mon Sep 17 00:00:00 2001 | ||||
| From: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Date: Thu, 11 Jul 2019 11:05:12 +0200 | ||||
| Subject: [PATCH] brcmfmac: remove unnecessary strlcpy() upon obtaining "ver" | ||||
|  iovar | ||||
|  | ||||
| Recently a strcpy() was replaced by strlcpy(). However, the strcpy() | ||||
| was not needed in the first place. So removing that line of code. | ||||
|  | ||||
| Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> | ||||
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> | ||||
| Reviewed-by: Franky Lin <franky.lin@broadcom.com> | ||||
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 1 - | ||||
|  1 file changed, 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | ||||
| @@ -269,7 +269,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i | ||||
|   | ||||
|  	/* query for 'ver' to get version info from firmware */ | ||||
|  	memset(buf, 0, sizeof(buf)); | ||||
| -	strlcpy(buf, "ver", sizeof(buf)); | ||||
|  	err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); | ||||
|  	if (err < 0) { | ||||
|  		bphy_err(drvr, "Retrieving version information failed, %d\n", | ||||
| @@ -0,0 +1,38 @@ | ||||
| From e3b1d879ccda9ffd5332777bb1beeb2cc913faa8 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Sun, 21 Jul 2019 21:52:17 +0200 | ||||
| Subject: [PATCH] brcmfmac: don't net_ratelimit() CONSOLE messages on firmware | ||||
|  crash | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Firmware crash is a pretty rare event and can't happen too frequently as | ||||
| it has to be followed by a hardware reinitialization and config reload. | ||||
| It should be safe to don't use net_ratelimit() when it happens. | ||||
|  | ||||
| For reporting & debugging purposes it's important to provide a complete | ||||
| log as the last lines are actually the most important. This change | ||||
| modifies brcmfmac to print all messages in an unlimited way in that | ||||
| specific case. With this change there should be finally a backtrace of | ||||
| firmware finally visible after a crash. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 ++- | ||||
|  1 file changed, 2 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -804,7 +804,8 @@ static void brcmf_pcie_bus_console_read( | ||||
|  		if (ch == '\n') { | ||||
|  			console->log_str[console->log_idx] = 0; | ||||
|  			if (error) | ||||
| -				brcmf_err(bus, "CONSOLE: %s", console->log_str); | ||||
| +				__brcmf_err(bus, __func__, "CONSOLE: %s", | ||||
| +					    console->log_str); | ||||
|  			else | ||||
|  				pr_debug("CONSOLE: %s", console->log_str); | ||||
|  			console->log_idx = 0; | ||||
| @@ -0,0 +1,54 @@ | ||||
| From cddecd92d1ec2fd05ed1123455e7c6cf6906b5a5 Mon Sep 17 00:00:00 2001 | ||||
| From: YueHaibing <yuehaibing@huawei.com> | ||||
| Date: Wed, 24 Jul 2019 22:12:01 +0800 | ||||
| Subject: [PATCH] brcmfmac: remove set but not used variable 'dtim_period' | ||||
|  | ||||
| Fixes gcc '-Wunused-but-set-variable' warning: | ||||
|  | ||||
| drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In function brcmf_update_bss_info: | ||||
| drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:2962:5: warning: variable dtim_period set but not used [-Wunused-but-set-variable] | ||||
| drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In function brcmf_update_bss_info: | ||||
| drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:2961:6: warning: variable beacon_interval set but not used [-Wunused-but-set-variable] | ||||
|  | ||||
| They are never used so can be removed. | ||||
|  | ||||
| Reported-by: Hulk Robot <hulkci@huawei.com> | ||||
| Signed-off-by: YueHaibing <yuehaibing@huawei.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c   | 8 +------- | ||||
|  1 file changed, 1 insertion(+), 7 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -2985,8 +2985,6 @@ static s32 brcmf_update_bss_info(struct | ||||
|  	struct brcmf_pub *drvr = cfg->pub; | ||||
|  	struct brcmf_bss_info_le *bi; | ||||
|  	const struct brcmf_tlv *tim; | ||||
| -	u16 beacon_interval; | ||||
| -	u8 dtim_period; | ||||
|  	size_t ie_len; | ||||
|  	u8 *ie; | ||||
|  	s32 err = 0; | ||||
| @@ -3010,12 +3008,9 @@ static s32 brcmf_update_bss_info(struct | ||||
|   | ||||
|  	ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset); | ||||
|  	ie_len = le32_to_cpu(bi->ie_length); | ||||
| -	beacon_interval = le16_to_cpu(bi->beacon_period); | ||||
|   | ||||
|  	tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM); | ||||
| -	if (tim) | ||||
| -		dtim_period = tim->data[1]; | ||||
| -	else { | ||||
| +	if (!tim) { | ||||
|  		/* | ||||
|  		* active scan was done so we could not get dtim | ||||
|  		* information out of probe response. | ||||
| @@ -3027,7 +3022,6 @@ static s32 brcmf_update_bss_info(struct | ||||
|  			bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err); | ||||
|  			goto update_bss_info_out; | ||||
|  		} | ||||
| -		dtim_period = (u8)var; | ||||
|  	} | ||||
|   | ||||
|  update_bss_info_out: | ||||
| @@ -0,0 +1,26 @@ | ||||
| From 73c742bb9c9ba30871fdd5c730d5ca8b6712833a Mon Sep 17 00:00:00 2001 | ||||
| From: Colin Ian King <colin.king@canonical.com> | ||||
| Date: Fri, 9 Aug 2019 18:22:17 +0100 | ||||
| Subject: [PATCH] brcmfmac: remove redundant assignment to pointer hash | ||||
|  | ||||
| The pointer hash is being initialized with a value that is never read | ||||
| and is being re-assigned a little later on. The assignment is | ||||
| redundant and hence can be removed. | ||||
|  | ||||
| Addresses-Coverity: ("Unused value") | ||||
| Signed-off-by: Colin Ian King <colin.king@canonical.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 1 - | ||||
|  1 file changed, 1 deletion(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | ||||
| @@ -1478,7 +1478,6 @@ static int brcmf_msgbuf_stats_read(struc | ||||
|  	seq_printf(seq, "\nh2d_flowrings: depth %u\n", | ||||
|  		   BRCMF_H2D_TXFLOWRING_MAX_ITEM); | ||||
|  	seq_puts(seq, "Active flowrings:\n"); | ||||
| -	hash = msgbuf->flow->hash; | ||||
|  	for (i = 0; i < msgbuf->flow->nrofrings; i++) { | ||||
|  		if (!msgbuf->flow->rings[i]) | ||||
|  			continue; | ||||
| @@ -0,0 +1,36 @@ | ||||
| From 5f42b382ead278c1f6c3854765c97eb20491aa2a Mon Sep 17 00:00:00 2001 | ||||
| From: Xulin Sun <xulin.sun@windriver.com> | ||||
| Date: Fri, 23 Aug 2019 15:47:08 +0800 | ||||
| Subject: [PATCH] brcmfmac: replace strncpy() by strscpy() | ||||
|  | ||||
| The strncpy() may truncate the copied string, | ||||
| replace it by the safer strscpy(). | ||||
|  | ||||
| To avoid below compile warning with gcc 8.2: | ||||
|  | ||||
| drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:In function 'brcmf_vndr_ie': | ||||
| drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:4227:2: | ||||
| warning: 'strncpy' output truncated before terminating nul copying 3 bytes from a string of the same length [-Wstringop-truncation] | ||||
|   strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); | ||||
|   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Signed-off-by: Xulin Sun <xulin.sun@windriver.com> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +--- | ||||
|  1 file changed, 1 insertion(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -4246,9 +4246,7 @@ next: | ||||
|  static u32 | ||||
|  brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) | ||||
|  { | ||||
| - | ||||
| -	strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); | ||||
| -	iebuf[VNDR_IE_CMD_LEN - 1] = '\0'; | ||||
| +	strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN); | ||||
|   | ||||
|  	put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]); | ||||
|   | ||||
| @@ -0,0 +1,80 @@ | ||||
| From 82f93cf46d6007ffa003b2d4a2834563b6b84d21 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Thu, 29 Aug 2019 10:27:01 +0200 | ||||
| Subject: [PATCH] brcmfmac: get chip's default RAM info during PCIe setup | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Getting RAM info just once per driver's lifetime (during chip | ||||
| recognition) is not enough as it may get adjusted later (depending on | ||||
| the used firmware). Subsequent inits may load different firmwares so a | ||||
| full RAM recognition is required on every PCIe setup. This is especially | ||||
| important since implementing hardware reset on a firmware crash. | ||||
|  | ||||
| Moreover calling brcmf_chip_get_raminfo() makes sure that RAM core is | ||||
| up. It's important as having BCMA_CORE_SYS_MEM down on BCM4366 was | ||||
| resulting in firmware failing to initialize and following error: | ||||
| [   65.657546] brcmfmac 0000:01:00.0: brcmf_pcie_download_fw_nvram: Invalid shared RAM address 0x04000001 | ||||
|  | ||||
| This change makes brcmf_chip_get_raminfo() call during chip recognition | ||||
| redundant for PCIe devices but SDIO and USB still need it and it's a | ||||
| very small overhead anyway. | ||||
|  | ||||
| Fixes: 4684997d9eea ("brcmfmac: reset PCIe bus on a firmware crash") | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 6 ++++-- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h | 1 + | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 6 ++++++ | ||||
|  3 files changed, 11 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | ||||
| @@ -700,8 +700,10 @@ static u32 brcmf_chip_tcm_rambase(struct | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| -static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) | ||||
| +int brcmf_chip_get_raminfo(struct brcmf_chip *pub) | ||||
|  { | ||||
| +	struct brcmf_chip_priv *ci = container_of(pub, struct brcmf_chip_priv, | ||||
| +						  pub); | ||||
|  	struct brcmf_core_priv *mem_core; | ||||
|  	struct brcmf_core *mem; | ||||
|   | ||||
| @@ -981,7 +983,7 @@ static int brcmf_chip_recognition(struct | ||||
|  		brcmf_chip_set_passive(&ci->pub); | ||||
|  	} | ||||
|   | ||||
| -	return brcmf_chip_get_raminfo(ci); | ||||
| +	return brcmf_chip_get_raminfo(&ci->pub); | ||||
|  } | ||||
|   | ||||
|  static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h | ||||
| @@ -80,6 +80,7 @@ struct brcmf_buscore_ops { | ||||
|  	void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); | ||||
|  }; | ||||
|   | ||||
| +int brcmf_chip_get_raminfo(struct brcmf_chip *pub); | ||||
|  struct brcmf_chip *brcmf_chip_attach(void *ctx, | ||||
|  				     const struct brcmf_buscore_ops *ops); | ||||
|  void brcmf_chip_detach(struct brcmf_chip *chip); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -1780,6 +1780,12 @@ static void brcmf_pcie_setup(struct devi | ||||
|  	nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; | ||||
|  	kfree(fwreq); | ||||
|   | ||||
| +	ret = brcmf_chip_get_raminfo(devinfo->ci); | ||||
| +	if (ret) { | ||||
| +		brcmf_err(bus, "Failed to get RAM info\n"); | ||||
| +		goto fail; | ||||
| +	} | ||||
| + | ||||
|  	/* Some of the firmwares have the size of the memory of the device | ||||
|  	 * defined inside the firmware. This is because part of the memory in | ||||
|  	 * the device is shared and the devision is determined by FW. Parse | ||||
| @@ -0,0 +1,31 @@ | ||||
| From cb34212b1c25f7656a315f956d72696777e88340 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Sun, 1 Sep 2019 13:34:35 +0200 | ||||
| Subject: [PATCH] brcmfmac: add stub version of brcmf_debugfs_get_devdir() | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| In case of compiling driver without DEBUG expose a stub function to make | ||||
| writing debug code much simpler (no extra conditions). This will allow | ||||
| e.g. using debugfs_create_file() without any magic if or #ifdef. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 4 ++++ | ||||
|  1 file changed, 4 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | ||||
| @@ -132,6 +132,10 @@ int brcmf_debugfs_add_entry(struct brcmf | ||||
|  int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, | ||||
|  			       size_t len); | ||||
|  #else | ||||
| +static inline struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) | ||||
| +{ | ||||
| +	return ERR_PTR(-ENOENT); | ||||
| +} | ||||
|  static inline | ||||
|  int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, | ||||
|  			    int (*read_fn)(struct seq_file *seq, void *data)) | ||||
| @@ -0,0 +1,59 @@ | ||||
| From 2f8c8e62cd50d72ac68de884a09c6f5a969a269c Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Sun, 1 Sep 2019 13:34:36 +0200 | ||||
| Subject: [PATCH] brcmfmac: add "reset" debugfs entry for testing reset | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This is a trivial debugfs entry for triggering reset just like in case | ||||
| of firmware crash. It works by writing 1 to it: | ||||
| echo 1 > reset | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/core.c        | 25 +++++++++++++++++++ | ||||
|  1 file changed, 25 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1117,6 +1117,29 @@ static void brcmf_core_bus_reset(struct | ||||
|  	brcmf_bus_reset(drvr->bus_if); | ||||
|  } | ||||
|   | ||||
| +static ssize_t bus_reset_write(struct file *file, const char __user *user_buf, | ||||
| +			       size_t count, loff_t *ppos) | ||||
| +{ | ||||
| +	struct brcmf_pub *drvr = file->private_data; | ||||
| +	u8 value; | ||||
| + | ||||
| +	if (kstrtou8_from_user(user_buf, count, 0, &value)) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	if (value != 1) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	schedule_work(&drvr->bus_reset); | ||||
| + | ||||
| +	return count; | ||||
| +} | ||||
| + | ||||
| +static const struct file_operations bus_reset_fops = { | ||||
| +	.open	= simple_open, | ||||
| +	.llseek	= no_llseek, | ||||
| +	.write	= bus_reset_write, | ||||
| +}; | ||||
| + | ||||
|  static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) | ||||
|  { | ||||
|  	int ret = -1; | ||||
| @@ -1192,6 +1215,8 @@ static int brcmf_bus_started(struct brcm | ||||
|   | ||||
|  	/* populate debugfs */ | ||||
|  	brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); | ||||
| +	debugfs_create_file("reset", 0600, brcmf_debugfs_get_devdir(drvr), drvr, | ||||
| +			    &bus_reset_fops); | ||||
|  	brcmf_feat_debugfs_create(drvr); | ||||
|  	brcmf_proto_debugfs_create(drvr); | ||||
|   | ||||
| @@ -0,0 +1,58 @@ | ||||
| From 0e48b86d9a8f5c695bb02c9c02f6dc7d2ec8f2e2 Mon Sep 17 00:00:00 2001 | ||||
| From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Date: Wed, 4 Sep 2019 20:50:52 +0300 | ||||
| Subject: [PATCH] brcmfmac: use %*ph to print small buffer | ||||
|  | ||||
| Use %*ph format to print small buffer as hex string. | ||||
|  | ||||
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c     | 18 ++++++------------ | ||||
|  1 file changed, 6 insertions(+), 12 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -4224,10 +4224,8 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_b | ||||
|   | ||||
|  		vndr_ies->count++; | ||||
|   | ||||
| -		brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n", | ||||
| -			  parsed_info->vndrie.oui[0], | ||||
| -			  parsed_info->vndrie.oui[1], | ||||
| -			  parsed_info->vndrie.oui[2], | ||||
| +		brcmf_dbg(TRACE, "** OUI %3ph, type 0x%02x\n", | ||||
| +			  parsed_info->vndrie.oui, | ||||
|  			  parsed_info->vndrie.oui_type); | ||||
|   | ||||
|  		if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT) | ||||
| @@ -4351,12 +4349,10 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c | ||||
|  		for (i = 0; i < old_vndr_ies.count; i++) { | ||||
|  			vndrie_info = &old_vndr_ies.ie_info[i]; | ||||
|   | ||||
| -			brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n", | ||||
| +			brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%3ph\n", | ||||
|  				  vndrie_info->vndrie.id, | ||||
|  				  vndrie_info->vndrie.len, | ||||
| -				  vndrie_info->vndrie.oui[0], | ||||
| -				  vndrie_info->vndrie.oui[1], | ||||
| -				  vndrie_info->vndrie.oui[2]); | ||||
| +				  vndrie_info->vndrie.oui); | ||||
|   | ||||
|  			del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag, | ||||
|  							   vndrie_info->ie_ptr, | ||||
| @@ -4388,12 +4384,10 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c | ||||
|  			remained_buf_len -= (vndrie_info->ie_len + | ||||
|  					     VNDR_IE_VSIE_OFFSET); | ||||
|   | ||||
| -			brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n", | ||||
| +			brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%3ph\n", | ||||
|  				  vndrie_info->vndrie.id, | ||||
|  				  vndrie_info->vndrie.len, | ||||
| -				  vndrie_info->vndrie.oui[0], | ||||
| -				  vndrie_info->vndrie.oui[1], | ||||
| -				  vndrie_info->vndrie.oui[2]); | ||||
| +				  vndrie_info->vndrie.oui); | ||||
|   | ||||
|  			del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag, | ||||
|  							   vndrie_info->ie_ptr, | ||||
| @@ -0,0 +1,95 @@ | ||||
| From ba76ff25ee64d5cfc86209d1fbb3c294b2c04412 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Tue, 3 Sep 2019 06:29:26 +0200 | ||||
| Subject: [PATCH 1/3] brcmfmac: move "cfg80211_ops" pointer to another struct | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This moves "ops" pointer from "struct brcmf_cfg80211_info" to the | ||||
| "struct brcmf_pub". This movement makes it possible to allocate wiphy | ||||
| without attaching cfg80211 (brcmf_cfg80211_attach()). It's required for | ||||
| later separation of wiphy allocation and driver initialization. | ||||
|  | ||||
| While at it fix also an unlikely memory leak in the brcmf_attach(). | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c  | 1 - | ||||
|  .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h  | 1 - | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c  | 9 ++++++--- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h  | 1 + | ||||
|  4 files changed, 7 insertions(+), 5 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -7186,7 +7186,6 @@ void brcmf_cfg80211_detach(struct brcmf_ | ||||
|  	brcmf_pno_detach(cfg); | ||||
|  	brcmf_btcoex_detach(cfg); | ||||
|  	wiphy_unregister(cfg->wiphy); | ||||
| -	kfree(cfg->ops); | ||||
|  	wl_deinit_priv(cfg); | ||||
|  	brcmf_free_wiphy(cfg->wiphy); | ||||
|  	kfree(cfg); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | ||||
| @@ -303,7 +303,6 @@ struct brcmf_cfg80211_wowl { | ||||
|   */ | ||||
|  struct brcmf_cfg80211_info { | ||||
|  	struct wiphy *wiphy; | ||||
| -	struct cfg80211_ops *ops; | ||||
|  	struct brcmf_cfg80211_conf *conf; | ||||
|  	struct brcmf_p2p_info p2p; | ||||
|  	struct brcmf_btcoex_info *btcoex; | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1254,12 +1254,15 @@ int brcmf_attach(struct device *dev, str | ||||
|  		return -ENOMEM; | ||||
|   | ||||
|  	wiphy = wiphy_new(ops, sizeof(*drvr)); | ||||
| -	if (!wiphy) | ||||
| +	if (!wiphy) { | ||||
| +		kfree(ops); | ||||
|  		return -ENOMEM; | ||||
| +	} | ||||
|   | ||||
|  	set_wiphy_dev(wiphy, dev); | ||||
|  	drvr = wiphy_priv(wiphy); | ||||
|  	drvr->wiphy = wiphy; | ||||
| +	drvr->ops = ops; | ||||
|   | ||||
|  	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) | ||||
|  		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; | ||||
| @@ -1292,12 +1295,10 @@ int brcmf_attach(struct device *dev, str | ||||
|  		goto fail; | ||||
|  	} | ||||
|   | ||||
| -	drvr->config->ops = ops; | ||||
|  	return 0; | ||||
|   | ||||
|  fail: | ||||
|  	brcmf_detach(dev); | ||||
| -	kfree(ops); | ||||
|   | ||||
|  	return ret; | ||||
|  } | ||||
| @@ -1383,6 +1384,8 @@ void brcmf_detach(struct device *dev) | ||||
|   | ||||
|  	bus_if->drvr = NULL; | ||||
|   | ||||
| +	kfree(drvr->ops); | ||||
| + | ||||
|  	wiphy_free(drvr->wiphy); | ||||
|  } | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | ||||
| @@ -108,6 +108,7 @@ struct brcmf_pub { | ||||
|  	struct brcmf_bus *bus_if; | ||||
|  	struct brcmf_proto *proto; | ||||
|  	struct wiphy *wiphy; | ||||
| +	struct cfg80211_ops *ops; | ||||
|  	struct brcmf_cfg80211_info *config; | ||||
|   | ||||
|  	/* Internal brcmf items */ | ||||
| @@ -0,0 +1,255 @@ | ||||
| From 450914c39f88d1adada26256360dea7050ff4e83 Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Tue, 3 Sep 2019 06:29:27 +0200 | ||||
| Subject: [PATCH 2/3] brcmfmac: split brcmf_attach() and brcmf_detach() | ||||
|  functions | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Move code allocating/freeing wiphy out of above functions. This will | ||||
| allow reinitializing the driver (e.g. on some error) without allocating | ||||
| a new wiphy. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  .../broadcom/brcm80211/brcmfmac/bus.h         |  4 ++- | ||||
|  .../broadcom/brcm80211/brcmfmac/core.c        | 33 ++++++++++++++---- | ||||
|  .../broadcom/brcm80211/brcmfmac/pcie.c        | 13 +++++-- | ||||
|  .../broadcom/brcm80211/brcmfmac/sdio.c        | 15 ++++++-- | ||||
|  .../broadcom/brcm80211/brcmfmac/usb.c         | 34 +++++++++++++++---- | ||||
|  5 files changed, 80 insertions(+), 19 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | ||||
| @@ -254,10 +254,12 @@ void brcmf_rx_frame(struct device *dev, | ||||
|  /* Receive async event packet from firmware. Callee disposes of rxp. */ | ||||
|  void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); | ||||
|   | ||||
| +int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings); | ||||
|  /* Indication from bus module regarding presence/insertion of dongle. */ | ||||
| -int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); | ||||
| +int brcmf_attach(struct device *dev); | ||||
|  /* Indication from bus module regarding removal/absence of dongle */ | ||||
|  void brcmf_detach(struct device *dev); | ||||
| +void brcmf_free(struct device *dev); | ||||
|  /* Indication from bus module that dongle should be reset */ | ||||
|  void brcmf_dev_reset(struct device *dev); | ||||
|  /* Request from bus module to initiate a coredump */ | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1239,13 +1239,11 @@ fail: | ||||
|  	return ret; | ||||
|  } | ||||
|   | ||||
| -int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) | ||||
| +int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings) | ||||
|  { | ||||
|  	struct wiphy *wiphy; | ||||
|  	struct cfg80211_ops *ops; | ||||
|  	struct brcmf_pub *drvr = NULL; | ||||
| -	int ret = 0; | ||||
| -	int i; | ||||
|   | ||||
|  	brcmf_dbg(TRACE, "Enter\n"); | ||||
|   | ||||
| @@ -1263,6 +1261,21 @@ int brcmf_attach(struct device *dev, str | ||||
|  	drvr = wiphy_priv(wiphy); | ||||
|  	drvr->wiphy = wiphy; | ||||
|  	drvr->ops = ops; | ||||
| +	drvr->bus_if = dev_get_drvdata(dev); | ||||
| +	drvr->bus_if->drvr = drvr; | ||||
| +	drvr->settings = settings; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +int brcmf_attach(struct device *dev) | ||||
| +{ | ||||
| +	struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||||
| +	struct brcmf_pub *drvr = bus_if->drvr; | ||||
| +	int ret = 0; | ||||
| +	int i; | ||||
| + | ||||
| +	brcmf_dbg(TRACE, "Enter\n"); | ||||
|   | ||||
|  	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) | ||||
|  		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; | ||||
| @@ -1271,9 +1284,6 @@ int brcmf_attach(struct device *dev, str | ||||
|   | ||||
|  	/* Link to bus module */ | ||||
|  	drvr->hdrlen = 0; | ||||
| -	drvr->bus_if = dev_get_drvdata(dev); | ||||
| -	drvr->bus_if->drvr = drvr; | ||||
| -	drvr->settings = settings; | ||||
|   | ||||
|  	/* Attach and link in the protocol */ | ||||
|  	ret = brcmf_proto_attach(drvr); | ||||
| @@ -1289,7 +1299,7 @@ int brcmf_attach(struct device *dev, str | ||||
|  	/* attach firmware event handler */ | ||||
|  	brcmf_fweh_attach(drvr); | ||||
|   | ||||
| -	ret = brcmf_bus_started(drvr, ops); | ||||
| +	ret = brcmf_bus_started(drvr, drvr->ops); | ||||
|  	if (ret != 0) { | ||||
|  		bphy_err(drvr, "dongle is not responding: err=%d\n", ret); | ||||
|  		goto fail; | ||||
| @@ -1381,6 +1391,15 @@ void brcmf_detach(struct device *dev) | ||||
|  		brcmf_cfg80211_detach(drvr->config); | ||||
|  		drvr->config = NULL; | ||||
|  	} | ||||
| +} | ||||
| + | ||||
| +void brcmf_free(struct device *dev) | ||||
| +{ | ||||
| +	struct brcmf_bus *bus_if = dev_get_drvdata(dev); | ||||
| +	struct brcmf_pub *drvr = bus_if->drvr; | ||||
| + | ||||
| +	if (!drvr) | ||||
| +		return; | ||||
|   | ||||
|  	bus_if->drvr = NULL; | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -1440,6 +1440,7 @@ static int brcmf_pcie_reset(struct devic | ||||
|  	brcmf_pcie_bus_console_read(devinfo, true); | ||||
|   | ||||
|  	brcmf_detach(dev); | ||||
| +	brcmf_free(dev); | ||||
|   | ||||
|  	brcmf_pcie_release_irq(devinfo); | ||||
|  	brcmf_pcie_release_scratchbuffers(devinfo); | ||||
| @@ -1834,11 +1835,18 @@ static void brcmf_pcie_setup(struct devi | ||||
|   | ||||
|  	brcmf_pcie_intr_enable(devinfo); | ||||
|  	brcmf_pcie_hostready(devinfo); | ||||
| -	if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) | ||||
| -		return; | ||||
| + | ||||
| +	ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); | ||||
| +	if (ret) | ||||
| +		goto fail; | ||||
| +	ret = brcmf_attach(&devinfo->pdev->dev); | ||||
| +	if (ret) | ||||
| +		goto fail; | ||||
|   | ||||
|  	brcmf_pcie_bus_console_read(devinfo, false); | ||||
|   | ||||
| +	return; | ||||
| + | ||||
|  fail: | ||||
|  	device_release_driver(dev); | ||||
|  } | ||||
| @@ -1981,6 +1989,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) | ||||
|  		brcmf_pcie_intr_disable(devinfo); | ||||
|   | ||||
|  	brcmf_detach(&pdev->dev); | ||||
| +	brcmf_free(&pdev->dev); | ||||
|   | ||||
|  	kfree(bus->bus_priv.pcie); | ||||
|  	kfree(bus->msgbuf->flowrings); | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | ||||
| @@ -4140,10 +4140,17 @@ static void brcmf_sdio_firmware_callback | ||||
|  	sdiod->bus_if->chip = bus->ci->chip; | ||||
|  	sdiod->bus_if->chiprev = bus->ci->chiprev; | ||||
|   | ||||
| +	err = brcmf_alloc(sdiod->dev, sdiod->settings); | ||||
| +	if (err) { | ||||
| +		brcmf_err("brcmf_alloc failed\n"); | ||||
| +		goto fail; | ||||
| +	} | ||||
| + | ||||
|  	/* Attach to the common layer, reserve hdr space */ | ||||
| -	err = brcmf_attach(sdiod->dev, sdiod->settings); | ||||
| +	err = brcmf_attach(sdiod->dev); | ||||
|  	if (err != 0) { | ||||
|  		brcmf_err("brcmf_attach failed\n"); | ||||
| +		brcmf_free(sdiod->dev); | ||||
|  		goto fail; | ||||
|  	} | ||||
|   | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | ||||
| @@ -1191,8 +1191,12 @@ static void brcmf_usb_probe_phase2(struc | ||||
|  	if (ret) | ||||
|  		goto error; | ||||
|   | ||||
| +	ret = brcmf_alloc(devinfo->dev, devinfo->settings); | ||||
| +	if (ret) | ||||
| +		goto error; | ||||
| + | ||||
|  	/* Attach to the common driver interface */ | ||||
| -	ret = brcmf_attach(devinfo->dev, devinfo->settings); | ||||
| +	ret = brcmf_attach(devinfo->dev); | ||||
|  	if (ret) | ||||
|  		goto error; | ||||
|   | ||||
| @@ -1264,7 +1268,10 @@ static int brcmf_usb_probe_cb(struct brc | ||||
|  	} | ||||
|   | ||||
|  	if (!brcmf_usb_dlneeded(devinfo)) { | ||||
| -		ret = brcmf_attach(devinfo->dev, devinfo->settings); | ||||
| +		ret = brcmf_alloc(devinfo->dev, devinfo->settings); | ||||
| +		if (ret) | ||||
| +			goto fail; | ||||
| +		ret = brcmf_attach(devinfo->dev); | ||||
|  		if (ret) | ||||
|  			goto fail; | ||||
|  		/* we are done */ | ||||
| @@ -1292,6 +1299,7 @@ static int brcmf_usb_probe_cb(struct brc | ||||
|   | ||||
|  fail: | ||||
|  	/* Release resources in reverse order */ | ||||
| +	brcmf_free(devinfo->dev); | ||||
|  	kfree(bus); | ||||
|  	brcmf_usb_detach(devinfo); | ||||
|  	return ret; | ||||
| @@ -1305,6 +1313,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usb | ||||
|  	brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); | ||||
|   | ||||
|  	brcmf_detach(devinfo->dev); | ||||
| +	brcmf_free(devinfo->dev); | ||||
|  	kfree(devinfo->bus_pub.bus); | ||||
|  	brcmf_usb_detach(devinfo); | ||||
|  } | ||||
| @@ -1449,10 +1458,12 @@ static int brcmf_usb_suspend(struct usb_ | ||||
|   | ||||
|  	brcmf_dbg(USB, "Enter\n"); | ||||
|  	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; | ||||
| -	if (devinfo->wowl_enabled) | ||||
| +	if (devinfo->wowl_enabled) { | ||||
|  		brcmf_cancel_all_urbs(devinfo); | ||||
| -	else | ||||
| +	} else { | ||||
|  		brcmf_detach(&usb->dev); | ||||
| +		brcmf_free(&usb->dev); | ||||
| +	} | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -1465,8 +1476,19 @@ static int brcmf_usb_resume(struct usb_i | ||||
|  	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | ||||
|   | ||||
|  	brcmf_dbg(USB, "Enter\n"); | ||||
| -	if (!devinfo->wowl_enabled) | ||||
| -		return brcmf_attach(devinfo->dev, devinfo->settings); | ||||
| +	if (!devinfo->wowl_enabled) { | ||||
| +		int err; | ||||
| + | ||||
| +		err = brcmf_alloc(&usb->dev, devinfo->settings); | ||||
| +		if (err) | ||||
| +			return err; | ||||
| + | ||||
| +		err = brcmf_attach(devinfo->dev); | ||||
| +		if (err) { | ||||
| +			brcmf_free(devinfo->dev); | ||||
| +			return err; | ||||
| +		} | ||||
| +	} | ||||
|   | ||||
|  	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP; | ||||
|  	brcmf_usb_rx_fill_all(devinfo); | ||||
| @@ -0,0 +1,51 @@ | ||||
| From a1f5aac1765afbeace9581afa27da34085f68e1d Mon Sep 17 00:00:00 2001 | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Tue, 3 Sep 2019 06:29:28 +0200 | ||||
| Subject: [PATCH 3/3] brcmfmac: don't realloc wiphy during PCIe reset | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Providing a new wiphy on every PCIe reset was confusing and was causing | ||||
| configuration problems for some users (supplicant and authenticators). | ||||
| Sticking to the existing wiphy should make error recovery much simpler | ||||
| and more reliable. | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com> | ||||
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++---- | ||||
|  1 file changed, 4 insertions(+), 4 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -1440,7 +1440,6 @@ static int brcmf_pcie_reset(struct devic | ||||
|  	brcmf_pcie_bus_console_read(devinfo, true); | ||||
|   | ||||
|  	brcmf_detach(dev); | ||||
| -	brcmf_free(dev); | ||||
|   | ||||
|  	brcmf_pcie_release_irq(devinfo); | ||||
|  	brcmf_pcie_release_scratchbuffers(devinfo); | ||||
| @@ -1836,9 +1835,6 @@ static void brcmf_pcie_setup(struct devi | ||||
|  	brcmf_pcie_intr_enable(devinfo); | ||||
|  	brcmf_pcie_hostready(devinfo); | ||||
|   | ||||
| -	ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); | ||||
| -	if (ret) | ||||
| -		goto fail; | ||||
|  	ret = brcmf_attach(&devinfo->pdev->dev); | ||||
|  	if (ret) | ||||
|  		goto fail; | ||||
| @@ -1941,6 +1937,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c | ||||
|  	bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); | ||||
|  	dev_set_drvdata(&pdev->dev, bus); | ||||
|   | ||||
| +	ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); | ||||
| +	if (ret) | ||||
| +		goto fail_bus; | ||||
| + | ||||
|  	fwreq = brcmf_pcie_prepare_fw_request(devinfo); | ||||
|  	if (!fwreq) { | ||||
|  		ret = -ENOMEM; | ||||
| @@ -0,0 +1,54 @@ | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 18 Nov 2019 11:52:41 +0100 | ||||
| Subject: [PATCH FIX] brcmfmac: disable PCIe interrupts before bus reset | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| Keeping interrupts on could result in brcmfmac freeing some resources | ||||
| and then IRQ handlers trying to use them. That was obviously a straight | ||||
| path for crashing a kernel. | ||||
|  | ||||
| Example: | ||||
| CPU0                           CPU1 | ||||
| ----                           ---- | ||||
| brcmf_pcie_reset | ||||
|   brcmf_pcie_bus_console_read | ||||
|   brcmf_detach | ||||
|     ... | ||||
|     brcmf_fweh_detach | ||||
|     brcmf_proto_detach | ||||
|                                brcmf_pcie_isr_thread | ||||
|                                  ... | ||||
|                                  brcmf_proto_msgbuf_rx_trigger | ||||
|                                    ... | ||||
|                                    drvr->proto->pd | ||||
|     brcmf_pcie_release_irq | ||||
|  | ||||
| [  363.789218] Unable to handle kernel NULL pointer dereference at virtual address 00000038 | ||||
| [  363.797339] pgd = c0004000 | ||||
| [  363.800050] [00000038] *pgd=00000000 | ||||
| [  363.803635] Internal error: Oops: 17 [#1] SMP ARM | ||||
| (...) | ||||
| [  364.029209] Backtrace: | ||||
| [  364.031725] [<bf243838>] (brcmf_proto_msgbuf_rx_trigger [brcmfmac]) from [<bf2471dc>] (brcmf_pcie_isr_thread+0x228/0x274 [brcmfmac]) | ||||
| [  364.043662]  r7:00000001 r6:c8ca0000 r5:00010000 r4:c7b4f800 | ||||
|  | ||||
| Fixes: 4684997d9eea ("brcmfmac: reset PCIe bus on a firmware crash") | ||||
| Cc: stable@vger.kernel.org # v5.2+ | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 ++ | ||||
|  1 file changed, 2 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | ||||
| @@ -1437,6 +1437,8 @@ static int brcmf_pcie_reset(struct devic | ||||
|  	struct brcmf_fw_request *fwreq; | ||||
|  	int err; | ||||
|   | ||||
| +	brcmf_pcie_intr_disable(devinfo); | ||||
| + | ||||
|  	brcmf_pcie_bus_console_read(devinfo, true); | ||||
|   | ||||
|  	brcmf_detach(dev); | ||||
| @@ -0,0 +1,30 @@ | ||||
| From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||
| Date: Mon, 18 Nov 2019 13:35:20 +0100 | ||||
| Subject: [PATCH 5.5] brcmfmac: remove monitor interface when detaching | ||||
| MIME-Version: 1.0 | ||||
| Content-Type: text/plain; charset=UTF-8 | ||||
| Content-Transfer-Encoding: 8bit | ||||
|  | ||||
| This fixes a minor WARNING in the cfg80211: | ||||
| [  130.658034] ------------[ cut here ]------------ | ||||
| [  130.662805] WARNING: CPU: 1 PID: 610 at net/wireless/core.c:954 wiphy_unregister+0xb4/0x198 [cfg80211] | ||||
|  | ||||
| Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||
| --- | ||||
|  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++++ | ||||
|  1 file changed, 5 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1380,6 +1380,11 @@ void brcmf_detach(struct device *dev) | ||||
|  	brcmf_fweh_detach(drvr); | ||||
|  	brcmf_proto_detach(drvr); | ||||
|   | ||||
| +	if (drvr->mon_if) { | ||||
| +		brcmf_net_detach(drvr->mon_if->ndev, false); | ||||
| +		drvr->mon_if = NULL; | ||||
| +	} | ||||
| + | ||||
|  	/* make sure primary interface removed last */ | ||||
|  	for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { | ||||
|  		if (drvr->iflist[i]) | ||||
| @@ -87,7 +87,7 @@ | ||||
|  	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) | ||||
| --- a/net/mac80211/ieee80211_i.h | ||||
| +++ b/net/mac80211/ieee80211_i.h | ||||
| @@ -1348,6 +1348,7 @@ struct ieee80211_local { | ||||
| @@ -1350,6 +1350,7 @@ struct ieee80211_local { | ||||
|  	int dynamic_ps_forced_timeout; | ||||
|   | ||||
|  	int user_power_level; /* in dBm, for all interfaces */ | ||||
|   | ||||
| @@ -45,7 +45,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  #ifdef CPTCFG_ATH9K_DEBUGFS | ||||
| --- a/drivers/net/wireless/ath/ath9k/gpio.c | ||||
| +++ b/drivers/net/wireless/ath/ath9k/gpio.c | ||||
| @@ -16,13 +16,130 @@ | ||||
| @@ -16,13 +16,139 @@ | ||||
|   | ||||
|  #include "ath9k.h" | ||||
|  #include <linux/ath9k_platform.h> | ||||
| @@ -126,7 +126,13 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
| +	gc->sc = sc; | ||||
| +	snprintf(gc->label, sizeof(gc->label), "ath9k-%s", | ||||
| +		 wiphy_name(sc->hw->wiphy)); | ||||
| + | ||||
| +#ifdef CONFIG_OF | ||||
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) | ||||
| +	gc->gchip.parent = sc->dev; | ||||
| +#else | ||||
| +	gc->gchip.dev = sc->dev; | ||||
| +#endif | ||||
| +#endif | ||||
| +	gc->gchip.label = gc->label; | ||||
| +	gc->gchip.base = -1;	/* determine base automatically */ | ||||
| +	gc->gchip.ngpio = ah->caps.num_gpio_pins; | ||||
| @@ -141,6 +147,9 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
| +		return; | ||||
| +	} | ||||
| + | ||||
| +#ifdef CONFIG_OF | ||||
| +	gc->gchip.owner = NULL; | ||||
| +#endif | ||||
| +	sc->gpiochip = gc; | ||||
| +} | ||||
| + | ||||
| @@ -178,7 +187,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  static void ath_fill_led_pin(struct ath_softc *sc) | ||||
|  { | ||||
|  	struct ath_hw *ah = sc->sc_ah; | ||||
| @@ -80,6 +197,12 @@ static int ath_add_led(struct ath_softc | ||||
| @@ -80,6 +206,12 @@ static int ath_add_led(struct ath_softc | ||||
|  	else | ||||
|  		ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); | ||||
|   | ||||
| @@ -191,7 +200,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -136,17 +259,24 @@ void ath_deinit_leds(struct ath_softc *s | ||||
| @@ -136,17 +268,24 @@ void ath_deinit_leds(struct ath_softc *s | ||||
|   | ||||
|  	while (!list_empty(&sc->leds)) { | ||||
|  		led = list_first_entry(&sc->leds, struct ath_led, list); | ||||
| @@ -216,7 +225,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	char led_name[32]; | ||||
|  	const char *trigger; | ||||
|  	int i; | ||||
| @@ -156,6 +286,15 @@ void ath_init_leds(struct ath_softc *sc) | ||||
| @@ -156,6 +295,15 @@ void ath_init_leds(struct ath_softc *sc) | ||||
|  	if (AR_SREV_9100(sc->sc_ah)) | ||||
|  		return; | ||||
|   | ||||
| @@ -232,7 +241,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	ath_fill_led_pin(sc); | ||||
|   | ||||
|  	if (pdata && pdata->leds && pdata->num_leds) | ||||
| @@ -180,6 +319,7 @@ void ath_init_leds(struct ath_softc *sc) | ||||
| @@ -180,6 +328,7 @@ void ath_init_leds(struct ath_softc *sc) | ||||
|  	ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, | ||||
|  			   !sc->sc_ah->config.led_active_high); | ||||
|  } | ||||
|   | ||||
| @@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|   | ||||
|  #ifdef CPTCFG_MAC80211_LEDS | ||||
|   | ||||
| @@ -124,6 +126,67 @@ static void ath9k_unregister_gpio_chip(s | ||||
| @@ -133,6 +135,67 @@ static void ath9k_unregister_gpio_chip(s | ||||
|  	sc->gpiochip = NULL; | ||||
|  } | ||||
|   | ||||
| @@ -97,7 +97,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  #else /* CONFIG_GPIOLIB */ | ||||
|   | ||||
|  static inline void ath9k_register_gpio_chip(struct ath_softc *sc) | ||||
| @@ -134,6 +197,14 @@ static inline void ath9k_unregister_gpio | ||||
| @@ -143,6 +206,14 @@ static inline void ath9k_unregister_gpio | ||||
|  { | ||||
|  } | ||||
|   | ||||
| @@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  #endif /* CONFIG_GPIOLIB */ | ||||
|   | ||||
|  /********************************/ | ||||
| @@ -257,6 +328,7 @@ void ath_deinit_leds(struct ath_softc *s | ||||
| @@ -266,6 +337,7 @@ void ath_deinit_leds(struct ath_softc *s | ||||
|  { | ||||
|  	struct ath_led *led; | ||||
|   | ||||
| @@ -120,7 +120,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||
|  	while (!list_empty(&sc->leds)) { | ||||
|  		led = list_first_entry(&sc->leds, struct ath_led, list); | ||||
|  #ifdef CONFIG_GPIOLIB | ||||
| @@ -296,6 +368,7 @@ void ath_init_leds(struct ath_softc *sc) | ||||
| @@ -305,6 +377,7 @@ void ath_init_leds(struct ath_softc *sc) | ||||
|  	} | ||||
|   | ||||
|  	ath_fill_led_pin(sc); | ||||
|   | ||||
| @@ -0,0 +1,94 @@ | ||||
| From 4420866ef1b602682b009e0186fbb8aefd2125be Mon Sep 17 00:00:00 2001 | ||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| Date: Tue, 20 Aug 2019 18:20:19 +0200 | ||||
| Subject: [PATCH 1/4] ath9k: dynack: introduce ath_dynack_set_timeout routine | ||||
|  | ||||
| Introduce ath_dynack_set_timeout routine to configure slottime/ack/cts | ||||
| timeouts and remove duplicated code | ||||
|  | ||||
| Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com> | ||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| --- | ||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 37 ++++++++++++++----------- | ||||
|  1 file changed, 21 insertions(+), 16 deletions(-) | ||||
|  | ||||
| diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| index f112fa5b2eac..38dbe25919f7 100644 | ||||
| --- a/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| +++ b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| @@ -78,6 +78,24 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) | ||||
|  	return true; | ||||
|  } | ||||
|   | ||||
| +/** | ||||
| + * ath_dynack_set_timeout - configure timeouts/slottime registers | ||||
| + * @ah: ath hw | ||||
| + * @to: timeout value | ||||
| + * | ||||
| + */ | ||||
| +static void ath_dynack_set_timeout(struct ath_hw *ah, int to) | ||||
| +{ | ||||
| +	struct ath_common *common = ath9k_hw_common(ah); | ||||
| +	int slottime = (to - 3) / 2; | ||||
| + | ||||
| +	ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n", | ||||
| +		to, slottime); | ||||
| +	ath9k_hw_setslottime(ah, slottime); | ||||
| +	ath9k_hw_set_ack_timeout(ah, to); | ||||
| +	ath9k_hw_set_cts_timeout(ah, to); | ||||
| +} | ||||
| + | ||||
|  /** | ||||
|   * ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout | ||||
|   * @ah: ath hw | ||||
| @@ -86,7 +104,6 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) | ||||
|   */ | ||||
|  static void ath_dynack_compute_ackto(struct ath_hw *ah) | ||||
|  { | ||||
| -	struct ath_common *common = ath9k_hw_common(ah); | ||||
|  	struct ath_dynack *da = &ah->dynack; | ||||
|  	struct ath_node *an; | ||||
|  	int to = 0; | ||||
| @@ -96,15 +113,8 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah) | ||||
|  			to = an->ackto; | ||||
|   | ||||
|  	if (to && da->ackto != to) { | ||||
| -		u32 slottime; | ||||
| - | ||||
| -		slottime = (to - 3) / 2; | ||||
| +		ath_dynack_set_timeout(ah, to); | ||||
|  		da->ackto = to; | ||||
| -		ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n", | ||||
| -			da->ackto, slottime); | ||||
| -		ath9k_hw_setslottime(ah, slottime); | ||||
| -		ath9k_hw_set_ack_timeout(ah, da->ackto); | ||||
| -		ath9k_hw_set_cts_timeout(ah, da->ackto); | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| @@ -198,10 +208,7 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, | ||||
|  		    ieee80211_is_assoc_resp(hdr->frame_control) || | ||||
|  		    ieee80211_is_auth(hdr->frame_control)) { | ||||
|  			ath_dbg(common, DYNACK, "late ack\n"); | ||||
| - | ||||
| -			ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2); | ||||
| -			ath9k_hw_set_ack_timeout(ah, LATEACK_TO); | ||||
| -			ath9k_hw_set_cts_timeout(ah, LATEACK_TO); | ||||
| +			ath_dynack_set_timeout(ah, LATEACK_TO); | ||||
|  			if (sta) { | ||||
|  				struct ath_node *an; | ||||
|   | ||||
| @@ -340,9 +347,7 @@ void ath_dynack_reset(struct ath_hw *ah) | ||||
|  	da->ack_rbf.h_rb = 0; | ||||
|   | ||||
|  	/* init acktimeout */ | ||||
| -	ath9k_hw_setslottime(ah, (ackto - 3) / 2); | ||||
| -	ath9k_hw_set_ack_timeout(ah, ackto); | ||||
| -	ath9k_hw_set_cts_timeout(ah, ackto); | ||||
| +	ath_dynack_set_timeout(ah, ackto); | ||||
|  } | ||||
|  EXPORT_SYMBOL(ath_dynack_reset); | ||||
|   | ||||
| --  | ||||
| 2.17.1 | ||||
|  | ||||
| @@ -0,0 +1,32 @@ | ||||
| From e5b56ce50eab31d24df6a70cf025db3acc4aa3ac Mon Sep 17 00:00:00 2001 | ||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| Date: Tue, 20 Aug 2019 18:20:20 +0200 | ||||
| Subject: [PATCH 2/4] ath9k: dynack: properly set last timeout timestamp in | ||||
|  ath_dynack_reset | ||||
|  | ||||
| Add compute timeout to last computation timestamp in | ||||
| ath_dynack_reset in order to not run ath_dynack_compute_ackto | ||||
| immediately | ||||
|  | ||||
| Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com> | ||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| --- | ||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 2 +- | ||||
|  1 file changed, 1 insertion(+), 1 deletion(-) | ||||
|  | ||||
| diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| index 38dbe25919f7..398ea872751f 100644 | ||||
| --- a/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| +++ b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| @@ -338,7 +338,7 @@ void ath_dynack_reset(struct ath_hw *ah) | ||||
|  	u32 ackto = 9 + 16 + 64; | ||||
|  	struct ath_dynack *da = &ah->dynack; | ||||
|   | ||||
| -	da->lto = jiffies; | ||||
| +	da->lto = jiffies + COMPUTE_TO; | ||||
|  	da->ackto = ackto; | ||||
|   | ||||
|  	da->st_rbf.t_rb = 0; | ||||
| --  | ||||
| 2.17.1 | ||||
|  | ||||
| @@ -0,0 +1,96 @@ | ||||
| From 3f737abb7d53cc80d619a3b4a30b6fa63cdc8df7 Mon Sep 17 00:00:00 2001 | ||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| Date: Tue, 20 Aug 2019 18:20:21 +0200 | ||||
| Subject: [PATCH 3/4] ath9k: dynack: set max timeout according to channel width | ||||
|  | ||||
| Compute maximum configurable ackimeout/ctstimeout according to channel | ||||
| width (clockrate) | ||||
|  | ||||
| Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com> | ||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| --- | ||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 38 +++++++++++++++++++------ | ||||
|  1 file changed, 30 insertions(+), 8 deletions(-) | ||||
|  | ||||
| diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| index 398ea872751f..fe9181533de3 100644 | ||||
| --- a/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| +++ b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| @@ -20,11 +20,30 @@ | ||||
|   | ||||
|  #define COMPUTE_TO		(5 * HZ) | ||||
|  #define LATEACK_DELAY		(10 * HZ) | ||||
| -#define LATEACK_TO		256 | ||||
| -#define MAX_DELAY		300 | ||||
|  #define EWMA_LEVEL		96 | ||||
|  #define EWMA_DIV		128 | ||||
|   | ||||
| +/** | ||||
| + * ath_dynack_get_max_to - set max timeout according to channel width | ||||
| + * @ah: ath hw | ||||
| + * | ||||
| + */ | ||||
| +static u32 ath_dynack_get_max_to(struct ath_hw *ah) | ||||
| +{ | ||||
| +	const struct ath9k_channel *chan = ah->curchan; | ||||
| + | ||||
| +	if (!chan) | ||||
| +		return 300; | ||||
| + | ||||
| +	if (IS_CHAN_HT40(chan)) | ||||
| +		return 300; | ||||
| +	if (IS_CHAN_HALF_RATE(chan)) | ||||
| +		return 750; | ||||
| +	if (IS_CHAN_QUARTER_RATE(chan)) | ||||
| +		return 1500; | ||||
| +	return 600; | ||||
| +} | ||||
| + | ||||
|  /** | ||||
|   * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation | ||||
|   * | ||||
| @@ -126,15 +145,16 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah) | ||||
|   */ | ||||
|  static void ath_dynack_compute_to(struct ath_hw *ah) | ||||
|  { | ||||
| -	u32 ackto, ack_ts; | ||||
| -	u8 *dst, *src; | ||||
| +	struct ath_dynack *da = &ah->dynack; | ||||
| +	u32 ackto, ack_ts, max_to; | ||||
|  	struct ieee80211_sta *sta; | ||||
| -	struct ath_node *an; | ||||
|  	struct ts_info *st_ts; | ||||
| -	struct ath_dynack *da = &ah->dynack; | ||||
| +	struct ath_node *an; | ||||
| +	u8 *dst, *src; | ||||
|   | ||||
|  	rcu_read_lock(); | ||||
|   | ||||
| +	max_to = ath_dynack_get_max_to(ah); | ||||
|  	while (da->st_rbf.h_rb != da->st_rbf.t_rb && | ||||
|  	       da->ack_rbf.h_rb != da->ack_rbf.t_rb) { | ||||
|  		ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb]; | ||||
| @@ -150,7 +170,7 @@ static void ath_dynack_compute_to(struct ath_hw *ah) | ||||
|  		if (ack_ts > st_ts->tstamp + st_ts->dur) { | ||||
|  			ackto = ack_ts - st_ts->tstamp - st_ts->dur; | ||||
|   | ||||
| -			if (ackto < MAX_DELAY) { | ||||
| +			if (ackto < max_to) { | ||||
|  				sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst, | ||||
|  								   src); | ||||
|  				if (sta) { | ||||
| @@ -207,8 +227,10 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, | ||||
|  		if (ieee80211_is_assoc_req(hdr->frame_control) || | ||||
|  		    ieee80211_is_assoc_resp(hdr->frame_control) || | ||||
|  		    ieee80211_is_auth(hdr->frame_control)) { | ||||
| +			u32 max_to = ath_dynack_get_max_to(ah); | ||||
| + | ||||
|  			ath_dbg(common, DYNACK, "late ack\n"); | ||||
| -			ath_dynack_set_timeout(ah, LATEACK_TO); | ||||
| +			ath_dynack_set_timeout(ah, max_to); | ||||
|  			if (sta) { | ||||
|  				struct ath_node *an; | ||||
|   | ||||
| --  | ||||
| 2.17.1 | ||||
|  | ||||
| @@ -0,0 +1,78 @@ | ||||
| From cc783bfa67e87d2e6206f7626b7bbb74d5c5f269 Mon Sep 17 00:00:00 2001 | ||||
| From: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| Date: Tue, 20 Aug 2019 18:20:22 +0200 | ||||
| Subject: [PATCH 4/4] ath9k: dynack: set ackto to max timeout in | ||||
|  ath_dynack_reset | ||||
|  | ||||
| Initialize acktimeout to the maximum configurable value in | ||||
| ath_dynack_reset in order to not disconnect long distance static links | ||||
| enabling dynack and even to take care of possible errors configuring | ||||
| a static timeout. Moreover initialize station timeout value to the current | ||||
| acktimeout value | ||||
|  | ||||
| Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com> | ||||
| Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> | ||||
| --- | ||||
|  drivers/net/wireless/ath/ath9k/dynack.c | 20 +++++++++++++------- | ||||
|  1 file changed, 13 insertions(+), 7 deletions(-) | ||||
|  | ||||
| diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| index fe9181533de3..f786be04d0ac 100644 | ||||
| --- a/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| +++ b/drivers/net/wireless/ath/ath9k/dynack.c | ||||
| @@ -321,11 +321,9 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts); | ||||
|   */ | ||||
|  void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) | ||||
|  { | ||||
| -	/* ackto = slottime + sifs + air delay */ | ||||
| -	u32 ackto = 9 + 16 + 64; | ||||
|  	struct ath_dynack *da = &ah->dynack; | ||||
|   | ||||
| -	an->ackto = ackto; | ||||
| +	an->ackto = da->ackto; | ||||
|   | ||||
|  	spin_lock(&da->qlock); | ||||
|  	list_add_tail(&an->list, &da->nodes); | ||||
| @@ -356,20 +354,26 @@ EXPORT_SYMBOL(ath_dynack_node_deinit); | ||||
|   */ | ||||
|  void ath_dynack_reset(struct ath_hw *ah) | ||||
|  { | ||||
| -	/* ackto = slottime + sifs + air delay */ | ||||
| -	u32 ackto = 9 + 16 + 64; | ||||
|  	struct ath_dynack *da = &ah->dynack; | ||||
| +	struct ath_node *an; | ||||
| + | ||||
| +	spin_lock_bh(&da->qlock); | ||||
|   | ||||
|  	da->lto = jiffies + COMPUTE_TO; | ||||
| -	da->ackto = ackto; | ||||
|   | ||||
|  	da->st_rbf.t_rb = 0; | ||||
|  	da->st_rbf.h_rb = 0; | ||||
|  	da->ack_rbf.t_rb = 0; | ||||
|  	da->ack_rbf.h_rb = 0; | ||||
|   | ||||
| +	da->ackto = ath_dynack_get_max_to(ah); | ||||
| +	list_for_each_entry(an, &da->nodes, list) | ||||
| +		an->ackto = da->ackto; | ||||
| + | ||||
|  	/* init acktimeout */ | ||||
| -	ath_dynack_set_timeout(ah, ackto); | ||||
| +	ath_dynack_set_timeout(ah, da->ackto); | ||||
| + | ||||
| +	spin_unlock_bh(&da->qlock); | ||||
|  } | ||||
|  EXPORT_SYMBOL(ath_dynack_reset); | ||||
|   | ||||
| @@ -386,6 +390,8 @@ void ath_dynack_init(struct ath_hw *ah) | ||||
|   | ||||
|  	spin_lock_init(&da->qlock); | ||||
|  	INIT_LIST_HEAD(&da->nodes); | ||||
| +	/* ackto = slottime + sifs + air delay */ | ||||
| +	da->ackto = 9 + 16 + 64; | ||||
|   | ||||
|  	ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION; | ||||
|  } | ||||
| --  | ||||
| 2.17.1 | ||||
|  | ||||
| @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | ||||
| @@ -1347,6 +1347,7 @@ int __init brcmf_core_init(void) | ||||
| @@ -1486,6 +1486,7 @@ int __init brcmf_core_init(void) | ||||
|  { | ||||
|  	if (!schedule_work(&brcmf_driver_work)) | ||||
|  		return -EBUSY; | ||||
| @@ -40,15 +40,16 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||
|  	kfree(fwctx); | ||||
|  } | ||||
|   | ||||
| @@ -598,6 +601,7 @@ int brcmf_fw_get_firmwares(struct device | ||||
| @@ -598,6 +601,8 @@ int brcmf_fw_get_firmwares(struct device | ||||
|  { | ||||
|  	struct brcmf_fw_item *first = &req->items[0]; | ||||
|  	struct brcmf_fw *fwctx; | ||||
| +	struct completion completion; | ||||
| +	unsigned long time_left; | ||||
|  	int ret; | ||||
|   | ||||
|  	brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); | ||||
| @@ -615,12 +619,17 @@ int brcmf_fw_get_firmwares(struct device | ||||
| @@ -615,12 +620,20 @@ int brcmf_fw_get_firmwares(struct device | ||||
|  	fwctx->req = req; | ||||
|  	fwctx->done = fw_cb; | ||||
|   | ||||
| @@ -61,7 +62,10 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||
|  	if (ret < 0) | ||||
|  		brcmf_fw_request_done(NULL, fwctx); | ||||
|   | ||||
| +	wait_for_completion_timeout(&completion, msecs_to_jiffies(5000)); | ||||
| +	time_left = wait_for_completion_timeout(&completion, | ||||
| +						msecs_to_jiffies(5000)); | ||||
| +	if (!time_left && fwctx) | ||||
| +		fwctx->completion = NULL; | ||||
| + | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -10,12 +10,11 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -614,9 +614,37 @@ static struct wireless_dev *brcmf_cfg802 | ||||
|  						     enum nl80211_iftype type, | ||||
|  						     struct vif_params *params) | ||||
|  { | ||||
| +	struct net_device *dev; | ||||
| @@ -639,8 +639,36 @@ static struct wireless_dev *brcmf_cfg802 | ||||
|  	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||||
|  	struct brcmf_pub *drvr = cfg->pub; | ||||
|  	struct wireless_dev *wdev; | ||||
| +	struct net_device *dev; | ||||
|  	int err; | ||||
|   | ||||
| +	/* | ||||
|   | ||||
| @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org> | ||||
|  | ||||
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | ||||
| @@ -2725,6 +2725,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip | ||||
| @@ -2798,6 +2798,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip | ||||
|  	 * preference in cfg struct to apply this to | ||||
|  	 * FW later while initializing the dongle | ||||
|  	 */ | ||||
|   | ||||
| @@ -8,9 +8,9 @@ PKG_LICENSE_FILES:= | ||||
|  | ||||
| PKG_SOURCE_URL:=https://github.com/openwrt/mt76 | ||||
| PKG_SOURCE_PROTO:=git | ||||
| PKG_SOURCE_DATE:=2019-01-25 | ||||
| PKG_SOURCE_VERSION:=0b939dc7edf0629ee2d1475b6dd6b9a4a1f9384d | ||||
| PKG_MIRROR_HASH:=64279b0186a6dabd8916085e6bb272b11a1a8c3f2ad4e41c9fb1cefef71d71ba | ||||
| PKG_SOURCE_DATE:=2019-03-23 | ||||
| PKG_SOURCE_VERSION:=a5f5605f3246e65341cc11098e8168aff22a824b | ||||
| PKG_MIRROR_HASH:=a05b1179d82ba79c729eabcb2ba6999d935646607eea2f7a7632766896277fba | ||||
|  | ||||
| PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name> | ||||
| PKG_BUILD_PARALLEL:=1 | ||||
|   | ||||
| @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk | ||||
| include $(INCLUDE_DIR)/kernel.mk | ||||
|  | ||||
| PKG_NAME:=w1-gpio-custom | ||||
| PKG_RELEASE:=3 | ||||
| PKG_RELEASE:=4 | ||||
|  | ||||
| include $(INCLUDE_DIR)/package.mk | ||||
|  | ||||
|   | ||||
| @@ -47,7 +47,7 @@ | ||||
|  | ||||
| #define DRV_NAME	"w1-gpio-custom" | ||||
| #define DRV_DESC	"Custom GPIO-based W1 driver" | ||||
| #define DRV_VERSION	"0.1.1" | ||||
| #define DRV_VERSION	"0.1.2" | ||||
|  | ||||
| #define PFX		DRV_NAME ": " | ||||
|  | ||||
| @@ -86,7 +86,7 @@ static void w1_gpio_custom_cleanup(void) | ||||
|  | ||||
| 	for (i = 0; i < nr_devices; i++) | ||||
| 		if (devices[i]) | ||||
| 			platform_device_put(devices[i]); | ||||
| 			platform_device_unregister(devices[i]); | ||||
| } | ||||
|  | ||||
| static int __init w1_gpio_custom_add_one(unsigned int id, unsigned int *params) | ||||
|   | ||||
| @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=libbsd | ||||
| PKG_VERSION:=0.8.7 | ||||
| PKG_RELEASE:=1 | ||||
| PKG_RELEASE:=2 | ||||
|  | ||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz | ||||
| PKG_HASH:=f548f10e5af5a08b1e22889ce84315b1ebe41505b015c9596bad03fd13a12b31 | ||||
|   | ||||
							
								
								
									
										30
									
								
								package/libs/libbsd/patches/010-fix-arc.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								package/libs/libbsd/patches/010-fix-arc.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| From f60b6777cc2047f9845de2c88cf092b045c160c0 Mon Sep 17 00:00:00 2001 | ||||
| From: Rosen Penev <rosenp@gmail.com> | ||||
| Date: Fri, 17 May 2019 01:44:56 +0000 | ||||
| Subject: [PATCH] local-elf: Add ARC support | ||||
|  | ||||
| Signed-off-by: Rosen Penev <rosenp@gmail.com> | ||||
| --- | ||||
|  src/local-elf.h | 6 ++++++ | ||||
|  1 file changed, 6 insertions(+) | ||||
|  | ||||
| diff --git a/src/local-elf.h b/src/local-elf.h | ||||
| index 83ca253..b90baf3 100644 | ||||
| --- a/src/local-elf.h | ||||
| +++ b/src/local-elf.h | ||||
| @@ -53,6 +53,12 @@ | ||||
|  #endif | ||||
|  #define ELF_TARG_DATA	ELFDATA2LSB | ||||
|   | ||||
| +#elif defined (__arc__) | ||||
| + | ||||
| +#define ELF_TARG_MACH   EM_ARC | ||||
| +#define ELF_TARG_CLASS  ELFCLASS32 | ||||
| +#define ELF_TARG_DATA   ELFDATA2LSB | ||||
| + | ||||
|  #elif defined(__arm__) | ||||
|   | ||||
|  #define ELF_TARG_MACH	EM_ARM | ||||
| --  | ||||
| 2.18.1 | ||||
|  | ||||
| @@ -8,13 +8,13 @@ | ||||
| include $(TOPDIR)/rules.mk | ||||
|  | ||||
| PKG_NAME:=libpcap | ||||
| PKG_VERSION:=1.8.1 | ||||
| PKG_VERSION:=1.9.1 | ||||
| PKG_RELEASE:=1 | ||||
|  | ||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz | ||||
| PKG_SOURCE_URL:=http://www.us.tcpdump.org/release/ \ | ||||
|         http://www.tcpdump.org/release/ | ||||
| PKG_HASH:=673dbc69fdc3f5a86fb5759ab19899039a8e5e6c631749e48dcd9c6f0c83541e | ||||
| PKG_HASH:=635237637c5b619bcceba91900666b64d56ecb7be63f298f601ec786ce087094 | ||||
| PKG_FIXUP:=patch-libtool | ||||
|  | ||||
| PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name> | ||||
|   | ||||
| @@ -1,41 +0,0 @@ | ||||
| From 64aa033a061c43fc15c711f2490ae41d23b868c3 Mon Sep 17 00:00:00 2001 | ||||
| From: Fabio Berton <fabio.berton@ossystems.com.br> | ||||
| Date: Thu, 17 Nov 2016 09:44:42 -0200 | ||||
| Subject: [PATCH 1/2] Fix compiler_state_t.ai usage when INET6 is not defined | ||||
| Organization: O.S. Systems Software LTDA. | ||||
|  | ||||
| Fix error: | ||||
|  | ||||
| / | ||||
| | ../libpcap-1.8.1/gencode.c: In function 'pcap_compile': | ||||
| | ../libpcap-1.8.1/gencode.c:693:8: error: 'compiler_state_t | ||||
| | {aka struct _compiler_state}' has no member named 'ai' | ||||
| |   cstate.ai = NULL; | ||||
| \ | ||||
|  | ||||
| Upstream-Status: Submitted [1] | ||||
|  | ||||
| [1] https://github.com/the-tcpdump-group/libpcap/pull/541 | ||||
|  | ||||
| Signed-off-by: Fabio Berton <fabio.berton@ossystems.com.br> | ||||
| --- | ||||
|  gencode.c | 2 ++ | ||||
|  1 file changed, 2 insertions(+) | ||||
|  | ||||
| diff --git a/gencode.c b/gencode.c | ||||
| index a887f27..e103c70 100644 | ||||
| --- a/gencode.c | ||||
| +++ b/gencode.c | ||||
| @@ -690,7 +690,9 @@ pcap_compile(pcap_t *p, struct bpf_program *program, | ||||
|  	} | ||||
|  	initchunks(&cstate); | ||||
|  	cstate.no_optimize = 0; | ||||
| +#ifdef INET6 | ||||
|  	cstate.ai = NULL; | ||||
| +#endif | ||||
|  	cstate.ic.root = NULL; | ||||
|  	cstate.ic.cur_mark = 0; | ||||
|  	cstate.bpf_pcap = p; | ||||
| --  | ||||
| 2.1.4 | ||||
|  | ||||
| @@ -1,67 +0,0 @@ | ||||
| From 50ec0a088d5924a8305b2d70dcba71b0942dee1a Mon Sep 17 00:00:00 2001 | ||||
| From: Fabio Berton <fabio.berton@ossystems.com.br> | ||||
| Date: Thu, 17 Nov 2016 09:47:29 -0200 | ||||
| Subject: [PATCH 2/2] Add missing compiler_state_t parameter | ||||
| Organization: O.S. Systems Software LTDA. | ||||
|  | ||||
| Fix error: | ||||
|  | ||||
| / | ||||
| |../libpcap-1.8.1/gencode.c: In function 'gen_gateway': | ||||
| |../libpcap-1.8.1/gencode.c:4914:13: error: 'cstate' undeclared | ||||
| | (first use in this function) | ||||
| |    bpf_error(cstate, "direction applied to 'gateway'"); | ||||
| \ | ||||
|  | ||||
| Upstream-Status: Submitted [1] | ||||
|  | ||||
| [1] https://github.com/the-tcpdump-group/libpcap/pull/541 | ||||
|  | ||||
| Signed-off-by: Fabio Berton <fabio.berton@ossystems.com.br> | ||||
| --- | ||||
|  gencode.c | 15 ++++++++------- | ||||
|  1 file changed, 8 insertions(+), 7 deletions(-) | ||||
|  | ||||
| diff --git a/gencode.c b/gencode.c | ||||
| index e103c70..f07c0be 100644 | ||||
| --- a/gencode.c | ||||
| +++ b/gencode.c | ||||
| @@ -523,7 +523,7 @@ static struct block *gen_host6(compiler_state_t *, struct in6_addr *, | ||||
|      struct in6_addr *, int, int, int); | ||||
|  #endif | ||||
|  #ifndef INET6 | ||||
| -static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int); | ||||
| +static struct block *gen_gateway(compiler_state_t *, const u_char *, bpf_u_int32 **, int, int); | ||||
|  #endif | ||||
|  static struct block *gen_ipfrag(compiler_state_t *); | ||||
|  static struct block *gen_portatom(compiler_state_t *, int, bpf_int32); | ||||
| @@ -4904,11 +4904,12 @@ gen_host6(compiler_state_t *cstate, struct in6_addr *addr, | ||||
|   | ||||
|  #ifndef INET6 | ||||
|  static struct block * | ||||
| -gen_gateway(eaddr, alist, proto, dir) | ||||
| -	const u_char *eaddr; | ||||
| -	bpf_u_int32 **alist; | ||||
| -	int proto; | ||||
| -	int dir; | ||||
| +gen_gateway(cstate, eaddr, alist, proto, dir) | ||||
| +    compiler_state_t *cstate; | ||||
| +    const u_char *eaddr; | ||||
| +    bpf_u_int32 **alist; | ||||
| +    int proto; | ||||
| +    int dir; | ||||
|  { | ||||
|  	struct block *b0, *b1, *tmp; | ||||
|   | ||||
| @@ -6472,7 +6473,7 @@ gen_scode(compiler_state_t *cstate, const char *name, struct qual q) | ||||
|  		alist = pcap_nametoaddr(name); | ||||
|  		if (alist == NULL || *alist == NULL) | ||||
|  			bpf_error(cstate, "unknown host '%s'", name); | ||||
| -		b = gen_gateway(eaddr, alist, proto, dir); | ||||
| +		b = gen_gateway(cstate, eaddr, alist, proto, dir); | ||||
|  		free(eaddr); | ||||
|  		return b; | ||||
|  #else | ||||
| --  | ||||
| 2.1.4 | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user