From bdff38dfc41291f20fe2f536af7a0b410cf334a3 Mon Sep 17 00:00:00 2001 From: Ycarus Date: Fri, 7 Sep 2018 15:07:38 +0200 Subject: [PATCH] Add latest and patched mac80211 ans hostapd packages --- root/package/kernel/mac80211/Makefile | 1980 +++++++++++++++++ .../files/lib/netifd/wireless/mac80211.sh | 836 +++++++ .../mac80211/files/lib/wifi/mac80211.sh | 132 ++ .../kernel/mac80211/files/mac80211.hotplug | 5 + .../mac80211/patches/000-fix_kconfig.patch | 14 + .../mac80211/patches/001-fix_build.patch | 167 ++ .../patches/002-change_allconfig.patch | 64 + .../patches/003-remove_bogus_modparams.patch | 34 + .../patches/004-kconfig_backport_fix.patch | 28 + .../patches/005-revert-devcoredump.patch | 11 + .../patches/006-fix-genl-multicast.patch | 10 + .../007-fix-linux-verification-h.patch | 11 + .../patches/008-fix-genl-family-id.patch | 10 + .../mac80211/patches/010-disable_rfkill.patch | 15 + .../patches/012-kernel_build_check.patch | 11 + .../mac80211/patches/015-ipw200-mtu.patch | 34 + .../mac80211/patches/030-rt2x00_options.patch | 47 + .../patches/040-brcmutil_option.patch | 9 + .../patches/050-lib80211_option.patch | 30 + .../patches/060-no_local_ssb_bcma.patch | 132 ++ .../patches/070-ath_common_config.patch | 9 + .../patches/080-ath10k_thermal_config.patch | 47 + .../081-ath10k-calibration-variant.patch | 111 + ...press-Unknown-eventid-36925-warnings.patch | 36 + ...00-use-TXOP_BACKOFF-for-probe-frames.patch | 45 + .../100-remove-cryptoapi-dependencies.patch | 705 ++++++ .../110-mac80211_keep_keys_on_stop_ap.patch | 12 + .../120-cfg80211_allow_perm_addr_change.patch | 43 + .../mac80211/patches/130-disable-fils.patch | 32 + ...aes-cmac-switch-to-shash-CMAC-driver.patch | 199 ++ .../132-mac80211-remove-cmac-dependency.patch | 10 + .../patches/140-tweak-TSQ-setting.patch | 15 + .../patches/150-disable_addr_notifier.patch | 67 + ...-IEs-for-variant-before-falling-back.patch | 237 ++ .../201-ath5k-WAR-for-AR71xx-PCI-bug.patch | 38 + .../kernel/mac80211/patches/210-ap_scan.patch | 11 + ...h10k-fix-build-errors-with-CONFIG_PM.patch | 72 + ...y-free-requested-but-not-started-TX-.patch | 37 + ...-drop-frames-appearing-to-be-from-us.patch | 25 + ...mac-handle-FWHALT-mailbox-indication.patch | 60 + ...-packet-filtering-in-promiscuous-mod.patch | 133 ++ ...leanup-brcmf_cfg80211_escan-function.patch | 133 ++ ...cs_to_jiffies-instead-of-calculation.patch | 31 + ...rid-of-brcmf_cfg80211_escan-function.patch | 83 + ...-of-struct-brcmf_cfg80211_info-activ.patch | 86 + ...e-configuration-of-probe-request-IEs.patch | 55 + ...15-brcmfmac-add-CLM-download-support.patch | 434 ++++ ...driver-unbind-order-of-the-sdio-func.patch | 37 + ...fmac-Avoid-build-error-with-make-W-1.patch | 33 + ...-load-error-for-legacy-chips-when-us.patch | 40 + ...ral-scan-support-under-a-separate-co.patch | 103 + ...tral-scan-support-under-a-separate-c.patch | 91 + ....16-ath9k-discard-undersized-packets.patch | 25 + ...ameter-order-in-brcmf_sdiod_f0_write.patch | 39 + ...r-sizes-on-hardware-are-not-dependen.patch | 105 + ...ac-Split-brcmf_sdiod_regrw_helper-up.patch | 179 ++ ...ean-up-brcmf_sdiod_set_sbaddr_window.patch | 62 + ...16-0005-brcmfmac-Remove-dead-IO-code.patch | 91 + ...brcmfmac-Remove-bandaid-for-SleepCSR.patch | 61 + ...fmac-Remove-brcmf_sdiod_request_data.patch | 344 +++ ...brcmfmac-Fix-asymmetric-IO-functions.patch | 28 + ...0009-brcmfmac-Remove-noisy-debugging.patch | 53 + ...0010-brcmfmac-Rename-bcmerror-to-err.patch | 58 + ...Split-brcmf_sdiod_buffrw-function-up.patch | 143 ++ ...espace-fixes-in-brcmf_sdiod_send_buf.patch | 34 + ...003-brcmfmac-Clarify-if-using-braces.patch | 36 + ...replace-old-IO-functions-with-simple.patch | 831 +++++++ ...c-Tidy-register-definitions-a-little.patch | 59 + ...brcmfmac-Remove-brcmf_sdiod_addrprep.patch | 190 ++ ...unnecessary-call-to-brcmf_sdiod_set_.patch | 32 + ...v4.16-0008-brcmfmac-Cleanup-offsetof.patch | 134 ++ ...16-0009-brcmfmac-Remove-unused-macro.patch | 26 + ...repeated-calls-to-brcmf_chip_get_cor.patch | 128 ++ ...rge-buffer-size-of-caps-to-512-bytes.patch | 44 + ...16-0001-brcmfmac-Remove-r-w-_sdreg32.patch | 227 ++ ...name-buscore-to-core-for-consistency.patch | 33 + ...se-the-value-of-sbwad-in-use-for-som.patch | 82 + ...rectly-handle-accesses-to-SDIO-func0.patch | 45 + ...mac-Remove-func0-from-function-array.patch | 111 + ...ficient-and-slightly-easier-to-read-.patch | 40 + ...-function-index-with-function-pointe.patch | 347 +++ ...8-brcmfmac-Clean-up-interrupt-macros.patch | 53 + ...-43455-save-restore-SR-feature-if-FW.patch | 27 + ...1-brcmfmac-Remove-array-of-functions.patch | 1043 +++++++++ ...ment-block-in-brcmf_sdio_buscore_rea.patch | 31 + ...brcmf_sdiod_buff_-read-write-functio.patch | 137 ++ ...oing-memory-allocator-than-allocator.patch | 59 + ...EEE80211_TX_STATUS_HEADROOM-up-to-mu.patch | 26 + ...ames-with-unexpected-DS-bits-from-fa.patch | 21 + ...80211-support-AP-4-addr-mode-fast-rx.patch | 25 + ...-fast-rx-with-incompatible-PS-capabi.patch | 53 + ...-support-station-4-addr-mode-fast-rx.patch | 34 + ...7-mac80211-support-A-MSDU-in-fast-rx.patch | 256 +++ ...bcdc-dcmd-api-does-not-return-value-.patch | 68 + ...rate-firmware-errors-from-i-o-errors.patch | 186 ++ ...possibility-to-obtain-firmware-error.patch | 92 + ...P_DEVICE-ethernet-address-generation.patch | 64 + ...ter-Access-Point-Protocol-packets-by.patch | 157 ++ ...-brcmfmac-Fix-check-for-ISO3166-code.patch | 29 + ...cmf_bus_preinit-call-just-after-chan.patch | 45 + ...location-of-control-rx-buffer-to-brc.patch | 69 + ...cmf_attach-just-before-calling-brcmf.patch | 106 + ...l-brcmf_usb_up-during-brcmf_bus_prei.patch | 41 + ...move-brcmf_attach-function-in-core.c.patch | 130 ++ ...emove-brcmf_bus_started-from-bus-api.patch | 190 ++ ...log-level-for-some-low-level-sdio-fu.patch | 64 + ...duplicate-pointer-variable-from-brcm.patch | 126 ++ ...17-0001-brcmfmac-reject-too-long-PSK.patch | 27 + ...convert-linux-error-to-firmware-erro.patch | 31 + ...mf_chip_name-to-store-name-in-revinf.patch | 203 ++ ...-use-brcmf_chip_name-for-consistency.patch | 69 + ...e-struct-brcmf_pub-instance-using-wi.patch | 452 ++++ ...brcmfmac-use-wiphy-debugfs-dir-entry.patch | 349 +++ ...firmware-filenames-from-basename-map.patch | 286 +++ ...ass-struct-in-brcmf_fw_get_firmwares.patch | 574 +++++ ...duce-brcmf_fw_alloc_request-function.patch | 328 +++ ...d-extension-to-.get_fwname-callbacks.patch | 231 ++ ...get-rid-of-brcmf_fw_map_chip_to_name.patch | 92 + ...ac-get-rid-of-brcmf_fw_get_full_name.patch | 44 + ...erneldoc-for-struct-brcmf_bus-msgbuf.patch | 23 + ...mware-request-processing-if-nvram-lo.patch | 81 + ...mac-add-support-for-BCM4366E-chipset.patch | 48 + ...-check-p2pdev-mac-address-uniqueness.patch | 34 + ...orts-boottime_ns-while-informing-bss.patch | 76 + ...0211_band-directly-to-get-ieee80211-.patch | 43 + ...mac-constify-firmware-mapping-tables.patch | 76 + ...05-brcmfmac-add-hostready-indication.patch | 74 + ...support-for-PCIe-shared-structure-re.patch | 97 + ...upport-for-bcm43364-wireless-chipset.patch | 45 + ...fmac-set-WIPHY_FLAG_HAVE_AP_SME-flag.patch | 34 + ...tialization-of-struct-cfg80211_infor.patch | 29 + ...ugfs-entry-for-reading-firmware-capa.patch | 75 + ...w-reset-AHB-WMAC-interface-on-AR91xx.patch | 25 + ..._hw-issue-external-reset-for-QCA955x.patch | 129 ++ ...ctral-scan-enable-bit-on-trigger-for.patch | 21 + ...periodic-and-nf-calibation-at-the-sa.patch | 27 + ...h9k-force-rx_clear-when-disabling-rx.patch | 35 + ...erpret-requested-txpower-in-EIRP-dom.patch | 37 + ...0211-add-hdrlen-to-ieee80211_tx_data.patch | 219 ++ ...80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch | 233 ++ ...l-Enable-STBC-and-LDPC-for-VHT-Rates.patch | 82 + ...ata-bit-in-PS-buffered-frame-release.patch | 50 + ...ntially-stale-EOSP-status-bit-in-int.patch | 22 + .../362-ath9k-report-tx-status-on-EOSP.patch | 19 + ...fix-block-ack-window-tracking-issues.patch | 114 + ...fix-channel-maximum-power-level-test.patch | 47 + ...power-reduction-for-US-regulatory-do.patch | 24 + ...ata-flag-for-buffered-multicast-pack.patch | 41 + ...sable-wake_tx_queue-for-older-device.patch | 27 + ...-fix-recent-bandwidth-conversion-bug.patch | 61 + ...e-only-1Mbps-for-basic-rates-in-mesh.patch | 55 + ...l-remove-unnecessary-debugfs-cleanup.patch | 150 ++ ...l-merge-with-minstrel_ht-always-enab.patch | 576 +++++ ...trel-reduce-minstrel_mcs_groups-size.patch | 368 +++ ...l-fix-using-short-preamble-CCK-rates.patch | 31 + ...tect-queue-draining-by-rcu_read_lock.patch | 43 + ...rel-fix-CCK-rate-group-streams-value.patch | 20 + ...l-fix-sampling-reporting-of-CCK-rate.patch | 58 + ...l-do-not-sample-rates-3-times-slower.patch | 40 + ...ory-accounting-with-A-MSDU-aggregati.patch | 58 + .../patches/400-ath_move_debug_code.patch | 31 + .../patches/401-ath9k_blink_default.patch | 11 + .../patches/402-ath_regd_optional.patch | 92 + .../patches/403-world_regd_fixup.patch | 84 + .../patches/404-regd_no_assoc_hints.patch | 19 + .../mac80211/patches/405-ath_regd_us.patch | 26 + .../patches/406-ath_relax_default_regd.patch | 51 + .../410-ath9k_allow_adhoc_and_ap.patch | 10 + .../411-ath5k_allow_adhoc_and_ap.patch | 46 + .../patches/420-ath5k_disable_fast_cc.patch | 18 + .../patches/430-add_ath5k_platform.patch | 33 + ...add_platform_eeprom_support_to_ath5k.patch | 56 + .../patches/432-ath5k_add_pciids.patch | 11 + .../440-ath5k_channel_bw_debugfs.patch | 143 ++ .../patches/500-ath9k_eeprom_debugfs.patch | 65 + .../mac80211/patches/501-ath9k_ahb_init.patch | 32 + .../510-ath9k_intr_mitigation_tweak.patch | 18 + .../patches/511-ath9k_reduce_rxbuf.patch | 11 + .../patches/512-ath9k_channelbw_debugfs.patch | 125 ++ .../patches/513-ath9k_add_pci_ids.patch | 30 + .../522-mac80211_configure_antenna_gain.patch | 160 ++ .../patches/530-ath9k_extra_leds.patch | 267 +++ .../531-ath9k_extra_platform_leds.patch | 76 + .../540-ath9k_reduce_ani_interval.patch | 11 + .../patches/542-ath9k_debugfs_diag.patch | 139 ++ .../patches/543-ath9k_entropy_from_adc.patch | 186 ++ ...544-ath9k-ar933x-usb-hang-workaround.patch | 79 + .../patches/545-ath9k_ani_ws_detect.patch | 155 ++ .../patches/547-ath9k_led_defstate_fix.patch | 29 + .../patches/548-ath9k_enable_gpio_chip.patch | 247 ++ .../549-ath9k_enable_gpio_buttons.patch | 143 ++ .../550-ath9k-disable-bands-via-dt.patch | 15 + .../patches/551-ath9k_ubnt_uap_plus_hsr.patch | 418 ++++ .../kernel/mac80211/patches/552-ahb_of.patch | 330 +++ ...to-build-rt2800soc-module-for-RT3883.patch | 30 + ...-rt2800lib-enable-support-for-RT3883.patch | 20 + ...x00-rt2800lib-add-rf_vals-for-RF3853.patch | 112 + ...ib-enable-VCO-calibration-for-RF3853.patch | 28 + ...-add-channel-configuration-function-.patch | 235 ++ ...2x00-rt2800lib-enable-RF3853-support.patch | 20 + ...-add-MAC-register-initialization-for.patch | 62 + ...-fix-rt2800soc_disable_radio-for-RT3.patch | 30 + ...-add-BBP-register-initialization-for.patch | 71 + ...-add-RFCSR-initialization-for-RT3883.patch | 178 ++ ...-use-the-extended-EEPROM-map-for-RT3.patch | 22 + ...ib-force-rf-type-to-RF3853-on-RT3883.patch | 21 + ...-add-channel-configuration-code-for-.patch | 136 ++ ...-fix-txpower_to_dev-function-for-RT3.patch | 30 + ...-use-correct-txpower-calculation-fun.patch | 23 + ...-hardcode-txmixer-gain-values-to-zer.patch | 33 + ...b-use-correct-RT-XWI-size-for-RT3883.patch | 20 + ...-fix-antenna-configuration-for-RT388.patch | 22 + ...-fix-LNA-gain-configuration-for-RT38.patch | 32 + ...0-rt2800lib-fix-VGC-setup-for-RT3883.patch | 44 + ...-fix-EEPROM-LNA-validation-for-RT388.patch | 42 + ...-fix-txpower-compensation-for-RT3883.patch | 22 + ...o-add-a-workaround-for-spurious-TX_F.patch | 136 ++ ...1-rt2x00-introduce-rt2x00_platform_h.patch | 32 + .../602-rt2x00-introduce-rt2x00eeprom.patch | 295 +++ .../603-rt2x00-of_load_eeprom_filename.patch | 33 + ...om-on-SoC-from-a-mtd-device-defines-.patch | 108 + ...isabling_bands_through_platform_data.patch | 47 + ...07-rt2x00-add_platform_data_mac_addr.patch | 26 + ...00-allow_disabling_bands_through_dts.patch | 19 + ...c-loadable-via-OF-on-rt288x-305x-SoC.patch | 33 + ...0-rt2x00-change-led-polarity-from-OF.patch | 40 + .../611-rt2x00-add-AP+STA-support.patch | 11 + ...dd-support-for-external-PA-on-MT7620.patch | 118 + .../651-rt2x00-remove-unneccesary-code.patch | 132 ++ ...700-mwl8k-missing-pci-id-for-WNR854T.patch | 10 + .../801-libertas-configure-sysfs-links.patch | 21 + .../802-libertas-set-wireless-macaddr.patch | 11 + .../810-b43-gpio-mask-module-option.patch | 37 + .../mac80211/patches/811-b43_no_pio.patch | 86 + .../patches/812-b43-add-antenna-control.patch | 131 ++ .../813-b43-reduce-number-of-RX-slots.patch | 11 + .../814-b43-only-use-gpio-0-1-for-led.patch | 17 + ...815-b43-always-take-overlapping-devs.patch | 11 + ...-remove-extra-regulation-restriction.patch | 27 + ...-register-wiphy-s-during-module_init.patch | 66 + ...und-bug-with-some-inconsistent-BSSes.patch | 50 + ...62-brcmfmac-Disable-power-management.patch | 27 + ...-in-driver-tables-with-country-codes.patch | 60 + ...e-internal-roaming-engine-by-default.patch | 23 + ...21-ath10k_init_devices_synchronously.patch | 33 + .../930-ath10k_add_tpt_led_trigger.patch | 37 + .../936-ath10k-fix-otp-failure-result.patch | 11 + ...940-mwl8k_init_devices_synchronously.patch | 20 + ...0-0010-ath10k-limit-htt-rx-ring-size.patch | 11 + ...60-0011-ath10k-limit-pci-buffer-size.patch | 38 + ...d-reported-build-errors-with-CONFIG_PM-off | 93 + ..._sdio_reinit_device-out-of-CONFIG_PM.patch | 96 + ...-of-peer_bw_rxnss_override-parameter.patch | 132 ++ ...dling-for-VHT160-in-recent-firmwares.patch | 50 + ...rolling-support-for-various-chipsets.patch | 617 +++++ ...75-ath10k-use-tpt-trigger-by-default.patch | 53 + .../mac80211/scripts/import-backports.sh | 109 + .../network/services/hostapd/Config.in | 96 + .../package/network/services/hostapd/Makefile | 644 ++++++ .../hostapd/files/hostapd-full.config | 380 ++++ .../hostapd/files/hostapd-mini.config | 380 ++++ .../network/services/hostapd/files/hostapd.sh | 856 +++++++ .../services/hostapd/files/multicall.c | 28 + .../hostapd/files/wpa_supplicant-full.config | 593 +++++ .../hostapd/files/wpa_supplicant-mini.config | 593 +++++ .../hostapd/files/wpa_supplicant-p2p.config | 593 +++++ .../services/hostapd/files/wps-hotplug.sh | 11 + ...1-mesh-factor-out-mesh-join-function.patch | 211 ++ ...2-mesh-factor-out-rsn-initialization.patch | 133 ++ .../003-mesh-relocate-RSN-init-function.patch | 41 + ...ompletion-callback-to-complete-mesh-.patch | 73 + ...ountry-setting-to-mesh-configuration.patch | 35 + ...rnel-driver-DFS-handler-in-userspace.patch | 48 + ...annel-attributes-before-running-Mesh.patch | 33 + ...ce-type-to-mesh-before-setting-inter.patch | 36 + .../009-mesh-set-mesh-center-frequency.patch | 22 + ...-mesh-interface-on-dfs-event-handler.patch | 176 ++ ...hannels-to-be-selected-if-dfs-is-ena.patch | 79 + ...-mesh-to-send-channel-switch-request.patch | 25 + ...-do-not-allow-pri-sec-channel-switch.patch | 27 + ...ot-allow-scan-result-to-swap-pri-sec.patch | 24 + ...sh-do-not-use-offchan-mgmt-tx-on-DFS.patch | 49 + ...-fix-channel-switch-error-during-CAC.patch | 64 + ...nterface-context-to-send-DFS-event-m.patch | 107 + ...18-mesh-make-forwarding-configurable.patch | 219 ++ ...x-crash-with-CONFIG_TAXONOMY-enabled.patch | 23 + ...CHANWIDTH_USE_HT-to-max_oper_chwidth.patch | 49 + ...ent-use-of-VHT20-config-in-mesh-mode.patch | 82 + ...mesh-fix-parsing-of-max_oper_chwidth.patch | 45 + .../hostapd/patches/100-daemonize_fix.patch | 97 + .../hostapd/patches/110-no_eapol_fix.patch | 14 + ...120-disable_bridge_packet_workaround.patch | 12 + .../hostapd/patches/200-multicall.patch | 355 +++ .../services/hostapd/patches/300-noscan.patch | 58 + .../hostapd/patches/301-mesh-noscan.patch | 68 + .../patches/310-rescan_immediately.patch | 11 + .../hostapd/patches/320-optional_rfkill.patch | 61 + .../patches/330-nl80211_fix_set_freq.patch | 11 + .../patches/340-reload_freq_change.patch | 69 + .../patches/350-nl80211_del_beacon_bss.patch | 54 + .../patches/360-ctrl_iface_reload.patch | 106 + .../hostapd/patches/370-ap_sta_support.patch | 246 ++ .../patches/380-disable_ctrl_iface_mib.patch | 193 ++ .../381-hostapd_cli_UNKNOWN-COMMAND.patch | 13 + .../patches/390-wpa_ie_cap_workaround.patch | 56 + .../400-wps_single_auth_enc_type.patch | 22 + .../patches/410-limit_debug_messages.patch | 214 ++ .../patches/420-indicate-features.patch | 62 + .../patches/430-hostapd_cli_ifdef.patch | 58 + .../hostapd/patches/431-wpa_cli_ifdef.patch | 12 + .../hostapd/patches/432-missing-typedef.patch | 10 + .../hostapd/patches/450-scan_wait.patch | 73 + ...dd-new-config-params-to-be-used-with.patch | 189 ++ ...-use-new-parameters-during-ibss-join.patch | 59 + .../patches/463-add-mcast_rate-to-11s.patch | 68 + .../patches/464-fix-mesh-obss-check.patch | 19 + .../patches/470-survey_data_fallback.patch | 45 + .../hostapd/patches/600-ubus_support.patch | 351 +++ .../services/hostapd/src/src/ap/ubus.c | 1060 +++++++++ .../services/hostapd/src/src/ap/ubus.h | 83 + .../hostapd/src/src/utils/build_features.h | 29 + 321 files changed, 36273 insertions(+) create mode 100644 root/package/kernel/mac80211/Makefile create mode 100644 root/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh create mode 100644 root/package/kernel/mac80211/files/lib/wifi/mac80211.sh create mode 100644 root/package/kernel/mac80211/files/mac80211.hotplug create mode 100644 root/package/kernel/mac80211/patches/000-fix_kconfig.patch create mode 100644 root/package/kernel/mac80211/patches/001-fix_build.patch create mode 100644 root/package/kernel/mac80211/patches/002-change_allconfig.patch create mode 100644 root/package/kernel/mac80211/patches/003-remove_bogus_modparams.patch create mode 100644 root/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch create mode 100644 root/package/kernel/mac80211/patches/005-revert-devcoredump.patch create mode 100644 root/package/kernel/mac80211/patches/006-fix-genl-multicast.patch create mode 100644 root/package/kernel/mac80211/patches/007-fix-linux-verification-h.patch create mode 100644 root/package/kernel/mac80211/patches/008-fix-genl-family-id.patch create mode 100644 root/package/kernel/mac80211/patches/010-disable_rfkill.patch create mode 100644 root/package/kernel/mac80211/patches/012-kernel_build_check.patch create mode 100644 root/package/kernel/mac80211/patches/015-ipw200-mtu.patch create mode 100644 root/package/kernel/mac80211/patches/030-rt2x00_options.patch create mode 100644 root/package/kernel/mac80211/patches/040-brcmutil_option.patch create mode 100644 root/package/kernel/mac80211/patches/050-lib80211_option.patch create mode 100644 root/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch create mode 100644 root/package/kernel/mac80211/patches/070-ath_common_config.patch create mode 100644 root/package/kernel/mac80211/patches/080-ath10k_thermal_config.patch create mode 100644 root/package/kernel/mac80211/patches/081-ath10k-calibration-variant.patch create mode 100644 root/package/kernel/mac80211/patches/082-ath10k-suppress-Unknown-eventid-36925-warnings.patch create mode 100644 root/package/kernel/mac80211/patches/090-Revert-rt2800-use-TXOP_BACKOFF-for-probe-frames.patch create mode 100644 root/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch create mode 100644 root/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch create mode 100644 root/package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch create mode 100644 root/package/kernel/mac80211/patches/130-disable-fils.patch create mode 100644 root/package/kernel/mac80211/patches/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch create mode 100644 root/package/kernel/mac80211/patches/132-mac80211-remove-cmac-dependency.patch create mode 100644 root/package/kernel/mac80211/patches/140-tweak-TSQ-setting.patch create mode 100644 root/package/kernel/mac80211/patches/150-disable_addr_notifier.patch create mode 100644 root/package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch create mode 100644 root/package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch create mode 100644 root/package/kernel/mac80211/patches/210-ap_scan.patch create mode 100644 root/package/kernel/mac80211/patches/300-v4.15-ath10k-fix-build-errors-with-CONFIG_PM.patch create mode 100644 root/package/kernel/mac80211/patches/301-v4.15-mac80211-properly-free-requested-but-not-started-TX-.patch create mode 100644 root/package/kernel/mac80211/patches/302-v4.15-mac80211-mesh-drop-frames-appearing-to-be-from-us.patch create mode 100644 root/package/kernel/mac80211/patches/303-v4.15-0001-brcmfmac-handle-FWHALT-mailbox-indication.patch create mode 100644 root/package/kernel/mac80211/patches/303-v4.15-0002-brcmfmac-disable-packet-filtering-in-promiscuous-mod.patch create mode 100644 root/package/kernel/mac80211/patches/303-v4.15-0003-brcmfmac-cleanup-brcmf_cfg80211_escan-function.patch create mode 100644 root/package/kernel/mac80211/patches/303-v4.15-0004-brcmfmac-use-msecs_to_jiffies-instead-of-calculation.patch create mode 100644 root/package/kernel/mac80211/patches/303-v4.15-0005-brcmfmac-get-rid-of-brcmf_cfg80211_escan-function.patch create mode 100644 root/package/kernel/mac80211/patches/303-v4.15-0006-brcmfmac-get-rid-of-struct-brcmf_cfg80211_info-activ.patch create mode 100644 root/package/kernel/mac80211/patches/303-v4.15-0007-brcmfmac-move-configuration-of-probe-request-IEs.patch create mode 100644 root/package/kernel/mac80211/patches/304-v4.15-brcmfmac-add-CLM-download-support.patch create mode 100644 root/package/kernel/mac80211/patches/305-v4.15-brcmfmac-change-driver-unbind-order-of-the-sdio-func.patch create mode 100644 root/package/kernel/mac80211/patches/306-v4.15-brcmfmac-Avoid-build-error-with-make-W-1.patch create mode 100644 root/package/kernel/mac80211/patches/307-v4.15-brcmfmac-fix-CLM-load-error-for-legacy-chips-when-us.patch create mode 100644 root/package/kernel/mac80211/patches/308-v4.16-0001-ath9k-move-spectral-scan-support-under-a-separate-co.patch create mode 100644 root/package/kernel/mac80211/patches/309-v4.16-0002-ath10k-move-spectral-scan-support-under-a-separate-c.patch create mode 100644 root/package/kernel/mac80211/patches/310-v4.16-ath9k-discard-undersized-packets.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0001-brcmfmac-Fix-parameter-order-in-brcmf_sdiod_f0_write.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0002-brcmfmac-Register-sizes-on-hardware-are-not-dependen.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0003-brcmfmac-Split-brcmf_sdiod_regrw_helper-up.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0004-brcmfmac-Clean-up-brcmf_sdiod_set_sbaddr_window.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0005-brcmfmac-Remove-dead-IO-code.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0006-brcmfmac-Remove-bandaid-for-SleepCSR.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0007-brcmfmac-Remove-brcmf_sdiod_request_data.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0008-brcmfmac-Fix-asymmetric-IO-functions.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0009-brcmfmac-Remove-noisy-debugging.patch create mode 100644 root/package/kernel/mac80211/patches/311-v4.16-0010-brcmfmac-Rename-bcmerror-to-err.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0001-brcmfmac-Split-brcmf_sdiod_buffrw-function-up.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0002-brcmfmac-whitespace-fixes-in-brcmf_sdiod_send_buf.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0003-brcmfmac-Clarify-if-using-braces.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0004-brcmfmac-Rename-replace-old-IO-functions-with-simple.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0005-brcmfmac-Tidy-register-definitions-a-little.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0007-brcmfmac-remove-unnecessary-call-to-brcmf_sdiod_set_.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0009-brcmfmac-Remove-unused-macro.patch create mode 100644 root/package/kernel/mac80211/patches/312-v4.16-0010-brcmfmac-Remove-repeated-calls-to-brcmf_chip_get_cor.patch create mode 100644 root/package/kernel/mac80211/patches/313-v4.16-0001-brcmfmac-enlarge-buffer-size-of-caps-to-512-bytes.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0001-brcmfmac-Remove-r-w-_sdreg32.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0002-brcmfmac-Rename-buscore-to-core-for-consistency.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0003-brcmfmac-stabilise-the-value-of-sbwad-in-use-for-som.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0004-brcmfmac-Correctly-handle-accesses-to-SDIO-func0.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0005-brcmfmac-Remove-func0-from-function-array.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0006-brcmfmac-More-efficient-and-slightly-easier-to-read-.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch create mode 100644 root/package/kernel/mac80211/patches/314-v4.16-0008-brcmfmac-Clean-up-interrupt-macros.patch create mode 100644 root/package/kernel/mac80211/patches/315-v4.16-0001-brcmfmac-Support-43455-save-restore-SR-feature-if-FW.patch create mode 100644 root/package/kernel/mac80211/patches/316-v4.16-0001-brcmfmac-Remove-array-of-functions.patch create mode 100644 root/package/kernel/mac80211/patches/316-v4.16-0002-brcmfmac-add-comment-block-in-brcmf_sdio_buscore_rea.patch create mode 100644 root/package/kernel/mac80211/patches/316-v4.16-0003-brcmfmac-rename-brcmf_sdiod_buff_-read-write-functio.patch create mode 100644 root/package/kernel/mac80211/patches/317-v4.16-0001-brcmfmac-Use-zeroing-memory-allocator-than-allocator.patch create mode 100644 root/package/kernel/mac80211/patches/318-v4.17-mac80211-round-IEEE80211_TX_STATUS_HEADROOM-up-to-mu.patch create mode 100644 root/package/kernel/mac80211/patches/319-v4.17-0001-mac80211-drop-frames-with-unexpected-DS-bits-from-fa.patch create mode 100644 root/package/kernel/mac80211/patches/319-v4.17-0002-mac80211-support-AP-4-addr-mode-fast-rx.patch create mode 100644 root/package/kernel/mac80211/patches/319-v4.17-0003-mac80211-support-fast-rx-with-incompatible-PS-capabi.patch create mode 100644 root/package/kernel/mac80211/patches/319-v4.17-0004-mac80211-support-station-4-addr-mode-fast-rx.patch create mode 100644 root/package/kernel/mac80211/patches/320-v4.17-mac80211-support-A-MSDU-in-fast-rx.patch create mode 100644 root/package/kernel/mac80211/patches/321-v4.16-0001-brcmfmac-assure-bcdc-dcmd-api-does-not-return-value-.patch create mode 100644 root/package/kernel/mac80211/patches/321-v4.16-0002-brcmfmac-separate-firmware-errors-from-i-o-errors.patch create mode 100644 root/package/kernel/mac80211/patches/322-v4.16-0001-brcmfmac-add-possibility-to-obtain-firmware-error.patch create mode 100644 root/package/kernel/mac80211/patches/322-v4.16-0002-brcmfmac-fix-P2P_DEVICE-ethernet-address-generation.patch create mode 100644 root/package/kernel/mac80211/patches/323-v4.16-0001-brcmfmac-drop-Inter-Access-Point-Protocol-packets-by.patch create mode 100644 root/package/kernel/mac80211/patches/324-v4.16-0001-brcmfmac-Fix-check-for-ISO3166-code.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0001-brcmfmac-move-brcmf_bus_preinit-call-just-after-chan.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0002-brcmfmac-move-allocation-of-control-rx-buffer-to-brc.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0003-brcmfmac-call-brcmf_attach-just-before-calling-brcmf.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0004-brcmfmac-usb-call-brcmf_usb_up-during-brcmf_bus_prei.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0005-brcmfmac-move-brcmf_attach-function-in-core.c.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0006-brcmfmac-remove-brcmf_bus_started-from-bus-api.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0007-brcmfmac-change-log-level-for-some-low-level-sdio-fu.patch create mode 100644 root/package/kernel/mac80211/patches/325-v4.17-0008-brcmfmac-remove-duplicate-pointer-variable-from-brcm.patch create mode 100644 root/package/kernel/mac80211/patches/326-v4.17-0001-brcmfmac-reject-too-long-PSK.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0001-brcmfmac-do-not-convert-linux-error-to-firmware-erro.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0002-brcmfmac-use-brcmf_chip_name-to-store-name-in-revinf.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0003-brcmfmac-use-brcmf_chip_name-for-consistency.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0004-brcmfmac-allocate-struct-brcmf_pub-instance-using-wi.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0005-brcmfmac-use-wiphy-debugfs-dir-entry.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0006-brcmfmac-derive-firmware-filenames-from-basename-map.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0007-brcmfmac-pass-struct-in-brcmf_fw_get_firmwares.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0008-brcmfmac-introduce-brcmf_fw_alloc_request-function.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0009-brcmfmac-add-extension-to-.get_fwname-callbacks.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0010-brcmfmac-get-rid-of-brcmf_fw_map_chip_to_name.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0011-brcmfmac-get-rid-of-brcmf_fw_get_full_name.patch create mode 100644 root/package/kernel/mac80211/patches/327-v4.17-0012-brcmfmac-add-kerneldoc-for-struct-brcmf_bus-msgbuf.patch create mode 100644 root/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch create mode 100644 root/package/kernel/mac80211/patches/329-v4.18-0001-brcmfmac-add-support-for-BCM4366E-chipset.patch create mode 100644 root/package/kernel/mac80211/patches/330-v4.18-0001-brcmfmac-check-p2pdev-mac-address-uniqueness.patch create mode 100644 root/package/kernel/mac80211/patches/330-v4.18-0002-brcmfmac-reports-boottime_ns-while-informing-bss.patch create mode 100644 root/package/kernel/mac80211/patches/330-v4.18-0003-brcmfmac-use-nl80211_band-directly-to-get-ieee80211-.patch create mode 100644 root/package/kernel/mac80211/patches/330-v4.18-0004-brcmfmac-constify-firmware-mapping-tables.patch create mode 100644 root/package/kernel/mac80211/patches/330-v4.18-0005-brcmfmac-add-hostready-indication.patch create mode 100644 root/package/kernel/mac80211/patches/330-v4.18-0006-brcmfmac-coarse-support-for-PCIe-shared-structure-re.patch create mode 100644 root/package/kernel/mac80211/patches/331-v4.18-0001-brcmfmac-Add-support-for-bcm43364-wireless-chipset.patch create mode 100644 root/package/kernel/mac80211/patches/332-v4.18-0001-brcmfmac-set-WIPHY_FLAG_HAVE_AP_SME-flag.patch create mode 100644 root/package/kernel/mac80211/patches/333-v4.18-0001-brcmfmac-fix-initialization-of-struct-cfg80211_infor.patch create mode 100644 root/package/kernel/mac80211/patches/334-v4.18-0001-brcmfmac-add-debugfs-entry-for-reading-firmware-capa.patch create mode 100644 root/package/kernel/mac80211/patches/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch create mode 100644 root/package/kernel/mac80211/patches/351-ath9k_hw-issue-external-reset-for-QCA955x.patch create mode 100644 root/package/kernel/mac80211/patches/352-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch create mode 100644 root/package/kernel/mac80211/patches/353-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch create mode 100644 root/package/kernel/mac80211/patches/354-ath9k-force-rx_clear-when-disabling-rx.patch create mode 100644 root/package/kernel/mac80211/patches/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch create mode 100644 root/package/kernel/mac80211/patches/357-mac80211-add-hdrlen-to-ieee80211_tx_data.patch create mode 100644 root/package/kernel/mac80211/patches/358-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch create mode 100644 root/package/kernel/mac80211/patches/359-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch create mode 100644 root/package/kernel/mac80211/patches/360-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch create mode 100644 root/package/kernel/mac80211/patches/361-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch create mode 100644 root/package/kernel/mac80211/patches/362-ath9k-report-tx-status-on-EOSP.patch create mode 100644 root/package/kernel/mac80211/patches/363-ath9k-fix-block-ack-window-tracking-issues.patch create mode 100644 root/package/kernel/mac80211/patches/364-ath9k_hw-fix-channel-maximum-power-level-test.patch create mode 100644 root/package/kernel/mac80211/patches/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch create mode 100644 root/package/kernel/mac80211/patches/366-ath9k-fix-more-data-flag-for-buffered-multicast-pack.patch create mode 100644 root/package/kernel/mac80211/patches/367-Revert-ath10k-disable-wake_tx_queue-for-older-device.patch create mode 100644 root/package/kernel/mac80211/patches/368-ath10k-fix-recent-bandwidth-conversion-bug.patch create mode 100644 root/package/kernel/mac80211/patches/369-cfg80211-use-only-1Mbps-for-basic-rates-in-mesh.patch create mode 100644 root/package/kernel/mac80211/patches/370-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch create mode 100644 root/package/kernel/mac80211/patches/371-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch create mode 100644 root/package/kernel/mac80211/patches/372-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch create mode 100644 root/package/kernel/mac80211/patches/373-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch create mode 100644 root/package/kernel/mac80211/patches/374-ath9k-Protect-queue-draining-by-rcu_read_lock.patch create mode 100644 root/package/kernel/mac80211/patches/375-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch create mode 100644 root/package/kernel/mac80211/patches/376-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch create mode 100644 root/package/kernel/mac80211/patches/377-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch create mode 100644 root/package/kernel/mac80211/patches/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch create mode 100644 root/package/kernel/mac80211/patches/400-ath_move_debug_code.patch create mode 100644 root/package/kernel/mac80211/patches/401-ath9k_blink_default.patch create mode 100644 root/package/kernel/mac80211/patches/402-ath_regd_optional.patch create mode 100644 root/package/kernel/mac80211/patches/403-world_regd_fixup.patch create mode 100644 root/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch create mode 100644 root/package/kernel/mac80211/patches/405-ath_regd_us.patch create mode 100644 root/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch create mode 100644 root/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch create mode 100644 root/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch create mode 100644 root/package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch create mode 100644 root/package/kernel/mac80211/patches/430-add_ath5k_platform.patch create mode 100644 root/package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch create mode 100644 root/package/kernel/mac80211/patches/432-ath5k_add_pciids.patch create mode 100644 root/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch create mode 100644 root/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch create mode 100644 root/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch create mode 100644 root/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch create mode 100644 root/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch create mode 100644 root/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch create mode 100644 root/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch create mode 100644 root/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch create mode 100644 root/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch create mode 100644 root/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch create mode 100644 root/package/kernel/mac80211/patches/540-ath9k_reduce_ani_interval.patch create mode 100644 root/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch create mode 100644 root/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch create mode 100644 root/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch create mode 100644 root/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch create mode 100644 root/package/kernel/mac80211/patches/547-ath9k_led_defstate_fix.patch create mode 100644 root/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch create mode 100644 root/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch create mode 100644 root/package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch create mode 100644 root/package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch create mode 100644 root/package/kernel/mac80211/patches/552-ahb_of.patch create mode 100644 root/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch create mode 100644 root/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch create mode 100644 root/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch create mode 100644 root/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch create mode 100644 root/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch create mode 100644 root/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch create mode 100644 root/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch create mode 100644 root/package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch create mode 100644 root/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch create mode 100644 root/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch create mode 100644 root/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch create mode 100644 root/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch create mode 100644 root/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch create mode 100644 root/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch create mode 100644 root/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch create mode 100644 root/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch create mode 100644 root/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch create mode 100644 root/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch create mode 100644 root/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch create mode 100644 root/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch create mode 100644 root/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch create mode 100644 root/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch create mode 100644 root/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch create mode 100644 root/package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch create mode 100644 root/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch create mode 100644 root/package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch create mode 100644 root/package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch create mode 100644 root/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch create mode 100644 root/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch create mode 100644 root/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch create mode 100644 root/package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch create mode 100644 root/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch create mode 100644 root/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch create mode 100644 root/package/kernel/mac80211/patches/650-rt2x00-add-support-for-external-PA-on-MT7620.patch create mode 100644 root/package/kernel/mac80211/patches/651-rt2x00-remove-unneccesary-code.patch create mode 100644 root/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch create mode 100644 root/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch create mode 100644 root/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch create mode 100644 root/package/kernel/mac80211/patches/810-b43-gpio-mask-module-option.patch create mode 100644 root/package/kernel/mac80211/patches/811-b43_no_pio.patch create mode 100644 root/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch create mode 100644 root/package/kernel/mac80211/patches/813-b43-reduce-number-of-RX-slots.patch create mode 100644 root/package/kernel/mac80211/patches/814-b43-only-use-gpio-0-1-for-led.patch create mode 100644 root/package/kernel/mac80211/patches/815-b43-always-take-overlapping-devs.patch create mode 100644 root/package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch create mode 100644 root/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch create mode 100644 root/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch create mode 100644 root/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch create mode 100644 root/package/kernel/mac80211/patches/863-brcmfmac-add-in-driver-tables-with-country-codes.patch create mode 100644 root/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch create mode 100644 root/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch create mode 100644 root/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch create mode 100644 root/package/kernel/mac80211/patches/936-ath10k-fix-otp-failure-result.patch create mode 100644 root/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch create mode 100644 root/package/kernel/mac80211/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch create mode 100644 root/package/kernel/mac80211/patches/960-0011-ath10k-limit-pci-buffer-size.patch create mode 100644 root/package/kernel/mac80211/patches/970-rsi-fix-kbuild-reported-build-errors-with-CONFIG_PM-off create mode 100644 root/package/kernel/mac80211/patches/971-rsi-move-rsi_sdio_reinit_device-out-of-CONFIG_PM.patch create mode 100644 root/package/kernel/mac80211/patches/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch create mode 100644 root/package/kernel/mac80211/patches/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch create mode 100644 root/package/kernel/mac80211/patches/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch create mode 100644 root/package/kernel/mac80211/patches/975-ath10k-use-tpt-trigger-by-default.patch create mode 100755 root/package/kernel/mac80211/scripts/import-backports.sh create mode 100644 root/package/network/services/hostapd/Config.in create mode 100644 root/package/network/services/hostapd/Makefile create mode 100644 root/package/network/services/hostapd/files/hostapd-full.config create mode 100644 root/package/network/services/hostapd/files/hostapd-mini.config create mode 100644 root/package/network/services/hostapd/files/hostapd.sh create mode 100644 root/package/network/services/hostapd/files/multicall.c create mode 100644 root/package/network/services/hostapd/files/wpa_supplicant-full.config create mode 100644 root/package/network/services/hostapd/files/wpa_supplicant-mini.config create mode 100644 root/package/network/services/hostapd/files/wpa_supplicant-p2p.config create mode 100644 root/package/network/services/hostapd/files/wps-hotplug.sh create mode 100644 root/package/network/services/hostapd/patches/001-mesh-factor-out-mesh-join-function.patch create mode 100644 root/package/network/services/hostapd/patches/002-mesh-factor-out-rsn-initialization.patch create mode 100644 root/package/network/services/hostapd/patches/003-mesh-relocate-RSN-init-function.patch create mode 100644 root/package/network/services/hostapd/patches/004-mesh-use-setup-completion-callback-to-complete-mesh-.patch create mode 100644 root/package/network/services/hostapd/patches/005-mesh-reflect-country-setting-to-mesh-configuration.patch create mode 100644 root/package/network/services/hostapd/patches/006-mesh-inform-kernel-driver-DFS-handler-in-userspace.patch create mode 100644 root/package/network/services/hostapd/patches/007-mesh-apply-channel-attributes-before-running-Mesh.patch create mode 100644 root/package/network/services/hostapd/patches/008-mesh-set-interface-type-to-mesh-before-setting-inter.patch create mode 100644 root/package/network/services/hostapd/patches/009-mesh-set-mesh-center-frequency.patch create mode 100644 root/package/network/services/hostapd/patches/010-mesh-consider-mesh-interface-on-dfs-event-handler.patch create mode 100644 root/package/network/services/hostapd/patches/011-mesh-Allow-DFS-channels-to-be-selected-if-dfs-is-ena.patch create mode 100644 root/package/network/services/hostapd/patches/012-mesh-allow-mesh-to-send-channel-switch-request.patch create mode 100644 root/package/network/services/hostapd/patches/013-mesh-do-not-allow-pri-sec-channel-switch.patch create mode 100644 root/package/network/services/hostapd/patches/014-mesh-do-not-allow-scan-result-to-swap-pri-sec.patch create mode 100644 root/package/network/services/hostapd/patches/015-mesh-do-not-use-offchan-mgmt-tx-on-DFS.patch create mode 100644 root/package/network/services/hostapd/patches/016-mesh-fix-channel-switch-error-during-CAC.patch create mode 100644 root/package/network/services/hostapd/patches/017-mesh-use-right-interface-context-to-send-DFS-event-m.patch create mode 100644 root/package/network/services/hostapd/patches/018-mesh-make-forwarding-configurable.patch create mode 100644 root/package/network/services/hostapd/patches/022-mesh-fix-crash-with-CONFIG_TAXONOMY-enabled.patch create mode 100644 root/package/network/services/hostapd/patches/031-mesh-add-VHT_CHANWIDTH_USE_HT-to-max_oper_chwidth.patch create mode 100644 root/package/network/services/hostapd/patches/032-mesh-implement-use-of-VHT20-config-in-mesh-mode.patch create mode 100644 root/package/network/services/hostapd/patches/033-mesh-fix-parsing-of-max_oper_chwidth.patch create mode 100644 root/package/network/services/hostapd/patches/100-daemonize_fix.patch create mode 100644 root/package/network/services/hostapd/patches/110-no_eapol_fix.patch create mode 100644 root/package/network/services/hostapd/patches/120-disable_bridge_packet_workaround.patch create mode 100644 root/package/network/services/hostapd/patches/200-multicall.patch create mode 100644 root/package/network/services/hostapd/patches/300-noscan.patch create mode 100644 root/package/network/services/hostapd/patches/301-mesh-noscan.patch create mode 100644 root/package/network/services/hostapd/patches/310-rescan_immediately.patch create mode 100644 root/package/network/services/hostapd/patches/320-optional_rfkill.patch create mode 100644 root/package/network/services/hostapd/patches/330-nl80211_fix_set_freq.patch create mode 100644 root/package/network/services/hostapd/patches/340-reload_freq_change.patch create mode 100644 root/package/network/services/hostapd/patches/350-nl80211_del_beacon_bss.patch create mode 100644 root/package/network/services/hostapd/patches/360-ctrl_iface_reload.patch create mode 100644 root/package/network/services/hostapd/patches/370-ap_sta_support.patch create mode 100644 root/package/network/services/hostapd/patches/380-disable_ctrl_iface_mib.patch create mode 100644 root/package/network/services/hostapd/patches/381-hostapd_cli_UNKNOWN-COMMAND.patch create mode 100644 root/package/network/services/hostapd/patches/390-wpa_ie_cap_workaround.patch create mode 100644 root/package/network/services/hostapd/patches/400-wps_single_auth_enc_type.patch create mode 100644 root/package/network/services/hostapd/patches/410-limit_debug_messages.patch create mode 100644 root/package/network/services/hostapd/patches/420-indicate-features.patch create mode 100644 root/package/network/services/hostapd/patches/430-hostapd_cli_ifdef.patch create mode 100644 root/package/network/services/hostapd/patches/431-wpa_cli_ifdef.patch create mode 100644 root/package/network/services/hostapd/patches/432-missing-typedef.patch create mode 100644 root/package/network/services/hostapd/patches/450-scan_wait.patch create mode 100644 root/package/network/services/hostapd/patches/460-wpa_supplicant-add-new-config-params-to-be-used-with.patch create mode 100644 root/package/network/services/hostapd/patches/461-driver_nl80211-use-new-parameters-during-ibss-join.patch create mode 100644 root/package/network/services/hostapd/patches/463-add-mcast_rate-to-11s.patch create mode 100644 root/package/network/services/hostapd/patches/464-fix-mesh-obss-check.patch create mode 100644 root/package/network/services/hostapd/patches/470-survey_data_fallback.patch create mode 100644 root/package/network/services/hostapd/patches/600-ubus_support.patch create mode 100644 root/package/network/services/hostapd/src/src/ap/ubus.c create mode 100644 root/package/network/services/hostapd/src/src/ap/ubus.h create mode 100644 root/package/network/services/hostapd/src/src/utils/build_features.h diff --git a/root/package/kernel/mac80211/Makefile b/root/package/kernel/mac80211/Makefile new file mode 100644 index 00000000..3c88e451 --- /dev/null +++ b/root/package/kernel/mac80211/Makefile @@ -0,0 +1,1980 @@ +# +# Copyright (C) 2007-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=mac80211 + +PKG_VERSION:=2017-11-01 +PKG_RELEASE:=9 +PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources +PKG_HASH:=8437ab7886b988c8152e7a4db30b7f41009e49a3b2cb863edd05da1ecd7eb05a + +PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) +PKG_BUILD_PARALLEL:=1 + +PKG_MAINTAINER:=Felix Fietkau + +PKG_DRIVERS = \ + adm8211 \ + airo \ + ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k \ + b43 b43legacy \ + carl9170 \ + hermes hermes-pci hermes-pcmcia hermes-plx\ + iwl-legacy iwl3945 iwl4965 iwlwifi \ + lib80211 \ + libipw ipw2100 ipw2200 \ + libertas-sdio libertas-usb libertas-spi \ + mac80211-hwsim \ + mt7601u \ + mwl8k mwifiex-pcie mwifiex-sdio \ + p54-common p54-pci p54-spi p54-usb \ + rsi91x rsi91x-usb rsi91x-sdio\ + rt2x00-lib rt2x00-pci rt2x00-usb \ + rt2400-pci rt2500-pci rt2500-usb \ + rt2800-lib rt2800-mmio rt2800-pci rt2800-soc rt2800-usb \ + rt61-pci rt73-usb \ + rtl8180 rtl8187 \ + rtlwifi rtlwifi-pci rtlwifi-btcoexist rtlwifi-usb rtl8192c-common \ + rtl8192ce rtl8192se rtl8192de rtl8192cu rtl8821ae \ + rtl8xxxu \ + wlcore wl12xx wl18xx \ + zd1211rw + +PKG_CONFIG_DEPENDS:= \ + CONFIG_PACKAGE_kmod-mac80211 \ + $(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS)) \ + CONFIG_PACKAGE_MAC80211_DEBUGFS \ + CONFIG_PACKAGE_MAC80211_MESH \ + CONFIG_PACKAGE_MAC80211_TRACING \ + CONFIG_PACKAGE_ATH_DEBUG \ + CONFIG_PACKAGE_ATH_DFS \ + CONFIG_PACKAGE_ATH_SPECTRAL \ + CONFIG_PACKAGE_B43_DEBUG \ + CONFIG_PACKAGE_B43_PIO \ + CONFIG_PACKAGE_B43_PHY_G \ + CONFIG_PACKAGE_B43_PHY_N \ + CONFIG_PACKAGE_B43_PHY_LP \ + CONFIG_PACKAGE_B43_PHY_HT \ + CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \ + CONFIG_PACKAGE_B43_BUSES_BCMA \ + CONFIG_PACKAGE_B43_BUSES_SSB \ + CONFIG_PACKAGE_BRCM80211_DEBUG \ + CONFIG_PACKAGE_IWLWIFI_DEBUG \ + CONFIG_PACKAGE_IWLWIFI_DEBUGFS \ + CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS \ + CONFIG_PACKAGE_RT2X00_DEBUG \ + CONFIG_PACKAGE_RTLWIFI_DEBUG \ + CONFIG_ATH9K_SUPPORT_PCOEM \ + CONFIG_ATH9K_TX99 \ + CONFIG_ATH10K_LEDS \ + CONFIG_ATH10K_THERMAL \ + CONFIG_ATH_USER_REGD \ + +include $(INCLUDE_DIR)/package.mk + +WMENU:=Wireless Drivers + +define KernelPackage/mac80211/Default + SUBMENU:=$(WMENU) + URL:=https://wireless.wiki.kernel.org/ + MAINTAINER:=Felix Fietkau +endef + +define KernelPackage/cfg80211 + $(call KernelPackage/mac80211/Default) + TITLE:=cfg80211 - wireless configuration API + DEPENDS+= +iw +wireless-regdb + FILES:= \ + $(PKG_BUILD_DIR)/compat/compat.ko \ + $(PKG_BUILD_DIR)/net/wireless/cfg80211.ko +endef + +define KernelPackage/cfg80211/description +cfg80211 is the Linux wireless LAN (802.11) configuration API. +endef + +define KernelPackage/mac80211 + $(call KernelPackage/mac80211/Default) + TITLE:=Linux 802.11 Wireless Networking Stack + # +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c + DEPENDS+= +kmod-cfg80211 +hostapd-common + KCONFIG:=\ + CONFIG_AVERAGE=y + FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko + MENU:=1 +endef + +define KernelPackage/mac80211/config + if PACKAGE_kmod-mac80211 + + config PACKAGE_MAC80211_DEBUGFS + bool "Export mac80211 internals in DebugFS" + select KERNEL_DEBUG_FS + default y + help + Select this to see extensive information about + the internal state of mac80211 in debugfs. + + config PACKAGE_MAC80211_TRACING + bool "Enable tracing (mac80211 and supported drivers)" + select KERNEL_FTRACE + select KERNEL_ENABLE_DEFAULT_TRACERS + default n + help + Select this to enable tracing of mac80211 and + related wifi drivers (using trace-cmd). + + config PACKAGE_MAC80211_MESH + bool "Enable 802.11s mesh support" + default y + + endif +endef + +define KernelPackage/mac80211/description +Generic IEEE 802.11 Networking Stack (mac80211) +endef + +define KernelPackage/adm8211 + $(call KernelPackage/mac80211/Default) + TITLE:=ADMTek 8211 support + DEPENDS+=@PCI_SUPPORT +kmod-mac80211 +kmod-eeprom-93cx6 + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/admtek/adm8211.ko + AUTOLOAD:=$(call AutoProbe,adm8211) +endef + +define KernelPackage/airo + $(call KernelPackage/mac80211/Default) + TITLE:=Cisco Aironet driver + DEPENDS+=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-cfg80211 @TARGET_x86 + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/cisco/airo.ko + AUTOLOAD:=$(call AutoProbe,airo) +endef + +define KernelPackage/airo/description + Kernel support for Cisco Aironet cards +endef + +define KernelPackage/ath/config + if PACKAGE_kmod-ath + config ATH_USER_REGD + bool "Force Atheros drivers to respect the user's regdomain settings" + default y + help + Atheros' idea of regulatory handling is that the EEPROM of the card defines + the regulatory limits and the user is only allowed to restrict the settings + even further, even if the country allows frequencies or power levels that + are forbidden by the EEPROM settings. + + Select this option if you want the driver to respect the user's decision about + regulatory settings. + + config PACKAGE_ATH_DEBUG + bool "Atheros wireless debugging" + help + Say Y, if you want to debug atheros wireless drivers. + Only ath9k & ath10k make use of this. + + config PACKAGE_ATH_DFS + bool "Enable DFS support" + default y + help + Dynamic frequency selection (DFS) is required for most of the 5 GHz band + channels in Europe, US, and Japan. + + Select this option if you want to use such channels. + + config PACKAGE_ATH_SPECTRAL + bool "Atheros spectral scan support" + depends on PACKAGE_ATH_DEBUG + select KERNEL_RELAY + help + Say Y to enable access to the FFT/spectral data via debugfs. + + endif +endef + +define KernelPackage/ath + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros common driver part + DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79||TARGET_ath25 +kmod-mac80211 + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko + MENU:=1 +endef + +define KernelPackage/ath/description + This module contains some common parts needed by Atheros Wireless drivers. +endef + +define KernelPackage/ath5k + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 5xxx wireless cards support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath5k + DEPENDS+= @PCI_SUPPORT||@TARGET_ath25 +kmod-ath +@DRIVER_11W_SUPPORT + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath5k/ath5k.ko + AUTOLOAD:=$(call AutoProbe,ath5k) +endef + +define KernelPackage/ath5k/description + This module adds support for wireless adapters based on + Atheros 5xxx chipset. +endef + +define KernelPackage/ath6kl + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros FullMAC wireless devices (common code for ath6kl_sdio and ath6kl_usb) + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl + HIDDEN:=1 + DEPENDS+= +kmod-ath +@DRIVER_11N_SUPPORT + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_core.ko +endef + +define KernelPackage/ath6kl-sdio + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11n SDIO wireless cards support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl + DEPENDS+= +kmod-mmc +kmod-ath6kl + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_sdio.ko + AUTOLOAD:=$(call AutoProbe,ath6kl_sdio) +endef + +define KernelPackage/ath6kl-sdio/description +This module adds support for wireless adapters based on +Atheros IEEE 802.11n AR6003 and AR6004 family of chipsets. +endef + +define KernelPackage/ath6kl-usb + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11n USB wireless cards support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl + DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-ath6kl + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_usb.ko + AUTOLOAD:=$(call AutoProbe,ath6kl_usb) +endef + +define KernelPackage/ath6kl-usb/description +This module adds support for wireless adapters based on the +Atheros IEEE 802.11n AR6004 chipset. +endef + +define KernelPackage/ath9k-common + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc) + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k + HIDDEN:=1 + DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko +endef + +define KernelPackage/ath9k + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11n PCI wireless cards support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k + DEPENDS+= @PCI_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath9k-common + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k.ko + AUTOLOAD:=$(call AutoProbe,ath9k) +endef + +define KernelPackage/ath9k/description +This module adds support for wireless adapters based on +Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. +endef + +define KernelPackage/ath9k/config + + config ATH9K_SUPPORT_PCOEM + bool "Support chips used in PC OEM cards" + depends on PACKAGE_kmod-ath9k + + config ATH9K_TX99 + bool "Enable TX99 support (WARNING: testing only, breaks normal operation!)" + depends on PACKAGE_kmod-ath9k + + config ATH9K_UBNTHSR + bool "Support for Ubiquiti UniFi Outdoor+ access point" + depends on PACKAGE_kmod-ath9k && (TARGET_ar71xx_generic||TARGET_ath79) + default y + +endef + +define KernelPackage/ath9k-htc + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11n USB device support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k + DEPENDS+= @USB_SUPPORT +kmod-ath9k-common +kmod-usb-core +ath9k-htc-firmware + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_htc.ko + AUTOLOAD:=$(call AutoProbe,ath9k_htc) +endef + +define KernelPackage/ath9k-htc/description +This module adds support for wireless adapters based on +Atheros USB AR9271 and AR7010 family of chipsets. +endef + +define KernelPackage/ath10k + $(call KernelPackage/mac80211/Default) + TITLE:=Atheros 802.11ac wireless cards support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath10k + DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT \ + +ATH10K_THERMAL:kmod-hwmon-core +ATH10K_THERMAL:kmod-thermal + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko + AUTOLOAD:=$(call AutoProbe,ath10k_pci) +endef + +define KernelPackage/ath10k/description +This module adds support for wireless adapters based on +Atheros IEEE 802.11ac family of chipsets. For now only +PCI is supported. +endef + +define KernelPackage/ath10k/config + + config ATH10K_LEDS + bool "Enable LED support" + default y + depends on PACKAGE_kmod-ath10k + + config ATH10K_THERMAL + bool "Enable thermal sensors and throttling support" + depends on PACKAGE_kmod-ath10k + +endef + +#Broadcom firmware +ifneq ($(CONFIG_B43_FW_6_30),) + PKG_B43_FWV4_NAME:=broadcom-wl + PKG_B43_FWV4_VERSION:=6.30.163.46 + PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).wl_apsta.o + PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 + PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ + PKG_B43_FWV4_HASH:=a07c3b6b277833c7dbe61daa511f908cd66c5e2763eb7a0859abc36cd9335c2d +else +ifneq ($(CONFIG_B43_FW_5_10),) + PKG_B43_FWV4_NAME:=broadcom-wl + PKG_B43_FWV4_VERSION:=5.10.56.27.3 + PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta/wl_prebuilt.o + PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)_mipsel.tar.bz2 + PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/ + PKG_B43_FWV4_HASH:=26a8c370f48fc129d0731cfd751c36cae1419b0bc8ca35781126744e60eae009 +else +ifneq ($(CONFIG_B43_FW_4_178),) + PKG_B43_FWV4_NAME:=broadcom-wl + PKG_B43_FWV4_VERSION:=4.178.10.4 + PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o + PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 + PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/ + PKG_B43_FWV4_HASH:=32f6ad98facbb9045646fdc8b54bb03086d204153253f9c65d0234a5d90ae53f +else +ifneq ($(CONFIG_B43_FW_5_100_138),) + PKG_B43_FWV4_NAME:=broadcom-wl + PKG_B43_FWV4_VERSION:=5.100.138 + PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o + PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 + PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ + PKG_B43_FWV4_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f +else + PKG_B43_FWV4_NAME:=broadcom-wl + PKG_B43_FWV4_VERSION:=4.150.10.5 + PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta_mimo.o + PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2 + PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/ + PKG_B43_FWV4_HASH:=a9f4e276a4d8d3a1cd0f2eb87080ae89b77f0a7140f06d4e9e2135fc44fdd533 +endif +endif +endif +endif +ifneq ($(CONFIG_B43_OPENFIRMWARE),) + PKG_B43_FWV4_NAME:=broadcom-wl + PKG_B43_FWV4_VERSION:=5.2 + PKG_B43_FWV4_OBJECT:=openfwwf-$(PKG_B43_FWV4_VERSION) + PKG_B43_FWV4_SOURCE:=openfwwf-$(PKG_B43_FWV4_VERSION).tar.gz + PKG_B43_FWV4_SOURCE_URL:=http://netweb.ing.unibs.it/~openfwwf/firmware + PKG_B43_FWV4_HASH:=9de03320083201080b2e94b81637ac07a159cf4e6f3481383e1a217e627bc0dc +endif + + +define Download/b43 + FILE:=$(PKG_B43_FWV4_SOURCE) + URL:=$(PKG_B43_FWV4_SOURCE_URL) + HASH:=$(PKG_B43_FWV4_HASH) +endef +$(eval $(call Download,b43)) + +define KernelPackage/b43 + $(call KernelPackage/mac80211/Default) + TITLE:=Broadcom 43xx wireless support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43 + KCONFIG:= \ + CONFIG_HW_RANDOM=y + # Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb + DEPENDS += \ + @PCI_SUPPORT +kmod-mac80211 \ + $(if $(CONFIG_PACKAGE_B43_USE_SSB),+kmod-ssb) \ + $(if $(CONFIG_PACKAGE_B43_USE_BCMA),+kmod-bcma) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43/b43.ko + AUTOLOAD:=$(call AutoProbe,b43) + MENU:=1 +endef + +define KernelPackage/b43/config + +config PACKAGE_B43_USE_SSB + select PACKAGE_kmod-ssb + tristate + depends on !TARGET_brcm47xx && !TARGET_brcm63xx + default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB + default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_SSB + +config PACKAGE_B43_USE_BCMA + select PACKAGE_kmod-bcma + tristate + depends on !TARGET_brcm47xx && !TARGET_bcm53xx + default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB + default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA + + if PACKAGE_kmod-b43 + + choice + prompt "b43 firmware version" + default B43_FW_5_100_138 + help + This option allows you to select the version of the b43 firmware. + + config B43_FW_4_150 + bool "Firmware 410.2160 from driver 4.150.10.5 (old stable)" + help + Old stable firmware for BCM43xx devices. + + If unsure, select this. + + config B43_FW_4_178 + bool "Firmware 478.104 from driver 4.178.10.4" + help + Older firmware for BCM43xx devices. + + If unsure, select the "stable" firmware. + + config B43_FW_5_10 + bool "Firmware 508.1084 from driver 5.10.56.27" + help + Older firmware for BCM43xx devices. + + If unsure, select the "stable" firmware. + + config B43_FW_5_100_138 + bool "Firmware 666.2 from driver 5.100.138 (stable)" + help + The currently default firmware for BCM43xx devices. + + This firmware currently gets most of the testing and is needed for some N-PHY devices. + + If unsure, select the this firmware. + + config B43_FW_6_30 + bool "Firmware 784.2 from driver 6.30.163.46 (experimental)" + help + Newer experimental firmware for BCM43xx devices. + + This firmware is mostly untested. + + If unsure, select the "stable" firmware. + + config B43_OPENFIRMWARE + bool "Open FirmWare for WiFi networks" + help + Opensource firmware for BCM43xx devices. + + Do _not_ select this, unless you know what you are doing. + The Opensource firmware is not suitable for embedded devices, yet. + It does not support QoS, which is bad for AccessPoints. + It does not support hardware crypto acceleration, which is a showstopper + for embedded devices with low CPU resources. + + If unsure, select the "stable" firmware. + + endchoice + + config B43_FW_SQUASH + bool "Remove unnecessary firmware files" + depends on !B43_OPENFIRMWARE + default y + help + This options allows you to remove unnecessary b43 firmware files + from the final rootfs image. This can reduce the rootfs size by + up to 200k. + + If unsure, say Y. + + config B43_FW_SQUASH_COREREVS + string "Core revisions to include" + depends on B43_FW_SQUASH + default "5,6,7,8,9,10,11,13,15" if TARGET_brcm47xx_legacy + default "16,28,29,30" if TARGET_brcm47xx_mips74k + default "5,6,7,8,9,10,11,13,15,16,28,29,30" + help + This is a comma seperated list of core revision numbers. + + Example (keep files for rev5 only): + 5 + + Example (keep files for rev5 and rev11): + 5,11 + + config B43_FW_SQUASH_PHYTYPES + string "PHY types to include" + depends on B43_FW_SQUASH + default "G,N,LP" if TARGET_brcm47xx_legacy + default "N,HT" if TARGET_brcm47xx_mips74k + default "G,N,LP,HT" + help + This is a comma seperated list of PHY types: + A => A-PHY + AG => Dual A-PHY G-PHY + G => G-PHY + LP => LP-PHY + N => N-PHY + HT => HT-PHY + LCN => LCN-PHY + LCN40 => LCN40-PHY + AC => AC-PHY + + Example (keep files for G-PHY only): + G + + Example (keep files for G-PHY and N-PHY): + G,N + + choice + prompt "Supported buses" + default PACKAGE_B43_BUSES_BCMA_AND_SSB + help + This allows choosing buses that b43 should support. + + config PACKAGE_B43_BUSES_BCMA_AND_SSB + depends on !TARGET_brcm47xx_legacy && !TARGET_brcm47xx_mips74k && !TARGET_bcm53xx + bool "BCMA and SSB" + + config PACKAGE_B43_BUSES_BCMA + depends on !TARGET_brcm47xx_legacy + bool "BCMA only" + + config PACKAGE_B43_BUSES_SSB + depends on !TARGET_brcm47xx_mips74k && !TARGET_bcm53xx + bool "SSB only" + + endchoice + + config PACKAGE_B43_DEBUG + bool "Enable debug output and debugfs for b43" + default n + help + Enable additional debug output and runtime sanity checks for b43 + and enables the debugfs interface. + + If unsure, say N. + + config PACKAGE_B43_PIO + bool "Enable support for PIO transfer mode" + default n + help + Enable support for using PIO instead of DMA. Unless you have DMA + transfer problems you don't need this. + + If unsure, say N. + + config PACKAGE_B43_PHY_G + bool "Enable support for G-PHYs" + default n if TARGET_brcm47xx_mips74k + default y + help + Enable support for G-PHY. This includes support for the following devices: + PCI: BCM4306, BCM4311, BCM4318 + SoC: BCM5352E, BCM4712 + + If unsure, say Y. + + config PACKAGE_B43_PHY_N + bool "Enable support for N-PHYs" + default y + help + Enable support for N-PHY. This includes support for the following devices: + PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225 + SoC: BCM4716, BCM4717, BCM4718 + + Currently only 11g speed is available. + + If unsure, say Y. + + config PACKAGE_B43_PHY_LP + bool "Enable support for LP-PHYs" + default n if TARGET_brcm47xx_mips74k + default y + help + Enable support for LP-PHY. This includes support for the following devices: + PCI: BCM4312 + SoC: BCM5354 + + If unsure, say Y. + + config PACKAGE_B43_PHY_HT + bool "Enable support for HT-PHYs" + default n if TARGET_brcm47xx_legacy + default y + help + Enable support for HT-PHY. This includes support for the following devices: + PCI: BCM4331 + + Currently only 11g speed is available. + + If unsure, say Y. + + config PACKAGE_B43_PHY_LCN + bool "Enable support for LCN-PHYs" + depends on BROKEN + default n + help + Currently broken. + + If unsure, say N. + + endif +endef + +define KernelPackage/b43/description +Kernel module for Broadcom 43xx wireless support (mac80211 stack) new +endef + +define KernelPackage/b43legacy + $(call KernelPackage/mac80211/Default) + TITLE:=Broadcom 43xx-legacy wireless support + URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43 + KCONFIG:= \ + CONFIG_HW_RANDOM=y + DEPENDS+= +kmod-mac80211 +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb +b43legacy-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43legacy/b43legacy.ko + AUTOLOAD:=$(call AutoProbe,b43legacy) + MENU:=1 +endef + +define KernelPackage/b43legacy/description +Kernel module for Broadcom 43xx-legacy wireless support (mac80211 stack) new +endef + + +define KernelPackage/brcmutil + $(call KernelPackage/mac80211/Default) + TITLE:=Broadcom IEEE802.11n common driver parts + URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 + DEPENDS+=@PCI_SUPPORT||USB_SUPPORT + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko + AUTOLOAD:=$(call AutoProbe,brcmutil) + MENU:=1 +endef + +define KernelPackage/brcmutil/description + This module contains some common parts needed by Broadcom Wireless drivers brcmsmac and brcmfmac. +endef + +define KernelPackage/brcmutil/config + if PACKAGE_kmod-brcmutil + + config PACKAGE_BRCM80211_DEBUG + bool "Broadcom wireless driver debugging" + help + Say Y, if you want to debug brcmsmac and brcmfmac wireless driver. + + endif +endef + +PKG_BRCMSMAC_FW_NAME:=broadcom-wl +PKG_BRCMSMAC_FW_VERSION:=5.100.138 +PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o +PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2 +PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/ +PKG_BRCMSMAC_FW_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f + +define Download/brcmsmac + FILE:=$(PKG_BRCMSMAC_FW_SOURCE) + URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL) + HASH:=$(PKG_BRCMSMAC_FW_HASH) +endef +$(eval $(call Download,brcmsmac)) + +define KernelPackage/brcmsmac + $(call KernelPackage/mac80211/Default) + TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver + URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 + DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil +!BRCMSMAC_USE_FW_FROM_WL:brcmsmac-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcmsmac.ko + AUTOLOAD:=$(call AutoProbe,brcmsmac) + MENU:=1 +endef + +define KernelPackage/brcmsmac/description + Kernel module for Broadcom IEEE802.11n PCIe Wireless cards +endef + +define KernelPackage/brcmsmac/config + if PACKAGE_kmod-brcmsmac + + config BRCMSMAC_USE_FW_FROM_WL + bool "Use firmware extracted from broadcom proprietary driver" + default y + help + Instead of using the official brcmsmac firmware a firmware + version 666.2 extracted from the proprietary Broadcom driver + is used. This is needed to get core rev 17 used in bcm4716 + to work. + + If unsure, say Y. + + endif +endef + + +define KernelPackage/brcmfmac + $(call KernelPackage/mac80211/Default) + TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver + URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211 + DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +kmod-brcmutil \ + +BRCMFMAC_SDIO:kmod-mmc @!TARGET_uml \ + +BRCMFMAC_USB:kmod-usb-core +BRCMFMAC_USB:brcmfmac-firmware-usb + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko + AUTOLOAD:=$(call AutoProbe,brcmfmac) +endef + +define KernelPackage/brcmfmac/description + Kernel module for Broadcom IEEE802.11n USB Wireless cards +endef + +define KernelPackage/brcmfmac/config + if PACKAGE_kmod-brcmfmac + + config BRCMFMAC_SDIO + bool "Enable SDIO bus interface support" + default y if TARGET_brcm2708 + default y if TARGET_sunxi + default n + help + Enable support for cards attached to an SDIO bus. + Select this option only if you are sure that your + board has a Broadcom wireless chip atacched to + that bus. + + config BRCMFMAC_USB + bool "Enable USB bus interface support" + depends on USB_SUPPORT + default y + help + Supported USB connected chipsets: + BCM43235, BCM43236, BCM43238 (all in revision 3 only) + BCM43143, BCM43242, BCM43566, BCM43569 + + config BRCMFMAC_PCIE + bool "Enable PCIE bus interface support" + depends on PCI_SUPPORT + default y + help + Supported PCIe connected chipsets: + BCM4354, BCM4356, BCM43567, BCM43570, BCM43602 + + endif +endef + + +define KernelPackage/carl9170 + $(call KernelPackage/mac80211/Default) + TITLE:=Driver for Atheros AR9170 USB sticks + DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core +@DRIVER_11N_SUPPORT +carl9170-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/carl9170/carl9170.ko + AUTOLOAD:=$(call AutoProbe,carl9170) +endef + + +define KernelPackage/hermes + $(call KernelPackage/mac80211/Default) + TITLE:=Hermes 802.11b chipset support + DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT +kmod-crypto-michael-mic + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco.ko + AUTOLOAD:=$(call AutoProbe,orinoco) +endef + +define KernelPackage/hermes/description + Kernel support for Hermes 802.11b chipsets +endef + +define KernelPackage/hermes-pci + $(call KernelPackage/mac80211/Default) + TITLE:=Intersil Prism 2.5 PCI support + DEPENDS:=@PCI_SUPPORT +kmod-hermes + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_pci.ko + AUTOLOAD:=$(call AutoProbe,orinoco_pci) +endef + +define KernelPackage/hermes-pci/description + Kernel modules for Intersil Prism 2.5 PCI support +endef + +define KernelPackage/hermes-plx + $(call KernelPackage/mac80211/Default) + TITLE:=PLX9052 based PCI adaptor + DEPENDS:=@PCI_SUPPORT +kmod-hermes + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_plx.ko + AUTOLOAD:=$(call AutoProbe,orinoco_plx) +endef + +define KernelPackage/hermes-plx/description + Kernel modules for Hermes in PLX9052 based PCI adaptors +endef + +define KernelPackage/hermes-pcmcia + $(call KernelPackage/mac80211/Default) + TITLE:=Hermes based PCMCIA adaptors + DEPENDS:=@PCMCIA_SUPPORT +kmod-hermes @BROKEN + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_cs.ko + AUTOLOAD:=$(call AutoProbe,orinoco_cs) +endef + +define KernelPackage/hermes-pcmcia/description + Kernel modules for Hermes based PCMCIA adaptors +endef + + +define KernelPackage/iwlwifi + $(call KernelPackage/mac80211/Default) + DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT @!LINUX_3_18 + TITLE:=Intel AGN Wireless support + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/dvm/iwldvm.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/mvm/iwlmvm.ko + AUTOLOAD:=$(call AutoProbe,iwlwifi iwldvm iwlmvm) + MENU:=1 +endef + +define KernelPackage/iwlwifi/description + iwlwifi kernel module for + Intel Wireless WiFi Link 6250AGN Adapter + Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN) + Intel WiFi Link 1000BGN + Intel Wireless WiFi 5150AGN + Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN + Intel 6005 Series Wi-Fi Adapters + Intel 6030 Series Wi-Fi Adapters + Intel Wireless WiFi Link 6150BGN 2 Adapter + Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN) + Intel 2000 Series Wi-Fi Adapters + Intel 7260 Wi-Fi Adapter + Intel 3160 Wi-Fi Adapter + Intel 7265 Wi-Fi Adapter + Intel 8260 Wi-Fi Adapter + Intel 3165 Wi-Fi Adapter +endef + +define KernelPackage/iwlwifi/config + if PACKAGE_kmod-iwlwifi + + config PACKAGE_IWLWIFI_DEBUG + bool "Enable full debugging output in the iwlwifi driver" + default n + help + This option will enable debug tracing output for the iwlwifi drivers + + This will result in the kernel module being ~100k larger. You can + control which debug output is sent to the kernel log by setting the + value in + + /sys/module/iwlwifi/parameters/debug + + This entry will only exist if this option is enabled. + + To set a value, simply echo an 8-byte hex value to the same file: + + % echo 0x43fff > /sys/module/iwlwifi/parameters/debug + + You can find the list of debug mask values in: + drivers/net/wireless/intel/iwlwifi/iwl-debug.h + + If this is your first time using this driver, you should say Y here + as the debug information can assist others in helping you resolve + any problems you may encounter. + + config PACKAGE_IWLWIFI_DEBUGFS + bool "iwlwifi debugfs support" + depends on PACKAGE_MAC80211_DEBUGFS + default n + help + Enable creation of debugfs files for the iwlwifi drivers. This + is a low-impact option that allows getting insight into the + driver's state at runtime. + + endif +endef + +define KernelPackage/iwl-legacy + $(call KernelPackage/mac80211/Default) + DEPENDS:= +kmod-mac80211 @PCI_SUPPORT + TITLE:=Intel legacy Wireless support + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlegacy/iwlegacy.ko + AUTOLOAD:=$(call AutoProbe,iwlegacy) +endef + +define KernelPackage/iwl-legacy/description + iwl-legacy kernel module for legacy Intel wireless support +endef + +define KernelPackage/iwl3945 + $(call KernelPackage/mac80211/Default) + DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy +iwl3945-firmware + TITLE:=Intel iwl3945 Wireless support + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlegacy/iwl3945.ko + AUTOLOAD:=$(call AutoProbe,iwl3945) +endef + +define KernelPackage/iwl3945/description + iwl3945 kernel module for Intel 3945 support +endef + +define KernelPackage/iwl4965 + $(call KernelPackage/mac80211/Default) + DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy +@DRIVER_11N_SUPPORT +iwl4965-firmware + TITLE:=Intel iwl4965 Wireless support + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlegacy/iwl4965.ko + AUTOLOAD:=$(call AutoProbe,iwl4965) +endef + +define KernelPackage/iwl4965/description + iwl4965 kernel module for Intel 4965 support +endef + + +define KernelPackage/lib80211 + $(call KernelPackage/mac80211/Default) + TITLE:=802.11 Networking stack + DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash + FILES:= \ + $(PKG_BUILD_DIR)/net/wireless/lib80211.ko \ + $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \ + $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_ccmp.ko \ + $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_tkip.ko + AUTOLOAD:=$(call AutoProbe, \ + lib80211 \ + lib80211_crypt_wep \ + lib80211_crypt_ccmp \ + lib80211_crypt_tkip \ + ) +endef + +define KernelPackage/lib80211/description + Kernel modules for 802.11 Networking stack + Includes: + - lib80211 + - lib80211_crypt_wep + - lib80211_crypt_tkip + - lib80211_crytp_ccmp +endef + + +define KernelPackage/libipw + $(call KernelPackage/mac80211/Default) + TITLE:=libipw for ipw2100 and ipw2200 + DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-crypto-ecb +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN @!LINUX_3_18 + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/libipw.ko + AUTOLOAD:=$(call AutoProbe,libipw) +endef + +define KernelPackage/libipw/description + Hardware independent IEEE 802.11 networking stack for ipw2100 and ipw2200. +endef + +IPW2100_NAME:=ipw2100-fw +IPW2100_VERSION:=1.3 + +define Download/ipw2100 + URL:= \ + https://src.fedoraproject.org/repo/pkgs/ipw2100-firmware/ipw2100-fw-1.3.tgz/46aa75bcda1a00efa841f9707bbbd113/ \ + https://archlinux.mirror.pkern.at/other/packages/ipw2100-fw/ \ + http://mirror.ox.ac.uk/sites/ftp.openbsd.org/pub/OpenBSD/distfiles/firmware/ \ + http://firmware.openbsd.org/firmware-dist/ + FILE:=$(IPW2100_NAME)-$(IPW2100_VERSION).tgz + HASH:=e1107c455e48d324a616b47a622593bc8413dcce72026f72731c0b03dae3a7a2 +endef +$(eval $(call Download,ipw2100)) + +define KernelPackage/ipw2100 + $(call KernelPackage/mac80211/Default) + TITLE:=Intel IPW2100 driver + DEPENDS:=@PCI_SUPPORT +kmod-libipw + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/ipw2100.ko + AUTOLOAD:=$(call AutoProbe,ipw2100) +endef + +define KernelPackage/ipw2100/description + Kernel support for Intel IPW2100 + Includes: + - ipw2100 +endef + +IPW2200_NAME:=ipw2200-fw +IPW2200_VERSION:=3.1 + +define Download/ipw2200 + URL:= \ + https://src.fedoraproject.org/repo/pkgs/ipw2200-firmware/ipw2200-fw-3.1.tgz/eaba788643c7cc7483dd67ace70f6e99/ \ + https://archlinux.mirror.pkern.at/other/packages/ipw2200-fw/ \ + http://mirror.ox.ac.uk/sites/ftp.openbsd.org/pub/OpenBSD/distfiles/firmware/ \ + http://firmware.openbsd.org/firmware-dist/ + FILE:=$(IPW2200_NAME)-$(IPW2200_VERSION).tgz + HASH:=c6818c11c18cc030d55ff83f64b2bad8feef485e7742f84f94a61d811a6258bd +endef +$(eval $(call Download,ipw2200)) + +define KernelPackage/ipw2200 + $(call KernelPackage/mac80211/Default) + TITLE:=Intel IPW2200 driver + DEPENDS:=@PCI_SUPPORT +kmod-libipw + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/ipw2200.ko + AUTOLOAD:=$(call AutoProbe,ipw2200) +endef + +define KernelPackage/ipw2200/description + Kernel support for Intel IPW2200 + Includes: + - ipw2200 +endef + + +define KernelPackage/libertas-usb + $(call KernelPackage/mac80211/Default) + DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-usb-firmware @!LINUX_3_18 + TITLE:=Marvell 88W8015 Wireless Driver + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/usb8xxx.ko + AUTOLOAD:=$(call AutoProbe,libertas usb8xxx) +endef + +define KernelPackage/libertas-sdio + $(call KernelPackage/mac80211/Default) + DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware @!LINUX_3_18 + TITLE:=Marvell 88W8686 Wireless Driver + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_sdio.ko + AUTOLOAD:=$(call AutoProbe,libertas libertas_sdio) +endef + +define KernelPackage/libertas-spi + $(call KernelPackage/mac80211/Default) + SUBMENU:=Wireless Drivers + DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware @!LINUX_3_18 + KCONFIG := \ + CONFIG_SPI=y \ + CONFIG_SPI_MASTER=y + TITLE:=Marvell 88W8686 SPI Wireless Driver + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_spi.ko + AUTOLOAD:=$(call AutoProbe,libertas libertas_spi) +endef + +define KernelPackage/mac80211-hwsim + $(call KernelPackage/mac80211/Default) + TITLE:=mac80211 HW simulation device + DEPENDS+= +kmod-mac80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko + AUTOLOAD:=$(call AutoProbe,mac80211_hwsim) +endef + + +define KernelPackage/mt7601u + $(call KernelPackage/mac80211/Default) + TITLE:=MT7601U-based USB dongles Wireless Driver + DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT @USB_SUPPORT +kmod-usb-core +mt7601u-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko + AUTOLOAD:=$(call AutoProbe,mt7601u) +endef + + +define KernelPackage/mwl8k + $(call KernelPackage/mac80211/Default) + TITLE:=Driver for Marvell TOPDOG 802.11 Wireless cards + URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwl8k + DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +mwl8k-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwl8k.ko + AUTOLOAD:=$(call AutoProbe,mwl8k) +endef + +define KernelPackage/mwl8k/description + Kernel modules for Marvell TOPDOG 802.11 Wireless cards +endef + + +define KernelPackage/mwifiex-pcie + $(call KernelPackage/mac80211/Default) + TITLE:=Driver for Marvell 802.11n/802.11ac PCIe Wireless cards + URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex + DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-pcie-firmware + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_pcie.ko + AUTOLOAD:=$(call AutoProbe,mwifiex_pcie) +endef + +define KernelPackage/mwifiex-pcie/description + Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards +endef + +define KernelPackage/mwifiex-sdio + $(call KernelPackage/mac80211/Default) + TITLE:=Driver for Marvell 802.11n/802.11ac SDIO Wireless cards + URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex + DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-sdio-firmware + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_sdio.ko + AUTOLOAD:=$(call AutoProbe,mwifiex_sdio) +endef + +define KernelPackage/mwifiex-sdio/description + Kernel modules for Marvell 802.11n/802.11ac SDIO Wireless cards +endef + +define KernelPackage/p54/Default + $(call KernelPackage/mac80211/Default) + TITLE:=Prism54 Drivers +endef + +define KernelPackage/p54/description + Kernel module for Prism54 chipsets (mac80211) +endef + +define KernelPackage/p54-common + $(call KernelPackage/p54/Default) + DEPENDS+= @PCI_SUPPORT||@USB_SUPPORT||@TARGET_omap24xx +kmod-mac80211 +kmod-lib-crc-ccitt + TITLE+= (COMMON) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54common.ko +endef + +define KernelPackage/p54-pci + $(call KernelPackage/p54/Default) + TITLE+= (PCI) + DEPENDS+= @PCI_SUPPORT +kmod-p54-common +p54-pci-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54pci.ko + AUTOLOAD:=$(call AutoProbe,p54pci) +endef + +define KernelPackage/p54-usb + $(call KernelPackage/p54/Default) + TITLE+= (USB) + DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-p54-common +p54-usb-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54usb.ko + AUTOLOAD:=$(call AutoProbe,p54usb) +endef + +define KernelPackage/p54-spi + $(call KernelPackage/p54/Default) + TITLE+= (SPI) + DEPENDS+= @TARGET_omap24xx +kmod-p54-common +p54-spi-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54spi.ko + AUTOLOAD:=$(call AutoProbe,p54spi) +endef + +define KernelPackage/rsi91x + $(call KernelPackage/mac80211/Default) + TITLE:=Redpine Signals Inc 91x WLAN driver support + DEPENDS+= +kmod-mac80211 +rs9113-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko +endef + +define KernelPackage/rsi91x-usb + $(call KernelPackage/mac80211/Default) + TITLE:=Redpine Signals USB bus support + DEPENDS+= +kmod-mac80211 +kmod-usb2 +kmod-rsi91x +rs9113-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_usb.ko + AUTOLOAD:=$(call AutoProbe,rsi_usb) +endef + +define KernelPackage/rsi91x-sdio + $(call KernelPackage/mac80211/Default) + TITLE:=Redpine Signals SDIO bus support + DEPENDS+= +kmod-mac80211 +kmod-mmc +kmod-rsi91x +rs9113-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_sdio.ko + AUTOLOAD:=$(call AutoProbe,rsi_sdio) +endef + + + +define KernelPackage/rt2x00/Default + $(call KernelPackage/mac80211/Default) + TITLE:=Ralink Drivers for RT2x00 cards +endef + +define KernelPackage/rt2x00-lib +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211 +kmod-lib-crc-itu-t + TITLE+= (LIB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00lib.ko + MENU:=1 +endef + +define KernelPackage/rt2x00-lib/config + if PACKAGE_kmod-rt2x00-lib + + config PACKAGE_RT2X00_LIB_DEBUGFS + bool "Enable rt2x00 debugfs support" + depends on PACKAGE_MAC80211_DEBUGFS + help + Enable creation of debugfs files for the rt2x00 drivers. + These debugfs files support both reading and writing of the + most important register types of the rt2x00 hardware. + + config PACKAGE_RT2X00_DEBUG + bool "Enable rt2x00 debug output" + help + Enable debugging output for all rt2x00 modules + + endif +endef + +define KernelPackage/rt2x00-mmio +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-eeprom-93cx6 + HIDDEN:=1 + TITLE+= (MMIO) + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.ko +endef + +define KernelPackage/rt2x00-pci +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-mmio +kmod-rt2x00-lib + HIDDEN:=1 + TITLE+= (PCI) + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00pci.ko + AUTOLOAD:=$(call AutoProbe,rt2x00pci) +endef + +define KernelPackage/rt2x00-usb +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @USB_SUPPORT +kmod-rt2x00-lib +kmod-usb-core + HIDDEN:=1 + TITLE+= (USB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00usb.ko + AUTOLOAD:=$(call AutoProbe,rt2x00usb) +endef + +define KernelPackage/rt2800-lib +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-lib-crc-ccitt +@DRIVER_11N_SUPPORT + HIDDEN:=1 + TITLE+= (rt2800 LIB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800lib.ko +endef + +define KernelPackage/rt2400-pci +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci + TITLE+= (RT2400 PCI) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2400pci.ko + AUTOLOAD:=$(call AutoProbe,rt2400pci) +endef + +define KernelPackage/rt2500-pci +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci + TITLE+= (RT2500 PCI) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2500pci.ko + AUTOLOAD:=$(call AutoProbe,rt2500pci) +endef + +define KernelPackage/rt2500-usb +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb + TITLE+= (RT2500 USB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2500usb.ko + AUTOLOAD:=$(call AutoProbe,rt2500usb) +endef + +define KernelPackage/rt2800-mmio +$(call KernelPackage/rt2x00/Default) + TITLE += (RT28xx/RT3xxx MMIO) + DEPENDS += +kmod-rt2800-lib +kmod-rt2x00-mmio + HIDDEN:=1 + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800mmio.ko +endef + +define KernelPackage/rt2800-soc +$(call KernelPackage/rt2x00/Default) + DEPENDS += @(TARGET_ramips_rt288x||TARGET_ramips_rt305x||TARGET_ramips_rt3883||TARGET_ramips_mt7620) +kmod-rt2800-mmio +kmod-rt2800-lib + TITLE += (RT28xx/RT3xxx SoC) + FILES := \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00soc.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800soc.ko + AUTOLOAD:=$(call AutoProbe,rt2800soc) +endef + +define KernelPackage/rt2800-pci +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-rt2800-mmio +rt2800-pci-firmware + TITLE+= (RT2860 PCI) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800pci.ko + AUTOLOAD:=$(call AutoProbe,rt2800pci) +endef + +define KernelPackage/rt2800-usb +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-lib-crc-ccitt +rt2800-usb-firmware + TITLE+= (RT2870 USB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800usb.ko + AUTOLOAD:=$(call AutoProbe,rt2800usb) +endef + + +define KernelPackage/rt61-pci +$(call KernelPackage/rt2x00/Default) + DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +rt61-pci-firmware + TITLE+= (RT2x61 PCI) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt61pci.ko + AUTOLOAD:=$(call AutoProbe,rt61pci) +endef + +define KernelPackage/rt73-usb + $(call KernelPackage/rt2x00/Default) + DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +rt73-usb-firmware + TITLE+= (RT73 USB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt73usb.ko + AUTOLOAD:=$(call AutoProbe,rt73usb) +endef + + +define KernelPackage/rtl818x/Default + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek Drivers for RTL818x devices + URL:=https://wireless.wiki.kernel.org/en/users/drivers/rtl8187 + DEPENDS+= +kmod-eeprom-93cx6 +kmod-mac80211 +endef + +define KernelPackage/rtl8180 + $(call KernelPackage/rtl818x/Default) + DEPENDS+= @PCI_SUPPORT + TITLE+= (RTL8180 PCI) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl818x_pci.ko + AUTOLOAD:=$(call AutoProbe,rtl818x_pci) +endef + +define KernelPackage/rtl8187 +$(call KernelPackage/rtl818x/Default) + DEPENDS+= @USB_SUPPORT +kmod-usb-core + TITLE+= (RTL8187 USB) + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.ko + AUTOLOAD:=$(call AutoProbe,rtl8187) +endef + +define KernelPackage/rtlwifi/config + config PACKAGE_RTLWIFI_DEBUG + bool "Realtek wireless debugging" + depends on PACKAGE_kmod-rtlwifi + help + Say Y, if you want to debug realtek wireless drivers. + +endef + +define KernelPackage/rtlwifi + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek common driver part + DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +@DRIVER_11N_SUPPORT + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko + HIDDEN:=1 +endef + +define KernelPackage/rtlwifi-pci + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek common driver part (PCI support) + DEPENDS+= @PCI_SUPPORT +kmod-rtlwifi + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_pci.ko + AUTOLOAD:=$(call AutoProbe,rtl_pci) + HIDDEN:=1 +endef + +define KernelPackage/rtlwifi-btcoexist + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek BT coexist support + DEPENDS+= +kmod-rtlwifi + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/btcoexist/btcoexist.ko + AUTOLOAD:=$(call AutoProbe,btcoexist) + HIDDEN:=1 +endef + +define KernelPackage/rtlwifi-usb + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek common driver part (USB support) + DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-rtlwifi + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_usb.ko + AUTOLOAD:=$(call AutoProbe,rtl_usb) + HIDDEN:=1 +endef + +define KernelPackage/rtl8192c-common + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8192CE/RTL8192CU common support module + DEPENDS+= +kmod-rtlwifi + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192c/rtl8192c-common.ko + HIDDEN:=1 +endef + +define KernelPackage/rtl8192ce + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8192CE/RTL8188CE support + DEPENDS+= +kmod-rtlwifi-pci +kmod-rtl8192c-common +rtl8192ce-firmware + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rtl8192ce.ko + AUTOLOAD:=$(call AutoProbe,rtl8192ce) +endef + +define KernelPackage/rtl8192se + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8192SE/RTL8191SE support + DEPENDS+= +kmod-rtlwifi-pci +rtl8192se-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rtl8192se.ko + AUTOLOAD:=$(call AutoProbe,rtl8192se) +endef + +define KernelPackage/rtl8192de + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8192DE/RTL8188DE support + DEPENDS+= +kmod-rtlwifi-pci +rtl8192de-firmware + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rtl8192de.ko + AUTOLOAD:=$(call AutoProbe,rtl8192de) +endef + +define KernelPackage/rtl8192cu + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8192CU/RTL8188CU support + DEPENDS+= +kmod-rtlwifi-usb +kmod-rtl8192c-common +rtl8192cu-firmware + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rtl8192cu.ko + AUTOLOAD:=$(call AutoProbe,rtl8192cu) +endef + +define KernelPackage/rtl8821ae + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8821AE support + DEPENDS+= +kmod-rtlwifi-btcoexist +kmod-rtlwifi-pci +rtl8821ae-firmware + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rtl8821ae.ko + AUTOLOAD:=$(call AutoProbe,rtl8821ae) +endef + +define KernelPackage/rtl8xxxu + $(call KernelPackage/mac80211/Default) + TITLE:=alternative Realtek RTL8XXXU support + DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211 + FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.ko + AUTOLOAD:=$(call AutoProbe,rtl8xxxu) +endef + +define KernelPackage/rtl8xxxu/description + This is an alternative driver for various Realtek RTL8XXX + parts written to utilize the Linux mac80211 stack. + The driver is known to work with a number of RTL8723AU, + RL8188CU, RTL8188RU, RTL8191CU, and RTL8192CU devices + + This driver is under development and has a limited feature + set. In particular it does not yet support 40MHz channels + and power management. However it should have a smaller + memory footprint than the vendor drivers and benetifs + from the in kernel mac80211 stack. + + It can coexist with drivers from drivers/staging/rtl8723au, + drivers/staging/rtl8192u, and drivers/net/wireless/rtlwifi, + but you will need to control which module you wish to load. + + RTL8XXXU_UNTESTED is enabled + This option enables detection of Realtek 8723/8188/8191/8192 WiFi + USB devices which have not been tested directly by the driver + author or reported to be working by third parties. + + Please report your results! +endef + + +define KernelPackage/wlcore + $(call KernelPackage/mac80211/Default) + TITLE:=TI common driver part + DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT + FILES:= \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \ + $(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko + AUTOLOAD:=$(call AutoProbe,wlcore wlcore_sdio) +endef + +define KernelPackage/wlcore/description + This module contains some common parts needed by TI Wireless drivers. +endef + +define KernelPackage/wl12xx + $(call KernelPackage/mac80211/Default) + TITLE:=Driver for TI WL12xx + URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl12xx + DEPENDS+= +kmod-wlcore +wl12xx-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl12xx/wl12xx.ko + AUTOLOAD:=$(call AutoProbe,wl12xx) +endef + +define KernelPackage/wl12xx/description + Kernel modules for TI WL12xx +endef + +define KernelPackage/wl18xx + $(call KernelPackage/mac80211/Default) + TITLE:=Driver for TI WL18xx + URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl18xx + DEPENDS+= +kmod-wlcore +wl18xx-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl18xx/wl18xx.ko + AUTOLOAD:=$(call AutoProbe,wl18xx) +endef + +define KernelPackage/wl18xx/description + Kernel modules for TI WL18xx +endef + + +ZD1211FW_NAME:=zd1211-firmware +ZD1211FW_VERSION:=1.4 +define Download/zd1211rw + FILE:=$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2 + URL:=@SF/zd1211/ + HASH:=866308f6f59f7075f075d4959dff2ede47735c751251fecd1496df1ba4d338e1 +endef +$(eval $(call Download,zd1211rw)) + +define KernelPackage/zd1211rw + $(call KernelPackage/mac80211/Default) + TITLE:=Zydas ZD1211 support + DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211 + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/zydas/zd1211rw/zd1211rw.ko + AUTOLOAD:=$(call AutoProbe,zd1211rw) +endef + + + +config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m) + +config-y:= \ + WLAN \ + NL80211_TESTMODE \ + CFG80211_WEXT \ + CFG80211_CERTIFICATION_ONUS \ + MAC80211_RC_MINSTREL \ + MAC80211_RC_MINSTREL_HT \ + MAC80211_RC_MINSTREL_VHT \ + MAC80211_RC_DEFAULT_MINSTREL \ + WLAN_VENDOR_ADMTEK \ + WLAN_VENDOR_ATH \ + WLAN_VENDOR_ATMEL \ + WLAN_VENDOR_BROADCOM \ + WLAN_VENDOR_CISCO \ + WLAN_VENDOR_INTEL \ + WLAN_VENDOR_INTERSIL \ + WLAN_VENDOR_MARVELL \ + WLAN_VENDOR_MEDIATEK \ + WLAN_VENDOR_RALINK \ + WLAN_VENDOR_REALTEK \ + WLAN_VENDOR_RSI \ + WLAN_VENDOR_ST \ + WLAN_VENDOR_TI \ + WLAN_VENDOR_ZYDAS \ + +config-$(call config_package,cfg80211) += CFG80211 + +config-$(call config_package,mac80211) += MAC80211 +config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH +ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS + config-y += \ + CFG80211_DEBUGFS \ + MAC80211_DEBUGFS \ + ATH9K_DEBUGFS \ + ATH9K_HTC_DEBUGFS \ + ATH10K_DEBUGFS \ + CARL9170_DEBUGFS \ + ATH5K_DEBUG \ + ATH6KL_DEBUG +endif + +ifdef CONFIG_PACKAGE_MAC80211_TRACING + config-y += \ + ATH10K_TRACING \ + ATH6KL_TRACING \ + ATH_TRACEPOINTS \ + WIL6210_TRACING \ + ATH5K_TRACER \ + IWLWIFI_DEVICE_TRACING +endif + +config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_CRYPT_CCMP LIB80211_CRYPT_TKIP + +config-$(call config_package,airo) += AIRO + +config-$(call config_package,ath) += ATH_CARDS ATH_COMMON ATH_REG_DYNAMIC_USER_REG_HINTS +config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS +config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED +config-$(CONFIG_PACKAGE_ATH_SPECTRAL) += ATH9K_COMMON_SPECTRAL ATH10K_SPECTRAL + +config-$(call config_package,ath9k) += ATH9K +config-$(call config_package,ath9k-common) += ATH9K_COMMON +config-$(CONFIG_TARGET_ar71xx) += ATH9K_AHB +config-$(CONFIG_TARGET_ath79) += ATH9K_AHB +config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB +config-$(CONFIG_PCI) += ATH9K_PCI +config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD +config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM +config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 +config-$(CONFIG_ATH9K_UBNTHSR) += ATH9K_UBNTHSR +config-$(CONFIG_ATH10K_LEDS) += ATH10K_LEDS +config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL + +config-$(call config_package,ath9k-htc) += ATH9K_HTC +config-$(call config_package,ath10k) += ATH10K ATH10K_PCI + +config-$(call config_package,ath5k) += ATH5K +ifdef CONFIG_TARGET_ath25 + config-y += ATH5K_AHB +else + config-y += ATH5K_PCI +endif + +config-$(call config_package,ath6kl) += ATH6KL +config-$(call config_package,ath6kl-sdio) += ATH6KL_SDIO +config-$(call config_package,ath6kl-usb) += ATH6KL_USB + +config-$(call config_package,carl9170) += CARL9170 + +config-$(call config_package,b43) += B43 +config-$(CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB) += B43_BUSES_BCMA_AND_SSB +config-$(CONFIG_PACKAGE_B43_BUSES_BCMA) += B43_BUSES_BCMA +config-$(CONFIG_PACKAGE_B43_BUSES_SSB) += B43_BUSES_SSB +config-$(CONFIG_PACKAGE_B43_PHY_G) += B43_PHY_G +config-$(CONFIG_PACKAGE_B43_PHY_N) += B43_PHY_N +config-$(CONFIG_PACKAGE_B43_PHY_LP) += B43_PHY_LP +config-$(CONFIG_PACKAGE_B43_PHY_HT) += B43_PHY_HT +config-$(CONFIG_PACKAGE_B43_PIO) += B43_PIO +config-$(CONFIG_PACKAGE_B43_DEBUG) += B43_DEBUG + +config-$(call config_package,b43legacy) += B43LEGACY +config-y += B43LEGACY_DMA_MODE + +config-$(call config_package,brcmutil) += BRCMUTIL +config-$(call config_package,brcmsmac) += BRCMSMAC +config-$(call config_package,brcmfmac) += BRCMFMAC +config-$(CONFIG_BRCMFMAC_SDIO) += BRCMFMAC_SDIO +config-$(CONFIG_BRCMFMAC_USB) += BRCMFMAC_USB +config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE +config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG + +config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM +config-$(call config_package,mt7601u) += MT7601U +config-y += WL_MEDIATEK + +config-$(call config_package,rt2x00-lib) += RT2X00 RT2X00_LIB +config-$(call config_package,rt2x00-pci) += RT2X00_LIB_PCI +config-$(call config_package,rt2x00-mmio) += RT2X00_LIB_MMIO +config-$(call config_package,rt2x00-usb) += RT2X00_LIB_USB +config-$(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS) += RT2X00_LIB_DEBUGFS +config-$(CONFIG_PACKAGE_RT2X00_DEBUG) += RT2X00_DEBUG + +config-$(call config_package,rt2400-pci) += RT2400PCI +config-$(call config_package,rt2500-pci) += RT2500PCI +config-$(call config_package,rt2500-usb) += RT2500USB +config-$(call config_package,rt61-pci) += RT61PCI +config-$(call config_package,rt73-usb) += RT73USB + +config-$(call config_package,rt2800-lib) += RT2800_LIB + +config-$(call config_package,rt2800-soc) += RT2800SOC +config-$(call config_package,rt2800-pci) += RT2800PCI +config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290 + +config-$(call config_package,rt2800-usb) += RT2800USB +config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT3573 RT2800USB_RT53XX RT2800USB_RT55XX RT2800USB_UNKNOWN + +config-$(call config_package,iwl-legacy) += IWLEGACY +config-$(call config_package,iwl3945) += IWL3945 +config-$(call config_package,iwl4965) += IWL4965 +config-$(call config_package,iwlwifi) += IWLWIFI IWLDVM IWLMVM +config-$(CONFIG_PACKAGE_IWLWIFI_DEBUG)+= IWLWIFI_DEBUG +config-$(CONFIG_PACKAGE_IWLWIFI_DEBUGFS)+= IWLWIFI_DEBUGFS + +config-$(call config_package,libipw) += LIBIPW +config-$(call config_package,ipw2100) += IPW2100 +config-$(call config_package,ipw2200) += IPW2200 + +config-$(call config_package,p54-common) += P54_COMMON +config-$(call config_package,p54-pci) += P54_PCI +config-$(call config_package,p54-usb) += P54_USB +config-$(call config_package,p54-spi) += P54_SPI + +config-$(call config_package,hermes) += HERMES +config-$(call config_package,hermes-pci) += PCI_HERMES +config-$(call config_package,hermes-plx) += PLX_HERMES +config-$(call config_package,hermes-pcmcia) += PCMCIA_HERMES +config-y += HERMES_PRISM + +config-$(call config_package,adm8211) += ADM8211 +config-$(call config_package,libertas-sdio) += LIBERTAS LIBERTAS_SDIO +config-$(call config_package,libertas-usb) += LIBERTAS LIBERTAS_USB +config-$(call config_package,libertas-spi) += LIBERTAS LIBERTAS_SPI +config-$(call config_package,mwl8k) += MWL8K +config-$(call config_package,mwifiex-pcie) += MWIFIEX MWIFIEX_PCIE +config-$(call config_package,mwifiex-sdio) += MWIFIEX MWIFIEX_SDIO +config-$(call config_package,rtl8180) += RTL8180 +config-$(call config_package,rtl8187) += RTL8187 +config-$(call config_package,wlcore) += WLCORE WLCORE_SDIO +config-$(call config_package,wl12xx) += WL12XX +config-$(call config_package,wl18xx) += WL18XX +config-y += WL_TI WILINK_PLATFORM_DATA +config-$(call config_package,zd1211rw) += ZD1211RW +config-$(call config_package,rsi91x) += RSI_91X +config-$(call config_package,rsi91x-usb) += RSI_USB +config-$(call config_package,rsi91x-sdio) += RSI_SDIO + +config-$(call config_package,rtlwifi) += RTL_CARDS RTLWIFI +config-$(call config_package,rtlwifi-pci) += RTLWIFI_PCI +config-$(call config_package,rtlwifi-btcoexist) += RTLBTCOEXIST +config-$(call config_package,rtlwifi-usb) += RTLWIFI_USB +config-$(call config_package,rtl8192c-common) += RTL8192C_COMMON +config-$(call config_package,rtl8192ce) += RTL8192CE +config-$(call config_package,rtl8192se) += RTL8192SE +config-$(call config_package,rtl8192de) += RTL8192DE +config-$(call config_package,rtl8192cu) += RTL8192CU +config-$(call config_package,rtl8821ae) += RTL8821AE +config-$(CONFIG_PACKAGE_RTLWIFI_DEBUG) += RTLWIFI_DEBUG + +config-$(call config_package,rtl8xxxu) += RTL8XXXU +config-y += RTL8XXXU_UNTESTED + +config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS B43_LEDS B43LEGACY_LEDS + +MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS)" \ + KLIB_BUILD="$(LINUX_DIR)" \ + MODPROBE=true \ + KLIB=$(TARGET_MODULES_DIR) \ + KERNEL_SUBLEVEL=$(lastword $(subst ., ,$(KERNEL_PATCHVER))) \ + KBUILD_LDFLAGS_MODULE_PREREQ= + +define ConfigVars +$(subst $(space),,$(foreach opt,$(config-$(1)),CPTCFG_$(opt)=$(1) +)) +endef + +define mac80211_config +$(call ConfigVars,m)$(call ConfigVars,y) +endef +$(eval $(call shexport,mac80211_config)) + +define Build/Prepare + rm -rf $(PKG_BUILD_DIR) + mkdir -p $(PKG_BUILD_DIR) + $(PKG_UNPACK) + $(Build/Patch) + $(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2100_NAME)-$(IPW2100_VERSION).tgz + $(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION).tgz + $(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2 + rm -rf \ + $(PKG_BUILD_DIR)/include/linux/ssb \ + $(PKG_BUILD_DIR)/include/linux/bcma \ + $(PKG_BUILD_DIR)/include/net/bluetooth + + rm -f \ + $(PKG_BUILD_DIR)/include/linux/cordic.h \ + $(PKG_BUILD_DIR)/include/linux/crc8.h \ + $(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \ + $(PKG_BUILD_DIR)/include/linux/wl12xx.h \ + $(PKG_BUILD_DIR)/include/linux/spi/libertas_spi.h \ + $(PKG_BUILD_DIR)/include/net/ieee80211.h \ + $(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h + + echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version +endef + +ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),) + define Build/Compile/kmod + rm -rf $(PKG_BUILD_DIR)/modules + +$(MAKE) $(PKG_JOBS) $(MAKE_OPTS) modules + endef +endif + +#do not Build/Configure for EXTERNAL KERNEL +ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"") + ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"") + define Build/Configure + cmp $(PKG_BUILD_DIR)/include/linux/ath9k_platform.h $(LINUX_DIR)/include/linux/ath9k_platform.h + cmp $(PKG_BUILD_DIR)/include/linux/ath5k_platform.h $(LINUX_DIR)/include/linux/ath5k_platform.h + cmp $(PKG_BUILD_DIR)/include/linux/rt2x00_platform.h $(LINUX_DIR)/include/linux/rt2x00_platform.h + endef + endif +endif + +define Build/Compile + $(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config + $(MAKE) $(MAKE_OPTS) allnoconfig + $(call Build/Compile/kmod) +endef + +define Build/InstallDev + mkdir -p \ + $(1)/usr/include/mac80211 \ + $(1)/usr/include/mac80211-backport \ + $(1)/usr/include/mac80211/ath \ + $(1)/usr/include/net/mac80211 + $(CP) $(PKG_BUILD_DIR)/net/mac80211/*.h $(PKG_BUILD_DIR)/include/* $(1)/usr/include/mac80211/ + $(CP) $(PKG_BUILD_DIR)/backport-include/* $(1)/usr/include/mac80211-backport/ + $(CP) $(PKG_BUILD_DIR)/net/mac80211/rate.h $(1)/usr/include/net/mac80211/ + $(CP) $(PKG_BUILD_DIR)/drivers/net/wireless/ath/*.h $(1)/usr/include/mac80211/ath/ + rm -f $(1)/usr/include/mac80211-backport/linux/module.h +endef + + +define KernelPackage/b43/install + rm -rf $(1)/lib/firmware/ +ifeq ($(CONFIG_B43_OPENFIRMWARE),y) + tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)" +else + tar xjf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)" +endif + $(INSTALL_DIR) $(1)/lib/firmware/ +ifeq ($(CONFIG_B43_OPENFIRMWARE),y) + $(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/" + $(INSTALL_DIR) $(1)/lib/firmware/b43-open/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/ucode5.fw $(1)/lib/firmware/b43-open/ucode5.fw + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0bsinitvals5.fw $(1)/lib/firmware/b43-open/b0g0bsinitvals5.fw + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0initvals5.fw $(1)/lib/firmware/b43-open/b0g0initvals5.fw +else + b43-fwcutter -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT) +endif +ifneq ($(CONFIG_B43_FW_SQUASH),) + b43-fwsquash.py "$(CONFIG_B43_FW_SQUASH_PHYTYPES)" "$(CONFIG_B43_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43" +endif +endef + +define KernelPackage/brcmsmac/install + $(INSTALL_DIR) $(1)/lib/firmware/brcm +ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y) + tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)" + b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT) +endif +endef + +define KernelPackage/cfg80211/install + $(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless + $(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi + $(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless + $(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211 + $(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect +endef + +define KernelPackage/ipw2100/install + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/ipw2100-$(IPW2100_VERSION)*.fw $(1)/lib/firmware +endef + +define KernelPackage/ipw2200/install + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION)/ipw2200*.fw $(1)/lib/firmware +endef + +define KernelPackage/zd1211rw/install + $(INSTALL_DIR) $(1)/lib/firmware/zd1211 + $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ZD1211FW_NAME)/zd1211* $(1)/lib/firmware/zd1211 +endef + + +$(eval $(call KernelPackage,adm8211)) +$(eval $(call KernelPackage,airo)) +$(eval $(call KernelPackage,ath)) +$(eval $(call KernelPackage,ath10k)) +$(eval $(call KernelPackage,ath5k)) +$(eval $(call KernelPackage,ath6kl)) +$(eval $(call KernelPackage,ath6kl-sdio)) +$(eval $(call KernelPackage,ath6kl-usb)) +$(eval $(call KernelPackage,ath9k)) +$(eval $(call KernelPackage,ath9k-common)) +$(eval $(call KernelPackage,ath9k-htc)) +$(eval $(call KernelPackage,b43)) +$(eval $(call KernelPackage,b43legacy)) +$(eval $(call KernelPackage,brcmsmac)) +$(eval $(call KernelPackage,brcmfmac)) +$(eval $(call KernelPackage,brcmutil)) +$(eval $(call KernelPackage,carl9170)) +$(eval $(call KernelPackage,cfg80211)) +$(eval $(call KernelPackage,hermes)) +$(eval $(call KernelPackage,hermes-pci)) +$(eval $(call KernelPackage,hermes-plx)) +$(eval $(call KernelPackage,hermes-pcmcia)) +$(eval $(call KernelPackage,iwlwifi)) +$(eval $(call KernelPackage,iwl-legacy)) +$(eval $(call KernelPackage,iwl4965)) +$(eval $(call KernelPackage,iwl3945)) +$(eval $(call KernelPackage,lib80211)) +$(eval $(call KernelPackage,libertas-usb)) +$(eval $(call KernelPackage,libertas-sdio)) +$(eval $(call KernelPackage,libertas-spi)) +$(eval $(call KernelPackage,libipw)) +$(eval $(call KernelPackage,ipw2100)) +$(eval $(call KernelPackage,ipw2200)) +$(eval $(call KernelPackage,mac80211)) +$(eval $(call KernelPackage,mac80211-hwsim)) +$(eval $(call KernelPackage,mt7601u)) +$(eval $(call KernelPackage,mwl8k)) +$(eval $(call KernelPackage,mwifiex-pcie)) +$(eval $(call KernelPackage,mwifiex-sdio)) +$(eval $(call KernelPackage,p54-common)) +$(eval $(call KernelPackage,p54-pci)) +$(eval $(call KernelPackage,p54-usb)) +$(eval $(call KernelPackage,p54-spi)) +$(eval $(call KernelPackage,rsi91x)) +$(eval $(call KernelPackage,rsi91x-usb)) +$(eval $(call KernelPackage,rsi91x-sdio)) +$(eval $(call KernelPackage,rt2x00-lib)) +$(eval $(call KernelPackage,rt2x00-mmio)) +$(eval $(call KernelPackage,rt2x00-pci)) +$(eval $(call KernelPackage,rt2x00-usb)) +$(eval $(call KernelPackage,rt2800-lib)) +$(eval $(call KernelPackage,rt2400-pci)) +$(eval $(call KernelPackage,rt2500-pci)) +$(eval $(call KernelPackage,rt2500-usb)) +$(eval $(call KernelPackage,rt2800-mmio)) +$(eval $(call KernelPackage,rt2800-soc)) +$(eval $(call KernelPackage,rt2800-pci)) +$(eval $(call KernelPackage,rt2800-usb)) +$(eval $(call KernelPackage,rt61-pci)) +$(eval $(call KernelPackage,rt73-usb)) +$(eval $(call KernelPackage,rtl8180)) +$(eval $(call KernelPackage,rtl8187)) +$(eval $(call KernelPackage,rtlwifi)) +$(eval $(call KernelPackage,rtlwifi-pci)) +$(eval $(call KernelPackage,rtlwifi-btcoexist)) +$(eval $(call KernelPackage,rtlwifi-usb)) +$(eval $(call KernelPackage,rtl8192c-common)) +$(eval $(call KernelPackage,rtl8192ce)) +$(eval $(call KernelPackage,rtl8192se)) +$(eval $(call KernelPackage,rtl8192de)) +$(eval $(call KernelPackage,rtl8192cu)) +$(eval $(call KernelPackage,rtl8821ae)) +$(eval $(call KernelPackage,rtl8xxxu)) +$(eval $(call KernelPackage,wlcore)) +$(eval $(call KernelPackage,wl12xx)) +$(eval $(call KernelPackage,wl18xx)) +$(eval $(call KernelPackage,zd1211rw)) diff --git a/root/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/root/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh new file mode 100644 index 00000000..97788a14 --- /dev/null +++ b/root/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -0,0 +1,836 @@ +#!/bin/sh +. /lib/netifd/netifd-wireless.sh +. /lib/netifd/hostapd.sh + +init_wireless_driver "$@" + +MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links + mesh_max_retries mesh_ttl mesh_element_ttl mesh_hwmp_max_preq_retries + mesh_path_refresh_time mesh_min_discovery_timeout mesh_hwmp_active_path_timeout + mesh_hwmp_preq_min_interval mesh_hwmp_net_diameter_traversal_time mesh_hwmp_rootmode + mesh_hwmp_rann_interval mesh_gate_announcements mesh_sync_offset_max_neighor + mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval + mesh_hwmp_confirmation_interval mesh_awake_window mesh_plink_timeout" +MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding" +MP_CONFIG_STRING="mesh_power_mode" + +drv_mac80211_init_device_config() { + hostapd_common_add_device_config + + config_add_string path phy 'macaddr:macaddr' + config_add_string hwmode + config_add_int beacon_int chanbw frag rts + config_add_int rxantenna txantenna antenna_gain txpower distance + config_add_boolean noscan ht_coex + config_add_array ht_capab + config_add_array channels + config_add_boolean \ + rxldpc \ + short_gi_80 \ + short_gi_160 \ + tx_stbc_2by1 \ + su_beamformer \ + su_beamformee \ + mu_beamformer \ + mu_beamformee \ + vht_txop_ps \ + htc_vht \ + rx_antenna_pattern \ + tx_antenna_pattern + config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc + config_add_boolean \ + ldpc \ + greenfield \ + short_gi_20 \ + short_gi_40 \ + max_amsdu \ + dsss_cck_40 +} + +drv_mac80211_init_iface_config() { + hostapd_common_add_bss_config + + config_add_string 'macaddr:macaddr' ifname + + config_add_boolean wds powersave + config_add_int maxassoc + config_add_int max_listen_int + config_add_int dtim_period + config_add_int start_disabled + + # mesh + config_add_string mesh_id + config_add_int $MP_CONFIG_INT + config_add_boolean $MP_CONFIG_BOOL + config_add_string $MP_CONFIG_STRING +} + +mac80211_add_capabilities() { + local __var="$1"; shift + local __mask="$1"; shift + local __out= oifs + + oifs="$IFS" + IFS=: + for capab in "$@"; do + set -- $capab + + [ "$(($4))" -gt 0 ] || continue + [ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue + __out="$__out[$1]" + done + IFS="$oifs" + + export -n -- "$__var=$__out" +} + +mac80211_hostapd_setup_base() { + local phy="$1" + + json_select config + + [ "$auto_channel" -gt 0 ] && channel=acs_survey + [ "$auto_channel" -gt 0 ] && json_get_values channel_list channels + + json_get_vars noscan ht_coex + json_get_values ht_capab_list ht_capab + + ieee80211n=1 + ht_capab= + case "$htmode" in + VHT20|HT20) ;; + HT40*|VHT40|VHT80|VHT160) + case "$hwmode" in + a) + case "$(( ($channel / 4) % 2 ))" in + 1) ht_capab="[HT40+]";; + 0) ht_capab="[HT40-]";; + esac + ;; + *) + case "$htmode" in + HT40+) ht_capab="[HT40+]";; + HT40-) ht_capab="[HT40-]";; + *) + if [ "$channel" -lt 7 ]; then + ht_capab="[HT40+]" + else + ht_capab="[HT40-]" + fi + ;; + esac + ;; + esac + [ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]" + ;; + *) ieee80211n= ;; + esac + + [ -n "$ieee80211n" ] && { + append base_cfg "ieee80211n=1" "$N" + + set_default ht_coex 0 + append base_cfg "ht_coex=$ht_coex" "$N" + + json_get_vars \ + ldpc:1 \ + greenfield:0 \ + short_gi_20:1 \ + short_gi_40:0 \ + tx_stbc:1 \ + rx_stbc:3 \ + max_amsdu:1 \ + dsss_cck_40:1 + + ht_cap_mask=0 + for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do + ht_cap_mask="$(($ht_cap_mask | $cap))" + done + + cap_rx_stbc=$((($ht_cap_mask >> 8) & 3)) + [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc" + ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))" + + mac80211_add_capabilities ht_capab_flags $ht_cap_mask \ + LDPC:0x1::$ldpc \ + GF:0x10::$greenfield \ + SHORT-GI-20:0x20::$short_gi_20 \ + SHORT-GI-40:0x40::$short_gi_40 \ + TX-STBC:0x80::$tx_stbc \ + RX-STBC1:0x300:0x100:1 \ + RX-STBC12:0x300:0x200:1 \ + RX-STBC123:0x300:0x300:1 \ + MAX-AMSDU-7935:0x800::$max_amsdu \ + DSSS_CCK-40:0x1000::$dsss_cck_40 + + ht_capab="$ht_capab$ht_capab_flags" + [ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N" + } + + # 802.11ac + enable_ac=0 + idx="$channel" + case "$htmode" in + VHT20) enable_ac=1;; + VHT40) + case "$(( ($channel / 4) % 2 ))" in + 1) idx=$(($channel + 2));; + 0) idx=$(($channel - 2));; + esac + enable_ac=1 + append base_cfg "vht_oper_chwidth=0" "$N" + append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N" + ;; + VHT80) + case "$(( ($channel / 4) % 4 ))" in + 1) idx=$(($channel + 6));; + 2) idx=$(($channel + 2));; + 3) idx=$(($channel - 2));; + 0) idx=$(($channel - 6));; + esac + enable_ac=1 + append base_cfg "vht_oper_chwidth=1" "$N" + append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N" + ;; + VHT160) + case "$channel" in + 36|40|44|48|52|56|60|64) idx=50;; + 100|104|108|112|116|120|124|128) idx=114;; + esac + enable_ac=1 + append base_cfg "vht_oper_chwidth=2" "$N" + append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N" + ;; + esac + + if [ "$enable_ac" != "0" ]; then + json_get_vars \ + rxldpc:1 \ + short_gi_80:1 \ + short_gi_160:1 \ + tx_stbc_2by1:1 \ + su_beamformer:1 \ + su_beamformee:1 \ + mu_beamformer:1 \ + mu_beamformee:1 \ + vht_txop_ps:1 \ + htc_vht:1 \ + rx_antenna_pattern:1 \ + tx_antenna_pattern:1 \ + vht_max_a_mpdu_len_exp:7 \ + vht_max_mpdu:11454 \ + rx_stbc:4 \ + vht_link_adapt:3 \ + vht160:2 + + append base_cfg "ieee80211ac=1" "$N" + vht_cap=0 + for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do + vht_cap="$(($vht_cap | $cap))" + done + + cap_rx_stbc=$((($vht_cap >> 8) & 7)) + [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc" + vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))" + + mac80211_add_capabilities vht_capab $vht_cap \ + RXLDPC:0x10::$rxldpc \ + SHORT-GI-80:0x20::$short_gi_80 \ + SHORT-GI-160:0x40::$short_gi_160 \ + TX-STBC-2BY1:0x80::$tx_stbc_2by1 \ + SU-BEAMFORMER:0x800::$su_beamformer \ + SU-BEAMFORMEE:0x1000::$su_beamformee \ + MU-BEAMFORMER:0x80000::$mu_beamformer \ + MU-BEAMFORMEE:0x100000::$mu_beamformee \ + VHT-TXOP-PS:0x200000::$vht_txop_ps \ + HTC-VHT:0x400000::$htc_vht \ + RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \ + TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \ + RX-STBC-1:0x700:0x100:1 \ + RX-STBC-12:0x700:0x200:1 \ + RX-STBC-123:0x700:0x300:1 \ + RX-STBC-1234:0x700:0x400:1 \ + + # supported Channel widths + vht160_hw=0 + [ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \ + vht160_hw=1 + [ "$(($vht_cap & 12))" -eq 8 -a 2 -le "$vht160" ] && \ + vht160_hw=2 + [ "$vht160_hw" = 1 ] && vht_capab="$vht_capab[VHT160]" + [ "$vht160_hw" = 2 ] && vht_capab="$vht_capab[VHT160-80PLUS80]" + + # maximum MPDU length + vht_max_mpdu_hw=3895 + [ "$(($vht_cap & 3))" -ge 1 -a 7991 -le "$vht_max_mpdu" ] && \ + vht_max_mpdu_hw=7991 + [ "$(($vht_cap & 3))" -ge 2 -a 11454 -le "$vht_max_mpdu" ] && \ + vht_max_mpdu_hw=11454 + [ "$vht_max_mpdu_hw" != 3895 ] && \ + vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]" + + # maximum A-MPDU length exponent + vht_max_a_mpdu_len_exp_hw=0 + [ "$(($vht_cap & 58720256))" -ge 8388608 -a 1 -le "$vht_max_a_mpdu_len_exp" ] && \ + vht_max_a_mpdu_len_exp_hw=1 + [ "$(($vht_cap & 58720256))" -ge 16777216 -a 2 -le "$vht_max_a_mpdu_len_exp" ] && \ + vht_max_a_mpdu_len_exp_hw=2 + [ "$(($vht_cap & 58720256))" -ge 25165824 -a 3 -le "$vht_max_a_mpdu_len_exp" ] && \ + vht_max_a_mpdu_len_exp_hw=3 + [ "$(($vht_cap & 58720256))" -ge 33554432 -a 4 -le "$vht_max_a_mpdu_len_exp" ] && \ + vht_max_a_mpdu_len_exp_hw=4 + [ "$(($vht_cap & 58720256))" -ge 41943040 -a 5 -le "$vht_max_a_mpdu_len_exp" ] && \ + vht_max_a_mpdu_len_exp_hw=5 + [ "$(($vht_cap & 58720256))" -ge 50331648 -a 6 -le "$vht_max_a_mpdu_len_exp" ] && \ + vht_max_a_mpdu_len_exp_hw=6 + [ "$(($vht_cap & 58720256))" -ge 58720256 -a 7 -le "$vht_max_a_mpdu_len_exp" ] && \ + vht_max_a_mpdu_len_exp_hw=7 + vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]" + + # whether or not the STA supports link adaptation using VHT variant + vht_link_adapt_hw=0 + [ "$(($vht_cap & 201326592))" -ge 134217728 -a 2 -le "$vht_link_adapt" ] && \ + vht_link_adapt_hw=2 + [ "$(($vht_cap & 201326592))" -ge 201326592 -a 3 -le "$vht_link_adapt" ] && \ + vht_link_adapt_hw=3 + [ "$vht_link_adapt_hw" != 0 ] && \ + vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]" + + [ -n "$vht_capab" ] && append base_cfg "vht_capab=$vht_capab" "$N" + fi + + hostapd_prepare_device_config "$hostapd_conf_file" nl80211 + cat >> "$hostapd_conf_file" <> /var/run/hostapd-$phy.conf </dev/null); do + case "$(readlink -f /sys/class/ieee80211/$phy/device)" in + *$path) return 0;; + esac + done + } + [ -n "$macaddr" ] && { + for phy in $(ls /sys/class/ieee80211 2>/dev/null); do + grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0 + done + } + return 1 +} + +mac80211_check_ap() { + has_ap=1 +} + +mac80211_iw_interface_add() { + local phy="$1" + local ifname="$2" + local type="$3" + local wdsflag="$4" + local rc + + iw phy "$phy" interface add "$ifname" type "$type" $wdsflag + rc="$?" + + [ "$rc" = 233 ] && { + # Device might have just been deleted, give the kernel some time to finish cleaning it up + sleep 1 + + iw phy "$phy" interface add "$ifname" type "$type" $wdsflag + rc="$?" + } + + [ "$rc" = 233 -o "$rc" = 161 ] && { + # Device might not support virtual interfaces, so the interface never got deleted in the first place. + # Check if the interface already exists, and avoid failing in this case. + ip link show dev "$ifname" >/dev/null 2>/dev/null && rc=0 + } + + [ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED + return $rc +} + +mac80211_prepare_vif() { + json_select config + + json_get_vars ifname mode ssid wds powersave macaddr + + [ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}" + if_idx=$((${if_idx:-0} + 1)) + + set_default wds 0 + set_default powersave 0 + + json_select .. + + [ -n "$macaddr" ] || { + macaddr="$(mac80211_generate_mac $phy)" + macidx="$(($macidx + 1))" + } + + json_add_object data + json_add_string ifname "$ifname" + json_close_object + json_select config + + # It is far easier to delete and create the desired interface + case "$mode" in + adhoc) + mac80211_iw_interface_add "$phy" "$ifname" adhoc || return + ;; + ap) + # Hostapd will handle recreating the interface and + # subsequent virtual APs belonging to the same PHY + if [ -n "$hostapd_ctrl" ]; then + type=bss + else + type=interface + fi + + mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return + + [ -n "$hostapd_ctrl" ] || { + mac80211_iw_interface_add "$phy" "$ifname" __ap || return + hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}" + } + ;; + mesh) + mac80211_iw_interface_add "$phy" "$ifname" mp || return + ;; + monitor) + mac80211_iw_interface_add "$phy" "$ifname" monitor || return + ;; + sta) + local wdsflag= + staidx="$(($staidx + 1))" + [ "$wds" -gt 0 ] && wdsflag="4addr on" + mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return + [ "$powersave" -gt 0 ] && powersave="on" || powersave="off" + iw "$ifname" set power_save "$powersave" + ;; + esac + + case "$mode" in + monitor|mesh) + [ "$auto_channel" -gt 0 ] || iw dev "$ifname" set channel "$channel" $htmode + ;; + esac + + if [ "$mode" != "ap" ]; then + # ALL ap functionality will be passed to hostapd + # All interfaces must have unique mac addresses + # which can either be explicitly set in the device + # section, or automatically generated + ip link set dev "$ifname" address "$macaddr" + fi + + json_select .. +} + +mac80211_setup_supplicant() { + wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1 + if [ "$mode" = "sta" ]; then + wpa_supplicant_add_network "$ifname" + else + wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" + fi + wpa_supplicant_run "$ifname" ${hostapd_ctrl:+-H $hostapd_ctrl} +} + +mac80211_setup_supplicant_noctl() { + wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1 + wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan" + wpa_supplicant_run "$ifname" +} + +mac80211_setup_adhoc_htmode() { + case "$htmode" in + VHT20|HT20) ibss_htmode=HT20;; + HT40*|VHT40|VHT160) + case "$hwmode" in + a) + case "$(( ($channel / 4) % 2 ))" in + 1) ibss_htmode="HT40+" ;; + 0) ibss_htmode="HT40-";; + esac + ;; + *) + case "$htmode" in + HT40+) ibss_htmode="HT40+";; + HT40-) ibss_htmode="HT40-";; + *) + if [ "$channel" -lt 7 ]; then + ibss_htmode="HT40+" + else + ibss_htmode="HT40-" + fi + ;; + esac + ;; + esac + [ "$auto_channel" -gt 0 ] && ibss_htmode="HT40+" + ;; + VHT80) + ibss_htmode="80MHZ" + ;; + NONE|NOHT) + ibss_htmode="NOHT" + ;; + *) ibss_htmode="" ;; + esac + +} + +mac80211_setup_adhoc() { + json_get_vars bssid ssid key mcast_rate + + keyspec= + [ "$auth_type" = "wep" ] && { + set_default key 1 + case "$key" in + [1234]) + local idx + for idx in 1 2 3 4; do + json_get_var ikey "key$idx" + + [ -n "$ikey" ] && { + ikey="$(($idx - 1)):$(prepare_key_wep "$ikey")" + [ $idx -eq $key ] && ikey="d:$ikey" + append keyspec "$ikey" + } + done + ;; + *) + append keyspec "d:0:$(prepare_key_wep "$key")" + ;; + esac + } + + brstr= + for br in $basic_rate_list; do + wpa_supplicant_add_rate brstr "$br" + done + + mcval= + [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" + + iw dev "$ifname" ibss join "$ssid" $freq $ibss_htmode fixed-freq $bssid \ + beacon-interval $beacon_int \ + ${brstr:+basic-rates $brstr} \ + ${mcval:+mcast-rate $mcval} \ + ${keyspec:+keys $keyspec} +} + +mac80211_setup_mesh() { + json_get_vars ssid mesh_id mcast_rate + + mcval= + [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate" + [ -n "$mesh_id" ] && ssid="$mesh_id" + + case "$htmode" in + VHT20|HT20) mesh_htmode=HT20;; + HT40*|VHT40) + case "$hwmode" in + a) + case "$(( ($channel / 4) % 2 ))" in + 1) mesh_htmode="HT40+" ;; + 0) mesh_htmode="HT40-";; + esac + ;; + *) + case "$htmode" in + HT40+) mesh_htmode="HT40+";; + HT40-) mesh_htmode="HT40-";; + *) + if [ "$channel" -lt 7 ]; then + mesh_htmode="HT40+" + else + mesh_htmode="HT40-" + fi + ;; + esac + ;; + esac + ;; + VHT80) + mesh_htmode="80Mhz" + ;; + VHT160) + mesh_htmode="160Mhz" + ;; + *) mesh_htmode="NOHT" ;; + esac + iw dev "$ifname" mesh join "$ssid" freq $freq $mesh_htmode \ + ${mcval:+mcast-rate $mcval} \ + beacon-interval $beacon_int +} + +mac80211_setup_vif() { + local name="$1" + local failed + + json_select data + json_get_vars ifname + json_select .. + + json_select config + json_get_vars mode + json_get_var vif_txpower txpower + + ip link set dev "$ifname" up || { + wireless_setup_vif_failed IFUP_ERROR + json_select .. + return + } + + set_default vif_txpower "$txpower" + [ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00" + + case "$mode" in + mesh) + wireless_vif_parse_encryption + freq="$(get_freq "$phy" "$channel")" + if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then + mac80211_setup_supplicant || failed=1 + else + mac80211_setup_mesh + fi + for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do + json_get_var mp_val "$var" + [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val" + done + ;; + adhoc) + wireless_vif_parse_encryption + mac80211_setup_adhoc_htmode + if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then + freq="$(get_freq "$phy" "$channel")" + mac80211_setup_supplicant_noctl || failed=1 + else + mac80211_setup_adhoc + fi + ;; + sta) + mac80211_setup_supplicant || failed=1 + ;; + esac + + json_select .. + [ -n "$failed" ] || wireless_add_vif "$name" "$ifname" +} + +get_freq() { + local phy="$1" + local chan="$2" + iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}' +} + +chan_is_dfs() { + local phy="$1" + local chan="$2" + iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep -q "MHz.*radar detection" + return $! +} + +mac80211_interface_cleanup() { + local phy="$1" + + for wdev in $(list_phy_interfaces "$phy"); do + ip link set dev "$wdev" down 2>/dev/null + iw dev "$wdev" del + done +} + +drv_mac80211_cleanup() { + hostapd_common_cleanup +} + +drv_mac80211_setup() { + json_select config + json_get_vars \ + phy macaddr path \ + country chanbw distance \ + txpower antenna_gain \ + rxantenna txantenna \ + frag rts beacon_int:100 htmode + json_get_values basic_rate_list basic_rate + json_select .. + + find_phy || { + echo "Could not find PHY for device '$1'" + wireless_set_retry 0 + return 1 + } + + wireless_set_data phy="$phy" + mac80211_interface_cleanup "$phy" + + # convert channel to frequency + [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")" + + [ -n "$country" ] && { + iw reg get | grep -q "^country $country:" || { + iw reg set "$country" + sleep 1 + } + } + + hostapd_conf_file="/var/run/hostapd-$phy.conf" + + no_ap=1 + macidx=0 + staidx=0 + + [ -n "$chanbw" ] && { + for file in /sys/kernel/debug/ieee80211/$phy/ath9k/chanbw /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode; do + [ -f "$file" ] && echo "$chanbw" > "$file" + done + } + + set_default rxantenna all + set_default txantenna all + set_default distance 0 + set_default antenna_gain 0 + + iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1 + iw phy "$phy" set antenna_gain $antenna_gain + iw phy "$phy" set distance "$distance" + + [ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}" + [ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}" + + has_ap= + hostapd_ctrl= + for_each_interface "ap" mac80211_check_ap + + rm -f "$hostapd_conf_file" + [ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy" + + for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif + for_each_interface "ap" mac80211_prepare_vif + + [ -n "$hostapd_ctrl" ] && { + /usr/sbin/hostapd -s -P /var/run/wifi-$phy.pid -B "$hostapd_conf_file" + ret="$?" + wireless_add_process "$(cat /var/run/wifi-$phy.pid)" "/usr/sbin/hostapd" 1 + [ "$ret" != 0 ] && { + wireless_setup_failed HOSTAPD_START_FAILED + return + } + } + + for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif + + wireless_set_up +} + +list_phy_interfaces() { + local phy="$1" + if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then + ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null; + else + ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g' + fi +} + +drv_mac80211_teardown() { + wireless_process_kill_all + + json_select data + json_get_vars phy + json_select .. + + mac80211_interface_cleanup "$phy" +} + +add_driver mac80211 diff --git a/root/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/root/package/kernel/mac80211/files/lib/wifi/mac80211.sh new file mode 100644 index 00000000..314ef043 --- /dev/null +++ b/root/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -0,0 +1,132 @@ +#!/bin/sh +append DRIVERS "mac80211" + +lookup_phy() { + [ -n "$phy" ] && { + [ -d /sys/class/ieee80211/$phy ] && return + } + + local devpath + config_get devpath "$device" path + [ -n "$devpath" ] && { + for phy in $(ls /sys/class/ieee80211 2>/dev/null); do + case "$(readlink -f /sys/class/ieee80211/$phy/device)" in + *$devpath) return;; + esac + done + } + + local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')" + [ -n "$macaddr" ] && { + for _phy in /sys/class/ieee80211/*; do + [ -e "$_phy" ] || continue + + [ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue + phy="${_phy##*/}" + return + done + } + phy= + return +} + +find_mac80211_phy() { + local device="$1" + + config_get phy "$device" phy + lookup_phy + [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || { + echo "PHY for wifi device $1 not found" + return 1 + } + config_set "$device" phy "$phy" + + config_get macaddr "$device" macaddr + [ -z "$macaddr" ] && { + config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)" + } + + return 0 +} + +check_mac80211_device() { + config_get phy "$1" phy + [ -z "$phy" ] && { + find_mac80211_phy "$1" >/dev/null || return 0 + config_get phy "$1" phy + } + [ "$phy" = "$dev" ] && found=1 +} + +detect_mac80211() { + devidx=0 + config_load wireless + while :; do + config_get type "radio$devidx" type + [ -n "$type" ] || break + devidx=$(($devidx + 1)) + done + + for _dev in /sys/class/ieee80211/*; do + [ -e "$_dev" ] || continue + + dev="${_dev##*/}" + + found=0 + config_foreach check_mac80211_device wifi-device + [ "$found" -gt 0 ] && continue + + mode_band="g" + channel="11" + htmode="" + ht_capab="" + + iw phy "$dev" info | grep -q 'Capabilities:' && htmode=HT20 + + iw phy "$dev" info | grep -q '5180 MHz' && { + mode_band="a" + channel="36" + iw phy "$dev" info | grep -q 'VHT Capabilities' && htmode="VHT80" + } + + [ -n "$htmode" ] && ht_capab="set wireless.radio${devidx}.htmode=$htmode" + + if [ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${dev} ]; then + path="$(readlink -f /sys/class/ieee80211/${dev}/device)" + else + path="" + fi + macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)" + if [ -n "$path" ]; then + path="${path##/sys/devices/}" + case "$path" in + platform*/pci*) path="${path##platform/}";; + esac + dev_id="set wireless.radio${devidx}.path='$path'" + elif [ "$macaddr" != "00:00:00:00:00:00" ]; then + dev_id="set wireless.radio${devidx}.macaddr=$macaddr" + else + dev_id="set wireless.radio${devidx}.phy=$dev" + fi + + uci -q batch <<-EOF + set wireless.radio${devidx}=wifi-device + set wireless.radio${devidx}.type=mac80211 + set wireless.radio${devidx}.channel=${channel} + set wireless.radio${devidx}.hwmode=11${mode_band} + ${dev_id} + ${ht_capab} + set wireless.radio${devidx}.disabled=1 + + set wireless.default_radio${devidx}=wifi-iface + set wireless.default_radio${devidx}.device=radio${devidx} + set wireless.default_radio${devidx}.network=lan + set wireless.default_radio${devidx}.mode=ap + set wireless.default_radio${devidx}.ssid=OpenWrt + set wireless.default_radio${devidx}.encryption=none +EOF + uci -q commit wireless + + devidx=$(($devidx + 1)) + done +} diff --git a/root/package/kernel/mac80211/files/mac80211.hotplug b/root/package/kernel/mac80211/files/mac80211.hotplug new file mode 100644 index 00000000..b8655526 --- /dev/null +++ b/root/package/kernel/mac80211/files/mac80211.hotplug @@ -0,0 +1,5 @@ +#!/bin/sh + +[ "${ACTION}" = "add" ] && { + /sbin/wifi config +} diff --git a/root/package/kernel/mac80211/patches/000-fix_kconfig.patch b/root/package/kernel/mac80211/patches/000-fix_kconfig.patch new file mode 100644 index 00000000..3987aae4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/000-fix_kconfig.patch @@ -0,0 +1,14 @@ +--- a/kconf/Makefile ++++ b/kconf/Makefile +@@ -1,9 +1,9 @@ +-CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer ++CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS + + LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o + + conf: conf.o zconf.tab.o +-mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE ++mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) + mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC)) + mconf: CFLAGS += $(mconf_CFLAGS) + diff --git a/root/package/kernel/mac80211/patches/001-fix_build.patch b/root/package/kernel/mac80211/patches/001-fix_build.patch new file mode 100644 index 00000000..9e272e90 --- /dev/null +++ b/root/package/kernel/mac80211/patches/001-fix_build.patch @@ -0,0 +1,167 @@ +--- a/Makefile ++++ b/Makefile +@@ -5,7 +5,7 @@ + ifeq ($(KERNELRELEASE),) + + MAKEFLAGS += --no-print-directory +-SHELL := /bin/bash ++SHELL := /usr/bin/env bash + BACKPORT_DIR := $(shell pwd) + + KMODDIR ?= updates +@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/ + KERNEL_CONFIG := $(KLIB_BUILD)/.config + KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile + CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//') ++STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5) + + export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG + +@@ -36,7 +37,8 @@ mrproper: + @rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel + @rm -f backport-include/backport/autoconf.h + +-.DEFAULT: ++.SILENT: $(STAMP_KERNEL_CONFIG) ++$(STAMP_KERNEL_CONFIG): + @set -e ; test -f local-symbols || ( \ + echo "/--------------" ;\ + echo "| You shouldn't run make in the backports tree, but only in" ;\ +@@ -60,57 +62,61 @@ mrproper: + echo "| (that isn't currently running.)" ;\ + echo "\\--" ;\ + false) +- @set -e ; if [ "$$(cat .kernel_config_md5 2>/dev/null)" != "$(CONFIG_MD5)" ] ;\ +- then \ +- echo -n "Generating local configuration database from kernel ..." ;\ +- grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \ +- while read l ; do \ +- if [ "$${l:0:7}" != "CONFIG_" ] ; then \ +- continue ;\ +- fi ;\ +- l=$${l:7} ;\ +- n=$${l%%=*} ;\ +- v=$${l#*=} ;\ +- if [ "$$v" = "m" ] ; then \ +- echo config $$n ;\ +- echo ' tristate' ;\ +- elif [ "$$v" = "y" ] ; then \ +- echo config $$n ;\ +- echo ' bool' ;\ +- else \ +- continue ;\ +- fi ;\ +- echo " default $$v" ;\ +- echo "" ;\ +- done \ +- ) > Kconfig.kernel ;\ +- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \ +- sed 's/^\(\([3-4]\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\ +- test "$$kver" != "" || echo "Kernel version parse failed!" ;\ +- test "$$kver" != "" ;\ +- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ +- kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\ +- kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')" ;\ +- print=0 ;\ +- for v in $$kvers ; do \ +- if [ "$$print" = "1" ] ; then \ +- echo config KERNEL_$$(echo $$v | tr . _) ;\ +- echo " def_bool y" ;\ +- fi ;\ +- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\ +- done > Kconfig.versions ;\ +- # RHEL as well, sadly we need to grep for it ;\ +- RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \ +- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ +- RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \ +- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ +- for v in $$(seq 0 $$RHEL_MINOR) ; do \ +- echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\ +- echo " def_bool y" ;\ +- done >> Kconfig.versions ;\ +- echo " done." ;\ +- fi ;\ +- echo "$(CONFIG_MD5)" > .kernel_config_md5 ++ @rm -f .kernel_config_md5_* ++ @touch $@ ++ ++Kconfig.kernel: $(STAMP_KERNEL_CONFIG) local-symbols ++ @printf "Generating local configuration database from kernel ..." ++ @grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \ ++ while read l ; do \ ++ if [ "$${l:0:7}" != "CONFIG_" ] ; then \ ++ continue ;\ ++ fi ;\ ++ l=$${l:7} ;\ ++ n=$${l%%=*} ;\ ++ v=$${l#*=} ;\ ++ if [ "$$v" = "m" ] ; then \ ++ echo config $$n ;\ ++ echo ' tristate' ;\ ++ elif [ "$$v" = "y" ] ; then \ ++ echo config $$n ;\ ++ echo ' bool' ;\ ++ else \ ++ continue ;\ ++ fi ;\ ++ echo " default $$v" ;\ ++ echo "" ;\ ++ done \ ++ ) > $@ ++ @echo " done." ++ ++Kconfig.versions: Kconfig.kernel ++ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) kernelversion | \ ++ sed 's/^\(\([3-4]\|2\.6\)\.[0-9]\+\).*/\1/;t;d') ;\ ++ test "$$kver" != "" || echo "Kernel version parse failed!" ;\ ++ test "$$kver" != "" ;\ ++ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\ ++ kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\ ++ kvers="$$kvers $$(seq 0 99 | sed 's/^/4./')" ;\ ++ print=0 ;\ ++ for v in $$kvers ; do \ ++ if [ "$$print" = "1" ] ; then \ ++ echo config KERNEL_$$(echo $$v | tr . _) ;\ ++ echo " def_bool y" ;\ ++ fi ;\ ++ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\ ++ done > $@ ++ @RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \ ++ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ ++ RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \ ++ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\ ++ for v in $$(seq 0 $$RHEL_MINOR) ; do \ ++ echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\ ++ echo " def_bool y" ;\ ++ done >> $@ ++ ++.DEFAULT: ++ @$(MAKE) Kconfig.versions + @$(MAKE) -f Makefile.real "$@" + + .PHONY: defconfig-help +--- a/Makefile.real ++++ b/Makefile.real +@@ -59,7 +59,7 @@ defconfig-%:: + + backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel + @$(MAKE) oldconfig +- @echo -n "Building backport-include/backport/autoconf.h ..." ++ @printf "Building backport-include/backport/autoconf.h ..." + @grep -f local-symbols .config | ( \ + echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\ + echo "#define COMPAT_AUTOCONF_INCLUDED" ;\ +@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c + esac ;\ + done ;\ + echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\ +- ) > backport-include/backport/autoconf.h ++ ) > $@.new ++ @if cmp -s $@ $@.new; then \ ++ rm -f $@.new; \ ++ else \ ++ mv $@.new $@; \ ++ fi + @echo " done." + + .PHONY: modules diff --git a/root/package/kernel/mac80211/patches/002-change_allconfig.patch b/root/package/kernel/mac80211/patches/002-change_allconfig.patch new file mode 100644 index 00000000..a071ae63 --- /dev/null +++ b/root/package/kernel/mac80211/patches/002-change_allconfig.patch @@ -0,0 +1,64 @@ +--- a/kconf/conf.c ++++ b/kconf/conf.c +@@ -594,40 +594,12 @@ int main(int ac, char **av) + case oldconfig: + case listnewconfig: + case olddefconfig: +- conf_read(NULL); +- break; + case allnoconfig: + case allyesconfig: + case allmodconfig: + case alldefconfig: + case randconfig: +- name = getenv("KCONFIG_ALLCONFIG"); +- if (!name) +- break; +- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { +- if (conf_read_simple(name, S_DEF_USER)) { +- fprintf(stderr, +- _("*** Can't read seed configuration \"%s\"!\n"), +- name); +- exit(1); +- } +- break; +- } +- switch (input_mode) { +- case allnoconfig: name = "allno.config"; break; +- case allyesconfig: name = "allyes.config"; break; +- case allmodconfig: name = "allmod.config"; break; +- case alldefconfig: name = "alldef.config"; break; +- case randconfig: name = "allrandom.config"; break; +- default: break; +- } +- if (conf_read_simple(name, S_DEF_USER) && +- conf_read_simple("all.config", S_DEF_USER)) { +- fprintf(stderr, +- _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), +- name); +- exit(1); +- } ++ conf_read(NULL); + break; + default: + break; +--- a/kconf/confdata.c ++++ b/kconf/confdata.c +@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_ + } + bool has_changed = false; + ++ sym_clear_all_valid(); ++ + for_all_symbols(i, sym) { + if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID)) + continue; +@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_ + + } + +- sym_clear_all_valid(); +- + /* + * We have different type of choice blocks. + * If curr.tri equals to mod then we can select several diff --git a/root/package/kernel/mac80211/patches/003-remove_bogus_modparams.patch b/root/package/kernel/mac80211/patches/003-remove_bogus_modparams.patch new file mode 100644 index 00000000..8fa465a7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/003-remove_bogus_modparams.patch @@ -0,0 +1,34 @@ +--- a/compat/main.c ++++ b/compat/main.c +@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL"); + #error "You need a CPTCFG_VERSION" + #endif + +-static char *backported_kernel_name = CPTCFG_KERNEL_NAME; +- +-module_param(backported_kernel_name, charp, 0400); +-MODULE_PARM_DESC(backported_kernel_name, +- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")"); +- +-#ifdef BACKPORTS_GIT_TRACKED +-static char *backports_tracker_id = BACKPORTS_GIT_TRACKED; +-module_param(backports_tracker_id, charp, 0400); +-MODULE_PARM_DESC(backports_tracker_id, +- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")"); +-#else +-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION; +-static char *backports_version = CPTCFG_VERSION; +- +-module_param(backported_kernel_version, charp, 0400); +-MODULE_PARM_DESC(backported_kernel_version, +- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")"); +- +-module_param(backports_version, charp, 0400); +-MODULE_PARM_DESC(backports_version, +- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")"); +- +-#endif +- + void backport_dependency_symbol(void) + { + } diff --git a/root/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch b/root/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch new file mode 100644 index 00000000..2c9572ec --- /dev/null +++ b/root/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch @@ -0,0 +1,28 @@ +--- a/backport-include/linux/kconfig.h ++++ b/backport-include/linux/kconfig.h +@@ -5,6 +5,8 @@ + #include_next + #endif + ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) ++ + #ifndef __ARG_PLACEHOLDER_1 + #define __ARG_PLACEHOLDER_1 0, + #define config_enabled(cfg) _config_enabled(cfg) +@@ -16,6 +18,7 @@ + * 3.1 - 3.3 had a broken version of this, so undef + * (they didn't have __ARG_PLACEHOLDER_1) + */ ++ + #undef IS_ENABLED + #define IS_ENABLED(option) \ + (config_enabled(option) || config_enabled(option##_MODULE)) +@@ -31,6 +34,8 @@ + #undef IS_BUILTIN + #define IS_BUILTIN(option) config_enabled(option) + ++#endif ++ + #ifndef IS_REACHABLE + /* + * IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled diff --git a/root/package/kernel/mac80211/patches/005-revert-devcoredump.patch b/root/package/kernel/mac80211/patches/005-revert-devcoredump.patch new file mode 100644 index 00000000..d485d955 --- /dev/null +++ b/root/package/kernel/mac80211/patches/005-revert-devcoredump.patch @@ -0,0 +1,11 @@ +--- a/compat/Makefile ++++ b/compat/Makefile +@@ -70,8 +70,6 @@ quiet_cmd_build_OID_registry = GEN $ + cmd_build_OID_registry = perl $(src)/build_OID_registry $< $@ + compat-$(CPTCFG_BPAUTO_ASN1_DECODER) += lib-asn1_decoder.o + compat-$(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) += lib-oid_registry.o +-skcipher-objs += crypto-skcipher.o +-obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o + compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o + cordic-objs += lib-cordic.o + obj-$(CPTCFG_BPAUTO_BUILD_CORDIC) += cordic.o diff --git a/root/package/kernel/mac80211/patches/006-fix-genl-multicast.patch b/root/package/kernel/mac80211/patches/006-fix-genl-multicast.patch new file mode 100644 index 00000000..42fd3e82 --- /dev/null +++ b/root/package/kernel/mac80211/patches/006-fix-genl-multicast.patch @@ -0,0 +1,10 @@ +--- a/compat/backport-4.12.c ++++ b/compat/backport-4.12.c +@@ -225,6 +225,7 @@ int bp_extack_genl_register_family(struc + + /* copy this since the family might access it directly */ + family->attrbuf = copy->family.attrbuf; ++ family->mcgrp_offset = copy->family.mcgrp_offset; + + mutex_lock(&copies_mutex); + list_add_tail(©->list, &copies_list); diff --git a/root/package/kernel/mac80211/patches/007-fix-linux-verification-h.patch b/root/package/kernel/mac80211/patches/007-fix-linux-verification-h.patch new file mode 100644 index 00000000..4011f1d3 --- /dev/null +++ b/root/package/kernel/mac80211/patches/007-fix-linux-verification-h.patch @@ -0,0 +1,11 @@ +--- a/backport-include/linux/verification.h ++++ b/backport-include/linux/verification.h +@@ -1,7 +1,7 @@ + #ifndef __BP_VERIFICATION_H + #define __BP_VERIFICATION_H + #include +-#ifndef CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION ++#if LINUX_VERSION_IS_GEQ(4,7,0) && !defined(CPTCFG_BPAUTO_BUILD_SYSTEM_DATA_VERIFICATION) + #include_next + #else + #include diff --git a/root/package/kernel/mac80211/patches/008-fix-genl-family-id.patch b/root/package/kernel/mac80211/patches/008-fix-genl-family-id.patch new file mode 100644 index 00000000..ee8fa6c2 --- /dev/null +++ b/root/package/kernel/mac80211/patches/008-fix-genl-family-id.patch @@ -0,0 +1,10 @@ +--- a/compat/backport-4.12.c ++++ b/compat/backport-4.12.c +@@ -224,6 +224,7 @@ int bp_extack_genl_register_family(struc + } + + /* copy this since the family might access it directly */ ++ family->id = copy->family.id; + family->attrbuf = copy->family.attrbuf; + family->mcgrp_offset = copy->family.mcgrp_offset; + diff --git a/root/package/kernel/mac80211/patches/010-disable_rfkill.patch b/root/package/kernel/mac80211/patches/010-disable_rfkill.patch new file mode 100644 index 00000000..d5253063 --- /dev/null +++ b/root/package/kernel/mac80211/patches/010-disable_rfkill.patch @@ -0,0 +1,15 @@ +--- a/backport-include/linux/rfkill.h ++++ b/backport-include/linux/rfkill.h +@@ -2,6 +2,12 @@ + #define __COMPAT_RFKILL_H + #include + ++#undef CONFIG_RFKILL ++#undef CONFIG_RFKILL_FULL ++#undef CONFIG_RFKILL_LEDS ++#undef CONFIG_RFKILL_MODULE ++#undef CONFIG_RFKILL_FULL_MODULE ++ + #if LINUX_VERSION_IS_GEQ(3,10,0) + #include_next + #else diff --git a/root/package/kernel/mac80211/patches/012-kernel_build_check.patch b/root/package/kernel/mac80211/patches/012-kernel_build_check.patch new file mode 100644 index 00000000..d225ba18 --- /dev/null +++ b/root/package/kernel/mac80211/patches/012-kernel_build_check.patch @@ -0,0 +1,11 @@ +--- a/Makefile ++++ b/Makefile +@@ -2,7 +2,7 @@ + # Makefile for the output source package + # + +-ifeq ($(KERNELRELEASE),) ++ifeq ($(KERNELVERSION),) + + MAKEFLAGS += --no-print-directory + SHELL := /usr/bin/env bash diff --git a/root/package/kernel/mac80211/patches/015-ipw200-mtu.patch b/root/package/kernel/mac80211/patches/015-ipw200-mtu.patch new file mode 100644 index 00000000..8d273a09 --- /dev/null +++ b/root/package/kernel/mac80211/patches/015-ipw200-mtu.patch @@ -0,0 +1,34 @@ +--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c +@@ -11506,6 +11506,15 @@ static const struct attribute_group ipw_ + .attrs = ipw_sysfs_entries, + }; + ++#if LINUX_VERSION_IS_LESS(4,10,0) ++static int __change_mtu(struct net_device *ndev, int new_mtu){ ++ if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN) ++ return -EINVAL; ++ ndev->mtu = new_mtu; ++ return 0; ++} ++#endif ++ + #ifdef CPTCFG_IPW2200_PROMISCUOUS + static int ipw_prom_open(struct net_device *dev) + { +@@ -11554,15 +11563,6 @@ static netdev_tx_t ipw_prom_hard_start_x + return NETDEV_TX_OK; + } + +-#if LINUX_VERSION_IS_LESS(4,10,0) +-static int __change_mtu(struct net_device *ndev, int new_mtu){ +- if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN) +- return -EINVAL; +- ndev->mtu = new_mtu; +- return 0; +-} +-#endif +- + static const struct net_device_ops ipw_prom_netdev_ops = { + #if LINUX_VERSION_IS_LESS(4,10,0) + .ndo_change_mtu = __change_mtu, diff --git a/root/package/kernel/mac80211/patches/030-rt2x00_options.patch b/root/package/kernel/mac80211/patches/030-rt2x00_options.patch new file mode 100644 index 00000000..9dd34815 --- /dev/null +++ b/root/package/kernel/mac80211/patches/030-rt2x00_options.patch @@ -0,0 +1,47 @@ +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -225,36 +225,37 @@ config RT2800SOC + + + config RT2800_LIB +- tristate ++ tristate "RT2800 USB/PCI support" + depends on m + + config RT2800_LIB_MMIO +- tristate ++ tristate "RT2800 MMIO support" + depends on m + select RT2X00_LIB_MMIO + select RT2800_LIB + + config RT2X00_LIB_MMIO +- tristate ++ tristate "RT2x00 MMIO support" + depends on m + + config RT2X00_LIB_PCI +- tristate ++ tristate "RT2x00 PCI support" + depends on m + select RT2X00_LIB + + config RT2X00_LIB_SOC +- tristate ++ tristate "RT2x00 SoC support" ++ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 + depends on m + select RT2X00_LIB + + config RT2X00_LIB_USB +- tristate ++ tristate "RT2x00 USB support" + depends on m + select RT2X00_LIB + + config RT2X00_LIB +- tristate ++ tristate "RT2x00 support" + depends on m + + config RT2X00_LIB_FIRMWARE diff --git a/root/package/kernel/mac80211/patches/040-brcmutil_option.patch b/root/package/kernel/mac80211/patches/040-brcmutil_option.patch new file mode 100644 index 00000000..167332d9 --- /dev/null +++ b/root/package/kernel/mac80211/patches/040-brcmutil_option.patch @@ -0,0 +1,9 @@ +--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig ++++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig +@@ -1,5 +1,5 @@ + config BRCMUTIL +- tristate ++ tristate "Broadcom 802.11 driver utility functions" + depends on m + + config BRCMSMAC diff --git a/root/package/kernel/mac80211/patches/050-lib80211_option.patch b/root/package/kernel/mac80211/patches/050-lib80211_option.patch new file mode 100644 index 00000000..28a0d905 --- /dev/null +++ b/root/package/kernel/mac80211/patches/050-lib80211_option.patch @@ -0,0 +1,30 @@ +--- a/net/wireless/Kconfig ++++ b/net/wireless/Kconfig +@@ -181,7 +181,7 @@ config CFG80211_WEXT_EXPORT + wext compatibility symbols to be exported. + + config LIB80211 +- tristate ++ tristate "lib80211" + depends on m + default n + help +@@ -191,15 +191,15 @@ config LIB80211 + Drivers should select this themselves if needed. + + config LIB80211_CRYPT_WEP +- tristate ++ tristate "lib80211 WEP support" + depends on m + + config LIB80211_CRYPT_CCMP +- tristate ++ tristate "lib80211 CCMP support" + depends on m + + config LIB80211_CRYPT_TKIP +- tristate ++ tristate "lib80211 TKIP support" + depends on m + + config LIB80211_DEBUG diff --git a/root/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch b/root/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch new file mode 100644 index 00000000..d897b2b4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch @@ -0,0 +1,132 @@ +--- a/local-symbols ++++ b/local-symbols +@@ -388,45 +388,6 @@ USB_IPHETH= + USB_SIERRA_NET= + USB_VL600= + USB_NET_CH9200= +-SSB_POSSIBLE= +-SSB= +-SSB_SPROM= +-SSB_BLOCKIO= +-SSB_PCIHOST_POSSIBLE= +-SSB_PCIHOST= +-SSB_B43_PCI_BRIDGE= +-SSB_PCMCIAHOST_POSSIBLE= +-SSB_PCMCIAHOST= +-SSB_SDIOHOST_POSSIBLE= +-SSB_SDIOHOST= +-SSB_HOST_SOC= +-SSB_SILENT= +-SSB_DEBUG= +-SSB_SERIAL= +-SSB_DRIVER_PCICORE_POSSIBLE= +-SSB_DRIVER_PCICORE= +-SSB_PCICORE_HOSTMODE= +-SSB_DRIVER_MIPS= +-SSB_SFLASH= +-SSB_EMBEDDED= +-SSB_DRIVER_EXTIF= +-SSB_DRIVER_GIGE= +-SSB_DRIVER_GPIO= +-BCMA_POSSIBLE= +-BCMA= +-BCMA_BLOCKIO= +-BCMA_HOST_PCI_POSSIBLE= +-BCMA_HOST_PCI= +-BCMA_HOST_SOC= +-BCMA_DRIVER_PCI= +-BCMA_DRIVER_PCI_HOSTMODE= +-BCMA_DRIVER_MIPS= +-BCMA_PFLASH= +-BCMA_SFLASH= +-BCMA_NFLASH= +-BCMA_DRIVER_GMAC_CMN= +-BCMA_DRIVER_GPIO= +-BCMA_DEBUG= + NFC= + NFC_DIGITAL= + NFC_NCI= +--- a/drivers/net/wireless/broadcom/b43/main.c ++++ b/drivers/net/wireless/broadcom/b43/main.c +@@ -2876,7 +2876,7 @@ static struct ssb_device *b43_ssb_gpio_d + { + struct ssb_bus *bus = dev->dev->sdev->bus; + +-#ifdef CPTCFG_SSB_DRIVER_PCICORE ++#ifdef CONFIG_SSB_DRIVER_PCICORE + return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); + #else + return bus->chipco.dev; +@@ -4893,7 +4893,7 @@ static int b43_wireless_core_init(struct + } + if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) + hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ +-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE) ++#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE) + if (dev->dev->bus_type == B43_BUS_SSB && + dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && + dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) +--- a/drivers/net/wireless/broadcom/b43legacy/main.c ++++ b/drivers/net/wireless/broadcom/b43legacy/main.c +@@ -1937,7 +1937,7 @@ static int b43legacy_gpio_init(struct b4 + if (dev->dev->id.revision >= 2) + mask |= 0x0010; /* FIXME: This is redundant. */ + +-#ifdef CPTCFG_SSB_DRIVER_PCICORE ++#ifdef CONFIG_SSB_DRIVER_PCICORE + pcidev = bus->pcicore.dev; + #endif + gpiodev = bus->chipco.dev ? : pcidev; +@@ -1956,7 +1956,7 @@ static void b43legacy_gpio_cleanup(struc + struct ssb_bus *bus = dev->dev->bus; + struct ssb_device *gpiodev, *pcidev = NULL; + +-#ifdef CPTCFG_SSB_DRIVER_PCICORE ++#ifdef CONFIG_SSB_DRIVER_PCICORE + pcidev = bus->pcicore.dev; + #endif + gpiodev = bus->chipco.dev ? : pcidev; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile +@@ -42,6 +42,6 @@ brcmsmac-y := \ + brcms_trace_events.o \ + debug.o + +-brcmsmac-$(CPTCFG_BCMA_DRIVER_GPIO) += led.o ++brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o + + obj-$(CPTCFG_BRCMSMAC) += brcmsmac.o +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h +@@ -22,7 +22,7 @@ struct brcms_led { + bool active_low; + }; + +-#ifdef CPTCFG_BCMA_DRIVER_GPIO ++#ifdef CONFIG_BCMA_DRIVER_GPIO + void brcms_led_unregister(struct brcms_info *wl); + int brcms_led_register(struct brcms_info *wl); + #else +--- a/Kconfig.sources ++++ b/Kconfig.sources +@@ -9,9 +9,6 @@ source "$BACKPORT_DIR/drivers/net/wirele + #source "$BACKPORT_DIR/drivers/net/ethernet/Kconfig" + source "$BACKPORT_DIR/drivers/net/usb/Kconfig" + +-source "$BACKPORT_DIR/drivers/ssb/Kconfig" +-source "$BACKPORT_DIR/drivers/bcma/Kconfig" +- + source "$BACKPORT_DIR/net/nfc/Kconfig" + + #source "$BACKPORT_DIR/drivers/media/Kconfig" +--- a/Makefile.kernel ++++ b/Makefile.kernel +@@ -42,8 +42,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/ + obj-$(CPTCFG_WLAN) += drivers/net/wireless/ + #obj-$(CPTCFG_BT) += net/bluetooth/ + #obj-$(CPTCFG_BT) += drivers/bluetooth/ +-obj-$(CPTCFG_SSB) += drivers/ssb/ +-obj-$(CPTCFG_BCMA) += drivers/bcma/ + #obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/ + obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/ + obj-$(CPTCFG_NFC) += net/nfc/ diff --git a/root/package/kernel/mac80211/patches/070-ath_common_config.patch b/root/package/kernel/mac80211/patches/070-ath_common_config.patch new file mode 100644 index 00000000..41774fe5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/070-ath_common_config.patch @@ -0,0 +1,9 @@ +--- a/drivers/net/wireless/ath/Kconfig ++++ b/drivers/net/wireless/ath/Kconfig +@@ -1,5 +1,5 @@ + config ATH_COMMON +- tristate ++ tristate "ath.ko" + depends on m + + config WLAN_VENDOR_ATH diff --git a/root/package/kernel/mac80211/patches/080-ath10k_thermal_config.patch b/root/package/kernel/mac80211/patches/080-ath10k_thermal_config.patch new file mode 100644 index 00000000..adcd788b --- /dev/null +++ b/root/package/kernel/mac80211/patches/080-ath10k_thermal_config.patch @@ -0,0 +1,47 @@ +--- a/drivers/net/wireless/ath/ath10k/Kconfig ++++ b/drivers/net/wireless/ath/ath10k/Kconfig +@@ -65,6 +65,12 @@ config ATH10K_TRACING + ---help--- + Select this to ath10k use tracing infrastructure. + ++config ATH10K_THERMAL ++ bool "Atheros ath10k thermal monitoring support" ++ depends on THERMAL ++ ---help--- ++ Select this to ath10k use hwmon for thermal measurement. ++ + config ATH10K_DFS_CERTIFIED + bool "Atheros DFS support for certified platforms" + depends on ATH10K && CFG80211_CERTIFICATION_ONUS +--- a/drivers/net/wireless/ath/ath10k/Makefile ++++ b/drivers/net/wireless/ath/ath10k/Makefile +@@ -17,7 +17,7 @@ ath10k_core-y += mac.o \ + ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o + ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o + ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o +-ath10k_core-$(CONFIG_THERMAL) += thermal.o ++ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o + ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o + ath10k_core-$(CONFIG_PM) += wow.o + +--- a/drivers/net/wireless/ath/ath10k/thermal.h ++++ b/drivers/net/wireless/ath/ath10k/thermal.h +@@ -36,7 +36,7 @@ struct ath10k_thermal { + int temperature; + }; + +-#if IS_REACHABLE(CONFIG_THERMAL) ++#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL) + int ath10k_thermal_register(struct ath10k *ar); + void ath10k_thermal_unregister(struct ath10k *ar); + void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); +--- a/local-symbols ++++ b/local-symbols +@@ -139,6 +139,7 @@ ATH10K_SDIO= + ATH10K_USB= + ATH10K_DEBUG= + ATH10K_DEBUGFS= ++ATH10K_THERMAL= + ATH10K_TRACING= + ATH10K_DFS_CERTIFIED= + WCN36XX= diff --git a/root/package/kernel/mac80211/patches/081-ath10k-calibration-variant.patch b/root/package/kernel/mac80211/patches/081-ath10k-calibration-variant.patch new file mode 100644 index 00000000..27240278 --- /dev/null +++ b/root/package/kernel/mac80211/patches/081-ath10k-calibration-variant.patch @@ -0,0 +1,111 @@ +From d06f26c5c8a41f246a9c40862a77a55725cedbd3 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Fri, 8 Dec 2017 11:37:42 +0100 +Subject: ath10k: search DT for qcom,ath10k-calibration-variant + +Board Data File (BDF) is loaded upon driver boot-up procedure. The right +board data file is identified on QCA4019 using bus, bmi-chip-id and +bmi-board-id. + +The problem, however, can occur when the (default) board data file cannot +fulfill with the vendor requirements and it is necessary to use a different +board data file. + +This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8. +Something similar has to be provided for systems without SMBIOS but with +device trees. No solution was specified by QCA and therefore a new one has +to be found for ath10k. + +The device tree requires addition strings to define the variant name + + wifi@a000000 { + status = "okay"; + qcom,ath10k-calibration-variant = "RT-AC58U"; + }; + + wifi@a800000 { + status = "okay"; + qcom,ath10k-calibration-variant = "RT-AC58U"; + }; + +This would create the boarddata identifiers for the board-2.bin search + + * bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U + * bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U + +Signed-off-by: Sven Eckelmann +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath10k/core.c | 40 ++++++++++++++++++++++++++++------ + 1 file changed, 33 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -860,6 +860,28 @@ static int ath10k_core_check_smbios(stru + return 0; + } + ++static int ath10k_core_check_dt(struct ath10k *ar) ++{ ++ struct device_node *node; ++ const char *variant = NULL; ++ ++ node = ar->dev->of_node; ++ if (!node) ++ return -ENOENT; ++ ++ of_property_read_string(node, "qcom,ath10k-calibration-variant", ++ &variant); ++ if (!variant) ++ return -ENODATA; ++ ++ if (strscpy(ar->id.bdf_ext, variant, sizeof(ar->id.bdf_ext)) < 0) ++ ath10k_dbg(ar, ATH10K_DBG_BOOT, ++ "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", ++ variant); ++ ++ return 0; ++} ++ + static int ath10k_download_and_run_otp(struct ath10k *ar) + { + u32 result, address = ar->hw_params.patch_load_addr; +@@ -1231,19 +1253,19 @@ static int ath10k_core_create_board_name + /* strlen(',variant=') + strlen(ar->id.bdf_ext) */ + char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 }; + ++ if (ar->id.bdf_ext[0] != '\0') ++ scnprintf(variant, sizeof(variant), ",variant=%s", ++ ar->id.bdf_ext); ++ + if (ar->id.bmi_ids_valid) { + scnprintf(name, name_len, +- "bus=%s,bmi-chip-id=%d,bmi-board-id=%d", ++ "bus=%s,bmi-chip-id=%d,bmi-board-id=%d%s", + ath10k_bus_str(ar->hif.bus), + ar->id.bmi_chip_id, +- ar->id.bmi_board_id); ++ ar->id.bmi_board_id, variant); + goto out; + } + +- if (ar->id.bdf_ext[0] != '\0') +- scnprintf(variant, sizeof(variant), ",variant=%s", +- ar->id.bdf_ext); +- + scnprintf(name, name_len, + "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s", + ath10k_bus_str(ar->hif.bus), +@@ -2343,7 +2365,11 @@ static int ath10k_core_probe_fw(struct a + + ret = ath10k_core_check_smbios(ar); + if (ret) +- ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not set.\n"); ++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "SMBIOS bdf variant name not set.\n"); ++ ++ ret = ath10k_core_check_dt(ar); ++ if (ret) ++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n"); + + ret = ath10k_core_fetch_board_file(ar); + if (ret) { diff --git a/root/package/kernel/mac80211/patches/082-ath10k-suppress-Unknown-eventid-36925-warnings.patch b/root/package/kernel/mac80211/patches/082-ath10k-suppress-Unknown-eventid-36925-warnings.patch new file mode 100644 index 00000000..9ddede3a --- /dev/null +++ b/root/package/kernel/mac80211/patches/082-ath10k-suppress-Unknown-eventid-36925-warnings.patch @@ -0,0 +1,36 @@ +From 606204bb863fa3b0bb54929d79b4dc46338f9180 Mon Sep 17 00:00:00 2001 +From: Sathishkumar Muruganandam +Date: Tue, 27 Mar 2018 11:26:46 +0300 +Subject: [PATCH] ath10k: suppress "Unknown eventid: 36925" warnings + +FW has Smart Logging feature enabled by default for detecting failures +and processing FATAL_CONDITION_EVENTID (36925 - 0x903D) back to host. + +Since ath10k doesn't implement the Smart Logging and FATAL CONDITION +EVENT processing yet, suppressing the unknown event ID warning by moving +this under ATH10K_DBG_WMI. + +Simulated the same issue by having associated STA powered off when +ping flood was running from AP backbone. This triggerd STA KICKOUT +in AP followed by FATAL CONDITION event 36925. + +Issue was reproduced and verified in below DUT +------------------------------------------------ +AP mode of OpenWRT QCA9984 running 6.0.8 with FW ver 10.4-3.5.3-00053 + +Signed-off-by: Sathishkumar Muruganandam +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath10k/wmi.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -5462,6 +5462,7 @@ static void ath10k_wmi_10_4_op_rx(struct + case WMI_10_4_WOW_WAKEUP_HOST_EVENTID: + case WMI_10_4_PEER_RATECODE_LIST_EVENTID: + case WMI_10_4_WDS_PEER_EVENTID: ++ case WMI_10_4_DEBUG_FATAL_CONDITION_EVENTID: + ath10k_dbg(ar, ATH10K_DBG_WMI, + "received event id %d not implemented\n", id); + break; diff --git a/root/package/kernel/mac80211/patches/090-Revert-rt2800-use-TXOP_BACKOFF-for-probe-frames.patch b/root/package/kernel/mac80211/patches/090-Revert-rt2800-use-TXOP_BACKOFF-for-probe-frames.patch new file mode 100644 index 00000000..95feffa0 --- /dev/null +++ b/root/package/kernel/mac80211/patches/090-Revert-rt2800-use-TXOP_BACKOFF-for-probe-frames.patch @@ -0,0 +1,45 @@ +From patchwork Mon May 28 11:25:06 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: Revert "rt2800: use TXOP_BACKOFF for probe frames" +From: Stanislaw Gruszka +X-Patchwork-Id: 10431861 +Message-Id: <1527506706-6488-1-git-send-email-sgruszka@redhat.com> +To: linux-wireless@vger.kernel.org +Date: Mon, 28 May 2018 13:25:06 +0200 + +This reverts commit fb47ada8dc3c30c8e7b415da155742b49536c61e. + +In some situations when we set TXOP_BACKOFF, the probe frame is +not sent at all. What it worse then sending probe frame as part +of AMPDU and can degrade 11n performance to 11g rates. + +Cc: stable@vger.kernel.org +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -372,16 +372,15 @@ static void rt2x00queue_create_tx_descri + + /* + * Determine IFS values +- * - Use TXOP_BACKOFF for probe and management frames except beacons ++ * - Use TXOP_BACKOFF for management frames except beacons + * - Use TXOP_SIFS for fragment bursts + * - Use TXOP_HTTXOP for everything else + * + * Note: rt2800 devices won't use CTS protection (if used) + * for frames not transmitted with TXOP_HTTXOP + */ +- if ((ieee80211_is_mgmt(hdr->frame_control) && +- !ieee80211_is_beacon(hdr->frame_control)) || +- (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) ++ if (ieee80211_is_mgmt(hdr->frame_control) && ++ !ieee80211_is_beacon(hdr->frame_control)) + txdesc->u.ht.txop = TXOP_BACKOFF; + else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)) + txdesc->u.ht.txop = TXOP_SIFS; diff --git a/root/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch b/root/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch new file mode 100644 index 00000000..8d7a39a6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch @@ -0,0 +1,705 @@ +--- a/net/mac80211/Makefile ++++ b/net/mac80211/Makefile +@@ -6,7 +6,6 @@ mac80211-y := \ + driver-ops.o \ + sta_info.o \ + wep.o \ +- aead_api.o \ + wpa.o \ + scan.o offchannel.o \ + ht.o agg-tx.o agg-rx.o \ +@@ -16,8 +15,8 @@ mac80211-y := \ + rate.o \ + michael.o \ + tkip.o \ ++ aes_ccm.o \ + aes_cmac.o \ +- aes_gmac.o \ + fils_aead.o \ + cfg.o \ + ethtool.o \ +--- a/net/mac80211/aead_api.c ++++ /dev/null +@@ -1,115 +0,0 @@ +-/* +- * Copyright 2003-2004, Instant802 Networks, Inc. +- * Copyright 2005-2006, Devicescape Software, Inc. +- * Copyright 2014-2015, Qualcomm Atheros, Inc. +- * +- * Rewrite: Copyright (C) 2013 Linaro Ltd +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License version 2 as +- * published by the Free Software Foundation. +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include "aead_api.h" +- +-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, +- u8 *data, size_t data_len, u8 *mic) +-{ +- size_t mic_len = crypto_aead_authsize(tfm); +- struct scatterlist sg[3]; +- struct aead_request *aead_req; +- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +- u8 *__aad; +- +- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); +- if (!aead_req) +- return -ENOMEM; +- +- __aad = (u8 *)aead_req + reqsize; +- memcpy(__aad, aad, aad_len); +- +- sg_init_table(sg, 3); +- sg_set_buf(&sg[0], __aad, aad_len); +- sg_set_buf(&sg[1], data, data_len); +- sg_set_buf(&sg[2], mic, mic_len); +- +- aead_request_set_tfm(aead_req, tfm); +- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0); +- aead_request_set_ad(aead_req, sg[0].length); +- +- crypto_aead_encrypt(aead_req); +- kzfree(aead_req); +- +- return 0; +-} +- +-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len, +- u8 *data, size_t data_len, u8 *mic) +-{ +- size_t mic_len = crypto_aead_authsize(tfm); +- struct scatterlist sg[3]; +- struct aead_request *aead_req; +- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); +- u8 *__aad; +- int err; +- +- if (data_len == 0) +- return -EINVAL; +- +- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC); +- if (!aead_req) +- return -ENOMEM; +- +- __aad = (u8 *)aead_req + reqsize; +- memcpy(__aad, aad, aad_len); +- +- sg_init_table(sg, 3); +- sg_set_buf(&sg[0], __aad, aad_len); +- sg_set_buf(&sg[1], data, data_len); +- sg_set_buf(&sg[2], mic, mic_len); +- +- aead_request_set_tfm(aead_req, tfm); +- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0); +- aead_request_set_ad(aead_req, sg[0].length); +- +- err = crypto_aead_decrypt(aead_req); +- kzfree(aead_req); +- +- return err; +-} +- +-struct crypto_aead * +-aead_key_setup_encrypt(const char *alg, const u8 key[], +- size_t key_len, size_t mic_len) +-{ +- struct crypto_aead *tfm; +- int err; +- +- tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC); +- if (IS_ERR(tfm)) +- return tfm; +- +- err = crypto_aead_setkey(tfm, key, key_len); +- if (err) +- goto free_aead; +- err = crypto_aead_setauthsize(tfm, mic_len); +- if (err) +- goto free_aead; +- +- return tfm; +- +-free_aead: +- crypto_free_aead(tfm); +- return ERR_PTR(err); +-} +- +-void aead_key_free(struct crypto_aead *tfm) +-{ +- crypto_free_aead(tfm); +-} +--- a/net/mac80211/aead_api.h ++++ /dev/null +@@ -1,27 +0,0 @@ +-/* +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License version 2 as +- * published by the Free Software Foundation. +- */ +- +-#ifndef _AEAD_API_H +-#define _AEAD_API_H +- +-#include +-#include +- +-struct crypto_aead * +-aead_key_setup_encrypt(const char *alg, const u8 key[], +- size_t key_len, size_t mic_len); +- +-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +- size_t aad_len, u8 *data, +- size_t data_len, u8 *mic); +- +-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, +- size_t aad_len, u8 *data, +- size_t data_len, u8 *mic); +- +-void aead_key_free(struct crypto_aead *tfm); +- +-#endif /* _AEAD_API_H */ +--- a/net/mac80211/aes_ccm.h ++++ b/net/mac80211/aes_ccm.h +@@ -10,39 +10,17 @@ + #ifndef AES_CCM_H + #define AES_CCM_H + +-#include "aead_api.h" ++#include + +-#define CCM_AAD_LEN 32 +- +-static inline struct crypto_aead * +-ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len) +-{ +- return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len); +-} +- +-static inline int +-ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, +- u8 *b_0, u8 *aad, u8 *data, +- size_t data_len, u8 *mic) +-{ +- return aead_encrypt(tfm, b_0, aad + 2, +- be16_to_cpup((__be16 *)aad), +- data, data_len, mic); +-} +- +-static inline int +-ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, +- u8 *b_0, u8 *aad, u8 *data, +- size_t data_len, u8 *mic) +-{ +- return aead_decrypt(tfm, b_0, aad + 2, +- be16_to_cpup((__be16 *)aad), +- data, data_len, mic); +-} +- +-static inline void ieee80211_aes_key_free(struct crypto_aead *tfm) +-{ +- return aead_key_free(tfm); +-} ++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], ++ size_t key_len, ++ size_t mic_len); ++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic, ++ size_t mic_len); ++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic, ++ size_t mic_len); ++void ieee80211_aes_key_free(struct crypto_cipher *tfm); + + #endif /* AES_CCM_H */ +--- /dev/null ++++ b/net/mac80211/aes_gcm.c +@@ -0,0 +1,109 @@ ++/* ++ * Copyright 2014-2015, Qualcomm Atheros, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include "key.h" ++#include "aes_gcm.h" ++ ++int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic) ++{ ++ struct scatterlist sg[3]; ++ struct aead_request *aead_req; ++ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); ++ u8 *__aad; ++ ++ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); ++ if (!aead_req) ++ return -ENOMEM; ++ ++ __aad = (u8 *)aead_req + reqsize; ++ memcpy(__aad, aad, GCM_AAD_LEN); ++ ++ sg_init_table(sg, 3); ++ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); ++ sg_set_buf(&sg[1], data, data_len); ++ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); ++ ++ aead_request_set_tfm(aead_req, tfm); ++ aead_request_set_crypt(aead_req, sg, sg, data_len, j_0); ++ aead_request_set_ad(aead_req, sg[0].length); ++ ++ crypto_aead_encrypt(aead_req); ++ kzfree(aead_req); ++ return 0; ++} ++ ++int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic) ++{ ++ struct scatterlist sg[3]; ++ struct aead_request *aead_req; ++ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm); ++ u8 *__aad; ++ int err; ++ ++ if (data_len == 0) ++ return -EINVAL; ++ ++ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC); ++ if (!aead_req) ++ return -ENOMEM; ++ ++ __aad = (u8 *)aead_req + reqsize; ++ memcpy(__aad, aad, GCM_AAD_LEN); ++ ++ sg_init_table(sg, 3); ++ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad)); ++ sg_set_buf(&sg[1], data, data_len); ++ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN); ++ ++ aead_request_set_tfm(aead_req, tfm); ++ aead_request_set_crypt(aead_req, sg, sg, ++ data_len + IEEE80211_GCMP_MIC_LEN, j_0); ++ aead_request_set_ad(aead_req, sg[0].length); ++ ++ err = crypto_aead_decrypt(aead_req); ++ kzfree(aead_req); ++ ++ return err; ++} ++ ++struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], ++ size_t key_len) ++{ ++ struct crypto_aead *tfm; ++ int err; ++ ++ tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); ++ if (IS_ERR(tfm)) ++ return tfm; ++ ++ err = crypto_aead_setkey(tfm, key, key_len); ++ if (err) ++ goto free_aead; ++ err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN); ++ if (err) ++ goto free_aead; ++ ++ return tfm; ++ ++free_aead: ++ crypto_free_aead(tfm); ++ return ERR_PTR(err); ++} ++ ++void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) ++{ ++ crypto_free_aead(tfm); ++} +--- a/net/mac80211/aes_gcm.h ++++ b/net/mac80211/aes_gcm.h +@@ -9,38 +9,30 @@ + #ifndef AES_GCM_H + #define AES_GCM_H + +-#include "aead_api.h" ++#include + +-#define GCM_AAD_LEN 32 +- +-static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, +- u8 *j_0, u8 *aad, u8 *data, +- size_t data_len, u8 *mic) ++static inline void ++ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic) + { +- return aead_encrypt(tfm, j_0, aad + 2, +- be16_to_cpup((__be16 *)aad), +- data, data_len, mic); + } + +-static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, +- u8 *j_0, u8 *aad, u8 *data, +- size_t data_len, u8 *mic) ++static inline int ++ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic) + { +- return aead_decrypt(tfm, j_0, aad + 2, +- be16_to_cpup((__be16 *)aad), +- data, data_len, mic); ++ return -EOPNOTSUPP; + } + + static inline struct crypto_aead * + ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len) + { +- return aead_key_setup_encrypt("gcm(aes)", key, +- key_len, IEEE80211_GCMP_MIC_LEN); ++ return NULL; + } + +-static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) ++static inline void ++ieee80211_aes_gcm_key_free(struct crypto_aead *tfm) + { +- return aead_key_free(tfm); + } + + #endif /* AES_GCM_H */ +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -306,7 +306,8 @@ ieee80211_crypto_tkip_decrypt(struct iee + } + + +-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad) ++static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, ++ u16 data_len) + { + __le16 mask_fc; + int a4_included, mgmt; +@@ -336,14 +337,8 @@ static void ccmp_special_blocks(struct s + else + qos_tid = 0; + +- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC +- * mode authentication are not allowed to collide, yet both are derived +- * from this vector b_0. We only set L := 1 here to indicate that the +- * data size can be represented in (L+1) bytes. The CCM layer will take +- * care of storing the data length in the top (L+1) bytes and setting +- * and clearing the other bits as is required to derive the two IVs. +- */ +- b_0[0] = 0x1; ++ /* First block, b_0 */ ++ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ + + /* Nonce: Nonce Flags | A2 | PN + * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) +@@ -351,6 +346,8 @@ static void ccmp_special_blocks(struct s + b_0[1] = qos_tid | (mgmt << 4); + memcpy(&b_0[2], hdr->addr2, ETH_ALEN); + memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); ++ /* l(m) */ ++ put_unaligned_be16(data_len, &b_0[14]); + + /* AAD (extra authenticate-only data) / masked 802.11 header + * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ +@@ -407,7 +404,7 @@ static int ccmp_encrypt_skb(struct ieee8 + u8 *pos; + u8 pn[6]; + u64 pn64; +- u8 aad[CCM_AAD_LEN]; ++ u8 aad[2 * AES_BLOCK_SIZE]; + u8 b_0[AES_BLOCK_SIZE]; + + if (info->control.hw_key && +@@ -462,9 +459,11 @@ static int ccmp_encrypt_skb(struct ieee8 + return 0; + + pos += IEEE80211_CCMP_HDR_LEN; +- ccmp_special_blocks(skb, pn, b_0, aad); +- return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, +- skb_put(skb, mic_len)); ++ ccmp_special_blocks(skb, pn, b_0, aad, len); ++ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, ++ skb_put(skb, mic_len), mic_len); ++ ++ return 0; + } + + +@@ -537,13 +536,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee + u8 aad[2 * AES_BLOCK_SIZE]; + u8 b_0[AES_BLOCK_SIZE]; + /* hardware didn't decrypt/verify MIC */ +- ccmp_special_blocks(skb, pn, b_0, aad); ++ ccmp_special_blocks(skb, pn, b_0, aad, data_len); + + if (ieee80211_aes_ccm_decrypt( + key->u.ccmp.tfm, b_0, aad, + skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, + data_len, +- skb->data + skb->len - mic_len)) ++ skb->data + skb->len - mic_len, mic_len)) + return RX_DROP_UNUSABLE; + } + +@@ -639,7 +638,7 @@ static int gcmp_encrypt_skb(struct ieee8 + u8 *pos; + u8 pn[6]; + u64 pn64; +- u8 aad[GCM_AAD_LEN]; ++ u8 aad[2 * AES_BLOCK_SIZE]; + u8 j_0[AES_BLOCK_SIZE]; + + if (info->control.hw_key && +@@ -696,8 +695,10 @@ static int gcmp_encrypt_skb(struct ieee8 + + pos += IEEE80211_GCMP_HDR_LEN; + gcmp_special_blocks(skb, pn, j_0, aad); +- return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, +- skb_put(skb, IEEE80211_GCMP_MIC_LEN)); ++ ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len, ++ skb_put(skb, IEEE80211_GCMP_MIC_LEN)); ++ ++ return 0; + } + + ieee80211_tx_result +@@ -1121,9 +1122,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct + struct ieee80211_key *key = tx->key; + struct ieee80211_mmie_16 *mmie; + struct ieee80211_hdr *hdr; +- u8 aad[GMAC_AAD_LEN]; ++ u8 aad[20]; + u64 pn64; +- u8 nonce[GMAC_NONCE_LEN]; ++ u8 nonce[12]; + + if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) + return TX_DROP; +@@ -1169,7 +1170,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_key *key = rx->key; + struct ieee80211_mmie_16 *mmie; +- u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN]; ++ u8 aad[20], mic[16], ipn[6], nonce[12]; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + + if (!ieee80211_is_mgmt(hdr->frame_control)) +--- /dev/null ++++ b/net/mac80211/aes_ccm.c +@@ -0,0 +1,144 @@ ++/* ++ * Copyright 2003-2004, Instant802 Networks, Inc. ++ * Copyright 2005-2006, Devicescape Software, Inc. ++ * ++ * Rewrite: Copyright (C) 2013 Linaro Ltd ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "key.h" ++#include "aes_ccm.h" ++ ++static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0, ++ u8 *a, u8 *b) ++{ ++ int i; ++ ++ crypto_cipher_encrypt_one(tfm, b, b_0); ++ ++ /* Extra Authenticate-only data (always two AES blocks) */ ++ for (i = 0; i < AES_BLOCK_SIZE; i++) ++ aad[i] ^= b[i]; ++ crypto_cipher_encrypt_one(tfm, b, aad); ++ ++ aad += AES_BLOCK_SIZE; ++ ++ for (i = 0; i < AES_BLOCK_SIZE; i++) ++ aad[i] ^= b[i]; ++ crypto_cipher_encrypt_one(tfm, a, aad); ++ ++ /* Mask out bits from auth-only-b_0 */ ++ b_0[0] &= 0x07; ++ ++ /* S_0 is used to encrypt T (= MIC) */ ++ b_0[14] = 0; ++ b_0[15] = 0; ++ crypto_cipher_encrypt_one(tfm, s_0, b_0); ++} ++ ++ ++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic, ++ size_t mic_len) ++{ ++ int i, j, last_len, num_blocks; ++ u8 b[AES_BLOCK_SIZE]; ++ u8 s_0[AES_BLOCK_SIZE]; ++ u8 e[AES_BLOCK_SIZE]; ++ u8 *pos, *cpos; ++ ++ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); ++ last_len = data_len % AES_BLOCK_SIZE; ++ aes_ccm_prepare(tfm, b_0, aad, s_0, b, b); ++ ++ /* Process payload blocks */ ++ pos = data; ++ cpos = data; ++ for (j = 1; j <= num_blocks; j++) { ++ int blen = (j == num_blocks && last_len) ? ++ last_len : AES_BLOCK_SIZE; ++ ++ /* Authentication followed by encryption */ ++ for (i = 0; i < blen; i++) ++ b[i] ^= pos[i]; ++ crypto_cipher_encrypt_one(tfm, b, b); ++ ++ b_0[14] = (j >> 8) & 0xff; ++ b_0[15] = j & 0xff; ++ crypto_cipher_encrypt_one(tfm, e, b_0); ++ for (i = 0; i < blen; i++) ++ *cpos++ = *pos++ ^ e[i]; ++ } ++ ++ for (i = 0; i < mic_len; i++) ++ mic[i] = b[i] ^ s_0[i]; ++} ++ ++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, ++ u8 *data, size_t data_len, u8 *mic, ++ size_t mic_len) ++{ ++ int i, j, last_len, num_blocks; ++ u8 *pos, *cpos; ++ u8 a[AES_BLOCK_SIZE]; ++ u8 b[AES_BLOCK_SIZE]; ++ u8 s_0[AES_BLOCK_SIZE]; ++ ++ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE); ++ last_len = data_len % AES_BLOCK_SIZE; ++ aes_ccm_prepare(tfm, b_0, aad, s_0, a, b); ++ ++ /* Process payload blocks */ ++ cpos = data; ++ pos = data; ++ for (j = 1; j <= num_blocks; j++) { ++ int blen = (j == num_blocks && last_len) ? ++ last_len : AES_BLOCK_SIZE; ++ ++ /* Decryption followed by authentication */ ++ b_0[14] = (j >> 8) & 0xff; ++ b_0[15] = j & 0xff; ++ crypto_cipher_encrypt_one(tfm, b, b_0); ++ for (i = 0; i < blen; i++) { ++ *pos = *cpos++ ^ b[i]; ++ a[i] ^= *pos++; ++ } ++ crypto_cipher_encrypt_one(tfm, a, a); ++ } ++ ++ for (i = 0; i < mic_len; i++) { ++ if ((mic[i] ^ s_0[i]) != a[i]) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[], ++ size_t key_len, ++ size_t mic_len) ++{ ++ struct crypto_cipher *tfm; ++ ++ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); ++ if (!IS_ERR(tfm)) ++ crypto_cipher_setkey(tfm, key, key_len); ++ ++ return tfm; ++} ++ ++ ++void ieee80211_aes_key_free(struct crypto_cipher *tfm) ++{ ++ crypto_free_cipher(tfm); ++} +--- a/net/mac80211/Kconfig ++++ b/net/mac80211/Kconfig +@@ -5,8 +5,6 @@ config MAC80211 + depends on CRYPTO + depends on CRYPTO_ARC4 + depends on CRYPTO_AES +- depends on CRYPTO_CCM +- depends on CRYPTO_GCM + depends on CRYPTO_CMAC + depends on CRC32 + ---help--- +--- a/net/mac80211/aes_gmac.h ++++ b/net/mac80211/aes_gmac.h +@@ -15,10 +15,22 @@ + #define GMAC_MIC_LEN 16 + #define GMAC_NONCE_LEN 12 + +-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[], +- size_t key_len); +-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, +- const u8 *data, size_t data_len, u8 *mic); +-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm); ++static inline struct crypto_aead * ++ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len) ++{ ++ return NULL; ++} ++ ++static inline int ++ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce, ++ const u8 *data, size_t data_len, u8 *mic) ++{ ++ return -EOPNOTSUPP; ++} ++ ++static inline void ++ieee80211_aes_gmac_key_free(struct crypto_aead *tfm) ++{ ++} + + #endif /* AES_GMAC_H */ +--- a/net/mac80211/key.h ++++ b/net/mac80211/key.h +@@ -88,7 +88,7 @@ struct ieee80211_key { + * Management frames. + */ + u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; +- struct crypto_aead *tfm; ++ struct crypto_cipher *tfm; + u32 replays; /* dot11RSNAStatsCCMPReplays */ + } ccmp; + struct { diff --git a/root/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch b/root/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch new file mode 100644 index 00000000..3b1fcdf9 --- /dev/null +++ b/root/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch @@ -0,0 +1,12 @@ +Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1058,7 +1058,6 @@ static int ieee80211_stop_ap(struct wiph + sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; + + __sta_info_flush(sdata, true); +- ieee80211_free_keys(sdata, true); + + sdata->vif.bss_conf.enable_beacon = false; + sdata->vif.bss_conf.ssid_len = 0; diff --git a/root/package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch b/root/package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch new file mode 100644 index 00000000..ffd8807c --- /dev/null +++ b/root/package/kernel/mac80211/patches/120-cfg80211_allow_perm_addr_change.patch @@ -0,0 +1,43 @@ +--- a/net/wireless/sysfs.c ++++ b/net/wireless/sysfs.c +@@ -24,18 +24,35 @@ static inline struct cfg80211_registered + return container_of(dev, struct cfg80211_registered_device, wiphy.dev); + } + +-#define SHOW_FMT(name, fmt, member) \ ++#define SHOW_FMT(name, fmt, member, mode) \ + static ssize_t name ## _show(struct device *dev, \ + struct device_attribute *attr, \ + char *buf) \ + { \ + return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ + } \ +-static DEVICE_ATTR_RO(name) ++static DEVICE_ATTR_##mode(name) + +-SHOW_FMT(index, "%d", wiphy_idx); +-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); +-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); ++static ssize_t macaddress_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t len) ++{ ++ u8 mac[ETH_ALEN]; ++ ++ if (!mac_pton(buf, mac)) ++ return -EINVAL; ++ ++ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n') ++ return -EINVAL; ++ ++ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN); ++ ++ return strnlen(buf, len); ++} ++ ++SHOW_FMT(index, "%d", wiphy_idx, RO); ++SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW); ++SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO); + + static ssize_t name_show(struct device *dev, + struct device_attribute *attr, diff --git a/root/package/kernel/mac80211/patches/130-disable-fils.patch b/root/package/kernel/mac80211/patches/130-disable-fils.patch new file mode 100644 index 00000000..1f035898 --- /dev/null +++ b/root/package/kernel/mac80211/patches/130-disable-fils.patch @@ -0,0 +1,32 @@ +Disable FILS support, since it pulls in crypto hash support + +--- a/net/mac80211/fils_aead.h ++++ b/net/mac80211/fils_aead.h +@@ -10,7 +10,7 @@ + #ifndef FILS_AEAD_H + #define FILS_AEAD_H + +-#if LINUX_VERSION_IS_GEQ(4,3,0) ++#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ + int fils_encrypt_assoc_req(struct sk_buff *skb, + struct ieee80211_mgd_assoc_data *assoc_data); + int fils_decrypt_assoc_resp(struct ieee80211_sub_if_data *sdata, +--- a/net/mac80211/fils_aead.c ++++ b/net/mac80211/fils_aead.c +@@ -1,4 +1,4 @@ +-#if LINUX_VERSION_IS_GEQ(4,3,0) ++#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ + /* + * FILS AEAD for (Re)Association Request/Response frames + * Copyright 2016, Qualcomm Atheros, Inc. +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -550,7 +550,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + NL80211_FEATURE_MAC_ON_CREATE | + NL80211_FEATURE_USERSPACE_MPM | + NL80211_FEATURE_FULL_AP_CLIENT_STATE; +-#if LINUX_VERSION_IS_GEQ(4,3,0) ++#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA); + #endif + diff --git a/root/package/kernel/mac80211/patches/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch b/root/package/kernel/mac80211/patches/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch new file mode 100644 index 00000000..d138b2c5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch @@ -0,0 +1,199 @@ +From: Felix Fietkau +Date: Sat, 7 Oct 2017 09:37:28 +0200 +Subject: [PATCH] Revert "mac80211: aes-cmac: switch to shash CMAC + driver" + +This reverts commit 26717828b75dd5c46e97f7f4a9b937d038bb2852. +Reduces mac80211 dependencies for LEDE + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/aes_cmac.c ++++ b/net/mac80211/aes_cmac.c +@@ -22,50 +22,126 @@ + #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ + #define AAD_LEN 20 + +-static const u8 zero[CMAC_TLEN_256]; + +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++void gf_mulx(u8 *pad) ++{ ++ int i, carry; ++ ++ carry = pad[0] & 0x80; ++ for (i = 0; i < AES_BLOCK_SIZE - 1; i++) ++ pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7); ++ pad[AES_BLOCK_SIZE - 1] <<= 1; ++ if (carry) ++ pad[AES_BLOCK_SIZE - 1] ^= 0x87; ++} ++ ++void aes_cmac_vector(struct crypto_cipher *tfm, size_t num_elem, ++ const u8 *addr[], const size_t *len, u8 *mac, ++ size_t mac_len) + { +- SHASH_DESC_ON_STACK(desc, tfm); +- u8 out[AES_BLOCK_SIZE]; ++ u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE]; ++ const u8 *pos, *end; ++ size_t i, e, left, total_len; ++ ++ memset(cbc, 0, AES_BLOCK_SIZE); ++ ++ total_len = 0; ++ for (e = 0; e < num_elem; e++) ++ total_len += len[e]; ++ left = total_len; ++ ++ e = 0; ++ pos = addr[0]; ++ end = pos + len[0]; ++ ++ while (left >= AES_BLOCK_SIZE) { ++ for (i = 0; i < AES_BLOCK_SIZE; i++) { ++ cbc[i] ^= *pos++; ++ if (pos >= end) { ++ e++; ++ pos = addr[e]; ++ end = pos + len[e]; ++ } ++ } ++ if (left > AES_BLOCK_SIZE) ++ crypto_cipher_encrypt_one(tfm, cbc, cbc); ++ left -= AES_BLOCK_SIZE; ++ } ++ ++ memset(pad, 0, AES_BLOCK_SIZE); ++ crypto_cipher_encrypt_one(tfm, pad, pad); ++ gf_mulx(pad); ++ ++ if (left || total_len == 0) { ++ for (i = 0; i < left; i++) { ++ cbc[i] ^= *pos++; ++ if (pos >= end) { ++ e++; ++ pos = addr[e]; ++ end = pos + len[e]; ++ } ++ } ++ cbc[left] ^= 0x80; ++ gf_mulx(pad); ++ } ++ ++ for (i = 0; i < AES_BLOCK_SIZE; i++) ++ pad[i] ^= cbc[i]; ++ crypto_cipher_encrypt_one(tfm, pad, pad); ++ memcpy(mac, pad, mac_len); ++} + +- desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); +- crypto_shash_update(desc, data, data_len - CMAC_TLEN); +- crypto_shash_finup(desc, zero, CMAC_TLEN, out); ++void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) ++{ ++ const u8 *addr[3]; ++ size_t len[3]; ++ u8 zero[CMAC_TLEN]; ++ ++ memset(zero, 0, CMAC_TLEN); ++ addr[0] = aad; ++ len[0] = AAD_LEN; ++ addr[1] = data; ++ len[1] = data_len - CMAC_TLEN; ++ addr[2] = zero; ++ len[2] = CMAC_TLEN; + +- memcpy(mic, out, CMAC_TLEN); ++ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN); + } + +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic) + { +- SHASH_DESC_ON_STACK(desc, tfm); ++ const u8 *addr[3]; ++ size_t len[3]; ++ u8 zero[CMAC_TLEN_256]; ++ ++ memset(zero, 0, CMAC_TLEN_256); ++ addr[0] = aad; ++ len[0] = AAD_LEN; ++ addr[1] = data; ++ len[1] = data_len - CMAC_TLEN_256; ++ addr[2] = zero; ++ len[2] = CMAC_TLEN_256; + +- desc->tfm = tfm; +- +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); +- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); +- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); ++ aes_cmac_vector(tfm, 3, addr, len, mic, CMAC_TLEN_256); + } + +-struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +- size_t key_len) ++struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], ++ size_t key_len) + { +- struct crypto_shash *tfm; ++ struct crypto_cipher *tfm; + +- tfm = crypto_alloc_shash("cmac(aes)", 0, 0); ++ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + if (!IS_ERR(tfm)) +- crypto_shash_setkey(tfm, key, key_len); ++ crypto_cipher_setkey(tfm, key, key_len); + + return tfm; + } + +-void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm) ++ ++void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm) + { +- crypto_free_shash(tfm); ++ crypto_free_cipher(tfm); + } +--- a/net/mac80211/aes_cmac.h ++++ b/net/mac80211/aes_cmac.h +@@ -10,14 +10,13 @@ + #define AES_CMAC_H + + #include +-#include + +-struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +- size_t key_len); +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++struct crypto_cipher *ieee80211_aes_cmac_key_setup(const u8 key[], ++ size_t key_len); ++void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic); +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++void ieee80211_aes_cmac_256(struct crypto_cipher *tfm, const u8 *aad, + const u8 *data, size_t data_len, u8 *mic); +-void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); ++void ieee80211_aes_cmac_key_free(struct crypto_cipher *tfm); + + #endif /* AES_CMAC_H */ +--- a/net/mac80211/key.h ++++ b/net/mac80211/key.h +@@ -93,7 +93,7 @@ struct ieee80211_key { + } ccmp; + struct { + u8 rx_pn[IEEE80211_CMAC_PN_LEN]; +- struct crypto_shash *tfm; ++ struct crypto_cipher *tfm; + u32 replays; /* dot11RSNAStatsCMACReplays */ + u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ + } aes_cmac; diff --git a/root/package/kernel/mac80211/patches/132-mac80211-remove-cmac-dependency.patch b/root/package/kernel/mac80211/patches/132-mac80211-remove-cmac-dependency.patch new file mode 100644 index 00000000..9d185e61 --- /dev/null +++ b/root/package/kernel/mac80211/patches/132-mac80211-remove-cmac-dependency.patch @@ -0,0 +1,10 @@ +--- a/net/mac80211/Kconfig ++++ b/net/mac80211/Kconfig +@@ -5,7 +5,6 @@ config MAC80211 + depends on CRYPTO + depends on CRYPTO_ARC4 + depends on CRYPTO_AES +- depends on CRYPTO_CMAC + depends on CRC32 + ---help--- + This option enables the hardware independent IEEE 802.11 diff --git a/root/package/kernel/mac80211/patches/140-tweak-TSQ-setting.patch b/root/package/kernel/mac80211/patches/140-tweak-TSQ-setting.patch new file mode 100644 index 00000000..6e9a07a9 --- /dev/null +++ b/root/package/kernel/mac80211/patches/140-tweak-TSQ-setting.patch @@ -0,0 +1,15 @@ +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3750,6 +3750,12 @@ out: + netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev) + { ++#if defined(sk_pacing_shift) || LINUX_VERSION_IS_GEQ(4,15,0) ++ if (skb->sk && sk_fullsock(skb->sk) && ++ skb->sk->sk_pacing_shift != 6) ++ skb->sk->sk_pacing_shift = 6; ++#endif ++ + if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) { + struct sk_buff_head queue; + diff --git a/root/package/kernel/mac80211/patches/150-disable_addr_notifier.patch b/root/package/kernel/mac80211/patches/150-disable_addr_notifier.patch new file mode 100644 index 00000000..781dd3c1 --- /dev/null +++ b/root/package/kernel/mac80211/patches/150-disable_addr_notifier.patch @@ -0,0 +1,67 @@ +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -292,7 +292,7 @@ void ieee80211_restart_hw(struct ieee802 + } + EXPORT_SYMBOL(ieee80211_restart_hw); + +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + static int ieee80211_ifa_changed(struct notifier_block *nb, + unsigned long data, void *arg) + { +@@ -351,7 +351,7 @@ static int ieee80211_ifa_changed(struct + } + #endif + +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + static int ieee80211_ifa6_changed(struct notifier_block *nb, + unsigned long data, void *arg) + { +@@ -1114,14 +1114,14 @@ int ieee80211_register_hw(struct ieee802 + if (result) + goto fail_flows; + +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + local->ifa_notifier.notifier_call = ieee80211_ifa_changed; + result = register_inetaddr_notifier(&local->ifa_notifier); + if (result) + goto fail_ifa; + #endif + +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; + result = register_inet6addr_notifier(&local->ifa6_notifier); + if (result) +@@ -1130,13 +1130,13 @@ int ieee80211_register_hw(struct ieee802 + + return 0; + +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + fail_ifa6: +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + unregister_inetaddr_notifier(&local->ifa_notifier); + #endif + #endif +-#if defined(CONFIG_INET) || defined(CONFIG_IPV6) ++#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6) + fail_ifa: + #endif + ieee80211_txq_teardown_flows(local); +@@ -1166,10 +1166,10 @@ void ieee80211_unregister_hw(struct ieee + tasklet_kill(&local->tx_pending_tasklet); + tasklet_kill(&local->tasklet); + +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + unregister_inetaddr_notifier(&local->ifa_notifier); + #endif +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + unregister_inet6addr_notifier(&local->ifa6_notifier); + #endif + diff --git a/root/package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch b/root/package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch new file mode 100644 index 00000000..357b006b --- /dev/null +++ b/root/package/kernel/mac80211/patches/160-ath10k-search-all-IEs-for-variant-before-falling-back.patch @@ -0,0 +1,237 @@ +From: Thomas Hebb +Subject: [PATCH] ath10k: search all IEs for variant before falling back +Date: Wed, 21 Feb 2018 11:43:39 -0500 + +commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file +extension") added a feature to ath10k that allows Board Data File +(BDF) conflicts between multiple devices that use the same device IDs +but have different calibration requirements to be resolved by allowing +a "variant" string to be stored in SMBIOS [and later device tree, added +by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration- +variant")] that gets appended to the ID stored in board-2.bin. + +This original patch had a regression, however. Namely that devices with +a variant present in SMBIOS that didn't need custom BDFs could no longer +find the default BDF, which has no variant appended. The patch was +reverted and re-applied with a fix for this issue in commit 1657b8f84ed9 +("search SMBIOS for OEM board file extension"). + +But the fix to fall back to a default BDF introduced another issue: the +driver currently parses IEs in board-2.bin one by one, and for each one +it first checks to see if it matches the ID with the variant appended. +If it doesn't, it checks to see if it matches the "fallback" ID with no +variant. If a matching BDF is found at any point during this search, the +search is terminated and that BDF is used. The issue is that it's very +possible (and is currently the case for board-2.bin files present in the +ath10k-firmware repository) for the default BDF to occur in an earlier +IE than the variant-specific BDF. In this case, the current code will +happily choose the default BDF even though a better-matching BDF is +present later in the file. + +This patch fixes the issue by first searching the entire file for the ID +with variant, and searching for the fallback ID only if that search +fails. It also includes some code cleanup in the area, as +ath10k_core_fetch_board_data_api_n() no longer does its own string +mangling to remove the variant from an ID, instead leaving that job to a +new flag passed to ath10k_core_create_board_name(). + +I've tested this patch on a QCA4019 and verified that the driver behaves +correctly for 1) both fallback and variant BDFs present, 2) only fallback +BDF present, and 3) no matching BDFs present. + +Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension") +Signed-off-by: Thomas Hebb +--- + drivers/net/wireless/ath/ath10k/core.c | 134 ++++++++++++++++++--------------- + 1 file changed, 72 insertions(+), 62 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -1132,14 +1132,61 @@ out: + return ret; + } + ++static int ath10k_core_search_bd(struct ath10k *ar, ++ const char *boardname, ++ const u8 *data, ++ size_t len) ++{ ++ size_t ie_len; ++ struct ath10k_fw_ie *hdr; ++ int ret = -ENOENT, ie_id; ++ ++ while (len > sizeof(struct ath10k_fw_ie)) { ++ hdr = (struct ath10k_fw_ie *)data; ++ ie_id = le32_to_cpu(hdr->id); ++ ie_len = le32_to_cpu(hdr->len); ++ ++ len -= sizeof(*hdr); ++ data = hdr->data; ++ ++ if (len < ALIGN(ie_len, 4)) { ++ ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n", ++ ie_id, ie_len, len); ++ return -EINVAL; ++ } ++ ++ switch (ie_id) { ++ case ATH10K_BD_IE_BOARD: ++ ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len, ++ boardname); ++ if (ret == -ENOENT) ++ /* no match found, continue */ ++ break; ++ ++ /* either found or error, so stop searching */ ++ goto out; ++ } ++ ++ /* jump over the padding */ ++ ie_len = ALIGN(ie_len, 4); ++ ++ len -= ie_len; ++ data += ie_len; ++ } ++ ++out: ++ /* return result of parse_bd_ie_board() or -ENOENT */ ++ return ret; ++} ++ + static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar, + const char *boardname, ++ const char *fallback_boardname, + const char *filename) + { +- size_t len, magic_len, ie_len; +- struct ath10k_fw_ie *hdr; ++ size_t len, magic_len; + const u8 *data; +- int ret, ie_id; ++ int ret; + + ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar, + ar->hw_params.fw.dir, +@@ -1177,69 +1224,23 @@ static int ath10k_core_fetch_board_data_ + data += magic_len; + len -= magic_len; + +- while (len > sizeof(struct ath10k_fw_ie)) { +- hdr = (struct ath10k_fw_ie *)data; +- ie_id = le32_to_cpu(hdr->id); +- ie_len = le32_to_cpu(hdr->len); +- +- len -= sizeof(*hdr); +- data = hdr->data; +- +- if (len < ALIGN(ie_len, 4)) { +- ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n", +- ie_id, ie_len, len); +- ret = -EINVAL; +- goto err; +- } ++ /* attempt to find boardname in the IE list */ ++ ret = ath10k_core_search_bd(ar, boardname, data, len); + +- switch (ie_id) { +- case ATH10K_BD_IE_BOARD: +- ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len, +- boardname); +- if (ret == -ENOENT && ar->id.bdf_ext[0] != '\0') { +- /* try default bdf if variant was not found */ +- char *s, *v = ",variant="; +- char boardname2[100]; +- +- strlcpy(boardname2, boardname, +- sizeof(boardname2)); +- +- s = strstr(boardname2, v); +- if (s) +- *s = '\0'; /* strip ",variant=%s" */ +- +- ret = ath10k_core_parse_bd_ie_board(ar, data, +- ie_len, +- boardname2); +- } ++ /* if we didn't find it and have a fallback name, try that */ ++ if (ret == -ENOENT && fallback_boardname) ++ ret = ath10k_core_search_bd(ar, fallback_boardname, data, len); + +- if (ret == -ENOENT) +- /* no match found, continue */ +- break; +- else if (ret) +- /* there was an error, bail out */ +- goto err; +- +- /* board data found */ +- goto out; +- } +- +- /* jump over the padding */ +- ie_len = ALIGN(ie_len, 4); +- +- len -= ie_len; +- data += ie_len; +- } +- +-out: +- if (!ar->normal_mode_fw.board_data || !ar->normal_mode_fw.board_len) { ++ if (ret == -ENOENT) { + ath10k_err(ar, + "failed to fetch board data for %s from %s/%s\n", + boardname, ar->hw_params.fw.dir, filename); + ret = -ENODATA; +- goto err; + } + ++ if (ret) ++ goto err; ++ + return 0; + + err: +@@ -1248,12 +1249,12 @@ err: + } + + static int ath10k_core_create_board_name(struct ath10k *ar, char *name, +- size_t name_len) ++ size_t name_len, bool with_variant) + { + /* strlen(',variant=') + strlen(ar->id.bdf_ext) */ + char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 }; + +- if (ar->id.bdf_ext[0] != '\0') ++ if (with_variant && ar->id.bdf_ext[0] != '\0') + scnprintf(variant, sizeof(variant), ",variant=%s", + ar->id.bdf_ext); + +@@ -1279,17 +1280,26 @@ out: + + static int ath10k_core_fetch_board_file(struct ath10k *ar) + { +- char boardname[100]; ++ char boardname[100], fallback_boardname[100]; + int ret; + +- ret = ath10k_core_create_board_name(ar, boardname, sizeof(boardname)); ++ ret = ath10k_core_create_board_name(ar, boardname, ++ sizeof(boardname), true); + if (ret) { + ath10k_err(ar, "failed to create board name: %d", ret); + return ret; + } + ++ ret = ath10k_core_create_board_name(ar, fallback_boardname, ++ sizeof(boardname), false); ++ if (ret) { ++ ath10k_err(ar, "failed to create fallback board name: %d", ret); ++ return ret; ++ } ++ + ar->bd_api = 2; + ret = ath10k_core_fetch_board_data_api_n(ar, boardname, ++ fallback_boardname, + ATH10K_BOARD_API2_FILE); + if (!ret) + goto success; diff --git a/root/package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch b/root/package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch new file mode 100644 index 00000000..21516ffd --- /dev/null +++ b/root/package/kernel/mac80211/patches/201-ath5k-WAR-for-AR71xx-PCI-bug.patch @@ -0,0 +1,38 @@ +--- a/drivers/net/wireless/ath/ath5k/initvals.c ++++ b/drivers/net/wireless/ath/ath5k/initvals.c +@@ -62,8 +62,14 @@ static const struct ath5k_ini ar5210_ini + { AR5K_IMR, 0 }, + { AR5K_IER, AR5K_IER_DISABLE }, + { AR5K_BSR, 0, AR5K_INI_READ }, ++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) + { AR5K_TXCFG, AR5K_DMASIZE_128B }, + { AR5K_RXCFG, AR5K_DMASIZE_128B }, ++#else ++ /* WAR for AR71xx PCI bug */ ++ { AR5K_TXCFG, AR5K_DMASIZE_128B }, ++ { AR5K_RXCFG, AR5K_DMASIZE_4B }, ++#endif + { AR5K_CFG, AR5K_INIT_CFG }, + { AR5K_TOPS, 8 }, + { AR5K_RXNOFRM, 8 }, +--- a/drivers/net/wireless/ath/ath5k/dma.c ++++ b/drivers/net/wireless/ath/ath5k/dma.c +@@ -869,10 +869,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah) + * guess we can tweak it and see how it goes ;-) + */ + if (ah->ah_version != AR5K_AR5210) { ++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) + AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, + AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); + AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, + AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); ++#else ++ /* WAR for AR71xx PCI bug */ ++ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, ++ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); ++ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, ++ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B); ++#endif + } + + /* Pre-enable interrupts on 5211/5212*/ diff --git a/root/package/kernel/mac80211/patches/210-ap_scan.patch b/root/package/kernel/mac80211/patches/210-ap_scan.patch new file mode 100644 index 00000000..8ade963c --- /dev/null +++ b/root/package/kernel/mac80211/patches/210-ap_scan.patch @@ -0,0 +1,11 @@ +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2215,7 +2215,7 @@ static int ieee80211_scan(struct wiphy * + * the frames sent while scanning on other channel will be + * lost) + */ +- if (sdata->u.ap.beacon && ++ if (0 && sdata->u.ap.beacon && + (!(wiphy->features & NL80211_FEATURE_AP_SCAN) || + !(req->flags & NL80211_SCAN_FLAG_AP))) + return -EOPNOTSUPP; diff --git a/root/package/kernel/mac80211/patches/300-v4.15-ath10k-fix-build-errors-with-CONFIG_PM.patch b/root/package/kernel/mac80211/patches/300-v4.15-ath10k-fix-build-errors-with-CONFIG_PM.patch new file mode 100644 index 00000000..2aeb49dc --- /dev/null +++ b/root/package/kernel/mac80211/patches/300-v4.15-ath10k-fix-build-errors-with-CONFIG_PM.patch @@ -0,0 +1,72 @@ +From: Brian Norris +Date: Thu, 19 Oct 2017 11:45:19 -0700 +Subject: [PATCH] ath10k: fix build errors with !CONFIG_PM + +Build errors have been reported with CONFIG_PM=n: + +drivers/net/wireless/ath/ath10k/pci.c:3416:8: error: implicit +declaration of function 'ath10k_pci_suspend' +[-Werror=implicit-function-declaration] + +drivers/net/wireless/ath/ath10k/pci.c:3428:8: error: implicit +declaration of function 'ath10k_pci_resume' +[-Werror=implicit-function-declaration] + +These are caused by the combination of the following two commits: + +6af1de2e4ec4 ("ath10k: mark PM functions as __maybe_unused") +96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but +disabled") + +Both build fine on their own. + +But now that ath10k_pci_pm_{suspend,resume}() is compiled +unconditionally, we should also compile ath10k_pci_{suspend,resume}() +unconditionally. + +And drop the #ifdef around ath10k_pci_hif_{suspend,resume}() too; they +are trivial (empty), so we're not saving much space by compiling them +out. And the alternatives would be to sprinkle more __maybe_unused, or +spread the #ifdef's further. + +Build tested with the following combinations: +CONFIG_PM=y && CONFIG_PM_SLEEP=y +CONFIG_PM=y && CONFIG_PM_SLEEP=n +CONFIG_PM=n + +Fixes: 96378bd2c6cd ("ath10k: fix core PCI suspend when WoWLAN is supported but disabled") +Fixes: 096ad2a15fd8 ("Merge branch 'ath-next'") +Signed-off-by: Brian Norris +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/ath/ath10k/pci.c ++++ b/drivers/net/wireless/ath/ath10k/pci.c +@@ -2577,8 +2577,6 @@ void ath10k_pci_hif_power_down(struct at + */ + } + +-#ifdef CONFIG_PM +- + static int ath10k_pci_hif_suspend(struct ath10k *ar) + { + /* Nothing to do; the important stuff is in the driver suspend. */ +@@ -2627,7 +2625,6 @@ static int ath10k_pci_resume(struct ath1 + + return ret; + } +-#endif + + static bool ath10k_pci_validate_cal(void *data, size_t size) + { +@@ -2782,10 +2779,8 @@ static const struct ath10k_hif_ops ath10 + .power_down = ath10k_pci_hif_power_down, + .read32 = ath10k_pci_read32, + .write32 = ath10k_pci_write32, +-#ifdef CONFIG_PM + .suspend = ath10k_pci_hif_suspend, + .resume = ath10k_pci_hif_resume, +-#endif + .fetch_cal_eeprom = ath10k_pci_hif_fetch_cal_eeprom, + }; + diff --git a/root/package/kernel/mac80211/patches/301-v4.15-mac80211-properly-free-requested-but-not-started-TX-.patch b/root/package/kernel/mac80211/patches/301-v4.15-mac80211-properly-free-requested-but-not-started-TX-.patch new file mode 100644 index 00000000..ecc5e491 --- /dev/null +++ b/root/package/kernel/mac80211/patches/301-v4.15-mac80211-properly-free-requested-but-not-started-TX-.patch @@ -0,0 +1,37 @@ +From: Johannes Berg +Date: Mon, 20 Nov 2017 17:01:44 +0100 +Subject: [PATCH] mac80211: properly free requested-but-not-started TX agg + sessions + +When deleting a station or otherwise tearing down all aggregation +sessions, make sure to delete requested but not yet started ones, +to avoid the following scenario: + + * session is requested, added to tid_start_tx[] + * ieee80211_ba_session_work() runs, gets past BLOCK_BA check + * ieee80211_sta_tear_down_BA_sessions() runs, locks &sta->ampdu_mlme.mtx, + e.g. while deleting the station - deleting all active sessions + * ieee80211_ba_session_work() continues since tear down flushes it, and + calls ieee80211_tx_ba_session_handle_start() for the new session, arms + the timer for it + * station deletion continues to __cleanup_single_sta() and frees the + session struct, while the timer is armed + +Reported-by: Fengguang Wu +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -330,6 +330,11 @@ int ___ieee80211_stop_tx_ba_session(stru + + spin_lock_bh(&sta->lock); + ++ /* free struct pending for start, if present */ ++ tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; ++ kfree(tid_tx); ++ sta->ampdu_mlme.tid_start_tx[tid] = NULL; ++ + tid_tx = rcu_dereference_protected_tid_tx(sta, tid); + if (!tid_tx) { + spin_unlock_bh(&sta->lock); diff --git a/root/package/kernel/mac80211/patches/302-v4.15-mac80211-mesh-drop-frames-appearing-to-be-from-us.patch b/root/package/kernel/mac80211/patches/302-v4.15-mac80211-mesh-drop-frames-appearing-to-be-from-us.patch new file mode 100644 index 00000000..839e9278 --- /dev/null +++ b/root/package/kernel/mac80211/patches/302-v4.15-mac80211-mesh-drop-frames-appearing-to-be-from-us.patch @@ -0,0 +1,25 @@ +From: Johannes Berg +Date: Thu, 4 Jan 2018 15:51:53 +0100 +Subject: [PATCH] mac80211: mesh: drop frames appearing to be from us + +If there are multiple mesh stations with the same MAC address, +they will both get confused and start throwing warnings. + +Obviously in this case nothing can actually work anyway, so just +drop frames that look like they're from ourselves early on. + +Reported-by: Gui Iribarren +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3632,6 +3632,8 @@ static bool ieee80211_accept_frame(struc + } + return true; + case NL80211_IFTYPE_MESH_POINT: ++ if (ether_addr_equal(sdata->vif.addr, hdr->addr2)) ++ return false; + if (multicast) + return true; + return ether_addr_equal(sdata->vif.addr, hdr->addr1); diff --git a/root/package/kernel/mac80211/patches/303-v4.15-0001-brcmfmac-handle-FWHALT-mailbox-indication.patch b/root/package/kernel/mac80211/patches/303-v4.15-0001-brcmfmac-handle-FWHALT-mailbox-indication.patch new file mode 100644 index 00000000..b8f3be1c --- /dev/null +++ b/root/package/kernel/mac80211/patches/303-v4.15-0001-brcmfmac-handle-FWHALT-mailbox-indication.patch @@ -0,0 +1,60 @@ +From 2fd3877b5bb7d39782c3205a1dcda02023b8514a Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 8 Nov 2017 14:36:31 +0100 +Subject: [PATCH] brcmfmac: handle FWHALT mailbox indication + +The firmware uses a mailbox to communicate to the host what is going +on. In the driver we validate the bit received. Various people seen +the following message: + + brcmfmac: brcmf_sdio_hostmail: Unknown mailbox data content: 0x40012 + +Bit 4 is cause of this message, but this actually indicates the firmware +has halted. Handle this bit by giving a more meaningful error message. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -260,10 +260,11 @@ struct rte_console { + #define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */ + + /* tohostmailboxdata */ +-#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */ +-#define HMB_DATA_DEVREADY 2 /* talk to host after enable */ +-#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */ +-#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */ ++#define HMB_DATA_NAKHANDLED 0x0001 /* retransmit NAK'd frame */ ++#define HMB_DATA_DEVREADY 0x0002 /* talk to host after enable */ ++#define HMB_DATA_FC 0x0004 /* per prio flowcontrol update flag */ ++#define HMB_DATA_FWREADY 0x0008 /* fw ready for protocol activity */ ++#define HMB_DATA_FWHALT 0x0010 /* firmware halted */ + + #define HMB_DATA_FCDATA_MASK 0xff000000 + #define HMB_DATA_FCDATA_SHIFT 24 +@@ -1094,6 +1095,10 @@ static u32 brcmf_sdio_hostmail(struct br + offsetof(struct sdpcmd_regs, tosbmailbox)); + bus->sdcnt.f1regdata += 2; + ++ /* dongle indicates the firmware has halted/crashed */ ++ if (hmb_data & HMB_DATA_FWHALT) ++ brcmf_err("mailbox indicates firmware halted\n"); ++ + /* Dongle recomposed rx frames, accept them again */ + if (hmb_data & HMB_DATA_NAKHANDLED) { + brcmf_dbg(SDIO, "Dongle reports NAK handled, expect rtx of %d\n", +@@ -1151,6 +1156,7 @@ static u32 brcmf_sdio_hostmail(struct br + HMB_DATA_NAKHANDLED | + HMB_DATA_FC | + HMB_DATA_FWREADY | ++ HMB_DATA_FWHALT | + HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) + brcmf_err("Unknown mailbox data content: 0x%02x\n", + hmb_data); diff --git a/root/package/kernel/mac80211/patches/303-v4.15-0002-brcmfmac-disable-packet-filtering-in-promiscuous-mod.patch b/root/package/kernel/mac80211/patches/303-v4.15-0002-brcmfmac-disable-packet-filtering-in-promiscuous-mod.patch new file mode 100644 index 00000000..90166319 --- /dev/null +++ b/root/package/kernel/mac80211/patches/303-v4.15-0002-brcmfmac-disable-packet-filtering-in-promiscuous-mod.patch @@ -0,0 +1,133 @@ +From 6c219b0088158da839a5be63c5b3d96c145501d2 Mon Sep 17 00:00:00 2001 +From: Franky Lin +Date: Wed, 8 Nov 2017 14:36:32 +0100 +Subject: [PATCH] brcmfmac: disable packet filtering in promiscuous mode + +Disable arp and nd offload to allow all packets sending to host. + +Reported-by: Phil Elwell +Tested-by: Phil Elwell +Reviewed-by: Arend Van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 41 ---------------------- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 38 ++++++++++++++++++++ + .../wireless/broadcom/brcm80211/brcmfmac/core.h | 1 + + 3 files changed, 39 insertions(+), 41 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -472,47 +472,6 @@ send_key_to_dongle(struct brcmf_if *ifp, + return err; + } + +-static s32 +-brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) +-{ +- s32 err; +- u32 mode; +- +- if (enable) +- mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; +- else +- mode = 0; +- +- /* Try to set and enable ARP offload feature, this may fail, then it */ +- /* is simply not supported and err 0 will be returned */ +- err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); +- if (err) { +- brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", +- mode, err); +- err = 0; +- } else { +- err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); +- if (err) { +- brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", +- enable, err); +- err = 0; +- } else +- brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", +- enable, mode); +- } +- +- err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); +- if (err) { +- brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", +- enable, err); +- err = 0; +- } else +- brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", +- enable, mode); +- +- return err; +-} +- + static void + brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev) + { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -71,6 +71,43 @@ struct brcmf_if *brcmf_get_ifp(struct br + return ifp; + } + ++void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) ++{ ++ s32 err; ++ u32 mode; ++ ++ if (enable) ++ mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY; ++ else ++ mode = 0; ++ ++ /* Try to set and enable ARP offload feature, this may fail, then it */ ++ /* is simply not supported and err 0 will be returned */ ++ err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode); ++ if (err) { ++ brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n", ++ mode, err); ++ } else { ++ err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable); ++ if (err) { ++ brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n", ++ enable, err); ++ } else { ++ brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n", ++ enable, mode); ++ } ++ } ++ ++ err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); ++ if (err) { ++ brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", ++ enable, err); ++ } else { ++ brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", ++ enable, mode); ++ } ++} ++ + static void _brcmf_set_multicast_list(struct work_struct *work) + { + struct brcmf_if *ifp; +@@ -134,6 +171,7 @@ static void _brcmf_set_multicast_list(st + if (err < 0) + brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n", + err); ++ brcmf_configure_arp_nd_offload(ifp, !cmd_value); + } + + #if IS_ENABLED(CONFIG_IPV6) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -203,6 +203,7 @@ int brcmf_netdev_wait_pend8021x(struct b + /* Return pointer to interface name */ + char *brcmf_ifname(struct brcmf_if *ifp); + struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); ++void brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable); + int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, + bool is_p2pdev, const char *name, u8 *mac_addr); diff --git a/root/package/kernel/mac80211/patches/303-v4.15-0003-brcmfmac-cleanup-brcmf_cfg80211_escan-function.patch b/root/package/kernel/mac80211/patches/303-v4.15-0003-brcmfmac-cleanup-brcmf_cfg80211_escan-function.patch new file mode 100644 index 00000000..b6f3d0c6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/303-v4.15-0003-brcmfmac-cleanup-brcmf_cfg80211_escan-function.patch @@ -0,0 +1,133 @@ +From 8c6efda22f5f9f73fc948f517424466be01ae84d Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 8 Nov 2017 14:36:33 +0100 +Subject: [PATCH] brcmfmac: cleanup brcmf_cfg80211_escan() function + +The function brcmf_cfg80211_escan() was always called with a non-null +request parameter and null pointer for this_ssid parameter. Clean up +the function removing the dead code path. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 76 ++++------------------ + 1 file changed, 11 insertions(+), 65 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1072,18 +1072,10 @@ brcmf_do_escan(struct brcmf_if *ifp, str + + static s32 + brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, +- struct cfg80211_scan_request *request, +- struct cfg80211_ssid *this_ssid) ++ struct cfg80211_scan_request *request) + { +- struct brcmf_if *ifp = vif->ifp; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); +- struct cfg80211_ssid *ssids; +- u32 passive_scan; +- bool escan_req; +- bool spec_scan; + s32 err; +- struct brcmf_ssid_le ssid_le; +- u32 SSID_len; + + brcmf_dbg(SCAN, "START ESCAN\n"); + +@@ -1101,8 +1093,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy + cfg->scan_status); + return -EAGAIN; + } +- if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { +- brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state); ++ if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { ++ brcmf_err("Connecting: status (%lu)\n", vif->sme_state); + return -EAGAIN; + } + +@@ -1110,63 +1102,17 @@ brcmf_cfg80211_escan(struct wiphy *wiphy + if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) + vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; + +- escan_req = false; +- if (request) { +- /* scan bss */ +- ssids = request->ssids; +- escan_req = true; +- } else { +- /* scan in ibss */ +- /* we don't do escan in ibss */ +- ssids = this_ssid; +- } +- + cfg->scan_request = request; + set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); +- if (escan_req) { +- cfg->escan_info.run = brcmf_run_escan; +- err = brcmf_p2p_scan_prep(wiphy, request, vif); +- if (err) +- goto scan_out; +- +- err = brcmf_do_escan(vif->ifp, request); +- if (err) +- goto scan_out; +- } else { +- brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n", +- ssids->ssid, ssids->ssid_len); +- memset(&ssid_le, 0, sizeof(ssid_le)); +- SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len); +- ssid_le.SSID_len = cpu_to_le32(0); +- spec_scan = false; +- if (SSID_len) { +- memcpy(ssid_le.SSID, ssids->ssid, SSID_len); +- ssid_le.SSID_len = cpu_to_le32(SSID_len); +- spec_scan = true; +- } else +- brcmf_dbg(SCAN, "Broadcast scan\n"); +- +- passive_scan = cfg->active_scan ? 0 : 1; +- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, +- passive_scan); +- if (err) { +- brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err); +- goto scan_out; +- } +- brcmf_scan_config_mpc(ifp, 0); +- err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le, +- sizeof(ssid_le)); +- if (err) { +- if (err == -EBUSY) +- brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n", +- ssid_le.SSID); +- else +- brcmf_err("WLC_SCAN error (%d)\n", err); +- +- brcmf_scan_config_mpc(ifp, 1); +- goto scan_out; +- } +- } ++ ++ cfg->escan_info.run = brcmf_run_escan; ++ err = brcmf_p2p_scan_prep(wiphy, request, vif); ++ if (err) ++ goto scan_out; ++ ++ err = brcmf_do_escan(vif->ifp, request); ++ if (err) ++ goto scan_out; + + /* Arm scan timeout timer */ + mod_timer(&cfg->escan_timeout, jiffies + +@@ -1191,7 +1137,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, + if (!check_vif_up(vif)) + return -EIO; + +- err = brcmf_cfg80211_escan(wiphy, vif, request, NULL); ++ err = brcmf_cfg80211_escan(wiphy, vif, request); + + if (err) + brcmf_err("scan error (%d)\n", err); diff --git a/root/package/kernel/mac80211/patches/303-v4.15-0004-brcmfmac-use-msecs_to_jiffies-instead-of-calculation.patch b/root/package/kernel/mac80211/patches/303-v4.15-0004-brcmfmac-use-msecs_to_jiffies-instead-of-calculation.patch new file mode 100644 index 00000000..c2e3cba5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/303-v4.15-0004-brcmfmac-use-msecs_to_jiffies-instead-of-calculation.patch @@ -0,0 +1,31 @@ +From df2d8388bc96c0f29d27d121f2a4cd054f8b3900 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 8 Nov 2017 14:36:34 +0100 +Subject: [PATCH] brcmfmac: use msecs_to_jiffies() instead of calculation using + HZ + +Minor cleanup using provided macro to convert milliseconds interval +to jiffies in brcmf_cfg80211_escan(). + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1115,8 +1115,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy + goto scan_out; + + /* Arm scan timeout timer */ +- mod_timer(&cfg->escan_timeout, jiffies + +- BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); ++ mod_timer(&cfg->escan_timeout, ++ jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS)); + + return 0; + diff --git a/root/package/kernel/mac80211/patches/303-v4.15-0005-brcmfmac-get-rid-of-brcmf_cfg80211_escan-function.patch b/root/package/kernel/mac80211/patches/303-v4.15-0005-brcmfmac-get-rid-of-brcmf_cfg80211_escan-function.patch new file mode 100644 index 00000000..575ffb01 --- /dev/null +++ b/root/package/kernel/mac80211/patches/303-v4.15-0005-brcmfmac-get-rid-of-brcmf_cfg80211_escan-function.patch @@ -0,0 +1,83 @@ +From 588378f15cff285ac81c929239ccba01d7f71d50 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 8 Nov 2017 14:36:35 +0100 +Subject: [PATCH] brcmfmac: get rid of brcmf_cfg80211_escan() function + +The function brcmf_cfg80211_escan() is only called by brcmf_cfg80211_scan() +so there is no reason to split in two function especially since the latter +does not do an awful lot. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 34 +++++++--------------- + 1 file changed, 10 insertions(+), 24 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1071,13 +1071,16 @@ brcmf_do_escan(struct brcmf_if *ifp, str + } + + static s32 +-brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif, +- struct cfg80211_scan_request *request) ++brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); +- s32 err; ++ struct brcmf_cfg80211_vif *vif; ++ s32 err = 0; + +- brcmf_dbg(SCAN, "START ESCAN\n"); ++ brcmf_dbg(TRACE, "Enter\n"); ++ vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); ++ if (!check_vif_up(vif)) ++ return -EIO; + + if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { + brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); +@@ -1102,6 +1105,8 @@ brcmf_cfg80211_escan(struct wiphy *wiphy + if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) + vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; + ++ brcmf_dbg(SCAN, "START ESCAN\n"); ++ + cfg->scan_request = request; + set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + +@@ -1121,31 +1126,12 @@ brcmf_cfg80211_escan(struct wiphy *wiphy + return 0; + + scan_out: ++ brcmf_err("scan error (%d)\n", err); + clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + cfg->scan_request = NULL; + return err; + } + +-static s32 +-brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) +-{ +- struct brcmf_cfg80211_vif *vif; +- s32 err = 0; +- +- brcmf_dbg(TRACE, "Enter\n"); +- vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev); +- if (!check_vif_up(vif)) +- return -EIO; +- +- err = brcmf_cfg80211_escan(wiphy, vif, request); +- +- if (err) +- brcmf_err("scan error (%d)\n", err); +- +- brcmf_dbg(TRACE, "Exit\n"); +- return err; +-} +- + static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) + { + s32 err = 0; diff --git a/root/package/kernel/mac80211/patches/303-v4.15-0006-brcmfmac-get-rid-of-struct-brcmf_cfg80211_info-activ.patch b/root/package/kernel/mac80211/patches/303-v4.15-0006-brcmfmac-get-rid-of-struct-brcmf_cfg80211_info-activ.patch new file mode 100644 index 00000000..4d4235f4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/303-v4.15-0006-brcmfmac-get-rid-of-struct-brcmf_cfg80211_info-activ.patch @@ -0,0 +1,86 @@ +From bbf35414cd23a9d7230bfd7046e1e2c26020e7eb Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 8 Nov 2017 14:36:36 +0100 +Subject: [PATCH] brcmfmac: get rid of struct brcmf_cfg80211_info::active_scan + field + +The field struct brcmf_cfg80211_info::active_scan is set to true upon +initializing the driver instance, but it is never changed so simply +get rid of it. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 +--------- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 2 -- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 5 +---- + 3 files changed, 2 insertions(+), 15 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1043,7 +1043,6 @@ brcmf_do_escan(struct brcmf_if *ifp, str + { + struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + s32 err; +- u32 passive_scan; + struct brcmf_scan_results *results; + struct escan_info *escan = &cfg->escan_info; + +@@ -1051,13 +1050,7 @@ brcmf_do_escan(struct brcmf_if *ifp, str + escan->ifp = ifp; + escan->wiphy = cfg->wiphy; + escan->escan_state = WL_ESCAN_STATE_SCANNING; +- passive_scan = cfg->active_scan ? 0 : 1; +- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, +- passive_scan); +- if (err) { +- brcmf_err("error (%d)\n", err); +- return err; +- } ++ + brcmf_scan_config_mpc(ifp, 0); + results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; + results->version = 0; +@@ -5767,7 +5760,6 @@ static s32 wl_init_priv(struct brcmf_cfg + + cfg->scan_request = NULL; + cfg->pwr_save = true; +- cfg->active_scan = true; /* we do active scan per default */ + cfg->dongle_up = false; /* dongle is not up yet */ + err = brcmf_init_priv_mem(cfg); + if (err) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -283,7 +283,6 @@ struct brcmf_cfg80211_wowl { + * @scan_status: scan activity on the dongle. + * @pub: common driver information. + * @channel: current channel. +- * @active_scan: current scan mode. + * @int_escan_map: bucket map for which internal e-scan is done. + * @ibss_starter: indicates this sta is ibss starter. + * @pwr_save: indicate whether dongle to support power save mode. +@@ -316,7 +315,6 @@ struct brcmf_cfg80211_info { + unsigned long scan_status; + struct brcmf_pub *pub; + u32 channel; +- bool active_scan; + u32 int_escan_map; + bool ibss_starter; + bool pwr_save; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -692,10 +692,7 @@ static s32 brcmf_p2p_escan(struct brcmf_ + + /* determine the scan engine parameters */ + sparams->bss_type = DOT11_BSSTYPE_ANY; +- if (p2p->cfg->active_scan) +- sparams->scan_type = 0; +- else +- sparams->scan_type = 1; ++ sparams->scan_type = BRCMF_SCANTYPE_ACTIVE; + + eth_broadcast_addr(sparams->bssid); + sparams->home_time = cpu_to_le32(P2PAPI_SCAN_HOME_TIME_MS); diff --git a/root/package/kernel/mac80211/patches/303-v4.15-0007-brcmfmac-move-configuration-of-probe-request-IEs.patch b/root/package/kernel/mac80211/patches/303-v4.15-0007-brcmfmac-move-configuration-of-probe-request-IEs.patch new file mode 100644 index 00000000..3ad6e79d --- /dev/null +++ b/root/package/kernel/mac80211/patches/303-v4.15-0007-brcmfmac-move-configuration-of-probe-request-IEs.patch @@ -0,0 +1,55 @@ +From bd99a3013bdc00f8fc7534c657b39616792b4467 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 8 Nov 2017 14:36:37 +0100 +Subject: [PATCH] brcmfmac: move configuration of probe request IEs + +The configuration of the IEs for probe requests was done in a P2P +related function, which is not very obvious. Moving it to +.scan callback function, ie. brcmf_cfg80211_scan(). + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 6 ++---- + 2 files changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1108,6 +1108,11 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, + if (err) + goto scan_out; + ++ err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, ++ request->ie, request->ie_len); ++ if (err) ++ goto scan_out; ++ + err = brcmf_do_escan(vif->ifp, request); + if (err) + goto scan_out; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -881,7 +881,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wi + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_p2p_info *p2p = &cfg->p2p; +- int err = 0; ++ int err; + + if (brcmf_p2p_scan_is_p2p_request(request)) { + /* find my listen channel */ +@@ -904,9 +904,7 @@ int brcmf_p2p_scan_prep(struct wiphy *wi + /* override .run_escan() callback. */ + cfg->escan_info.run = brcmf_p2p_run_escan; + } +- err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, +- request->ie, request->ie_len); +- return err; ++ return 0; + } + + diff --git a/root/package/kernel/mac80211/patches/304-v4.15-brcmfmac-add-CLM-download-support.patch b/root/package/kernel/mac80211/patches/304-v4.15-brcmfmac-add-CLM-download-support.patch new file mode 100644 index 00000000..2cd5f731 --- /dev/null +++ b/root/package/kernel/mac80211/patches/304-v4.15-brcmfmac-add-CLM-download-support.patch @@ -0,0 +1,434 @@ +From fdd0bd88ceaecf729db103ac8836af5805dd2dc1 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Fri, 10 Nov 2017 17:27:15 +0800 +Subject: [PATCH] brcmfmac: add CLM download support + +The firmware for brcmfmac devices includes information regarding +regulatory constraints. For certain devices this information is kept +separately in a binary form that needs to be downloaded to the device. +This patch adds support to download this so-called CLM blob file. It +uses the same naming scheme as the other firmware files with extension +of .clm_blob. + +The CLM blob file is optional. If the file does not exist, the download +process will be bypassed. It will not affect the driver loading. + +Reviewed-by: Arend van Spriel +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 10 ++ + .../wireless/broadcom/brcm80211/brcmfmac/common.c | 157 +++++++++++++++++++++ + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 2 + + .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 + + .../broadcom/brcm80211/brcmfmac/fwil_types.h | 31 ++++ + .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 19 +++ + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 19 +++ + .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 18 +++ + 8 files changed, 258 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -71,6 +71,7 @@ struct brcmf_bus_dcmd { + * @wowl_config: specify if dongle is configured for wowl when going to suspend + * @get_ramsize: obtain size of device memory. + * @get_memdump: obtain device memory dump in provided buffer. ++ * @get_fwname: obtain firmware name. + * + * This structure provides an abstract interface towards the + * bus specific driver. For control messages to common driver +@@ -87,6 +88,8 @@ struct brcmf_bus_ops { + void (*wowl_config)(struct device *dev, bool enabled); + size_t (*get_ramsize)(struct device *dev); + int (*get_memdump)(struct device *dev, void *data, size_t len); ++ int (*get_fwname)(struct device *dev, uint chip, uint chiprev, ++ unsigned char *fw_name); + }; + + +@@ -224,6 +227,13 @@ int brcmf_bus_get_memdump(struct brcmf_b + return bus->ops->get_memdump(bus->dev, data, len); + } + ++static inline ++int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev, ++ unsigned char *fw_name) ++{ ++ return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name); ++} ++ + /* + * interface functions from common layer + */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include "core.h" +@@ -28,6 +29,7 @@ + #include "tracepoint.h" + #include "common.h" + #include "of.h" ++#include "firmware.h" + + MODULE_AUTHOR("Broadcom Corporation"); + MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); +@@ -104,12 +106,140 @@ void brcmf_c_set_joinpref_default(struct + brcmf_err("Set join_pref error (%d)\n", err); + } + ++static int brcmf_c_download(struct brcmf_if *ifp, u16 flag, ++ struct brcmf_dload_data_le *dload_buf, ++ u32 len) ++{ ++ s32 err; ++ ++ flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT); ++ dload_buf->flag = cpu_to_le16(flag); ++ dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM); ++ dload_buf->len = cpu_to_le32(len); ++ dload_buf->crc = cpu_to_le32(0); ++ len = sizeof(*dload_buf) + len - 1; ++ ++ err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len); ++ ++ return err; ++} ++ ++static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) ++{ ++ struct brcmf_bus *bus = ifp->drvr->bus_if; ++ struct brcmf_rev_info *ri = &ifp->drvr->revinfo; ++ u8 fw_name[BRCMF_FW_NAME_LEN]; ++ u8 *ptr; ++ size_t len; ++ s32 err; ++ ++ memset(fw_name, 0, BRCMF_FW_NAME_LEN); ++ err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name); ++ if (err) { ++ brcmf_err("get firmware name failed (%d)\n", err); ++ goto done; ++ } ++ ++ /* generate CLM blob file name */ ++ ptr = strrchr(fw_name, '.'); ++ if (!ptr) { ++ err = -ENOENT; ++ goto done; ++ } ++ ++ len = ptr - fw_name + 1; ++ if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) { ++ err = -E2BIG; ++ } else { ++ strlcpy(clm_name, fw_name, len); ++ strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN); ++ } ++done: ++ return err; ++} ++ ++static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) ++{ ++ struct device *dev = ifp->drvr->bus_if->dev; ++ struct brcmf_dload_data_le *chunk_buf; ++ const struct firmware *clm = NULL; ++ u8 clm_name[BRCMF_FW_NAME_LEN]; ++ u32 chunk_len; ++ u32 datalen; ++ u32 cumulative_len; ++ u16 dl_flag = DL_BEGIN; ++ u32 status; ++ s32 err; ++ ++ brcmf_dbg(TRACE, "Enter\n"); ++ ++ memset(clm_name, 0, BRCMF_FW_NAME_LEN); ++ err = brcmf_c_get_clm_name(ifp, clm_name); ++ if (err) { ++ brcmf_err("get CLM blob file name failed (%d)\n", err); ++ return err; ++ } ++ ++ err = request_firmware(&clm, clm_name, dev); ++ if (err) { ++ if (err == -ENOENT) { ++ brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n"); ++ return 0; ++ } ++ brcmf_err("request CLM blob file failed (%d)\n", err); ++ return err; ++ } ++ ++ chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL); ++ if (!chunk_buf) { ++ err = -ENOMEM; ++ goto done; ++ } ++ ++ datalen = clm->size; ++ cumulative_len = 0; ++ do { ++ if (datalen > MAX_CHUNK_LEN) { ++ chunk_len = MAX_CHUNK_LEN; ++ } else { ++ chunk_len = datalen; ++ dl_flag |= DL_END; ++ } ++ memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len); ++ ++ err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len); ++ ++ dl_flag &= ~DL_BEGIN; ++ ++ cumulative_len += chunk_len; ++ datalen -= chunk_len; ++ } while ((datalen > 0) && (err == 0)); ++ ++ if (err) { ++ brcmf_err("clmload (%zu byte file) failed (%d); ", ++ clm->size, err); ++ /* Retrieve clmload_status and print */ ++ err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status); ++ if (err) ++ brcmf_err("get clmload_status failed (%d)\n", err); ++ else ++ brcmf_dbg(INFO, "clmload_status=%d\n", status); ++ err = -EIO; ++ } ++ ++ kfree(chunk_buf); ++done: ++ release_firmware(clm); ++ return err; ++} ++ + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) + { + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + u8 buf[BRCMF_DCMD_SMLEN]; + struct brcmf_rev_info_le revinfo; + struct brcmf_rev_info *ri; ++ char *clmver; + char *ptr; + s32 err; + +@@ -148,6 +278,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + } + ri->result = err; + ++ /* Do any CLM downloading */ ++ err = brcmf_c_process_clm_blob(ifp); ++ if (err < 0) { ++ brcmf_err("download CLM blob file failed, %d\n", err); ++ goto done; ++ } ++ + /* query for 'ver' to get version info from firmware */ + memset(buf, 0, sizeof(buf)); + strcpy(buf, "ver"); +@@ -167,6 +304,26 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + ptr = strrchr(buf, ' ') + 1; + strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); + ++ /* Query for 'clmver' to get CLM version info from firmware */ ++ memset(buf, 0, sizeof(buf)); ++ err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf)); ++ if (err) { ++ brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err); ++ } else { ++ clmver = (char *)buf; ++ /* store CLM version for adding it to revinfo debugfs file */ ++ memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver)); ++ ++ /* Replace all newline/linefeed characters with space ++ * character ++ */ ++ ptr = clmver; ++ while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL) ++ *ptr = ' '; ++ ++ brcmf_dbg(INFO, "CLM version = %s\n", clmver); ++ } ++ + /* set mpc */ + err = brcmf_fil_iovar_int_set(ifp, "mpc", 1); + if (err) { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1009,6 +1009,8 @@ static int brcmf_revinfo_read(struct seq + seq_printf(s, "anarev: %u\n", ri->anarev); + seq_printf(s, "nvramrev: %08x\n", ri->nvramrev); + ++ seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver); ++ + return 0; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -141,6 +141,8 @@ struct brcmf_pub { + struct notifier_block inetaddr_notifier; + struct notifier_block inet6addr_notifier; + struct brcmf_mp_device *settings; ++ ++ u8 clmver[BRCMF_DCMD_SMLEN]; + }; + + /* forward declarations */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -155,6 +155,21 @@ + #define BRCMF_MFP_CAPABLE 1 + #define BRCMF_MFP_REQUIRED 2 + ++/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each ++ * ioctl. It is relatively small because firmware has small maximum size input ++ * playload restriction for ioctls. ++ */ ++#define MAX_CHUNK_LEN 1400 ++ ++#define DLOAD_HANDLER_VER 1 /* Downloader version */ ++#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */ ++#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */ ++ ++#define DL_BEGIN 0x0002 ++#define DL_END 0x0004 ++ ++#define DL_TYPE_CLM 2 ++ + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { + BRCMF_JOIN_PREF_RSSI = 1, +@@ -827,6 +842,22 @@ struct brcmf_pno_macaddr_le { + }; + + /** ++ * struct brcmf_dload_data_le - data passing to firmware for downloading ++ * @flag: flags related to download data. ++ * @dload_type: type of download data. ++ * @len: length in bytes of download data. ++ * @crc: crc of download data. ++ * @data: download data. ++ */ ++struct brcmf_dload_data_le { ++ __le16 flag; ++ __le16 dload_type; ++ __le32 len; ++ __le32 crc; ++ u8 data[1]; ++}; ++ ++/** + * struct brcmf_pno_bssid_le - bssid configuration for PNO scan. + * + * @bssid: BSS network identifier. +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1350,6 +1350,24 @@ static int brcmf_pcie_get_memdump(struct + return 0; + } + ++static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev, ++ u8 *fw_name) ++{ ++ 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; ++ int ret = 0; ++ ++ if (devinfo->fw_name[0] != '\0') ++ strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); ++ else ++ ret = brcmf_fw_map_chip_to_name(chip, chiprev, ++ brcmf_pcie_fwnames, ++ ARRAY_SIZE(brcmf_pcie_fwnames), ++ fw_name, NULL); ++ ++ return ret; ++} + + static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { + .txdata = brcmf_pcie_tx, +@@ -1359,6 +1377,7 @@ static const struct brcmf_bus_ops brcmf_ + .wowl_config = brcmf_pcie_wowl_config, + .get_ramsize = brcmf_pcie_get_ramsize, + .get_memdump = brcmf_pcie_get_memdump, ++ .get_fwname = brcmf_pcie_get_fwname, + }; + + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3985,6 +3985,24 @@ brcmf_sdio_watchdog(unsigned long data) + } + } + ++static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev, ++ u8 *fw_name) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; ++ int ret = 0; ++ ++ if (sdiodev->fw_name[0] != '\0') ++ strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN); ++ else ++ ret = brcmf_fw_map_chip_to_name(chip, chiprev, ++ brcmf_sdio_fwnames, ++ ARRAY_SIZE(brcmf_sdio_fwnames), ++ fw_name, NULL); ++ ++ return ret; ++} ++ + static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { + .stop = brcmf_sdio_bus_stop, + .preinit = brcmf_sdio_bus_preinit, +@@ -3995,6 +4013,7 @@ static const struct brcmf_bus_ops brcmf_ + .wowl_config = brcmf_sdio_wowl_config, + .get_ramsize = brcmf_sdio_bus_get_ramsize, + .get_memdump = brcmf_sdio_bus_get_memdump, ++ .get_fwname = brcmf_sdio_get_fwname, + }; + + static void brcmf_sdio_firmware_callback(struct device *dev, int err, +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1128,12 +1128,30 @@ static void brcmf_usb_wowl_config(struct + device_set_wakeup_enable(devinfo->dev, false); + } + ++static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev, ++ u8 *fw_name) ++{ ++ struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); ++ int ret = 0; ++ ++ if (devinfo->fw_name[0] != '\0') ++ strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); ++ else ++ ret = brcmf_fw_map_chip_to_name(chip, chiprev, ++ brcmf_usb_fwnames, ++ ARRAY_SIZE(brcmf_usb_fwnames), ++ fw_name, NULL); ++ ++ return ret; ++} ++ + static const struct brcmf_bus_ops brcmf_usb_bus_ops = { + .txdata = brcmf_usb_tx, + .stop = brcmf_usb_down, + .txctl = brcmf_usb_tx_ctlpkt, + .rxctl = brcmf_usb_rx_ctlpkt, + .wowl_config = brcmf_usb_wowl_config, ++ .get_fwname = brcmf_usb_get_fwname, + }; + + static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) diff --git a/root/package/kernel/mac80211/patches/305-v4.15-brcmfmac-change-driver-unbind-order-of-the-sdio-func.patch b/root/package/kernel/mac80211/patches/305-v4.15-brcmfmac-change-driver-unbind-order-of-the-sdio-func.patch new file mode 100644 index 00000000..3649bdda --- /dev/null +++ b/root/package/kernel/mac80211/patches/305-v4.15-brcmfmac-change-driver-unbind-order-of-the-sdio-func.patch @@ -0,0 +1,37 @@ +From 5c3de777bdaf48bd0cfb43097c0d0fb85056cab7 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Sat, 25 Nov 2017 21:39:25 +0100 +Subject: [PATCH] brcmfmac: change driver unbind order of the sdio function + devices + +In the function brcmf_sdio_firmware_callback() the driver is +unbound from the sdio function devices in the error path. +However, the order in which it is done resulted in a use-after-free +issue (see brcmf_ops_sdio_remove() in bcmsdh.c). Hence change +the order and first unbind sdio function #2 device and then +unbind sdio function #1 device. + +Cc: stable@vger.kernel.org # v4.12.x +Fixes: 7a51461fc2da ("brcmfmac: unbind all devices upon failure in firmware callback") +Reported-by: Stefan Wahren +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4121,8 +4121,8 @@ release: + sdio_release_host(sdiodev->func[1]); + fail: + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); +- device_release_driver(dev); + device_release_driver(&sdiodev->func[2]->dev); ++ device_release_driver(dev); + } + + struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) diff --git a/root/package/kernel/mac80211/patches/306-v4.15-brcmfmac-Avoid-build-error-with-make-W-1.patch b/root/package/kernel/mac80211/patches/306-v4.15-brcmfmac-Avoid-build-error-with-make-W-1.patch new file mode 100644 index 00000000..7344580d --- /dev/null +++ b/root/package/kernel/mac80211/patches/306-v4.15-brcmfmac-Avoid-build-error-with-make-W-1.patch @@ -0,0 +1,33 @@ +From 51ef7925e10688c57186d438e784532e063492e4 Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Thu, 23 Nov 2017 17:57:04 +0200 +Subject: [PATCH] brcmfmac: Avoid build error with make W=1 + +When I run make W=1 on gcc (Debian 7.2.0-16) 7.2.0 I got an error for +the first run, all next ones are okay. + + CC [M] drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o +drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:2078: error: Cannot parse struct or union! +scripts/Makefile.build:310: recipe for target 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o' failed + +Seems like something happened with W=1 and wrong kernel doc format. +As a quick fix remove dubious /** in the code. + +Signed-off-by: Andy Shevchenko +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -2070,7 +2070,7 @@ static int brcmf_sdio_txpkt_hdalign(stru + return head_pad; + } + +-/** ++/* + * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for + * bus layer usage. + */ diff --git a/root/package/kernel/mac80211/patches/307-v4.15-brcmfmac-fix-CLM-load-error-for-legacy-chips-when-us.patch b/root/package/kernel/mac80211/patches/307-v4.15-brcmfmac-fix-CLM-load-error-for-legacy-chips-when-us.patch new file mode 100644 index 00000000..ead5e721 --- /dev/null +++ b/root/package/kernel/mac80211/patches/307-v4.15-brcmfmac-fix-CLM-load-error-for-legacy-chips-when-us.patch @@ -0,0 +1,40 @@ +From cc124d5cc8d81985c3511892d7a6d546552ff754 Mon Sep 17 00:00:00 2001 +From: Wright Feng +Date: Tue, 16 Jan 2018 17:26:50 +0800 +Subject: [PATCH] brcmfmac: fix CLM load error for legacy chips when user + helper is enabled + +For legacy chips without CLM blob files, kernel with user helper function +returns -EAGAIN when we request_firmware(), and then driver got failed +when bringing up legacy chips. We expect the CLM blob file for legacy chip +is not existence in firmware path, but the -ENOENT error is transferred to +-EAGAIN in firmware_class.c with user helper. +Because of that, we continue with CLM data currently present in firmware +if getting error from doing request_firmware(). + +Cc: stable@vger.kernel.org # v4.15.y +Reviewed-by: Arend van Spriel +Signed-off-by: Wright Feng +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -182,12 +182,9 @@ static int brcmf_c_process_clm_blob(stru + + err = request_firmware(&clm, clm_name, dev); + if (err) { +- if (err == -ENOENT) { +- brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n"); +- return 0; +- } +- brcmf_err("request CLM blob file failed (%d)\n", err); +- return err; ++ brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n", ++ err); ++ return 0; + } + + chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL); diff --git a/root/package/kernel/mac80211/patches/308-v4.16-0001-ath9k-move-spectral-scan-support-under-a-separate-co.patch b/root/package/kernel/mac80211/patches/308-v4.16-0001-ath9k-move-spectral-scan-support-under-a-separate-co.patch new file mode 100644 index 00000000..703051fe --- /dev/null +++ b/root/package/kernel/mac80211/patches/308-v4.16-0001-ath9k-move-spectral-scan-support-under-a-separate-co.patch @@ -0,0 +1,103 @@ +From 9df7ddc3ed25b7d3473f117a0680b9418adb5753 Mon Sep 17 00:00:00 2001 +Message-Id: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net> +From: Matthias Schiffer +Date: Mon, 27 Nov 2017 18:56:22 +0100 +Subject: [PATCH 1/2] ath9k: move spectral scan support under a separate config + symbol + +At the moment, spectral scan support, and with it RELAY, is always enabled +with ATH9K[_HTC]_DEBUGFS. Spectral scan support is currently the only user +of RELAY in ath9k, and it unconditionally reserves a relay channel. + +Having debugfs support in ath9k is often useful even on very small embedded +routers, where we'd rather like to avoid the code size and RAM usage of the +relay support. + +Signed-off-by: Matthias Schiffer +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath9k/Kconfig | 14 ++++++++++---- + drivers/net/wireless/ath/ath9k/Makefile | 4 ++-- + drivers/net/wireless/ath/ath9k/common-spectral.h | 4 ++-- + 3 files changed, 14 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/Kconfig ++++ b/drivers/net/wireless/ath/ath9k/Kconfig +@@ -64,13 +64,12 @@ config ATH9K_DEBUGFS + depends on ATH9K && DEBUG_FS + select MAC80211_DEBUGFS + select ATH9K_COMMON_DEBUG +- depends on RELAY + ---help--- + Say Y, if you need access to ath9k's statistics for + interrupts, rate control, etc. + +- Also required for changing debug message flags at run time. +- As well as access to the FFT/spectral data and TX99. ++ Also required for changing debug message flags at run time and for ++ TX99. + + config ATH9K_STATION_STATISTICS + bool "Detailed station statistics" +@@ -181,7 +180,6 @@ config ATH9K_HTC_DEBUGFS + bool "Atheros ath9k_htc debugging" + depends on ATH9K_HTC && DEBUG_FS + select ATH9K_COMMON_DEBUG +- depends on RELAY + ---help--- + Say Y, if you need access to ath9k_htc's statistics. + As well as access to the FFT/spectral data. +@@ -197,3 +195,11 @@ config ATH9K_HWRNG + + Say Y, feeds the entropy directly from the WiFi driver to the input + pool. ++ ++config ATH9K_COMMON_SPECTRAL ++ bool "Atheros ath9k/ath9k_htc spectral scan support" ++ depends on ATH9K_DEBUGFS || ATH9K_HTC_DEBUGFS ++ depends on RELAY ++ default n ++ ---help--- ++ Say Y to enable access to the FFT/spectral data via debugfs. +--- a/drivers/net/wireless/ath/ath9k/Makefile ++++ b/drivers/net/wireless/ath/ath9k/Makefile +@@ -61,8 +61,8 @@ ath9k_common-y:= common.o \ + common-init.o \ + common-beacon.o \ + +-ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o \ +- common-spectral.o ++ath9k_common-$(CPTCFG_ATH9K_COMMON_DEBUG) += common-debug.o ++ath9k_common-$(CPTCFG_ATH9K_COMMON_SPECTRAL) += common-spectral.o + + ath9k_htc-y += htc_hst.o \ + hif_usb.o \ +--- a/drivers/net/wireless/ath/ath9k/common-spectral.h ++++ b/drivers/net/wireless/ath/ath9k/common-spectral.h +@@ -151,7 +151,7 @@ static inline u8 spectral_bitmap_weight( + return bins[0] & 0x3f; + } + +-#ifdef CPTCFG_ATH9K_COMMON_DEBUG ++#ifdef CPTCFG_ATH9K_COMMON_SPECTRAL + void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy); + void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv); + +@@ -183,6 +183,6 @@ static inline int ath_cmn_process_fft(st + { + return 0; + } +-#endif /* CPTCFG_ATH9K_COMMON_DEBUG */ ++#endif /* CPTCFG_ATH9K_COMMON_SPECTRAL */ + + #endif /* SPECTRAL_H */ +--- a/local-symbols ++++ b/local-symbols +@@ -116,6 +116,7 @@ ATH9K_PCOEM= + ATH9K_HTC= + ATH9K_HTC_DEBUGFS= + ATH9K_HWRNG= ++ATH9K_COMMON_SPECTRAL= + CARL9170= + CARL9170_LEDS= + CARL9170_DEBUGFS= diff --git a/root/package/kernel/mac80211/patches/309-v4.16-0002-ath10k-move-spectral-scan-support-under-a-separate-c.patch b/root/package/kernel/mac80211/patches/309-v4.16-0002-ath10k-move-spectral-scan-support-under-a-separate-c.patch new file mode 100644 index 00000000..9eefdbce --- /dev/null +++ b/root/package/kernel/mac80211/patches/309-v4.16-0002-ath10k-move-spectral-scan-support-under-a-separate-c.patch @@ -0,0 +1,91 @@ +From 42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61 Mon Sep 17 00:00:00 2001 +Message-Id: <42e01cb9cb109fb0bb4743f6c54d6aa67ac39b61.1515610034.git.mschiffer@universe-factory.net> +In-Reply-To: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net> +References: <9df7ddc3ed25b7d3473f117a0680b9418adb5753.1515610034.git.mschiffer@universe-factory.net> +From: Matthias Schiffer +Date: Mon, 27 Nov 2017 18:56:23 +0100 +Subject: [PATCH 2/2] ath10k: move spectral scan support under a separate + config symbol + +At the moment, spectral scan support, and with it RELAY, is always enabled +with ATH10K_DEBUGFS. Spectral scan support is currently the only user of +RELAY in ath10k, and it unconditionally reserves a relay channel. + +Having debugfs support in ath10k is often useful even on very small +embedded routers, where we'd rather like to avoid the code size and RAM +usage of the relay support. While ath10k-based devices usually have more +resources than ath9k-based ones, it makes sense to keep the configuration +symmetric to ath9k, so the same base kernel without RELAY can be used for +both ath9k and ath10k hardware. + +Signed-off-by: Matthias Schiffer +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath10k/Kconfig | 9 ++++++++- + drivers/net/wireless/ath/ath10k/Makefile | 2 +- + drivers/net/wireless/ath/ath10k/spectral.h | 4 ++-- + 3 files changed, 11 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/Kconfig ++++ b/drivers/net/wireless/ath/ath10k/Kconfig +@@ -51,12 +51,19 @@ config ATH10K_DEBUG + config ATH10K_DEBUGFS + bool "Atheros ath10k debugfs support" + depends on ATH10K && DEBUG_FS +- depends on RELAY + ---help--- + Enabled debugfs support + + If unsure, say Y to make it easier to debug problems. + ++config ATH10K_SPECTRAL ++ bool "Atheros ath10k spectral scan support" ++ depends on ATH10K_DEBUGFS ++ depends on RELAY ++ default n ++ ---help--- ++ Say Y to enable access to the FFT/spectral data via debugfs. ++ + config ATH10K_TRACING + depends on !KERNEL_3_4 + bool "Atheros ath10k tracing support" +--- a/drivers/net/wireless/ath/ath10k/Makefile ++++ b/drivers/net/wireless/ath/ath10k/Makefile +@@ -14,7 +14,7 @@ ath10k_core-y += mac.o \ + p2p.o \ + swap.o + +-ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o ++ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o + ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o + ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o + ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o +--- a/drivers/net/wireless/ath/ath10k/spectral.h ++++ b/drivers/net/wireless/ath/ath10k/spectral.h +@@ -44,7 +44,7 @@ enum ath10k_spectral_mode { + SPECTRAL_MANUAL, + }; + +-#ifdef CPTCFG_ATH10K_DEBUGFS ++#ifdef CPTCFG_ATH10K_SPECTRAL + + int ath10k_spectral_process_fft(struct ath10k *ar, + struct wmi_phyerr_ev_arg *phyerr, +@@ -85,6 +85,6 @@ static inline void ath10k_spectral_destr + { + } + +-#endif /* CPTCFG_ATH10K_DEBUGFS */ ++#endif /* CPTCFG_ATH10K_SPECTRAL */ + + #endif /* SPECTRAL_H */ +--- a/local-symbols ++++ b/local-symbols +@@ -140,6 +140,7 @@ ATH10K_SDIO= + ATH10K_USB= + ATH10K_DEBUG= + ATH10K_DEBUGFS= ++ATH10K_SPECTRAL= + ATH10K_THERMAL= + ATH10K_TRACING= + ATH10K_DFS_CERTIFIED= diff --git a/root/package/kernel/mac80211/patches/310-v4.16-ath9k-discard-undersized-packets.patch b/root/package/kernel/mac80211/patches/310-v4.16-ath9k-discard-undersized-packets.patch new file mode 100644 index 00000000..b2b2fcf4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/310-v4.16-ath9k-discard-undersized-packets.patch @@ -0,0 +1,25 @@ +From: Felix Fietkau +Date: Wed, 17 Jan 2018 11:11:17 +0100 +Subject: [PATCH] ath9k: discard undersized packets + +Sometimes the hardware will push small packets that trigger a WARN_ON +in mac80211. Discard them early to avoid this issue. + +Reported-by: Stijn Tintel +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -826,9 +826,9 @@ static int ath9k_rx_skb_preprocess(struc + sc->rx.discard_next = false; + + /* +- * Discard zero-length packets. ++ * Discard zero-length packets and packets smaller than an ACK + */ +- if (!rx_stats->rs_datalen) { ++ if (rx_stats->rs_datalen < 10) { + RX_STAT_INC(rx_len_err); + goto corrupt; + } diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0001-brcmfmac-Fix-parameter-order-in-brcmf_sdiod_f0_write.patch b/root/package/kernel/mac80211/patches/311-v4.16-0001-brcmfmac-Fix-parameter-order-in-brcmf_sdiod_f0_write.patch new file mode 100644 index 00000000..616a8211 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0001-brcmfmac-Fix-parameter-order-in-brcmf_sdiod_f0_write.patch @@ -0,0 +1,39 @@ +From 1fd3ae124d5e675f57cf7e3c601fb8f7712e0329 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:38 +0100 +Subject: [PATCH] brcmfmac: Fix parameter order in brcmf_sdiod_f0_writeb() + +All the other IO functions are the other way round in this +driver. Make this one match. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -230,8 +230,8 @@ void brcmf_sdiod_change_state(struct brc + sdiodev->state = state; + } + +-static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, +- uint regaddr, u8 byte) ++static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte, ++ uint regaddr) + { + int err_ret; + +@@ -269,8 +269,8 @@ static int brcmf_sdiod_request_data(stru + if (fn) + sdio_writeb(func, *(u8 *)data, addr, &ret); + else +- ret = brcmf_sdiod_f0_writeb(func, addr, +- *(u8 *)data); ++ ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data, ++ addr); + } else { + if (fn) + *(u8 *)data = sdio_readb(func, addr, &ret); diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0002-brcmfmac-Register-sizes-on-hardware-are-not-dependen.patch b/root/package/kernel/mac80211/patches/311-v4.16-0002-brcmfmac-Register-sizes-on-hardware-are-not-dependen.patch new file mode 100644 index 00000000..719268f8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0002-brcmfmac-Register-sizes-on-hardware-are-not-dependen.patch @@ -0,0 +1,105 @@ +From 1e6f676f43aa4270ebc5cff8e32a55f72362e042 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:39 +0100 +Subject: [PATCH] brcmfmac: Register sizes on hardware are not dependent on + compiler types + +The 4 IO functions in this patch are incorrect as they use compiler types +to determine how many bytes to send to the hardware. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -264,7 +264,7 @@ static int brcmf_sdiod_request_data(stru + func = sdiodev->func[fn]; + + switch (regsz) { +- case sizeof(u8): ++ case 1: + if (write) { + if (fn) + sdio_writeb(func, *(u8 *)data, addr, &ret); +@@ -278,13 +278,13 @@ static int brcmf_sdiod_request_data(stru + *(u8 *)data = sdio_f0_readb(func, addr, &ret); + } + break; +- case sizeof(u16): ++ case 2: + if (write) + sdio_writew(func, *(u16 *)data, addr, &ret); + else + *(u16 *)data = sdio_readw(func, addr, &ret); + break; +- case sizeof(u32): ++ case 4: + if (write) + sdio_writel(func, *(u32 *)data, addr, &ret); + else +@@ -368,7 +368,7 @@ brcmf_sdiod_set_sbaddr_window(struct brc + for (i = 0; i < 3; i++) { + err = brcmf_sdiod_regrw_helper(sdiodev, + SBSDIO_FUNC1_SBADDRLOW + i, +- sizeof(u8), &addr[i], true); ++ 1, &addr[i], true); + if (err) { + brcmf_err("failed at addr: 0x%0x\n", + SBSDIO_FUNC1_SBADDRLOW + i); +@@ -407,7 +407,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, ++ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, + false); + brcmf_dbg(SDIO, "data:0x%02x\n", data); + +@@ -423,10 +423,10 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); +- retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); ++ retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + if (retval) + goto done; +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, ++ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, + false); + brcmf_dbg(SDIO, "data:0x%08x\n", data); + +@@ -443,7 +443,7 @@ void brcmf_sdiod_regwb(struct brcmf_sdio + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, ++ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, + true); + if (ret) + *ret = retval; +@@ -455,10 +455,10 @@ void brcmf_sdiod_regwl(struct brcmf_sdio + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); +- retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); ++ retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + if (retval) + goto done; +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, ++ retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, + true); + + done: +@@ -876,7 +876,7 @@ int brcmf_sdiod_abort(struct brcmf_sdio_ + + /* issue abort cmd52 command through F0 */ + brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT, +- sizeof(t_func), &t_func, true); ++ 1, &t_func, true); + + brcmf_dbg(SDIO, "Exit\n"); + return 0; diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0003-brcmfmac-Split-brcmf_sdiod_regrw_helper-up.patch b/root/package/kernel/mac80211/patches/311-v4.16-0003-brcmfmac-Split-brcmf_sdiod_regrw_helper-up.patch new file mode 100644 index 00000000..b04465ae --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0003-brcmfmac-Split-brcmf_sdiod_regrw_helper-up.patch @@ -0,0 +1,179 @@ +From 0fcc9fe0048422d66bb906eaa73cc75e11ff7345 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:40 +0100 +Subject: [PATCH] brcmfmac: Split brcmf_sdiod_regrw_helper() up. + +This large function is concealing a LOT of obscure logic about +how the hardware functions. Time to split it up. + +This first patch splits the function into two pieces - read and write, +doing away with the rw flag in the process. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 94 +++++++++++++++++----- + 1 file changed, 73 insertions(+), 21 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -302,8 +302,8 @@ static int brcmf_sdiod_request_data(stru + return ret; + } + +-static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, +- u8 regsz, void *data, bool write) ++static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, ++ u8 regsz, void *data) + { + u8 func; + s32 retry = 0; +@@ -324,13 +324,66 @@ static int brcmf_sdiod_regrw_helper(stru + func = SDIO_FUNC_1; + + do { +- if (!write) +- memset(data, 0, regsz); + /* for retry wait for 1 ms till bus get settled down */ + if (retry) + usleep_range(1000, 2000); ++ ++ ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, ++ data, true); ++ ++ } while (ret != 0 && ret != -ENOMEDIUM && ++ retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); ++ ++ if (ret == -ENOMEDIUM) { ++ brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); ++ } else if (ret != 0) { ++ /* ++ * SleepCSR register access can fail when ++ * waking up the device so reduce this noise ++ * in the logs. ++ */ ++ if (addr != SBSDIO_FUNC1_SLEEPCSR) ++ brcmf_err("failed to write data F%d@0x%05x, err: %d\n", ++ func, addr, ret); ++ else ++ brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: %d\n", ++ func, addr, ret); ++ } ++ ++ return ret; ++} ++ ++static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, ++ u8 regsz, void *data) ++{ ++ u8 func; ++ s32 retry = 0; ++ int ret; ++ ++ if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) ++ return -ENOMEDIUM; ++ ++ /* ++ * figure out how to read the register based on address range ++ * 0x00 ~ 0x7FF: function 0 CCCR and FBR ++ * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers ++ * The rest: function 1 silicon backplane core registers ++ */ ++ if ((addr & ~REG_F0_REG_MASK) == 0) ++ func = SDIO_FUNC_0; ++ else ++ func = SDIO_FUNC_1; ++ ++ do { ++ memset(data, 0, regsz); ++ ++ /* for retry wait for 1 ms till bus get settled down */ ++ if (retry) ++ usleep_range(1000, 2000); ++ + ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, +- data, write); ++ data, false); ++ + } while (ret != 0 && ret != -ENOMEDIUM && + retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); + +@@ -343,12 +396,13 @@ static int brcmf_sdiod_regrw_helper(stru + * in the logs. + */ + if (addr != SBSDIO_FUNC1_SLEEPCSR) +- brcmf_err("failed to %s data F%d@0x%05x, err: %d\n", +- write ? "write" : "read", func, addr, ret); ++ brcmf_err("failed to read data F%d@0x%05x, err: %d\n", ++ func, addr, ret); + else +- brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", +- write ? "write" : "read", func, addr, ret); ++ brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: %d\n", ++ func, addr, ret); + } ++ + return ret; + } + +@@ -366,13 +420,11 @@ brcmf_sdiod_set_sbaddr_window(struct brc + addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; + + for (i = 0; i < 3; i++) { +- err = brcmf_sdiod_regrw_helper(sdiodev, +- SBSDIO_FUNC1_SBADDRLOW + i, +- 1, &addr[i], true); ++ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i], ++ &err); + if (err) { + brcmf_err("failed at addr: 0x%0x\n", + SBSDIO_FUNC1_SBADDRLOW + i); +- break; + } + } + +@@ -407,8 +459,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, +- false); ++ retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data); + brcmf_dbg(SDIO, "data:0x%02x\n", data); + + if (ret) +@@ -426,8 +477,9 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ + retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + if (retval) + goto done; +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, +- false); ++ ++ retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); ++ + brcmf_dbg(SDIO, "data:0x%08x\n", data); + + done: +@@ -443,8 +495,8 @@ void brcmf_sdiod_regwb(struct brcmf_sdio + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 1, &data, +- true); ++ retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data); ++ + if (ret) + *ret = retval; + } +@@ -458,8 +510,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio + retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); + if (retval) + goto done; +- retval = brcmf_sdiod_regrw_helper(sdiodev, addr, 4, &data, +- true); ++ ++ retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); + + done: + if (ret) diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0004-brcmfmac-Clean-up-brcmf_sdiod_set_sbaddr_window.patch b/root/package/kernel/mac80211/patches/311-v4.16-0004-brcmfmac-Clean-up-brcmf_sdiod_set_sbaddr_window.patch new file mode 100644 index 00000000..1f0488a6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0004-brcmfmac-Clean-up-brcmf_sdiod_set_sbaddr_window.patch @@ -0,0 +1,62 @@ +From b9b0d290bc0c90a5a262bc89c9d995988ea98669 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:41 +0100 +Subject: [PATCH] brcmfmac: Clean up brcmf_sdiod_set_sbaddr_window() + +This function sets the address of the IO window used for +SDIO accesses onto the backplane of the chip. + +It currently uses 3 separate masks despite the full mask being +defined in the code already. Remove the separate masks and clean up. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 17 +++++------------ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 3 --- + 2 files changed, 5 insertions(+), 15 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -410,23 +410,16 @@ static int + brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) + { + int err = 0, i; +- u8 addr[3]; ++ u32 addr; + + if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) + return -ENOMEDIUM; + +- addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; +- addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; +- addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; ++ addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; + +- for (i = 0; i < 3; i++) { +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, addr[i], +- &err); +- if (err) { +- brcmf_err("failed at addr: 0x%0x\n", +- SBSDIO_FUNC1_SBADDRLOW + i); +- } +- } ++ for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) ++ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, ++ addr & 0xff, &err); + + return err; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -133,9 +133,6 @@ + + /* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ + +-#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ +-#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ +-#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ + /* Address bits from SBADDR regs */ + #define SBSDIO_SBWINDOW_MASK 0xffff8000 + diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0005-brcmfmac-Remove-dead-IO-code.patch b/root/package/kernel/mac80211/patches/311-v4.16-0005-brcmfmac-Remove-dead-IO-code.patch new file mode 100644 index 00000000..7d50ce92 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0005-brcmfmac-Remove-dead-IO-code.patch @@ -0,0 +1,91 @@ +From ea243e9077b3545f20d93884e91c50ac0719685a Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:42 +0100 +Subject: [PATCH] brcmfmac: Remove dead IO code + +The value passed to brcmf_sdiod_addrprep() is *always* 4 +remove this parameter and the unused code to handle it. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -425,7 +425,7 @@ brcmf_sdiod_set_sbaddr_window(struct brc + } + + static int +-brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) ++brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) + { + uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; + int err = 0; +@@ -439,9 +439,7 @@ brcmf_sdiod_addrprep(struct brcmf_sdio_d + } + + *addr &= SBSDIO_SB_OFT_ADDR_MASK; +- +- if (width == 4) +- *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; ++ *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + return 0; + } +@@ -467,7 +465,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); +- retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); ++ retval = brcmf_sdiod_addrprep(sdiodev, &addr); + if (retval) + goto done; + +@@ -500,7 +498,7 @@ void brcmf_sdiod_regwl(struct brcmf_sdio + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); +- retval = brcmf_sdiod_addrprep(sdiodev, 4, &addr); ++ retval = brcmf_sdiod_addrprep(sdiodev, &addr); + if (retval) + goto done; + +@@ -736,7 +734,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd + + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); + +- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); ++ err = brcmf_sdiod_addrprep(sdiodev, &addr); + if (err) + goto done; + +@@ -757,7 +755,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", + addr, pktq->qlen); + +- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); ++ err = brcmf_sdiod_addrprep(sdiodev, &addr); + if (err) + goto done; + +@@ -801,7 +799,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + + memcpy(mypkt->data, buf, nbytes); + +- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); ++ err = brcmf_sdiod_addrprep(sdiodev, &addr); + + if (!err) + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr, +@@ -821,7 +819,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); + +- err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); ++ err = brcmf_sdiod_addrprep(sdiodev, &addr); + if (err) + return err; + diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0006-brcmfmac-Remove-bandaid-for-SleepCSR.patch b/root/package/kernel/mac80211/patches/311-v4.16-0006-brcmfmac-Remove-bandaid-for-SleepCSR.patch new file mode 100644 index 00000000..fef29fc7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0006-brcmfmac-Remove-bandaid-for-SleepCSR.patch @@ -0,0 +1,61 @@ +From 4a3338ba2a7421db2260159cca5a27bd2ee36d00 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:43 +0100 +Subject: [PATCH] brcmfmac: Remove bandaid for SleepCSR + +Register access code is not the place for band-aid fixes like this. +If this is a genuine problem, it should be fixed further up in the driver +stack. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 28 +--------------------- + 1 file changed, 1 insertion(+), 27 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -334,21 +334,8 @@ static int brcmf_sdiod_reg_write(struct + } while (ret != 0 && ret != -ENOMEDIUM && + retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); + +- if (ret == -ENOMEDIUM) { ++ if (ret == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); +- } else if (ret != 0) { +- /* +- * SleepCSR register access can fail when +- * waking up the device so reduce this noise +- * in the logs. +- */ +- if (addr != SBSDIO_FUNC1_SLEEPCSR) +- brcmf_err("failed to write data F%d@0x%05x, err: %d\n", +- func, addr, ret); +- else +- brcmf_dbg(SDIO, "failed to write data F%d@0x%05x, err: %d\n", +- func, addr, ret); +- } + + return ret; + } +@@ -389,19 +376,6 @@ static int brcmf_sdiod_reg_read(struct b + + if (ret == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); +- else if (ret != 0) { +- /* +- * SleepCSR register access can fail when +- * waking up the device so reduce this noise +- * in the logs. +- */ +- if (addr != SBSDIO_FUNC1_SLEEPCSR) +- brcmf_err("failed to read data F%d@0x%05x, err: %d\n", +- func, addr, ret); +- else +- brcmf_dbg(SDIO, "failed to read data F%d@0x%05x, err: %d\n", +- func, addr, ret); +- } + + return ret; + } diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0007-brcmfmac-Remove-brcmf_sdiod_request_data.patch b/root/package/kernel/mac80211/patches/311-v4.16-0007-brcmfmac-Remove-brcmf_sdiod_request_data.patch new file mode 100644 index 00000000..552f9fb4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0007-brcmfmac-Remove-brcmf_sdiod_request_data.patch @@ -0,0 +1,344 @@ +From 993a98a42e6e790fd0d2bf7d55a031513c7ba7dc Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:44 +0100 +Subject: [PATCH] brcmfmac: Remove brcmf_sdiod_request_data() + +This function is obfuscating how IO works on this chip. Remove it +and push its logic into brcmf_sdiod_reg_{read,write}(). + +Handling of -ENOMEDIUM is altered, but as that's pretty much broken anyway +we can ignore that. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 237 ++++++++------------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 2 +- + 2 files changed, 87 insertions(+), 152 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -230,6 +230,43 @@ void brcmf_sdiod_change_state(struct brc + sdiodev->state = state; + } + ++static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, ++ u32 address) ++{ ++ int err = 0, i; ++ u32 addr; ++ ++ if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) ++ return -ENOMEDIUM; ++ ++ addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; ++ ++ for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) ++ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, ++ addr & 0xff, &err); ++ ++ return err; ++} ++ ++static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) ++{ ++ uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; ++ int err = 0; ++ ++ if (bar0 != sdiodev->sbwad) { ++ err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); ++ if (err) ++ return err; ++ ++ sdiodev->sbwad = bar0; ++ } ++ ++ *addr &= SBSDIO_SB_OFT_ADDR_MASK; ++ *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; ++ ++ return 0; ++} ++ + static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte, + uint regaddr) + { +@@ -249,173 +286,84 @@ static inline int brcmf_sdiod_f0_writeb( + return err_ret; + } + +-static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, +- u32 addr, u8 regsz, void *data, bool write) +-{ +- struct sdio_func *func; +- int ret = -EINVAL; +- +- brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", +- write, fn, addr, regsz); +- +- /* only allow byte access on F0 */ +- if (WARN_ON(regsz > 1 && !fn)) +- return -EINVAL; +- func = sdiodev->func[fn]; +- +- switch (regsz) { +- case 1: +- if (write) { +- if (fn) +- sdio_writeb(func, *(u8 *)data, addr, &ret); +- else +- ret = brcmf_sdiod_f0_writeb(func, *(u8 *)data, +- addr); +- } else { +- if (fn) +- *(u8 *)data = sdio_readb(func, addr, &ret); +- else +- *(u8 *)data = sdio_f0_readb(func, addr, &ret); +- } +- break; +- case 2: +- if (write) +- sdio_writew(func, *(u16 *)data, addr, &ret); +- else +- *(u16 *)data = sdio_readw(func, addr, &ret); +- break; +- case 4: +- if (write) +- sdio_writel(func, *(u32 *)data, addr, &ret); +- else +- *(u32 *)data = sdio_readl(func, addr, &ret); +- break; +- default: +- brcmf_err("invalid size: %d\n", regsz); +- break; +- } +- +- if (ret) +- brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", +- write ? "write" : "read", fn, addr, ret); +- +- return ret; +-} +- + static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, + u8 regsz, void *data) + { +- u8 func; +- s32 retry = 0; + int ret; + +- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) +- return -ENOMEDIUM; +- + /* + * figure out how to read the register based on address range + * 0x00 ~ 0x7FF: function 0 CCCR and FBR + * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers + * The rest: function 1 silicon backplane core registers ++ * f0 writes must be bytewise + */ +- if ((addr & ~REG_F0_REG_MASK) == 0) +- func = SDIO_FUNC_0; +- else +- func = SDIO_FUNC_1; +- +- do { +- /* for retry wait for 1 ms till bus get settled down */ +- if (retry) +- usleep_range(1000, 2000); + +- ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, +- data, true); +- +- } while (ret != 0 && ret != -ENOMEDIUM && +- retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); ++ if ((addr & ~REG_F0_REG_MASK) == 0) { ++ if (WARN_ON(regsz > 1)) ++ return -EINVAL; ++ ret = brcmf_sdiod_f0_writeb(sdiodev->func[0], ++ *(u8 *)data, addr); ++ } else { ++ switch (regsz) { ++ case 1: ++ sdio_writeb(sdiodev->func[1], *(u8 *)data, addr, &ret); ++ break; ++ case 4: ++ ret = brcmf_sdiod_addrprep(sdiodev, &addr); ++ if (ret) ++ goto done; + +- if (ret == -ENOMEDIUM) +- brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); ++ sdio_writel(sdiodev->func[1], *(u32 *)data, addr, &ret); ++ break; ++ default: ++ WARN(1, "Invalid reg size\n"); ++ ret = -EINVAL; ++ break; ++ } ++ } + ++done: + return ret; + } + + static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, + u8 regsz, void *data) + { +- u8 func; +- s32 retry = 0; + int ret; + +- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) +- return -ENOMEDIUM; +- + /* + * figure out how to read the register based on address range + * 0x00 ~ 0x7FF: function 0 CCCR and FBR + * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers + * The rest: function 1 silicon backplane core registers ++ * f0 reads must be bytewise + */ +- if ((addr & ~REG_F0_REG_MASK) == 0) +- func = SDIO_FUNC_0; +- else +- func = SDIO_FUNC_1; +- +- do { +- memset(data, 0, regsz); +- +- /* for retry wait for 1 ms till bus get settled down */ +- if (retry) +- usleep_range(1000, 2000); +- +- ret = brcmf_sdiod_request_data(sdiodev, func, addr, regsz, +- data, false); +- +- } while (ret != 0 && ret != -ENOMEDIUM && +- retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); +- +- if (ret == -ENOMEDIUM) +- brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); +- +- return ret; +-} +- +-static int +-brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) +-{ +- int err = 0, i; +- u32 addr; +- +- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) +- return -ENOMEDIUM; +- +- addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; +- +- for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, +- addr & 0xff, &err); +- +- return err; +-} +- +-static int +-brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) +-{ +- uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; +- int err = 0; +- +- if (bar0 != sdiodev->sbwad) { +- err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); +- if (err) +- return err; ++ if ((addr & ~REG_F0_REG_MASK) == 0) { ++ if (WARN_ON(regsz > 1)) ++ return -EINVAL; ++ *(u8 *)data = sdio_f0_readb(sdiodev->func[0], addr, &ret); ++ } else { ++ switch (regsz) { ++ case 1: ++ *(u8 *)data = sdio_readb(sdiodev->func[1], addr, &ret); ++ break; ++ case 4: ++ ret = brcmf_sdiod_addrprep(sdiodev, &addr); ++ if (ret) ++ goto done; + +- sdiodev->sbwad = bar0; ++ *(u32 *)data = sdio_readl(sdiodev->func[1], addr, &ret); ++ break; ++ default: ++ WARN(1, "Invalid reg size\n"); ++ ret = -EINVAL; ++ break; ++ } + } + +- *addr &= SBSDIO_SB_OFT_ADDR_MASK; +- *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; +- +- return 0; ++done: ++ return ret; + } + + u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +@@ -439,15 +387,9 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); +- retval = brcmf_sdiod_addrprep(sdiodev, &addr); +- if (retval) +- goto done; +- + retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); +- + brcmf_dbg(SDIO, "data:0x%08x\n", data); + +-done: + if (ret) + *ret = retval; + +@@ -472,13 +414,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); +- retval = brcmf_sdiod_addrprep(sdiodev, &addr); +- if (retval) +- goto done; +- + retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); + +-done: + if (ret) + *ret = retval; + } +@@ -886,14 +823,12 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + return bcmerror; + } + +-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) ++int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn) + { +- char t_func = (char)fn; + brcmf_dbg(SDIO, "Enter\n"); + + /* issue abort cmd52 command through F0 */ +- brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT, +- 1, &t_func, true); ++ brcmf_sdiod_reg_write(sdiodev, SDIO_CCCR_ABORT, 1, &fn); + + brcmf_dbg(SDIO, "Exit\n"); + return 0; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -339,7 +339,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_ + u8 *data, uint size); + + /* Issue an abort to the specified function */ +-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); ++int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn); + void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev); + void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, + enum brcmf_sdiod_state state); diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0008-brcmfmac-Fix-asymmetric-IO-functions.patch b/root/package/kernel/mac80211/patches/311-v4.16-0008-brcmfmac-Fix-asymmetric-IO-functions.patch new file mode 100644 index 00000000..bcf59722 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0008-brcmfmac-Fix-asymmetric-IO-functions.patch @@ -0,0 +1,28 @@ +From 3508a056a1f45d95c874fc9af8748bf4229432b6 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:45 +0100 +Subject: [PATCH] brcmfmac: Fix asymmetric IO functions. + +Unlikely to be a problem, but brcmf_sdiod_regrl() is +not symmetric with brcmf_sdiod_regrb() in initializing +the data value on stack. Fix that. + +Signed-off-by: Ian Molton +[arend: reword the commit message a bit] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -383,7 +383,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d + + u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) + { +- u32 data = 0; ++ u32 data; + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0009-brcmfmac-Remove-noisy-debugging.patch b/root/package/kernel/mac80211/patches/311-v4.16-0009-brcmfmac-Remove-noisy-debugging.patch new file mode 100644 index 00000000..9a570450 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0009-brcmfmac-Remove-noisy-debugging.patch @@ -0,0 +1,53 @@ +From 12e3e74e2820e11d91ee44fd3a190cd80d109faa Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:46 +0100 +Subject: [PATCH] brcmfmac: Remove noisy debugging. + +If you need debugging this low level, you're doing something wrong. +Remove these noisy debug statements so the code is more readable. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 6 ------ + 1 file changed, 6 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -371,9 +371,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d + u8 data; + int retval; + +- brcmf_dbg(SDIO, "addr:0x%08x\n", addr); + retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data); +- brcmf_dbg(SDIO, "data:0x%02x\n", data); + + if (ret) + *ret = retval; +@@ -386,9 +384,7 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ + u32 data; + int retval; + +- brcmf_dbg(SDIO, "addr:0x%08x\n", addr); + retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); +- brcmf_dbg(SDIO, "data:0x%08x\n", data); + + if (ret) + *ret = retval; +@@ -401,7 +397,6 @@ void brcmf_sdiod_regwb(struct brcmf_sdio + { + int retval; + +- brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); + retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data); + + if (ret) +@@ -413,7 +408,6 @@ void brcmf_sdiod_regwl(struct brcmf_sdio + { + int retval; + +- brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); + retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); + + if (ret) diff --git a/root/package/kernel/mac80211/patches/311-v4.16-0010-brcmfmac-Rename-bcmerror-to-err.patch b/root/package/kernel/mac80211/patches/311-v4.16-0010-brcmfmac-Rename-bcmerror-to-err.patch new file mode 100644 index 00000000..dd153fe6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/311-v4.16-0010-brcmfmac-Rename-bcmerror-to-err.patch @@ -0,0 +1,58 @@ +From dd8a2d49e4ed321ab8e7b679499c3a98ccc5ca24 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Mon, 13 Nov 2017 21:35:47 +0100 +Subject: [PATCH] brcmfmac: Rename bcmerror to err + +Trivial cleanup of nasty variable name + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -746,7 +746,7 @@ int + brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, + u8 *data, uint size) + { +- int bcmerror = 0; ++ int err = 0; + struct sk_buff *pkt; + u32 sdaddr; + uint dsize; +@@ -771,8 +771,8 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + /* Do the transfer(s) */ + while (size) { + /* Set the backplane window to include the start address */ +- bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address); +- if (bcmerror) ++ err = brcmf_sdiod_set_sbaddr_window(sdiodev, address); ++ if (err) + break; + + brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", +@@ -785,9 +785,9 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + skb_put(pkt, dsize); + if (write) + memcpy(pkt->data, data, dsize); +- bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, +- sdaddr, pkt); +- if (bcmerror) { ++ err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr, ++ pkt); ++ if (err) { + brcmf_err("membytes transfer failed\n"); + break; + } +@@ -814,7 +814,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + + sdio_release_host(sdiodev->func[1]); + +- return bcmerror; ++ return err; + } + + int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn) diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0001-brcmfmac-Split-brcmf_sdiod_buffrw-function-up.patch b/root/package/kernel/mac80211/patches/312-v4.16-0001-brcmfmac-Split-brcmf_sdiod_buffrw-function-up.patch new file mode 100644 index 00000000..c260b965 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0001-brcmfmac-Split-brcmf_sdiod_buffrw-function-up.patch @@ -0,0 +1,143 @@ +From 8f13c87ccc495e30de5f58bbda967f6edd5bec53 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:26 +0100 +Subject: [PATCH] brcmfmac: Split brcmf_sdiod_buffrw function up. + +This function needs to be split up into separate read / write variants +for clarity. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 67 +++++++++++++++------- + 1 file changed, 45 insertions(+), 22 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -414,8 +414,8 @@ void brcmf_sdiod_regwl(struct brcmf_sdio + *ret = retval; + } + +-static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, +- bool write, u32 addr, struct sk_buff *pkt) ++static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn, ++ u32 addr, struct sk_buff *pkt) + { + unsigned int req_sz; + int err; +@@ -424,18 +424,36 @@ static int brcmf_sdiod_buffrw(struct brc + req_sz = pkt->len + 3; + req_sz &= (uint)~3; + +- if (write) +- err = sdio_memcpy_toio(sdiodev->func[fn], addr, +- ((u8 *)(pkt->data)), req_sz); +- else if (fn == 1) +- err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)), +- addr, req_sz); ++ if (fn == 1) ++ err = sdio_memcpy_fromio(sdiodev->func[fn], ++ ((u8 *)(pkt->data)), addr, req_sz); + else + /* function 2 read is FIFO operation */ +- err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, +- req_sz); ++ err = sdio_readsb(sdiodev->func[fn], ++ ((u8 *)(pkt->data)), addr, req_sz); ++ ++ if (err == -ENOMEDIUM) ++ brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); ++ ++ return err; ++} ++ ++static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn, ++ u32 addr, struct sk_buff *pkt) ++{ ++ unsigned int req_sz; ++ int err; ++ ++ /* Single skb use the standard mmc interface */ ++ req_sz = pkt->len + 3; ++ req_sz &= (uint)~3; ++ ++ err = sdio_memcpy_toio(sdiodev->func[fn], addr, ++ ((u8 *)(pkt->data)), req_sz); ++ + if (err == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); ++ + return err; + } + +@@ -643,7 +661,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd + if (err) + goto done; + +- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt); ++ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt); + + done: + return err; +@@ -665,14 +683,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + goto done; + + if (pktq->qlen == 1) +- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, +- pktq->next); ++ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, ++ pktq->next); + else if (!sdiodev->sg_support) { + glom_skb = brcmu_pkt_buf_get_skb(totlen); + if (!glom_skb) + return -ENOMEM; +- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, +- glom_skb); ++ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, ++ glom_skb); + if (err) + goto done; + +@@ -707,8 +725,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + err = brcmf_sdiod_addrprep(sdiodev, &addr); + + if (!err) +- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr, +- mypkt); ++ err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); + + brcmu_pkt_buf_free_skb(mypkt); + return err; +@@ -730,8 +747,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + + if (pktq->qlen == 1 || !sdiodev->sg_support) + skb_queue_walk(pktq, skb) { +- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, +- addr, skb); ++ err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, ++ addr, skb); + if (err) + break; + } +@@ -783,10 +800,16 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + skb_put(pkt, dsize); +- if (write) ++ ++ if (write) { + memcpy(pkt->data, data, dsize); +- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, sdaddr, +- pkt); ++ err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1, ++ sdaddr, pkt); ++ } else { ++ err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1, ++ sdaddr, pkt); ++ } ++ + if (err) { + brcmf_err("membytes transfer failed\n"); + break; diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0002-brcmfmac-whitespace-fixes-in-brcmf_sdiod_send_buf.patch b/root/package/kernel/mac80211/patches/312-v4.16-0002-brcmfmac-whitespace-fixes-in-brcmf_sdiod_send_buf.patch new file mode 100644 index 00000000..088a6169 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0002-brcmfmac-whitespace-fixes-in-brcmf_sdiod_send_buf.patch @@ -0,0 +1,34 @@ +From 6e24dd012bfda479d0046f7995058f167e1923bc Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:27 +0100 +Subject: [PATCH] brcmfmac: whitespace fixes in brcmf_sdiod_send_buf() + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +[arend: mention function in patch subject] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -714,6 +714,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + int err; + + mypkt = brcmu_pkt_buf_get_skb(nbytes); ++ + if (!mypkt) { + brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", + nbytes); +@@ -728,8 +729,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); + + brcmu_pkt_buf_free_skb(mypkt); +- return err; + ++ return err; + } + + int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0003-brcmfmac-Clarify-if-using-braces.patch b/root/package/kernel/mac80211/patches/312-v4.16-0003-brcmfmac-Clarify-if-using-braces.patch new file mode 100644 index 00000000..a44155b6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0003-brcmfmac-Clarify-if-using-braces.patch @@ -0,0 +1,36 @@ +From a7323378dcf1f10a98f47b744e6f65e6fd671d84 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:28 +0100 +Subject: [PATCH] brcmfmac: Clarify if using braces. + +Whilst this if () statement is technically correct, it lacks clarity. + +Signed-off-by: Ian Molton +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -746,16 +746,17 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + if (err) + return err; + +- if (pktq->qlen == 1 || !sdiodev->sg_support) ++ if (pktq->qlen == 1 || !sdiodev->sg_support) { + skb_queue_walk(pktq, skb) { + err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, + addr, skb); + if (err) + break; + } +- else ++ } else { + err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr, + pktq); ++ } + + return err; + } diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0004-brcmfmac-Rename-replace-old-IO-functions-with-simple.patch b/root/package/kernel/mac80211/patches/312-v4.16-0004-brcmfmac-Rename-replace-old-IO-functions-with-simple.patch new file mode 100644 index 00000000..7c27e177 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0004-brcmfmac-Rename-replace-old-IO-functions-with-simple.patch @@ -0,0 +1,831 @@ +From 71bd508d7ded8c504ef05d1b4befecfe25e54cb1 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:29 +0100 +Subject: [PATCH] brcmfmac: Rename / replace old IO functions with simpler + ones. + +Primarily this patch removes: + +brcmf_sdiod_f0_writeb() +brcmf_sdiod_reg_write() +brcmf_sdiod_reg_read() + +Since we no longer use the quirky method of deciding which function to +address via the address being accessed, take the opportunity to rename +some IO functions more in line with common kernel code. We also convert +those that map directly to sdio_{read,write}*() to macros. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 169 +++---------------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 186 ++++++++++----------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 28 +++- + 3 files changed, 138 insertions(+), 245 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -137,27 +137,27 @@ int brcmf_sdiod_intr_register(struct brc + if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) { + /* assign GPIO to SDIO core */ + addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol); +- gpiocontrol = brcmf_sdiod_regrl(sdiodev, addr, &ret); ++ gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret); + gpiocontrol |= 0x2; +- brcmf_sdiod_regwl(sdiodev, addr, gpiocontrol, &ret); ++ brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret); + +- brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_SELECT, 0xf, +- &ret); +- brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret); +- brcmf_sdiod_regwb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT, ++ 0xf, &ret); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret); + } + + /* must configure SDIO_CCCR_IENx to enable irq */ +- data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret); ++ data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret); + data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; +- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); ++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret); + + /* redirect, configure and enable io for interrupt signal */ + data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; + if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) + data |= SDIO_SEPINT_ACT_HI; +- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); +- ++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, ++ data, &ret); + sdio_release_host(sdiodev->func[1]); + } else { + brcmf_dbg(SDIO, "Entering\n"); +@@ -183,8 +183,8 @@ void brcmf_sdiod_intr_unregister(struct + + pdata = &sdiodev->settings->bus.sdio; + sdio_claim_host(sdiodev->func[1]); +- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); +- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); ++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); ++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL); + sdio_release_host(sdiodev->func[1]); + + sdiodev->oob_irq_requested = false; +@@ -242,8 +242,8 @@ static int brcmf_sdiod_set_sbaddr_window + addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; + + for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, +- addr & 0xff, &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, ++ addr & 0xff, &err); + + return err; + } +@@ -267,124 +267,15 @@ static int brcmf_sdiod_addrprep(struct b + return 0; + } + +-static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, u8 byte, +- uint regaddr) +-{ +- int err_ret; +- +- /* +- * Can only directly write to some F0 registers. +- * Handle CCCR_IENx and CCCR_ABORT command +- * as a special case. +- */ +- if ((regaddr == SDIO_CCCR_ABORT) || +- (regaddr == SDIO_CCCR_IENx)) +- sdio_writeb(func, byte, regaddr, &err_ret); +- else +- sdio_f0_writeb(func, byte, regaddr, &err_ret); +- +- return err_ret; +-} +- +-static int brcmf_sdiod_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, +- u8 regsz, void *data) +-{ +- int ret; +- +- /* +- * figure out how to read the register based on address range +- * 0x00 ~ 0x7FF: function 0 CCCR and FBR +- * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers +- * The rest: function 1 silicon backplane core registers +- * f0 writes must be bytewise +- */ +- +- if ((addr & ~REG_F0_REG_MASK) == 0) { +- if (WARN_ON(regsz > 1)) +- return -EINVAL; +- ret = brcmf_sdiod_f0_writeb(sdiodev->func[0], +- *(u8 *)data, addr); +- } else { +- switch (regsz) { +- case 1: +- sdio_writeb(sdiodev->func[1], *(u8 *)data, addr, &ret); +- break; +- case 4: +- ret = brcmf_sdiod_addrprep(sdiodev, &addr); +- if (ret) +- goto done; +- +- sdio_writel(sdiodev->func[1], *(u32 *)data, addr, &ret); +- break; +- default: +- WARN(1, "Invalid reg size\n"); +- ret = -EINVAL; +- break; +- } +- } +- +-done: +- return ret; +-} +- +-static int brcmf_sdiod_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, +- u8 regsz, void *data) +-{ +- int ret; +- +- /* +- * figure out how to read the register based on address range +- * 0x00 ~ 0x7FF: function 0 CCCR and FBR +- * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers +- * The rest: function 1 silicon backplane core registers +- * f0 reads must be bytewise +- */ +- if ((addr & ~REG_F0_REG_MASK) == 0) { +- if (WARN_ON(regsz > 1)) +- return -EINVAL; +- *(u8 *)data = sdio_f0_readb(sdiodev->func[0], addr, &ret); +- } else { +- switch (regsz) { +- case 1: +- *(u8 *)data = sdio_readb(sdiodev->func[1], addr, &ret); +- break; +- case 4: +- ret = brcmf_sdiod_addrprep(sdiodev, &addr); +- if (ret) +- goto done; +- +- *(u32 *)data = sdio_readl(sdiodev->func[1], addr, &ret); +- break; +- default: +- WARN(1, "Invalid reg size\n"); +- ret = -EINVAL; +- break; +- } +- } +- +-done: +- return ret; +-} +- +-u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) ++u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) + { +- u8 data; ++ u32 data = 0; + int retval; + +- retval = brcmf_sdiod_reg_read(sdiodev, addr, 1, &data); +- +- if (ret) +- *ret = retval; +- +- return data; +-} ++ retval = brcmf_sdiod_addrprep(sdiodev, &addr); + +-u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +-{ +- u32 data; +- int retval; +- +- retval = brcmf_sdiod_reg_read(sdiodev, addr, 4, &data); ++ if (!retval) ++ data = sdio_readl(sdiodev->func[1], addr, &retval); + + if (ret) + *ret = retval; +@@ -392,23 +283,15 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_ + return data; + } + +-void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, +- u8 data, int *ret) ++void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, ++ u32 data, int *ret) + { + int retval; + +- retval = brcmf_sdiod_reg_write(sdiodev, addr, 1, &data); +- +- if (ret) +- *ret = retval; +-} +- +-void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, +- u32 data, int *ret) +-{ +- int retval; ++ retval = brcmf_sdiod_addrprep(sdiodev, &addr); + +- retval = brcmf_sdiod_reg_write(sdiodev, addr, 4, &data); ++ if (!retval) ++ sdio_writel(sdiodev->func[1], data, addr, &retval); + + if (ret) + *ret = retval; +@@ -846,8 +729,8 @@ int brcmf_sdiod_abort(struct brcmf_sdio_ + { + brcmf_dbg(SDIO, "Enter\n"); + +- /* issue abort cmd52 command through F0 */ +- brcmf_sdiod_reg_write(sdiodev, SDIO_CCCR_ABORT, 1, &fn); ++ /* Issue abort cmd52 command through F0 */ ++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL); + + brcmf_dbg(SDIO, "Exit\n"); + return 0; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -669,7 +669,7 @@ static int r_sdreg32(struct brcmf_sdio * + int ret; + + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); +- *regvar = brcmf_sdiod_regrl(bus->sdiodev, core->base + offset, &ret); ++ *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret); + + return ret; + } +@@ -680,7 +680,7 @@ static int w_sdreg32(struct brcmf_sdio * + int ret; + + core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); +- brcmf_sdiod_regwl(bus->sdiodev, core->base + reg_offset, regval, &ret); ++ brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret); + + return ret; + } +@@ -697,8 +697,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio + + wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); + /* 1st KSO write goes to AOS wake up core if device is asleep */ +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, +- wr_val, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err); + + if (on) { + /* device WAKEUP through KSO: +@@ -724,7 +723,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio + * just one write attempt may fail, + * read it back until it matches written value + */ +- rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, ++ rd_val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + &err); + if (!err) { + if ((rd_val & bmask) == cmp_val) +@@ -734,9 +733,11 @@ brcmf_sdio_kso_control(struct brcmf_sdio + /* bail out upon subsequent access errors */ + if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) + break; ++ + udelay(KSO_WAIT_US); +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, +- wr_val, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, ++ &err); ++ + } while (try_cnt++ < MAX_KSO_ATTEMPTS); + + if (try_cnt > 2) +@@ -772,15 +773,15 @@ static int brcmf_sdio_htclk(struct brcmf + clkreq = + bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; + +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, +- clkreq, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ clkreq, &err); + if (err) { + brcmf_err("HT Avail request error: %d\n", err); + return -EBADE; + } + + /* Check current status */ +- clkctl = brcmf_sdiod_regrb(bus->sdiodev, ++ clkctl = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); + if (err) { + brcmf_err("HT Avail read error: %d\n", err); +@@ -790,35 +791,34 @@ static int brcmf_sdio_htclk(struct brcmf + /* Go to pending and await interrupt if appropriate */ + if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { + /* Allow only clock-available interrupt */ +- devctl = brcmf_sdiod_regrb(bus->sdiodev, ++ devctl = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); + if (err) { +- brcmf_err("Devctl error setting CA: %d\n", +- err); ++ brcmf_err("Devctl error setting CA: %d\n", err); + return -EBADE; + } + + devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, +- devctl, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, ++ devctl, &err); + brcmf_dbg(SDIO, "CLKCTL: set PENDING\n"); + bus->clkstate = CLK_PENDING; + + return 0; + } else if (bus->clkstate == CLK_PENDING) { + /* Cancel CA-only interrupt filter */ +- devctl = brcmf_sdiod_regrb(bus->sdiodev, ++ devctl = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); + devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, +- devctl, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, ++ devctl, &err); + } + + /* Otherwise, wait here (polling) for HT Avail */ + timeout = jiffies + + msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); + while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { +- clkctl = brcmf_sdiod_regrb(bus->sdiodev, ++ clkctl = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, + &err); + if (time_after(jiffies, timeout)) +@@ -852,16 +852,16 @@ static int brcmf_sdio_htclk(struct brcmf + + if (bus->clkstate == CLK_PENDING) { + /* Cancel CA-only interrupt filter */ +- devctl = brcmf_sdiod_regrb(bus->sdiodev, ++ devctl = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); + devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, +- devctl, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_DEVICE_CTL, ++ devctl, &err); + } + + bus->clkstate = CLK_SDONLY; +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, +- clkreq, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ clkreq, &err); + brcmf_dbg(SDIO, "CLKCTL: turned OFF\n"); + if (err) { + brcmf_err("Failed access turning clock off: %d\n", +@@ -951,14 +951,14 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio * + + /* Going to sleep */ + if (sleep) { +- clkcsr = brcmf_sdiod_regrb(bus->sdiodev, ++ clkcsr = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, + &err); + if ((clkcsr & SBSDIO_CSR_MASK) == 0) { + brcmf_dbg(SDIO, "no clock, set ALP\n"); +- brcmf_sdiod_regwb(bus->sdiodev, +- SBSDIO_FUNC1_CHIPCLKCSR, +- SBSDIO_ALP_AVAIL_REQ, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, ++ SBSDIO_FUNC1_CHIPCLKCSR, ++ SBSDIO_ALP_AVAIL_REQ, &err); + } + err = brcmf_sdio_kso_control(bus, false); + } else { +@@ -1178,16 +1178,16 @@ static void brcmf_sdio_rxfail(struct brc + if (abort) + brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); + +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, +- SFC_RF_TERM, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, ++ &err); + bus->sdcnt.f1regdata++; + + /* Wait until the packet has been flushed (device/FIFO stable) */ + for (lastrbc = retries = 0xffff; retries > 0; retries--) { +- hi = brcmf_sdiod_regrb(bus->sdiodev, +- SBSDIO_FUNC1_RFRAMEBCHI, &err); +- lo = brcmf_sdiod_regrb(bus->sdiodev, +- SBSDIO_FUNC1_RFRAMEBCLO, &err); ++ hi = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCHI, ++ &err); ++ lo = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO, ++ &err); + bus->sdcnt.f1regdata += 2; + + if ((hi == 0) && (lo == 0)) +@@ -1229,12 +1229,12 @@ static void brcmf_sdio_txfail(struct brc + bus->sdcnt.tx_sderrs++; + + brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2); +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); + bus->sdcnt.f1regdata++; + + for (i = 0; i < 3; i++) { +- hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL); +- lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); ++ hi = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL); ++ lo = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); + bus->sdcnt.f1regdata += 2; + if ((hi == 0) && (lo == 0)) + break; +@@ -2446,11 +2446,11 @@ static void brcmf_sdio_bus_stop(struct d + bus->hostintmask = 0; + + /* Force backplane clocks to assure F2 interrupt propagates */ +- saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + &err); + if (!err) +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, +- (saveclk | SBSDIO_FORCE_HT), &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ (saveclk | SBSDIO_FORCE_HT), &err); + if (err) + brcmf_err("Failed to force clock for F2: err %d\n", + err); +@@ -2509,7 +2509,7 @@ static int brcmf_sdio_intr_rstatus(struc + buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); + addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); + +- val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); ++ val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); + bus->sdcnt.f1regdata++; + if (ret != 0) + return ret; +@@ -2519,7 +2519,7 @@ static int brcmf_sdio_intr_rstatus(struc + + /* Clear interrupts */ + if (val) { +- brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); ++ brcmf_sdiod_writel(bus->sdiodev, addr, val, &ret); + bus->sdcnt.f1regdata++; + atomic_or(val, &bus->intstatus); + } +@@ -2545,23 +2545,23 @@ static void brcmf_sdio_dpc(struct brcmf_ + + #ifdef DEBUG + /* Check for inconsistent device control */ +- devctl = brcmf_sdiod_regrb(bus->sdiodev, +- SBSDIO_DEVICE_CTL, &err); ++ devctl = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_DEVICE_CTL, ++ &err); + #endif /* DEBUG */ + + /* Read CSR, if clock on switch to AVAIL, else ignore */ +- clkctl = brcmf_sdiod_regrb(bus->sdiodev, ++ clkctl = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); + + brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", + devctl, clkctl); + + if (SBSDIO_HTAV(clkctl)) { +- devctl = brcmf_sdiod_regrb(bus->sdiodev, ++ devctl = brcmf_sdiod_readb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); + devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, +- devctl, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, ++ SBSDIO_DEVICE_CTL, devctl, &err); + bus->clkstate = CLK_AVAIL; + } + } +@@ -3347,31 +3347,31 @@ static void brcmf_sdio_sr_init(struct br + + brcmf_dbg(TRACE, "Enter\n"); + +- val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err); ++ val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err); + if (err) { + brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n"); + return; + } + + val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err); + if (err) { + brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n"); + return; + } + + /* Add CMD14 Support */ +- brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, +- (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | +- SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), +- &err); ++ brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, ++ (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | ++ SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), ++ &err); + if (err) { + brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n"); + return; + } + +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, +- SBSDIO_FORCE_HT, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ SBSDIO_FORCE_HT, &err); + if (err) { + brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n"); + return; +@@ -3394,7 +3394,7 @@ static int brcmf_sdio_kso_init(struct br + if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) + return 0; + +- val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); ++ val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); + if (err) { + brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n"); + return err; +@@ -3403,8 +3403,8 @@ static int brcmf_sdio_kso_init(struct br + if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { + val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << + SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, +- val, &err); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, ++ val, &err); + if (err) { + brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n"); + return err; +@@ -3565,9 +3565,9 @@ static void brcmf_sdio_bus_watchdog(stru + u8 devpend; + + sdio_claim_host(bus->sdiodev->func[1]); +- devpend = brcmf_sdiod_regrb(bus->sdiodev, +- SDIO_CCCR_INTx, +- NULL); ++ devpend = brcmf_sdiod_func0_rb(bus->sdiodev, ++ SDIO_CCCR_INTx, ++ NULL); + sdio_release_host(bus->sdiodev->func[1]); + intstatus = devpend & (INTR_STATUS_FUNC1 | + INTR_STATUS_FUNC2); +@@ -3705,12 +3705,12 @@ brcmf_sdio_drivestrengthinit(struct brcm + } + } + addr = CORE_CC_REG(pmu->base, chipcontrol_addr); +- brcmf_sdiod_regwl(sdiodev, addr, 1, NULL); +- cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL); ++ brcmf_sdiod_writel(sdiodev, addr, 1, NULL); ++ cc_data_temp = brcmf_sdiod_readl(sdiodev, addr, NULL); + cc_data_temp &= ~str_mask; + drivestrength_sel <<= str_shift; + cc_data_temp |= drivestrength_sel; +- brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL); ++ brcmf_sdiod_writel(sdiodev, addr, cc_data_temp, NULL); + + brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n", + str_tab[i].strength, drivestrength, cc_data_temp); +@@ -3725,7 +3725,7 @@ static int brcmf_sdio_buscoreprep(void * + + /* Try forcing SDIO core to do ALPAvail request only */ + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + if (err) { + brcmf_err("error writing for HT off\n"); + return err; +@@ -3733,8 +3733,7 @@ static int brcmf_sdio_buscoreprep(void * + + /* If register supported, wait for ALPAvail and then force ALP */ + /* This may take up to 15 milliseconds */ +- clkval = brcmf_sdiod_regrb(sdiodev, +- SBSDIO_FUNC1_CHIPCLKCSR, NULL); ++ clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, NULL); + + if ((clkval & ~SBSDIO_AVBITS) != clkset) { + brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n", +@@ -3742,10 +3741,11 @@ static int brcmf_sdio_buscoreprep(void * + return -EACCES; + } + +- SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev, +- SBSDIO_FUNC1_CHIPCLKCSR, NULL)), +- !SBSDIO_ALPAV(clkval)), +- PMU_MAX_TRANSITION_DLY); ++ SPINWAIT(((clkval = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ NULL)), ++ !SBSDIO_ALPAV(clkval)), ++ PMU_MAX_TRANSITION_DLY); ++ + if (!SBSDIO_ALPAV(clkval)) { + brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n", + clkval); +@@ -3753,11 +3753,11 @@ static int brcmf_sdio_buscoreprep(void * + } + + clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + udelay(65); + + /* Also, disable the extra SDIO pull-ups */ +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); + + return 0; + } +@@ -3772,7 +3772,7 @@ static void brcmf_sdio_buscore_activate( + /* clear all interrupts */ + core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV); + reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus); +- brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); ++ brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + + if (rstvec) + /* Write reset vector to address 0 */ +@@ -3785,7 +3785,7 @@ static u32 brcmf_sdio_buscore_read32(voi + struct brcmf_sdio_dev *sdiodev = ctx; + u32 val, rev; + +- val = brcmf_sdiod_regrl(sdiodev, addr, NULL); ++ val = brcmf_sdiod_readl(sdiodev, addr, NULL); + if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || + sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) && + addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { +@@ -3802,7 +3802,7 @@ static void brcmf_sdio_buscore_write32(v + { + struct brcmf_sdio_dev *sdiodev = ctx; + +- brcmf_sdiod_regwl(sdiodev, addr, val, NULL); ++ brcmf_sdiod_writel(sdiodev, addr, val, NULL); + } + + static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { +@@ -3826,18 +3826,18 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + sdio_claim_host(sdiodev->func[1]); + + pr_debug("F1 signature read @0x18000000=0x%4x\n", +- brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL)); ++ brcmf_sdiod_readl(sdiodev, SI_ENUM_BASE, NULL)); + + /* + * Force PLL off until brcmf_chip_attach() + * programs PLL control regs + */ + +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, +- BRCMF_INIT_CLKCTL1, &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, BRCMF_INIT_CLKCTL1, ++ &err); + if (!err) +- clkctl = brcmf_sdiod_regrb(sdiodev, +- SBSDIO_FUNC1_CHIPCLKCSR, &err); ++ clkctl = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ &err); + + if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { + brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", +@@ -3897,25 +3897,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); + + /* Set card control so an SDIO card reset does a WLAN backplane reset */ +- reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); ++ reg_val = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); + if (err) + goto fail; + + reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; + +- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); ++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); + if (err) + goto fail; + + /* set PMUControl so a backplane reset does PMU state reload */ + reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); +- reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err); ++ reg_val = brcmf_sdiod_readl(sdiodev, reg_addr, &err); + if (err) + goto fail; + + reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); + +- brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err); ++ brcmf_sdiod_writel(sdiodev, reg_addr, reg_val, &err); + if (err) + goto fail; + +@@ -4055,10 +4055,10 @@ static void brcmf_sdio_firmware_callback + goto release; + + /* Force clocks on backplane to be sure F2 interrupt propagates */ +- saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); ++ saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); + if (!err) { +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, +- (saveclk | SBSDIO_FORCE_HT), &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ (saveclk | SBSDIO_FORCE_HT), &err); + } + if (err) { + brcmf_err("Failed to force clock for F2: err %d\n", err); +@@ -4080,7 +4080,7 @@ static void brcmf_sdio_firmware_callback + w_sdreg32(bus, bus->hostintmask, + offsetof(struct sdpcmd_regs, hostintmask)); + +- brcmf_sdiod_regwb(sdiodev, SBSDIO_WATERMARK, 8, &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); + } else { + /* Disable F2 again */ + sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); +@@ -4091,8 +4091,8 @@ static void brcmf_sdio_firmware_callback + brcmf_sdio_sr_init(bus); + } else { + /* Restore previous clock setting */ +- brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, +- saveclk, &err); ++ brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ saveclk, &err); + } + + if (err == 0) { +@@ -4225,7 +4225,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->rxflow = false; + + /* Done with backplane-dependent accesses, can drop clock... */ +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); ++ brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); + + sdio_release_host(bus->sdiodev->func[1]); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -50,6 +50,7 @@ + #define SBSDIO_NUM_FUNCTION 3 + + /* function 0 vendor specific CCCR registers */ ++ + #define SDIO_CCCR_BRCM_CARDCAP 0xf0 + #define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 + #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 +@@ -131,8 +132,6 @@ + /* with b15, maps to 32-bit SB access */ + #define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 + +-/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ +- + /* Address bits from SBADDR regs */ + #define SBSDIO_SBWINDOW_MASK 0xffff8000 + +@@ -293,13 +292,24 @@ struct sdpcmd_regs { + int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev); + void brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev); + +-/* sdio device register access interface */ +-u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +-u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +-void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, +- int *ret); +-void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, +- int *ret); ++/* SDIO device register access interface */ ++/* Accessors for SDIO Function 0 */ ++#define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ ++ sdio_readb((sdiodev)->func[0], (addr), (r)) ++ ++#define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ ++ sdio_writeb((sdiodev)->func[0], (v), (addr), (ret)) ++ ++/* Accessors for SDIO Function 1 */ ++#define brcmf_sdiod_readb(sdiodev, addr, r) \ ++ sdio_readb((sdiodev)->func[1], (addr), (r)) ++ ++#define brcmf_sdiod_writeb(sdiodev, addr, v, ret) \ ++ sdio_writeb((sdiodev)->func[1], (v), (addr), (ret)) ++ ++u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); ++void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, ++ int *ret); + + /* Buffer transfer to/from device (client) core via cmd53. + * fn: function number diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0005-brcmfmac-Tidy-register-definitions-a-little.patch b/root/package/kernel/mac80211/patches/312-v4.16-0005-brcmfmac-Tidy-register-definitions-a-little.patch new file mode 100644 index 00000000..e77d601a --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0005-brcmfmac-Tidy-register-definitions-a-little.patch @@ -0,0 +1,59 @@ +From eeef8a5da781e11746347b3cd9f1942be48ebaf0 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:30 +0100 +Subject: [PATCH] brcmfmac: Tidy register definitions a little + +Trivial tidy of register definitions. + +Signed-off-by: Ian Molton +Acked-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 ++-- + .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 19 ++++++++++--------- + 2 files changed, 12 insertions(+), 11 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -153,9 +153,9 @@ int brcmf_sdiod_intr_register(struct brc + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret); + + /* redirect, configure and enable io for interrupt signal */ +- data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; ++ data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE; + if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) +- data |= SDIO_SEPINT_ACT_HI; ++ data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI; + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, + data, &ret); + sdio_release_host(sdiodev->func[1]); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -52,16 +52,17 @@ + /* function 0 vendor specific CCCR registers */ + + #define SDIO_CCCR_BRCM_CARDCAP 0xf0 +-#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT 0x02 +-#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT 0x04 +-#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC 0x08 +-#define SDIO_CCCR_BRCM_CARDCTRL 0xf1 +-#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET 0x02 +-#define SDIO_CCCR_BRCM_SEPINT 0xf2 ++#define SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT BIT(1) ++#define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT BIT(2) ++#define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC BIT(3) ++ ++#define SDIO_CCCR_BRCM_CARDCTRL 0xf1 ++#define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET BIT(1) + +-#define SDIO_SEPINT_MASK 0x01 +-#define SDIO_SEPINT_OE 0x02 +-#define SDIO_SEPINT_ACT_HI 0x04 ++#define SDIO_CCCR_BRCM_SEPINT 0xf2 ++#define SDIO_CCCR_BRCM_SEPINT_MASK BIT(0) ++#define SDIO_CCCR_BRCM_SEPINT_OE BIT(1) ++#define SDIO_CCCR_BRCM_SEPINT_ACT_HI BIT(2) + + /* function 1 miscellaneous registers */ + diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch b/root/package/kernel/mac80211/patches/312-v4.16-0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch new file mode 100644 index 00000000..dc598aa4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0006-brcmfmac-Remove-brcmf_sdiod_addrprep.patch @@ -0,0 +1,190 @@ +From a7c3aa1509e243a09c5b1660c8702d792ca76aed Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:31 +0100 +Subject: [PATCH] brcmfmac: Remove brcmf_sdiod_addrprep() + +This function has become trivial enough that it may as well be pushed into +its callers, which has the side-benefit of clarifying what's going on. + +Remove it, and rename brcmf_sdiod_set_sbaddr_window() to +brcmf_sdiod_set_backplane_window() as it's easier to understand. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 84 ++++++++++++---------- + 1 file changed, 46 insertions(+), 38 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -230,41 +230,25 @@ void brcmf_sdiod_change_state(struct brc + sdiodev->state = state; + } + +-static int brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, +- u32 address) ++static int brcmf_sdiod_set_backplane_window(struct brcmf_sdio_dev *sdiodev, ++ u32 addr) + { ++ u32 v, bar0 = addr & SBSDIO_SBWINDOW_MASK; + int err = 0, i; +- u32 addr; + +- if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM) +- return -ENOMEDIUM; ++ if (bar0 == sdiodev->sbwad) ++ return 0; + +- addr = (address & SBSDIO_SBWINDOW_MASK) >> 8; ++ v = bar0 >> 8; + +- for (i = 0 ; i < 3 && !err ; i++, addr >>= 8) ++ for (i = 0 ; i < 3 && !err ; i++, v >>= 8) + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_SBADDRLOW + i, +- addr & 0xff, &err); +- +- return err; +-} +- +-static int brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, u32 *addr) +-{ +- uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; +- int err = 0; +- +- if (bar0 != sdiodev->sbwad) { +- err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); +- if (err) +- return err; ++ v & 0xff, &err); + ++ if (!err) + sdiodev->sbwad = bar0; +- } + +- *addr &= SBSDIO_SB_OFT_ADDR_MASK; +- *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; +- +- return 0; ++ return err; + } + + u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +@@ -272,11 +256,16 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_ + u32 data = 0; + int retval; + +- retval = brcmf_sdiod_addrprep(sdiodev, &addr); ++ retval = brcmf_sdiod_set_backplane_window(sdiodev, addr); ++ if (retval) ++ goto out; ++ ++ addr &= SBSDIO_SB_OFT_ADDR_MASK; ++ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + +- if (!retval) +- data = sdio_readl(sdiodev->func[1], addr, &retval); ++ data = sdio_readl(sdiodev->func[1], addr, &retval); + ++out: + if (ret) + *ret = retval; + +@@ -288,11 +277,16 @@ void brcmf_sdiod_writel(struct brcmf_sdi + { + int retval; + +- retval = brcmf_sdiod_addrprep(sdiodev, &addr); ++ retval = brcmf_sdiod_set_backplane_window(sdiodev, addr); ++ if (retval) ++ goto out; + +- if (!retval) +- sdio_writel(sdiodev->func[1], data, addr, &retval); ++ addr &= SBSDIO_SB_OFT_ADDR_MASK; ++ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + ++ sdio_writel(sdiodev->func[1], data, addr, &retval); ++ ++out: + if (ret) + *ret = retval; + } +@@ -540,10 +534,13 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd + + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); + +- err = brcmf_sdiod_addrprep(sdiodev, &addr); ++ err = brcmf_sdiod_set_backplane_window(sdiodev, addr); + if (err) + goto done; + ++ addr &= SBSDIO_SB_OFT_ADDR_MASK; ++ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; ++ + err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt); + + done: +@@ -561,10 +558,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", + addr, pktq->qlen); + +- err = brcmf_sdiod_addrprep(sdiodev, &addr); ++ err = brcmf_sdiod_set_backplane_window(sdiodev, addr); + if (err) + goto done; + ++ addr &= SBSDIO_SB_OFT_ADDR_MASK; ++ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; ++ + if (pktq->qlen == 1) + err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, + pktq->next); +@@ -606,7 +606,12 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + + memcpy(mypkt->data, buf, nbytes); + +- err = brcmf_sdiod_addrprep(sdiodev, &addr); ++ err = brcmf_sdiod_set_backplane_window(sdiodev, addr); ++ if (err) ++ return err; ++ ++ addr &= SBSDIO_SB_OFT_ADDR_MASK; ++ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (!err) + err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); +@@ -625,10 +630,13 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); + +- err = brcmf_sdiod_addrprep(sdiodev, &addr); ++ err = brcmf_sdiod_set_backplane_window(sdiodev, addr); + if (err) + return err; + ++ addr &= SBSDIO_SB_OFT_ADDR_MASK; ++ addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; ++ + if (pktq->qlen == 1 || !sdiodev->sg_support) { + skb_queue_walk(pktq, skb) { + err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, +@@ -673,7 +681,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + /* Do the transfer(s) */ + while (size) { + /* Set the backplane window to include the start address */ +- err = brcmf_sdiod_set_sbaddr_window(sdiodev, address); ++ err = brcmf_sdiod_set_backplane_window(sdiodev, address); + if (err) + break; + +@@ -716,7 +724,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + dev_kfree_skb(pkt); + + /* Return the window to backplane enumeration space for core access */ +- if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad)) ++ if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad)) + brcmf_err("FAILED to set window back to 0x%x\n", + sdiodev->sbwad); + diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0007-brcmfmac-remove-unnecessary-call-to-brcmf_sdiod_set_.patch b/root/package/kernel/mac80211/patches/312-v4.16-0007-brcmfmac-remove-unnecessary-call-to-brcmf_sdiod_set_.patch new file mode 100644 index 00000000..b9410dd7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0007-brcmfmac-remove-unnecessary-call-to-brcmf_sdiod_set_.patch @@ -0,0 +1,32 @@ +From c900072bd6faff089aa4fb7b19136a2a0fe3baf0 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:32 +0100 +Subject: [PATCH] brcmfmac: remove unnecessary call to + brcmf_sdiod_set_backplane_window() + +All functions that might require the window address changing call +brcmf_sdiod_set_backplane_window() prior to access. Thus resetting +the window is not required. + +Signed-off-by: Ian Molton +[arend: corrected the driver prefix in the subject] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -723,11 +723,6 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + + dev_kfree_skb(pkt); + +- /* Return the window to backplane enumeration space for core access */ +- if (brcmf_sdiod_set_backplane_window(sdiodev, sdiodev->sbwad)) +- brcmf_err("FAILED to set window back to 0x%x\n", +- sdiodev->sbwad); +- + sdio_release_host(sdiodev->func[1]); + + return err; diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch b/root/package/kernel/mac80211/patches/312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch new file mode 100644 index 00000000..f9e5df55 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0008-brcmfmac-Cleanup-offsetof.patch @@ -0,0 +1,134 @@ +From e4c05fc3c0a6c79376f72f17d08014477e962ada Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:33 +0100 +Subject: [PATCH] brcmfmac: Cleanup offsetof() + +Create a macro to make the code a bit more readable, whilst we're stuck +with using struct element offsets as register offsets. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +[arend: rename macro to SD_REG] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 35 +++++++++------------- + 1 file changed, 14 insertions(+), 21 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -161,6 +161,8 @@ struct rte_console { + + #define CORE_BUS_REG(base, field) \ + (base + offsetof(struct sdpcmd_regs, field)) ++#define SD_REG(field) \ ++ (offsetof(struct sdpcmd_regs, field)) + + /* SDIO function 1 register CHIPCLKCSR */ + /* Force ALP request to backplane */ +@@ -1087,12 +1089,10 @@ static u32 brcmf_sdio_hostmail(struct br + brcmf_dbg(SDIO, "Enter\n"); + + /* Read mailbox data and ack that we did so */ +- ret = r_sdreg32(bus, &hmb_data, +- offsetof(struct sdpcmd_regs, tohostmailboxdata)); ++ ret = r_sdreg32(bus, &hmb_data, SD_REG(tohostmailboxdata)); + + if (ret == 0) +- w_sdreg32(bus, SMB_INT_ACK, +- offsetof(struct sdpcmd_regs, tosbmailbox)); ++ w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox)); + bus->sdcnt.f1regdata += 2; + + /* dongle indicates the firmware has halted/crashed */ +@@ -1207,8 +1207,7 @@ static void brcmf_sdio_rxfail(struct brc + + if (rtx) { + bus->sdcnt.rxrtx++; +- err = w_sdreg32(bus, SMB_NAK, +- offsetof(struct sdpcmd_regs, tosbmailbox)); ++ err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox)); + + bus->sdcnt.f1regdata++; + if (err == 0) +@@ -2333,9 +2332,7 @@ static uint brcmf_sdio_sendfromq(struct + if (!bus->intr) { + /* Check device status, signal pending interrupt */ + sdio_claim_host(bus->sdiodev->func[1]); +- ret = r_sdreg32(bus, &intstatus, +- offsetof(struct sdpcmd_regs, +- intstatus)); ++ ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus)); + sdio_release_host(bus->sdiodev->func[1]); + bus->sdcnt.f2txdata++; + if (ret != 0) +@@ -2441,7 +2438,7 @@ static void brcmf_sdio_bus_stop(struct d + brcmf_sdio_bus_sleep(bus, false, false); + + /* Disable and clear interrupts at the chip level also */ +- w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); ++ w_sdreg32(bus, 0, SD_REG(hostintmask)); + local_hostintmask = bus->hostintmask; + bus->hostintmask = 0; + +@@ -2460,8 +2457,7 @@ static void brcmf_sdio_bus_stop(struct d + sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); + + /* Clear any pending interrupts now that F2 is disabled */ +- w_sdreg32(bus, local_hostintmask, +- offsetof(struct sdpcmd_regs, intstatus)); ++ w_sdreg32(bus, local_hostintmask, SD_REG(intstatus)); + + sdio_release_host(sdiodev->func[1]); + } +@@ -2507,7 +2503,7 @@ static int brcmf_sdio_intr_rstatus(struc + int ret; + + buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); +- addr = buscore->base + offsetof(struct sdpcmd_regs, intstatus); ++ addr = buscore->base + SD_REG(intstatus); + + val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); + bus->sdcnt.f1regdata++; +@@ -2584,11 +2580,9 @@ static void brcmf_sdio_dpc(struct brcmf_ + */ + if (intstatus & I_HMB_FC_CHANGE) { + intstatus &= ~I_HMB_FC_CHANGE; +- err = w_sdreg32(bus, I_HMB_FC_CHANGE, +- offsetof(struct sdpcmd_regs, intstatus)); ++ err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus)); + +- err = r_sdreg32(bus, &newstatus, +- offsetof(struct sdpcmd_regs, intstatus)); ++ err = r_sdreg32(bus, &newstatus, SD_REG(intstatus)); + bus->sdcnt.f1regdata += 2; + atomic_set(&bus->fcstate, + !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE))); +@@ -3771,7 +3765,7 @@ static void brcmf_sdio_buscore_activate( + + /* clear all interrupts */ + core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV); +- reg_addr = core->base + offsetof(struct sdpcmd_regs, intstatus); ++ reg_addr = core->base + SD_REG(intstatus); + brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + + if (rstvec) +@@ -4067,7 +4061,7 @@ static void brcmf_sdio_firmware_callback + + /* Enable function 2 (frame transfers) */ + w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, +- offsetof(struct sdpcmd_regs, tosbmailboxdata)); ++ SD_REG(tosbmailboxdata)); + err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]); + + +@@ -4077,8 +4071,7 @@ static void brcmf_sdio_firmware_callback + if (!err) { + /* Set up the interrupt mask and enable interrupts */ + bus->hostintmask = HOSTINTMASK; +- w_sdreg32(bus, bus->hostintmask, +- offsetof(struct sdpcmd_regs, hostintmask)); ++ w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask)); + + brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); + } else { diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0009-brcmfmac-Remove-unused-macro.patch b/root/package/kernel/mac80211/patches/312-v4.16-0009-brcmfmac-Remove-unused-macro.patch new file mode 100644 index 00000000..df72a70b --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0009-brcmfmac-Remove-unused-macro.patch @@ -0,0 +1,26 @@ +From 5cfe38f1f8d3c6b98e15b8cfde05028a3c79930b Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:34 +0100 +Subject: [PATCH] brcmfmac: Remove unused macro. + +This macro is used exactly nowhere in the code. Delete it. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -159,8 +159,6 @@ struct rte_console { + /* manfid tuple length, include tuple, link bytes */ + #define SBSDIO_CIS_MANFID_TUPLE_LEN 6 + +-#define CORE_BUS_REG(base, field) \ +- (base + offsetof(struct sdpcmd_regs, field)) + #define SD_REG(field) \ + (offsetof(struct sdpcmd_regs, field)) + diff --git a/root/package/kernel/mac80211/patches/312-v4.16-0010-brcmfmac-Remove-repeated-calls-to-brcmf_chip_get_cor.patch b/root/package/kernel/mac80211/patches/312-v4.16-0010-brcmfmac-Remove-repeated-calls-to-brcmf_chip_get_cor.patch new file mode 100644 index 00000000..69fbf5c8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/312-v4.16-0010-brcmfmac-Remove-repeated-calls-to-brcmf_chip_get_cor.patch @@ -0,0 +1,128 @@ +From 21a10846d09db3c5e3bdfb0be0fc7aa9fdc7000a Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Fri, 8 Dec 2017 13:10:35 +0100 +Subject: [PATCH] brcmfmac: Remove repeated calls to brcmf_chip_get_core() + +There is no need to repeatdly call brcmf_chip_get_core(), which +traverses a list of cores every time its called (including during +register access code!). + +Call it once, and store a pointer to the core structure. The existing +code does nto keep track of users of the cores anyway, and even so, this +will allow for easier refcounting in future. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 25 +++++++++++++--------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -436,6 +436,7 @@ struct brcmf_sdio_count { + struct brcmf_sdio { + struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ + struct brcmf_chip *ci; /* Chip info struct */ ++ struct brcmf_core *sdio_core; /* sdio core info struct */ + + u32 hostintmask; /* Copy of Host Interrupt Mask */ + atomic_t intstatus; /* Intstatus bits (events) pending */ +@@ -665,10 +666,9 @@ static bool data_ok(struct brcmf_sdio *b + */ + static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) + { +- struct brcmf_core *core; ++ struct brcmf_core *core = bus->sdio_core; + int ret; + +- core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); + *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret); + + return ret; +@@ -676,10 +676,9 @@ static int r_sdreg32(struct brcmf_sdio * + + static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) + { +- struct brcmf_core *core; ++ struct brcmf_core *core = bus->sdio_core; + int ret; + +- core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); + brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret); + + return ret; +@@ -2495,12 +2494,11 @@ static inline void brcmf_sdio_clrintr(st + + static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) + { +- struct brcmf_core *buscore; ++ struct brcmf_core *buscore = bus->sdio_core; + u32 addr; + unsigned long val; + int ret; + +- buscore = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); + addr = buscore->base + SD_REG(intstatus); + + val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); +@@ -3377,13 +3375,14 @@ static void brcmf_sdio_sr_init(struct br + /* enable KSO bit */ + static int brcmf_sdio_kso_init(struct brcmf_sdio *bus) + { ++ struct brcmf_core *core = bus->sdio_core; + u8 val; + int err = 0; + + brcmf_dbg(TRACE, "Enter\n"); + + /* KSO bit added in SDIO core rev 12 */ +- if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) ++ if (core->rev < 12) + return 0; + + val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); +@@ -3412,6 +3411,7 @@ static int brcmf_sdio_bus_preinit(struct + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio *bus = sdiodev->bus; ++ struct brcmf_core *core = bus->sdio_core; + uint pad_size; + u32 value; + int err; +@@ -3420,7 +3420,7 @@ static int brcmf_sdio_bus_preinit(struct + * a device perspective, ie. bus:txglom affects the + * bus transfers from device to host. + */ +- if (brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV)->rev < 12) { ++ if (core->rev < 12) { + /* for sdio core rev < 12, disable txgloming */ + value = 0; + err = brcmf_iovar_data_set(dev, "bus:txglom", &value, +@@ -3758,11 +3758,10 @@ static void brcmf_sdio_buscore_activate( + u32 rstvec) + { + struct brcmf_sdio_dev *sdiodev = ctx; +- struct brcmf_core *core; ++ struct brcmf_core *core = sdiodev->bus->sdio_core; + u32 reg_addr; + + /* clear all interrupts */ +- core = brcmf_chip_get_core(chip, BCMA_CORE_SDIO_DEV); + reg_addr = core->base + SD_REG(intstatus); + brcmf_sdiod_writel(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + +@@ -3843,6 +3842,12 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + bus->ci = NULL; + goto fail; + } ++ ++ /* Pick up the SDIO core info struct from chip.c */ ++ bus->sdio_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_SDIO_DEV); ++ if (!bus->sdio_core) ++ goto fail; ++ + sdiodev->settings = brcmf_get_module_param(sdiodev->dev, + BRCMF_BUSTYPE_SDIO, + bus->ci->chip, diff --git a/root/package/kernel/mac80211/patches/313-v4.16-0001-brcmfmac-enlarge-buffer-size-of-caps-to-512-bytes.patch b/root/package/kernel/mac80211/patches/313-v4.16-0001-brcmfmac-enlarge-buffer-size-of-caps-to-512-bytes.patch new file mode 100644 index 00000000..731b7eda --- /dev/null +++ b/root/package/kernel/mac80211/patches/313-v4.16-0001-brcmfmac-enlarge-buffer-size-of-caps-to-512-bytes.patch @@ -0,0 +1,44 @@ +From 7762bb134e3b40e8ee2611365775b7432190a9c7 Mon Sep 17 00:00:00 2001 +From: Wright Feng +Date: Mon, 11 Dec 2017 15:38:21 +0800 +Subject: [PATCH] brcmfmac: enlarge buffer size of caps to 512 bytes + +The buffer size of return of cap iovar is greater than 256 bytes in some +firmwares. For instance, the return size of cap iovar is 271 bytes in 4373 +13.10.246.79 firmare. It makes feature capability parsing failed because +caps buffer is default value. +So we enlarge caps buffer size to 512 bytes and add the error print for +cap iovar error. + +Signed-off-by: Wright Feng +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -130,13 +130,19 @@ static void brcmf_feat_iovar_data_set(st + } + } + ++#define MAX_CAPS_BUFFER_SIZE 512 + static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) + { +- char caps[256]; ++ char caps[MAX_CAPS_BUFFER_SIZE]; + enum brcmf_feat_id id; +- int i; ++ int i, err; ++ ++ err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); ++ if (err) { ++ brcmf_err("could not get firmware cap (%d)\n", err); ++ return; ++ } + +- brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); + brcmf_dbg(INFO, "[ %s]\n", caps); + + for (i = 0; i < ARRAY_SIZE(brcmf_fwcap_map); i++) { diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0001-brcmfmac-Remove-r-w-_sdreg32.patch b/root/package/kernel/mac80211/patches/314-v4.16-0001-brcmfmac-Remove-r-w-_sdreg32.patch new file mode 100644 index 00000000..291cd5d7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0001-brcmfmac-Remove-r-w-_sdreg32.patch @@ -0,0 +1,227 @@ +From 3d110df8f74781354051e4bb1e3e97fa368b2f80 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Tue, 19 Dec 2017 13:47:07 +0100 +Subject: [PATCH] brcmfmac: Remove {r,w}_sdreg32 + +Remove yet another IO function from the code and replace with one +that already exists. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +[arend: keep address calculation, ie. (base + offset) in one line] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 88 +++++++++++----------- + 1 file changed, 42 insertions(+), 46 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -660,30 +660,6 @@ static bool data_ok(struct brcmf_sdio *b + ((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0; + } + +-/* +- * Reads a register in the SDIO hardware block. This block occupies a series of +- * adresses on the 32 bit backplane bus. +- */ +-static int r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) +-{ +- struct brcmf_core *core = bus->sdio_core; +- int ret; +- +- *regvar = brcmf_sdiod_readl(bus->sdiodev, core->base + offset, &ret); +- +- return ret; +-} +- +-static int w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) +-{ +- struct brcmf_core *core = bus->sdio_core; +- int ret; +- +- brcmf_sdiod_writel(bus->sdiodev, core->base + reg_offset, regval, &ret); +- +- return ret; +-} +- + static int + brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) + { +@@ -1078,6 +1054,8 @@ static void brcmf_sdio_get_console_addr( + + static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) + { ++ struct brcmf_sdio_dev *sdiod = bus->sdiodev; ++ struct brcmf_core *core = bus->sdio_core; + u32 intstatus = 0; + u32 hmb_data; + u8 fcbits; +@@ -1086,10 +1064,14 @@ static u32 brcmf_sdio_hostmail(struct br + brcmf_dbg(SDIO, "Enter\n"); + + /* Read mailbox data and ack that we did so */ +- ret = r_sdreg32(bus, &hmb_data, SD_REG(tohostmailboxdata)); ++ hmb_data = brcmf_sdiod_readl(sdiod, ++ core->base + SD_REG(tohostmailboxdata), ++ &ret); ++ ++ if (!ret) ++ brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailbox), ++ SMB_INT_ACK, &ret); + +- if (ret == 0) +- w_sdreg32(bus, SMB_INT_ACK, SD_REG(tosbmailbox)); + bus->sdcnt.f1regdata += 2; + + /* dongle indicates the firmware has halted/crashed */ +@@ -1163,6 +1145,8 @@ static u32 brcmf_sdio_hostmail(struct br + + static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) + { ++ struct brcmf_sdio_dev *sdiod = bus->sdiodev; ++ struct brcmf_core *core = bus->sdio_core; + uint retries = 0; + u16 lastrbc; + u8 hi, lo; +@@ -1204,7 +1188,8 @@ static void brcmf_sdio_rxfail(struct brc + + if (rtx) { + bus->sdcnt.rxrtx++; +- err = w_sdreg32(bus, SMB_NAK, SD_REG(tosbmailbox)); ++ brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailbox), ++ SMB_NAK, &err); + + bus->sdcnt.f1regdata++; + if (err == 0) +@@ -2291,6 +2276,7 @@ static uint brcmf_sdio_sendfromq(struct + { + struct sk_buff *pkt; + struct sk_buff_head pktq; ++ u32 intstat_addr = bus->sdio_core->base + SD_REG(intstatus); + u32 intstatus = 0; + int ret = 0, prec_out, i; + uint cnt = 0; +@@ -2329,7 +2315,8 @@ static uint brcmf_sdio_sendfromq(struct + if (!bus->intr) { + /* Check device status, signal pending interrupt */ + sdio_claim_host(bus->sdiodev->func[1]); +- ret = r_sdreg32(bus, &intstatus, SD_REG(intstatus)); ++ intstatus = brcmf_sdiod_readl(bus->sdiodev, ++ intstat_addr, &ret); + sdio_release_host(bus->sdiodev->func[1]); + bus->sdcnt.f2txdata++; + if (ret != 0) +@@ -2413,12 +2400,13 @@ static int brcmf_sdio_tx_ctrlframe(struc + + static void brcmf_sdio_bus_stop(struct device *dev) + { +- u32 local_hostintmask; +- u8 saveclk; +- int err; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio *bus = sdiodev->bus; ++ struct brcmf_core *core = bus->sdio_core; ++ u32 local_hostintmask; ++ u8 saveclk; ++ int err; + + brcmf_dbg(TRACE, "Enter\n"); + +@@ -2435,7 +2423,9 @@ static void brcmf_sdio_bus_stop(struct d + brcmf_sdio_bus_sleep(bus, false, false); + + /* Disable and clear interrupts at the chip level also */ +- w_sdreg32(bus, 0, SD_REG(hostintmask)); ++ brcmf_sdiod_writel(sdiodev, core->base + SD_REG(hostintmask), ++ 0, NULL); ++ + local_hostintmask = bus->hostintmask; + bus->hostintmask = 0; + +@@ -2454,7 +2444,8 @@ static void brcmf_sdio_bus_stop(struct d + sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); + + /* Clear any pending interrupts now that F2 is disabled */ +- w_sdreg32(bus, local_hostintmask, SD_REG(intstatus)); ++ brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus), ++ local_hostintmask, NULL); + + sdio_release_host(sdiodev->func[1]); + } +@@ -2521,7 +2512,9 @@ static int brcmf_sdio_intr_rstatus(struc + + static void brcmf_sdio_dpc(struct brcmf_sdio *bus) + { ++ struct brcmf_sdio_dev *sdiod = bus->sdiodev; + u32 newstatus = 0; ++ u32 intstat_addr = bus->sdio_core->base + SD_REG(intstatus); + unsigned long intstatus; + uint txlimit = bus->txbound; /* Tx frames to send before resched */ + uint framecnt; /* Temporary counter of tx/rx frames */ +@@ -2576,9 +2569,10 @@ static void brcmf_sdio_dpc(struct brcmf_ + */ + if (intstatus & I_HMB_FC_CHANGE) { + intstatus &= ~I_HMB_FC_CHANGE; +- err = w_sdreg32(bus, I_HMB_FC_CHANGE, SD_REG(intstatus)); ++ brcmf_sdiod_writel(sdiod, intstat_addr, I_HMB_FC_CHANGE, &err); ++ ++ newstatus = brcmf_sdiod_readl(sdiod, intstat_addr, &err); + +- err = r_sdreg32(bus, &newstatus, SD_REG(intstatus)); + bus->sdcnt.f1regdata += 2; + atomic_set(&bus->fcstate, + !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE))); +@@ -4017,22 +4011,21 @@ static void brcmf_sdio_firmware_callback + const struct firmware *code, + void *nvram, u32 nvram_len) + { +- struct brcmf_bus *bus_if; +- struct brcmf_sdio_dev *sdiodev; +- struct brcmf_sdio *bus; ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; ++ struct brcmf_sdio *bus = sdiodev->bus; ++ struct brcmf_sdio_dev *sdiod = bus->sdiodev; ++ struct brcmf_core *core = bus->sdio_core; + u8 saveclk; + + brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); +- bus_if = dev_get_drvdata(dev); +- sdiodev = bus_if->bus_priv.sdio; ++ + if (err) + goto fail; + + if (!bus_if->drvr) + return; + +- bus = sdiodev->bus; +- + /* try to download image and nvram to the dongle */ + bus->alp_only = true; + err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); +@@ -4063,8 +4056,9 @@ static void brcmf_sdio_firmware_callback + } + + /* Enable function 2 (frame transfers) */ +- w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, +- SD_REG(tosbmailboxdata)); ++ brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata), ++ SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL); ++ + err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]); + + +@@ -4074,7 +4068,9 @@ static void brcmf_sdio_firmware_callback + if (!err) { + /* Set up the interrupt mask and enable interrupts */ + bus->hostintmask = HOSTINTMASK; +- w_sdreg32(bus, bus->hostintmask, SD_REG(hostintmask)); ++ brcmf_sdiod_writel(sdiod, core->base + SD_REG(hostintmask), ++ bus->hostintmask, NULL); ++ + + brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); + } else { diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0002-brcmfmac-Rename-buscore-to-core-for-consistency.patch b/root/package/kernel/mac80211/patches/314-v4.16-0002-brcmfmac-Rename-buscore-to-core-for-consistency.patch new file mode 100644 index 00000000..e9b56283 --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0002-brcmfmac-Rename-buscore-to-core-for-consistency.patch @@ -0,0 +1,33 @@ +From dbda7dacb79a377e8ed9d38ce0e4a58b70aa9060 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 19 Dec 2017 13:47:08 +0100 +Subject: [PATCH] brcmfmac: Rename buscore to core for consistency + +Avoid confusion with unrelated _buscore labels. + +Signed-off-by: Ian Molton +Acked-by: Arend van Spriel +[arend: only do the rename] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -2485,12 +2485,12 @@ static inline void brcmf_sdio_clrintr(st + + static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) + { +- struct brcmf_core *buscore = bus->sdio_core; ++ struct brcmf_core *core = bus->sdio_core; + u32 addr; + unsigned long val; + int ret; + +- addr = buscore->base + SD_REG(intstatus); ++ addr = core->base + SD_REG(intstatus); + + val = brcmf_sdiod_readl(bus->sdiodev, addr, &ret); + bus->sdcnt.f1regdata++; diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0003-brcmfmac-stabilise-the-value-of-sbwad-in-use-for-som.patch b/root/package/kernel/mac80211/patches/314-v4.16-0003-brcmfmac-stabilise-the-value-of-sbwad-in-use-for-som.patch new file mode 100644 index 00000000..3828c320 --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0003-brcmfmac-stabilise-the-value-of-sbwad-in-use-for-som.patch @@ -0,0 +1,82 @@ +From 874bb8e49b7c6368f8ff9f2566c7bd06a2249be0 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Tue, 19 Dec 2017 13:47:09 +0100 +Subject: [PATCH] brcmfmac: stabilise the value of ->sbwad in use for some xfer + routines. + +The IO functions operate within the Chipcommon IO window. Explicitly +set this, rather than relying on the last initialisation IO access to +leave it set to the right value by chance. + +Signed-off-by: Ian Molton +Acked-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 ++++---- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 5 +++++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 1 + + 3 files changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -529,7 +529,7 @@ int brcmf_sdiod_recv_buf(struct brcmf_sd + + int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt) + { +- u32 addr = sdiodev->sbwad; ++ u32 addr = sdiodev->cc_core->base; + int err = 0; + + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); +@@ -552,7 +552,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + { + struct sk_buff *glom_skb = NULL; + struct sk_buff *skb; +- u32 addr = sdiodev->sbwad; ++ u32 addr = sdiodev->cc_core->base; + int err = 0; + + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", +@@ -593,7 +593,7 @@ done: + int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) + { + struct sk_buff *mypkt; +- u32 addr = sdiodev->sbwad; ++ u32 addr = sdiodev->cc_core->base; + int err; + + mypkt = brcmu_pkt_buf_get_skb(nbytes); +@@ -625,7 +625,7 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + struct sk_buff_head *pktq) + { + struct sk_buff *skb; +- u32 addr = sdiodev->sbwad; ++ u32 addr = sdiodev->cc_core->base; + int err; + + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3842,6 +3842,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + if (!bus->sdio_core) + goto fail; + ++ /* Pick up the CHIPCOMMON core info struct, for bulk IO in bcmsdh.c */ ++ sdiodev->cc_core = brcmf_chip_get_core(bus->ci, BCMA_CORE_CHIPCOMMON); ++ if (!sdiodev->cc_core) ++ goto fail; ++ + sdiodev->settings = brcmf_get_module_param(sdiodev->dev, + BRCMF_BUSTYPE_SDIO, + bus->ci->chip, +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -178,6 +178,7 @@ struct brcmf_sdio_dev { + struct sdio_func *func[SDIO_MAX_FUNCS]; + u8 num_funcs; /* Supported funcs on client */ + u32 sbwad; /* Save backplane window address */ ++ struct brcmf_core *cc_core; /* chipcommon core info struct */ + struct brcmf_sdio *bus; + struct device *dev; + struct brcmf_bus *bus_if; diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0004-brcmfmac-Correctly-handle-accesses-to-SDIO-func0.patch b/root/package/kernel/mac80211/patches/314-v4.16-0004-brcmfmac-Correctly-handle-accesses-to-SDIO-func0.patch new file mode 100644 index 00000000..86b269a3 --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0004-brcmfmac-Correctly-handle-accesses-to-SDIO-func0.patch @@ -0,0 +1,45 @@ +From 508422f3695bf66f7b85fb4723c22f5166003ec6 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Tue, 19 Dec 2017 13:47:10 +0100 +Subject: [PATCH] brcmfmac: Correctly handle accesses to SDIO func0 + +Rather than workaround the restrictions on func0 addressing in the +driver, set MMC_QUIRK_LENIENT_FN0 + +Signed-off-by: Ian Molton +Acked-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 ++++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 4 ++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -995,6 +995,10 @@ static int brcmf_ops_sdio_probe(struct s + brcmf_dbg(SDIO, "Function#: %d\n", func->num); + + dev = &func->dev; ++ ++ /* Set MMC_QUIRK_LENIENT_FN0 for this card */ ++ func->card->quirks |= MMC_QUIRK_LENIENT_FN0; ++ + /* prohibit ACPI power management for this device */ + brcmf_sdiod_acpi_set_power_manageable(dev, 0); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -297,10 +297,10 @@ void brcmf_sdiod_intr_unregister(struct + /* SDIO device register access interface */ + /* Accessors for SDIO Function 0 */ + #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ +- sdio_readb((sdiodev)->func[0], (addr), (r)) ++ sdio_f0_readb((sdiodev)->func[0], (addr), (r)) + + #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ +- sdio_writeb((sdiodev)->func[0], (v), (addr), (ret)) ++ sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret)) + + /* Accessors for SDIO Function 1 */ + #define brcmf_sdiod_readb(sdiodev, addr, r) \ diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0005-brcmfmac-Remove-func0-from-function-array.patch b/root/package/kernel/mac80211/patches/314-v4.16-0005-brcmfmac-Remove-func0-from-function-array.patch new file mode 100644 index 00000000..715b8656 --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0005-brcmfmac-Remove-func0-from-function-array.patch @@ -0,0 +1,111 @@ +From 99d7b6fdfc8c24052c92c720330d31ca1332f996 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Tue, 19 Dec 2017 13:47:11 +0100 +Subject: [PATCH] brcmfmac: Remove func0 from function array + +func0 is not provided by the mmc stack as a function when probing. +Instead providing specific access functions to read/write it. + +This prepares for a patch to remove the actual array entry itself. + +Signed-off-by: Ian Molton +Acked-by: Arend van Spriel +[arend: rephrased the commit message] +[arend: removed unrelated comment for which separate patch is warranted] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 5 +---- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 ++++--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 13 ++++++------- + 3 files changed, 11 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -1022,8 +1022,7 @@ static int brcmf_ops_sdio_probe(struct s + /* store refs to functions used. mmc_card does + * not hold the F0 function pointer. + */ +- sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL); +- sdiodev->func[0]->num = 0; ++ sdiodev->func[0] = NULL; + sdiodev->func[1] = func->card->sdio_func[0]; + sdiodev->func[2] = func; + +@@ -1049,7 +1048,6 @@ static int brcmf_ops_sdio_probe(struct s + fail: + dev_set_drvdata(&func->dev, NULL); + dev_set_drvdata(&sdiodev->func[1]->dev, NULL); +- kfree(sdiodev->func[0]); + kfree(sdiodev); + kfree(bus_if); + return err; +@@ -1082,7 +1080,6 @@ static void brcmf_ops_sdio_remove(struct + dev_set_drvdata(&sdiodev->func[2]->dev, NULL); + + kfree(bus_if); +- kfree(sdiodev->func[0]); + kfree(sdiodev); + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3771,9 +3771,10 @@ static u32 brcmf_sdio_buscore_read32(voi + u32 val, rev; + + val = brcmf_sdiod_readl(sdiodev, addr, NULL); +- if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || +- sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) && +- addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { ++ ++ if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || ++ sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) && ++ addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { + rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; + if (rev >= 2) { + val &= ~CID_ID_MASK; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -21,7 +21,9 @@ + #include + #include "firmware.h" + +-#define SDIO_FUNC_0 0 ++/* Maximum number of I/O funcs */ ++#define NUM_SDIO_FUNCS 3 ++ + #define SDIO_FUNC_1 1 + #define SDIO_FUNC_2 2 + +@@ -39,9 +41,6 @@ + #define INTR_STATUS_FUNC1 0x2 + #define INTR_STATUS_FUNC2 0x4 + +-/* Maximum number of I/O funcs */ +-#define SDIOD_MAX_IOFUNCS 7 +- + /* mask of register map */ + #define REG_F0_REG_MASK 0x7FF + #define REG_F1_MISC_MASK 0x1FFFF +@@ -175,7 +174,7 @@ struct brcmf_sdio; + struct brcmf_sdiod_freezer; + + struct brcmf_sdio_dev { +- struct sdio_func *func[SDIO_MAX_FUNCS]; ++ struct sdio_func *func[NUM_SDIO_FUNCS]; + u8 num_funcs; /* Supported funcs on client */ + u32 sbwad; /* Save backplane window address */ + struct brcmf_core *cc_core; /* chipcommon core info struct */ +@@ -297,10 +296,10 @@ void brcmf_sdiod_intr_unregister(struct + /* SDIO device register access interface */ + /* Accessors for SDIO Function 0 */ + #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ +- sdio_f0_readb((sdiodev)->func[0], (addr), (r)) ++ sdio_f0_readb((sdiodev)->func[1], (addr), (r)) + + #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ +- sdio_f0_writeb((sdiodev)->func[0], (v), (addr), (ret)) ++ sdio_f0_writeb((sdiodev)->func[1], (v), (addr), (ret)) + + /* Accessors for SDIO Function 1 */ + #define brcmf_sdiod_readb(sdiodev, addr, r) \ diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0006-brcmfmac-More-efficient-and-slightly-easier-to-read-.patch b/root/package/kernel/mac80211/patches/314-v4.16-0006-brcmfmac-More-efficient-and-slightly-easier-to-read-.patch new file mode 100644 index 00000000..71e4894b --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0006-brcmfmac-More-efficient-and-slightly-easier-to-read-.patch @@ -0,0 +1,40 @@ +From bcadaaa097c7ec103fe75f9da41f8fe52693b644 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 19 Dec 2017 13:47:12 +0100 +Subject: [PATCH] brcmfmac: More efficient and slightly easier to read fixup + for 4339 chips + +Its more efficient to test the register we're interested in first, +potentially avoiding two more comparisons, and therefore always avoiding +one comparison per call on all other chips. + +Signed-off-by: Ian Molton +[arend: fix some checkpatch warnings] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3772,15 +3772,16 @@ static u32 brcmf_sdio_buscore_read32(voi + + val = brcmf_sdiod_readl(sdiodev, addr, NULL); + +- if ((sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || +- sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339) && +- addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { ++ if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) && ++ (sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339 || ++ sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) { + rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; + if (rev >= 2) { + val &= ~CID_ID_MASK; + val |= BRCM_CC_4339_CHIP_ID; + } + } ++ + return val; + } + diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch b/root/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch new file mode 100644 index 00000000..4354a708 --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0007-brcmfmac-Replace-function-index-with-function-pointe.patch @@ -0,0 +1,347 @@ +From 00eb62cfc5f806b003fe5d54c8b5fe9a9665482f Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Tue, 19 Dec 2017 13:47:13 +0100 +Subject: [PATCH] brcmfmac: Replace function index with function pointer + +In preparation for removing the function array, remove all code that +refers to function by index and replace with pointers to the function +itself. + +Signed-off-by: Ian Molton +Reviewed-by: Arend van Spriel +[arend: replace BUG() with WARN() macro] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 85 ++++++++++++---------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 15 ++-- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 6 +- + 3 files changed, 56 insertions(+), 50 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -291,8 +291,9 @@ out: + *ret = retval; + } + +-static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, uint fn, +- u32 addr, struct sk_buff *pkt) ++static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, ++ struct sdio_func *func, u32 addr, ++ struct sk_buff *pkt) + { + unsigned int req_sz; + int err; +@@ -301,13 +302,19 @@ static int brcmf_sdiod_buff_read(struct + req_sz = pkt->len + 3; + req_sz &= (uint)~3; + +- if (fn == 1) +- err = sdio_memcpy_fromio(sdiodev->func[fn], +- ((u8 *)(pkt->data)), addr, req_sz); +- else +- /* function 2 read is FIFO operation */ +- err = sdio_readsb(sdiodev->func[fn], +- ((u8 *)(pkt->data)), addr, req_sz); ++ switch (func->num) { ++ case 1: ++ err = sdio_memcpy_fromio(func, ((u8 *)(pkt->data)), addr, ++ req_sz); ++ break; ++ case 2: ++ err = sdio_readsb(func, ((u8 *)(pkt->data)), addr, req_sz); ++ break; ++ default: ++ /* bail out as things are really fishy here */ ++ WARN(1, "invalid sdio function number: %d\n", func->num); ++ err = -ENOMEDIUM; ++ }; + + if (err == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); +@@ -315,8 +322,9 @@ static int brcmf_sdiod_buff_read(struct + return err; + } + +-static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, uint fn, +- u32 addr, struct sk_buff *pkt) ++static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, ++ struct sdio_func *func, u32 addr, ++ struct sk_buff *pkt) + { + unsigned int req_sz; + int err; +@@ -325,8 +333,7 @@ static int brcmf_sdiod_buff_write(struct + req_sz = pkt->len + 3; + req_sz &= (uint)~3; + +- err = sdio_memcpy_toio(sdiodev->func[fn], addr, +- ((u8 *)(pkt->data)), req_sz); ++ err = sdio_memcpy_toio(func, addr, ((u8 *)(pkt->data)), req_sz); + + if (err == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); +@@ -337,7 +344,7 @@ static int brcmf_sdiod_buff_write(struct + /** + * brcmf_sdiod_sglist_rw - SDIO interface function for block data access + * @sdiodev: brcmfmac sdio device +- * @fn: SDIO function number ++ * @func: SDIO function + * @write: direction flag + * @addr: dongle memory address as source/destination + * @pkt: skb pointer +@@ -346,7 +353,8 @@ static int brcmf_sdiod_buff_write(struct + * stack for block data access. It assumes that the skb passed down by the + * caller has already been padded and aligned. + */ +-static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, ++static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, ++ struct sdio_func *func, + bool write, u32 addr, + struct sk_buff_head *pktlist) + { +@@ -372,7 +380,7 @@ static int brcmf_sdiod_sglist_rw(struct + req_sz = 0; + skb_queue_walk(pktlist, pkt_next) + req_sz += pkt_next->len; +- req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize); ++ req_sz = ALIGN(req_sz, func->cur_blksize); + while (req_sz > PAGE_SIZE) { + pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE); + if (pkt_next == NULL) { +@@ -391,7 +399,7 @@ static int brcmf_sdiod_sglist_rw(struct + target_list = &local_list; + } + +- func_blk_sz = sdiodev->func[fn]->cur_blksize; ++ func_blk_sz = func->cur_blksize; + max_req_sz = sdiodev->max_request_size; + max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count, + target_list->qlen); +@@ -408,10 +416,10 @@ static int brcmf_sdiod_sglist_rw(struct + mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; + mmc_cmd.opcode = SD_IO_RW_EXTENDED; + mmc_cmd.arg = write ? 1<<31 : 0; /* write flag */ +- mmc_cmd.arg |= (fn & 0x7) << 28; /* SDIO func num */ +- mmc_cmd.arg |= 1<<27; /* block mode */ ++ mmc_cmd.arg |= (func->num & 0x7) << 28; /* SDIO func num */ ++ mmc_cmd.arg |= 1 << 27; /* block mode */ + /* for function 1 the addr will be incremented */ +- mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0; ++ mmc_cmd.arg |= (func->num == 1) ? 1 << 26 : 0; + mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; + mmc_req.cmd = &mmc_cmd; + mmc_req.data = &mmc_dat; +@@ -457,11 +465,11 @@ static int brcmf_sdiod_sglist_rw(struct + mmc_cmd.arg |= (addr & 0x1FFFF) << 9; /* address */ + mmc_cmd.arg |= mmc_dat.blocks & 0x1FF; /* block count */ + /* incrementing addr for function 1 */ +- if (fn == 1) ++ if (func->num == 1) + addr += req_sz; + +- mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card); +- mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); ++ mmc_set_data_timeout(&mmc_dat, func->card); ++ mmc_wait_for_req(func->card->host, &mmc_req); + + ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; + if (ret == -ENOMEDIUM) { +@@ -541,7 +549,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + +- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, pkt); ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, pkt); + + done: + return err; +@@ -566,13 +574,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (pktq->qlen == 1) +- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, + pktq->next); + else if (!sdiodev->sg_support) { + glom_skb = brcmu_pkt_buf_get_skb(totlen); + if (!glom_skb) + return -ENOMEM; +- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_2, addr, ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, + glom_skb); + if (err) + goto done; +@@ -582,8 +590,8 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + skb_pull(glom_skb, skb->len); + } + } else +- err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr, +- pktq); ++ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], false, ++ addr, pktq); + + done: + brcmu_pkt_buf_free_skb(glom_skb); +@@ -614,7 +622,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (!err) +- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, addr, mypkt); ++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], addr, ++ mypkt); + + brcmu_pkt_buf_free_skb(mypkt); + +@@ -639,14 +648,14 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + + if (pktq->qlen == 1 || !sdiodev->sg_support) { + skb_queue_walk(pktq, skb) { +- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_2, ++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], + addr, skb); + if (err) + break; + } + } else { +- err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr, +- pktq); ++ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], true, ++ addr, pktq); + } + + return err; +@@ -696,10 +705,10 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + + if (write) { + memcpy(pkt->data, data, dsize); +- err = brcmf_sdiod_buff_write(sdiodev, SDIO_FUNC_1, ++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[1], + sdaddr, pkt); + } else { +- err = brcmf_sdiod_buff_read(sdiodev, SDIO_FUNC_1, ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[1], + sdaddr, pkt); + } + +@@ -728,12 +737,12 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + return err; + } + +-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn) ++int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func) + { + brcmf_dbg(SDIO, "Enter\n"); + + /* Issue abort cmd52 command through F0 */ +- brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, fn, NULL); ++ brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_ABORT, func->num, NULL); + + brcmf_dbg(SDIO, "Exit\n"); + return 0; +@@ -1105,7 +1114,7 @@ static int brcmf_ops_sdio_suspend(struct + + func = container_of(dev, struct sdio_func, dev); + brcmf_dbg(SDIO, "Enter: F%d\n", func->num); +- if (func->num != SDIO_FUNC_1) ++ if (func->num != 1) + return 0; + + +@@ -1134,7 +1143,7 @@ static int brcmf_ops_sdio_resume(struct + struct sdio_func *func = container_of(dev, struct sdio_func, dev); + + brcmf_dbg(SDIO, "Enter: F%d\n", func->num); +- if (func->num != SDIO_FUNC_2) ++ if (func->num != 2) + return 0; + + brcmf_sdiod_freezer_off(sdiodev); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1157,7 +1157,7 @@ static void brcmf_sdio_rxfail(struct brc + rtx ? ", send NAK" : ""); + + if (abort) +- brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); ++ brcmf_sdiod_abort(bus->sdiodev, bus->sdiodev->func[2]); + + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, + &err); +@@ -1209,7 +1209,7 @@ static void brcmf_sdio_txfail(struct brc + brcmf_err("sdio error, abort command and terminate frame\n"); + bus->sdcnt.tx_sderrs++; + +- brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2); ++ brcmf_sdiod_abort(sdiodev, sdiodev->func[2]); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); + bus->sdcnt.f1regdata++; + +@@ -2072,7 +2072,7 @@ static int brcmf_sdio_txpkt_prep_sg(stru + int ntail, ret; + + sdiodev = bus->sdiodev; +- blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; ++ blksize = sdiodev->func[2]->cur_blksize; + /* sg entry alignment should be a divisor of block size */ + WARN_ON(blksize % bus->sgentry_align); + +@@ -2441,7 +2441,7 @@ static void brcmf_sdio_bus_stop(struct d + + /* Turn off the bus (F2), free any pending packets */ + brcmf_dbg(INTR, "disable SDIO interrupts\n"); +- sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); ++ sdio_disable_func(sdiodev->func[2]); + + /* Clear any pending interrupts now that F2 is disabled */ + brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus), +@@ -4066,8 +4066,7 @@ static void brcmf_sdio_firmware_callback + brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata), + SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL); + +- err = sdio_enable_func(sdiodev->func[SDIO_FUNC_2]); +- ++ err = sdio_enable_func(sdiodev->func[2]); + + brcmf_dbg(INFO, "enable F2: err=%d\n", err); + +@@ -4082,7 +4081,7 @@ static void brcmf_sdio_firmware_callback + brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); + } else { + /* Disable F2 again */ +- sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); ++ sdio_disable_func(sdiodev->func[2]); + goto release; + } + +@@ -4219,7 +4218,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + sdio_claim_host(bus->sdiodev->func[1]); + + /* Disable F2 to clear any intermediate frame state on the dongle */ +- sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); ++ sdio_disable_func(bus->sdiodev->func[2]); + + bus->rxflow = false; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -45,9 +45,6 @@ + #define REG_F0_REG_MASK 0x7FF + #define REG_F1_MISC_MASK 0x1FFFF + +-/* as of sdiod rev 0, supports 3 functions */ +-#define SBSDIO_NUM_FUNCTION 3 +- + /* function 0 vendor specific CCCR registers */ + + #define SDIO_CCCR_BRCM_CARDCAP 0xf0 +@@ -350,7 +347,8 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_ + u8 *data, uint size); + + /* Issue an abort to the specified function */ +-int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, u8 fn); ++int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, struct sdio_func *func); ++ + void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev); + void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, + enum brcmf_sdiod_state state); diff --git a/root/package/kernel/mac80211/patches/314-v4.16-0008-brcmfmac-Clean-up-interrupt-macros.patch b/root/package/kernel/mac80211/patches/314-v4.16-0008-brcmfmac-Clean-up-interrupt-macros.patch new file mode 100644 index 00000000..d732c8e5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/314-v4.16-0008-brcmfmac-Clean-up-interrupt-macros.patch @@ -0,0 +1,53 @@ +From 9c3438ed215adba7025268ee1f0b6f7a2af12316 Mon Sep 17 00:00:00 2001 +From: Ian Molton +Date: Tue, 19 Dec 2017 13:47:14 +0100 +Subject: [PATCH] brcmfmac: Clean up interrupt macros + +Make it more obvious that this code acually enables interrupts, and +provide nice definitions for the bits in the register. + +Signed-off-by: Ian Molton +Acked-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 3 ++- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 8 +++++--- + 2 files changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -149,7 +149,8 @@ int brcmf_sdiod_intr_register(struct brc + + /* must configure SDIO_CCCR_IENx to enable irq */ + data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret); +- data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; ++ data |= SDIO_CCCR_IEN_FUNC1 | SDIO_CCCR_IEN_FUNC2 | ++ SDIO_CCCR_IEN_FUNC0; + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret); + + /* redirect, configure and enable io for interrupt signal */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -24,9 +24,6 @@ + /* Maximum number of I/O funcs */ + #define NUM_SDIO_FUNCS 3 + +-#define SDIO_FUNC_1 1 +-#define SDIO_FUNC_2 2 +- + #define SDIOD_FBR_SIZE 0x100 + + /* io_en */ +@@ -52,6 +49,11 @@ + #define SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT BIT(2) + #define SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC BIT(3) + ++/* Interrupt enable bits for each function */ ++#define SDIO_CCCR_IEN_FUNC0 BIT(0) ++#define SDIO_CCCR_IEN_FUNC1 BIT(1) ++#define SDIO_CCCR_IEN_FUNC2 BIT(2) ++ + #define SDIO_CCCR_BRCM_CARDCTRL 0xf1 + #define SDIO_CCCR_BRCM_CARDCTRL_WLANRESET BIT(1) + diff --git a/root/package/kernel/mac80211/patches/315-v4.16-0001-brcmfmac-Support-43455-save-restore-SR-feature-if-FW.patch b/root/package/kernel/mac80211/patches/315-v4.16-0001-brcmfmac-Support-43455-save-restore-SR-feature-if-FW.patch new file mode 100644 index 00000000..d010d23f --- /dev/null +++ b/root/package/kernel/mac80211/patches/315-v4.16-0001-brcmfmac-Support-43455-save-restore-SR-feature-if-FW.patch @@ -0,0 +1,27 @@ +From e3720dad99859251a8b0fe2807275a8afcfb560d Mon Sep 17 00:00:00 2001 +From: Double Lo +Date: Tue, 19 Dec 2017 14:56:44 +0800 +Subject: [PATCH] brcmfmac: Support 43455 save-restore (SR) feature if FW + include -sr + +This patch will add 43455 into the save-restore(SR) capable chip list, so +the SR engine will be enabled with 43455 FW which built-in the -sr +function. + +Signed-off-by: Double Lo +Signed-off-by: Wright Feng +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -1338,6 +1338,7 @@ bool brcmf_chip_sr_capable(struct brcmf_ + switch (pub->chip) { + case BRCM_CC_4354_CHIP_ID: + case BRCM_CC_4356_CHIP_ID: ++ case BRCM_CC_4345_CHIP_ID: + /* explicitly check SR engine enable bit */ + pmu_cc3_mask = BIT(2); + /* fall-through */ diff --git a/root/package/kernel/mac80211/patches/316-v4.16-0001-brcmfmac-Remove-array-of-functions.patch b/root/package/kernel/mac80211/patches/316-v4.16-0001-brcmfmac-Remove-array-of-functions.patch new file mode 100644 index 00000000..bd9de13d --- /dev/null +++ b/root/package/kernel/mac80211/patches/316-v4.16-0001-brcmfmac-Remove-array-of-functions.patch @@ -0,0 +1,1043 @@ +From c9aa7a91de740c537dc8c2f9f3d36fc651371b13 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 9 Jan 2018 13:22:52 +0100 +Subject: [PATCH] brcmfmac: Remove array of functions + +Replace the array of functions with a pair of pointers to the +relevant functions. + +Signed-off-by: Ian Molton +Acked-by: Arend van Spriel +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 115 +++++++------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 168 ++++++++++----------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.h | 15 +- + 3 files changed, 146 insertions(+), 152 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -118,7 +118,7 @@ int brcmf_sdiod_intr_register(struct brc + + ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler, + pdata->oob_irq_flags, "brcmf_oob_intr", +- &sdiodev->func[1]->dev); ++ &sdiodev->func1->dev); + if (ret != 0) { + brcmf_err("request_irq failed %d\n", ret); + return ret; +@@ -132,7 +132,7 @@ int brcmf_sdiod_intr_register(struct brc + } + sdiodev->irq_wake = true; + +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + + if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) { + /* assign GPIO to SDIO core */ +@@ -159,13 +159,13 @@ int brcmf_sdiod_intr_register(struct brc + data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI; + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, + data, &ret); +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + } else { + brcmf_dbg(SDIO, "Entering\n"); +- sdio_claim_host(sdiodev->func[1]); +- sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler); +- sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler); +- sdio_release_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); ++ sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler); ++ sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler); ++ sdio_release_host(sdiodev->func1); + sdiodev->sd_irq_requested = true; + } + +@@ -183,26 +183,26 @@ void brcmf_sdiod_intr_unregister(struct + struct brcmfmac_sdio_pd *pdata; + + pdata = &sdiodev->settings->bus.sdio; +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); + brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, 0, NULL); +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + + sdiodev->oob_irq_requested = false; + if (sdiodev->irq_wake) { + disable_irq_wake(pdata->oob_irq_nr); + sdiodev->irq_wake = false; + } +- free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev); ++ free_irq(pdata->oob_irq_nr, &sdiodev->func1->dev); + sdiodev->irq_en = false; + sdiodev->oob_irq_requested = false; + } + + if (sdiodev->sd_irq_requested) { +- sdio_claim_host(sdiodev->func[1]); +- sdio_release_irq(sdiodev->func[2]); +- sdio_release_irq(sdiodev->func[1]); +- sdio_release_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); ++ sdio_release_irq(sdiodev->func2); ++ sdio_release_irq(sdiodev->func1); ++ sdio_release_host(sdiodev->func1); + sdiodev->sd_irq_requested = false; + } + } +@@ -264,7 +264,7 @@ u32 brcmf_sdiod_readl(struct brcmf_sdio_ + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + +- data = sdio_readl(sdiodev->func[1], addr, &retval); ++ data = sdio_readl(sdiodev->func1, addr, &retval); + + out: + if (ret) +@@ -285,7 +285,7 @@ void brcmf_sdiod_writel(struct brcmf_sdi + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + +- sdio_writel(sdiodev->func[1], data, addr, &retval); ++ sdio_writel(sdiodev->func1, data, addr, &retval); + + out: + if (ret) +@@ -550,7 +550,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, pkt); ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, pkt); + + done: + return err; +@@ -575,13 +575,13 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (pktq->qlen == 1) +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, + pktq->next); + else if (!sdiodev->sg_support) { + glom_skb = brcmu_pkt_buf_get_skb(totlen); + if (!glom_skb) + return -ENOMEM; +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[2], addr, ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, + glom_skb); + if (err) + goto done; +@@ -591,7 +591,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + skb_pull(glom_skb, skb->len); + } + } else +- err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], false, ++ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func2, false, + addr, pktq); + + done: +@@ -623,7 +623,7 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (!err) +- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], addr, ++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2, addr, + mypkt); + + brcmu_pkt_buf_free_skb(mypkt); +@@ -649,13 +649,13 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + + if (pktq->qlen == 1 || !sdiodev->sg_support) { + skb_queue_walk(pktq, skb) { +- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[2], ++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2, + addr, skb); + if (err) + break; + } + } else { +- err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func[2], true, ++ err = brcmf_sdiod_sglist_rw(sdiodev, sdiodev->func2, true, + addr, pktq); + } + +@@ -686,7 +686,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + else + dsize = size; + +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + + /* Do the transfer(s) */ + while (size) { +@@ -706,10 +706,10 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + + if (write) { + memcpy(pkt->data, data, dsize); +- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func[1], ++ err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func1, + sdaddr, pkt); + } else { +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func[1], ++ err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func1, + sdaddr, pkt); + } + +@@ -733,7 +733,7 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + + dev_kfree_skb(pkt); + +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + + return err; + } +@@ -757,7 +757,7 @@ void brcmf_sdiod_sgtable_alloc(struct br + uint nents; + int err; + +- func = sdiodev->func[2]; ++ func = sdiodev->func2; + host = func->card->host; + sdiodev->sg_support = host->max_segs > 1; + max_blocks = min_t(uint, host->max_blk_count, 511u); +@@ -818,17 +818,17 @@ static int brcmf_sdiod_freezer_on(struct + brcmf_sdio_trigger_dpc(sdiodev->bus); + wait_event(sdiodev->freezer->thread_freeze, + atomic_read(expect) == sdiodev->freezer->frozen_count); +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + res = brcmf_sdio_sleep(sdiodev->bus, true); +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + return res; + } + + static void brcmf_sdiod_freezer_off(struct brcmf_sdio_dev *sdiodev) + { +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + brcmf_sdio_sleep(sdiodev->bus, false); +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + atomic_set(&sdiodev->freezer->freezing, 0); + complete_all(&sdiodev->freezer->resumed); + } +@@ -878,19 +878,19 @@ static int brcmf_sdiod_remove(struct brc + brcmf_sdiod_freezer_detach(sdiodev); + + /* Disable Function 2 */ +- sdio_claim_host(sdiodev->func[2]); +- sdio_disable_func(sdiodev->func[2]); +- sdio_release_host(sdiodev->func[2]); ++ sdio_claim_host(sdiodev->func2); ++ sdio_disable_func(sdiodev->func2); ++ sdio_release_host(sdiodev->func2); + + /* Disable Function 1 */ +- sdio_claim_host(sdiodev->func[1]); +- sdio_disable_func(sdiodev->func[1]); +- sdio_release_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); ++ sdio_disable_func(sdiodev->func1); ++ sdio_release_host(sdiodev->func1); + + sg_free_table(&sdiodev->sgtable); + sdiodev->sbwad = 0; + +- pm_runtime_allow(sdiodev->func[1]->card->host->parent); ++ pm_runtime_allow(sdiodev->func1->card->host->parent); + return 0; + } + +@@ -906,29 +906,27 @@ static int brcmf_sdiod_probe(struct brcm + { + int ret = 0; + +- sdiodev->num_funcs = 2; ++ sdio_claim_host(sdiodev->func1); + +- sdio_claim_host(sdiodev->func[1]); +- +- ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); ++ ret = sdio_set_block_size(sdiodev->func1, SDIO_FUNC1_BLOCKSIZE); + if (ret) { + brcmf_err("Failed to set F1 blocksize\n"); +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + goto out; + } +- ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); ++ ret = sdio_set_block_size(sdiodev->func2, SDIO_FUNC2_BLOCKSIZE); + if (ret) { + brcmf_err("Failed to set F2 blocksize\n"); +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + goto out; + } + + /* increase F2 timeout */ +- sdiodev->func[2]->enable_timeout = SDIO_WAIT_F2RDY; ++ sdiodev->func2->enable_timeout = SDIO_WAIT_F2RDY; + + /* Enable Function 1 */ +- ret = sdio_enable_func(sdiodev->func[1]); +- sdio_release_host(sdiodev->func[1]); ++ ret = sdio_enable_func(sdiodev->func1); ++ sdio_release_host(sdiodev->func1); + if (ret) { + brcmf_err("Failed to enable F1: err=%d\n", ret); + goto out; +@@ -944,7 +942,7 @@ static int brcmf_sdiod_probe(struct brcm + ret = -ENODEV; + goto out; + } +- brcmf_sdiod_host_fixup(sdiodev->func[2]->card->host); ++ brcmf_sdiod_host_fixup(sdiodev->func2->card->host); + out: + if (ret) + brcmf_sdiod_remove(sdiodev); +@@ -1032,16 +1030,15 @@ static int brcmf_ops_sdio_probe(struct s + /* store refs to functions used. mmc_card does + * not hold the F0 function pointer. + */ +- sdiodev->func[0] = NULL; +- sdiodev->func[1] = func->card->sdio_func[0]; +- sdiodev->func[2] = func; ++ sdiodev->func1 = func->card->sdio_func[0]; ++ sdiodev->func2 = func; + + sdiodev->bus_if = bus_if; + bus_if->bus_priv.sdio = sdiodev; + bus_if->proto_type = BRCMF_PROTO_BCDC; + dev_set_drvdata(&func->dev, bus_if); +- dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); +- sdiodev->dev = &sdiodev->func[1]->dev; ++ dev_set_drvdata(&sdiodev->func1->dev, bus_if); ++ sdiodev->dev = &sdiodev->func1->dev; + + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN); + +@@ -1057,7 +1054,7 @@ static int brcmf_ops_sdio_probe(struct s + + fail: + dev_set_drvdata(&func->dev, NULL); +- dev_set_drvdata(&sdiodev->func[1]->dev, NULL); ++ dev_set_drvdata(&sdiodev->func1->dev, NULL); + kfree(sdiodev); + kfree(bus_if); + return err; +@@ -1086,8 +1083,8 @@ static void brcmf_ops_sdio_remove(struct + /* only proceed with rest of cleanup if func 1 */ + brcmf_sdiod_remove(sdiodev); + +- dev_set_drvdata(&sdiodev->func[1]->dev, NULL); +- dev_set_drvdata(&sdiodev->func[2]->dev, NULL); ++ dev_set_drvdata(&sdiodev->func1->dev, NULL); ++ dev_set_drvdata(&sdiodev->func2->dev, NULL); + + kfree(bus_if); + kfree(sdiodev); +@@ -1132,7 +1129,7 @@ static int brcmf_ops_sdio_suspend(struct + else + sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; + } +- if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) ++ if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags)) + brcmf_err("Failed to set pm_flags %x\n", sdio_flags); + return 0; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -979,7 +979,7 @@ static int brcmf_sdio_readshared(struct + struct sdpcm_shared_le sh_le; + __le32 addr_le; + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_bus_sleep(bus, false, false); + + /* +@@ -1013,7 +1013,7 @@ static int brcmf_sdio_readshared(struct + if (rv < 0) + goto fail; + +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + + /* Endianness */ + sh->flags = le32_to_cpu(sh_le.flags); +@@ -1035,7 +1035,7 @@ static int brcmf_sdio_readshared(struct + fail: + brcmf_err("unable to obtain sdpcm_shared info: rv=%d (addr=0x%x)\n", + rv, addr); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + return rv; + } + +@@ -1157,7 +1157,7 @@ static void brcmf_sdio_rxfail(struct brc + rtx ? ", send NAK" : ""); + + if (abort) +- brcmf_sdiod_abort(bus->sdiodev, bus->sdiodev->func[2]); ++ brcmf_sdiod_abort(bus->sdiodev, bus->sdiodev->func2); + + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, + &err); +@@ -1209,7 +1209,7 @@ static void brcmf_sdio_txfail(struct brc + brcmf_err("sdio error, abort command and terminate frame\n"); + bus->sdcnt.tx_sderrs++; + +- brcmf_sdiod_abort(sdiodev, sdiodev->func[2]); ++ brcmf_sdiod_abort(sdiodev, sdiodev->func2); + brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); + bus->sdcnt.f1regdata++; + +@@ -1565,10 +1565,10 @@ static u8 brcmf_sdio_rxglom(struct brcmf + * read directly into the chained packet, or allocate a large + * packet and and copy into the chain. + */ +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + errcode = brcmf_sdiod_recv_chain(bus->sdiodev, + &bus->glom, dlen); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + bus->sdcnt.f2rxdata++; + + /* On failure, kill the superframe */ +@@ -1576,11 +1576,11 @@ static u8 brcmf_sdio_rxglom(struct brcmf + brcmf_err("glom read of %d bytes failed: %d\n", + dlen, errcode); + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_rxfail(bus, true, false); + bus->sdcnt.rxglomfail++; + brcmf_sdio_free_glom(bus); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + return 0; + } + +@@ -1590,10 +1590,10 @@ static u8 brcmf_sdio_rxglom(struct brcmf + + rd_new.seq_num = rxseq; + rd_new.len = dlen; +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + errcode = brcmf_sdio_hdparse(bus, pfirst->data, &rd_new, + BRCMF_SDIO_FT_SUPER); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + bus->cur_read.len = rd_new.len_nxtfrm << 4; + + /* Remove superframe header, remember offset */ +@@ -1609,10 +1609,10 @@ static u8 brcmf_sdio_rxglom(struct brcmf + + rd_new.len = pnext->len; + rd_new.seq_num = rxseq++; +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + errcode = brcmf_sdio_hdparse(bus, pnext->data, &rd_new, + BRCMF_SDIO_FT_SUB); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pnext->data, 32, "subframe:\n"); + +@@ -1621,11 +1621,11 @@ static u8 brcmf_sdio_rxglom(struct brcmf + + if (errcode) { + /* Terminate frame on error */ +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_rxfail(bus, true, false); + bus->sdcnt.rxglomfail++; + brcmf_sdio_free_glom(bus); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + bus->cur_read.len = 0; + return 0; + } +@@ -1833,7 +1833,7 @@ static uint brcmf_sdio_readframes(struct + + rd->len_left = rd->len; + /* read header first for unknow frame length */ +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + if (!rd->len) { + ret = brcmf_sdiod_recv_buf(bus->sdiodev, + bus->rxhdr, BRCMF_FIRSTREAD); +@@ -1843,7 +1843,7 @@ static uint brcmf_sdio_readframes(struct + ret); + bus->sdcnt.rx_hdrfail++; + brcmf_sdio_rxfail(bus, true, true); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + continue; + } + +@@ -1853,7 +1853,7 @@ static uint brcmf_sdio_readframes(struct + + if (brcmf_sdio_hdparse(bus, bus->rxhdr, rd, + BRCMF_SDIO_FT_NORMAL)) { +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + if (!bus->rxpending) + break; + else +@@ -1869,7 +1869,7 @@ static uint brcmf_sdio_readframes(struct + rd->len_nxtfrm = 0; + /* treat all packet as event if we don't know */ + rd->channel = SDPCM_EVENT_CHANNEL; +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + continue; + } + rd->len_left = rd->len > BRCMF_FIRSTREAD ? +@@ -1886,7 +1886,7 @@ static uint brcmf_sdio_readframes(struct + brcmf_err("brcmu_pkt_buf_get_skb failed\n"); + brcmf_sdio_rxfail(bus, false, + RETRYCHAN(rd->channel)); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + continue; + } + skb_pull(pkt, head_read); +@@ -1894,16 +1894,16 @@ static uint brcmf_sdio_readframes(struct + + ret = brcmf_sdiod_recv_pkt(bus->sdiodev, pkt); + bus->sdcnt.f2rxdata++; +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + + if (ret < 0) { + brcmf_err("read %d bytes from channel %d failed: %d\n", + rd->len, rd->channel, ret); + brcmu_pkt_buf_free_skb(pkt); +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_rxfail(bus, true, + RETRYCHAN(rd->channel)); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + continue; + } + +@@ -1914,7 +1914,7 @@ static uint brcmf_sdio_readframes(struct + } else { + memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); + rd_new.seq_num = rd->seq_num; +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + if (brcmf_sdio_hdparse(bus, bus->rxhdr, &rd_new, + BRCMF_SDIO_FT_NORMAL)) { + rd->len = 0; +@@ -1927,11 +1927,11 @@ static uint brcmf_sdio_readframes(struct + roundup(rd_new.len, 16) >> 4); + rd->len = 0; + brcmf_sdio_rxfail(bus, true, true); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + brcmu_pkt_buf_free_skb(pkt); + continue; + } +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + rd->len_nxtfrm = rd_new.len_nxtfrm; + rd->channel = rd_new.channel; + rd->dat_offset = rd_new.dat_offset; +@@ -1947,9 +1947,9 @@ static uint brcmf_sdio_readframes(struct + rd_new.seq_num); + /* Force retry w/normal header read */ + rd->len = 0; +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_rxfail(bus, false, true); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + brcmu_pkt_buf_free_skb(pkt); + continue; + } +@@ -1972,9 +1972,9 @@ static uint brcmf_sdio_readframes(struct + } else { + brcmf_err("%s: glom superframe w/o " + "descriptor!\n", __func__); +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_rxfail(bus, false, false); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + } + /* prepare the descriptor for the next read */ + rd->len = rd->len_nxtfrm << 4; +@@ -2072,7 +2072,7 @@ static int brcmf_sdio_txpkt_prep_sg(stru + int ntail, ret; + + sdiodev = bus->sdiodev; +- blksize = sdiodev->func[2]->cur_blksize; ++ blksize = sdiodev->func2->cur_blksize; + /* sg entry alignment should be a divisor of block size */ + WARN_ON(blksize % bus->sgentry_align); + +@@ -2251,14 +2251,14 @@ static int brcmf_sdio_txpkt(struct brcmf + if (ret) + goto done; + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq); + bus->sdcnt.f2txdata++; + + if (ret < 0) + brcmf_sdio_txfail(bus); + +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + + done: + brcmf_sdio_txpkt_postp(bus, pktq); +@@ -2314,10 +2314,11 @@ static uint brcmf_sdio_sendfromq(struct + /* In poll mode, need to check for other events */ + if (!bus->intr) { + /* Check device status, signal pending interrupt */ +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + intstatus = brcmf_sdiod_readl(bus->sdiodev, + intstat_addr, &ret); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); ++ + bus->sdcnt.f2txdata++; + if (ret != 0) + break; +@@ -2417,7 +2418,7 @@ static void brcmf_sdio_bus_stop(struct d + } + + if (sdiodev->state != BRCMF_SDIOD_NOMEDIUM) { +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + + /* Enable clock for device interrupts */ + brcmf_sdio_bus_sleep(bus, false, false); +@@ -2441,13 +2442,13 @@ static void brcmf_sdio_bus_stop(struct d + + /* Turn off the bus (F2), free any pending packets */ + brcmf_dbg(INTR, "disable SDIO interrupts\n"); +- sdio_disable_func(sdiodev->func[2]); ++ sdio_disable_func(sdiodev->func2); + + /* Clear any pending interrupts now that F2 is disabled */ + brcmf_sdiod_writel(sdiodev, core->base + SD_REG(intstatus), + local_hostintmask, NULL); + +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + } + /* Clear the data packet queues */ + brcmu_pktq_flush(&bus->txq, true, NULL, NULL); +@@ -2522,7 +2523,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + + brcmf_dbg(TRACE, "Enter\n"); + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + + /* If waiting for HTAVAIL, check status */ + if (!bus->sr_enabled && bus->clkstate == CLK_PENDING) { +@@ -2585,7 +2586,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + intstatus |= brcmf_sdio_hostmail(bus); + } + +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + + /* Generally don't ask for these, can get CRC errors... */ + if (intstatus & I_WR_OOSYNC) { +@@ -2628,7 +2629,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + + if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && + data_ok(bus)) { +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + if (bus->ctrl_frame_stat) { + err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, + bus->ctrl_frame_len); +@@ -2636,7 +2637,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + wmb(); + bus->ctrl_frame_stat = false; + } +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + brcmf_sdio_wait_event_wakeup(bus); + } + /* Send queued frames (limit 1 if rx may still be pending) */ +@@ -2652,14 +2653,14 @@ static void brcmf_sdio_dpc(struct brcmf_ + brcmf_err("failed backplane access over SDIO, halting operation\n"); + atomic_set(&bus->intstatus, 0); + if (bus->ctrl_frame_stat) { +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + if (bus->ctrl_frame_stat) { + bus->ctrl_frame_err = -ENODEV; + wmb(); + bus->ctrl_frame_stat = false; + brcmf_sdio_wait_event_wakeup(bus); + } +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + } + } else if (atomic_read(&bus->intstatus) || + atomic_read(&bus->ipend) > 0 || +@@ -2874,13 +2875,13 @@ brcmf_sdio_bus_txctl(struct device *dev, + CTL_DONE_TIMEOUT); + ret = 0; + if (bus->ctrl_frame_stat) { +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + if (bus->ctrl_frame_stat) { + brcmf_dbg(SDIO, "ctrl_frame timeout\n"); + bus->ctrl_frame_stat = false; + ret = -ETIMEDOUT; + } +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + } + if (!ret) { + brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n", +@@ -3004,7 +3005,7 @@ static int brcmf_sdio_assert_info(struct + return 0; + } + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + if (sh->assert_file_addr != 0) { + error = brcmf_sdiod_ramrw(bus->sdiodev, false, + sh->assert_file_addr, (u8 *)file, 80); +@@ -3017,7 +3018,7 @@ static int brcmf_sdio_assert_info(struct + if (error < 0) + return error; + } +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + + seq_printf(seq, "dongle assert: %s:%d: assert(%s)\n", + file, sh->assert_line, expr); +@@ -3291,7 +3292,7 @@ static int brcmf_sdio_download_firmware( + int bcmerror; + u32 rstvec; + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + + rstvec = get_unaligned_le32(fw->data); +@@ -3320,7 +3321,7 @@ static int brcmf_sdio_download_firmware( + + err: + brcmf_sdio_clkctl(bus, CLK_SDONLY, false); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + return bcmerror; + } + +@@ -3435,7 +3436,7 @@ static int brcmf_sdio_bus_preinit(struct + if (sdiodev->sg_support) { + bus->txglom = false; + value = 1; +- pad_size = bus->sdiodev->func[2]->cur_blksize << 1; ++ pad_size = bus->sdiodev->func2->cur_blksize << 1; + err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", + &value, sizeof(u32)); + if (err < 0) { +@@ -3477,7 +3478,7 @@ static int brcmf_sdio_bus_get_memdump(st + + address = bus->ci->rambase; + offset = err = 0; +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + while (offset < mem_size) { + len = ((offset + MEMBLOCK) < mem_size) ? MEMBLOCK : + mem_size - offset; +@@ -3493,7 +3494,7 @@ static int brcmf_sdio_bus_get_memdump(st + } + + done: +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + return err; + } + +@@ -3550,11 +3551,10 @@ static void brcmf_sdio_bus_watchdog(stru + if (!bus->dpc_triggered) { + u8 devpend; + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + devpend = brcmf_sdiod_func0_rb(bus->sdiodev, +- SDIO_CCCR_INTx, +- NULL); +- sdio_release_host(bus->sdiodev->func[1]); ++ SDIO_CCCR_INTx, NULL); ++ sdio_release_host(bus->sdiodev->func1); + intstatus = devpend & (INTR_STATUS_FUNC1 | + INTR_STATUS_FUNC2); + } +@@ -3580,13 +3580,13 @@ static void brcmf_sdio_bus_watchdog(stru + bus->console.count += jiffies_to_msecs(BRCMF_WD_POLL); + if (bus->console.count >= bus->console_interval) { + bus->console.count -= bus->console_interval; +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + /* Make sure backplane clock is on */ + brcmf_sdio_bus_sleep(bus, false, false); + if (brcmf_sdio_readconsole(bus) < 0) + /* stop on error */ + bus->console_interval = 0; +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + } + } + #endif /* DEBUG */ +@@ -3599,11 +3599,11 @@ static void brcmf_sdio_bus_watchdog(stru + bus->idlecount++; + if (bus->idlecount > bus->idletime) { + brcmf_dbg(SDIO, "idle\n"); +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_wd_timer(bus, false); + bus->idlecount = 0; + brcmf_sdio_bus_sleep(bus, true, false); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + } + } else { + bus->idlecount = 0; +@@ -3773,8 +3773,8 @@ static u32 brcmf_sdio_buscore_read32(voi + val = brcmf_sdiod_readl(sdiodev, addr, NULL); + + if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) && +- (sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4339 || +- sdiodev->func[1]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) { ++ (sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4339 || ++ sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) { + rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; + if (rev >= 2) { + val &= ~CID_ID_MASK; +@@ -3810,7 +3810,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + u32 drivestrength; + + sdiodev = bus->sdiodev; +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + + pr_debug("F1 signature read @0x18000000=0x%4x\n", + brcmf_sdiod_readl(sdiodev, SI_ENUM_BASE, NULL)); +@@ -3877,8 +3877,8 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ + * is true or when platform data OOB irq is true). + */ +- if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && +- ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || ++ if ((sdio_get_host_pm_caps(sdiodev->func1) & MMC_PM_KEEP_POWER) && ++ ((sdio_get_host_pm_caps(sdiodev->func1) & MMC_PM_WAKE_SDIO_IRQ) || + (sdiodev->settings->bus.sdio.oob_irq_supported))) + sdiodev->bus_if->wowl_supported = true; + #endif +@@ -3917,7 +3917,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + if (err) + goto fail; + +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + + brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); + +@@ -3938,7 +3938,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + return true; + + fail: +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + return false; + } + +@@ -4044,7 +4044,7 @@ static void brcmf_sdio_firmware_callback + bus->sdcnt.tickcnt = 0; + brcmf_sdio_wd_timer(bus, true); + +- sdio_claim_host(sdiodev->func[1]); ++ sdio_claim_host(sdiodev->func1); + + /* Make sure backplane clock is on, needed to generate F2 interrupt */ + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); +@@ -4066,7 +4066,7 @@ static void brcmf_sdio_firmware_callback + brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata), + SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL); + +- err = sdio_enable_func(sdiodev->func[2]); ++ err = sdio_enable_func(sdiodev->func2); + + brcmf_dbg(INFO, "enable F2: err=%d\n", err); + +@@ -4081,7 +4081,7 @@ static void brcmf_sdio_firmware_callback + brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); + } else { + /* Disable F2 again */ +- sdio_disable_func(sdiodev->func[2]); ++ sdio_disable_func(sdiodev->func2); + goto release; + } + +@@ -4106,7 +4106,7 @@ static void brcmf_sdio_firmware_callback + if (err != 0) + brcmf_sdio_clkctl(bus, CLK_NONE, false); + +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + + err = brcmf_bus_started(dev); + if (err != 0) { +@@ -4116,10 +4116,10 @@ static void brcmf_sdio_firmware_callback + return; + + release: +- sdio_release_host(sdiodev->func[1]); ++ sdio_release_host(sdiodev->func1); + fail: + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); +- device_release_driver(&sdiodev->func[2]->dev); ++ device_release_driver(&sdiodev->func2->dev); + device_release_driver(dev); + } + +@@ -4146,7 +4146,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + + /* single-threaded workqueue */ + wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM, +- dev_name(&sdiodev->func[1]->dev)); ++ dev_name(&sdiodev->func1->dev)); + if (!wq) { + brcmf_err("insufficient memory to create txworkqueue\n"); + goto fail; +@@ -4173,7 +4173,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + init_completion(&bus->watchdog_wait); + bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread, + bus, "brcmf_wdog/%s", +- dev_name(&sdiodev->func[1]->dev)); ++ dev_name(&sdiodev->func1->dev)); + if (IS_ERR(bus->watchdog_tsk)) { + pr_warn("brcmf_watchdog thread failed to start\n"); + bus->watchdog_tsk = NULL; +@@ -4199,7 +4199,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + } + + /* Query the F2 block size, set roundup accordingly */ +- bus->blocksize = bus->sdiodev->func[2]->cur_blksize; ++ bus->blocksize = bus->sdiodev->func2->cur_blksize; + bus->roundup = min(max_roundup, bus->blocksize); + + /* Allocate buffers */ +@@ -4215,17 +4215,17 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + } + } + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + + /* Disable F2 to clear any intermediate frame state on the dongle */ +- sdio_disable_func(bus->sdiodev->func[2]); ++ sdio_disable_func(bus->sdiodev->func2); + + bus->rxflow = false; + + /* Done with backplane-dependent accesses, can drop clock... */ + brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); + +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + + /* ...and initialize clock/power states */ + bus->clkstate = CLK_SDONLY; +@@ -4277,7 +4277,7 @@ void brcmf_sdio_remove(struct brcmf_sdio + + if (bus->ci) { + if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) { +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + brcmf_sdio_wd_timer(bus, false); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + /* Leave the device in state where it is +@@ -4287,7 +4287,7 @@ void brcmf_sdio_remove(struct brcmf_sdio + msleep(20); + brcmf_chip_set_passive(bus->ci); + brcmf_sdio_clkctl(bus, CLK_NONE, false); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + } + brcmf_chip_detach(bus->ci); + } +@@ -4334,9 +4334,9 @@ int brcmf_sdio_sleep(struct brcmf_sdio * + { + int ret; + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdio_claim_host(bus->sdiodev->func1); + ret = brcmf_sdio_bus_sleep(bus, sleep, false); +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(bus->sdiodev->func1); + + return ret; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -21,9 +21,6 @@ + #include + #include "firmware.h" + +-/* Maximum number of I/O funcs */ +-#define NUM_SDIO_FUNCS 3 +- + #define SDIOD_FBR_SIZE 0x100 + + /* io_en */ +@@ -173,8 +170,8 @@ struct brcmf_sdio; + struct brcmf_sdiod_freezer; + + struct brcmf_sdio_dev { +- struct sdio_func *func[NUM_SDIO_FUNCS]; +- u8 num_funcs; /* Supported funcs on client */ ++ struct sdio_func *func1; ++ struct sdio_func *func2; + u32 sbwad; /* Save backplane window address */ + struct brcmf_core *cc_core; /* chipcommon core info struct */ + struct brcmf_sdio *bus; +@@ -295,17 +292,17 @@ void brcmf_sdiod_intr_unregister(struct + /* SDIO device register access interface */ + /* Accessors for SDIO Function 0 */ + #define brcmf_sdiod_func0_rb(sdiodev, addr, r) \ +- sdio_f0_readb((sdiodev)->func[1], (addr), (r)) ++ sdio_f0_readb((sdiodev)->func1, (addr), (r)) + + #define brcmf_sdiod_func0_wb(sdiodev, addr, v, ret) \ +- sdio_f0_writeb((sdiodev)->func[1], (v), (addr), (ret)) ++ sdio_f0_writeb((sdiodev)->func1, (v), (addr), (ret)) + + /* Accessors for SDIO Function 1 */ + #define brcmf_sdiod_readb(sdiodev, addr, r) \ +- sdio_readb((sdiodev)->func[1], (addr), (r)) ++ sdio_readb((sdiodev)->func1, (addr), (r)) + + #define brcmf_sdiod_writeb(sdiodev, addr, v, ret) \ +- sdio_writeb((sdiodev)->func[1], (v), (addr), (ret)) ++ sdio_writeb((sdiodev)->func1, (v), (addr), (ret)) + + u32 brcmf_sdiod_readl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); + void brcmf_sdiod_writel(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, diff --git a/root/package/kernel/mac80211/patches/316-v4.16-0002-brcmfmac-add-comment-block-in-brcmf_sdio_buscore_rea.patch b/root/package/kernel/mac80211/patches/316-v4.16-0002-brcmfmac-add-comment-block-in-brcmf_sdio_buscore_rea.patch new file mode 100644 index 00000000..dc78000b --- /dev/null +++ b/root/package/kernel/mac80211/patches/316-v4.16-0002-brcmfmac-add-comment-block-in-brcmf_sdio_buscore_rea.patch @@ -0,0 +1,31 @@ +From 32adbcaa5df49f1977441f7a4bf180a0bcfe9966 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 9 Jan 2018 13:22:53 +0100 +Subject: [PATCH] brcmfmac: add comment block in brcmf_sdio_buscore_read() + +In brcmf_sdio_buscore_read() there is some special handling upon +register access to chipid register of the chipcommon core. Add +comment explaining why it is done here. + +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3772,6 +3772,13 @@ static u32 brcmf_sdio_buscore_read32(voi + + val = brcmf_sdiod_readl(sdiodev, addr, NULL); + ++ /* ++ * this is a bit of special handling if reading the chipcommon chipid ++ * register. The 4339 is a next-gen of the 4335. It uses the same ++ * SDIO device id as 4335 and the chipid register returns 4335 as well. ++ * It can be identified as 4339 by looking at the chip revision. It ++ * is corrected here so the chip.c module has the right info. ++ */ + if (addr == CORE_CC_REG(SI_ENUM_BASE, chipid) && + (sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4339 || + sdiodev->func1->device == SDIO_DEVICE_ID_BROADCOM_4335_4339)) { diff --git a/root/package/kernel/mac80211/patches/316-v4.16-0003-brcmfmac-rename-brcmf_sdiod_buff_-read-write-functio.patch b/root/package/kernel/mac80211/patches/316-v4.16-0003-brcmfmac-rename-brcmf_sdiod_buff_-read-write-functio.patch new file mode 100644 index 00000000..c587f413 --- /dev/null +++ b/root/package/kernel/mac80211/patches/316-v4.16-0003-brcmfmac-rename-brcmf_sdiod_buff_-read-write-functio.patch @@ -0,0 +1,137 @@ +From 378f6a16043e5d3346301fc618f503e97aea335b Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 9 Jan 2018 13:22:54 +0100 +Subject: [PATCH] brcmfmac: rename brcmf_sdiod_buff_{read,write}() functions + +Rename functions to brcmf_sdio_skbuff_{read,write}() as we pass an +skbuff to this function. + +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 48 +++++++++++----------- + 1 file changed, 24 insertions(+), 24 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -292,24 +292,24 @@ out: + *ret = retval; + } + +-static int brcmf_sdiod_buff_read(struct brcmf_sdio_dev *sdiodev, +- struct sdio_func *func, u32 addr, +- struct sk_buff *pkt) ++static int brcmf_sdiod_skbuff_read(struct brcmf_sdio_dev *sdiodev, ++ struct sdio_func *func, u32 addr, ++ struct sk_buff *skb) + { + unsigned int req_sz; + int err; + + /* Single skb use the standard mmc interface */ +- req_sz = pkt->len + 3; ++ req_sz = skb->len + 3; + req_sz &= (uint)~3; + + switch (func->num) { + case 1: +- err = sdio_memcpy_fromio(func, ((u8 *)(pkt->data)), addr, ++ err = sdio_memcpy_fromio(func, ((u8 *)(skb->data)), addr, + req_sz); + break; + case 2: +- err = sdio_readsb(func, ((u8 *)(pkt->data)), addr, req_sz); ++ err = sdio_readsb(func, ((u8 *)(skb->data)), addr, req_sz); + break; + default: + /* bail out as things are really fishy here */ +@@ -323,18 +323,18 @@ static int brcmf_sdiod_buff_read(struct + return err; + } + +-static int brcmf_sdiod_buff_write(struct brcmf_sdio_dev *sdiodev, +- struct sdio_func *func, u32 addr, +- struct sk_buff *pkt) ++static int brcmf_sdiod_skbuff_write(struct brcmf_sdio_dev *sdiodev, ++ struct sdio_func *func, u32 addr, ++ struct sk_buff *skb) + { + unsigned int req_sz; + int err; + + /* Single skb use the standard mmc interface */ +- req_sz = pkt->len + 3; ++ req_sz = skb->len + 3; + req_sz &= (uint)~3; + +- err = sdio_memcpy_toio(func, addr, ((u8 *)(pkt->data)), req_sz); ++ err = sdio_memcpy_toio(func, addr, ((u8 *)(skb->data)), req_sz); + + if (err == -ENOMEDIUM) + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM); +@@ -550,7 +550,7 @@ int brcmf_sdiod_recv_pkt(struct brcmf_sd + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, pkt); ++ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, pkt); + + done: + return err; +@@ -575,14 +575,14 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (pktq->qlen == 1) +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, +- pktq->next); ++ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, ++ pktq->next); + else if (!sdiodev->sg_support) { + glom_skb = brcmu_pkt_buf_get_skb(totlen); + if (!glom_skb) + return -ENOMEM; +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func2, addr, +- glom_skb); ++ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func2, addr, ++ glom_skb); + if (err) + goto done; + +@@ -623,8 +623,8 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + + if (!err) +- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2, addr, +- mypkt); ++ err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, ++ mypkt); + + brcmu_pkt_buf_free_skb(mypkt); + +@@ -649,8 +649,8 @@ int brcmf_sdiod_send_pkt(struct brcmf_sd + + if (pktq->qlen == 1 || !sdiodev->sg_support) { + skb_queue_walk(pktq, skb) { +- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func2, +- addr, skb); ++ err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, ++ addr, skb); + if (err) + break; + } +@@ -706,11 +706,11 @@ brcmf_sdiod_ramrw(struct brcmf_sdio_dev + + if (write) { + memcpy(pkt->data, data, dsize); +- err = brcmf_sdiod_buff_write(sdiodev, sdiodev->func1, +- sdaddr, pkt); ++ err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func1, ++ sdaddr, pkt); + } else { +- err = brcmf_sdiod_buff_read(sdiodev, sdiodev->func1, +- sdaddr, pkt); ++ err = brcmf_sdiod_skbuff_read(sdiodev, sdiodev->func1, ++ sdaddr, pkt); + } + + if (err) { diff --git a/root/package/kernel/mac80211/patches/317-v4.16-0001-brcmfmac-Use-zeroing-memory-allocator-than-allocator.patch b/root/package/kernel/mac80211/patches/317-v4.16-0001-brcmfmac-Use-zeroing-memory-allocator-than-allocator.patch new file mode 100644 index 00000000..b60c81a3 --- /dev/null +++ b/root/package/kernel/mac80211/patches/317-v4.16-0001-brcmfmac-Use-zeroing-memory-allocator-than-allocator.patch @@ -0,0 +1,59 @@ +From b7acadaf038740c43515dc1548f43d01cc92823a Mon Sep 17 00:00:00 2001 +From: Himanshu Jha +Date: Tue, 9 Jan 2018 02:15:31 +0530 +Subject: [PATCH] brcmfmac: Use zeroing memory allocator than allocator/memset + +Use dma_zalloc_coherent for allocating zeroed +memory and remove unnecessary memset function. + +Generated-by: scripts/coccinelle/api/alloc/kzalloc-simple.cocci + +Suggested-by: Luis R. Rodriguez +Signed-off-by: Himanshu Jha +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1251,14 +1251,14 @@ static int brcmf_pcie_init_scratchbuffer + u64 address; + u32 addr; + +- devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev, +- BRCMF_DMA_D2H_SCRATCH_BUF_LEN, +- &devinfo->shared.scratch_dmahandle, GFP_KERNEL); ++ devinfo->shared.scratch = ++ dma_zalloc_coherent(&devinfo->pdev->dev, ++ BRCMF_DMA_D2H_SCRATCH_BUF_LEN, ++ &devinfo->shared.scratch_dmahandle, ++ GFP_KERNEL); + if (!devinfo->shared.scratch) + goto fail; + +- memset(devinfo->shared.scratch, 0, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); +- + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET; + address = (u64)devinfo->shared.scratch_dmahandle; +@@ -1268,14 +1268,14 @@ static int brcmf_pcie_init_scratchbuffer + BRCMF_SHARED_DMA_SCRATCH_LEN_OFFSET; + brcmf_pcie_write_tcm32(devinfo, addr, BRCMF_DMA_D2H_SCRATCH_BUF_LEN); + +- devinfo->shared.ringupd = dma_alloc_coherent(&devinfo->pdev->dev, +- BRCMF_DMA_D2H_RINGUPD_BUF_LEN, +- &devinfo->shared.ringupd_dmahandle, GFP_KERNEL); ++ devinfo->shared.ringupd = ++ dma_zalloc_coherent(&devinfo->pdev->dev, ++ BRCMF_DMA_D2H_RINGUPD_BUF_LEN, ++ &devinfo->shared.ringupd_dmahandle, ++ GFP_KERNEL); + if (!devinfo->shared.ringupd) + goto fail; + +- memset(devinfo->shared.ringupd, 0, BRCMF_DMA_D2H_RINGUPD_BUF_LEN); +- + addr = devinfo->shared.tcm_base_address + + BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET; + address = (u64)devinfo->shared.ringupd_dmahandle; diff --git a/root/package/kernel/mac80211/patches/318-v4.17-mac80211-round-IEEE80211_TX_STATUS_HEADROOM-up-to-mu.patch b/root/package/kernel/mac80211/patches/318-v4.17-mac80211-round-IEEE80211_TX_STATUS_HEADROOM-up-to-mu.patch new file mode 100644 index 00000000..e955cb3a --- /dev/null +++ b/root/package/kernel/mac80211/patches/318-v4.17-mac80211-round-IEEE80211_TX_STATUS_HEADROOM-up-to-mu.patch @@ -0,0 +1,26 @@ +From: Felix Fietkau +Date: Fri, 9 Feb 2018 19:46:54 +0100 +Subject: [PATCH] mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple + of 4 + +This ensures that mac80211 allocated management frames are properly +aligned, which makes copying them more efficient. +For instance, mt76 uses iowrite32_copy to copy beacon frames to beacon +template memory on the chip. +Misaligned 32-bit accesses cause CPU exceptions on MIPS and should be +avoided. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -4145,7 +4145,7 @@ void ieee80211_sta_uapsd_trigger(struct + * The TX headroom reserved by mac80211 for its own tx_status functions. + * This is enough for the radiotap header. + */ +-#define IEEE80211_TX_STATUS_HEADROOM 14 ++#define IEEE80211_TX_STATUS_HEADROOM ALIGN(14, 4) + + /** + * ieee80211_sta_set_buffered - inform mac80211 about driver-buffered frames diff --git a/root/package/kernel/mac80211/patches/319-v4.17-0001-mac80211-drop-frames-with-unexpected-DS-bits-from-fa.patch b/root/package/kernel/mac80211/patches/319-v4.17-0001-mac80211-drop-frames-with-unexpected-DS-bits-from-fa.patch new file mode 100644 index 00000000..a7562996 --- /dev/null +++ b/root/package/kernel/mac80211/patches/319-v4.17-0001-mac80211-drop-frames-with-unexpected-DS-bits-from-fa.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Fri, 23 Feb 2018 09:59:35 +0100 +Subject: [PATCH] mac80211: drop frames with unexpected DS bits from + fast-rx to slow path + +Fixes rx for 4-addr packets in AP mode + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3928,7 +3928,7 @@ static bool ieee80211_invoke_fast_rx(str + if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FROMDS | + IEEE80211_FCTL_TODS)) != + fast_rx->expected_ds_bits) +- goto drop; ++ return false; + + /* assign the key to drop unencrypted frames (later) + * and strip the IV/MIC if necessary diff --git a/root/package/kernel/mac80211/patches/319-v4.17-0002-mac80211-support-AP-4-addr-mode-fast-rx.patch b/root/package/kernel/mac80211/patches/319-v4.17-0002-mac80211-support-AP-4-addr-mode-fast-rx.patch new file mode 100644 index 00000000..3f3eb0a5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/319-v4.17-0002-mac80211-support-AP-4-addr-mode-fast-rx.patch @@ -0,0 +1,25 @@ +From: Felix Fietkau +Date: Fri, 23 Feb 2018 10:00:22 +0100 +Subject: [PATCH] mac80211: support AP 4-addr mode fast-rx + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3774,6 +3774,15 @@ void ieee80211_check_fast_rx(struct sta_ + !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && + (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || + !sdata->u.vlan.sta); ++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && ++ sdata->u.vlan.sta) { ++ fastrx.expected_ds_bits |= ++ cpu_to_le16(IEEE80211_FCTL_FROMDS); ++ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); ++ fastrx.internal_forward = 0; ++ } ++ + break; + default: + goto clear; diff --git a/root/package/kernel/mac80211/patches/319-v4.17-0003-mac80211-support-fast-rx-with-incompatible-PS-capabi.patch b/root/package/kernel/mac80211/patches/319-v4.17-0003-mac80211-support-fast-rx-with-incompatible-PS-capabi.patch new file mode 100644 index 00000000..8c4c724e --- /dev/null +++ b/root/package/kernel/mac80211/patches/319-v4.17-0003-mac80211-support-fast-rx-with-incompatible-PS-capabi.patch @@ -0,0 +1,53 @@ +From: Felix Fietkau +Date: Fri, 23 Feb 2018 10:01:53 +0100 +Subject: [PATCH] mac80211: support fast-rx with incompatible PS + capabilities when PS is disabled + +When powersave is disabled for the interface, we can do fast-rx anyway. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2658,6 +2658,7 @@ static int ieee80211_set_power_mgmt(stru + + ieee80211_recalc_ps(local); + ieee80211_recalc_ps_vif(sdata); ++ ieee80211_check_fast_rx_iface(sdata); + + return 0; + } +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3741,12 +3741,7 @@ void ieee80211_check_fast_rx(struct sta_ + /* 4-addr is harder to deal with, later maybe */ + if (sdata->u.mgd.use_4addr) + goto clear; +- /* software powersave is a huge mess, avoid all of it */ +- if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK)) +- goto clear; +- if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) && +- !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) +- goto clear; ++ + if (sta->sta.tdls) { + fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1); + fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2); +@@ -3758,6 +3753,16 @@ void ieee80211_check_fast_rx(struct sta_ + fastrx.expected_ds_bits = + cpu_to_le16(IEEE80211_FCTL_FROMDS); + } ++ ++ if (!sdata->u.mgd.powersave) ++ break; ++ ++ /* software powersave is a huge mess, avoid all of it */ ++ if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK)) ++ goto clear; ++ if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) && ++ !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) ++ goto clear; + break; + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_AP: diff --git a/root/package/kernel/mac80211/patches/319-v4.17-0004-mac80211-support-station-4-addr-mode-fast-rx.patch b/root/package/kernel/mac80211/patches/319-v4.17-0004-mac80211-support-station-4-addr-mode-fast-rx.patch new file mode 100644 index 00000000..97a5d8be --- /dev/null +++ b/root/package/kernel/mac80211/patches/319-v4.17-0004-mac80211-support-station-4-addr-mode-fast-rx.patch @@ -0,0 +1,34 @@ +From: Felix Fietkau +Date: Fri, 23 Feb 2018 10:05:08 +0100 +Subject: [PATCH] mac80211: support station 4-addr mode fast-rx + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3738,10 +3738,6 @@ void ieee80211_check_fast_rx(struct sta_ + + switch (sdata->vif.type) { + case NL80211_IFTYPE_STATION: +- /* 4-addr is harder to deal with, later maybe */ +- if (sdata->u.mgd.use_4addr) +- goto clear; +- + if (sta->sta.tdls) { + fastrx.da_offs = offsetof(struct ieee80211_hdr, addr1); + fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr2); +@@ -3754,6 +3750,13 @@ void ieee80211_check_fast_rx(struct sta_ + cpu_to_le16(IEEE80211_FCTL_FROMDS); + } + ++ if (sdata->u.mgd.use_4addr && !sta->sta.tdls) { ++ fastrx.expected_ds_bits |= ++ cpu_to_le16(IEEE80211_FCTL_TODS); ++ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3); ++ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); ++ } ++ + if (!sdata->u.mgd.powersave) + break; + diff --git a/root/package/kernel/mac80211/patches/320-v4.17-mac80211-support-A-MSDU-in-fast-rx.patch b/root/package/kernel/mac80211/patches/320-v4.17-mac80211-support-A-MSDU-in-fast-rx.patch new file mode 100644 index 00000000..3c6d342f --- /dev/null +++ b/root/package/kernel/mac80211/patches/320-v4.17-mac80211-support-A-MSDU-in-fast-rx.patch @@ -0,0 +1,256 @@ +From: Felix Fietkau +Date: Mon, 26 Feb 2018 22:09:29 +0100 +Subject: [PATCH] mac80211: support A-MSDU in fast-rx + +Only works if the IV was stripped from packets. Create a smaller +variant of ieee80211_rx_h_amsdu, which bypasses checks already done +within the fast-rx context. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2358,39 +2358,17 @@ ieee80211_deliver_skb(struct ieee80211_r + } + + static ieee80211_rx_result debug_noinline +-ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) ++__ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) + { + struct net_device *dev = rx->sdata->dev; + struct sk_buff *skb = rx->skb; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + __le16 fc = hdr->frame_control; + struct sk_buff_head frame_list; +- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + struct ethhdr ethhdr; + const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; + +- if (unlikely(!ieee80211_is_data(fc))) +- return RX_CONTINUE; +- +- if (unlikely(!ieee80211_is_data_present(fc))) +- return RX_DROP_MONITOR; +- +- if (!(status->rx_flags & IEEE80211_RX_AMSDU)) +- return RX_CONTINUE; +- + if (unlikely(ieee80211_has_a4(hdr->frame_control))) { +- switch (rx->sdata->vif.type) { +- case NL80211_IFTYPE_AP_VLAN: +- if (!rx->sdata->u.vlan.sta) +- return RX_DROP_UNUSABLE; +- break; +- case NL80211_IFTYPE_STATION: +- if (!rx->sdata->u.mgd.use_4addr) +- return RX_DROP_UNUSABLE; +- break; +- default: +- return RX_DROP_UNUSABLE; +- } + check_da = NULL; + check_sa = NULL; + } else switch (rx->sdata->vif.type) { +@@ -2410,15 +2388,13 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx + break; + } + +- if (is_multicast_ether_addr(hdr->addr1)) +- return RX_DROP_UNUSABLE; +- + skb->dev = dev; + __skb_queue_head_init(&frame_list); + + if (ieee80211_data_to_8023_exthdr(skb, ðhdr, + rx->sdata->vif.addr, +- rx->sdata->vif.type)) ++ rx->sdata->vif.type, ++ data_offset)) + return RX_DROP_UNUSABLE; + + ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, +@@ -2440,6 +2416,44 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx + return RX_QUEUED; + } + ++static ieee80211_rx_result debug_noinline ++ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) ++{ ++ struct sk_buff *skb = rx->skb; ++ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); ++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ __le16 fc = hdr->frame_control; ++ ++ if (!(status->rx_flags & IEEE80211_RX_AMSDU)) ++ return RX_CONTINUE; ++ ++ if (unlikely(!ieee80211_is_data(fc))) ++ return RX_CONTINUE; ++ ++ if (unlikely(!ieee80211_is_data_present(fc))) ++ return RX_DROP_MONITOR; ++ ++ if (unlikely(ieee80211_has_a4(hdr->frame_control))) { ++ switch (rx->sdata->vif.type) { ++ case NL80211_IFTYPE_AP_VLAN: ++ if (!rx->sdata->u.vlan.sta) ++ return RX_DROP_UNUSABLE; ++ break; ++ case NL80211_IFTYPE_STATION: ++ if (!rx->sdata->u.mgd.use_4addr) ++ return RX_DROP_UNUSABLE; ++ break; ++ default: ++ return RX_DROP_UNUSABLE; ++ } ++ } ++ ++ if (is_multicast_ether_addr(hdr->addr1)) ++ return RX_DROP_UNUSABLE; ++ ++ return __ieee80211_rx_h_amsdu(rx, 0); ++} ++ + #ifdef CPTCFG_MAC80211_MESH + static ieee80211_rx_result + ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) +@@ -3889,7 +3903,8 @@ static bool ieee80211_invoke_fast_rx(str + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct sta_info *sta = rx->sta; + int orig_len = skb->len; +- int snap_offs = ieee80211_hdrlen(hdr->frame_control); ++ int hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ int snap_offs = hdrlen; + struct { + u8 snap[sizeof(rfc1042_header)]; + __be16 proto; +@@ -3920,10 +3935,6 @@ static bool ieee80211_invoke_fast_rx(str + (status->flag & FAST_RX_CRYPT_FLAGS) != FAST_RX_CRYPT_FLAGS) + return false; + +- /* we don't deal with A-MSDU deaggregation here */ +- if (status->rx_flags & IEEE80211_RX_AMSDU) +- return false; +- + if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) + return false; + +@@ -3955,21 +3966,24 @@ static bool ieee80211_invoke_fast_rx(str + snap_offs += IEEE80211_CCMP_HDR_LEN; + } + +- if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) +- goto drop; +- payload = (void *)(skb->data + snap_offs); ++ if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { ++ if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) ++ goto drop; + +- if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr)) +- return false; ++ payload = (void *)(skb->data + snap_offs); + +- /* Don't handle these here since they require special code. +- * Accept AARP and IPX even though they should come with a +- * bridge-tunnel header - but if we get them this way then +- * there's little point in discarding them. +- */ +- if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) || +- payload->proto == fast_rx->control_port_protocol)) +- return false; ++ if (!ether_addr_equal(payload->snap, fast_rx->rfc1042_hdr)) ++ return false; ++ ++ /* Don't handle these here since they require special code. ++ * Accept AARP and IPX even though they should come with a ++ * bridge-tunnel header - but if we get them this way then ++ * there's little point in discarding them. ++ */ ++ if (unlikely(payload->proto == cpu_to_be16(ETH_P_TDLS) || ++ payload->proto == fast_rx->control_port_protocol)) ++ return false; ++ } + + /* after this point, don't punt to the slowpath! */ + +@@ -3983,12 +3997,6 @@ static bool ieee80211_invoke_fast_rx(str + } + + /* statistics part of ieee80211_rx_h_sta_process() */ +- stats->last_rx = jiffies; +- stats->last_rate = sta_stats_encode_rate(status); +- +- stats->fragments++; +- stats->packets++; +- + if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) { + stats->last_signal = status->signal; + if (!fast_rx->uses_rss) +@@ -4017,6 +4025,20 @@ static bool ieee80211_invoke_fast_rx(str + if (rx->key && !ieee80211_has_protected(hdr->frame_control)) + goto drop; + ++ if (status->rx_flags & IEEE80211_RX_AMSDU) { ++ if (__ieee80211_rx_h_amsdu(rx, snap_offs - hdrlen) != ++ RX_QUEUED) ++ goto drop; ++ ++ return true; ++ } ++ ++ stats->last_rx = jiffies; ++ stats->last_rate = sta_stats_encode_rate(status); ++ ++ stats->fragments++; ++ stats->packets++; ++ + /* do the header conversion - first grab the addresses */ + ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); + ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -4331,10 +4331,12 @@ unsigned int ieee80211_get_mesh_hdrlen(s + * of it being pushed into the SKB + * @addr: the device MAC address + * @iftype: the virtual interface type ++ * @data_offset: offset of payload after the 802.11 header + * Return: 0 on success. Non-zero on error. + */ + int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, +- const u8 *addr, enum nl80211_iftype iftype); ++ const u8 *addr, enum nl80211_iftype iftype, ++ u8 data_offset); + + /** + * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 +@@ -4346,7 +4348,7 @@ int ieee80211_data_to_8023_exthdr(struct + static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + enum nl80211_iftype iftype) + { +- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype); ++ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0); + } + + /** +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -419,7 +419,8 @@ unsigned int ieee80211_get_mesh_hdrlen(s + EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); + + int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, +- const u8 *addr, enum nl80211_iftype iftype) ++ const u8 *addr, enum nl80211_iftype iftype, ++ u8 data_offset) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct { +@@ -433,7 +434,7 @@ int ieee80211_data_to_8023_exthdr(struct + if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) + return -1; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset; + if (skb->len < hdrlen + 8) + return -1; + diff --git a/root/package/kernel/mac80211/patches/321-v4.16-0001-brcmfmac-assure-bcdc-dcmd-api-does-not-return-value-.patch b/root/package/kernel/mac80211/patches/321-v4.16-0001-brcmfmac-assure-bcdc-dcmd-api-does-not-return-value-.patch new file mode 100644 index 00000000..394fbfc5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/321-v4.16-0001-brcmfmac-assure-bcdc-dcmd-api-does-not-return-value-.patch @@ -0,0 +1,68 @@ +From 5242a5444e0b6464d7455beb55d936dd192b5e9d Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 22 Jan 2018 21:46:39 +0100 +Subject: [PATCH] brcmfmac: assure bcdc dcmd api does not return value > 0 + +The protocol layer api defines callbacks for dongle commands. +Although not really well documented these should only return an +error code in case of an error, or 0 upon success. In the bcdc +protocol it can return value above 0 and we carry a fix in the +caller of the protocol layer api. This patch makes it adhere to +the intent of the api as described above. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 6 +++++- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 8 +++----- + 2 files changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -211,6 +211,8 @@ retry: + memcpy(buf, info, len); + } + ++ ret = 0; ++ + /* Check the ERROR flag */ + if (flags & BCDC_DCMD_ERROR) + ret = le32_to_cpu(msg->status); +@@ -225,7 +227,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p + { + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; +- int ret = 0; ++ int ret; + u32 flags, id; + + brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); +@@ -249,6 +251,8 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p + goto done; + } + ++ ret = 0; ++ + /* Check the ERROR flag */ + if (flags & BCDC_DCMD_ERROR) + ret = le32_to_cpu(msg->status); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +@@ -121,11 +121,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, + else + err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); + +- if (err >= 0) +- return 0; +- +- brcmf_dbg(FIL, "Failed: %s (%d)\n", +- brcmf_fil_get_errstr((u32)(-err)), err); ++ if (err) ++ brcmf_dbg(FIL, "Failed: %s (%d)\n", ++ brcmf_fil_get_errstr((u32)(-err)), err); + + return err; + } diff --git a/root/package/kernel/mac80211/patches/321-v4.16-0002-brcmfmac-separate-firmware-errors-from-i-o-errors.patch b/root/package/kernel/mac80211/patches/321-v4.16-0002-brcmfmac-separate-firmware-errors-from-i-o-errors.patch new file mode 100644 index 00000000..28e3c1a6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/321-v4.16-0002-brcmfmac-separate-firmware-errors-from-i-o-errors.patch @@ -0,0 +1,186 @@ +From b69c1df47281ad47bd2037a42b98f5c7115b7fd5 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 22 Jan 2018 21:46:40 +0100 +Subject: [PATCH] brcmfmac: separate firmware errors from i/o errors + +When using the firmware api it can fail simply because firmware does +not like the request or it fails due to issues in the host interface. +Currently, there is only a single error code which is confusing. So +adding a parameter to pass the firmware error separately and in case +of a firmware error always return -EBADE to user-space. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 11 ++++++----- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 16 +++++++++++----- + .../net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 10 ++++++---- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | 14 ++++++++------ + 4 files changed, 31 insertions(+), 20 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -165,7 +165,7 @@ static int brcmf_proto_bcdc_cmplt(struct + + static int + brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, +- void *buf, uint len) ++ void *buf, uint len, int *fwerr) + { + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; +@@ -175,6 +175,7 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf + + brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); + ++ *fwerr = 0; + ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false); + if (ret < 0) { + brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", +@@ -215,15 +216,14 @@ retry: + + /* Check the ERROR flag */ + if (flags & BCDC_DCMD_ERROR) +- ret = le32_to_cpu(msg->status); +- ++ *fwerr = le32_to_cpu(msg->status); + done: + return ret; + } + + static int + brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, +- void *buf, uint len) ++ void *buf, uint len, int *fwerr) + { + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; +@@ -232,6 +232,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p + + brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); + ++ *fwerr = 0; + ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true); + if (ret < 0) + goto done; +@@ -255,7 +256,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p + + /* Check the ERROR flag */ + if (flags & BCDC_DCMD_ERROR) +- ret = le32_to_cpu(msg->status); ++ *fwerr = le32_to_cpu(msg->status); + + done: + return ret; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +@@ -107,7 +107,7 @@ static s32 + brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) + { + struct brcmf_pub *drvr = ifp->drvr; +- s32 err; ++ s32 err, fwerr; + + if (drvr->bus_if->state != BRCMF_BUS_UP) { + brcmf_err("bus is down. we have nothing to do.\n"); +@@ -117,14 +117,20 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, + if (data != NULL) + len = min_t(uint, len, BRCMF_DCMD_MAXLEN); + if (set) +- err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len); ++ err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, ++ data, len, &fwerr); + else +- err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); ++ err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, ++ data, len, &fwerr); + +- if (err) ++ if (err) { + brcmf_dbg(FIL, "Failed: %s (%d)\n", + brcmf_fil_get_errstr((u32)(-err)), err); +- ++ } else if (fwerr < 0) { ++ brcmf_dbg(FIL, "Firmware error: %s (%d)\n", ++ brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); ++ err = -EBADE; ++ } + return err; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -477,7 +477,7 @@ static void brcmf_msgbuf_ioctl_resp_wake + + + static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx, +- uint cmd, void *buf, uint len) ++ uint cmd, void *buf, uint len, int *fwerr) + { + struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; + struct sk_buff *skb = NULL; +@@ -485,6 +485,7 @@ static int brcmf_msgbuf_query_dcmd(struc + int err; + + brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len); ++ *fwerr = 0; + msgbuf->ctl_completed = false; + err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len); + if (err) +@@ -508,14 +509,15 @@ static int brcmf_msgbuf_query_dcmd(struc + } + brcmu_pkt_buf_free_skb(skb); + +- return msgbuf->ioctl_resp_status; ++ *fwerr = msgbuf->ioctl_resp_status; ++ return 0; + } + + + static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx, +- uint cmd, void *buf, uint len) ++ uint cmd, void *buf, uint len, int *fwerr) + { +- return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len); ++ return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len, fwerr); + } + + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h +@@ -30,9 +30,9 @@ struct brcmf_proto { + int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, + struct sk_buff *skb, struct brcmf_if **ifp); + int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, +- void *buf, uint len); ++ void *buf, uint len, int *fwerr); + int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, +- uint len); ++ uint len, int *fwerr); + int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx, + struct sk_buff *skb); + int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset, +@@ -71,14 +71,16 @@ static inline int brcmf_proto_hdrpull(st + return drvr->proto->hdrpull(drvr, do_fws, skb, ifp); + } + static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx, +- uint cmd, void *buf, uint len) ++ uint cmd, void *buf, uint len, ++ int *fwerr) + { +- return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len); ++ return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len,fwerr); + } + static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx, +- uint cmd, void *buf, uint len) ++ uint cmd, void *buf, uint len, ++ int *fwerr) + { +- return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); ++ return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len, fwerr); + } + + static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx, diff --git a/root/package/kernel/mac80211/patches/322-v4.16-0001-brcmfmac-add-possibility-to-obtain-firmware-error.patch b/root/package/kernel/mac80211/patches/322-v4.16-0001-brcmfmac-add-possibility-to-obtain-firmware-error.patch new file mode 100644 index 00000000..e6486160 --- /dev/null +++ b/root/package/kernel/mac80211/patches/322-v4.16-0001-brcmfmac-add-possibility-to-obtain-firmware-error.patch @@ -0,0 +1,92 @@ +From 933897342d0714ae1c10729cbaeecea0c6178db5 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 28 Feb 2018 21:15:19 +0100 +Subject: [PATCH] brcmfmac: add possibility to obtain firmware error + +The feature module needs to evaluate the actual firmware error return +upon a control command. This adds a flag to struct brcmf_if that the +caller can set. This flag is checked to determine the error code that +needs to be returned. + +Fixes: b69c1df47281 ("brcmfmac: separate firmware errors from i/o errors") +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 2 ++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 10 ++++++++++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 3 +++ + 3 files changed, 15 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -181,6 +181,7 @@ enum brcmf_netif_stop_reason { + * @netif_stop_lock: spinlock for update netif_stop from multiple sources. + * @pend_8021x_cnt: tracks outstanding number of 802.1x frames. + * @pend_8021x_wait: used for signalling change in count. ++ * @fwil_fwerr: flag indicating fwil layer should return firmware error codes. + */ + struct brcmf_if { + struct brcmf_pub *drvr; +@@ -198,6 +199,7 @@ struct brcmf_if { + wait_queue_head_t pend_8021x_wait; + struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES]; + u8 ipv6addr_idx; ++ bool fwil_fwerr; + }; + + int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -104,6 +104,9 @@ static void brcmf_feat_iovar_int_get(str + u32 data; + int err; + ++ /* we need to know firmware error */ ++ ifp->fwil_fwerr = true; ++ + err = brcmf_fil_iovar_int_get(ifp, name, &data); + if (err == 0) { + brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); +@@ -112,6 +115,8 @@ static void brcmf_feat_iovar_int_get(str + brcmf_dbg(TRACE, "%s feature check failed: %d\n", + brcmf_feat_names[id], err); + } ++ ++ ifp->fwil_fwerr = false; + } + + static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp, +@@ -120,6 +125,9 @@ static void brcmf_feat_iovar_data_set(st + { + int err; + ++ /* we need to know firmware error */ ++ ifp->fwil_fwerr = true; ++ + err = brcmf_fil_iovar_data_set(ifp, name, data, len); + if (err != -BRCMF_FW_UNSUPPORTED) { + brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]); +@@ -128,6 +136,8 @@ static void brcmf_feat_iovar_data_set(st + brcmf_dbg(TRACE, "%s feature check failed: %d\n", + brcmf_feat_names[id], err); + } ++ ++ ifp->fwil_fwerr = false; + } + + #define MAX_CAPS_BUFFER_SIZE 512 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +@@ -131,6 +131,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, + brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); + err = -EBADE; + } ++ if (ifp->fwil_fwerr) ++ return fwerr; ++ + return err; + } + diff --git a/root/package/kernel/mac80211/patches/322-v4.16-0002-brcmfmac-fix-P2P_DEVICE-ethernet-address-generation.patch b/root/package/kernel/mac80211/patches/322-v4.16-0002-brcmfmac-fix-P2P_DEVICE-ethernet-address-generation.patch new file mode 100644 index 00000000..20e16ad2 --- /dev/null +++ b/root/package/kernel/mac80211/patches/322-v4.16-0002-brcmfmac-fix-P2P_DEVICE-ethernet-address-generation.patch @@ -0,0 +1,64 @@ +From 455f3e76cfc0d893585a5f358b9ddbe9c1e1e53b Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 28 Feb 2018 21:15:20 +0100 +Subject: [PATCH] brcmfmac: fix P2P_DEVICE ethernet address generation + +The firmware has a requirement that the P2P_DEVICE address should +be different from the address of the primary interface. When not +specified by user-space, the driver generates the MAC address for +the P2P_DEVICE interface using the MAC address of the primary +interface and setting the locally administered bit. However, the MAC +address of the primary interface may already have that bit set causing +the creation of the P2P_DEVICE interface to fail with -EBUSY. Fix this +by using a random address instead to determine the P2P_DEVICE address. + +Cc: stable@vger.kernel.org # 3.10.y +Reported-by: Hans de Goede +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 24 ++++++++++------------ + 1 file changed, 11 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -462,25 +462,23 @@ static int brcmf_p2p_set_firmware(struct + * @dev_addr: optional device address. + * + * P2P needs mac addresses for P2P device and interface. If no device +- * address it specified, these are derived from the primary net device, ie. +- * the permanent ethernet address of the device. ++ * address it specified, these are derived from a random ethernet ++ * address. + */ + static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) + { +- struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; +- bool local_admin = false; ++ bool random_addr = false; + +- if (!dev_addr || is_zero_ether_addr(dev_addr)) { +- dev_addr = pri_ifp->mac_addr; +- local_admin = true; +- } ++ if (!dev_addr || is_zero_ether_addr(dev_addr)) ++ random_addr = true; + +- /* Generate the P2P Device Address. This consists of the device's +- * primary MAC address with the locally administered bit set. ++ /* Generate the P2P Device Address obtaining a random ethernet ++ * address with the locally administered bit set. + */ +- memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); +- if (local_admin) +- p2p->dev_addr[0] |= 0x02; ++ if (random_addr) ++ eth_random_addr(p2p->dev_addr); ++ else ++ memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); + + /* Generate the P2P Interface Address. If the discovery and connection + * BSSCFGs need to simultaneously co-exist, then this address must be diff --git a/root/package/kernel/mac80211/patches/323-v4.16-0001-brcmfmac-drop-Inter-Access-Point-Protocol-packets-by.patch b/root/package/kernel/mac80211/patches/323-v4.16-0001-brcmfmac-drop-Inter-Access-Point-Protocol-packets-by.patch new file mode 100644 index 00000000..f25dea01 --- /dev/null +++ b/root/package/kernel/mac80211/patches/323-v4.16-0001-brcmfmac-drop-Inter-Access-Point-Protocol-packets-by.patch @@ -0,0 +1,157 @@ +From 1259055170287a350cad453e9eac139c81609860 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 15 Mar 2018 08:29:09 +0100 +Subject: [PATCH] brcmfmac: drop Inter-Access Point Protocol packets by default +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Testing brcmfmac with more recent firmwares resulted in AP interfaces +not working in some specific setups. Debugging resulted in discovering +support for IAPP in Broadcom's firmwares. + +Older firmwares were only generating 802.11f frames. Newer ones like: +1) 10.10 (TOB) (r663589) +2) 10.10.122.20 (r683106) +for 4366b1 and 4366c0 respectively seem to also /respect/ 802.11f frames +in the Tx path by performing a STA disassociation. + +This obsoleted standard and its implementation is something that: +1) Most people don't need / want to use +2) Can allow local DoS attacks +3) Breaks AP interfaces in some specific bridge setups + +To solve issues it can cause this commit modifies brcmfmac to drop IAPP +packets. If affects: +1) Rx path: driver won't be sending these unwanted packets up. +2) Tx path: driver will reject packets that would trigger STA + disassociation perfromed by a firmware (possible local DoS attack). + +It appears there are some Broadcom's clients/users who care about this +feature despite the drawbacks. They can switch it on using a new module +param. + +This change results in only two more comparisons (check for module param +and check for Ethernet packet length) for 99.9% of packets. Its overhead +should be very minimal. + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/common.c | 5 ++ + .../wireless/broadcom/brcm80211/brcmfmac/common.h | 1 + + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 57 ++++++++++++++++++++++ + 3 files changed, 63 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -75,6 +75,10 @@ static int brcmf_roamoff; + module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR); + MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); + ++static int brcmf_iapp_enable; ++module_param_named(iapp, brcmf_iapp_enable, int, 0); ++MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol"); ++ + #ifdef DEBUG + /* always succeed brcmf_bus_started() */ + static int brcmf_ignore_probe_fail; +@@ -441,6 +445,7 @@ struct brcmf_mp_device *brcmf_get_module + settings->feature_disable = brcmf_feature_disable; + settings->fcmode = brcmf_fcmode; + settings->roamoff = !!brcmf_roamoff; ++ settings->iapp = !!brcmf_iapp_enable; + #ifdef DEBUG + settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; + #endif +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -58,6 +58,7 @@ struct brcmf_mp_device { + unsigned int feature_disable; + int fcmode; + bool roamoff; ++ bool iapp; + bool ignore_probe_fail; + struct brcmfmac_pd_cc *country_codes; + union { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -230,6 +230,37 @@ static void brcmf_netdev_set_multicast_l + schedule_work(&ifp->multicast_work); + } + ++/** ++ * brcmf_skb_is_iapp - checks if skb is an IAPP packet ++ * ++ * @skb: skb to check ++ */ ++static bool brcmf_skb_is_iapp(struct sk_buff *skb) ++{ ++ static const u8 iapp_l2_update_packet[6] __aligned(2) = { ++ 0x00, 0x01, 0xaf, 0x81, 0x01, 0x00, ++ }; ++ unsigned char *eth_data; ++#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ++ const u16 *a, *b; ++#endif ++ ++ if (skb->len - skb->mac_len != 6 || ++ !is_multicast_ether_addr(eth_hdr(skb)->h_dest)) ++ return false; ++ ++ eth_data = skb_mac_header(skb) + ETH_HLEN; ++#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ++ return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) | ++ ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4)))); ++#else ++ a = (const u16 *)eth_data; ++ b = (const u16 *)iapp_l2_update_packet; ++ ++ return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])); ++#endif ++} ++ + static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, + struct net_device *ndev) + { +@@ -250,6 +281,23 @@ static netdev_tx_t brcmf_netdev_start_xm + goto done; + } + ++ /* Some recent Broadcom's firmwares disassociate STA when they receive ++ * an 802.11f ADD frame. This behavior can lead to a local DoS security ++ * issue. Attacker may trigger disassociation of any STA by sending a ++ * proper Ethernet frame to the wireless interface. ++ * ++ * Moreover this feature may break AP interfaces in some specific ++ * setups. This applies e.g. to the bridge with hairpin mode enabled and ++ * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware ++ * will get passed back to the wireless interface and cause immediate ++ * disassociation of a just-connected STA. ++ */ ++ if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { ++ dev_kfree_skb(skb); ++ ret = -EINVAL; ++ goto done; ++ } ++ + /* Make sure there's enough writeable headroom */ + if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) { + head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0); +@@ -325,6 +373,15 @@ void brcmf_txflowblock_if(struct brcmf_i + + void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) + { ++ /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new ++ * STA connects to the AP interface. This is an obsoleted standard most ++ * users don't use, so don't pass these frames up unless requested. ++ */ ++ if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) { ++ brcmu_pkt_buf_free_skb(skb); ++ return; ++ } ++ + if (skb->pkt_type == PACKET_MULTICAST) + ifp->ndev->stats.multicast++; + diff --git a/root/package/kernel/mac80211/patches/324-v4.16-0001-brcmfmac-Fix-check-for-ISO3166-code.patch b/root/package/kernel/mac80211/patches/324-v4.16-0001-brcmfmac-Fix-check-for-ISO3166-code.patch new file mode 100644 index 00000000..d45f64ff --- /dev/null +++ b/root/package/kernel/mac80211/patches/324-v4.16-0001-brcmfmac-Fix-check-for-ISO3166-code.patch @@ -0,0 +1,29 @@ +From 9b9322db5c5a1917a66c71fe47c3848a9a31227e Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Wed, 14 Mar 2018 20:02:59 +0100 +Subject: [PATCH] brcmfmac: Fix check for ISO3166 code + +The commit "regulatory: add NUL to request alpha2" increases the length of +alpha2 to 3. This causes a regression on brcmfmac, because +brcmf_cfg80211_reg_notifier() expect valid ISO3166 codes in the complete +array. So fix this accordingly. + +Fixes: 657308f73e67 ("regulatory: add NUL to request alpha2") +Signed-off-by: Stefan Wahren +Acked-by: Franky Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6803,7 +6803,7 @@ static void brcmf_cfg80211_reg_notifier( + return; + + /* ignore non-ISO3166 country codes */ +- for (i = 0; i < sizeof(req->alpha2); i++) ++ for (i = 0; i < 2; i++) + if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { + brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n", + req->alpha2[0], req->alpha2[1]); diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0001-brcmfmac-move-brcmf_bus_preinit-call-just-after-chan.patch b/root/package/kernel/mac80211/patches/325-v4.17-0001-brcmfmac-move-brcmf_bus_preinit-call-just-after-chan.patch new file mode 100644 index 00000000..f4d9a84b --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0001-brcmfmac-move-brcmf_bus_preinit-call-just-after-chan.patch @@ -0,0 +1,45 @@ +From da472385a29f1fddcac7cfa0499482704310bd16 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:18 +0100 +Subject: [PATCH] brcmfmac: move brcmf_bus_preinit() call just after changing + bus state + +Moving the brcmf_bus_preinit() call allows the bus code to do some +required initialization before handling firmware control messages. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 3 --- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++++ + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -369,9 +369,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + + /* Enable tx beamforming, errors can be ignored (not supported) */ + (void)brcmf_fil_iovar_int_set(ifp, "txbf", 1); +- +- /* do bus specific preinit here */ +- err = brcmf_bus_preinit(ifp->drvr->bus_if); + done: + return err; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1091,6 +1091,11 @@ int brcmf_bus_started(struct device *dev + /* signal bus ready */ + brcmf_bus_change_state(bus_if, BRCMF_BUS_UP); + ++ /* do bus specific preinit here */ ++ ret = brcmf_bus_preinit(ifp->drvr->bus_if); ++ if (ret < 0) ++ goto fail; ++ + /* Bus is ready, do any initialization */ + ret = brcmf_c_preinit_dcmds(ifp); + if (ret < 0) diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0002-brcmfmac-move-allocation-of-control-rx-buffer-to-brc.patch b/root/package/kernel/mac80211/patches/325-v4.17-0002-brcmfmac-move-allocation-of-control-rx-buffer-to-brc.patch new file mode 100644 index 00000000..230e891c --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0002-brcmfmac-move-allocation-of-control-rx-buffer-to-brc.patch @@ -0,0 +1,69 @@ +From 4b5adc736828dc25ca33e263ad8c0b9dcd3bf325 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:19 +0100 +Subject: [PATCH] brcmfmac: move allocation of control rx buffer to + brcmf_sdio_bus_preinit() + +Allocate the control rx buffer needed for firmware control interface +during brcmf_sdio_bus_preinit(). This relies on common layer setting +struct brcmf_bus::maxctl during brcmf_attach(). By moving the allocation +we can move brcmf_attach() in subsequent change. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 26 ++++++++++------------ + 1 file changed, 12 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1707,7 +1707,6 @@ brcmf_sdio_read_control(struct brcmf_sdi + int sdret; + + brcmf_dbg(TRACE, "Enter\n"); +- + if (bus->rxblen) + buf = vzalloc(bus->rxblen); + if (!buf) +@@ -3411,6 +3410,18 @@ static int brcmf_sdio_bus_preinit(struct + u32 value; + int err; + ++ /* maxctl provided by common layer */ ++ if (WARN_ON(!bus_if->maxctl)) ++ return -EINVAL; ++ ++ /* Allocate control receive buffer */ ++ bus_if->maxctl += bus->roundup; ++ value = roundup((bus_if->maxctl + SDPCM_HDRLEN), ALIGNMENT); ++ value += bus->head_align; ++ bus->rxbuf = kmalloc(value, GFP_ATOMIC); ++ if (bus->rxbuf) ++ bus->rxblen = value; ++ + /* the commands below use the terms tx and rx from + * a device perspective, ie. bus:txglom affects the + * bus transfers from device to host. +@@ -4209,19 +4220,6 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->blocksize = bus->sdiodev->func2->cur_blksize; + bus->roundup = min(max_roundup, bus->blocksize); + +- /* Allocate buffers */ +- if (bus->sdiodev->bus_if->maxctl) { +- bus->sdiodev->bus_if->maxctl += bus->roundup; +- bus->rxblen = +- roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), +- ALIGNMENT) + bus->head_align; +- bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); +- if (!(bus->rxbuf)) { +- brcmf_err("rxbuf allocation failed\n"); +- goto fail; +- } +- } +- + sdio_claim_host(bus->sdiodev->func1); + + /* Disable F2 to clear any intermediate frame state on the dongle */ diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0003-brcmfmac-call-brcmf_attach-just-before-calling-brcmf.patch b/root/package/kernel/mac80211/patches/325-v4.17-0003-brcmfmac-call-brcmf_attach-just-before-calling-brcmf.patch new file mode 100644 index 00000000..a8b0171c --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0003-brcmfmac-call-brcmf_attach-just-before-calling-brcmf.patch @@ -0,0 +1,106 @@ +From 262f2b53f67936b59cc8dfc6f3899ab8905bf1ed Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:20 +0100 +Subject: [PATCH] brcmfmac: call brcmf_attach() just before calling + brcmf_bus_started() + +Now we can move brcmf_attach() until after the firmware has been downloaded +to the device. Make the call just before brcmf_bus_started(). + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 6 ++++ + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 34 +++++++++++----------- + 2 files changed, 23 insertions(+), 17 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1268,6 +1268,12 @@ void brcmf_bus_change_state(struct brcmf + int ifidx; + + brcmf_dbg(TRACE, "%d -> %d\n", bus->state, state); ++ ++ if (!drvr) { ++ brcmf_dbg(INFO, "ignoring transition, bus not attached yet\n"); ++ return; ++ } ++ + bus->state = state; + + if (state == BRCMF_BUS_UP) { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4048,9 +4048,6 @@ static void brcmf_sdio_firmware_callback + if (err) + goto fail; + +- if (!bus_if->drvr) +- return; +- + /* try to download image and nvram to the dongle */ + bus->alp_only = true; + err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); +@@ -4126,11 +4123,28 @@ static void brcmf_sdio_firmware_callback + + sdio_release_host(sdiodev->func1); + ++ /* Assign bus interface call back */ ++ sdiodev->bus_if->dev = sdiodev->dev; ++ sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; ++ sdiodev->bus_if->chip = bus->ci->chip; ++ sdiodev->bus_if->chiprev = bus->ci->chiprev; ++ ++ /* Attach to the common layer, reserve hdr space */ ++ err = brcmf_attach(sdiodev->dev, sdiodev->settings); ++ if (err != 0) { ++ brcmf_err("brcmf_attach failed\n"); ++ goto fail; ++ } ++ ++ brcmf_sdio_debugfs_create(bus); ++ + err = brcmf_bus_started(dev); + if (err != 0) { + brcmf_err("dongle is not responding\n"); + goto fail; + } ++ ++ /* ready */ + return; + + release: +@@ -4200,22 +4214,9 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->dpc_triggered = false; + bus->dpc_running = false; + +- /* Assign bus interface call back */ +- bus->sdiodev->bus_if->dev = bus->sdiodev->dev; +- bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; +- bus->sdiodev->bus_if->chip = bus->ci->chip; +- bus->sdiodev->bus_if->chiprev = bus->ci->chiprev; +- + /* default sdio bus header length for tx packet */ + bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; + +- /* Attach to the common layer, reserve hdr space */ +- ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings); +- if (ret != 0) { +- brcmf_err("brcmf_attach failed\n"); +- goto fail; +- } +- + /* Query the F2 block size, set roundup accordingly */ + bus->blocksize = bus->sdiodev->func2->cur_blksize; + bus->roundup = min(max_roundup, bus->blocksize); +@@ -4240,7 +4241,6 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + /* SR state */ + bus->sr_enabled = false; + +- brcmf_sdio_debugfs_create(bus); + brcmf_dbg(INFO, "completed!!\n"); + + ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev, diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0004-brcmfmac-usb-call-brcmf_usb_up-during-brcmf_bus_prei.patch b/root/package/kernel/mac80211/patches/325-v4.17-0004-brcmfmac-usb-call-brcmf_usb_up-during-brcmf_bus_prei.patch new file mode 100644 index 00000000..00c4141c --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0004-brcmfmac-usb-call-brcmf_usb_up-during-brcmf_bus_prei.patch @@ -0,0 +1,41 @@ +From a7f4a80c0070b673d4a4ce94b99979ea6d0c6296 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:21 +0100 +Subject: [PATCH] brcmfmac: usb: call brcmf_usb_up() during brcmf_bus_preinit() + +By calling brcmf_usb_up() during brcmf_bus_preinit() it does not need +to be called in brcmf_usb_bus_setup(). + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1146,8 +1146,9 @@ static int brcmf_usb_get_fwname(struct d + } + + static const struct brcmf_bus_ops brcmf_usb_bus_ops = { +- .txdata = brcmf_usb_tx, ++ .preinit = brcmf_usb_up, + .stop = brcmf_usb_down, ++ .txdata = brcmf_usb_tx, + .txctl = brcmf_usb_tx_ctlpkt, + .rxctl = brcmf_usb_rx_ctlpkt, + .wowl_config = brcmf_usb_wowl_config, +@@ -1165,10 +1166,6 @@ static int brcmf_usb_bus_setup(struct br + return ret; + } + +- ret = brcmf_usb_up(devinfo->dev); +- if (ret) +- goto fail; +- + ret = brcmf_bus_started(devinfo->dev); + if (ret) + goto fail; diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0005-brcmfmac-move-brcmf_attach-function-in-core.c.patch b/root/package/kernel/mac80211/patches/325-v4.17-0005-brcmfmac-move-brcmf_attach-function-in-core.c.patch new file mode 100644 index 00000000..086b5fad --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0005-brcmfmac-move-brcmf_attach-function-in-core.c.patch @@ -0,0 +1,130 @@ +From 0542503c4c164c65cd1567b0f2b3f887af6c81eb Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:22 +0100 +Subject: [PATCH] brcmfmac: move brcmf_attach() function in core.c + +Moving the function in preparation of subsequent patch. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 98 +++++++++++----------- + 1 file changed, 49 insertions(+), 49 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -992,55 +992,6 @@ static int brcmf_inet6addr_changed(struc + } + #endif + +-int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) +-{ +- struct brcmf_pub *drvr = NULL; +- int ret = 0; +- int i; +- +- brcmf_dbg(TRACE, "Enter\n"); +- +- /* Allocate primary brcmf_info */ +- drvr = kzalloc(sizeof(struct brcmf_pub), GFP_ATOMIC); +- if (!drvr) +- return -ENOMEM; +- +- for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) +- drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; +- +- mutex_init(&drvr->proto_block); +- +- /* Link to bus module */ +- drvr->hdrlen = 0; +- drvr->bus_if = dev_get_drvdata(dev); +- drvr->bus_if->drvr = drvr; +- drvr->settings = settings; +- +- /* attach debug facilities */ +- brcmf_debug_attach(drvr); +- +- /* Attach and link in the protocol */ +- ret = brcmf_proto_attach(drvr); +- if (ret != 0) { +- brcmf_err("brcmf_prot_attach failed\n"); +- goto fail; +- } +- +- /* Attach to events important for core code */ +- brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG, +- brcmf_psm_watchdog_notify); +- +- /* attach firmware event handler */ +- brcmf_fweh_attach(drvr); +- +- return ret; +- +-fail: +- brcmf_detach(dev); +- +- return ret; +-} +- + static int brcmf_revinfo_read(struct seq_file *s, void *data) + { + struct brcmf_bus *bus_if = dev_get_drvdata(s->private); +@@ -1170,6 +1121,55 @@ fail: + + return ret; + } ++ ++int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) ++{ ++ struct brcmf_pub *drvr = NULL; ++ int ret = 0; ++ int i; ++ ++ brcmf_dbg(TRACE, "Enter\n"); ++ ++ /* Allocate primary brcmf_info */ ++ drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC); ++ if (!drvr) ++ return -ENOMEM; ++ ++ for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) ++ drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; ++ ++ mutex_init(&drvr->proto_block); ++ ++ /* Link to bus module */ ++ drvr->hdrlen = 0; ++ drvr->bus_if = dev_get_drvdata(dev); ++ drvr->bus_if->drvr = drvr; ++ drvr->settings = settings; ++ ++ /* attach debug facilities */ ++ brcmf_debug_attach(drvr); ++ ++ /* Attach and link in the protocol */ ++ ret = brcmf_proto_attach(drvr); ++ if (ret != 0) { ++ brcmf_err("brcmf_prot_attach failed\n"); ++ goto fail; ++ } ++ ++ /* Attach to events important for core code */ ++ brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG, ++ brcmf_psm_watchdog_notify); ++ ++ /* attach firmware event handler */ ++ brcmf_fweh_attach(drvr); ++ ++ return ret; ++ ++fail: ++ brcmf_detach(dev); ++ ++ return ret; ++} + + void brcmf_bus_add_txhdrlen(struct device *dev, uint len) + { diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0006-brcmfmac-remove-brcmf_bus_started-from-bus-api.patch b/root/package/kernel/mac80211/patches/325-v4.17-0006-brcmfmac-remove-brcmf_bus_started-from-bus-api.patch new file mode 100644 index 00000000..6d23ccda --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0006-brcmfmac-remove-brcmf_bus_started-from-bus-api.patch @@ -0,0 +1,190 @@ +From de2a3027f6f15e2f6558dc4d178282ccc1f054db Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:23 +0100 +Subject: [PATCH] brcmfmac: remove brcmf_bus_started() from bus api + +No longer needed to call this in bus layer so make it static and call +it in the last phase of brcmf_attach() instead. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 1 - + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 14 +++++++---- + .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 20 +--------------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 10 ++------ + .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 28 ++++------------------ + 5 files changed, 16 insertions(+), 57 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -253,7 +253,6 @@ void brcmf_dev_reset(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); + +-int brcmf_bus_started(struct device *dev); + s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len); + void brcmf_bus_add_txhdrlen(struct device *dev, uint len); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1022,11 +1022,10 @@ static int brcmf_revinfo_read(struct seq + return 0; + } + +-int brcmf_bus_started(struct device *dev) ++static int brcmf_bus_started(struct brcmf_pub *drvr) + { + int ret = -1; +- struct brcmf_bus *bus_if = dev_get_drvdata(dev); +- struct brcmf_pub *drvr = bus_if->drvr; ++ struct brcmf_bus *bus_if = drvr->bus_if; + struct brcmf_if *ifp; + struct brcmf_if *p2p_ifp; + +@@ -1043,7 +1042,7 @@ int brcmf_bus_started(struct device *dev + brcmf_bus_change_state(bus_if, BRCMF_BUS_UP); + + /* do bus specific preinit here */ +- ret = brcmf_bus_preinit(ifp->drvr->bus_if); ++ ret = brcmf_bus_preinit(bus_if); + if (ret < 0) + goto fail; + +@@ -1163,7 +1162,12 @@ int brcmf_attach(struct device *dev, str + /* attach firmware event handler */ + brcmf_fweh_attach(drvr); + +- return ret; ++ ret = brcmf_bus_started(drvr); ++ if (ret != 0) { ++ brcmf_err("dongle is not responding: err=%d\n", ret); ++ goto fail; ++ } ++ return 0; + + fail: + brcmf_detach(dev); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1581,24 +1581,6 @@ static void brcmf_pcie_release_resource( + } + + +-static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo) +-{ +- int ret; +- +- /* Attach to the common driver interface */ +- ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings); +- if (ret) { +- brcmf_err("brcmf_attach failed\n"); +- } else { +- ret = brcmf_bus_started(&devinfo->pdev->dev); +- if (ret) +- brcmf_err("dongle is not responding\n"); +- } +- +- return ret; +-} +- +- + static u32 brcmf_pcie_buscore_prep_addr(const struct pci_dev *pdev, u32 addr) + { + u32 ret_addr; +@@ -1735,7 +1717,7 @@ static void brcmf_pcie_setup(struct devi + init_waitqueue_head(&devinfo->mbdata_resp_wait); + + brcmf_pcie_intr_enable(devinfo); +- if (brcmf_pcie_attach_bus(devinfo) == 0) ++ if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) + return; + + brcmf_pcie_bus_console_read(devinfo); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3422,6 +3422,8 @@ static int brcmf_sdio_bus_preinit(struct + if (bus->rxbuf) + bus->rxblen = value; + ++ brcmf_sdio_debugfs_create(bus); ++ + /* the commands below use the terms tx and rx from + * a device perspective, ie. bus:txglom affects the + * bus transfers from device to host. +@@ -4136,14 +4138,6 @@ static void brcmf_sdio_firmware_callback + goto fail; + } + +- brcmf_sdio_debugfs_create(bus); +- +- err = brcmf_bus_started(dev); +- if (err != 0) { +- brcmf_err("dongle is not responding\n"); +- goto fail; +- } +- + /* ready */ + return; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1155,27 +1155,6 @@ static const struct brcmf_bus_ops brcmf_ + .get_fwname = brcmf_usb_get_fwname, + }; + +-static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) +-{ +- int ret; +- +- /* Attach to the common driver interface */ +- ret = brcmf_attach(devinfo->dev, devinfo->settings); +- if (ret) { +- brcmf_err("brcmf_attach failed\n"); +- return ret; +- } +- +- ret = brcmf_bus_started(devinfo->dev); +- if (ret) +- goto fail; +- +- return 0; +-fail: +- brcmf_detach(devinfo->dev); +- return ret; +-} +- + static void brcmf_usb_probe_phase2(struct device *dev, int ret, + const struct firmware *fw, + void *nvram, u32 nvlen) +@@ -1203,7 +1182,8 @@ static void brcmf_usb_probe_phase2(struc + if (ret) + goto error; + +- ret = brcmf_usb_bus_setup(devinfo); ++ /* Attach to the common driver interface */ ++ ret = brcmf_attach(devinfo->dev, devinfo->settings); + if (ret) + goto error; + +@@ -1253,7 +1233,7 @@ static int brcmf_usb_probe_cb(struct brc + } + + if (!brcmf_usb_dlneeded(devinfo)) { +- ret = brcmf_usb_bus_setup(devinfo); ++ ret = brcmf_attach(devinfo->dev, devinfo->settings); + if (ret) + goto fail; + /* we are done */ +@@ -1456,7 +1436,7 @@ static int brcmf_usb_resume(struct usb_i + + brcmf_dbg(USB, "Enter\n"); + if (!devinfo->wowl_enabled) +- return brcmf_usb_bus_setup(devinfo); ++ return brcmf_attach(devinfo->dev, devinfo->settings); + + devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP; + brcmf_usb_rx_fill_all(devinfo); diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0007-brcmfmac-change-log-level-for-some-low-level-sdio-fu.patch b/root/package/kernel/mac80211/patches/325-v4.17-0007-brcmfmac-change-log-level-for-some-low-level-sdio-fu.patch new file mode 100644 index 00000000..34482691 --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0007-brcmfmac-change-log-level-for-some-low-level-sdio-fu.patch @@ -0,0 +1,64 @@ +From d678296bfb9a630d0000222fc21f4ed0d0d65332 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:24 +0100 +Subject: [PATCH] brcmfmac: change log level for some low-level sdio functions + +Reducing the number of trace level messages in sdio code giving +them sdio log level instead. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1706,7 +1706,7 @@ brcmf_sdio_read_control(struct brcmf_sdi + u8 *buf = NULL, *rbuf; + int sdret; + +- brcmf_dbg(TRACE, "Enter\n"); ++ brcmf_dbg(SDIO, "Enter\n"); + if (bus->rxblen) + buf = vzalloc(bus->rxblen); + if (!buf) +@@ -1809,7 +1809,7 @@ static uint brcmf_sdio_readframes(struct + struct brcmf_sdio_hdrinfo *rd = &bus->cur_read, rd_new; + u8 head_read = 0; + +- brcmf_dbg(TRACE, "Enter\n"); ++ brcmf_dbg(SDIO, "Enter\n"); + + /* Not finished unless we encounter no more frames indication */ + bus->rxpending = true; +@@ -2344,7 +2344,7 @@ static int brcmf_sdio_tx_ctrlframe(struc + struct brcmf_sdio_hdrinfo hd_info = {0}; + int ret; + +- brcmf_dbg(TRACE, "Enter\n"); ++ brcmf_dbg(SDIO, "Enter\n"); + + /* Back the pointer to make room for bus header */ + frame -= bus->tx_hdrlen; +@@ -2520,7 +2520,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + uint framecnt; /* Temporary counter of tx/rx frames */ + int err = 0; + +- brcmf_dbg(TRACE, "Enter\n"); ++ brcmf_dbg(SDIO, "Enter\n"); + + sdio_claim_host(bus->sdiodev->func1); + +@@ -2605,7 +2605,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + + /* Would be active due to wake-wlan in gSPI */ + if (intstatus & I_CHIPACTIVE) { +- brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n"); ++ brcmf_dbg(SDIO, "Dongle reports CHIPACTIVE\n"); + intstatus &= ~I_CHIPACTIVE; + } + diff --git a/root/package/kernel/mac80211/patches/325-v4.17-0008-brcmfmac-remove-duplicate-pointer-variable-from-brcm.patch b/root/package/kernel/mac80211/patches/325-v4.17-0008-brcmfmac-remove-duplicate-pointer-variable-from-brcm.patch new file mode 100644 index 00000000..39fba211 --- /dev/null +++ b/root/package/kernel/mac80211/patches/325-v4.17-0008-brcmfmac-remove-duplicate-pointer-variable-from-brcm.patch @@ -0,0 +1,126 @@ +From 2d6edad4b2da1991f74e7b02053eeb4a043b887f Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 20 Feb 2018 00:14:25 +0100 +Subject: [PATCH] brcmfmac: remove duplicate pointer variable from + brcmf_sdio_firmware_callback() + +In brcmf_sdio_firmware_callback() two pointer variables were used +pointing to the same construct. Get rid of sdiodev variable. + +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 37 +++++++++++----------- + 1 file changed, 18 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4039,9 +4039,8 @@ static void brcmf_sdio_firmware_callback + void *nvram, u32 nvram_len) + { + struct brcmf_bus *bus_if = dev_get_drvdata(dev); +- struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; +- struct brcmf_sdio *bus = sdiodev->bus; +- struct brcmf_sdio_dev *sdiod = bus->sdiodev; ++ struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio; ++ struct brcmf_sdio *bus = sdiod->bus; + struct brcmf_core *core = bus->sdio_core; + u8 saveclk; + +@@ -4061,7 +4060,7 @@ static void brcmf_sdio_firmware_callback + bus->sdcnt.tickcnt = 0; + brcmf_sdio_wd_timer(bus, true); + +- sdio_claim_host(sdiodev->func1); ++ sdio_claim_host(sdiod->func1); + + /* Make sure backplane clock is on, needed to generate F2 interrupt */ + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); +@@ -4069,9 +4068,9 @@ static void brcmf_sdio_firmware_callback + goto release; + + /* Force clocks on backplane to be sure F2 interrupt propagates */ +- saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); ++ saveclk = brcmf_sdiod_readb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, &err); + if (!err) { +- brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); + } + if (err) { +@@ -4083,7 +4082,7 @@ static void brcmf_sdio_firmware_callback + brcmf_sdiod_writel(sdiod, core->base + SD_REG(tosbmailboxdata), + SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, NULL); + +- err = sdio_enable_func(sdiodev->func2); ++ err = sdio_enable_func(sdiod->func2); + + brcmf_dbg(INFO, "enable F2: err=%d\n", err); + +@@ -4095,10 +4094,10 @@ static void brcmf_sdio_firmware_callback + bus->hostintmask, NULL); + + +- brcmf_sdiod_writeb(sdiodev, SBSDIO_WATERMARK, 8, &err); ++ brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, 8, &err); + } else { + /* Disable F2 again */ +- sdio_disable_func(sdiodev->func2); ++ sdio_disable_func(sdiod->func2); + goto release; + } + +@@ -4106,7 +4105,7 @@ static void brcmf_sdio_firmware_callback + brcmf_sdio_sr_init(bus); + } else { + /* Restore previous clock setting */ +- brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, + saveclk, &err); + } + +@@ -4114,7 +4113,7 @@ static void brcmf_sdio_firmware_callback + /* Allow full data communication using DPC from now on. */ + brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); + +- err = brcmf_sdiod_intr_register(sdiodev); ++ err = brcmf_sdiod_intr_register(sdiod); + if (err != 0) + brcmf_err("intr register failed:%d\n", err); + } +@@ -4123,16 +4122,16 @@ static void brcmf_sdio_firmware_callback + if (err != 0) + brcmf_sdio_clkctl(bus, CLK_NONE, false); + +- sdio_release_host(sdiodev->func1); ++ sdio_release_host(sdiod->func1); + + /* Assign bus interface call back */ +- sdiodev->bus_if->dev = sdiodev->dev; +- sdiodev->bus_if->ops = &brcmf_sdio_bus_ops; +- sdiodev->bus_if->chip = bus->ci->chip; +- sdiodev->bus_if->chiprev = bus->ci->chiprev; ++ sdiod->bus_if->dev = sdiod->dev; ++ sdiod->bus_if->ops = &brcmf_sdio_bus_ops; ++ sdiod->bus_if->chip = bus->ci->chip; ++ sdiod->bus_if->chiprev = bus->ci->chiprev; + + /* Attach to the common layer, reserve hdr space */ +- err = brcmf_attach(sdiodev->dev, sdiodev->settings); ++ err = brcmf_attach(sdiod->dev, sdiod->settings); + if (err != 0) { + brcmf_err("brcmf_attach failed\n"); + goto fail; +@@ -4142,10 +4141,10 @@ static void brcmf_sdio_firmware_callback + return; + + release: +- sdio_release_host(sdiodev->func1); ++ sdio_release_host(sdiod->func1); + fail: + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err); +- device_release_driver(&sdiodev->func2->dev); ++ device_release_driver(&sdiod->func2->dev); + device_release_driver(dev); + } + diff --git a/root/package/kernel/mac80211/patches/326-v4.17-0001-brcmfmac-reject-too-long-PSK.patch b/root/package/kernel/mac80211/patches/326-v4.17-0001-brcmfmac-reject-too-long-PSK.patch new file mode 100644 index 00000000..b83f2fce --- /dev/null +++ b/root/package/kernel/mac80211/patches/326-v4.17-0001-brcmfmac-reject-too-long-PSK.patch @@ -0,0 +1,27 @@ +From 64d1519edc959f5b8f86a66a51c40971c215e4ec Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 19 Feb 2018 13:30:45 +0100 +Subject: [PATCH] brcmfmac: reject too long PSK + +nl80211 already allows specifying 48 bytes, but brcmfmac +only supports 32. Reject keys that are too long. + +Signed-off-by: Johannes Berg +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + 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 +@@ -5125,6 +5125,9 @@ static int brcmf_cfg80211_set_pmk(struct + if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X)) + return -EINVAL; + ++ if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN) ++ return -ERANGE; ++ + return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len); + } + diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0001-brcmfmac-do-not-convert-linux-error-to-firmware-erro.patch b/root/package/kernel/mac80211/patches/327-v4.17-0001-brcmfmac-do-not-convert-linux-error-to-firmware-erro.patch new file mode 100644 index 00000000..2e9ec8b9 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0001-brcmfmac-do-not-convert-linux-error-to-firmware-erro.patch @@ -0,0 +1,31 @@ +From 1170f6d1be6a39e1a115a2c0f50923eb4ce2a7ec Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:20 +0100 +Subject: [PATCH] brcmfmac: do not convert linux error to firmware error string + +In case of a linux error brcmf_fil_cmd_data() blurts an error message +in which the error code is translated to an error string. However, it +maps it to a firmware error string which should not happen. Simply +print only the numeric error code and be done with it. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +@@ -124,8 +124,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, + data, len, &fwerr); + + if (err) { +- brcmf_dbg(FIL, "Failed: %s (%d)\n", +- brcmf_fil_get_errstr((u32)(-err)), err); ++ brcmf_dbg(FIL, "Failed: error=%d\n", err); + } else if (fwerr < 0) { + brcmf_dbg(FIL, "Firmware error: %s (%d)\n", + brcmf_fil_get_errstr((u32)(-fwerr)), fwerr); diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0002-brcmfmac-use-brcmf_chip_name-to-store-name-in-revinf.patch b/root/package/kernel/mac80211/patches/327-v4.17-0002-brcmfmac-use-brcmf_chip_name-to-store-name-in-revinf.patch new file mode 100644 index 00000000..79081195 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0002-brcmfmac-use-brcmf_chip_name-to-store-name-in-revinf.patch @@ -0,0 +1,203 @@ +From 756a2b390874d274f2f615921318ef0856ff9313 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:21 +0100 +Subject: [PATCH] brcmfmac: use brcmf_chip_name() to store name in revinfo + +The chip id can either be four or five digits. For the chip name either +the hexadecimal value needs to be taken (four digits) or the decimal +value (five digits). The function brcmf_chip_name() does this conversion +so use it to store the name in driver revision info. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/chip.c | 9 +++++---- + .../wireless/broadcom/brcm80211/brcmfmac/chip.h | 3 ++- + .../wireless/broadcom/brcm80211/brcmfmac/common.c | 23 ++++++++++++++++------ + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 10 +--------- + .../wireless/broadcom/brcm80211/brcmfmac/core.h | 3 +-- + 5 files changed, 26 insertions(+), 22 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -464,12 +464,12 @@ static void brcmf_chip_ai_resetcore(stru + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL); + } + +-static char *brcmf_chip_name(uint chipid, char *buf, uint len) ++char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len) + { + const char *fmt; + +- fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x"; +- snprintf(buf, len, fmt, chipid); ++ fmt = ((id > 0xa000) || (id < 0x4000)) ? "BCM%d/%u" : "BCM%x/%u"; ++ snprintf(buf, len, fmt, id, rev); + return buf; + } + +@@ -924,7 +924,8 @@ static int brcmf_chip_recognition(struct + ci->pub.chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; + socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; + +- brcmf_chip_name(ci->pub.chip, ci->pub.name, sizeof(ci->pub.name)); ++ brcmf_chip_name(ci->pub.chip, ci->pub.chiprev, ++ ci->pub.name, sizeof(ci->pub.name)); + brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n", + socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name, + ci->pub.chiprev); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +@@ -45,7 +45,7 @@ struct brcmf_chip { + u32 rambase; + u32 ramsize; + u32 srsize; +- char name[8]; ++ char name[12]; + }; + + /** +@@ -93,5 +93,6 @@ void brcmf_chip_resetcore(struct brcmf_c + void brcmf_chip_set_passive(struct brcmf_chip *ci); + bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec); + bool brcmf_chip_sr_capable(struct brcmf_chip *pub); ++char *brcmf_chip_name(u32 chipid, u32 chiprev, char *buf, uint len); + + #endif /* BRCMF_AXIDMP_H */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -30,6 +30,7 @@ + #include "common.h" + #include "of.h" + #include "firmware.h" ++#include "chip.h" + + MODULE_AUTHOR("Broadcom Corporation"); + MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); +@@ -131,14 +132,13 @@ static int brcmf_c_download(struct brcmf + static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) + { + struct brcmf_bus *bus = ifp->drvr->bus_if; +- struct brcmf_rev_info *ri = &ifp->drvr->revinfo; + u8 fw_name[BRCMF_FW_NAME_LEN]; + u8 *ptr; + size_t len; + s32 err; + + memset(fw_name, 0, BRCMF_FW_NAME_LEN); +- err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name); ++ err = brcmf_bus_get_fwname(bus, bus->chip, bus->chiprev, fw_name); + if (err) { + brcmf_err("get firmware name failed (%d)\n", err); + goto done; +@@ -238,6 +238,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + { + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + u8 buf[BRCMF_DCMD_SMLEN]; ++ struct brcmf_bus *bus; + struct brcmf_rev_info_le revinfo; + struct brcmf_rev_info *ri; + char *clmver; +@@ -253,16 +254,18 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + } + memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); + ++ bus = ifp->drvr->bus_if; ++ ri = &ifp->drvr->revinfo; ++ + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, + &revinfo, sizeof(revinfo)); +- ri = &ifp->drvr->revinfo; + if (err < 0) { + brcmf_err("retrieving revision info failed, %d\n", err); ++ strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname)); + } else { + ri->vendorid = le32_to_cpu(revinfo.vendorid); + ri->deviceid = le32_to_cpu(revinfo.deviceid); + ri->radiorev = le32_to_cpu(revinfo.radiorev); +- ri->chiprev = le32_to_cpu(revinfo.chiprev); + ri->corerev = le32_to_cpu(revinfo.corerev); + ri->boardid = le32_to_cpu(revinfo.boardid); + ri->boardvendor = le32_to_cpu(revinfo.boardvendor); +@@ -270,15 +273,23 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + ri->driverrev = le32_to_cpu(revinfo.driverrev); + ri->ucoderev = le32_to_cpu(revinfo.ucoderev); + ri->bus = le32_to_cpu(revinfo.bus); +- ri->chipnum = le32_to_cpu(revinfo.chipnum); + ri->phytype = le32_to_cpu(revinfo.phytype); + ri->phyrev = le32_to_cpu(revinfo.phyrev); + ri->anarev = le32_to_cpu(revinfo.anarev); + ri->chippkg = le32_to_cpu(revinfo.chippkg); + ri->nvramrev = le32_to_cpu(revinfo.nvramrev); ++ ++ if (!bus->chip) { ++ bus->chip = le32_to_cpu(revinfo.chipnum); ++ bus->chiprev = le32_to_cpu(revinfo.chiprev); ++ } + } + ri->result = err; + ++ if (bus->chip) ++ brcmf_chip_name(bus->chip, bus->chiprev, ++ ri->chipname, sizeof(ri->chipname)); ++ + /* Do any CLM downloading */ + err = brcmf_c_process_clm_blob(ifp); + if (err < 0) { +@@ -299,7 +310,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + strsep(&ptr, "\n"); + + /* Print fw version info */ +- brcmf_info("Firmware version = %s\n", buf); ++ brcmf_info("Firmware: %s %s\n", ri->chipname, buf); + + /* locate firmware version number for ethtool */ + ptr = strrchr(buf, ' ') + 1; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1002,8 +1002,7 @@ static int brcmf_revinfo_read(struct seq + seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid); + seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid); + seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev)); +- seq_printf(s, "chipnum: %u (%x)\n", ri->chipnum, ri->chipnum); +- seq_printf(s, "chiprev: %u\n", ri->chiprev); ++ seq_printf(s, "chip: %s\n", ri->chipname); + seq_printf(s, "chippkg: %u\n", ri->chippkg); + seq_printf(s, "corerev: %u\n", ri->corerev); + seq_printf(s, "boardid: 0x%04x\n", ri->boardid); +@@ -1053,13 +1052,6 @@ static int brcmf_bus_started(struct brcm + + brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); + +- /* assure we have chipid before feature attach */ +- if (!bus_if->chip) { +- bus_if->chip = drvr->revinfo.chipnum; +- bus_if->chiprev = drvr->revinfo.chiprev; +- brcmf_dbg(INFO, "firmware revinfo: chip %x (%d) rev %d\n", +- bus_if->chip, bus_if->chip, bus_if->chiprev); +- } + brcmf_feat_attach(drvr); + + ret = brcmf_proto_init_done(drvr); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -87,7 +87,6 @@ struct brcmf_rev_info { + u32 vendorid; + u32 deviceid; + u32 radiorev; +- u32 chiprev; + u32 corerev; + u32 boardid; + u32 boardvendor; +@@ -95,7 +94,7 @@ struct brcmf_rev_info { + u32 driverrev; + u32 ucoderev; + u32 bus; +- u32 chipnum; ++ char chipname[12]; + u32 phytype; + u32 phyrev; + u32 anarev; diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0003-brcmfmac-use-brcmf_chip_name-for-consistency.patch b/root/package/kernel/mac80211/patches/327-v4.17-0003-brcmfmac-use-brcmf_chip_name-for-consistency.patch new file mode 100644 index 00000000..e3d06f32 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0003-brcmfmac-use-brcmf_chip_name-for-consistency.patch @@ -0,0 +1,69 @@ +From c88cfa075de356ddf40c668896b2126340f19ba4 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:22 +0100 +Subject: [PATCH] brcmfmac: use brcmf_chip_name() for consistency + +When logging the chip id/revision information make use of +brcmf_chip_name() so it is always the same. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 5 ++--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 7 +++++-- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -926,9 +926,8 @@ static int brcmf_chip_recognition(struct + + brcmf_chip_name(ci->pub.chip, ci->pub.chiprev, + ci->pub.name, sizeof(ci->pub.name)); +- brcmf_dbg(INFO, "found %s chip: BCM%s, rev=%d\n", +- socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name, +- ci->pub.chiprev); ++ brcmf_dbg(INFO, "found %s chip: %s\n", ++ socitype == SOCI_SB ? "SB" : "AXI", ci->pub.name); + + if (socitype == SOCI_SB) { + if (ci->pub.chip != BRCM_CC_4329_CHIP_ID) { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -25,6 +25,7 @@ + #include "firmware.h" + #include "core.h" + #include "common.h" ++#include "chip.h" + + #define BRCMF_FW_MAX_NVRAM_SIZE 64000 + #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ +@@ -567,6 +568,7 @@ int brcmf_fw_map_chip_to_name(u32 chip, + u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], + char nvram_name[BRCMF_FW_NAME_LEN]) + { ++ char chipname[12]; + u32 i; + char end; + +@@ -581,6 +583,8 @@ int brcmf_fw_map_chip_to_name(u32 chip, + return -ENODEV; + } + ++ brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); ++ + /* check if firmware path is provided by module parameter */ + if (brcmf_mp_global.firmware_path[0] != '\0') { + strlcpy(fw_name, brcmf_mp_global.firmware_path, +@@ -601,8 +605,7 @@ int brcmf_fw_map_chip_to_name(u32 chip, + if ((nvram_name) && (mapping_table[i].nvram)) + strlcat(nvram_name, mapping_table[i].nvram, BRCMF_FW_NAME_LEN); + +- brcmf_info("using %s for chip %#08x(%d) rev %#08x\n", +- fw_name, chip, chip, chiprev); ++ brcmf_info("using %s for chip %s\n", fw_name, chipname); + + return 0; + } diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0004-brcmfmac-allocate-struct-brcmf_pub-instance-using-wi.patch b/root/package/kernel/mac80211/patches/327-v4.17-0004-brcmfmac-allocate-struct-brcmf_pub-instance-using-wi.patch new file mode 100644 index 00000000..42adff61 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0004-brcmfmac-allocate-struct-brcmf_pub-instance-using-wi.patch @@ -0,0 +1,452 @@ +From 856d5a011c86b59f6564be4508912fb1d866adfc Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:23 +0100 +Subject: [PATCH] brcmfmac: allocate struct brcmf_pub instance using + wiphy_new() + +Rework the driver so the wiphy instance holds the main driver information +in its private buffer. Previously it held struct brcmf_cfg80211_info +instance so a bit of reorg was needed. This was done so that the wiphy +name or its parent device can be shown in debug output. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/btcoex.c | 2 +- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 86 ++++++++++------------ + .../broadcom/brcm80211/brcmfmac/cfg80211.h | 17 +++-- + .../wireless/broadcom/brcm80211/brcmfmac/common.c | 2 + + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 27 +++++-- + .../wireless/broadcom/brcm80211/brcmfmac/core.h | 1 + + .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 2 +- + 7 files changed, 76 insertions(+), 61 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c +@@ -462,7 +462,7 @@ static void brcmf_btcoex_dhcp_end(struct + int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif, + enum brcmf_btcoex_mode mode, u16 duration) + { +- struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy); ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); + struct brcmf_btcoex_info *btci = cfg->btcoex; + struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -753,7 +753,7 @@ s32 brcmf_notify_escan_complete(struct b + static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, + struct wireless_dev *wdev) + { +- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct net_device *ndev = wdev->netdev; + struct brcmf_if *ifp = netdev_priv(ndev); + int ret; +@@ -786,7 +786,7 @@ err_unarm: + static + int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) + { +- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct net_device *ndev = wdev->netdev; + + if (ndev && ndev == cfg_to_ndev(cfg)) +@@ -831,7 +831,7 @@ brcmf_cfg80211_change_iface(struct wiphy + enum nl80211_iftype type, + struct vif_params *params) + { +- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_vif *vif = ifp->vif; + s32 infra = 0; +@@ -2127,17 +2127,15 @@ static s32 + brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, + s32 *dbm) + { +- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); +- struct net_device *ndev = cfg_to_ndev(cfg); +- struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev); + s32 qdbm = 0; + s32 err; + + brcmf_dbg(TRACE, "Enter\n"); +- if (!check_vif_up(ifp->vif)) ++ if (!check_vif_up(vif)) + return -EIO; + +- err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm); ++ err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm); + if (err) { + brcmf_err("error (%d)\n", err); + goto done; +@@ -3359,7 +3357,7 @@ brcmf_cfg80211_sched_scan_start(struct w + struct cfg80211_sched_scan_request *req) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + + brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n", + req->n_match_sets, req->n_ssids); +@@ -5191,6 +5189,12 @@ static struct cfg80211_ops brcmf_cfg8021 + .del_pmk = brcmf_cfg80211_del_pmk, + }; + ++struct cfg80211_ops *brcmf_cfg80211_get_ops(void) ++{ ++ return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops), ++ GFP_KERNEL); ++} ++ + struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, + enum nl80211_iftype type) + { +@@ -5898,7 +5902,7 @@ static void brcmf_update_bw40_channel_fl + static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + u32 bw_cap[]) + { +- struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); ++ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + struct ieee80211_supported_band *band; + struct ieee80211_channel *channel; + struct wiphy *wiphy; +@@ -6013,7 +6017,7 @@ fail_pbuf: + + static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) + { +- struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); ++ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + struct ieee80211_supported_band *band; + struct brcmf_fil_bwcap_le band_bwcap; + struct brcmf_chanspec_list *list; +@@ -6198,10 +6202,10 @@ static void brcmf_update_vht_cap(struct + } + } + +-static int brcmf_setup_wiphybands(struct wiphy *wiphy) ++static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + { +- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); +- struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); ++ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); ++ struct wiphy *wiphy; + u32 nmode = 0; + u32 vhtmode = 0; + u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; +@@ -6795,8 +6799,8 @@ static s32 brcmf_translate_country_code( + static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *req) + { +- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); +- struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + struct brcmf_fil_country_le ccreq; + s32 err; + int i; +@@ -6831,7 +6835,7 @@ static void brcmf_cfg80211_reg_notifier( + brcmf_err("Firmware rejected country setting\n"); + return; + } +- brcmf_setup_wiphybands(wiphy); ++ brcmf_setup_wiphybands(cfg); + } + + static void brcmf_free_wiphy(struct wiphy *wiphy) +@@ -6858,17 +6862,15 @@ static void brcmf_free_wiphy(struct wiph + if (wiphy->wowlan != &brcmf_wowlan_support) + kfree(wiphy->wowlan); + #endif +- wiphy_free(wiphy); + } + + struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, +- struct device *busdev, ++ struct cfg80211_ops *ops, + bool p2pdev_forced) + { ++ struct wiphy *wiphy = drvr->wiphy; + struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; + struct brcmf_cfg80211_info *cfg; +- struct wiphy *wiphy; +- struct cfg80211_ops *ops; + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; + s32 err = 0; +@@ -6880,26 +6882,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + return NULL; + } + +- ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL); +- if (!ops) +- return NULL; +- +- ifp = netdev_priv(ndev); +-#ifdef CONFIG_PM +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) +- ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; +-#endif +- wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info)); +- if (!wiphy) { ++ cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); ++ if (!cfg) { + brcmf_err("Could not allocate wiphy device\n"); +- goto ops_out; ++ return NULL; + } +- memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN); +- set_wiphy_dev(wiphy, busdev); + +- cfg = wiphy_priv(wiphy); + cfg->wiphy = wiphy; +- cfg->ops = ops; + cfg->pub = drvr; + init_vif_event(&cfg->vif_event); + INIT_LIST_HEAD(&cfg->vif_list); +@@ -6908,6 +6897,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + if (IS_ERR(vif)) + goto wiphy_out; + ++ ifp = netdev_priv(ndev); + vif->ifp = ifp; + vif->wdev.netdev = ndev; + ndev->ieee80211_ptr = &vif->wdev; +@@ -6934,6 +6924,11 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + if (err < 0) + goto priv_out; + ++ /* regulatory notifer below needs access to cfg so ++ * assign it now. ++ */ ++ drvr->config = cfg; ++ + brcmf_dbg(INFO, "Registering custom regulatory\n"); + wiphy->reg_notifier = brcmf_cfg80211_reg_notifier; + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; +@@ -6947,13 +6942,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap; + *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } ++#ifdef CONFIG_PM ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) ++ ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; ++#endif + err = wiphy_register(wiphy); + if (err < 0) { + brcmf_err("Could not register wiphy device (%d)\n", err); + goto priv_out; + } + +- err = brcmf_setup_wiphybands(wiphy); ++ err = brcmf_setup_wiphybands(cfg); + if (err) { + brcmf_err("Setting wiphy bands failed (%d)\n", err); + goto wiphy_unreg_out; +@@ -6970,12 +6969,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + else + *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + } +- /* p2p might require that "if-events" get processed by fweh. So +- * activate the already registered event handlers now and activate +- * the rest when initialization has completed. drvr->config needs to +- * be assigned before activating events. +- */ +- drvr->config = cfg; ++ + err = brcmf_fweh_activate_events(ifp); + if (err) { + brcmf_err("FWEH activation failed (%d)\n", err); +@@ -7043,8 +7037,7 @@ priv_out: + ifp->vif = NULL; + wiphy_out: + brcmf_free_wiphy(wiphy); +-ops_out: +- kfree(ops); ++ kfree(cfg); + return NULL; + } + +@@ -7059,4 +7052,5 @@ void brcmf_cfg80211_detach(struct brcmf_ + 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 +@@ -355,20 +355,24 @@ static inline struct wiphy *cfg_to_wiphy + + static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w) + { +- return (struct brcmf_cfg80211_info *)(wiphy_priv(w)); ++ struct brcmf_pub *drvr = wiphy_priv(w); ++ return drvr->config; + } + + static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd) + { +- return (struct brcmf_cfg80211_info *)(wdev_priv(wd)); ++ return wiphy_to_cfg(wd->wiphy); ++} ++ ++static inline struct brcmf_cfg80211_vif *wdev_to_vif(struct wireless_dev *wdev) ++{ ++ return container_of(wdev, struct brcmf_cfg80211_vif, wdev); + } + + static inline + struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg) + { +- struct brcmf_cfg80211_vif *vif; +- vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list); +- return vif->wdev.netdev; ++ return brcmf_get_ifp(cfg->pub, 0)->ndev; + } + + static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev) +@@ -395,11 +399,12 @@ brcmf_cfg80211_connect_info *cfg_to_conn + } + + struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, +- struct device *busdev, ++ struct cfg80211_ops *ops, + bool p2pdev_forced); + 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); + 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/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -252,6 +252,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + brcmf_err("Retreiving cur_etheraddr failed, %d\n", err); + goto done; + } ++ memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); + memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); + + bus = ifp->drvr->bus_if; +@@ -279,6 +280,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + ri->chippkg = le32_to_cpu(revinfo.chippkg); + ri->nvramrev = le32_to_cpu(revinfo.nvramrev); + ++ /* use revinfo if not known yet */ + if (!bus->chip) { + bus->chip = le32_to_cpu(revinfo.chipnum); + bus->chiprev = le32_to_cpu(revinfo.chiprev); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1021,7 +1021,7 @@ static int brcmf_revinfo_read(struct seq + return 0; + } + +-static int brcmf_bus_started(struct brcmf_pub *drvr) ++static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) + { + int ret = -1; + struct brcmf_bus *bus_if = drvr->bus_if; +@@ -1060,7 +1060,7 @@ static int brcmf_bus_started(struct brcm + + brcmf_proto_add_if(drvr, ifp); + +- drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev, ++ drvr->config = brcmf_cfg80211_attach(drvr, ops, + drvr->settings->p2p_enable); + if (drvr->config == NULL) { + ret = -ENOMEM; +@@ -1115,17 +1115,26 @@ fail: + + int brcmf_attach(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"); + +- /* Allocate primary brcmf_info */ +- drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC); +- if (!drvr) ++ ops = brcmf_cfg80211_get_ops(); ++ if (!ops) + return -ENOMEM; + ++ wiphy = wiphy_new(ops, sizeof(*drvr)); ++ if (!wiphy) ++ return -ENOMEM; ++ ++ set_wiphy_dev(wiphy, dev); ++ drvr = wiphy_priv(wiphy); ++ drvr->wiphy = wiphy; ++ + for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) + drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; + +@@ -1154,15 +1163,18 @@ int brcmf_attach(struct device *dev, str + /* attach firmware event handler */ + brcmf_fweh_attach(drvr); + +- ret = brcmf_bus_started(drvr); ++ ret = brcmf_bus_started(drvr, ops); + if (ret != 0) { + brcmf_err("dongle is not responding: err=%d\n", ret); + goto fail; + } ++ ++ drvr->config->ops = ops; + return 0; + + fail: + brcmf_detach(dev); ++ kfree(ops); + + return ret; + } +@@ -1220,6 +1232,7 @@ void brcmf_detach(struct device *dev) + brcmf_remove_interface(drvr->iflist[i], false); + + brcmf_cfg80211_detach(drvr->config); ++ drvr->config = NULL; + + brcmf_bus_stop(drvr->bus_if); + +@@ -1227,7 +1240,7 @@ void brcmf_detach(struct device *dev) + + brcmf_debug_detach(drvr); + bus_if->drvr = NULL; +- kfree(drvr); ++ wiphy_free(drvr->wiphy); + } + + s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -107,6 +107,7 @@ struct brcmf_pub { + /* Linkage ponters */ + struct brcmf_bus *bus_if; + struct brcmf_proto *proto; ++ struct wiphy *wiphy; + struct brcmf_cfg80211_info *config; + + /* Internal brcmf items */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2229,7 +2229,7 @@ fail: + */ + int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) + { +- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_p2p_info *p2p = &cfg->p2p; + struct brcmf_cfg80211_vif *vif; + enum nl80211_iftype iftype; diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0005-brcmfmac-use-wiphy-debugfs-dir-entry.patch b/root/package/kernel/mac80211/patches/327-v4.17-0005-brcmfmac-use-wiphy-debugfs-dir-entry.patch new file mode 100644 index 00000000..c5485c39 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0005-brcmfmac-use-wiphy-debugfs-dir-entry.patch @@ -0,0 +1,349 @@ +From 34789d0cf682c643862792750a06c31ccf016cbc Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:24 +0100 +Subject: [PATCH] brcmfmac: use wiphy debugfs dir entry + +The driver used to create a brcmfmac dir entry at the top level +debugfs mount point. This moves the debugfs entries into the +wiphy debugfs dir entry. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 6 ++++ + .../wireless/broadcom/brcm80211/brcmfmac/common.c | 5 --- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 11 +++--- + .../wireless/broadcom/brcm80211/brcmfmac/debug.c | 42 ++-------------------- + .../wireless/broadcom/brcm80211/brcmfmac/debug.h | 17 --------- + .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 3 ++ + .../wireless/broadcom/brcm80211/brcmfmac/feature.h | 7 ++++ + .../broadcom/brcm80211/brcmfmac/fwsignal.c | 11 +++--- + .../broadcom/brcm80211/brcmfmac/fwsignal.h | 1 + + .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 8 +++-- + .../wireless/broadcom/brcm80211/brcmfmac/proto.c | 3 +- + .../wireless/broadcom/brcm80211/brcmfmac/proto.h | 7 ++++ + 12 files changed, 47 insertions(+), 74 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -445,6 +445,11 @@ brcmf_proto_bcdc_init_done(struct brcmf_ + return 0; + } + ++static void brcmf_proto_bcdc_debugfs_create(struct brcmf_pub *drvr) ++{ ++ brcmf_fws_debugfs_create(drvr); ++} ++ + int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) + { + struct brcmf_bcdc *bcdc; +@@ -472,6 +477,7 @@ int brcmf_proto_bcdc_attach(struct brcmf + drvr->proto->del_if = brcmf_proto_bcdc_del_if; + drvr->proto->reset_if = brcmf_proto_bcdc_reset_if; + drvr->proto->init_done = brcmf_proto_bcdc_init_done; ++ drvr->proto->debugfs_create = brcmf_proto_bcdc_debugfs_create; + drvr->proto->pd = bcdc; + + drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -529,9 +529,6 @@ static int __init brcmfmac_module_init(v + { + int err; + +- /* Initialize debug system first */ +- brcmf_debugfs_init(); +- + /* Get the platform data (if available) for our devices */ + err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe); + if (err == -ENODEV) +@@ -543,7 +540,6 @@ static int __init brcmfmac_module_init(v + /* Continue the initialization by registering the different busses */ + err = brcmf_core_init(); + if (err) { +- brcmf_debugfs_exit(); + if (brcmfmac_pdata) + platform_driver_unregister(&brcmf_pd); + } +@@ -556,7 +552,6 @@ static void __exit brcmfmac_module_exit( + brcmf_core_exit(); + if (brcmfmac_pdata) + platform_driver_unregister(&brcmf_pd); +- brcmf_debugfs_exit(); + } + + module_init(brcmfmac_module_init); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1050,8 +1050,6 @@ static int brcmf_bus_started(struct brcm + if (ret < 0) + goto fail; + +- brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); +- + brcmf_feat_attach(drvr); + + ret = brcmf_proto_init_done(drvr); +@@ -1094,6 +1092,11 @@ static int brcmf_bus_started(struct brcm + #endif + #endif /* CONFIG_INET */ + ++ /* populate debugfs */ ++ brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); ++ brcmf_feat_debugfs_create(drvr); ++ brcmf_proto_debugfs_create(drvr); ++ + return 0; + + fail: +@@ -1146,9 +1149,6 @@ int brcmf_attach(struct device *dev, str + drvr->bus_if->drvr = drvr; + drvr->settings = settings; + +- /* attach debug facilities */ +- brcmf_debug_attach(drvr); +- + /* Attach and link in the protocol */ + ret = brcmf_proto_attach(drvr); + if (ret != 0) { +@@ -1238,7 +1238,6 @@ void brcmf_detach(struct device *dev) + + brcmf_proto_detach(drvr); + +- brcmf_debug_detach(drvr); + bus_if->drvr = NULL; + wiphy_free(drvr->wiphy); + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c +@@ -25,8 +25,6 @@ + #include "fweh.h" + #include "debug.h" + +-static struct dentry *root_folder; +- + int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, + size_t len) + { +@@ -54,44 +52,9 @@ int brcmf_debug_create_memdump(struct br + return 0; + } + +-void brcmf_debugfs_init(void) +-{ +- root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); +- if (IS_ERR(root_folder)) +- root_folder = NULL; +-} +- +-void brcmf_debugfs_exit(void) +-{ +- if (!root_folder) +- return; +- +- debugfs_remove_recursive(root_folder); +- root_folder = NULL; +-} +- +-int brcmf_debug_attach(struct brcmf_pub *drvr) +-{ +- struct device *dev = drvr->bus_if->dev; +- +- if (!root_folder) +- return -ENODEV; +- +- drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); +- return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); +-} +- +-void brcmf_debug_detach(struct brcmf_pub *drvr) +-{ +- brcmf_fweh_unregister(drvr, BRCMF_E_PSM_WATCHDOG); +- +- if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) +- debugfs_remove_recursive(drvr->dbgfs_dir); +-} +- + struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) + { +- return drvr->dbgfs_dir; ++ return drvr->wiphy->debugfsdir; + } + + int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, +@@ -99,7 +62,8 @@ int brcmf_debugfs_add_entry(struct brcmf + { + struct dentry *e; + ++ WARN(!drvr->wiphy->debugfsdir, "wiphy not (yet) registered\n"); + e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, +- drvr->dbgfs_dir, read_fn); ++ drvr->wiphy->debugfsdir, read_fn); + return PTR_ERR_OR_ZERO(e); + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h +@@ -113,29 +113,12 @@ extern int brcmf_msg_level; + struct brcmf_bus; + struct brcmf_pub; + #ifdef DEBUG +-void brcmf_debugfs_init(void); +-void brcmf_debugfs_exit(void); +-int brcmf_debug_attach(struct brcmf_pub *drvr); +-void brcmf_debug_detach(struct brcmf_pub *drvr); + struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); + int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)); + int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, + size_t len); + #else +-static inline void brcmf_debugfs_init(void) +-{ +-} +-static inline void brcmf_debugfs_exit(void) +-{ +-} +-static inline int brcmf_debug_attach(struct brcmf_pub *drvr) +-{ +- return 0; +-} +-static inline void brcmf_debug_detach(struct brcmf_pub *drvr) +-{ +-} + static inline + int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -228,7 +228,10 @@ void brcmf_feat_attach(struct brcmf_pub + /* no quirks */ + break; + } ++} + ++void brcmf_feat_debugfs_create(struct brcmf_pub *drvr) ++{ + brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read); + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -90,6 +90,13 @@ enum brcmf_feat_quirk { + void brcmf_feat_attach(struct brcmf_pub *drvr); + + /** ++ * brcmf_feat_debugfs_create() - create debugfs entries. ++ * ++ * @drvr: driver instance. ++ */ ++void brcmf_feat_debugfs_create(struct brcmf_pub *drvr); ++ ++/** + * brcmf_feat_is_enabled() - query feature. + * + * @ifp: interface instance. +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -2399,10 +2399,6 @@ struct brcmf_fws_info *brcmf_fws_attach( + brcmu_pktq_init(&fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT, + BRCMF_FWS_PSQ_LEN); + +- /* create debugfs file for statistics */ +- brcmf_debugfs_add_entry(drvr, "fws_stats", +- brcmf_debugfs_fws_stats_read); +- + brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", + fws->fw_signals ? "enabled" : "disabled", tlv); + return fws; +@@ -2429,6 +2425,13 @@ void brcmf_fws_detach(struct brcmf_fws_i + kfree(fws); + } + ++void brcmf_fws_debugfs_create(struct brcmf_pub *drvr) ++{ ++ /* create debugfs file for statistics */ ++ brcmf_debugfs_add_entry(drvr, "fws_stats", ++ brcmf_debugfs_fws_stats_read); ++} ++ + bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws) + { + return !fws->avoid_queueing; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h +@@ -20,6 +20,7 @@ + + struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); + 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); + void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -1418,6 +1418,11 @@ static int brcmf_msgbuf_stats_read(struc + } + #endif + ++static void brcmf_msgbuf_debugfs_create(struct brcmf_pub *drvr) ++{ ++ brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read); ++} ++ + int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) + { + struct brcmf_bus_msgbuf *if_msgbuf; +@@ -1472,6 +1477,7 @@ int brcmf_proto_msgbuf_attach(struct brc + drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; + drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer; + drvr->proto->rxreorder = brcmf_msgbuf_rxreorder; ++ drvr->proto->debugfs_create = brcmf_msgbuf_debugfs_create; + drvr->proto->pd = msgbuf; + + init_waitqueue_head(&msgbuf->ioctl_resp_wait); +@@ -1525,8 +1531,6 @@ int brcmf_proto_msgbuf_attach(struct brc + spin_lock_init(&msgbuf->flowring_work_lock); + INIT_LIST_HEAD(&msgbuf->work_queue); + +- brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read); +- + return 0; + + fail: +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c +@@ -54,7 +54,8 @@ int brcmf_proto_attach(struct brcmf_pub + if (!proto->tx_queue_data || (proto->hdrpull == NULL) || + (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) || + (proto->configure_addr_mode == NULL) || +- (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL)) { ++ (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) || ++ (proto->debugfs_create == NULL)) { + brcmf_err("Not all proto handlers have been installed\n"); + goto fail; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h +@@ -48,6 +48,7 @@ struct brcmf_proto { + void (*del_if)(struct brcmf_if *ifp); + void (*reset_if)(struct brcmf_if *ifp); + int (*init_done)(struct brcmf_pub *drvr); ++ void (*debugfs_create)(struct brcmf_pub *drvr); + void *pd; + }; + +@@ -156,4 +157,10 @@ brcmf_proto_init_done(struct brcmf_pub * + return drvr->proto->init_done(drvr); + } + ++static inline void ++brcmf_proto_debugfs_create(struct brcmf_pub *drvr) ++{ ++ drvr->proto->debugfs_create(drvr); ++} ++ + #endif /* BRCMFMAC_PROTO_H */ diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0006-brcmfmac-derive-firmware-filenames-from-basename-map.patch b/root/package/kernel/mac80211/patches/327-v4.17-0006-brcmfmac-derive-firmware-filenames-from-basename-map.patch new file mode 100644 index 00000000..0b1ae56b --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0006-brcmfmac-derive-firmware-filenames-from-basename-map.patch @@ -0,0 +1,286 @@ +From 41f573dbb534f14e62a4a5411f602c970cad1d77 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:25 +0100 +Subject: [PATCH] brcmfmac: derive firmware filenames from basename mapping + +Instead of defining individual filenames for firmware and nvram +use a basename and derive the names from that. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 31 ++++++--- + .../broadcom/brcm80211/brcmfmac/firmware.h | 24 ++----- + .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 56 ++++++++--------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 73 +++++++++++----------- + .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 10 +-- + 5 files changed, 96 insertions(+), 98 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -563,6 +563,13 @@ int brcmf_fw_get_firmwares(struct device + 0); + } + ++static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN], ++ const char *fw_base, const char *extension) ++{ ++ strlcat(fw_name, fw_base, BRCMF_FW_NAME_LEN); ++ strlcat(fw_name, extension, BRCMF_FW_NAME_LEN); ++} ++ + int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, + struct brcmf_firmware_mapping mapping_table[], + u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], +@@ -587,25 +594,31 @@ int brcmf_fw_map_chip_to_name(u32 chip, + + /* check if firmware path is provided by module parameter */ + if (brcmf_mp_global.firmware_path[0] != '\0') { +- strlcpy(fw_name, brcmf_mp_global.firmware_path, +- BRCMF_FW_NAME_LEN); +- if ((nvram_name) && (mapping_table[i].nvram)) ++ if (fw_name) ++ strlcpy(fw_name, brcmf_mp_global.firmware_path, ++ BRCMF_FW_NAME_LEN); ++ if (nvram_name) + strlcpy(nvram_name, brcmf_mp_global.firmware_path, + BRCMF_FW_NAME_LEN); + + end = brcmf_mp_global.firmware_path[ + strlen(brcmf_mp_global.firmware_path) - 1]; + if (end != '/') { +- strlcat(fw_name, "/", BRCMF_FW_NAME_LEN); +- if ((nvram_name) && (mapping_table[i].nvram)) ++ if (fw_name) ++ strlcat(fw_name, "/", BRCMF_FW_NAME_LEN); ++ if (nvram_name) + strlcat(nvram_name, "/", BRCMF_FW_NAME_LEN); + } + } +- strlcat(fw_name, mapping_table[i].fw, BRCMF_FW_NAME_LEN); +- if ((nvram_name) && (mapping_table[i].nvram)) +- strlcat(nvram_name, mapping_table[i].nvram, BRCMF_FW_NAME_LEN); + +- brcmf_info("using %s for chip %s\n", fw_name, chipname); ++ brcmf_info("using %s for chip %s\n", ++ mapping_table[i].fw_base, chipname); ++ if (fw_name) ++ brcmf_fw_get_full_name(fw_name, ++ mapping_table[i].fw_base, ".bin"); ++ if (nvram_name) ++ brcmf_fw_get_full_name(nvram_name, ++ mapping_table[i].fw_base, ".txt"); + + return 0; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +@@ -38,28 +38,16 @@ + struct brcmf_firmware_mapping { + u32 chipid; + u32 revmask; +- const char *fw; +- const char *nvram; ++ const char *fw_base; + }; + +-#define BRCMF_FW_NVRAM_DEF(fw_nvram_name, fw, nvram) \ +-static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \ +- BRCMF_FW_DEFAULT_PATH fw; \ +-static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \ +- BRCMF_FW_DEFAULT_PATH nvram; \ +-MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); +- +-#define BRCMF_FW_DEF(fw_name, fw) \ +-static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \ +- BRCMF_FW_DEFAULT_PATH fw; \ +-MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw) \ +- +-#define BRCMF_FW_NVRAM_ENTRY(chipid, mask, name) \ +- { chipid, mask, \ +- BRCM_ ## name ## _FIRMWARE_NAME, BRCM_ ## name ## _NVRAM_NAME } ++#define BRCMF_FW_DEF(fw_name, fw_base) \ ++static const char BRCM_ ## fw_name ## _FIRMWARE_BASENAME[] = \ ++ BRCMF_FW_DEFAULT_PATH fw_base; \ ++MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw_base ".bin") + + #define BRCMF_FW_ENTRY(chipid, mask, name) \ +- { chipid, mask, BRCM_ ## name ## _FIRMWARE_NAME, NULL } ++ { chipid, mask, BRCM_ ## name ## _FIRMWARE_BASENAME } + + int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, + struct brcmf_firmware_mapping mapping_table[], +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -46,36 +46,36 @@ enum brcmf_pcie_state { + BRCMFMAC_PCIE_STATE_UP + }; + +-BRCMF_FW_NVRAM_DEF(43602, "brcmfmac43602-pcie.bin", "brcmfmac43602-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4350, "brcmfmac4350-pcie.bin", "brcmfmac4350-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4350C, "brcmfmac4350c2-pcie.bin", "brcmfmac4350c2-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-pcie.bin", "brcmfmac4356-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4365C, "brcmfmac4365c-pcie.bin", "brcmfmac4365c-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt"); +-BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt"); ++BRCMF_FW_DEF(43602, "brcmfmac43602-pcie"); ++BRCMF_FW_DEF(4350, "brcmfmac4350-pcie"); ++BRCMF_FW_DEF(4350C, "brcmfmac4350c2-pcie"); ++BRCMF_FW_DEF(4356, "brcmfmac4356-pcie"); ++BRCMF_FW_DEF(43570, "brcmfmac43570-pcie"); ++BRCMF_FW_DEF(4358, "brcmfmac4358-pcie"); ++BRCMF_FW_DEF(4359, "brcmfmac4359-pcie"); ++BRCMF_FW_DEF(4365B, "brcmfmac4365b-pcie"); ++BRCMF_FW_DEF(4365C, "brcmfmac4365c-pcie"); ++BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie"); ++BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); ++BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); + + static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), ++ BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), ++ BRCMF_FW_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), ++ BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), ++ BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350), ++ BRCMF_FW_ENTRY(BRCM_CC_43525_CHIP_ID, 0xFFFFFFF0, 4365C), ++ BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), ++ BRCMF_FW_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570), ++ BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), ++ BRCMF_FW_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), ++ BRCMF_FW_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), ++ BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), ++ BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), ++ BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), ++ BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), ++ BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), ++ BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), + }; + + #define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -600,47 +600,44 @@ static const struct sdiod_drive_str sdio + {4, 0x1} + }; + +-BRCMF_FW_NVRAM_DEF(43143, "brcmfmac43143-sdio.bin", "brcmfmac43143-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(43241B0, "brcmfmac43241b0-sdio.bin", +- "brcmfmac43241b0-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(43241B4, "brcmfmac43241b4-sdio.bin", +- "brcmfmac43241b4-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(43241B5, "brcmfmac43241b5-sdio.bin", +- "brcmfmac43241b5-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(43430A0, "brcmfmac43430a0-sdio.bin", "brcmfmac43430a0-sdio.txt"); ++BRCMF_FW_DEF(43143, "brcmfmac43143-sdio"); ++BRCMF_FW_DEF(43241B0, "brcmfmac43241b0-sdio"); ++BRCMF_FW_DEF(43241B4, "brcmfmac43241b4-sdio"); ++BRCMF_FW_DEF(43241B5, "brcmfmac43241b5-sdio"); ++BRCMF_FW_DEF(4329, "brcmfmac4329-sdio"); ++BRCMF_FW_DEF(4330, "brcmfmac4330-sdio"); ++BRCMF_FW_DEF(4334, "brcmfmac4334-sdio"); ++BRCMF_FW_DEF(43340, "brcmfmac43340-sdio"); ++BRCMF_FW_DEF(4335, "brcmfmac4335-sdio"); ++BRCMF_FW_DEF(43362, "brcmfmac43362-sdio"); ++BRCMF_FW_DEF(4339, "brcmfmac4339-sdio"); ++BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio"); + /* Note the names are not postfixed with a1 for backward compatibility */ +-BRCMF_FW_NVRAM_DEF(43430A1, "brcmfmac43430-sdio.bin", "brcmfmac43430-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(43455, "brcmfmac43455-sdio.bin", "brcmfmac43455-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-sdio.bin", "brcmfmac4356-sdio.txt"); +-BRCMF_FW_NVRAM_DEF(4373, "brcmfmac4373-sdio.bin", "brcmfmac4373-sdio.txt"); ++BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio"); ++BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"); ++BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); ++BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); ++BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); + + static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, 43241B5), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, 4329), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), +- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), +- BRCMF_FW_NVRAM_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373) ++ BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), ++ BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), ++ BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), ++ BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, 43241B5), ++ BRCMF_FW_ENTRY(BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, 4329), ++ BRCMF_FW_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330), ++ BRCMF_FW_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334), ++ BRCMF_FW_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340), ++ BRCMF_FW_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340), ++ BRCMF_FW_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335), ++ BRCMF_FW_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362), ++ 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_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) + }; + + static void pkt_align(struct sk_buff *p, int len, int align) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -46,11 +46,11 @@ + #define BRCMF_USB_CBCTL_READ 1 + #define BRCMF_USB_MAX_PKT_SIZE 1600 + +-BRCMF_FW_DEF(43143, "brcmfmac43143.bin"); +-BRCMF_FW_DEF(43236B, "brcmfmac43236b.bin"); +-BRCMF_FW_DEF(43242A, "brcmfmac43242a.bin"); +-BRCMF_FW_DEF(43569, "brcmfmac43569.bin"); +-BRCMF_FW_DEF(4373, "brcmfmac4373.bin"); ++BRCMF_FW_DEF(43143, "brcmfmac43143"); ++BRCMF_FW_DEF(43236B, "brcmfmac43236b"); ++BRCMF_FW_DEF(43242A, "brcmfmac43242a"); ++BRCMF_FW_DEF(43569, "brcmfmac43569"); ++BRCMF_FW_DEF(4373, "brcmfmac4373"); + + static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0007-brcmfmac-pass-struct-in-brcmf_fw_get_firmwares.patch b/root/package/kernel/mac80211/patches/327-v4.17-0007-brcmfmac-pass-struct-in-brcmf_fw_get_firmwares.patch new file mode 100644 index 00000000..a75465a8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0007-brcmfmac-pass-struct-in-brcmf_fw_get_firmwares.patch @@ -0,0 +1,574 @@ +From d09ae51a4b676151edaf572bcd5f272b5532639f Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:26 +0100 +Subject: [PATCH] brcmfmac: pass struct in brcmf_fw_get_firmwares() + +Make the function brcmf_fw_get_firmwares() a bit more easy to extend +using a structure to pass the request parameters. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 175 ++++++++++++++------- + .../broadcom/brcm80211/brcmfmac/firmware.h | 43 +++-- + .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 38 ++++- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 32 +++- + .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 43 ++++- + 5 files changed, 245 insertions(+), 86 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -438,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram) + + struct brcmf_fw { + struct device *dev; +- u16 flags; +- const struct firmware *code; +- const char *nvram_name; +- u16 domain_nr; +- u16 bus_nr; +- void (*done)(struct device *dev, int err, const struct firmware *fw, +- void *nvram_image, u32 nvram_len); ++ struct brcmf_fw_request *req; ++ u32 curpos; ++ void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); + }; + ++static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); ++ ++static void brcmf_fw_free_request(struct brcmf_fw_request *req) ++{ ++ struct brcmf_fw_item *item; ++ int i; ++ ++ for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { ++ if (item->type == BRCMF_FW_TYPE_BINARY) ++ release_firmware(item->binary); ++ else if (item->type == BRCMF_FW_TYPE_NVRAM) ++ brcmf_fw_nvram_free(item->nv_data.data); ++ } ++ kfree(req); ++} ++ + static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) + { + struct brcmf_fw *fwctx = ctx; ++ struct brcmf_fw_item *cur; + u32 nvram_length = 0; + void *nvram = NULL; + u8 *data = NULL; +@@ -457,83 +470,150 @@ static void brcmf_fw_request_nvram_done( + bool raw_nvram; + + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); ++ ++ cur = &fwctx->req->items[fwctx->curpos]; ++ + if (fw && fw->data) { + data = (u8 *)fw->data; + data_len = fw->size; + raw_nvram = false; + } else { + data = bcm47xx_nvram_get_contents(&data_len); +- if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) ++ if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) + goto fail; + raw_nvram = true; + } + + if (data) + nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length, +- fwctx->domain_nr, fwctx->bus_nr); ++ fwctx->req->domain_nr, ++ fwctx->req->bus_nr); + + if (raw_nvram) + bcm47xx_nvram_release_contents(data); + release_firmware(fw); +- if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) ++ if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) + goto fail; + +- fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length); +- kfree(fwctx); ++ brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); ++ cur->nv_data.data = nvram; ++ cur->nv_data.len = nvram_length; + return; + + fail: + brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); +- release_firmware(fwctx->code); +- fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0); ++ fwctx->done(fwctx->dev, -ENOENT, NULL); ++ brcmf_fw_free_request(fwctx->req); + kfree(fwctx); + } + +-static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx) ++static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) ++{ ++ struct brcmf_fw_item *cur; ++ const struct firmware *fw = NULL; ++ int ret; ++ ++ cur = &fwctx->req->items[fwctx->curpos]; ++ ++ brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "", ++ cur->path); ++ ++ if (async) ++ ret = request_firmware_nowait(THIS_MODULE, true, cur->path, ++ fwctx->dev, GFP_KERNEL, fwctx, ++ brcmf_fw_request_done); ++ else ++ ret = request_firmware(&fw, cur->path, fwctx->dev); ++ ++ if (ret < 0) { ++ brcmf_fw_request_done(NULL, fwctx); ++ } else if (!async && fw) { ++ brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path, ++ fw ? "" : "not "); ++ if (cur->type == BRCMF_FW_TYPE_BINARY) ++ cur->binary = fw; ++ else if (cur->type == BRCMF_FW_TYPE_NVRAM) ++ brcmf_fw_request_nvram_done(fw, fwctx); ++ else ++ release_firmware(fw); ++ ++ return -EAGAIN; ++ } ++ return 0; ++} ++ ++static void brcmf_fw_request_done(const struct firmware *fw, void *ctx) + { + struct brcmf_fw *fwctx = ctx; ++ struct brcmf_fw_item *cur; + int ret = 0; + +- brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev)); +- if (!fw) { ++ cur = &fwctx->req->items[fwctx->curpos]; ++ ++ brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, ++ fw ? "" : "not "); ++ ++ if (fw) { ++ if (cur->type == BRCMF_FW_TYPE_BINARY) ++ cur->binary = fw; ++ else if (cur->type == BRCMF_FW_TYPE_NVRAM) ++ brcmf_fw_request_nvram_done(fw, fwctx); ++ else ++ release_firmware(fw); ++ } else if (cur->type == BRCMF_FW_TYPE_NVRAM) { ++ brcmf_fw_request_nvram_done(NULL, fwctx); ++ } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) { + ret = -ENOENT; + goto fail; + } +- /* only requested code so done here */ +- if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) +- goto done; +- +- fwctx->code = fw; +- ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name, +- fwctx->dev, GFP_KERNEL, fwctx, +- brcmf_fw_request_nvram_done); + +- /* pass NULL to nvram callback for bcm47xx fallback */ +- if (ret) +- brcmf_fw_request_nvram_done(NULL, fwctx); ++ do { ++ if (++fwctx->curpos == fwctx->req->n_items) { ++ ret = 0; ++ goto done; ++ } ++ ++ ret = brcmf_fw_request_next_item(fwctx, false); ++ } while (ret == -EAGAIN); ++ + return; + + fail: +- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); ++ brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret, ++ dev_name(fwctx->dev), cur->path); ++ brcmf_fw_free_request(fwctx->req); ++ fwctx->req = NULL; + done: +- fwctx->done(fwctx->dev, ret, fw, NULL, 0); ++ fwctx->done(fwctx->dev, ret, fwctx->req); + kfree(fwctx); + } + +-int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, +- const char *code, const char *nvram, +- void (*fw_cb)(struct device *dev, int err, +- const struct firmware *fw, +- void *nvram_image, u32 nvram_len), +- u16 domain_nr, u16 bus_nr) ++static bool brcmf_fw_request_is_valid(struct brcmf_fw_request *req) ++{ ++ struct brcmf_fw_item *item; ++ int i; ++ ++ if (!req->n_items) ++ return false; ++ ++ for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { ++ if (!item->path) ++ return false; ++ } ++ return true; ++} ++ ++int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req, ++ void (*fw_cb)(struct device *dev, int err, ++ struct brcmf_fw_request *req)) + { + struct brcmf_fw *fwctx; + + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); +- if (!fw_cb || !code) ++ if (!fw_cb) + return -EINVAL; + +- if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram) ++ if (!brcmf_fw_request_is_valid(req)) + return -EINVAL; + + fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL); +@@ -541,26 +621,11 @@ int brcmf_fw_get_firmwares_pcie(struct d + return -ENOMEM; + + fwctx->dev = dev; +- fwctx->flags = flags; ++ fwctx->req = req; + fwctx->done = fw_cb; +- if (flags & BRCMF_FW_REQUEST_NVRAM) +- fwctx->nvram_name = nvram; +- fwctx->domain_nr = domain_nr; +- fwctx->bus_nr = bus_nr; +- +- return request_firmware_nowait(THIS_MODULE, true, code, dev, +- GFP_KERNEL, fwctx, +- brcmf_fw_request_code_done); +-} + +-int brcmf_fw_get_firmwares(struct device *dev, u16 flags, +- const char *code, const char *nvram, +- void (*fw_cb)(struct device *dev, int err, +- const struct firmware *fw, +- void *nvram_image, u32 nvram_len)) +-{ +- return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, +- 0); ++ brcmf_fw_request_next_item(fwctx, true); ++ return 0; + } + + static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN], +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +@@ -16,10 +16,7 @@ + #ifndef BRCMFMAC_FIRMWARE_H + #define BRCMFMAC_FIRMWARE_H + +-#define BRCMF_FW_REQUEST 0x000F +-#define BRCMF_FW_REQUEST_NVRAM 0x0001 +-#define BRCMF_FW_REQ_FLAGS 0x00F0 +-#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010 ++#define BRCMF_FW_REQF_OPTIONAL 0x0001 + + #define BRCMF_FW_NAME_LEN 320 + +@@ -54,21 +51,39 @@ int brcmf_fw_map_chip_to_name(u32 chip, + u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], + char nvram_name[BRCMF_FW_NAME_LEN]); + void brcmf_fw_nvram_free(void *nvram); ++ ++enum brcmf_fw_type { ++ BRCMF_FW_TYPE_BINARY, ++ BRCMF_FW_TYPE_NVRAM ++}; ++ ++struct brcmf_fw_item { ++ const char *path; ++ enum brcmf_fw_type type; ++ u16 flags; ++ union { ++ const struct firmware *binary; ++ struct { ++ void *data; ++ u32 len; ++ } nv_data; ++ }; ++}; ++ ++struct brcmf_fw_request { ++ u16 domain_nr; ++ u16 bus_nr; ++ u32 n_items; ++ struct brcmf_fw_item items[0]; ++}; ++ + /* + * Request firmware(s) asynchronously. When the asynchronous request + * fails it will not use the callback, but call device_release_driver() + * instead which will call the driver .remove() callback. + */ +-int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags, +- const char *code, const char *nvram, +- void (*fw_cb)(struct device *dev, int err, +- const struct firmware *fw, +- void *nvram_image, u32 nvram_len), +- u16 domain_nr, u16 bus_nr); +-int brcmf_fw_get_firmwares(struct device *dev, u16 flags, +- const char *code, const char *nvram, ++int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req, + void (*fw_cb)(struct device *dev, int err, +- const struct firmware *fw, +- void *nvram_image, u32 nvram_len)); ++ struct brcmf_fw_request *req)); + + #endif /* BRCMFMAC_FIRMWARE_H */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1651,15 +1651,19 @@ static const struct brcmf_buscore_ops br + .write32 = brcmf_pcie_buscore_write32, + }; + ++#define BRCMF_PCIE_FW_CODE 0 ++#define BRCMF_PCIE_FW_NVRAM 1 ++ + static void brcmf_pcie_setup(struct device *dev, int ret, +- const struct firmware *fw, +- void *nvram, u32 nvram_len) ++ struct brcmf_fw_request *fwreq) + { ++ const struct firmware *fw; ++ void *nvram; + struct brcmf_bus *bus; + struct brcmf_pciedev *pcie_bus_dev; + struct brcmf_pciedev_info *devinfo; + struct brcmf_commonring **flowrings; +- u32 i; ++ u32 i, nvram_len; + + /* check firmware loading result */ + if (ret) +@@ -1670,6 +1674,11 @@ static void brcmf_pcie_setup(struct devi + devinfo = pcie_bus_dev->devinfo; + brcmf_pcie_attach(devinfo); + ++ fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary; ++ nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data; ++ nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; ++ kfree(fwreq); ++ + /* 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 +@@ -1730,6 +1739,7 @@ static int + brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { + int ret; ++ struct brcmf_fw_request *fwreq; + struct brcmf_pciedev_info *devinfo; + struct brcmf_pciedev *pcie_bus_dev; + struct brcmf_bus *bus; +@@ -1800,12 +1810,26 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + if (ret) + goto fail_bus; + +- ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM | +- BRCMF_FW_REQ_NV_OPTIONAL, +- devinfo->fw_name, devinfo->nvram_name, +- brcmf_pcie_setup, domain_nr, bus_nr); ++ fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item), ++ GFP_KERNEL); ++ if (!fwreq) { ++ ret = -ENOMEM; ++ goto fail_bus; ++ } ++ ++ fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name; ++ fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name; ++ fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; ++ fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; ++ fwreq->n_items = 2; ++ fwreq->domain_nr = domain_nr; ++ fwreq->bus_nr = bus_nr; ++ ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup); + if (ret == 0) + return 0; ++ ++ kfree(fwreq); + fail_bus: + kfree(bus->msgbuf); + kfree(bus); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4031,14 +4031,19 @@ static const struct brcmf_bus_ops brcmf_ + .get_fwname = brcmf_sdio_get_fwname, + }; + ++#define BRCMF_SDIO_FW_CODE 0 ++#define BRCMF_SDIO_FW_NVRAM 1 ++ + static void brcmf_sdio_firmware_callback(struct device *dev, int err, +- const struct firmware *code, +- void *nvram, u32 nvram_len) ++ struct brcmf_fw_request *fwreq) + { + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio; + struct brcmf_sdio *bus = sdiod->bus; + struct brcmf_core *core = bus->sdio_core; ++ const struct firmware *code; ++ void *nvram; ++ u32 nvram_len; + u8 saveclk; + + brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); +@@ -4046,6 +4051,11 @@ static void brcmf_sdio_firmware_callback + if (err) + goto fail; + ++ code = fwreq->items[BRCMF_SDIO_FW_CODE].binary; ++ nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data; ++ nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len; ++ kfree(fwreq); ++ + /* try to download image and nvram to the dongle */ + bus->alp_only = true; + err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); +@@ -4150,6 +4160,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + int ret; + struct brcmf_sdio *bus; + struct workqueue_struct *wq; ++ struct brcmf_fw_request *fwreq; + + brcmf_dbg(TRACE, "Enter\n"); + +@@ -4240,11 +4251,24 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + if (ret) + goto fail; + +- ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM, +- sdiodev->fw_name, sdiodev->nvram_name, ++ fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item), ++ GFP_KERNEL); ++ if (!fwreq) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++ fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name; ++ fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name; ++ fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; ++ fwreq->n_items = 2; ++ ++ ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq, + brcmf_sdio_firmware_callback); + if (ret != 0) { + brcmf_err("async firmware request failed: %d\n", ret); ++ kfree(fwreq); + goto fail; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1155,18 +1155,23 @@ static const struct brcmf_bus_ops brcmf_ + .get_fwname = brcmf_usb_get_fwname, + }; + ++#define BRCMF_USB_FW_CODE 0 ++ + static void brcmf_usb_probe_phase2(struct device *dev, int ret, +- const struct firmware *fw, +- void *nvram, u32 nvlen) ++ struct brcmf_fw_request *fwreq) + { + struct brcmf_bus *bus = dev_get_drvdata(dev); + struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo; ++ const struct firmware *fw; + + if (ret) + goto error; + + brcmf_dbg(USB, "Start fw downloading\n"); + ++ fw = fwreq->items[BRCMF_USB_FW_CODE].binary; ++ kfree(fwreq); ++ + ret = check_file(fw->data); + if (ret < 0) { + brcmf_err("invalid firmware\n"); +@@ -1200,6 +1205,7 @@ static int brcmf_usb_probe_cb(struct brc + struct brcmf_bus *bus = NULL; + struct brcmf_usbdev *bus_pub = NULL; + struct device *dev = devinfo->dev; ++ struct brcmf_fw_request *fwreq; + int ret; + + brcmf_dbg(USB, "Enter\n"); +@@ -1250,11 +1256,22 @@ static int brcmf_usb_probe_cb(struct brc + if (ret) + goto fail; + ++ fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), ++ GFP_KERNEL); ++ if (!fwreq) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++ fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; ++ fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ fwreq->n_items = 1; ++ + /* request firmware here */ +- ret = brcmf_fw_get_firmwares(dev, 0, devinfo->fw_name, NULL, +- brcmf_usb_probe_phase2); ++ ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2); + if (ret) { + brcmf_err("firmware request failed: %d\n", ret); ++ kfree(fwreq); + goto fail; + } + +@@ -1447,11 +1464,25 @@ static int brcmf_usb_reset_resume(struct + { + struct usb_device *usb = interface_to_usbdev(intf); + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); ++ struct brcmf_fw_request *fwreq; ++ int ret; + + brcmf_dbg(USB, "Enter\n"); + +- return brcmf_fw_get_firmwares(&usb->dev, 0, devinfo->fw_name, NULL, +- brcmf_usb_probe_phase2); ++ fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), ++ GFP_KERNEL); ++ if (!fwreq) ++ return -ENOMEM; ++ ++ fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; ++ fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ fwreq->n_items = 1; ++ ++ ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2); ++ if (ret < 0) ++ kfree(fwreq); ++ ++ return ret; + } + + #define BRCMF_USB_DEVICE(dev_id) \ diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0008-brcmfmac-introduce-brcmf_fw_alloc_request-function.patch b/root/package/kernel/mac80211/patches/327-v4.17-0008-brcmfmac-introduce-brcmf_fw_alloc_request-function.patch new file mode 100644 index 00000000..408154ef --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0008-brcmfmac-introduce-brcmf_fw_alloc_request-function.patch @@ -0,0 +1,328 @@ +From 2baa3aaee27f137b8db9a9224d0fe9b281d28e34 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:27 +0100 +Subject: [PATCH] brcmfmac: introduce brcmf_fw_alloc_request() function + +The function brcmf_fw_alloc_request() takes a list of required files +and allocated the struct brcmf_fw_request instance accordingly. The +request can be modified by the caller before being passed to the +brcmf_fw_request_firmwares() function. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 58 ++++++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/firmware.h | 11 ++++ + .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 58 ++++++++++++---------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 38 ++++++++------ + .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 42 +++++++++------- + 5 files changed, 147 insertions(+), 60 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -688,3 +688,61 @@ int brcmf_fw_map_chip_to_name(u32 chip, + return 0; + } + ++struct brcmf_fw_request * ++brcmf_fw_alloc_request(u32 chip, u32 chiprev, ++ struct brcmf_firmware_mapping mapping_table[], ++ u32 table_size, struct brcmf_fw_name *fwnames, ++ u32 n_fwnames) ++{ ++ struct brcmf_fw_request *fwreq; ++ char chipname[12]; ++ const char *mp_path; ++ u32 i, j; ++ char end; ++ size_t reqsz; ++ ++ for (i = 0; i < table_size; i++) { ++ if (mapping_table[i].chipid == chip && ++ mapping_table[i].revmask & BIT(chiprev)) ++ break; ++ } ++ ++ if (i == table_size) { ++ brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); ++ return NULL; ++ } ++ ++ reqsz = sizeof(*fwreq) + n_fwnames * sizeof(struct brcmf_fw_item); ++ fwreq = kzalloc(reqsz, GFP_KERNEL); ++ if (!fwreq) ++ return NULL; ++ ++ brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); ++ ++ brcmf_info("using %s for chip %s\n", ++ mapping_table[i].fw_base, chipname); ++ ++ mp_path = brcmf_mp_global.firmware_path; ++ end = mp_path[strlen(mp_path) - 1]; ++ fwreq->n_items = n_fwnames; ++ ++ for (j = 0; j < n_fwnames; j++) { ++ fwreq->items[j].path = fwnames[j].path; ++ /* check if firmware path is provided by module parameter */ ++ if (brcmf_mp_global.firmware_path[0] != '\0') { ++ strlcpy(fwnames[j].path, mp_path, ++ BRCMF_FW_NAME_LEN); ++ ++ if (end != '/') { ++ strlcat(fwnames[j].path, "/", ++ BRCMF_FW_NAME_LEN); ++ } ++ } ++ brcmf_fw_get_full_name(fwnames[j].path, ++ mapping_table[i].fw_base, ++ fwnames[j].extension); ++ fwreq->items[j].path = fwnames[j].path; ++ } ++ ++ return fwreq; ++} +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +@@ -77,6 +77,17 @@ struct brcmf_fw_request { + struct brcmf_fw_item items[0]; + }; + ++struct brcmf_fw_name { ++ const char *extension; ++ char *path; ++}; ++ ++struct brcmf_fw_request * ++brcmf_fw_alloc_request(u32 chip, u32 chiprev, ++ struct brcmf_firmware_mapping mapping_table[], ++ u32 table_size, struct brcmf_fw_name *fwnames, ++ u32 n_fwnames); ++ + /* + * Request firmware(s) asynchronously. When the asynchronous request + * fails it will not use the callback, but call device_release_driver() +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1735,6 +1735,31 @@ fail: + device_release_driver(dev); + } + ++static struct brcmf_fw_request * ++brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo) ++{ ++ struct brcmf_fw_request *fwreq; ++ struct brcmf_fw_name fwnames[] = { ++ { ".bin", devinfo->fw_name }, ++ { ".txt", devinfo->nvram_name }, ++ }; ++ ++ fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev, ++ brcmf_pcie_fwnames, ++ ARRAY_SIZE(brcmf_pcie_fwnames), ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return NULL; ++ ++ fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; ++ fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; ++ fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus); ++ fwreq->bus_nr = devinfo->pdev->bus->number; ++ ++ return fwreq; ++} ++ + static int + brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { +@@ -1743,13 +1768,8 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + struct brcmf_pciedev_info *devinfo; + struct brcmf_pciedev *pcie_bus_dev; + struct brcmf_bus *bus; +- u16 domain_nr; +- u16 bus_nr; + +- domain_nr = pci_domain_nr(pdev->bus) + 1; +- bus_nr = pdev->bus->number; +- brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device, +- domain_nr, bus_nr); ++ brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); + + ret = -ENOMEM; + devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); +@@ -1803,33 +1823,19 @@ 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_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev, +- brcmf_pcie_fwnames, +- ARRAY_SIZE(brcmf_pcie_fwnames), +- devinfo->fw_name, devinfo->nvram_name); +- if (ret) +- goto fail_bus; +- +- fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item), +- GFP_KERNEL); ++ fwreq = brcmf_pcie_prepare_fw_request(devinfo); + if (!fwreq) { + ret = -ENOMEM; + goto fail_bus; + } + +- fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name; +- fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY; +- fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name; +- fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; +- fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; +- fwreq->n_items = 2; +- fwreq->domain_nr = domain_nr; +- fwreq->bus_nr = bus_nr; + ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup); +- if (ret == 0) +- return 0; ++ if (ret < 0) { ++ kfree(fwreq); ++ goto fail_bus; ++ } ++ return 0; + +- kfree(fwreq); + fail_bus: + kfree(bus->msgbuf); + kfree(bus); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4155,6 +4155,28 @@ fail: + device_release_driver(dev); + } + ++static struct brcmf_fw_request * ++brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) ++{ ++ struct brcmf_fw_request *fwreq; ++ struct brcmf_fw_name fwnames[] = { ++ { ".bin", bus->sdiodev->fw_name }, ++ { ".txt", bus->sdiodev->nvram_name }, ++ }; ++ ++ fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev, ++ brcmf_sdio_fwnames, ++ ARRAY_SIZE(brcmf_sdio_fwnames), ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return NULL; ++ ++ fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; ++ ++ return fwreq; ++} ++ + struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) + { + int ret; +@@ -4244,26 +4266,12 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + + brcmf_dbg(INFO, "completed!!\n"); + +- ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev, +- brcmf_sdio_fwnames, +- ARRAY_SIZE(brcmf_sdio_fwnames), +- sdiodev->fw_name, sdiodev->nvram_name); +- if (ret) +- goto fail; +- +- fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item), +- GFP_KERNEL); ++ fwreq = brcmf_sdio_prepare_fw_request(bus); + if (!fwreq) { + ret = -ENOMEM; + goto fail; + } + +- fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name; +- fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY; +- fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name; +- fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM; +- fwreq->n_items = 2; +- + ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq, + brcmf_sdio_firmware_callback); + if (ret != 0) { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1200,6 +1200,27 @@ error: + device_release_driver(dev); + } + ++static struct brcmf_fw_request * ++brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo) ++{ ++ struct brcmf_fw_request *fwreq; ++ struct brcmf_fw_name fwnames[] = { ++ { ".bin", devinfo->fw_name }, ++ }; ++ ++ fwreq = brcmf_fw_alloc_request(devinfo->bus_pub.devid, ++ devinfo->bus_pub.chiprev, ++ brcmf_usb_fwnames, ++ ARRAY_SIZE(brcmf_usb_fwnames), ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return NULL; ++ ++ fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; ++ ++ return fwreq; ++} ++ + static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) + { + struct brcmf_bus *bus = NULL; +@@ -1249,24 +1270,12 @@ static int brcmf_usb_probe_cb(struct brc + bus->chip = bus_pub->devid; + bus->chiprev = bus_pub->chiprev; + +- ret = brcmf_fw_map_chip_to_name(bus_pub->devid, bus_pub->chiprev, +- brcmf_usb_fwnames, +- ARRAY_SIZE(brcmf_usb_fwnames), +- devinfo->fw_name, NULL); +- if (ret) +- goto fail; +- +- fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), +- GFP_KERNEL); ++ fwreq = brcmf_usb_prepare_fw_request(devinfo); + if (!fwreq) { + ret = -ENOMEM; + goto fail; + } + +- fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; +- fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; +- fwreq->n_items = 1; +- + /* request firmware here */ + ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2); + if (ret) { +@@ -1469,15 +1478,10 @@ static int brcmf_usb_reset_resume(struct + + brcmf_dbg(USB, "Enter\n"); + +- fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item), +- GFP_KERNEL); ++ fwreq = brcmf_usb_prepare_fw_request(devinfo); + if (!fwreq) + return -ENOMEM; + +- fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name; +- fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY; +- fwreq->n_items = 1; +- + ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2); + if (ret < 0) + kfree(fwreq); diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0009-brcmfmac-add-extension-to-.get_fwname-callbacks.patch b/root/package/kernel/mac80211/patches/327-v4.17-0009-brcmfmac-add-extension-to-.get_fwname-callbacks.patch new file mode 100644 index 00000000..391229a8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0009-brcmfmac-add-extension-to-.get_fwname-callbacks.patch @@ -0,0 +1,231 @@ +From bf7a7b37f6ef5090a2bae7e7ae23cd26b741cca4 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:28 +0100 +Subject: [PATCH] brcmfmac: add extension to .get_fwname() callbacks + +This changes the bus layer api by having the caller provide an +extension. With this the callback can use brcmf_fw_alloc_request() +to get the needed firmware name. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 6 +-- + .../wireless/broadcom/brcm80211/brcmfmac/common.c | 43 +++------------------- + .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 27 +++++++------- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 26 +++++++------ + .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 27 ++++++++------ + 5 files changed, 51 insertions(+), 78 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -88,7 +88,7 @@ struct brcmf_bus_ops { + void (*wowl_config)(struct device *dev, bool enabled); + size_t (*get_ramsize)(struct device *dev); + int (*get_memdump)(struct device *dev, void *data, size_t len); +- int (*get_fwname)(struct device *dev, uint chip, uint chiprev, ++ int (*get_fwname)(struct device *dev, const char *ext, + unsigned char *fw_name); + }; + +@@ -228,10 +228,10 @@ int brcmf_bus_get_memdump(struct brcmf_b + } + + static inline +-int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev, ++int brcmf_bus_get_fwname(struct brcmf_bus *bus, const char *ext, + unsigned char *fw_name) + { +- return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name); ++ return bus->ops->get_fwname(bus->dev, ext, fw_name); + } + + /* +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -129,42 +129,9 @@ static int brcmf_c_download(struct brcmf + return err; + } + +-static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name) +-{ +- struct brcmf_bus *bus = ifp->drvr->bus_if; +- u8 fw_name[BRCMF_FW_NAME_LEN]; +- u8 *ptr; +- size_t len; +- s32 err; +- +- memset(fw_name, 0, BRCMF_FW_NAME_LEN); +- err = brcmf_bus_get_fwname(bus, bus->chip, bus->chiprev, fw_name); +- if (err) { +- brcmf_err("get firmware name failed (%d)\n", err); +- goto done; +- } +- +- /* generate CLM blob file name */ +- ptr = strrchr(fw_name, '.'); +- if (!ptr) { +- err = -ENOENT; +- goto done; +- } +- +- len = ptr - fw_name + 1; +- if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) { +- err = -E2BIG; +- } else { +- strlcpy(clm_name, fw_name, len); +- strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN); +- } +-done: +- return err; +-} +- + static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) + { +- struct device *dev = ifp->drvr->bus_if->dev; ++ struct brcmf_bus *bus = ifp->drvr->bus_if; + struct brcmf_dload_data_le *chunk_buf; + const struct firmware *clm = NULL; + u8 clm_name[BRCMF_FW_NAME_LEN]; +@@ -177,16 +144,16 @@ static int brcmf_c_process_clm_blob(stru + + brcmf_dbg(TRACE, "Enter\n"); + +- memset(clm_name, 0, BRCMF_FW_NAME_LEN); +- err = brcmf_c_get_clm_name(ifp, clm_name); ++ memset(clm_name, 0, sizeof(clm_name)); ++ err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name); + if (err) { + brcmf_err("get CLM blob file name failed (%d)\n", err); + return err; + } + +- err = request_firmware(&clm, clm_name, dev); ++ err = request_firmware(&clm, clm_name, bus->dev); + if (err) { +- brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n", ++ brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n", + err); + return 0; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1350,23 +1350,24 @@ static int brcmf_pcie_get_memdump(struct + return 0; + } + +-static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev, +- u8 *fw_name) ++static ++int brcmf_pcie_get_fwname(struct device *dev, const char *ext, u8 *fw_name) + { + 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; +- int ret = 0; ++ struct brcmf_fw_request *fwreq; ++ struct brcmf_fw_name fwnames[] = { ++ { ext, fw_name }, ++ }; + +- if (devinfo->fw_name[0] != '\0') +- strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); +- else +- ret = brcmf_fw_map_chip_to_name(chip, chiprev, +- brcmf_pcie_fwnames, +- ARRAY_SIZE(brcmf_pcie_fwnames), +- fw_name, NULL); ++ fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev, ++ brcmf_pcie_fwnames, ++ ARRAY_SIZE(brcmf_pcie_fwnames), ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return -ENOMEM; + +- return ret; ++ kfree(fwreq); ++ return 0; + } + + static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4000,22 +4000,24 @@ brcmf_sdio_watchdog(unsigned long data) + } + } + +-static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev, +- u8 *fw_name) ++static ++int brcmf_sdio_get_fwname(struct device *dev, const char *ext, u8 *fw_name) + { + struct brcmf_bus *bus_if = dev_get_drvdata(dev); +- struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; +- int ret = 0; ++ struct brcmf_fw_request *fwreq; ++ struct brcmf_fw_name fwnames[] = { ++ { ext, fw_name }, ++ }; + +- if (sdiodev->fw_name[0] != '\0') +- strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN); +- else +- ret = brcmf_fw_map_chip_to_name(chip, chiprev, +- brcmf_sdio_fwnames, +- ARRAY_SIZE(brcmf_sdio_fwnames), +- fw_name, NULL); ++ fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev, ++ brcmf_sdio_fwnames, ++ ARRAY_SIZE(brcmf_sdio_fwnames), ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return -ENOMEM; + +- return ret; ++ kfree(fwreq); ++ return 0; + } + + static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1128,21 +1128,24 @@ static void brcmf_usb_wowl_config(struct + device_set_wakeup_enable(devinfo->dev, false); + } + +-static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev, +- u8 *fw_name) ++static ++int brcmf_usb_get_fwname(struct device *dev, const char *ext, u8 *fw_name) + { +- struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); +- int ret = 0; ++ struct brcmf_bus *bus = dev_get_drvdata(dev); ++ struct brcmf_fw_request *fwreq; ++ struct brcmf_fw_name fwnames[] = { ++ { ext, fw_name }, ++ }; + +- if (devinfo->fw_name[0] != '\0') +- strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN); +- else +- ret = brcmf_fw_map_chip_to_name(chip, chiprev, +- brcmf_usb_fwnames, +- ARRAY_SIZE(brcmf_usb_fwnames), +- fw_name, NULL); ++ fwreq = brcmf_fw_alloc_request(bus->chip, bus->chiprev, ++ brcmf_usb_fwnames, ++ ARRAY_SIZE(brcmf_usb_fwnames), ++ fwnames, ARRAY_SIZE(fwnames)); ++ if (!fwreq) ++ return -ENOMEM; + +- return ret; ++ kfree(fwreq); ++ return 0; + } + + static const struct brcmf_bus_ops brcmf_usb_bus_ops = { diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0010-brcmfmac-get-rid-of-brcmf_fw_map_chip_to_name.patch b/root/package/kernel/mac80211/patches/327-v4.17-0010-brcmfmac-get-rid-of-brcmf_fw_map_chip_to_name.patch new file mode 100644 index 00000000..becf7cf3 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0010-brcmfmac-get-rid-of-brcmf_fw_map_chip_to_name.patch @@ -0,0 +1,92 @@ +From 18c2b20e276e04476a3350b4a92c1dfad725d45d Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:29 +0100 +Subject: [PATCH] brcmfmac: get rid of brcmf_fw_map_chip_to_name() + +The function is no longer used so removing it. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 53 ---------------------- + .../broadcom/brcm80211/brcmfmac/firmware.h | 4 -- + 2 files changed, 57 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -635,59 +635,6 @@ static void brcmf_fw_get_full_name(char + strlcat(fw_name, extension, BRCMF_FW_NAME_LEN); + } + +-int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, +- struct brcmf_firmware_mapping mapping_table[], +- u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], +- char nvram_name[BRCMF_FW_NAME_LEN]) +-{ +- char chipname[12]; +- u32 i; +- char end; +- +- for (i = 0; i < table_size; i++) { +- if (mapping_table[i].chipid == chip && +- mapping_table[i].revmask & BIT(chiprev)) +- break; +- } +- +- if (i == table_size) { +- brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); +- return -ENODEV; +- } +- +- brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); +- +- /* check if firmware path is provided by module parameter */ +- if (brcmf_mp_global.firmware_path[0] != '\0') { +- if (fw_name) +- strlcpy(fw_name, brcmf_mp_global.firmware_path, +- BRCMF_FW_NAME_LEN); +- if (nvram_name) +- strlcpy(nvram_name, brcmf_mp_global.firmware_path, +- BRCMF_FW_NAME_LEN); +- +- end = brcmf_mp_global.firmware_path[ +- strlen(brcmf_mp_global.firmware_path) - 1]; +- if (end != '/') { +- if (fw_name) +- strlcat(fw_name, "/", BRCMF_FW_NAME_LEN); +- if (nvram_name) +- strlcat(nvram_name, "/", BRCMF_FW_NAME_LEN); +- } +- } +- +- brcmf_info("using %s for chip %s\n", +- mapping_table[i].fw_base, chipname); +- if (fw_name) +- brcmf_fw_get_full_name(fw_name, +- mapping_table[i].fw_base, ".bin"); +- if (nvram_name) +- brcmf_fw_get_full_name(nvram_name, +- mapping_table[i].fw_base, ".txt"); +- +- return 0; +-} +- + struct brcmf_fw_request * + brcmf_fw_alloc_request(u32 chip, u32 chiprev, + struct brcmf_firmware_mapping mapping_table[], +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +@@ -46,10 +46,6 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw + #define BRCMF_FW_ENTRY(chipid, mask, name) \ + { chipid, mask, BRCM_ ## name ## _FIRMWARE_BASENAME } + +-int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev, +- struct brcmf_firmware_mapping mapping_table[], +- u32 table_size, char fw_name[BRCMF_FW_NAME_LEN], +- char nvram_name[BRCMF_FW_NAME_LEN]); + void brcmf_fw_nvram_free(void *nvram); + + enum brcmf_fw_type { diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0011-brcmfmac-get-rid-of-brcmf_fw_get_full_name.patch b/root/package/kernel/mac80211/patches/327-v4.17-0011-brcmfmac-get-rid-of-brcmf_fw_get_full_name.patch new file mode 100644 index 00000000..d831f44f --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0011-brcmfmac-get-rid-of-brcmf_fw_get_full_name.patch @@ -0,0 +1,44 @@ +From bf291b7247e53f52a4236c0b55a5df046d6177df Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:30 +0100 +Subject: [PATCH] brcmfmac: get rid of brcmf_fw_get_full_name() + +The function was pretty minimal and now it is called only from one +place so just get rid of it. + +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -628,13 +628,6 @@ int brcmf_fw_get_firmwares(struct device + return 0; + } + +-static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN], +- const char *fw_base, const char *extension) +-{ +- strlcat(fw_name, fw_base, BRCMF_FW_NAME_LEN); +- strlcat(fw_name, extension, BRCMF_FW_NAME_LEN); +-} +- + struct brcmf_fw_request * + brcmf_fw_alloc_request(u32 chip, u32 chiprev, + struct brcmf_firmware_mapping mapping_table[], +@@ -685,9 +678,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi + BRCMF_FW_NAME_LEN); + } + } +- brcmf_fw_get_full_name(fwnames[j].path, +- mapping_table[i].fw_base, +- fwnames[j].extension); ++ strlcat(fwnames[j].path, mapping_table[i].fw_base, ++ BRCMF_FW_NAME_LEN); ++ strlcat(fwnames[j].path, fwnames[j].extension, ++ BRCMF_FW_NAME_LEN); + fwreq->items[j].path = fwnames[j].path; + } + diff --git a/root/package/kernel/mac80211/patches/327-v4.17-0012-brcmfmac-add-kerneldoc-for-struct-brcmf_bus-msgbuf.patch b/root/package/kernel/mac80211/patches/327-v4.17-0012-brcmfmac-add-kerneldoc-for-struct-brcmf_bus-msgbuf.patch new file mode 100644 index 00000000..1c9c9959 --- /dev/null +++ b/root/package/kernel/mac80211/patches/327-v4.17-0012-brcmfmac-add-kerneldoc-for-struct-brcmf_bus-msgbuf.patch @@ -0,0 +1,23 @@ +From 48eaee3f272a5bfe6986d07c51f6975d3c2f74d1 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 22 Mar 2018 21:28:31 +0100 +Subject: [PATCH] brcmfmac: add kerneldoc for struct brcmf_bus::msgbuf + +This field did not have kerneldoc description so adding it now. + +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -140,6 +140,7 @@ struct brcmf_bus_stats { + * @always_use_fws_queue: bus wants use queue also when fwsignal is inactive. + * @wowl_supported: is wowl supported by bus driver. + * @chiprev: revision of the dongle chip. ++ * @msgbuf: msgbuf protocol parameters provided by bus layer. + */ + struct brcmf_bus { + union { diff --git a/root/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch b/root/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch new file mode 100644 index 00000000..cd2279dd --- /dev/null +++ b/root/package/kernel/mac80211/patches/328-v4.17-0001-brcmfmac-fix-firmware-request-processing-if-nvram-lo.patch @@ -0,0 +1,81 @@ +From 0b5c0305e57ca940713bcb2b202fd2b412c62f31 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Tue, 3 Apr 2018 10:18:15 +0200 +Subject: [PATCH] brcmfmac: fix firmware request processing if nvram load fails + +When nvram loading fails a double free occurred. Fix this and reorg the +code a little. + +Fixes: d09ae51a4b67 ("brcmfmac: pass struct in brcmf_fw_get_firmwares()") +Reported-by: Dan Carpenter +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/firmware.c | 36 ++++++++++++---------- + 1 file changed, 20 insertions(+), 16 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -459,7 +459,7 @@ static void brcmf_fw_free_request(struct + kfree(req); + } + +-static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) ++static int brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) + { + struct brcmf_fw *fwctx = ctx; + struct brcmf_fw_item *cur; +@@ -498,13 +498,10 @@ static void brcmf_fw_request_nvram_done( + brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length); + cur->nv_data.data = nvram; + cur->nv_data.len = nvram_length; +- return; ++ return 0; + + fail: +- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); +- fwctx->done(fwctx->dev, -ENOENT, NULL); +- brcmf_fw_free_request(fwctx->req); +- kfree(fwctx); ++ return -ENOENT; + } + + static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async) +@@ -553,20 +550,27 @@ static void brcmf_fw_request_done(const + brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path, + fw ? "" : "not "); + +- if (fw) { +- if (cur->type == BRCMF_FW_TYPE_BINARY) +- cur->binary = fw; +- else if (cur->type == BRCMF_FW_TYPE_NVRAM) +- brcmf_fw_request_nvram_done(fw, fwctx); +- else +- release_firmware(fw); +- } else if (cur->type == BRCMF_FW_TYPE_NVRAM) { +- brcmf_fw_request_nvram_done(NULL, fwctx); +- } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) { ++ if (!fw) + ret = -ENOENT; ++ ++ switch (cur->type) { ++ case BRCMF_FW_TYPE_NVRAM: ++ ret = brcmf_fw_request_nvram_done(fw, fwctx); ++ break; ++ case BRCMF_FW_TYPE_BINARY: ++ cur->binary = fw; ++ break; ++ default: ++ /* something fishy here so bail out early */ ++ brcmf_err("unknown fw type: %d\n", cur->type); ++ release_firmware(fw); ++ ret = -EINVAL; + goto fail; + } + ++ if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL)) ++ goto fail; ++ + do { + if (++fwctx->curpos == fwctx->req->n_items) { + ret = 0; diff --git a/root/package/kernel/mac80211/patches/329-v4.18-0001-brcmfmac-add-support-for-BCM4366E-chipset.patch b/root/package/kernel/mac80211/patches/329-v4.18-0001-brcmfmac-add-support-for-BCM4366E-chipset.patch new file mode 100644 index 00000000..e31d6982 --- /dev/null +++ b/root/package/kernel/mac80211/patches/329-v4.18-0001-brcmfmac-add-support-for-BCM4366E-chipset.patch @@ -0,0 +1,48 @@ +From 1f589e2510d5df1192dca7c089103a2cbd028101 Mon Sep 17 00:00:00 2001 +From: Dan Haab +Date: Tue, 3 Apr 2018 10:21:56 +0200 +Subject: [PATCH] brcmfmac: add support for BCM4366E chipset + +BCM4366E is a wireless chipset with a BCM43664 ChipCommon. It's +supported by the same firmware as 4366c0. + +Signed-off-by: Dan Haab +[arend: rebase patch and remove unnecessary definition] +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 + + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 + + 3 files changed, 3 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -689,6 +689,7 @@ static u32 brcmf_chip_tcm_rambase(struct + case BRCM_CC_43525_CHIP_ID: + case BRCM_CC_4365_CHIP_ID: + case BRCM_CC_4366_CHIP_ID: ++ case BRCM_CC_43664_CHIP_ID: + return 0x200000; + case CY_CC_4373_CHIP_ID: + return 0x160000; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -75,6 +75,7 @@ static struct brcmf_firmware_mapping brc + BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFF0, 4365C), + BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), + BRCMF_FW_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), ++ BRCMF_FW_ENTRY(BRCM_CC_43664_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), + }; + +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -57,6 +57,7 @@ + #define BRCM_CC_43602_CHIP_ID 43602 + #define BRCM_CC_4365_CHIP_ID 0x4365 + #define BRCM_CC_4366_CHIP_ID 0x4366 ++#define BRCM_CC_43664_CHIP_ID 43664 + #define BRCM_CC_4371_CHIP_ID 0x4371 + #define CY_CC_4373_CHIP_ID 0x4373 + diff --git a/root/package/kernel/mac80211/patches/330-v4.18-0001-brcmfmac-check-p2pdev-mac-address-uniqueness.patch b/root/package/kernel/mac80211/patches/330-v4.18-0001-brcmfmac-check-p2pdev-mac-address-uniqueness.patch new file mode 100644 index 00000000..909000cc --- /dev/null +++ b/root/package/kernel/mac80211/patches/330-v4.18-0001-brcmfmac-check-p2pdev-mac-address-uniqueness.patch @@ -0,0 +1,34 @@ +From cb746e47837ad0f35c8ae28e9aacc8eb07916d2a Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 26 Apr 2018 12:16:47 +0200 +Subject: [PATCH] brcmfmac: check p2pdev mac address uniqueness + +The mac address for p2pdev must be different from the primary interface +due to firmware requirement. Add an explicit check for this requirement +if user-space provides a mac address. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2073,6 +2073,13 @@ static struct wireless_dev *brcmf_p2p_cr + } + + pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; ++ ++ /* firmware requires unique mac address for p2pdev interface */ ++ if (addr && ether_addr_equal(addr, pri_ifp->mac_addr)) { ++ brcmf_err("discovery vif must be different from primary interface\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ + brcmf_p2p_generate_bss_mac(p2p, addr); + brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); + diff --git a/root/package/kernel/mac80211/patches/330-v4.18-0002-brcmfmac-reports-boottime_ns-while-informing-bss.patch b/root/package/kernel/mac80211/patches/330-v4.18-0002-brcmfmac-reports-boottime_ns-while-informing-bss.patch new file mode 100644 index 00000000..4f59507c --- /dev/null +++ b/root/package/kernel/mac80211/patches/330-v4.18-0002-brcmfmac-reports-boottime_ns-while-informing-bss.patch @@ -0,0 +1,76 @@ +From 7742fce4c007141617dab9bcb90034b3c0fe2347 Mon Sep 17 00:00:00 2001 +From: Franky Lin +Date: Thu, 26 Apr 2018 12:18:35 +0200 +Subject: [PATCH] brcmfmac: reports boottime_ns while informing bss + +Provides a timestamp in bss information so user space can see when the +bss info was updated. Since tsf is not available from the dongle events +boottime is reported instead. + +Reported-by: Dmitry Shmidt +Reviewed-by: Arend van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 +++++++++++----------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2728,7 +2728,6 @@ static s32 brcmf_inform_single_bss(struc + struct brcmf_bss_info_le *bi) + { + struct wiphy *wiphy = cfg_to_wiphy(cfg); +- struct ieee80211_channel *notify_channel; + struct cfg80211_bss *bss; + struct ieee80211_supported_band *band; + struct brcmu_chan ch; +@@ -2738,7 +2737,7 @@ static s32 brcmf_inform_single_bss(struc + u16 notify_interval; + u8 *notify_ie; + size_t notify_ielen; +- s32 notify_signal; ++ struct cfg80211_inform_bss bss_data = { 0 }; + + if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) { + brcmf_err("Bss info is larger than buffer. Discarding\n"); +@@ -2758,27 +2757,28 @@ static s32 brcmf_inform_single_bss(struc + band = wiphy->bands[NL80211_BAND_5GHZ]; + + freq = ieee80211_channel_to_frequency(channel, band->band); +- notify_channel = ieee80211_get_channel(wiphy, freq); ++ bss_data.chan = ieee80211_get_channel(wiphy, freq); ++ bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20; ++ bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime()); + + notify_capability = le16_to_cpu(bi->capability); + notify_interval = le16_to_cpu(bi->beacon_period); + notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); + notify_ielen = le32_to_cpu(bi->ie_length); +- notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; ++ bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100; + + brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID); + brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq); + brcmf_dbg(CONN, "Capability: %X\n", notify_capability); + brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval); +- brcmf_dbg(CONN, "Signal: %d\n", notify_signal); ++ brcmf_dbg(CONN, "Signal: %d\n", bss_data.signal); + +- bss = cfg80211_inform_bss(wiphy, notify_channel, +- CFG80211_BSS_FTYPE_UNKNOWN, +- (const u8 *)bi->BSSID, +- 0, notify_capability, +- notify_interval, notify_ie, +- notify_ielen, notify_signal, +- GFP_KERNEL); ++ bss = cfg80211_inform_bss_data(wiphy, &bss_data, ++ CFG80211_BSS_FTYPE_UNKNOWN, ++ (const u8 *)bi->BSSID, ++ 0, notify_capability, ++ notify_interval, notify_ie, ++ notify_ielen, GFP_KERNEL); + + if (!bss) + return -ENOMEM; diff --git a/root/package/kernel/mac80211/patches/330-v4.18-0003-brcmfmac-use-nl80211_band-directly-to-get-ieee80211-.patch b/root/package/kernel/mac80211/patches/330-v4.18-0003-brcmfmac-use-nl80211_band-directly-to-get-ieee80211-.patch new file mode 100644 index 00000000..2d60c0d9 --- /dev/null +++ b/root/package/kernel/mac80211/patches/330-v4.18-0003-brcmfmac-use-nl80211_band-directly-to-get-ieee80211-.patch @@ -0,0 +1,43 @@ +From aed14219067ab96e5eeb7730e9bceed10d9be989 Mon Sep 17 00:00:00 2001 +From: Franky Lin +Date: Thu, 26 Apr 2018 12:16:48 +0200 +Subject: [PATCH] brcmfmac: use nl80211_band directly to get ieee80211 channel + +The enum nl80211_band used to retrieve wiphy->bands is the same as +wiphy->bands->band which is checked by wiphy_register(). So it can be used +directly as parameter of ieee80211_channel_to_frequency(). + +Reviewed-by: Arend van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2729,7 +2729,7 @@ static s32 brcmf_inform_single_bss(struc + { + struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct cfg80211_bss *bss; +- struct ieee80211_supported_band *band; ++ enum nl80211_band band; + struct brcmu_chan ch; + u16 channel; + u32 freq; +@@ -2752,11 +2752,11 @@ static s32 brcmf_inform_single_bss(struc + channel = bi->ctl_ch; + + if (channel <= CH_MAX_2G_CHANNEL) +- band = wiphy->bands[NL80211_BAND_2GHZ]; ++ band = NL80211_BAND_2GHZ; + else +- band = wiphy->bands[NL80211_BAND_5GHZ]; ++ band = NL80211_BAND_5GHZ; + +- freq = ieee80211_channel_to_frequency(channel, band->band); ++ freq = ieee80211_channel_to_frequency(channel, band); + bss_data.chan = ieee80211_get_channel(wiphy, freq); + bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20; + bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime()); diff --git a/root/package/kernel/mac80211/patches/330-v4.18-0004-brcmfmac-constify-firmware-mapping-tables.patch b/root/package/kernel/mac80211/patches/330-v4.18-0004-brcmfmac-constify-firmware-mapping-tables.patch new file mode 100644 index 00000000..df264837 --- /dev/null +++ b/root/package/kernel/mac80211/patches/330-v4.18-0004-brcmfmac-constify-firmware-mapping-tables.patch @@ -0,0 +1,76 @@ +From ff68c9f9c06d1fd437c8f90fc05ca28c47f7d85e Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Thu, 26 Apr 2018 12:16:49 +0200 +Subject: [PATCH] brcmfmac: constify firmware mapping tables + +The information in the firmware mapping does not need to be modified +so it can be static const. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -634,7 +634,7 @@ int brcmf_fw_get_firmwares(struct device + + struct brcmf_fw_request * + brcmf_fw_alloc_request(u32 chip, u32 chiprev, +- struct brcmf_firmware_mapping mapping_table[], ++ const struct brcmf_firmware_mapping mapping_table[], + u32 table_size, struct brcmf_fw_name *fwnames, + u32 n_fwnames) + { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h +@@ -80,7 +80,7 @@ struct brcmf_fw_name { + + struct brcmf_fw_request * + brcmf_fw_alloc_request(u32 chip, u32 chiprev, +- struct brcmf_firmware_mapping mapping_table[], ++ const struct brcmf_firmware_mapping mapping_table[], + u32 table_size, struct brcmf_fw_name *fwnames, + u32 n_fwnames); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -59,7 +59,7 @@ BRCMF_FW_DEF(4366B, "brcmfmac4366b-pcie" + BRCMF_FW_DEF(4366C, "brcmfmac4366c-pcie"); + BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); + +-static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { ++static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), + BRCMF_FW_ENTRY(BRCM_CC_43465_CHIP_ID, 0xFFFFFFF0, 4366C), + BRCMF_FW_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C), +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -619,7 +619,7 @@ BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); + BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); + BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); + +-static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { ++static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), + BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0), + BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4), +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -52,7 +52,7 @@ BRCMF_FW_DEF(43242A, "brcmfmac43242a"); + BRCMF_FW_DEF(43569, "brcmfmac43569"); + BRCMF_FW_DEF(4373, "brcmfmac4373"); + +-static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { ++static const struct brcmf_firmware_mapping brcmf_usb_fwnames[] = { + BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143), + BRCMF_FW_ENTRY(BRCM_CC_43235_CHIP_ID, 0x00000008, 43236B), + BRCMF_FW_ENTRY(BRCM_CC_43236_CHIP_ID, 0x00000008, 43236B), diff --git a/root/package/kernel/mac80211/patches/330-v4.18-0005-brcmfmac-add-hostready-indication.patch b/root/package/kernel/mac80211/patches/330-v4.18-0005-brcmfmac-add-hostready-indication.patch new file mode 100644 index 00000000..e3d4441f --- /dev/null +++ b/root/package/kernel/mac80211/patches/330-v4.18-0005-brcmfmac-add-hostready-indication.patch @@ -0,0 +1,74 @@ +From 84ad327d18debe19b8d509059b61db445d048b02 Mon Sep 17 00:00:00 2001 +From: Franky Lin +Date: Thu, 26 Apr 2018 12:16:50 +0200 +Subject: [PATCH] brcmfmac: add hostready indication + +A hostready signal is introduced to inform firmware through mailbox +doorbell1 when common ring initialized or D3 exited. + +Reviewed-by: Arend van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -105,7 +105,8 @@ static const struct brcmf_firmware_mappi + #define BRCMF_PCIE_PCIE2REG_MAILBOXMASK 0x4C + #define BRCMF_PCIE_PCIE2REG_CONFIGADDR 0x120 + #define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124 +-#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140 ++#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0 0x140 ++#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1 0x144 + + #define BRCMF_PCIE2_INTA 0x01 + #define BRCMF_PCIE2_INTB 0x02 +@@ -140,6 +141,7 @@ static const struct brcmf_firmware_mappi + #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF + #define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000 + #define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000 ++#define BRCMF_PCIE_SHARED_HOSTRDY_DB1 0x10000000 + + #define BRCMF_PCIE_FLAGS_HTOD_SPLIT 0x4000 + #define BRCMF_PCIE_FLAGS_DTOH_SPLIT 0x8000 +@@ -782,6 +784,12 @@ static void brcmf_pcie_intr_enable(struc + BRCMF_PCIE_MB_INT_FN0_1); + } + ++static void brcmf_pcie_hostready(struct brcmf_pciedev_info *devinfo) ++{ ++ if (devinfo->shared.flags & BRCMF_PCIE_SHARED_HOSTRDY_DB1) ++ brcmf_pcie_write_reg32(devinfo, ++ BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_1, 1); ++} + + static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg) + { +@@ -924,7 +932,7 @@ static int brcmf_pcie_ring_mb_ring_bell( + + brcmf_dbg(PCIE, "RING !\n"); + /* Any arbitrary value will do, lets use 1 */ +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1); ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX_0, 1); + + return 0; + } +@@ -1728,6 +1736,7 @@ static void brcmf_pcie_setup(struct devi + init_waitqueue_head(&devinfo->mbdata_resp_wait); + + brcmf_pcie_intr_enable(devinfo); ++ brcmf_pcie_hostready(devinfo); + if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) + return; + +@@ -1950,6 +1959,7 @@ static int brcmf_pcie_pm_leave_D3(struct + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); + brcmf_bus_change_state(bus, BRCMF_BUS_UP); + brcmf_pcie_intr_enable(devinfo); ++ brcmf_pcie_hostready(devinfo); + return 0; + } + diff --git a/root/package/kernel/mac80211/patches/330-v4.18-0006-brcmfmac-coarse-support-for-PCIe-shared-structure-re.patch b/root/package/kernel/mac80211/patches/330-v4.18-0006-brcmfmac-coarse-support-for-PCIe-shared-structure-re.patch new file mode 100644 index 00000000..8750037d --- /dev/null +++ b/root/package/kernel/mac80211/patches/330-v4.18-0006-brcmfmac-coarse-support-for-PCIe-shared-structure-re.patch @@ -0,0 +1,97 @@ +From f56324baf329bc9362a52ad77a4a1a0f3356d1bc Mon Sep 17 00:00:00 2001 +From: Franky Lin +Date: Thu, 26 Apr 2018 12:16:51 +0200 +Subject: [PATCH] brcmfmac: coarse support for PCIe shared structure rev7 + +Revision 7 of PCIe dongle interface increases the item size of tx and rx +complete rings to accommodate extra payload for new feature. This patch +simply bump up the size of these two rings without adding the support +for utilizing the new space. This makes brcmfmac compatible with rev7 +firmware. + +Reviewed-by: Arend van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.h | 6 ++++-- + .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 23 ++++++++++++++++++---- + 2 files changed, 23 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h +@@ -27,8 +27,10 @@ + #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40 + #define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE 32 + #define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE 24 +-#define BRCMF_D2H_MSGRING_TX_COMPLETE_ITEMSIZE 16 +-#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 32 ++#define BRCMF_D2H_MSGRING_TX_COMPLETE_ITEMSIZE_PRE_V7 16 ++#define BRCMF_D2H_MSGRING_TX_COMPLETE_ITEMSIZE 24 ++#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE_PRE_V7 32 ++#define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE 40 + #define BRCMF_H2D_TXFLOWRING_ITEMSIZE 48 + + struct msgbuf_buf_addr { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -136,8 +136,9 @@ static const struct brcmf_firmware_mappi + BRCMF_PCIE_MB_INT_D2H3_DB0 | \ + BRCMF_PCIE_MB_INT_D2H3_DB1) + ++#define BRCMF_PCIE_SHARED_VERSION_7 7 + #define BRCMF_PCIE_MIN_SHARED_VERSION 5 +-#define BRCMF_PCIE_MAX_SHARED_VERSION 6 ++#define BRCMF_PCIE_MAX_SHARED_VERSION BRCMF_PCIE_SHARED_VERSION_7 + #define BRCMF_PCIE_SHARED_VERSION_MASK 0x00FF + #define BRCMF_PCIE_SHARED_DMA_INDEX 0x10000 + #define BRCMF_PCIE_SHARED_DMA_2B_IDX 0x100000 +@@ -318,6 +319,14 @@ static const u32 brcmf_ring_max_item[BRC + BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM + }; + ++static const u32 brcmf_ring_itemsize_pre_v7[BRCMF_NROF_COMMON_MSGRINGS] = { ++ BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE, ++ BRCMF_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE, ++ BRCMF_D2H_MSGRING_CONTROL_COMPLETE_ITEMSIZE, ++ BRCMF_D2H_MSGRING_TX_COMPLETE_ITEMSIZE_PRE_V7, ++ BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE_PRE_V7 ++}; ++ + static const u32 brcmf_ring_itemsize[BRCMF_NROF_COMMON_MSGRINGS] = { + BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE, + BRCMF_H2D_MSGRING_RXPOST_SUBMIT_ITEMSIZE, +@@ -1007,8 +1016,14 @@ brcmf_pcie_alloc_dma_and_ring(struct brc + struct brcmf_pcie_ringbuf *ring; + u32 size; + u32 addr; ++ const u32 *ring_itemsize_array; ++ ++ if (devinfo->shared.version < BRCMF_PCIE_SHARED_VERSION_7) ++ ring_itemsize_array = brcmf_ring_itemsize_pre_v7; ++ else ++ ring_itemsize_array = brcmf_ring_itemsize; + +- size = brcmf_ring_max_item[ring_id] * brcmf_ring_itemsize[ring_id]; ++ size = brcmf_ring_max_item[ring_id] * ring_itemsize_array[ring_id]; + dma_buf = brcmf_pcie_init_dmabuffer_for_device(devinfo, size, + tcm_ring_phys_addr + BRCMF_RING_MEM_BASE_ADDR_OFFSET, + &dma_handle); +@@ -1018,7 +1033,7 @@ brcmf_pcie_alloc_dma_and_ring(struct brc + addr = tcm_ring_phys_addr + BRCMF_RING_MAX_ITEM_OFFSET; + brcmf_pcie_write_tcm16(devinfo, addr, brcmf_ring_max_item[ring_id]); + addr = tcm_ring_phys_addr + BRCMF_RING_LEN_ITEMS_OFFSET; +- brcmf_pcie_write_tcm16(devinfo, addr, brcmf_ring_itemsize[ring_id]); ++ brcmf_pcie_write_tcm16(devinfo, addr, ring_itemsize_array[ring_id]); + + ring = kzalloc(sizeof(*ring), GFP_KERNEL); + if (!ring) { +@@ -1027,7 +1042,7 @@ brcmf_pcie_alloc_dma_and_ring(struct brc + return NULL; + } + brcmf_commonring_config(&ring->commonring, brcmf_ring_max_item[ring_id], +- brcmf_ring_itemsize[ring_id], dma_buf); ++ ring_itemsize_array[ring_id], dma_buf); + ring->dma_handle = dma_handle; + ring->devinfo = devinfo; + brcmf_commonring_register_cb(&ring->commonring, diff --git a/root/package/kernel/mac80211/patches/331-v4.18-0001-brcmfmac-Add-support-for-bcm43364-wireless-chipset.patch b/root/package/kernel/mac80211/patches/331-v4.18-0001-brcmfmac-Add-support-for-bcm43364-wireless-chipset.patch new file mode 100644 index 00000000..13f169be --- /dev/null +++ b/root/package/kernel/mac80211/patches/331-v4.18-0001-brcmfmac-Add-support-for-bcm43364-wireless-chipset.patch @@ -0,0 +1,45 @@ +From 9c4a121e82634aa000a702c98cd6f05b27d6e186 Mon Sep 17 00:00:00 2001 +From: Sean Lanigan +Date: Fri, 4 May 2018 16:48:23 +1000 +Subject: [PATCH] brcmfmac: Add support for bcm43364 wireless chipset + +Add support for the BCM43364 chipset via an SDIO interface, as used in +e.g. the Murata 1FX module. + +The BCM43364 uses the same firmware as the BCM43430 (which is already +included), the only difference is the omission of Bluetooth. + +However, the SDIO_ID for the BCM43364 is 02D0:A9A4, giving it a MODALIAS +of sdio:c00v02D0dA9A4, which doesn't get recognised and hence doesn't +load the brcmfmac module. Adding the 'A9A4' ID in the appropriate place +triggers the brcmfmac driver to load, and then correctly use the +firmware file 'brcmfmac43430-sdio.bin'. + +Signed-off-by: Sean Lanigan +Acked-by: Ulf Hansson +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 + + include/linux/mmc/sdio_ids.h | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -963,6 +963,7 @@ static const struct sdio_device_id brcmf + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), ++ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43364), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430), +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -34,6 +34,7 @@ + #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 + #define SDIO_DEVICE_ID_BROADCOM_4339 0x4339 + #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 ++#define SDIO_DEVICE_ID_BROADCOM_43364 0xa9a4 + #define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6 + #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 + #define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf diff --git a/root/package/kernel/mac80211/patches/332-v4.18-0001-brcmfmac-set-WIPHY_FLAG_HAVE_AP_SME-flag.patch b/root/package/kernel/mac80211/patches/332-v4.18-0001-brcmfmac-set-WIPHY_FLAG_HAVE_AP_SME-flag.patch new file mode 100644 index 00000000..de41e1c4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/332-v4.18-0001-brcmfmac-set-WIPHY_FLAG_HAVE_AP_SME-flag.patch @@ -0,0 +1,34 @@ +From 1204aa17f3b4f63e67ac9b7c9afa9496485969c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 10 May 2018 15:21:39 +0200 +Subject: [PATCH] brcmfmac: set WIPHY_FLAG_HAVE_AP_SME flag +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +brcmfmac is a FullMAC driver and it implements/uses cfg80211 interface +for stations management. At the same time it doesn't receive or pass up +management frames. + +This flag indicates that authenticator doesn't have to subscribe to or +handle management frames. Some authenticators (e.g. hostapd) were +working with brcmfmac thanks to some extra assumptions. This commit +clears up the situation. + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6513,6 +6513,7 @@ static int brcmf_setup_wiphy(struct wiph + + wiphy->flags |= WIPHY_FLAG_NETNS_OK | + WIPHY_FLAG_PS_ON_BY_DEFAULT | ++ WIPHY_FLAG_HAVE_AP_SME | + WIPHY_FLAG_OFFCHAN_TX | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) diff --git a/root/package/kernel/mac80211/patches/333-v4.18-0001-brcmfmac-fix-initialization-of-struct-cfg80211_infor.patch b/root/package/kernel/mac80211/patches/333-v4.18-0001-brcmfmac-fix-initialization-of-struct-cfg80211_infor.patch new file mode 100644 index 00000000..2436bb8a --- /dev/null +++ b/root/package/kernel/mac80211/patches/333-v4.18-0001-brcmfmac-fix-initialization-of-struct-cfg80211_infor.patch @@ -0,0 +1,29 @@ +From 763ece85f45a6b93268e25a0abf02922f911dab4 Mon Sep 17 00:00:00 2001 +From: Franky Lin +Date: Tue, 15 May 2018 11:14:44 +0200 +Subject: [PATCH] brcmfmac: fix initialization of struct cfg80211_inform_bss + variable + +This patch fixes a sparse warning "Using plain integer as NULL pointer" +about cfg80211_inform_bss structure initialization. + +Reported-by: kbuild test robot +Reviewed-by: Arend van Spriel +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2737,7 +2737,7 @@ static s32 brcmf_inform_single_bss(struc + u16 notify_interval; + u8 *notify_ie; + size_t notify_ielen; +- struct cfg80211_inform_bss bss_data = { 0 }; ++ struct cfg80211_inform_bss bss_data = {}; + + if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) { + brcmf_err("Bss info is larger than buffer. Discarding\n"); diff --git a/root/package/kernel/mac80211/patches/334-v4.18-0001-brcmfmac-add-debugfs-entry-for-reading-firmware-capa.patch b/root/package/kernel/mac80211/patches/334-v4.18-0001-brcmfmac-add-debugfs-entry-for-reading-firmware-capa.patch new file mode 100644 index 00000000..f350d1e8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/334-v4.18-0001-brcmfmac-add-debugfs-entry-for-reading-firmware-capa.patch @@ -0,0 +1,75 @@ +From 88001968245c42c26416476bf0ef960442371605 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 14 May 2018 08:48:20 +0200 +Subject: [PATCH] brcmfmac: add debugfs entry for reading firmware capabilities +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows reading all capabilities as reported by a firmware. They are +printed using native (raw) names, just like developers like it the most. +It's how firmware reports support for various features, e.g. supported +modes, supported standards, power saving details, max BSS-es. + +Access to all that info is useful for trying new firmwares, comparing +them and debugging features AKA bugs. + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 36 ++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -165,6 +165,41 @@ static void brcmf_feat_firmware_capabili + } + } + ++/** ++ * brcmf_feat_fwcap_debugfs_read() - expose firmware capabilities to debugfs. ++ * ++ * @seq: sequence for debugfs entry. ++ * @data: raw data pointer. ++ */ ++static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); ++ struct brcmf_if *ifp = brcmf_get_ifp(bus_if->drvr, 0); ++ char caps[MAX_CAPS_BUFFER_SIZE + 1] = { }; ++ char *tmp; ++ int err; ++ ++ err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); ++ if (err) { ++ brcmf_err("could not get firmware cap (%d)\n", err); ++ return err; ++ } ++ ++ /* Put every capability in a new line */ ++ for (tmp = caps; *tmp; tmp++) { ++ if (*tmp == ' ') ++ *tmp = '\n'; ++ } ++ ++ /* Usually there is a space at the end of capabilities string */ ++ seq_printf(seq, "%s", caps); ++ /* So make sure we don't print two line breaks */ ++ if (tmp > caps && *(tmp - 1) != '\n') ++ seq_printf(seq, "\n"); ++ ++ return 0; ++} ++ + void brcmf_feat_attach(struct brcmf_pub *drvr) + { + struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); +@@ -233,6 +268,7 @@ void brcmf_feat_attach(struct brcmf_pub + void brcmf_feat_debugfs_create(struct brcmf_pub *drvr) + { + brcmf_debugfs_add_entry(drvr, "features", brcmf_feat_debugfs_read); ++ brcmf_debugfs_add_entry(drvr, "fwcap", brcmf_feat_fwcap_debugfs_read); + } + + bool brcmf_feat_is_enabled(struct brcmf_if *ifp, enum brcmf_feat_id id) diff --git a/root/package/kernel/mac80211/patches/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/root/package/kernel/mac80211/patches/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch new file mode 100644 index 00000000..a7bcfa54 --- /dev/null +++ b/root/package/kernel/mac80211/patches/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch @@ -0,0 +1,25 @@ +From: Felix Fietkau +Date: Sat, 9 Jul 2016 15:25:24 +0200 +Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx + +Should fix a few stability issues + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1394,8 +1394,12 @@ static bool ath9k_hw_set_reset(struct at + if (!AR_SREV_9100(ah)) + REG_WRITE(ah, AR_RC, 0); + +- if (AR_SREV_9100(ah)) ++ if (AR_SREV_9100(ah)) { ++ /* Reset the AHB-WMAC interface */ ++ if (ah->external_reset) ++ ah->external_reset(); + udelay(50); ++ } + + return true; + } diff --git a/root/package/kernel/mac80211/patches/351-ath9k_hw-issue-external-reset-for-QCA955x.patch b/root/package/kernel/mac80211/patches/351-ath9k_hw-issue-external-reset-for-QCA955x.patch new file mode 100644 index 00000000..5eb69b89 --- /dev/null +++ b/root/package/kernel/mac80211/patches/351-ath9k_hw-issue-external-reset-for-QCA955x.patch @@ -0,0 +1,129 @@ +From: Felix Fietkau +Date: Sat, 9 Jul 2016 15:26:44 +0200 +Subject: [PATCH] ath9k_hw: issue external reset for QCA955x + +The RTC interface on the SoC needs to be reset along with the rest of +the WMAC. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1271,39 +1271,56 @@ void ath9k_hw_get_delta_slope_vals(struc + *coef_exponent = coef_exp - 16; + } + +-/* AR9330 WAR: +- * call external reset function to reset WMAC if: +- * - doing a cold reset +- * - we have pending frames in the TX queues. +- */ +-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type) ++static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type) + { +- int i, npend = 0; ++ int i; + +- for (i = 0; i < AR_NUM_QCU; i++) { +- npend = ath9k_hw_numtxpending(ah, i); +- if (npend) +- break; +- } +- +- if (ah->external_reset && +- (npend || type == ATH9K_RESET_COLD)) { +- int reset_err = 0; +- +- ath_dbg(ath9k_hw_common(ah), RESET, +- "reset MAC via external reset\n"); +- +- reset_err = ah->external_reset(); +- if (reset_err) { +- ath_err(ath9k_hw_common(ah), +- "External reset failed, err=%d\n", +- reset_err); +- return false; ++ if (type == ATH9K_RESET_COLD) ++ return true; ++ ++ if (AR_SREV_9550(ah)) ++ return true; ++ ++ /* AR9330 WAR: ++ * call external reset function to reset WMAC if: ++ * - doing a cold reset ++ * - we have pending frames in the TX queues. ++ */ ++ if (AR_SREV_9330(ah)) { ++ for (i = 0; i < AR_NUM_QCU; i++) { ++ if (ath9k_hw_numtxpending(ah, i)) ++ return true; + } ++ } ++ ++ return false; ++} ++ ++static bool ath9k_hw_external_reset(struct ath_hw *ah, int type) ++{ ++ int err; ++ ++ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type)) ++ return true; ++ ++ ath_dbg(ath9k_hw_common(ah), RESET, ++ "reset MAC via external reset\n"); + +- REG_WRITE(ah, AR_RTC_RESET, 1); ++ err = ah->external_reset(); ++ if (err) { ++ ath_err(ath9k_hw_common(ah), ++ "External reset failed, err=%d\n", err); ++ return false; + } + ++ if (AR_SREV_9550(ah)) { ++ REG_WRITE(ah, AR_RTC_RESET, 0); ++ udelay(10); ++ } ++ ++ REG_WRITE(ah, AR_RTC_RESET, 1); ++ udelay(10); ++ + return true; + } + +@@ -1356,24 +1373,24 @@ static bool ath9k_hw_set_reset(struct at + rst_flags |= AR_RTC_RC_MAC_COLD; + } + +- if (AR_SREV_9330(ah)) { +- if (!ath9k_hw_ar9330_reset_war(ah, type)) +- return false; +- } +- + if (ath9k_hw_mci_is_enabled(ah)) + ar9003_mci_check_gpm_offset(ah); + + /* DMA HALT added to resolve ar9300 and ar9580 bus error during +- * RTC_RC reg read ++ * RTC_RC reg read. Also needed for AR9550 external reset + */ +- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) { ++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { + REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); + ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK, + 20 * AH_WAIT_TIMEOUT); +- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); + } + ++ if (!AR_SREV_9100(ah)) ++ ath9k_hw_external_reset(ah, type); ++ ++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) ++ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); ++ + REG_WRITE(ah, AR_RTC_RC, rst_flags); + + REGWRITE_BUFFER_FLUSH(ah); diff --git a/root/package/kernel/mac80211/patches/352-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch b/root/package/kernel/mac80211/patches/352-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch new file mode 100644 index 00000000..dfe9aae2 --- /dev/null +++ b/root/package/kernel/mac80211/patches/352-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Mon, 11 Jul 2016 12:07:40 +0200 +Subject: [PATCH] ath9k_hw: set spectral scan enable bit on trigger for + AR9003+ + +AR9002 code and QCA AR9003+ code do the same. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1800,6 +1800,8 @@ static void ar9003_hw_spectral_scan_conf + + static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah) + { ++ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, ++ AR_PHY_SPECTRAL_SCAN_ENABLE); + /* Activate spectral scan */ + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, + AR_PHY_SPECTRAL_SCAN_ACTIVE); diff --git a/root/package/kernel/mac80211/patches/353-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch b/root/package/kernel/mac80211/patches/353-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch new file mode 100644 index 00000000..22f51541 --- /dev/null +++ b/root/package/kernel/mac80211/patches/353-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch @@ -0,0 +1,27 @@ +From: Felix Fietkau +Date: Tue, 27 Dec 2016 23:16:23 +0100 +Subject: [PATCH] ath9k: don't run periodic and nf calibation at the same + time + +The checks already prevents periodic cal from being started while noise +floor calibration runs. It is missing checks for the other way around. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c +@@ -676,10 +676,10 @@ static int ar9002_hw_calibrate(struct at + return 0; + + ah->cal_list_curr = currCal = currCal->calNext; +- if (currCal->calState == CAL_WAITING) { ++ if (currCal->calState == CAL_WAITING) + ath9k_hw_reset_calibration(ah, currCal); +- return 0; +- } ++ ++ return 0; + } + + /* Do NF cal only at longer intervals */ diff --git a/root/package/kernel/mac80211/patches/354-ath9k-force-rx_clear-when-disabling-rx.patch b/root/package/kernel/mac80211/patches/354-ath9k-force-rx_clear-when-disabling-rx.patch new file mode 100644 index 00000000..8aaccf49 --- /dev/null +++ b/root/package/kernel/mac80211/patches/354-ath9k-force-rx_clear-when-disabling-rx.patch @@ -0,0 +1,35 @@ +From: Felix Fietkau +Date: Sun, 7 Jun 2015 13:53:35 +0200 +Subject: [PATCH] ath9k: force rx_clear when disabling rx + +This makes stopping Rx more reliable and should reduce the frequency of +Rx related DMA stop warnings. Don't use rx_clear in TX99 mode. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Helmut Schaa +--- + +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -678,13 +678,18 @@ void ath9k_hw_startpcureceive(struct ath + + ath9k_ani_reset(ah, is_scanning); + +- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); ++ REG_CLR_BIT(ah, AR_DIAG_SW, ++ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); + } + EXPORT_SYMBOL(ath9k_hw_startpcureceive); + + void ath9k_hw_abortpcurecv(struct ath_hw *ah) + { +- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); ++ u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT; ++ ++ if (!IS_ENABLED(CPTCFG_ATH9K_TX99)) ++ reg |= AR_DIAG_FORCE_RX_CLEAR; ++ REG_SET_BIT(ah, AR_DIAG_SW, reg); + + ath9k_hw_disable_mib_counters(ah); + } diff --git a/root/package/kernel/mac80211/patches/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/root/package/kernel/mac80211/patches/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch new file mode 100644 index 00000000..35d07430 --- /dev/null +++ b/root/package/kernel/mac80211/patches/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch @@ -0,0 +1,37 @@ +From: Felix Fietkau +Date: Sat, 14 May 2016 14:51:02 +0200 +Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP + domain" + +This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2935,7 +2935,8 @@ void ath9k_hw_apply_txpower(struct ath_h + { + struct ath_regulatory *reg = ath9k_hw_regulatory(ah); + struct ieee80211_channel *channel; +- int chan_pwr, new_pwr; ++ int chan_pwr, new_pwr, max_gain; ++ int ant_gain, ant_reduction = 0; + + if (!chan) + return; +@@ -2943,10 +2944,15 @@ void ath9k_hw_apply_txpower(struct ath_h + channel = chan->chan; + chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); + new_pwr = min_t(int, chan_pwr, reg->power_limit); ++ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; ++ ++ ant_gain = get_antenna_gain(ah, chan); ++ if (ant_gain > max_gain) ++ ant_reduction = ant_gain - max_gain; + + ah->eep_ops->set_txpower(ah, chan, + ath9k_regd_get_ctl(reg, chan), +- get_antenna_gain(ah, chan), new_pwr, test); ++ ant_reduction, new_pwr, test); + } + + void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) diff --git a/root/package/kernel/mac80211/patches/357-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/root/package/kernel/mac80211/patches/357-mac80211-add-hdrlen-to-ieee80211_tx_data.patch new file mode 100644 index 00000000..83c61343 --- /dev/null +++ b/root/package/kernel/mac80211/patches/357-mac80211-add-hdrlen-to-ieee80211_tx_data.patch @@ -0,0 +1,219 @@ +From: Janusz Dziedzic +Date: Fri, 19 Feb 2016 11:01:49 +0100 +Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data + +Add hdrlen to ieee80211_tx_data and use this +when wep/ccmd/tkip. This is preparation for +aligned4 code. + +Signed-off-by: Janusz Dziedzic +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -177,6 +177,7 @@ struct ieee80211_tx_data { + struct ieee80211_tx_rate rate; + + unsigned int flags; ++ unsigned int hdrlen; + }; + + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -921,7 +921,7 @@ ieee80211_tx_h_fragment(struct ieee80211 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + int frag_threshold = tx->local->hw.wiphy->frag_threshold; +- int hdrlen; ++ int hdrlen = tx->hdrlen; + int fragnum; + + /* no matter what happens, tx->skb moves to tx->skbs */ +@@ -942,8 +942,6 @@ ieee80211_tx_h_fragment(struct ieee80211 + if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- + /* internal error, why isn't DONTFRAG set? */ + if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) + return TX_DROP; +@@ -1175,6 +1173,8 @@ ieee80211_tx_prepare(struct ieee80211_su + + hdr = (struct ieee80211_hdr *) skb->data; + ++ tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ + if (likely(sta)) { + if (!IS_ERR(sta)) + tx->sta = sta; +@@ -3468,6 +3468,7 @@ begin: + tx.local = local; + tx.skb = skb; + tx.sdata = vif_to_sdata(info->control.vif); ++ tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); + + if (txq->sta) + tx.sta = container_of(txq->sta, struct sta_info, sta); +@@ -3796,6 +3797,7 @@ ieee80211_build_data_template(struct iee + hdr = (void *)skb->data; + tx.sta = sta_info_get(sdata, hdr->addr1); + tx.skb = skb; ++ tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control); + + if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { + rcu_read_unlock(); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1232,6 +1232,7 @@ void ieee80211_send_auth(struct ieee8021 + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; ++ unsigned int hdrlen; + int err; + + /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ +@@ -1255,8 +1256,10 @@ void ieee80211_send_auth(struct ieee8021 + skb_put_data(skb, extra, extra_len); + + if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { ++ hdrlen = ieee80211_hdrlen(mgmt->frame_control); + mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +- err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); ++ err = ieee80211_wep_encrypt(local, skb, hdrlen, key, ++ key_len, key_idx); + WARN_ON(err); + } + +--- a/net/mac80211/wep.c ++++ b/net/mac80211/wep.c +@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct + + static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + int keylen, int keyidx) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- unsigned int hdrlen; + u8 *newhdr; + + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i + if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) + return NULL; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); + newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN); + memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen); + +@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr + */ + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx) + { + u8 *iv; +@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802 + if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN)) + return -1; + +- iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); ++ iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx); + if (!iv) + return -1; + +@@ -307,13 +307,14 @@ static int wep_encrypt_skb(struct ieee80 + struct ieee80211_key_conf *hw_key = info->control.hw_key; + + if (!hw_key) { +- if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, ++ if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen, ++ tx->key->conf.key, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; + } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) || + (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { +- if (!ieee80211_wep_add_iv(tx->local, skb, ++ if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; +--- a/net/mac80211/wep.h ++++ b/net/mac80211/wep.h +@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr + size_t klen, u8 *data, size_t data_len); + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx); + int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, + size_t klen, u8 *data, size_t data_len); +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -44,7 +44,7 @@ ieee80211_tx_h_michael_mic_add(struct ie + skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) + return TX_CONTINUE; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + if (skb->len < hdrlen) + return TX_DROP; + +@@ -187,7 +187,6 @@ mic_fail_no_key: + + static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + unsigned int hdrlen; +@@ -202,7 +201,7 @@ static int tkip_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -420,7 +419,7 @@ static int ccmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -653,7 +652,7 @@ static int gcmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -793,7 +792,6 @@ static ieee80211_tx_result + ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, + struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + int hdrlen; +@@ -809,8 +807,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8 + pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC))) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- ++ hdrlen = tx->hdrlen; + pos = skb_push(skb, iv_len); + memmove(pos, pos + iv_len, hdrlen); + diff --git a/root/package/kernel/mac80211/patches/358-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch b/root/package/kernel/mac80211/patches/358-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch new file mode 100644 index 00000000..a9f01b36 --- /dev/null +++ b/root/package/kernel/mac80211/patches/358-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch @@ -0,0 +1,233 @@ +From: Janusz Dziedzic +Date: Fri, 19 Feb 2016 11:01:50 +0100 +Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag + +HW/driver should set NEED_ALIGNED4_SKBS flag in case +require aligned skbs to four-byte boundaries. +This affect only TX direction. + +Padding is added after ieee80211_hdr, before IV/LLC. + +Before we have to do memmove(hdrlen) twice in the +dirver. Once before we pass this to HW and next +in tx completion (to be sure monitor will report +this tx frame correctly). + +With this patch we can skip this memmove() and save CPU. + +Currently this was tested with ath9k, both hw/sw crypt for +wep/tkip/ccmp. + +Signed-off-by: Janusz Dziedzic +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2059,6 +2059,9 @@ struct ieee80211_txq { + * @IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA: Hardware supports buffer STA on + * TDLS links. + * ++ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte. ++ * Padding will be added after ieee80211_hdr, before IV/LLC. ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2102,6 +2105,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_REPORTS_LOW_ACK, + IEEE80211_HW_SUPPORTS_TX_FRAG, + IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, ++ IEEE80211_HW_NEEDS_ALIGNED4_SKBS, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -212,6 +212,7 @@ static const char *hw_flag_names[] = { + FLAG(REPORTS_LOW_ACK), + FLAG(SUPPORTS_TX_FRAG), + FLAG(SUPPORTS_TDLS_BUFFER_STA), ++ FLAG(NEEDS_ALIGNED4_SKBS), + #undef FLAG + }; + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1548,6 +1548,29 @@ ieee80211_vif_get_num_mcast_if(struct ie + return -1; + } + ++static inline unsigned int ++ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen) ++{ ++ /* ++ * While hdrlen is already aligned to two-byte boundaries, ++ * simple check with & 2 will return correct padsize. ++ */ ++ if (ieee80211_hw_check(hw, NEEDS_ALIGNED4_SKBS)) ++ return hdrlen & 2; ++ return 0; ++} ++ ++static inline unsigned int ++ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc) ++{ ++ unsigned int hdrlen; ++ ++ hdrlen = ieee80211_hdrlen(fc); ++ hdrlen += ieee80211_hdr_padsize(hw, hdrlen); ++ ++ return hdrlen; ++} ++ + u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, + struct ieee80211_rx_status *status, + unsigned int mpdu_len, +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -300,7 +300,7 @@ struct ieee80211_fast_tx { + u8 hdr_len; + u8 sa_offs, da_offs, pn_offs; + u8 band; +- u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + ++ u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV + + sizeof(rfc1042_header)] __aligned(2); + + struct rcu_head rcu_head; +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -642,9 +642,22 @@ void ieee80211_tx_monitor(struct ieee802 + struct sk_buff *skb2; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_hdr *hdr = (void *)skb->data; + struct net_device *prev_dev = NULL; ++ unsigned int hdrlen, padsize; + int rtap_len; + ++ /* Remove padding if was added */ ++ if (ieee80211_hw_check(&local->hw, NEEDS_ALIGNED4_SKBS)) { ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); ++ ++ if (padsize && skb->len > hdrlen + padsize) { ++ memmove(skb->data + padsize, skb->data, hdrlen); ++ skb_pull(skb, padsize); ++ } ++ } ++ + /* send frame to monitor interfaces now */ + rtap_len = ieee80211_tx_radiotap_len(info); + if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { +--- a/net/mac80211/tkip.c ++++ b/net/mac80211/tkip.c +@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8 + { + struct ieee80211_key *key = (struct ieee80211_key *) + container_of(keyconf, struct ieee80211_key, conf); ++ struct ieee80211_hw *hw = &key->local->hw; + const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; + struct tkip_ctx *ctx = &key->u.tkip.tx; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +- const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); ++ const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw, ++ hdr->frame_control); + u32 iv32 = get_unaligned_le32(&data[4]); + u16 iv16 = data[2] | (data[0] << 8); + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1172,8 +1172,7 @@ ieee80211_tx_prepare(struct ieee80211_su + info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING; + + hdr = (struct ieee80211_hdr *) skb->data; +- +- tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (likely(sta)) { + if (!IS_ERR(sta)) +@@ -2184,7 +2183,7 @@ netdev_tx_t ieee80211_monitor_start_xmit + goto fail; + + hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (skb->len < len_rthdr + hdrlen) + goto fail; +@@ -2402,7 +2401,7 @@ static struct sk_buff *ieee80211_build_h + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_sub_if_data *ap_sdata; + enum nl80211_band band; +- int ret; ++ int padsize, ret; + + if (IS_ERR(sta)) + sta = NULL; +@@ -2622,6 +2621,9 @@ static struct sk_buff *ieee80211_build_h + hdrlen += 2; + } + ++ /* Check aligned4 skb required */ ++ padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen); ++ + /* + * Drop unicast frames to unauthorised stations unless they are + * EAPOL frames from the local station. +@@ -2702,6 +2704,7 @@ static struct sk_buff *ieee80211_build_h + + skb_pull(skb, skip_header_bytes); + head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); ++ head_need += padsize; + + /* + * So we need to modify the skb header and hence need a copy of +@@ -2734,6 +2737,9 @@ static struct sk_buff *ieee80211_build_h + memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); + #endif + ++ if (padsize) ++ memset(skb_push(skb, padsize), 0, padsize); ++ + if (ieee80211_is_data_qos(fc)) { + __le16 *qos_control; + +@@ -2909,6 +2915,9 @@ void ieee80211_check_fast_xmit(struct st + fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + } + ++ /* Check aligned4 skb required */ ++ build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len); ++ + /* We store the key here so there's no point in using rcu_dereference() + * but that's fine because the code that changes the pointers will call + * this function after doing so. For a single CPU that would be enough, +@@ -3495,7 +3504,7 @@ begin: + + if (tx.key && + (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) +- pn_offs = ieee80211_hdrlen(hdr->frame_control); ++ pn_offs = tx.hdrlen; + + ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, + tx.key, skb); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1230,6 +1230,7 @@ void ieee80211_send_auth(struct ieee8021 + u32 tx_flags) + { + struct ieee80211_local *local = sdata->local; ++ struct ieee80211_hw *hw = &local->hw; + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; + unsigned int hdrlen; +@@ -1256,7 +1257,7 @@ void ieee80211_send_auth(struct ieee8021 + skb_put_data(skb, extra, extra_len); + + if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { +- hdrlen = ieee80211_hdrlen(mgmt->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control); + mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); + err = ieee80211_wep_encrypt(local, skb, hdrlen, key, + key_len, key_idx); diff --git a/root/package/kernel/mac80211/patches/359-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/root/package/kernel/mac80211/patches/359-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch new file mode 100644 index 00000000..609b15b8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/359-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch @@ -0,0 +1,82 @@ +From: Chaitanya T K +Date: Mon, 27 Jun 2016 15:23:26 +0530 +Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates + +If peer support reception of STBC and LDPC, enable them for better +performance. + +Signed-off-by: Chaitanya TK +--- + +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -1556,6 +1556,7 @@ struct ieee80211_vht_operation { + #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 + #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 + #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 ++#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8 + #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 + #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 + #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13 +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, stru + struct minstrel_ht_sta_priv *msp = priv_sta; + struct minstrel_ht_sta *mi = &msp->ht; + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; +- u16 sta_cap = sta->ht_cap.cap; ++ u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct sta_info *sinfo = container_of(sta, struct sta_info, sta); + int use_vht; +@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, stru + int ack_dur; + int stbc; + int i; ++ bool ldpc = false; + + /* fall back to the old minstrel for legacy stations */ + if (!sta->ht_cap.ht_supported) +@@ -1175,16 +1176,24 @@ minstrel_ht_update_caps(void *priv, stru + } + mi->sample_tries = 4; + +- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ + if (!use_vht) { +- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> ++ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >> + IEEE80211_HT_CAP_RX_STBC_SHIFT; +- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; + +- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) +- mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING) ++ ldpc = true; ++ } else { ++ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> ++ IEEE80211_VHT_CAP_RXSTBC_SHIFT; ++ ++ if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC) ++ ldpc = true; + } + ++ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; ++ if (ldpc) ++ mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ + for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { + u32 gflags = minstrel_mcs_groups[i].flags; + int bw, nss; +@@ -1197,10 +1206,10 @@ minstrel_ht_update_caps(void *priv, stru + + if (gflags & IEEE80211_TX_RC_SHORT_GI) { + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40)) + continue; + } else { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20)) + continue; + } + } diff --git a/root/package/kernel/mac80211/patches/360-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch b/root/package/kernel/mac80211/patches/360-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch new file mode 100644 index 00000000..d651e6ce --- /dev/null +++ b/root/package/kernel/mac80211/patches/360-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch @@ -0,0 +1,50 @@ +From: Felix Fietkau +Date: Sun, 28 Aug 2016 13:13:01 +0200 +Subject: [PATCH] ath9k: fix moredata bit in PS buffered frame release + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1659,6 +1659,22 @@ void ath_tx_aggr_wakeup(struct ath_softc + } + } + ++ ++static void ++ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val) ++{ ++ struct ieee80211_hdr *hdr; ++ u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA); ++ u16 mask_val = mask * val; ++ ++ hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; ++ if ((hdr->frame_control & mask) != mask_val) { ++ hdr->frame_control = (hdr->frame_control & ~mask) | mask_val; ++ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, ++ sizeof(*hdr), DMA_TO_DEVICE); ++ } ++} ++ + void ath9k_release_buffered_frames(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u16 tids, int nframes, +@@ -1689,6 +1705,7 @@ void ath9k_release_buffered_frames(struc + if (!bf) + break; + ++ ath9k_set_moredata(sc, bf, true); + list_add_tail(&bf->list, &bf_q); + ath_set_rates(tid->an->vif, tid->an->sta, bf); + if (bf_isampdu(bf)) { +@@ -1712,6 +1729,9 @@ void ath9k_release_buffered_frames(struc + if (list_empty(&bf_q)) + return; + ++ if (!more_data) ++ ath9k_set_moredata(sc, bf_tail, false); ++ + info = IEEE80211_SKB_CB(bf_tail->bf_mpdu); + info->flags |= IEEE80211_TX_STATUS_EOSP; + diff --git a/root/package/kernel/mac80211/patches/361-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch b/root/package/kernel/mac80211/patches/361-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch new file mode 100644 index 00000000..319de2a7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/361-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch @@ -0,0 +1,22 @@ +From: Felix Fietkau +Date: Sun, 28 Aug 2016 13:13:42 +0200 +Subject: [PATCH] ath9k: clear potentially stale EOSP status bit in + intermediate queues + +Prevents spurious ieee80211_sta_eosp calls. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -969,7 +969,8 @@ ath_tx_get_tid_subframe(struct ath_softc + bf->bf_lastbf = bf; + + tx_info = IEEE80211_SKB_CB(skb); +- tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; ++ tx_info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | ++ IEEE80211_TX_STATUS_EOSP); + + /* + * No aggregation session is running, but there may be frames diff --git a/root/package/kernel/mac80211/patches/362-ath9k-report-tx-status-on-EOSP.patch b/root/package/kernel/mac80211/patches/362-ath9k-report-tx-status-on-EOSP.patch new file mode 100644 index 00000000..80a3074a --- /dev/null +++ b/root/package/kernel/mac80211/patches/362-ath9k-report-tx-status-on-EOSP.patch @@ -0,0 +1,19 @@ +From: Felix Fietkau +Date: Sun, 28 Aug 2016 13:23:27 +0200 +Subject: [PATCH] ath9k: report tx status on EOSP + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -86,7 +86,8 @@ static void ath_tx_status(struct ieee802 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sta *sta = info->status.status_driver_data[0]; + +- if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { ++ if (info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | ++ IEEE80211_TX_STATUS_EOSP)) { + ieee80211_tx_status(hw, skb); + return; + } diff --git a/root/package/kernel/mac80211/patches/363-ath9k-fix-block-ack-window-tracking-issues.patch b/root/package/kernel/mac80211/patches/363-ath9k-fix-block-ack-window-tracking-issues.patch new file mode 100644 index 00000000..e25e92dd --- /dev/null +++ b/root/package/kernel/mac80211/patches/363-ath9k-fix-block-ack-window-tracking-issues.patch @@ -0,0 +1,114 @@ +From: Felix Fietkau +Date: Tue, 30 Aug 2016 12:44:08 +0200 +Subject: [PATCH] ath9k: fix block-ack window tracking issues + +Ensure that a buffer gets tracked as part of the block-ack window as +soon as it's dequeued from the tid for the first time. Ensure that +double calls to ath_tx_addto_baw (e.g. on retransmission) don't cause +any issues. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -62,7 +62,7 @@ static void ath_tx_rc_status(struct ath_ + struct ath_tx_status *ts, int nframes, int nbad, + int txok); + static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, +- int seqno); ++ struct ath_buf *bf); + static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, + struct ath_txq *txq, + struct ath_atx_tid *tid, +@@ -296,7 +296,7 @@ static void ath_tx_flush_tid(struct ath_ + } + + if (fi->baw_tracked) { +- ath_tx_update_baw(sc, tid, bf->bf_state.seqno); ++ ath_tx_update_baw(sc, tid, bf); + sendbar = true; + } + +@@ -312,10 +312,15 @@ static void ath_tx_flush_tid(struct ath_ + } + + static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, +- int seqno) ++ struct ath_buf *bf) + { ++ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); ++ u16 seqno = bf->bf_state.seqno; + int index, cindex; + ++ if (!fi->baw_tracked) ++ return; ++ + index = ATH_BA_INDEX(tid->seq_start, seqno); + cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); + +@@ -336,6 +341,9 @@ static void ath_tx_addto_baw(struct ath_ + u16 seqno = bf->bf_state.seqno; + int index, cindex; + ++ if (fi->baw_tracked) ++ return; ++ + index = ATH_BA_INDEX(tid->seq_start, seqno); + cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); + __set_bit(cindex, tid->tx_buf); +@@ -612,7 +620,7 @@ static void ath_tx_complete_aggr(struct + * complete the acked-ones/xretried ones; update + * block-ack window + */ +- ath_tx_update_baw(sc, tid, seqno); ++ ath_tx_update_baw(sc, tid, bf); + + if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { + memcpy(tx_info->control.rates, rates, sizeof(rates)); +@@ -642,7 +650,7 @@ static void ath_tx_complete_aggr(struct + * run out of tx buf. + */ + if (!tbf) { +- ath_tx_update_baw(sc, tid, seqno); ++ ath_tx_update_baw(sc, tid, bf); + + ath_tx_complete_buf(sc, bf, txq, + &bf_head, NULL, ts, +@@ -1011,11 +1019,14 @@ ath_tx_get_tid_subframe(struct ath_softc + + INIT_LIST_HEAD(&bf_head); + list_add(&bf->list, &bf_head); +- ath_tx_update_baw(sc, tid, seqno); ++ ath_tx_update_baw(sc, tid, bf); + ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); + continue; + } + ++ if (bf_isampdu(bf)) ++ ath_tx_addto_baw(sc, tid, bf); ++ + return bf; + } + +@@ -1073,8 +1084,6 @@ ath_tx_form_aggr(struct ath_softc *sc, s + bf->bf_next = NULL; + + /* link buffers of this frame to the aggregate */ +- if (!fi->baw_tracked) +- ath_tx_addto_baw(sc, tid, bf); + bf->bf_state.ndelim = ndelim; + + list_add_tail(&bf->list, bf_q); +@@ -1710,10 +1719,8 @@ void ath9k_release_buffered_frames(struc + ath9k_set_moredata(sc, bf, true); + list_add_tail(&bf->list, &bf_q); + ath_set_rates(tid->an->vif, tid->an->sta, bf); +- if (bf_isampdu(bf)) { +- ath_tx_addto_baw(sc, tid, bf); ++ if (bf_isampdu(bf)) + bf->bf_state.bf_type &= ~BUF_AGGR; +- } + if (bf_tail) + bf_tail->bf_next = bf; + diff --git a/root/package/kernel/mac80211/patches/364-ath9k_hw-fix-channel-maximum-power-level-test.patch b/root/package/kernel/mac80211/patches/364-ath9k_hw-fix-channel-maximum-power-level-test.patch new file mode 100644 index 00000000..67cbe92e --- /dev/null +++ b/root/package/kernel/mac80211/patches/364-ath9k_hw-fix-channel-maximum-power-level-test.patch @@ -0,0 +1,47 @@ +From: Felix Fietkau +Date: Wed, 22 Mar 2017 20:37:04 +0100 +Subject: [PATCH] ath9k_hw: fix channel maximum power level test + +The tx power applied by set_txpower is limited by the CTL (conformance +test limit) entries in the EEPROM. These can change based on the user +configured regulatory domain. +Depending on the EEPROM data this can cause the tx power to become too +limited, if the original regdomain CTLs impose lowr limits than the CTLs +of the user configured regdomain. + +To fix this issue, set the initial channel limits without any CTL +restrictions and only apply the CTL at run time when setting the channel +and the real tx power. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2937,10 +2937,14 @@ void ath9k_hw_apply_txpower(struct ath_h + struct ieee80211_channel *channel; + int chan_pwr, new_pwr, max_gain; + int ant_gain, ant_reduction = 0; ++ u16 ctl = NO_CTL; + + if (!chan) + return; + ++ if (!test) ++ ctl = ath9k_regd_get_ctl(reg, chan); ++ + channel = chan->chan; + chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); + new_pwr = min_t(int, chan_pwr, reg->power_limit); +@@ -2950,9 +2954,7 @@ void ath9k_hw_apply_txpower(struct ath_h + if (ant_gain > max_gain) + ant_reduction = ant_gain - max_gain; + +- ah->eep_ops->set_txpower(ah, chan, +- ath9k_regd_get_ctl(reg, chan), +- ant_reduction, new_pwr, test); ++ ah->eep_ops->set_txpower(ah, chan, ctl, ant_reduction, new_pwr, test); + } + + void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) diff --git a/root/package/kernel/mac80211/patches/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/root/package/kernel/mac80211/patches/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch new file mode 100644 index 00000000..78083517 --- /dev/null +++ b/root/package/kernel/mac80211/patches/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch @@ -0,0 +1,24 @@ +From: Felix Fietkau +Date: Wed, 19 Jul 2017 08:49:31 +0200 +Subject: [PATCH] ath9k: adjust tx power reduction for US regulatory + domain + +FCC regulatory rules allow for up to 3 dBi antenna gain. Account for +this in the EEPROM based tx power reduction code. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2954,6 +2954,10 @@ void ath9k_hw_apply_txpower(struct ath_h + if (ant_gain > max_gain) + ant_reduction = ant_gain - max_gain; + ++ /* FCC allows maximum antenna gain of 3 dBi */ ++ if (reg->region == NL80211_DFS_FCC) ++ ant_reduction = max_t(int, ant_reduction - 6, 0); ++ + ah->eep_ops->set_txpower(ah, chan, ctl, ant_reduction, new_pwr, test); + } + diff --git a/root/package/kernel/mac80211/patches/366-ath9k-fix-more-data-flag-for-buffered-multicast-pack.patch b/root/package/kernel/mac80211/patches/366-ath9k-fix-more-data-flag-for-buffered-multicast-pack.patch new file mode 100644 index 00000000..0f3120d6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/366-ath9k-fix-more-data-flag-for-buffered-multicast-pack.patch @@ -0,0 +1,41 @@ +From: Felix Fietkau +Date: Sun, 23 Jul 2017 14:58:22 +0200 +Subject: [PATCH] ath9k: fix more-data flag for buffered multicast + packets + +The flag needs to be cleared for the last packet in the list, not the +first one. Fixes some issues with multicast packet loss for powersave +clients connected to an ath9k AP. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2436,7 +2436,6 @@ void ath_tx_cabq(struct ieee80211_hw *hw + .txq = sc->beacon.cabq + }; + struct ath_tx_info info = {}; +- struct ieee80211_hdr *hdr; + struct ath_buf *bf_tail = NULL; + struct ath_buf *bf; + LIST_HEAD(bf_q); +@@ -2480,15 +2479,10 @@ void ath_tx_cabq(struct ieee80211_hw *hw + if (list_empty(&bf_q)) + return; + +- bf = list_first_entry(&bf_q, struct ath_buf, list); +- hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; +- +- if (hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) { +- hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA); +- dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, +- sizeof(*hdr), DMA_TO_DEVICE); +- } ++ bf = list_last_entry(&bf_q, struct ath_buf, list); ++ ath9k_set_moredata(sc, bf, false); + ++ bf = list_first_entry(&bf_q, struct ath_buf, list); + ath_txq_lock(sc, txctl.txq); + ath_tx_fill_desc(sc, bf, txctl.txq, 0); + ath_tx_txqaddbuf(sc, txctl.txq, &bf_q, false); diff --git a/root/package/kernel/mac80211/patches/367-Revert-ath10k-disable-wake_tx_queue-for-older-device.patch b/root/package/kernel/mac80211/patches/367-Revert-ath10k-disable-wake_tx_queue-for-older-device.patch new file mode 100644 index 00000000..56d86c15 --- /dev/null +++ b/root/package/kernel/mac80211/patches/367-Revert-ath10k-disable-wake_tx_queue-for-older-device.patch @@ -0,0 +1,27 @@ +From: dave taht +Date: Wed, 5 Oct 2016 20:09:15 -0700 +Subject: [PATCH] Revert "ath10k: disable wake_tx_queue for older + devices" + +This reverts commit 4ca1807815aa6801aaced7fdefa9edacc2521767 +in the hope that we've fixed all the performance problems now. +--- + +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -8319,15 +8319,6 @@ int ath10k_mac_register(struct ath10k *a + ath10k_warn(ar, "failed to initialise DFS pattern detector\n"); + } + +- /* Current wake_tx_queue implementation imposes a significant +- * performance penalty in some setups. The tx scheduling code needs +- * more work anyway so disable the wake_tx_queue unless firmware +- * supports the pull-push mechanism. +- */ +- if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, +- ar->running_fw->fw_file.fw_features)) +- ar->ops->wake_tx_queue = NULL; +- + ret = ath10k_mac_init_rd(ar); + if (ret) { + ath10k_err(ar, "failed to derive regdom: %d\n", ret); diff --git a/root/package/kernel/mac80211/patches/368-ath10k-fix-recent-bandwidth-conversion-bug.patch b/root/package/kernel/mac80211/patches/368-ath10k-fix-recent-bandwidth-conversion-bug.patch new file mode 100644 index 00000000..5d5329f2 --- /dev/null +++ b/root/package/kernel/mac80211/patches/368-ath10k-fix-recent-bandwidth-conversion-bug.patch @@ -0,0 +1,61 @@ +From: Christian Lamparter +Date: Wed, 1 Nov 2017 21:01:57 +0100 +Subject: [PATCH] ath10k: fix recent bandwidth conversion bug + +The commit "cfg80211: make RATE_INFO_BW_20 the default" changed +the index of RATE_INFO_BW_20, but the updates to ath10k missed +the special bandwidth calculation case in +ath10k_update_per_peer_tx_stats(). + +Fixes: 842be75c77cb ("cfg80211: make RATE_INFO_BW_20 the default") +Signed-off-by: Christian Lamparter +Patchwork-Id: 10037035 +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -592,6 +592,9 @@ struct amsdu_subframe_hdr { + + #define GROUP_ID_IS_SU_MIMO(x) ((x) == 0 || (x) == 63) + ++static const u8 ath10k_bw_to_mac80211[] = { RATE_INFO_BW_20, RATE_INFO_BW_40, ++ RATE_INFO_BW_80, RATE_INFO_BW_160 }; ++ + static void ath10k_htt_rx_h_rates(struct ath10k *ar, + struct ieee80211_rx_status *status, + struct htt_rx_desc *rxd) +@@ -694,23 +697,7 @@ static void ath10k_htt_rx_h_rates(struct + if (sgi) + status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + +- switch (bw) { +- /* 20MHZ */ +- case 0: +- break; +- /* 40MHZ */ +- case 1: +- status->bw = RATE_INFO_BW_40; +- break; +- /* 80MHZ */ +- case 2: +- status->bw = RATE_INFO_BW_80; +- break; +- case 3: +- status->bw = RATE_INFO_BW_160; +- break; +- } +- ++ status->bw = ath10k_bw_to_mac80211[bw]; + status->encoding = RX_ENC_VHT; + break; + default: +@@ -2297,7 +2284,7 @@ ath10k_update_per_peer_tx_stats(struct a + arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + + arsta->txrate.nss = txrate.nss; +- arsta->txrate.bw = txrate.bw + RATE_INFO_BW_20; ++ arsta->txrate.bw = ath10k_bw_to_mac80211[txrate.bw]; + } + + static void ath10k_htt_fetch_peer_stats(struct ath10k *ar, diff --git a/root/package/kernel/mac80211/patches/369-cfg80211-use-only-1Mbps-for-basic-rates-in-mesh.patch b/root/package/kernel/mac80211/patches/369-cfg80211-use-only-1Mbps-for-basic-rates-in-mesh.patch new file mode 100644 index 00000000..bc4174e4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/369-cfg80211-use-only-1Mbps-for-basic-rates-in-mesh.patch @@ -0,0 +1,55 @@ +From: Johannes Berg +Date: Tue, 30 Jan 2018 13:17:38 +0100 +Subject: [PATCH] cfg80211: use only 1Mbps for basic rates in mesh + +Mesh used to use the mandatory rates as basic rates, but we got +the calculation of mandatory rates wrong until some time ago. +Fix this this broke interoperability with older versions since +now more basic rates are required, and thus the MBSS isn't the +same and the network stops working. + +Fix this by simply using only 1Mbps as the basic rate in 2.4GHz. +Since the changed mandatory rates only affected 2.4GHz, this is +all we need to make it work again. + +Reported-and-tested-by: Matthias Schiffer +Fixes: 1bd773c077de ("wireless: set correct mandatory rate flags") +Signed-off-by: Johannes Berg +--- + net/wireless/mesh.c | 25 ++++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +--- a/net/wireless/mesh.c ++++ b/net/wireless/mesh.c +@@ -169,9 +169,28 @@ int __cfg80211_join_mesh(struct cfg80211 + enum nl80211_bss_scan_width scan_width; + struct ieee80211_supported_band *sband = + rdev->wiphy.bands[setup->chandef.chan->band]; +- scan_width = cfg80211_chandef_to_scan_width(&setup->chandef); +- setup->basic_rates = ieee80211_mandatory_rates(sband, +- scan_width); ++ ++ if (setup->chandef.chan->band == NL80211_BAND_2GHZ) { ++ int i; ++ ++ /* ++ * Older versions selected the mandatory rates for ++ * 2.4 GHz as well, but were broken in that only ++ * 1 Mbps was regarded as a mandatory rate. Keep ++ * using just 1 Mbps as the default basic rate for ++ * mesh to be interoperable with older versions. ++ */ ++ for (i = 0; i < sband->n_bitrates; i++) { ++ if (sband->bitrates[i].bitrate == 10) { ++ setup->basic_rates = BIT(i); ++ break; ++ } ++ } ++ } else { ++ scan_width = cfg80211_chandef_to_scan_width(&setup->chandef); ++ setup->basic_rates = ieee80211_mandatory_rates(sband, ++ scan_width); ++ } + } + + err = cfg80211_chandef_dfs_required(&rdev->wiphy, diff --git a/root/package/kernel/mac80211/patches/370-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch b/root/package/kernel/mac80211/patches/370-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch new file mode 100644 index 00000000..14cf6641 --- /dev/null +++ b/root/package/kernel/mac80211/patches/370-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch @@ -0,0 +1,150 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:41:51 +0100 +Subject: [PATCH] mac80211: minstrel: remove unnecessary debugfs cleanup + code + +debugfs entries are cleaned up by debugfs_remove_recursive already. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel.c ++++ b/net/mac80211/rc80211_minstrel.c +@@ -689,8 +689,8 @@ minstrel_alloc(struct ieee80211_hw *hw, + + #ifdef CPTCFG_MAC80211_DEBUGFS + mp->fixed_rate_idx = (u32) -1; +- mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx", +- S_IRUGO | S_IWUGO, debugfsdir, &mp->fixed_rate_idx); ++ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, ++ &mp->fixed_rate_idx); + #endif + + minstrel_init_cck_rates(mp); +@@ -701,9 +701,6 @@ minstrel_alloc(struct ieee80211_hw *hw, + static void + minstrel_free(void *priv) + { +-#ifdef CPTCFG_MAC80211_DEBUGFS +- debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate); +-#endif + kfree(priv); + } + +@@ -735,7 +732,6 @@ const struct rate_control_ops mac80211_m + .free_sta = minstrel_free_sta, + #ifdef CPTCFG_MAC80211_DEBUGFS + .add_sta_debugfs = minstrel_add_sta_debugfs, +- .remove_sta_debugfs = minstrel_remove_sta_debugfs, + #endif + .get_expected_throughput = minstrel_get_expected_throughput, + }; +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -109,11 +109,6 @@ struct minstrel_sta_info { + + /* sampling table */ + u8 *sample_table; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- struct dentry *dbg_stats; +- struct dentry *dbg_stats_csv; +-#endif + }; + + struct minstrel_priv { +@@ -137,7 +132,6 @@ struct minstrel_priv { + * - setting will be applied on next update + */ + u32 fixed_rate_idx; +- struct dentry *dbg_fixed_rate; + #endif + }; + +@@ -156,7 +150,6 @@ minstrel_get_ewmsd10(struct minstrel_rat + + extern const struct rate_control_ops mac80211_minstrel; + void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +-void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); + + /* Recalculate success probabilities and counters for a given rate using EWMA */ + void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs); +--- a/net/mac80211/rc80211_minstrel_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_debugfs.c +@@ -214,19 +214,7 @@ minstrel_add_sta_debugfs(void *priv, voi + { + struct minstrel_sta_info *mi = priv_sta; + +- mi->dbg_stats = debugfs_create_file("rc_stats", S_IRUGO, dir, mi, +- &minstrel_stat_fops); +- +- mi->dbg_stats_csv = debugfs_create_file("rc_stats_csv", S_IRUGO, dir, +- mi, &minstrel_stat_csv_fops); +-} +- +-void +-minstrel_remove_sta_debugfs(void *priv, void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- debugfs_remove(mi->dbg_stats); +- +- debugfs_remove(mi->dbg_stats_csv); ++ debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); ++ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, ++ &minstrel_stat_csv_fops); + } +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1393,7 +1393,6 @@ static const struct rate_control_ops mac + .free = minstrel_ht_free, + #ifdef CPTCFG_MAC80211_DEBUGFS + .add_sta_debugfs = minstrel_ht_add_sta_debugfs, +- .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs, + #endif + .get_expected_throughput = minstrel_ht_get_expected_throughput, + }; +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -110,17 +110,12 @@ struct minstrel_ht_sta_priv { + struct minstrel_ht_sta ht; + struct minstrel_sta_info legacy; + }; +-#ifdef CPTCFG_MAC80211_DEBUGFS +- struct dentry *dbg_stats; +- struct dentry *dbg_stats_csv; +-#endif + void *ratelist; + void *sample_table; + bool is_ht; + }; + + void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +-void minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta); + int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, + int prob_ewma); + +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -303,17 +303,8 @@ minstrel_ht_add_sta_debugfs(void *priv, + { + struct minstrel_ht_sta_priv *msp = priv_sta; + +- msp->dbg_stats = debugfs_create_file("rc_stats", S_IRUGO, dir, msp, +- &minstrel_ht_stat_fops); +- msp->dbg_stats_csv = debugfs_create_file("rc_stats_csv", S_IRUGO, +- dir, msp, &minstrel_ht_stat_csv_fops); +-} +- +-void +-minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta) +-{ +- struct minstrel_ht_sta_priv *msp = priv_sta; +- +- debugfs_remove(msp->dbg_stats); +- debugfs_remove(msp->dbg_stats_csv); ++ debugfs_create_file("rc_stats", S_IRUGO, dir, msp, ++ &minstrel_ht_stat_fops); ++ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, msp, ++ &minstrel_ht_stat_csv_fops); + } diff --git a/root/package/kernel/mac80211/patches/371-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch b/root/package/kernel/mac80211/patches/371-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch new file mode 100644 index 00000000..a2bdfd81 --- /dev/null +++ b/root/package/kernel/mac80211/patches/371-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch @@ -0,0 +1,576 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:43:30 +0100 +Subject: [PATCH] mac80211: minstrel: merge with minstrel_ht, always enable + VHT support + +Legacy-only devices are not very common and the overhead of the extra +code for HT and VHT rates is not big enough to justify all those extra +lines of code to make it optional. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/Kconfig ++++ b/net/mac80211/Kconfig +@@ -25,20 +25,6 @@ config MAC80211_RC_MINSTREL + ---help--- + This option enables the 'minstrel' TX rate control algorithm + +-config MAC80211_RC_MINSTREL_HT +- bool "Minstrel 802.11n support" if EXPERT +- depends on MAC80211_RC_MINSTREL +- default y +- ---help--- +- This option enables the 'minstrel_ht' TX rate control algorithm +- +-config MAC80211_RC_MINSTREL_VHT +- bool "Minstrel 802.11ac support" if EXPERT +- depends on MAC80211_RC_MINSTREL_HT +- default n +- ---help--- +- This option enables VHT in the 'minstrel_ht' TX rate control algorithm +- + choice + prompt "Default rate control algorithm" + depends on MAC80211_HAS_RC +@@ -60,8 +46,7 @@ endchoice + + config MAC80211_RC_DEFAULT + string +- default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT +- default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL ++ default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL + default "" + + endif +--- a/net/mac80211/Makefile ++++ b/net/mac80211/Makefile +@@ -50,13 +50,14 @@ mac80211-$(CONFIG_PM) += pm.o + + CFLAGS_trace.o := -I$(src) + +-rc80211_minstrel-y := rc80211_minstrel.o +-rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o ++rc80211_minstrel-y := \ ++ rc80211_minstrel.o \ ++ rc80211_minstrel_ht.o + +-rc80211_minstrel_ht-y := rc80211_minstrel_ht.o +-rc80211_minstrel_ht-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o ++rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += \ ++ rc80211_minstrel_debugfs.o \ ++ rc80211_minstrel_ht_debugfs.o + + mac80211-$(CPTCFG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) +-mac80211-$(CPTCFG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) + + ccflags-y += -DDEBUG +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -1252,18 +1252,12 @@ static int __init ieee80211_init(void) + if (ret) + return ret; + +- ret = rc80211_minstrel_ht_init(); +- if (ret) +- goto err_minstrel; +- + ret = ieee80211_iface_init(); + if (ret) + goto err_netdev; + + return 0; + err_netdev: +- rc80211_minstrel_ht_exit(); +- err_minstrel: + rc80211_minstrel_exit(); + + return ret; +@@ -1271,7 +1265,6 @@ static int __init ieee80211_init(void) + + static void __exit ieee80211_exit(void) + { +- rc80211_minstrel_ht_exit(); + rc80211_minstrel_exit(); + + ieee80211s_stop(); +--- a/net/mac80211/rate.h ++++ b/net/mac80211/rate.h +@@ -95,18 +95,5 @@ static inline void rc80211_minstrel_exit + } + #endif + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_HT +-int rc80211_minstrel_ht_init(void); +-void rc80211_minstrel_ht_exit(void); +-#else +-static inline int rc80211_minstrel_ht_init(void) +-{ +- return 0; +-} +-static inline void rc80211_minstrel_ht_exit(void) +-{ +-} +-#endif +- + + #endif /* IEEE80211_RATE_H */ +--- a/net/mac80211/rc80211_minstrel.c ++++ b/net/mac80211/rc80211_minstrel.c +@@ -572,138 +572,6 @@ minstrel_rate_init(void *priv, struct ie + minstrel_update_rates(mp, mi); + } + +-static void * +-minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) +-{ +- struct ieee80211_supported_band *sband; +- struct minstrel_sta_info *mi; +- struct minstrel_priv *mp = priv; +- struct ieee80211_hw *hw = mp->hw; +- int max_rates = 0; +- int i; +- +- mi = kzalloc(sizeof(struct minstrel_sta_info), gfp); +- if (!mi) +- return NULL; +- +- for (i = 0; i < NUM_NL80211_BANDS; i++) { +- sband = hw->wiphy->bands[i]; +- if (sband && sband->n_bitrates > max_rates) +- max_rates = sband->n_bitrates; +- } +- +- mi->r = kzalloc(sizeof(struct minstrel_rate) * max_rates, gfp); +- if (!mi->r) +- goto error; +- +- mi->sample_table = kmalloc(SAMPLE_COLUMNS * max_rates, gfp); +- if (!mi->sample_table) +- goto error1; +- +- mi->last_stats_update = jiffies; +- return mi; +- +-error1: +- kfree(mi->r); +-error: +- kfree(mi); +- return NULL; +-} +- +-static void +-minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- kfree(mi->sample_table); +- kfree(mi->r); +- kfree(mi); +-} +- +-static void +-minstrel_init_cck_rates(struct minstrel_priv *mp) +-{ +- static const int bitrates[4] = { 10, 20, 55, 110 }; +- struct ieee80211_supported_band *sband; +- u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); +- int i, j; +- +- sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; +- if (!sband) +- return; +- +- for (i = 0, j = 0; i < sband->n_bitrates; i++) { +- struct ieee80211_rate *rate = &sband->bitrates[i]; +- +- if (rate->flags & IEEE80211_RATE_ERP_G) +- continue; +- +- if ((rate_flags & sband->bitrates[i].flags) != rate_flags) +- continue; +- +- for (j = 0; j < ARRAY_SIZE(bitrates); j++) { +- if (rate->bitrate != bitrates[j]) +- continue; +- +- mp->cck_rates[j] = i; +- break; +- } +- } +-} +- +-static void * +-minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +-{ +- struct minstrel_priv *mp; +- +- mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); +- if (!mp) +- return NULL; +- +- /* contention window settings +- * Just an approximation. Using the per-queue values would complicate +- * the calculations and is probably unnecessary */ +- mp->cw_min = 15; +- mp->cw_max = 1023; +- +- /* number of packets (in %) to use for sampling other rates +- * sample less often for non-mrr packets, because the overhead +- * is much higher than with mrr */ +- mp->lookaround_rate = 5; +- mp->lookaround_rate_mrr = 10; +- +- /* maximum time that the hw is allowed to stay in one MRR segment */ +- mp->segment_size = 6000; +- +- if (hw->max_rate_tries > 0) +- mp->max_retry = hw->max_rate_tries; +- else +- /* safe default, does not necessarily have to match hw properties */ +- mp->max_retry = 7; +- +- if (hw->max_rates >= 4) +- mp->has_mrr = true; +- +- mp->hw = hw; +- mp->update_interval = 100; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- mp->fixed_rate_idx = (u32) -1; +- debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, +- &mp->fixed_rate_idx); +-#endif +- +- minstrel_init_cck_rates(mp); +- +- return mp; +-} +- +-static void +-minstrel_free(void *priv) +-{ +- kfree(priv); +-} +- + static u32 minstrel_get_expected_throughput(void *priv_sta) + { + struct minstrel_sta_info *mi = priv_sta; +@@ -722,29 +590,8 @@ static u32 minstrel_get_expected_through + } + + const struct rate_control_ops mac80211_minstrel = { +- .name = "minstrel", + .tx_status_ext = minstrel_tx_status, + .get_rate = minstrel_get_rate, + .rate_init = minstrel_rate_init, +- .alloc = minstrel_alloc, +- .free = minstrel_free, +- .alloc_sta = minstrel_alloc_sta, +- .free_sta = minstrel_free_sta, +-#ifdef CPTCFG_MAC80211_DEBUGFS +- .add_sta_debugfs = minstrel_add_sta_debugfs, +-#endif + .get_expected_throughput = minstrel_get_expected_throughput, + }; +- +-int __init +-rc80211_minstrel_init(void) +-{ +- return ieee80211_rate_control_register(&mac80211_minstrel); +-} +- +-void +-rc80211_minstrel_exit(void) +-{ +- ieee80211_rate_control_unregister(&mac80211_minstrel); +-} +- +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -158,7 +158,5 @@ int minstrel_get_tp_avg(struct minstrel_ + /* debugfs */ + int minstrel_stats_open(struct inode *inode, struct file *file); + int minstrel_stats_csv_open(struct inode *inode, struct file *file); +-ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); +-int minstrel_stats_release(struct inode *inode, struct file *file); + + #endif +--- a/net/mac80211/rc80211_minstrel_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_debugfs.c +@@ -54,22 +54,6 @@ + #include + #include "rc80211_minstrel.h" + +-ssize_t +-minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) +-{ +- struct minstrel_debugfs_info *ms; +- +- ms = file->private_data; +- return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); +-} +- +-int +-minstrel_stats_release(struct inode *inode, struct file *file) +-{ +- kfree(file->private_data); +- return 0; +-} +- + int + minstrel_stats_open(struct inode *inode, struct file *file) + { +@@ -135,14 +119,6 @@ minstrel_stats_open(struct inode *inode, + return 0; + } + +-static const struct file_operations minstrel_stat_fops = { +- .owner = THIS_MODULE, +- .open = minstrel_stats_open, +- .read = minstrel_stats_read, +- .release = minstrel_stats_release, +- .llseek = default_llseek, +-}; +- + int + minstrel_stats_csv_open(struct inode *inode, struct file *file) + { +@@ -200,21 +176,3 @@ minstrel_stats_csv_open(struct inode *in + + return 0; + } +- +-static const struct file_operations minstrel_stat_csv_fops = { +- .owner = THIS_MODULE, +- .open = minstrel_stats_csv_open, +- .read = minstrel_stats_read, +- .release = minstrel_stats_release, +- .llseek = default_llseek, +-}; +- +-void +-minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); +- debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, +- &minstrel_stat_csv_fops); +-} +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -137,12 +137,10 @@ + } \ + } + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + static bool minstrel_vht_only = true; + module_param(minstrel_vht_only, bool, 0644); + MODULE_PARM_DESC(minstrel_vht_only, + "Use only VHT rates when VHT is supported by sta."); +-#endif + + /* + * To enable sufficiently targeted rate sampling, MCS rates are divided into +@@ -171,7 +169,6 @@ const struct mcs_group minstrel_mcs_grou + + CCK_GROUP, + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + VHT_GROUP(1, 0, BW_20), + VHT_GROUP(2, 0, BW_20), + VHT_GROUP(3, 0, BW_20), +@@ -195,7 +192,6 @@ const struct mcs_group minstrel_mcs_grou + VHT_GROUP(1, 1, BW_80), + VHT_GROUP(2, 1, BW_80), + VHT_GROUP(3, 1, BW_80), +-#endif + }; + + static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +@@ -1146,12 +1142,10 @@ minstrel_ht_update_caps(void *priv, stru + + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + if (vht_cap->vht_supported) + use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); + else +-#endif +- use_vht = 0; ++ use_vht = 0; + + msp->is_ht = true; + memset(mi, 0, sizeof(*mi)); +@@ -1226,10 +1220,9 @@ minstrel_ht_update_caps(void *priv, stru + + /* HT rate */ + if (gflags & IEEE80211_TX_RC_MCS) { +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + if (use_vht && minstrel_vht_only) + continue; +-#endif ++ + mi->supported[i] = mcs->rx_mask[nss - 1]; + if (mi->supported[i]) + n_supported++; +@@ -1349,16 +1342,88 @@ minstrel_ht_free_sta(void *priv, struct + kfree(msp); + } + ++static void ++minstrel_ht_init_cck_rates(struct minstrel_priv *mp) ++{ ++ static const int bitrates[4] = { 10, 20, 55, 110 }; ++ struct ieee80211_supported_band *sband; ++ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); ++ int i, j; ++ ++ sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; ++ if (!sband) ++ return; ++ ++ for (i = 0, j = 0; i < sband->n_bitrates; i++) { ++ struct ieee80211_rate *rate = &sband->bitrates[i]; ++ ++ if (rate->flags & IEEE80211_RATE_ERP_G) ++ continue; ++ ++ if ((rate_flags & sband->bitrates[i].flags) != rate_flags) ++ continue; ++ ++ for (j = 0; j < ARRAY_SIZE(bitrates); j++) { ++ if (rate->bitrate != bitrates[j]) ++ continue; ++ ++ mp->cck_rates[j] = i; ++ break; ++ } ++ } ++} ++ + static void * + minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) + { +- return mac80211_minstrel.alloc(hw, debugfsdir); ++ struct minstrel_priv *mp; ++ ++ mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); ++ if (!mp) ++ return NULL; ++ ++ /* contention window settings ++ * Just an approximation. Using the per-queue values would complicate ++ * the calculations and is probably unnecessary */ ++ mp->cw_min = 15; ++ mp->cw_max = 1023; ++ ++ /* number of packets (in %) to use for sampling other rates ++ * sample less often for non-mrr packets, because the overhead ++ * is much higher than with mrr */ ++ mp->lookaround_rate = 5; ++ mp->lookaround_rate_mrr = 10; ++ ++ /* maximum time that the hw is allowed to stay in one MRR segment */ ++ mp->segment_size = 6000; ++ ++ if (hw->max_rate_tries > 0) ++ mp->max_retry = hw->max_rate_tries; ++ else ++ /* safe default, does not necessarily have to match hw properties */ ++ mp->max_retry = 7; ++ ++ if (hw->max_rates >= 4) ++ mp->has_mrr = true; ++ ++ mp->hw = hw; ++ mp->update_interval = 100; ++ ++#ifdef CPTCFG_MAC80211_DEBUGFS ++ mp->fixed_rate_idx = (u32) -1; ++ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, ++ &mp->fixed_rate_idx); ++#endif ++ ++ minstrel_ht_init_cck_rates(mp); ++ ++ return mp; + } + + static void + minstrel_ht_free(void *priv) + { +- mac80211_minstrel.free(priv); ++ kfree(priv); + } + + static u32 minstrel_ht_get_expected_throughput(void *priv_sta) +@@ -1417,14 +1482,14 @@ static void __init init_sample_table(voi + } + + int __init +-rc80211_minstrel_ht_init(void) ++rc80211_minstrel_init(void) + { + init_sample_table(); + return ieee80211_rate_control_register(&mac80211_minstrel_ht); + } + + void +-rc80211_minstrel_ht_exit(void) ++rc80211_minstrel_exit(void) + { + ieee80211_rate_control_unregister(&mac80211_minstrel_ht); + } +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -15,11 +15,7 @@ + */ + #define MINSTREL_MAX_STREAMS 3 + #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + #define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ +-#else +-#define MINSTREL_VHT_STREAM_GROUPS 0 +-#endif + + #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_HT_STREAM_GROUPS) +@@ -34,11 +30,7 @@ + #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) + #define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + #define MCS_GROUP_RATES 10 +-#else +-#define MCS_GROUP_RATES 8 +-#endif + + struct mcs_group { + u32 flags; +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -15,6 +15,22 @@ + #include "rc80211_minstrel.h" + #include "rc80211_minstrel_ht.h" + ++static ssize_t ++minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) ++{ ++ struct minstrel_debugfs_info *ms; ++ ++ ms = file->private_data; ++ return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); ++} ++ ++static int ++minstrel_stats_release(struct inode *inode, struct file *file) ++{ ++ kfree(file->private_data); ++ return 0; ++} ++ + static char * + minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) + { diff --git a/root/package/kernel/mac80211/patches/372-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch b/root/package/kernel/mac80211/patches/372-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch new file mode 100644 index 00000000..02a0ca0a --- /dev/null +++ b/root/package/kernel/mac80211/patches/372-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch @@ -0,0 +1,368 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:45:47 +0100 +Subject: [PATCH] mac80211: minstrel: reduce minstrel_mcs_groups size + +By storing a shift value for all duration values of a group, we can +reduce precision by a neglegible amount to make it fit into a u16 value. +This improves cache footprint and reduces size: + +Before: + text data bss dec hex filename + 10024 116 0 10140 279c rc80211_minstrel_ht.o + +After: + text data bss dec hex filename + 9368 116 0 9484 250c rc80211_minstrel_ht.o + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -52,22 +52,23 @@ + _streams - 1 + + /* MCS rate information for an MCS group */ +-#define MCS_GROUP(_streams, _sgi, _ht40) \ ++#define MCS_GROUP(_streams, _sgi, _ht40, _s) \ + [GROUP_IDX(_streams, _sgi, _ht40)] = { \ + .streams = _streams, \ ++ .shift = _s, \ + .flags = \ + IEEE80211_TX_RC_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ + (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \ + } \ + } + +@@ -80,9 +81,10 @@ + #define BW2VBPS(_bw, r3, r2, r1) \ + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) + +-#define VHT_GROUP(_streams, _sgi, _bw) \ ++#define VHT_GROUP(_streams, _sgi, _bw, _s) \ + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ + .streams = _streams, \ ++ .shift = _s, \ + .flags = \ + IEEE80211_TX_RC_VHT_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ +@@ -90,25 +92,25 @@ + _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 117, 54, 26)), \ ++ BW2VBPS(_bw, 117, 54, 26)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 234, 108, 52)), \ ++ BW2VBPS(_bw, 234, 108, 52)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 351, 162, 78)), \ ++ BW2VBPS(_bw, 351, 162, 78)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 468, 216, 104)), \ ++ BW2VBPS(_bw, 468, 216, 104)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 702, 324, 156)), \ ++ BW2VBPS(_bw, 702, 324, 156)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 936, 432, 208)), \ ++ BW2VBPS(_bw, 936, 432, 208)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1053, 486, 234)), \ ++ BW2VBPS(_bw, 1053, 486, 234)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1170, 540, 260)), \ ++ BW2VBPS(_bw, 1170, 540, 260)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1404, 648, 312)), \ ++ BW2VBPS(_bw, 1404, 648, 312)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1560, 720, 346)) \ ++ BW2VBPS(_bw, 1560, 720, 346)) >> _s \ + } \ + } + +@@ -121,19 +123,20 @@ + (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ + CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE)) + +-#define CCK_DURATION_LIST(_short) \ +- CCK_ACK_DURATION(10, _short), \ +- CCK_ACK_DURATION(20, _short), \ +- CCK_ACK_DURATION(55, _short), \ +- CCK_ACK_DURATION(110, _short) ++#define CCK_DURATION_LIST(_short, _s) \ ++ CCK_ACK_DURATION(10, _short) >> _s, \ ++ CCK_ACK_DURATION(20, _short) >> _s, \ ++ CCK_ACK_DURATION(55, _short) >> _s, \ ++ CCK_ACK_DURATION(110, _short) >> _s + +-#define CCK_GROUP \ ++#define CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ + .streams = 0, \ + .flags = 0, \ ++ .shift = _s, \ + .duration = { \ +- CCK_DURATION_LIST(false), \ +- CCK_DURATION_LIST(true) \ ++ CCK_DURATION_LIST(false, _s), \ ++ CCK_DURATION_LIST(true, _s) \ + } \ + } + +@@ -151,47 +154,47 @@ MODULE_PARM_DESC(minstrel_vht_only, + * BW -> SGI -> #streams + */ + const struct mcs_group minstrel_mcs_groups[] = { +- MCS_GROUP(1, 0, BW_20), +- MCS_GROUP(2, 0, BW_20), +- MCS_GROUP(3, 0, BW_20), +- +- MCS_GROUP(1, 1, BW_20), +- MCS_GROUP(2, 1, BW_20), +- MCS_GROUP(3, 1, BW_20), +- +- MCS_GROUP(1, 0, BW_40), +- MCS_GROUP(2, 0, BW_40), +- MCS_GROUP(3, 0, BW_40), +- +- MCS_GROUP(1, 1, BW_40), +- MCS_GROUP(2, 1, BW_40), +- MCS_GROUP(3, 1, BW_40), +- +- CCK_GROUP, +- +- VHT_GROUP(1, 0, BW_20), +- VHT_GROUP(2, 0, BW_20), +- VHT_GROUP(3, 0, BW_20), +- +- VHT_GROUP(1, 1, BW_20), +- VHT_GROUP(2, 1, BW_20), +- VHT_GROUP(3, 1, BW_20), +- +- VHT_GROUP(1, 0, BW_40), +- VHT_GROUP(2, 0, BW_40), +- VHT_GROUP(3, 0, BW_40), +- +- VHT_GROUP(1, 1, BW_40), +- VHT_GROUP(2, 1, BW_40), +- VHT_GROUP(3, 1, BW_40), +- +- VHT_GROUP(1, 0, BW_80), +- VHT_GROUP(2, 0, BW_80), +- VHT_GROUP(3, 0, BW_80), +- +- VHT_GROUP(1, 1, BW_80), +- VHT_GROUP(2, 1, BW_80), +- VHT_GROUP(3, 1, BW_80), ++ MCS_GROUP(1, 0, BW_20, 5), ++ MCS_GROUP(2, 0, BW_20, 4), ++ MCS_GROUP(3, 0, BW_20, 4), ++ ++ MCS_GROUP(1, 1, BW_20, 5), ++ MCS_GROUP(2, 1, BW_20, 4), ++ MCS_GROUP(3, 1, BW_20, 4), ++ ++ MCS_GROUP(1, 0, BW_40, 4), ++ MCS_GROUP(2, 0, BW_40, 4), ++ MCS_GROUP(3, 0, BW_40, 4), ++ ++ MCS_GROUP(1, 1, BW_40, 4), ++ MCS_GROUP(2, 1, BW_40, 4), ++ MCS_GROUP(3, 1, BW_40, 4), ++ ++ CCK_GROUP(8), ++ ++ VHT_GROUP(1, 0, BW_20, 5), ++ VHT_GROUP(2, 0, BW_20, 4), ++ VHT_GROUP(3, 0, BW_20, 4), ++ ++ VHT_GROUP(1, 1, BW_20, 5), ++ VHT_GROUP(2, 1, BW_20, 4), ++ VHT_GROUP(3, 1, BW_20, 4), ++ ++ VHT_GROUP(1, 0, BW_40, 4), ++ VHT_GROUP(2, 0, BW_40, 4), ++ VHT_GROUP(3, 0, BW_40, 4), ++ ++ VHT_GROUP(1, 1, BW_40, 4), ++ VHT_GROUP(2, 1, BW_40, 4), ++ VHT_GROUP(3, 1, BW_40, 4), ++ ++ VHT_GROUP(1, 0, BW_80, 4), ++ VHT_GROUP(2, 0, BW_80, 4), ++ VHT_GROUP(3, 0, BW_80, 4), ++ ++ VHT_GROUP(1, 1, BW_80, 4), ++ VHT_GROUP(2, 1, BW_80, 4), ++ VHT_GROUP(3, 1, BW_80, 4), + }; + + static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +@@ -307,7 +310,8 @@ minstrel_ht_get_tp_avg(struct minstrel_h + if (group != MINSTREL_CCK_GROUP) + nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); + +- nsecs += minstrel_mcs_groups[group].duration[rate]; ++ nsecs += minstrel_mcs_groups[group].duration[rate] << ++ minstrel_mcs_groups[group].shift; + + /* + * For the throughput calculation, limit the probability value to 90% to +@@ -755,12 +759,19 @@ minstrel_ht_tx_status(void *priv, struct + minstrel_ht_update_rates(mp, mi); + } + ++static inline int ++minstrel_get_duration(int index) ++{ ++ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; ++ unsigned int duration = group->duration[index % MCS_GROUP_RATES]; ++ return duration << group->shift; ++} ++ + static void + minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + int index) + { + struct minstrel_rate_stats *mrs; +- const struct mcs_group *group; + unsigned int tx_time, tx_time_rtscts, tx_time_data; + unsigned int cw = mp->cw_min; + unsigned int ctime = 0; +@@ -779,8 +790,7 @@ minstrel_calc_retransmit(struct minstrel + mrs->retry_count_rtscts = 2; + mrs->retry_updated = true; + +- group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000; ++ tx_time_data = minstrel_get_duration(index) * ampdu_len / 1000; + + /* Contention time for first 2 tries */ + ctime = (t_slot * cw) >> 1; +@@ -874,20 +884,24 @@ minstrel_ht_get_max_amsdu_len(struct min + int group = mi->max_prob_rate / MCS_GROUP_RATES; + const struct mcs_group *g = &minstrel_mcs_groups[group]; + int rate = mi->max_prob_rate % MCS_GROUP_RATES; ++ unsigned int duration; + + /* Disable A-MSDU if max_prob_rate is bad */ + if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100)) + return 1; + ++ duration = g->duration[rate]; ++ duration <<= g->shift; ++ + /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 52)) ++ if (duration > MCS_DURATION(1, 0, 52)) + return 500; + + /* + * If the rate is slower than single-stream MCS4, limit A-MSDU to usual + * data packet size + */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 104)) ++ if (duration > MCS_DURATION(1, 0, 104)) + return 1600; + + /* +@@ -895,7 +909,7 @@ minstrel_ht_get_max_amsdu_len(struct min + * rate success probability is less than 75%, limit A-MSDU to twice the usual + * data packet size + */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 260) || ++ if (duration > MCS_DURATION(1, 0, 260) || + (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) < + MINSTREL_FRAC(75, 100))) + return 3200; +@@ -942,13 +956,6 @@ minstrel_ht_update_rates(struct minstrel + rate_control_set_rates(mp->hw, mi->sta, rates); + } + +-static inline int +-minstrel_get_duration(int index) +-{ +- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- return group->duration[index % MCS_GROUP_RATES]; +-} +- + static int + minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) + { +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -33,9 +33,10 @@ + #define MCS_GROUP_RATES 10 + + struct mcs_group { +- u32 flags; +- unsigned int streams; +- unsigned int duration[MCS_GROUP_RATES]; ++ u16 flags; ++ u8 streams; ++ u8 shift; ++ u16 duration[MCS_GROUP_RATES]; + }; + + extern const struct mcs_group minstrel_mcs_groups[]; +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -58,6 +58,7 @@ minstrel_ht_stats_dump(struct minstrel_h + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -95,7 +96,9 @@ minstrel_ht_stats_dump(struct minstrel_h + p += sprintf(p, " %3u ", idx); + + /* tx_time[rate(i)] in usec */ +- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); + p += sprintf(p, "%6u ", tx_time); + + tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); +@@ -204,6 +207,7 @@ minstrel_ht_stats_csv_dump(struct minstr + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -238,7 +242,10 @@ minstrel_ht_stats_csv_dump(struct minstr + } + + p += sprintf(p, "%u,", idx); +- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); ++ ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); + p += sprintf(p, "%u,", tx_time); + + tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); diff --git a/root/package/kernel/mac80211/patches/373-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch b/root/package/kernel/mac80211/patches/373-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch new file mode 100644 index 00000000..502d8c77 --- /dev/null +++ b/root/package/kernel/mac80211/patches/373-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch @@ -0,0 +1,31 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 13:43:07 +0100 +Subject: [PATCH] mac80211: minstrel: fix using short preamble CCK rates on + HT clients + +mi->supported[MINSTREL_CCK_GROUP] needs to be updated + +Fixes: 782dda00ab8e ("mac80211: minstrel_ht: move short preamble check out of get_rate") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1135,7 +1135,6 @@ minstrel_ht_update_caps(void *priv, stru + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; + u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; +- struct sta_info *sinfo = container_of(sta, struct sta_info, sta); + int use_vht; + int n_supported = 0; + int ack_dur; +@@ -1267,8 +1266,7 @@ minstrel_ht_update_caps(void *priv, stru + if (!n_supported) + goto use_legacy; + +- if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE)) +- mi->cck_supported_short |= mi->cck_supported_short << 4; ++ mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4; + + /* create an initial rate table with the lowest supported rates */ + minstrel_ht_update_stats(mp, mi); diff --git a/root/package/kernel/mac80211/patches/374-ath9k-Protect-queue-draining-by-rcu_read_lock.patch b/root/package/kernel/mac80211/patches/374-ath9k-Protect-queue-draining-by-rcu_read_lock.patch new file mode 100644 index 00000000..0b599b73 --- /dev/null +++ b/root/package/kernel/mac80211/patches/374-ath9k-Protect-queue-draining-by-rcu_read_lock.patch @@ -0,0 +1,43 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Fri, 2 Feb 2018 11:36:45 +0100 +Subject: [PATCH] ath9k: Protect queue draining by rcu_read_lock() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When ath9k was switched over to use the mac80211 intermediate queues, +node cleanup now drains the mac80211 queues. However, this call path is +not protected by rcu_read_lock() as it was previously entirely internal +to the driver which uses its own locking. + +This leads to a possible rcu_dereference() without holding +rcu_read_lock(); but only if a station is cleaned up while having +packets queued on the TXQ. Fix this by adding the rcu_read_lock() to the +caller in ath9k. + +Fixes: 50f08edf9809 ("ath9k: Switch to using mac80211 intermediate software queues.") +Cc: stable@vger.kernel.org +Reported-by: Ben Greear +Signed-off-by: Toke Høiland-Jørgensen +--- + +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2915,6 +2915,8 @@ void ath_tx_node_cleanup(struct ath_soft + struct ath_txq *txq; + int tidno; + ++ rcu_read_lock(); ++ + for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { + tid = ath_node_to_tid(an, tidno); + txq = tid->txq; +@@ -2932,6 +2934,8 @@ void ath_tx_node_cleanup(struct ath_soft + if (!an->sta) + break; /* just one multicast ath_atx_tid */ + } ++ ++ rcu_read_unlock(); + } + + #ifdef CPTCFG_ATH9K_TX99 diff --git a/root/package/kernel/mac80211/patches/375-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch b/root/package/kernel/mac80211/patches/375-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch new file mode 100644 index 00000000..f0ffcd96 --- /dev/null +++ b/root/package/kernel/mac80211/patches/375-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:27:54 +0100 +Subject: [PATCH] mac80211: minstrel: fix CCK rate group streams value + +Fixes a harmless underflow issue when CCK rates are actively being used + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -131,7 +131,7 @@ + + #define CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ +- .streams = 0, \ ++ .streams = 1, \ + .flags = 0, \ + .shift = _s, \ + .duration = { \ diff --git a/root/package/kernel/mac80211/patches/376-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch b/root/package/kernel/mac80211/patches/376-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch new file mode 100644 index 00000000..e0049c36 --- /dev/null +++ b/root/package/kernel/mac80211/patches/376-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch @@ -0,0 +1,58 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:28:48 +0100 +Subject: [PATCH] mac80211: minstrel: fix sampling/reporting of CCK rates + in HT mode + +Long/short preamble selection cannot be sampled separately, since it +depends on the BSS state. Because of that, sampling attempts to +currently not used preamble modes are not counted in the statistics, +which leads to CCK rates being sampled too often. + +Fix statistics accounting for long/short preamble by increasing the +index where necessary. +Fix excessive CCK rate sampling by dropping unsupported sample attempts. + +This improves throughput on 2.4 GHz channels + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -281,7 +281,8 @@ minstrel_ht_get_stats(struct minstrel_pr + break; + + /* short preamble */ +- if (!(mi->supported[group] & BIT(idx))) ++ if ((mi->supported[group] & BIT(idx + 4)) && ++ (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) + idx += 4; + } + return &mi->groups[group].rates[idx]; +@@ -1080,18 +1081,23 @@ minstrel_ht_get_rate(void *priv, struct + return; + + sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; ++ sample_idx %= MCS_GROUP_RATES; ++ ++ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] && ++ (sample_idx >= 4) != txrc->short_preamble) ++ return; ++ + info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; + rate->count = 1; + +- if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { ++ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP]) { + int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); + rate->idx = mp->cck_rates[idx]; + } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { + ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, + sample_group->streams); + } else { +- rate->idx = sample_idx % MCS_GROUP_RATES + +- (sample_group->streams - 1) * 8; ++ rate->idx = sample_idx + (sample_group->streams - 1) * 8; + } + + rate->flags = sample_group->flags; diff --git a/root/package/kernel/mac80211/patches/377-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch b/root/package/kernel/mac80211/patches/377-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch new file mode 100644 index 00000000..414cb137 --- /dev/null +++ b/root/package/kernel/mac80211/patches/377-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch @@ -0,0 +1,40 @@ +From: Felix Fietkau +Date: Sat, 3 Mar 2018 18:48:58 +0100 +Subject: [PATCH] mac80211: minstrel: do not sample rates 3 times slower than + max_prob_rate + +These rates are highly unlikely to be used quickly, even if the link +deteriorates rapidly. This improves throughput in cases where CCK rates +are not reliable enough to be skipped entirely during sampling. +Sampling these rates regularly can cost a lot of airtime. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1004,10 +1004,13 @@ minstrel_get_sample_rate(struct minstrel + return -1; + + /* +- * Do not sample if the probability is already higher than 95% +- * to avoid wasting airtime. ++ * Do not sample if the probability is already higher than 95%, ++ * or if the rate is 3 times slower than the current max probability ++ * rate, to avoid wasting airtime. + */ +- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100)) ++ sample_dur = minstrel_get_duration(sample_idx); ++ if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) || ++ minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) + return -1; + + /* +@@ -1017,7 +1020,6 @@ minstrel_get_sample_rate(struct minstrel + + cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 / + MCS_GROUP_RATES].streams; +- sample_dur = minstrel_get_duration(sample_idx); + if (sample_dur >= minstrel_get_duration(tp_rate2) && + (cur_max_tp_streams - 1 < + minstrel_mcs_groups[sample_group].streams || diff --git a/root/package/kernel/mac80211/patches/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch b/root/package/kernel/mac80211/patches/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch new file mode 100644 index 00000000..c64457a1 --- /dev/null +++ b/root/package/kernel/mac80211/patches/378-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch @@ -0,0 +1,58 @@ +From: Felix Fietkau +Date: Thu, 8 Mar 2018 21:00:56 +0100 +Subject: [PATCH] mac80211: fix memory accounting with A-MSDU aggregation + +fq uses skb->truesize for memory usage tracking. Increments/decrements +are done on enqueue/dequeue. +When A-MSDU aggregation is performed on tx side, the packet is +aggregated with the last packet in the queue belonging to the same flow. +There are multiple bugs here: +- The truesize field of the aggregated packet isn't updated, so memory +usage is underestimated +- fq->memory_usage isn't adjusted. + +Because of the combination of both bugs, this only causes tx issues in +rare cases, mainly when the A-MSDU head needs to be reallocated. + +Fix this by adjusting both truesize of the A-MSDU head and adding the +truesize delta to fq->memory_usage. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3171,6 +3171,7 @@ static bool ieee80211_amsdu_aggregate(st + u8 max_subframes = sta->sta.max_amsdu_subframes; + int max_frags = local->hw.max_tx_fragments; + int max_amsdu_len = sta->sta.max_amsdu_len; ++ int orig_truesize; + __be16 len; + void *data; + bool ret = false; +@@ -3201,12 +3202,13 @@ static bool ieee80211_amsdu_aggregate(st + flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func); + head = skb_peek_tail(&flow->queue); + if (!head) +- goto out; ++ goto unlock; + ++ orig_truesize = head->truesize; + orig_len = head->len; + + if (skb->len + head->len > max_amsdu_len) +- goto out; ++ goto unlock; + + if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head)) + goto out; +@@ -3249,6 +3251,9 @@ static bool ieee80211_amsdu_aggregate(st + fq_recalc_backlog(fq, tin, flow); + + out: ++ fq->memory_usage += head->truesize - orig_truesize; ++ ++unlock: + spin_unlock_bh(&fq->lock); + + return ret; diff --git a/root/package/kernel/mac80211/patches/400-ath_move_debug_code.patch b/root/package/kernel/mac80211/patches/400-ath_move_debug_code.patch new file mode 100644 index 00000000..ed65053d --- /dev/null +++ b/root/package/kernel/mac80211/patches/400-ath_move_debug_code.patch @@ -0,0 +1,31 @@ +--- a/drivers/net/wireless/ath/Makefile ++++ b/drivers/net/wireless/ath/Makefile +@@ -13,10 +13,10 @@ ath-objs := main.o \ + regd.o \ + hw.o \ + key.o \ ++ debug.o \ + dfs_pattern_detector.o \ + dfs_pri_detector.o + +-ath-$(CPTCFG_ATH_DEBUG) += debug.o + ath-$(CPTCFG_ATH_TRACEPOINTS) += trace.o + + CFLAGS_trace.o := -I$(src) +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -318,14 +318,7 @@ void _ath_dbg(struct ath_common *common, + #endif /* CPTCFG_ATH_DEBUG */ + + /** Returns string describing opmode, or NULL if unknown mode. */ +-#ifdef CPTCFG_ATH_DEBUG + const char *ath_opmode_to_string(enum nl80211_iftype opmode); +-#else +-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) +-{ +- return "UNKNOWN"; +-} +-#endif + + extern const char *ath_bus_type_strings[]; + static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype) diff --git a/root/package/kernel/mac80211/patches/401-ath9k_blink_default.patch b/root/package/kernel/mac80211/patches/401-ath9k_blink_default.patch new file mode 100644 index 00000000..7405e594 --- /dev/null +++ b/root/package/kernel/mac80211/patches/401-ath9k_blink_default.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -47,7 +47,7 @@ int ath9k_modparam_nohwcrypt; + module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); + MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); + +-int ath9k_led_blink; ++int ath9k_led_blink = 1; + module_param_named(blink, ath9k_led_blink, int, 0444); + MODULE_PARM_DESC(blink, "Enable LED blink on activity"); + diff --git a/root/package/kernel/mac80211/patches/402-ath_regd_optional.patch b/root/package/kernel/mac80211/patches/402-ath_regd_optional.patch new file mode 100644 index 00000000..8fa56f40 --- /dev/null +++ b/root/package/kernel/mac80211/patches/402-ath_regd_optional.patch @@ -0,0 +1,92 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -24,6 +24,7 @@ + #include "regd_common.h" + + static int __ath_regd_init(struct ath_regulatory *reg); ++static struct reg_dmn_pair_mapping *ath_get_regpair(int regdmn); + + /* + * This is a set of common rules used by our world regulatory domains. +@@ -116,6 +117,9 @@ static const struct ieee80211_regdomain + + static bool dynamic_country_user_possible(struct ath_regulatory *reg) + { ++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) ++ return true; ++ + if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) + return true; + +@@ -188,6 +192,8 @@ static bool dynamic_country_user_possibl + + static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg) + { ++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) ++ return true; + if (!IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_REG_HINTS)) + return false; + if (!dynamic_country_user_possible(reg)) +@@ -345,6 +351,9 @@ ath_reg_apply_beaconing_flags(struct wip + struct ieee80211_channel *ch; + unsigned int i; + ++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) ++ return; ++ + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!wiphy->bands[band]) + continue; +@@ -378,6 +387,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip + { + struct ieee80211_supported_band *sband; + ++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) ++ return; ++ + sband = wiphy->bands[NL80211_BAND_2GHZ]; + if (!sband) + return; +@@ -407,6 +419,9 @@ static void ath_reg_apply_radar_flags(st + struct ieee80211_channel *ch; + unsigned int i; + ++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) ++ return; ++ + if (!wiphy->bands[NL80211_BAND_5GHZ]) + return; + +@@ -639,6 +654,10 @@ ath_regd_init_wiphy(struct ath_regulator + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; ++ ++ if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) ++ return 0; ++ + wiphy->regulatory_flags |= REGULATORY_STRICT_REG | + REGULATORY_CUSTOM_REG; + +--- a/drivers/net/wireless/ath/Kconfig ++++ b/drivers/net/wireless/ath/Kconfig +@@ -23,6 +23,9 @@ config WLAN_VENDOR_ATH + + if WLAN_VENDOR_ATH + ++config ATH_USER_REGD ++ bool "Do not enforce EEPROM regulatory restrictions" ++ + config ATH_DEBUG + bool "Atheros wireless debugging" + ---help--- +--- a/local-symbols ++++ b/local-symbols +@@ -87,6 +87,7 @@ ADM8211= + ATH_COMMON= + WLAN_VENDOR_ATH= + ATH_DEBUG= ++ATH_USER_REGD= + ATH_TRACEPOINTS= + ATH_REG_DYNAMIC_USER_REG_HINTS= + ATH_REG_DYNAMIC_USER_CERT_TESTING= diff --git a/root/package/kernel/mac80211/patches/403-world_regd_fixup.patch b/root/package/kernel/mac80211/patches/403-world_regd_fixup.patch new file mode 100644 index 00000000..20430831 --- /dev/null +++ b/root/package/kernel/mac80211/patches/403-world_regd_fixup.patch @@ -0,0 +1,84 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -44,7 +44,8 @@ static struct reg_dmn_pair_mapping *ath_ + NL80211_RRF_NO_OFDM) + + /* We allow IBSS on these on a case by case basis by regulatory domain */ +-#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ ++#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5240+10, 80, 0, 30, 0),\ ++ REG_RULE(5260-10, 5350+10, 80, 0, 30,\ + NL80211_RRF_NO_IR) + #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ + NL80211_RRF_NO_IR) +@@ -62,57 +63,56 @@ static struct reg_dmn_pair_mapping *ath_ + #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ + ATH9K_5GHZ_5725_5850 + ++#define REGD_RULES(...) \ ++ .reg_rules = { __VA_ARGS__ }, \ ++ .n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ })) ++ + /* Can be used for: + * 0x60, 0x61, 0x62 */ + static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { +- .n_reg_rules = 5, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_ALL, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + /* Can be used by 0x63 and 0x65 */ + static const struct ieee80211_regdomain ath_world_regdom_63_65 = { +- .n_reg_rules = 4, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_NO_MIDBAND, +- } ++ ) + }; + + /* Can be used by 0x64 only */ + static const struct ieee80211_regdomain ath_world_regdom_64 = { +- .n_reg_rules = 3, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_NO_MIDBAND, +- } ++ ) + }; + + /* Can be used by 0x66 and 0x69 */ + static const struct ieee80211_regdomain ath_world_regdom_66_69 = { +- .n_reg_rules = 3, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ + static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { +- .n_reg_rules = 4, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + static bool dynamic_country_user_possible(struct ath_regulatory *reg) diff --git a/root/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch b/root/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch new file mode 100644 index 00000000..00be2ef9 --- /dev/null +++ b/root/package/kernel/mac80211/patches/404-regd_no_assoc_hints.patch @@ -0,0 +1,19 @@ +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -2860,6 +2860,8 @@ void regulatory_hint_country_ie(struct w + enum environment_cap env = ENVIRON_ANY; + struct regulatory_request *request = NULL, *lr; + ++ return; ++ + /* IE len must be evenly divisible by 2 */ + if (country_ie_len & 0x01) + return; +@@ -3066,6 +3068,7 @@ static void restore_regulatory_settings( + + void regulatory_hint_disconnect(void) + { ++ return; + pr_debug("All devices are disconnected, going to restore regulatory settings\n"); + restore_regulatory_settings(false); + } diff --git a/root/package/kernel/mac80211/patches/405-ath_regd_us.patch b/root/package/kernel/mac80211/patches/405-ath_regd_us.patch new file mode 100644 index 00000000..cc558778 --- /dev/null +++ b/root/package/kernel/mac80211/patches/405-ath_regd_us.patch @@ -0,0 +1,26 @@ +--- a/drivers/net/wireless/ath/regd_common.h ++++ b/drivers/net/wireless/ath/regd_common.h +@@ -32,6 +32,7 @@ enum EnumRd { + FCC2_WORLD = 0x21, + FCC2_ETSIC = 0x22, + FCC6_WORLD = 0x23, ++ FCC3_FCCA_2 = 0x2A, + FRANCE_RES = 0x31, + FCC3_FCCA = 0x3A, + FCC3_WORLD = 0x3B, +@@ -167,6 +168,7 @@ static struct reg_dmn_pair_mapping regDo + {FCC2_WORLD, CTL_FCC, CTL_ETSI}, + {FCC2_ETSIC, CTL_FCC, CTL_ETSI}, + {FCC3_FCCA, CTL_FCC, CTL_FCC}, ++ {FCC3_FCCA_2, CTL_FCC, CTL_FCC}, + {FCC3_WORLD, CTL_FCC, CTL_ETSI}, + {FCC4_FCCA, CTL_FCC, CTL_FCC}, + {FCC5_FCCA, CTL_FCC, CTL_FCC}, +@@ -463,6 +465,7 @@ static struct country_code_to_enum_rd al + {CTRY_UAE, NULL1_WORLD, "AE"}, + {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"}, + {CTRY_UNITED_STATES, FCC3_FCCA, "US"}, ++ {CTRY_UNITED_STATES, FCC3_FCCA_2, "US"}, + /* This "PS" is for US public safety actually... to support this we + * would need to assign new special alpha2 to CRDA db as with the world + * regdomain and use another alpha2 */ diff --git a/root/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch b/root/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch new file mode 100644 index 00000000..35b0f2b7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/406-ath_relax_default_regd.patch @@ -0,0 +1,51 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -115,6 +115,16 @@ static const struct ieee80211_regdomain + ) + }; + ++static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) ++{ ++ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; ++} ++ ++static bool is_default_regd(struct ath_regulatory *reg) ++{ ++ return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT; ++} ++ + static bool dynamic_country_user_possible(struct ath_regulatory *reg) + { + if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) +@@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl + if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) + return true; + ++ if (is_default_regd(reg)) ++ return true; ++ + switch (reg->country_code) { + case CTRY_UNITED_STATES: + case CTRY_JAPAN1: +@@ -208,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd) + (regd == WORLD)); + } + +-static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) +-{ +- return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; +-} +- + bool ath_is_world_regd(struct ath_regulatory *reg) + { + return is_wwr_sku(ath_regd_get_eepromRD(reg)); +@@ -658,6 +666,9 @@ ath_regd_init_wiphy(struct ath_regulator + if (IS_ENABLED(CPTCFG_ATH_USER_REGD)) + return 0; + ++ if (is_default_regd(reg)) ++ return 0; ++ + wiphy->regulatory_flags |= REGULATORY_STRICT_REG | + REGULATORY_CUSTOM_REG; + diff --git a/root/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/root/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch new file mode 100644 index 00000000..86f96e8e --- /dev/null +++ b/root/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch @@ -0,0 +1,10 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -777,6 +777,7 @@ static const struct ieee80211_iface_limi + BIT(NL80211_IFTYPE_AP) }, + { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) }, ++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + }; + + #ifdef CPTCFG_WIRELESS_WDS diff --git a/root/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch b/root/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch new file mode 100644 index 00000000..2a5ab3d4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/411-ath5k_allow_adhoc_and_ap.patch @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c ++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c +@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw + goto end; + } + +- /* Don't allow other interfaces if one ad-hoc is configured. +- * TODO: Fix the problems with ad-hoc and multiple other interfaces. +- * We would need to operate the HW in ad-hoc mode to allow TSF updates +- * for the IBSS, but this breaks with additional AP or STA interfaces +- * at the moment. */ +- if (ah->num_adhoc_vifs || +- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { ++ /* Don't allow more than one ad-hoc interface */ ++ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) { + ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n"); + ret = -ELNRNG; + goto end; +--- a/drivers/net/wireless/ath/ath5k/base.c ++++ b/drivers/net/wireless/ath/ath5k/base.c +@@ -1965,7 +1965,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) + } + + if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + +- ah->num_mesh_vifs > 1) || ++ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) || + ah->opmode == NL80211_IFTYPE_MESH_POINT) { + u64 tsf = ath5k_hw_get_tsf64(ah); + u32 tsftu = TSF_TO_TU(tsf); +@@ -2051,7 +2051,7 @@ ath5k_beacon_update_timers(struct ath5k_ + + intval = ah->bintval & AR5K_BEACON_PERIOD; + if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +- + ah->num_mesh_vifs > 1) { ++ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) { + intval /= ATH_BCBUF; /* staggered multi-bss beacons */ + if (intval < 15) + ATH5K_WARN(ah, "intval %u is too low, min 15\n", +@@ -2518,6 +2518,7 @@ static const struct ieee80211_iface_limi + BIT(NL80211_IFTYPE_MESH_POINT) | + #endif + BIT(NL80211_IFTYPE_AP) }, ++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + }; + + static const struct ieee80211_iface_combination if_comb = { diff --git a/root/package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch b/root/package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch new file mode 100644 index 00000000..414f4950 --- /dev/null +++ b/root/package/kernel/mac80211/patches/420-ath5k_disable_fast_cc.patch @@ -0,0 +1,18 @@ +--- a/drivers/net/wireless/ath/ath5k/reset.c ++++ b/drivers/net/wireless/ath/ath5k/reset.c +@@ -1154,6 +1154,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum + tsf_lo = 0; + mode = 0; + ++#if 0 + /* + * Sanity check for fast flag + * Fast channel change only available +@@ -1161,6 +1162,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum + */ + if (fast && (ah->ah_radio != AR5K_RF2413) && + (ah->ah_radio != AR5K_RF5413)) ++#endif + fast = false; + + /* Disable sleep clock operation diff --git a/root/package/kernel/mac80211/patches/430-add_ath5k_platform.patch b/root/package/kernel/mac80211/patches/430-add_ath5k_platform.patch new file mode 100644 index 00000000..b213e2a8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/430-add_ath5k_platform.patch @@ -0,0 +1,33 @@ +--- /dev/null ++++ b/include/linux/ath5k_platform.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2008 Atheros Communications Inc. ++ * Copyright (c) 2009 Gabor Juhos ++ * Copyright (c) 2009 Imre Kaloz ++ * Copyright (c) 2010 Daniel Golle ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef _LINUX_ATH5K_PLATFORM_H ++#define _LINUX_ATH5K_PLATFORM_H ++ ++#define ATH5K_PLAT_EEP_MAX_WORDS 2048 ++ ++struct ath5k_platform_data { ++ u16 *eeprom_data; ++ u8 *macaddr; ++}; ++ ++#endif /* _LINUX_ATH5K_PLATFORM_H */ diff --git a/root/package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch b/root/package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch new file mode 100644 index 00000000..cdc9315c --- /dev/null +++ b/root/package/kernel/mac80211/patches/431-add_platform_eeprom_support_to_ath5k.patch @@ -0,0 +1,56 @@ +--- a/drivers/net/wireless/ath/ath5k/pci.c ++++ b/drivers/net/wireless/ath/ath5k/pci.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include "../ath.h" + #include "ath5k.h" + #include "debug.h" +@@ -72,7 +73,7 @@ static void ath5k_pci_read_cachesize(str + } + + /* +- * Read from eeprom ++ * Read from eeprom or platform_data + */ + static bool + ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) +@@ -80,6 +81,19 @@ ath5k_pci_eeprom_read(struct ath_common + struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; + u32 status, timeout; + ++ struct ath5k_platform_data *pdata = NULL; ++ ++ if (ah->pdev) ++ pdata = ah->pdev->dev.platform_data; ++ ++ if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) { ++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) ++ return false; ++ ++ *data = pdata->eeprom_data[offset]; ++ return true; ++ } ++ + /* + * Initialize EEPROM access + */ +@@ -123,6 +137,16 @@ static int ath5k_pci_eeprom_read_mac(str + u16 data; + int octet; + ++ struct ath5k_platform_data *pdata = NULL; ++ ++ if (ah->pdev) ++ pdata = ah->pdev->dev.platform_data; ++ ++ if (pdata && pdata->macaddr) { ++ memcpy(mac, pdata->macaddr, ETH_ALEN); ++ return 0; ++ } ++ + AR5K_EEPROM_READ(0x20, data); + + for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { diff --git a/root/package/kernel/mac80211/patches/432-ath5k_add_pciids.patch b/root/package/kernel/mac80211/patches/432-ath5k_add_pciids.patch new file mode 100644 index 00000000..d82f8001 --- /dev/null +++ b/root/package/kernel/mac80211/patches/432-ath5k_add_pciids.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath5k/pci.c ++++ b/drivers/net/wireless/ath/ath5k/pci.c +@@ -48,6 +48,8 @@ static const struct pci_device_id ath5k_ + { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ + { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ + { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ ++ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */ ++ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */ + { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ + { 0 } + }; diff --git a/root/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch b/root/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch new file mode 100644 index 00000000..3ae01a5c --- /dev/null +++ b/root/package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch @@ -0,0 +1,143 @@ +This adds a bwmode debugfs file which can be used to set alternate +channel operating bandwidths. Only tested with AR5413 and only at +5 and 20 mhz channels. + +Signed-off-by: Pat Erley +--- +Other devices will need to be added to the switch in write_file_bwmode + +drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ + 1 files changed, 86 insertions(+), 0 deletions(-) + +--- a/drivers/net/wireless/ath/ath5k/debug.c ++++ b/drivers/net/wireless/ath/ath5k/debug.c +@@ -822,6 +822,97 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++/* debugfs: bwmode */ ++ ++static ssize_t read_file_bwmode(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath5k_hw *ah = file->private_data; ++ char buf[15]; ++ unsigned int len = 0; ++ ++ int cur_ah_bwmode = ah->ah_bwmode_debug; ++ ++#define print_selected(MODE, LABEL) \ ++ if (cur_ah_bwmode == MODE) \ ++ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \ ++ else \ ++ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \ ++ len += snprintf(buf+len, sizeof(buf)-len, " "); ++ ++ print_selected(AR5K_BWMODE_5MHZ, "5"); ++ print_selected(AR5K_BWMODE_10MHZ, "10"); ++ print_selected(AR5K_BWMODE_DEFAULT, "20"); ++ print_selected(AR5K_BWMODE_40MHZ, "40"); ++#undef print_selected ++ ++ len += snprintf(buf+len, sizeof(buf)-len, "\n"); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_bwmode(struct file *file, ++ const char __user *userbuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath5k_hw *ah = file->private_data; ++ char buf[3]; ++ int bw = 20; ++ int tobwmode = AR5K_BWMODE_DEFAULT; ++ ++ if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) ++ return -EFAULT; ++ ++ /* TODO: Add check for active interface */ ++ ++ if(strncmp(buf, "5", 1) == 0 ) { ++ tobwmode = AR5K_BWMODE_5MHZ; ++ bw = 5; ++ } else if ( strncmp(buf, "10", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_10MHZ; ++ bw = 10; ++ } else if ( strncmp(buf, "20", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_DEFAULT; ++ bw = 20; ++ } else if ( strncmp(buf, "40", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_40MHZ; ++ bw = 40; ++ } else ++ return -EINVAL; ++ ++ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n", ++ bw, tobwmode); ++ ++ switch (ah->ah_radio) { ++ /* TODO: only define radios that actually support 5/10mhz channels */ ++ case AR5K_RF5413: ++ case AR5K_RF5110: ++ case AR5K_RF5111: ++ case AR5K_RF5112: ++ case AR5K_RF2413: ++ case AR5K_RF2316: ++ case AR5K_RF2317: ++ case AR5K_RF2425: ++ if(ah->ah_bwmode_debug != tobwmode) { ++ mutex_lock(&ah->lock); ++ ah->ah_bwmode = tobwmode; ++ ah->ah_bwmode_debug = tobwmode; ++ mutex_unlock(&ah->lock); ++ } ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ return count; ++} ++ ++static const struct file_operations fops_bwmode = { ++ .read = read_file_bwmode, ++ .write = write_file_bwmode, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; + + /* debugfs: queues etc */ + +@@ -1012,6 +1103,9 @@ ath5k_debug_init_device(struct ath5k_hw + debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah, + &fops_beacon); + ++ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah, ++ &fops_bwmode); ++ + debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset); + + debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah, +--- a/drivers/net/wireless/ath/ath5k/ath5k.h ++++ b/drivers/net/wireless/ath/ath5k/ath5k.h +@@ -1372,6 +1372,7 @@ struct ath5k_hw { + u8 ah_coverage_class; + bool ah_ack_bitrate_high; + u8 ah_bwmode; ++ u8 ah_bwmode_debug; + bool ah_short_slot; + + /* Antenna Control */ +--- a/drivers/net/wireless/ath/ath5k/base.c ++++ b/drivers/net/wireless/ath/ath5k/base.c +@@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru + return -EINVAL; + } + ++ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT) ++ ah->ah_bwmode = ah->ah_bwmode_debug; ++ + /* + * To switch channels clear any pending DMA operations; + * wait long enough for the RX fifo to drain, reset the diff --git a/root/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/root/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch new file mode 100644 index 00000000..b6dc45cd --- /dev/null +++ b/root/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch @@ -0,0 +1,65 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1374,6 +1374,53 @@ void ath9k_deinit_debug(struct ath_softc + ath9k_cmn_spectral_deinit_debug(&sc->spec_priv); + } + ++static ssize_t read_file_eeprom(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); ++ int bytes = 0; ++ int pos = *ppos; ++ int size = 4096; ++ u16 val; ++ int i; ++ ++ if (AR_SREV_9300_20_OR_LATER(ah)) ++ size = 16384; ++ ++ if (*ppos < 0) ++ return -EINVAL; ++ ++ if (count > size - *ppos) ++ count = size - *ppos; ++ ++ for (i = *ppos / 2; count > 0; count -= bytes, *ppos += bytes, i++) { ++ void *from = &val; ++ ++ if (!common->bus_ops->eeprom_read(common, i, &val)) ++ val = 0xffff; ++ ++ if (*ppos % 2) { ++ from++; ++ bytes = 1; ++ } else if (count == 1) { ++ bytes = 1; ++ } else { ++ bytes = 2; ++ } ++ copy_to_user(user_buf, from, bytes); ++ user_buf += bytes; ++ } ++ return *ppos - pos; ++} ++ ++static const struct file_operations fops_eeprom = { ++ .read = read_file_eeprom, ++ .open = simple_open, ++ .owner = THIS_MODULE ++}; ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1393,6 +1440,8 @@ int ath9k_init_debug(struct ath_hw *ah) + ath9k_tx99_init_debug(sc); + ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); + ++ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, ++ &fops_eeprom); + debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, + read_file_dma); + debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, diff --git a/root/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch b/root/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch new file mode 100644 index 00000000..53225dbc --- /dev/null +++ b/root/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch @@ -0,0 +1,32 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -1088,23 +1088,23 @@ static int __init ath9k_init(void) + { + int error; + +- error = ath_pci_init(); ++ error = ath_ahb_init(); + if (error < 0) { +- pr_err("No PCI devices found, driver not installed\n"); + error = -ENODEV; + goto err_out; + } + +- error = ath_ahb_init(); ++ error = ath_pci_init(); + if (error < 0) { ++ pr_err("No PCI devices found, driver not installed\n"); + error = -ENODEV; +- goto err_pci_exit; ++ goto err_ahb_exit; + } + + return 0; + +- err_pci_exit: +- ath_pci_exit(); ++ err_ahb_exit: ++ ath_ahb_exit(); + err_out: + return error; + } diff --git a/root/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch b/root/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch new file mode 100644 index 00000000..d2a3b965 --- /dev/null +++ b/root/package/kernel/mac80211/patches/510-ath9k_intr_mitigation_tweak.patch @@ -0,0 +1,18 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -390,13 +390,8 @@ static void ath9k_hw_init_config(struct + + ah->config.rx_intr_mitigation = true; + +- if (AR_SREV_9300_20_OR_LATER(ah)) { +- ah->config.rimt_last = 500; +- ah->config.rimt_first = 2000; +- } else { +- ah->config.rimt_last = 250; +- ah->config.rimt_first = 700; +- } ++ ah->config.rimt_last = 250; ++ ah->config.rimt_first = 500; + + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) + ah->config.pll_pwrsave = 7; diff --git a/root/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/root/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch new file mode 100644 index 00000000..15b8d7b8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc * + (_l) &= ((_sz) - 1); \ + } while (0) + +-#define ATH_RXBUF 512 ++#define ATH_RXBUF 256 + #define ATH_TXBUF 512 + #define ATH_TXBUF_RESERVE 5 + #define ATH_TXMAXTRY 13 diff --git a/root/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/root/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch new file mode 100644 index 00000000..2ebb73d6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch @@ -0,0 +1,125 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1421,6 +1421,52 @@ static const struct file_operations fops + .owner = THIS_MODULE + }; + ++ ++static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "0x%08x\n", common->chan_bw); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ unsigned long chan_bw; ++ char buf[32]; ++ ssize_t len; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (kstrtoul(buf, 0, &chan_bw)) ++ return -EINVAL; ++ ++ common->chan_bw = chan_bw; ++ if (!test_bit(ATH_OP_INVALID, &common->op_flags)) ++ ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL); ++ ++ return count; ++} ++ ++static const struct file_operations fops_chanbw = { ++ .read = read_file_chan_bw, ++ .write = write_file_chan_bw, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1442,6 +1488,8 @@ int ath9k_init_debug(struct ath_hw *ah) + + debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_eeprom); ++ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ sc, &fops_chanbw); + debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, + read_file_dma); + debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -151,6 +151,7 @@ struct ath_common { + int debug_mask; + enum ath_device_state state; + unsigned long op_flags; ++ u32 chan_bw; + + struct ath_ani ani; + +--- a/drivers/net/wireless/ath/ath9k/common.c ++++ b/drivers/net/wireless/ath/ath9k/common.c +@@ -297,11 +297,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke + /* + * Update internal channel flags. + */ +-static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, ++static void ath9k_cmn_update_ichannel(struct ath_common *common, ++ struct ath9k_channel *ichan, + struct cfg80211_chan_def *chandef) + { + struct ieee80211_channel *chan = chandef->chan; + u16 flags = 0; ++ int width; + + ichan->channel = chan->center_freq; + ichan->chan = chan; +@@ -309,7 +311,19 @@ static void ath9k_cmn_update_ichannel(st + if (chan->band == NL80211_BAND_5GHZ) + flags |= CHANNEL_5GHZ; + +- switch (chandef->width) { ++ switch (common->chan_bw) { ++ case 5: ++ width = NL80211_CHAN_WIDTH_5; ++ break; ++ case 10: ++ width = NL80211_CHAN_WIDTH_10; ++ break; ++ default: ++ width = chandef->width; ++ break; ++ } ++ ++ switch (width) { + case NL80211_CHAN_WIDTH_5: + flags |= CHANNEL_QUARTER; + break; +@@ -342,10 +356,11 @@ struct ath9k_channel *ath9k_cmn_get_chan + struct cfg80211_chan_def *chandef) + { + struct ieee80211_channel *curchan = chandef->chan; ++ struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_channel *channel; + + channel = &ah->channels[curchan->hw_value]; +- ath9k_cmn_update_ichannel(channel, chandef); ++ ath9k_cmn_update_ichannel(common, channel, chandef); + + return channel; + } diff --git a/root/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch b/root/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch new file mode 100644 index 00000000..fdeaed05 --- /dev/null +++ b/root/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch @@ -0,0 +1,30 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -647,6 +647,7 @@ int ath9k_hw_init(struct ath_hw *ah) + + /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */ + switch (ah->hw_version.devid) { ++ case AR9300_DEVID_INVALID: + case AR5416_DEVID_PCI: + case AR5416_DEVID_PCIE: + case AR5416_AR9100_DEVID: +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -36,6 +36,7 @@ + + #define ATHEROS_VENDOR_ID 0x168c + ++#define AR9300_DEVID_INVALID 0xabcd + #define AR5416_DEVID_PCI 0x0023 + #define AR5416_DEVID_PCIE 0x0024 + #define AR9160_DEVID_PCI 0x0027 +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -773,6 +773,7 @@ static const struct pci_device_id ath_pc + .driver_data = ATH9K_PCI_BT_ANT_DIV }, + #endif + ++ { PCI_VDEVICE(ATHEROS, 0xabcd) }, /* PCI-E internal chip default ID */ + { 0 } + }; + diff --git a/root/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/root/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch new file mode 100644 index 00000000..19f0ff2a --- /dev/null +++ b/root/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch @@ -0,0 +1,160 @@ +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -2750,6 +2750,7 @@ struct cfg80211_pmk_conf { + * (as advertised by the nl80211 feature flag.) + * @get_tx_power: store the current TX power into the dbm variable; + * return 0 if successful ++ * @set_antenna_gain: set antenna gain to reduce maximum tx power if necessary + * + * @set_wds_peer: set the WDS peer for a WDS interface + * +@@ -3041,6 +3042,7 @@ struct cfg80211_ops { + enum nl80211_tx_power_setting type, int mbm); + int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, + int *dbm); ++ int (*set_antenna_gain)(struct wiphy *wiphy, int dbi); + + int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr); +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1338,6 +1338,7 @@ enum ieee80211_smps_mode { + * + * @power_level: requested transmit power (in dBm), backward compatibility + * value only that is set to the minimum of all interfaces ++ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi) + * + * @chandef: the channel definition to tune to + * @radar_enabled: whether radar detection is enabled +@@ -1358,6 +1359,7 @@ enum ieee80211_smps_mode { + struct ieee80211_conf { + u32 flags; + int power_level, dynamic_ps_timeout; ++ int max_antenna_gain; + + u16 listen_interval; + u8 ps_dtim_period; +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2153,6 +2153,9 @@ enum nl80211_commands { + * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT. + * @NL80211_ATTR_PORT_AUTHORIZED: (reserved) + * ++ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce ++ * transmit power to stay within regulatory limits. u32, dBi. ++ * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use +@@ -2579,6 +2582,8 @@ enum nl80211_attrs { + NL80211_ATTR_PMKR0_NAME, + NL80211_ATTR_PORT_AUTHORIZED, + ++ NL80211_ATTR_WIPHY_ANTENNA_GAIN, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2447,6 +2447,19 @@ static int ieee80211_get_tx_power(struct + return 0; + } + ++static int ieee80211_set_antenna_gain(struct wiphy *wiphy, int dbi) ++{ ++ struct ieee80211_local *local = wiphy_priv(wiphy); ++ ++ if (dbi < 0) ++ return -EINVAL; ++ ++ local->user_antenna_gain = dbi; ++ ieee80211_hw_config(local, 0); ++ ++ return 0; ++} ++ + static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr) + { +@@ -3721,6 +3734,7 @@ const struct cfg80211_ops mac80211_confi + .set_wiphy_params = ieee80211_set_wiphy_params, + .set_tx_power = ieee80211_set_tx_power, + .get_tx_power = ieee80211_get_tx_power, ++ .set_antenna_gain = ieee80211_set_antenna_gain, + .set_wds_peer = ieee80211_set_wds_peer, + .rfkill_poll = ieee80211_rfkill_poll, + 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 { + int dynamic_ps_forced_timeout; + + int user_power_level; /* in dBm, for all interfaces */ ++ int user_antenna_gain; /* in dBi */ + + enum ieee80211_smps_mode smps_mode; + +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -93,7 +93,7 @@ static u32 ieee80211_hw_conf_chan(struct + struct ieee80211_sub_if_data *sdata; + struct cfg80211_chan_def chandef = {}; + u32 changed = 0; +- int power; ++ int power, max_power; + u32 offchannel_flag; + + offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; +@@ -150,6 +150,12 @@ static u32 ieee80211_hw_conf_chan(struct + } + rcu_read_unlock(); + ++ max_power = chandef.chan->max_reg_power; ++ if (local->user_antenna_gain > 0) { ++ max_power -= local->user_antenna_gain; ++ power = min(power, max_power); ++ } ++ + if (local->hw.conf.power_level != power) { + changed |= IEEE80211_CONF_CHANGE_POWER; + local->hw.conf.power_level = power; +@@ -592,6 +598,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + IEEE80211_RADIOTAP_MCS_HAVE_BW; + local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | + IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; ++ local->user_antenna_gain = 0; + local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; + local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; + local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -420,6 +420,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 }, + [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN }, + [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG }, ++ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, + }; + + /* policy for the key attributes */ +@@ -2395,6 +2396,20 @@ static int nl80211_set_wiphy(struct sk_b + if (result) + return result; + } ++ ++ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) { ++ int idx, dbi = 0; ++ ++ if (!rdev->ops->set_antenna_gain) ++ return -EOPNOTSUPP; ++ ++ idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN; ++ dbi = nla_get_u32(info->attrs[idx]); ++ ++ result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi); ++ if (result) ++ return result; ++ } + + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && + info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { diff --git a/root/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/root/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch new file mode 100644 index 00000000..8ea2f79a --- /dev/null +++ b/root/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch @@ -0,0 +1,267 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -850,6 +850,9 @@ static inline int ath9k_dump_btcoex(stru + #ifdef CPTCFG_MAC80211_LEDS + void ath_init_leds(struct ath_softc *sc); + void ath_deinit_leds(struct ath_softc *sc); ++int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name, ++ const char *trigger, bool active_low); ++ + #else + static inline void ath_init_leds(struct ath_softc *sc) + { +@@ -991,6 +994,13 @@ void ath_ant_comb_scan(struct ath_softc + #define AIRTIME_USE_NEW_QUEUES BIT(2) + #define AIRTIME_ACTIVE(flags) (!!(flags & (AIRTIME_USE_TX|AIRTIME_USE_RX))) + ++struct ath_led { ++ struct list_head list; ++ struct ath_softc *sc; ++ const struct gpio_led *gpio; ++ struct led_classdev cdev; ++}; ++ + struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; +@@ -1046,9 +1056,8 @@ struct ath_softc { + spinlock_t chan_lock; + + #ifdef CPTCFG_MAC80211_LEDS +- bool led_registered; +- char led_name[32]; +- struct led_classdev led_cdev; ++ const char *led_default_trigger; ++ struct list_head leds; + #endif + + #ifdef CPTCFG_ATH9K_DEBUGFS +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -39,61 +39,111 @@ static void ath_fill_led_pin(struct ath_ + else + ah->led_pin = ATH_LED_PIN_DEF; + } ++} ++ ++static void ath_led_brightness(struct led_classdev *led_cdev, ++ enum led_brightness brightness) ++{ ++ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev); ++ struct ath_softc *sc = led->sc; ++ ++ ath9k_ps_wakeup(sc); ++ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio, ++ (brightness != LED_OFF) ^ led->gpio->active_low); ++ ath9k_ps_restore(sc); ++} ++ ++static int ath_add_led(struct ath_softc *sc, struct ath_led *led) ++{ ++ const struct gpio_led *gpio = led->gpio; ++ int ret; ++ ++ led->cdev.name = gpio->name; ++ led->cdev.default_trigger = gpio->default_trigger; ++ led->cdev.brightness_set = ath_led_brightness; ++ ++ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev); ++ if (ret < 0) ++ return ret; ++ ++ led->sc = sc; ++ list_add(&led->list, &sc->leds); + + /* Configure gpio for output */ +- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led", ++ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + +- /* LED off, active low */ +- ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1); ++ /* LED off */ ++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); ++ ++ return 0; + } + +-static void ath_led_brightness(struct led_classdev *led_cdev, +- enum led_brightness brightness) ++int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name, ++ const char *trigger, bool active_low) + { +- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); +- u32 val = (brightness == LED_OFF); ++ struct ath_led *led; ++ struct gpio_led *gpio; ++ char *_name; ++ int ret; + +- if (sc->sc_ah->config.led_active_high) +- val = !val; ++ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1, ++ GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio = (struct gpio_led *) (led + 1); ++ _name = (char *) (led->gpio + 1); ++ ++ strcpy(_name, name); ++ gpio->name = _name; ++ gpio->gpio = gpio_num; ++ gpio->active_low = active_low; ++ gpio->default_trigger = trigger; ++ ++ ret = ath_add_led(sc, led); ++ if (unlikely(ret < 0)) ++ kfree(led); + +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); ++ return ret; + } + + void ath_deinit_leds(struct ath_softc *sc) + { +- if (!sc->led_registered) +- return; ++ struct ath_led *led; + +- ath_led_brightness(&sc->led_cdev, LED_OFF); +- led_classdev_unregister(&sc->led_cdev); +- +- ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin); ++ while (!list_empty(&sc->leds)) { ++ led = list_first_entry(&sc->leds, struct ath_led, list); ++ list_del(&led->list); ++ ath_led_brightness(&led->cdev, LED_OFF); ++ led_classdev_unregister(&led->cdev); ++ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); ++ kfree(led); ++ } + } + + void ath_init_leds(struct ath_softc *sc) + { +- int ret; ++ char led_name[32]; ++ const char *trigger; ++ ++ INIT_LIST_HEAD(&sc->leds); + + if (AR_SREV_9100(sc->sc_ah)) + return; + + ath_fill_led_pin(sc); + +- if (!ath9k_led_blink) +- sc->led_cdev.default_trigger = +- ieee80211_get_radio_led_name(sc->hw); +- +- snprintf(sc->led_name, sizeof(sc->led_name), +- "ath9k-%s", wiphy_name(sc->hw->wiphy)); +- sc->led_cdev.name = sc->led_name; +- sc->led_cdev.brightness_set = ath_led_brightness; ++ snprintf(led_name, sizeof(led_name), "ath9k-%s", ++ wiphy_name(sc->hw->wiphy)); + +- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); +- if (ret < 0) +- return; ++ if (ath9k_led_blink) ++ trigger = sc->led_default_trigger; ++ else ++ trigger = ieee80211_get_radio_led_name(sc->hw); + +- sc->led_registered = true; ++ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, ++ !sc->sc_ah->config.led_active_high); + } + #endif + +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -1000,7 +1000,7 @@ int ath9k_init_device(u16 devid, struct + + #ifdef CPTCFG_MAC80211_LEDS + /* must be initialized before ieee80211_register_hw */ +- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, ++ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, + ARRAY_SIZE(ath9k_tpt_blink)); + #endif +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1466,6 +1466,61 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++#ifdef CONFIG_MAC80211_LEDS ++ ++static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32], *str, *name, *c; ++ ssize_t len; ++ unsigned int gpio; ++ bool active_low = false; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, ubuf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ name = strchr(buf, ','); ++ if (!name) ++ return -EINVAL; ++ ++ *(name++) = 0; ++ if (!*name) ++ return -EINVAL; ++ ++ c = strchr(name, '\n'); ++ if (c) ++ *c = 0; ++ ++ str = buf; ++ if (*str == '!') { ++ str++; ++ active_low = true; ++ } ++ ++ if (kstrtouint(str, 0, &gpio) < 0) ++ return -EINVAL; ++ ++ if (gpio >= sc->sc_ah->caps.num_gpio_pins) ++ return -EINVAL; ++ ++ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0) ++ return -EINVAL; ++ ++ return count; ++} ++ ++static const struct file_operations fops_gpio_led = { ++ .write = write_file_gpio_led, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++#endif ++ + + int ath9k_init_debug(struct ath_hw *ah) + { +@@ -1490,6 +1545,10 @@ int ath9k_init_debug(struct ath_hw *ah) + &fops_eeprom); + debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_chanbw); ++#ifdef CONFIG_MAC80211_LEDS ++ debugfs_create_file("gpio_led", S_IWUSR, ++ sc->debug.debugfs_phy, sc, &fops_gpio_led); ++#endif + debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, + read_file_dma); + debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, diff --git a/root/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch b/root/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch new file mode 100644 index 00000000..8ed7ad8a --- /dev/null +++ b/root/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch @@ -0,0 +1,76 @@ +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -46,6 +46,9 @@ struct ath9k_platform_data { + int (*external_reset)(void); + + bool use_eeprom; ++ ++ int num_leds; ++ const struct gpio_led *leds; + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -15,6 +15,7 @@ + */ + + #include "ath9k.h" ++#include + + /********************************/ + /* LED functions */ +@@ -108,6 +109,24 @@ int ath_create_gpio_led(struct ath_softc + return ret; + } + ++static int ath_create_platform_led(struct ath_softc *sc, ++ const struct gpio_led *gpio) ++{ ++ struct ath_led *led; ++ int ret; ++ ++ led = kzalloc(sizeof(*led), GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio; ++ ret = ath_add_led(sc, led); ++ if (ret < 0) ++ kfree(led); ++ ++ return ret; ++} ++ + void ath_deinit_leds(struct ath_softc *sc) + { + struct ath_led *led; +@@ -124,8 +143,10 @@ void ath_deinit_leds(struct ath_softc *s + + void ath_init_leds(struct ath_softc *sc) + { ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + char led_name[32]; + const char *trigger; ++ int i; + + INIT_LIST_HEAD(&sc->leds); + +@@ -134,6 +155,17 @@ void ath_init_leds(struct ath_softc *sc) + + ath_fill_led_pin(sc); + ++ if (pdata && pdata->leds && pdata->num_leds) ++ for (i = 0; i < pdata->num_leds; i++) { ++ if (pdata->leds[i].gpio == sc->sc_ah->led_pin) ++ sc->sc_ah->led_pin = -1; ++ ++ ath_create_platform_led(sc, &pdata->leds[i]); ++ } ++ ++ if (sc->sc_ah->led_pin < 0) ++ return; ++ + snprintf(led_name, sizeof(led_name), "ath9k-%s", + wiphy_name(sc->hw->wiphy)); + diff --git a/root/package/kernel/mac80211/patches/540-ath9k_reduce_ani_interval.patch b/root/package/kernel/mac80211/patches/540-ath9k_reduce_ani_interval.patch new file mode 100644 index 00000000..e8999034 --- /dev/null +++ b/root/package/kernel/mac80211/patches/540-ath9k_reduce_ani_interval.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/ani.h ++++ b/drivers/net/wireless/ath/ath9k/ani.h +@@ -42,7 +42,7 @@ + #define ATH9K_ANI_PERIOD 300 + + /* in ms */ +-#define ATH9K_ANI_POLLINTERVAL 1000 ++#define ATH9K_ANI_POLLINTERVAL 300 + + #define ATH9K_SIG_FIRSTEP_SETTING_MIN 0 + #define ATH9K_SIG_FIRSTEP_SETTING_MAX 20 diff --git a/root/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/root/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch new file mode 100644 index 00000000..6dd03fd2 --- /dev/null +++ b/root/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch @@ -0,0 +1,139 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1522,6 +1522,50 @@ static const struct file_operations fops + #endif + + ++static ssize_t read_file_diag(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "0x%08lx\n", ah->diag); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_diag(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ unsigned long diag; ++ char buf[32]; ++ ssize_t len; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (kstrtoul(buf, 0, &diag)) ++ return -EINVAL; ++ ++ ah->diag = diag; ++ ath9k_hw_update_diag(ah); ++ ++ return count; ++} ++ ++static const struct file_operations fops_diag = { ++ .read = read_file_diag, ++ .write = write_file_diag, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1549,6 +1593,8 @@ int ath9k_init_debug(struct ath_hw *ah) + debugfs_create_file("gpio_led", S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_gpio_led); + #endif ++ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ sc, &fops_diag); + debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy, + read_file_dma); + debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy, +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -520,6 +520,12 @@ enum { + ATH9K_RESET_COLD, + }; + ++enum { ++ ATH_DIAG_DISABLE_RX, ++ ATH_DIAG_DISABLE_TX, ++ ATH_DIAG_TRIGGER_ERROR, ++}; ++ + struct ath9k_hw_version { + u32 magic; + u16 devid; +@@ -806,6 +812,8 @@ struct ath_hw { + u32 ah_flags; + s16 nf_override; + ++ unsigned long diag; ++ + bool reset_power_on; + bool htc_reset_init; + +@@ -1068,6 +1076,7 @@ void ath9k_hw_check_nav(struct ath_hw *a + bool ath9k_hw_check_alive(struct ath_hw *ah); + + bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); ++void ath9k_hw_update_diag(struct ath_hw *ah); + + /* Generic hw timer primitives */ + struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1842,6 +1842,20 @@ u32 ath9k_hw_get_tsf_offset(struct times + } + EXPORT_SYMBOL(ath9k_hw_get_tsf_offset); + ++void ath9k_hw_update_diag(struct ath_hw *ah) ++{ ++ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag)) ++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); ++ else ++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); ++ ++ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag)) ++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); ++ else ++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); ++} ++EXPORT_SYMBOL(ath9k_hw_update_diag); ++ + int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata, bool fastcc) + { +@@ -2050,6 +2064,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st + ar9003_hw_disable_phy_restart(ah); + + ath9k_hw_apply_gpio_override(ah); ++ ath9k_hw_update_diag(ah); + + if (AR_SREV_9565(ah) && common->bt_ant_diversity) + REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -528,6 +528,11 @@ irqreturn_t ath_isr(int irq, void *dev) + if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) + return IRQ_HANDLED; + ++ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) { ++ status |= ATH9K_INT_FATAL; ++ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag); ++ } ++ + /* + * If there are no status bits set, then this interrupt was not + * for me (should have been caught above). diff --git a/root/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch b/root/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch new file mode 100644 index 00000000..f9d3251c --- /dev/null +++ b/root/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch @@ -0,0 +1,186 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -721,6 +721,7 @@ struct ath_spec_scan { + * @config_pci_powersave: + * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC + * ++ * @get_adc_entropy: get entropy from the raw ADC I/Q output + * @spectral_scan_config: set parameters for spectral scan and enable/disable it + * @spectral_scan_trigger: trigger a spectral scan run + * @spectral_scan_wait: wait for a spectral scan run to finish +@@ -743,6 +744,7 @@ struct ath_hw_ops { + struct ath_hw_antcomb_conf *antconf); + void (*antdiv_comb_conf_set)(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf); ++ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len); + void (*spectral_scan_config)(struct ath_hw *ah, + struct ath_spec_scan *param); + void (*spectral_scan_trigger)(struct ath_hw *ah); +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1945,6 +1945,26 @@ void ar9003_hw_init_rate_txpower(struct + } + } + ++static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) ++{ ++ int i, j; ++ ++ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); ++ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); ++ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0); ++ ++ memset(buf, 0, len); ++ for (i = 0; i < len; i++) { ++ for (j = 0; j < 4; j++) { ++ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); ++ ++ buf[i] <<= 2; ++ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9); ++ udelay(1); ++ } ++ } ++} ++ + void ar9003_hw_attach_phy_ops(struct ath_hw *ah) + { + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); +@@ -1981,6 +2001,7 @@ void ar9003_hw_attach_phy_ops(struct ath + priv_ops->set_radar_params = ar9003_hw_set_radar_params; + priv_ops->fast_chan_change = ar9003_hw_fast_chan_change; + ++ ops->get_adc_entropy = ar9003_hw_get_adc_entropy; + ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; + ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; + ops->spectral_scan_config = ar9003_hw_spectral_scan_config; +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -765,7 +765,8 @@ static void ath9k_init_txpower_limits(st + if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) + ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ); + +- ah->curchan = curchan; ++ if (curchan) ++ ah->curchan = curchan; + } + + static const struct ieee80211_iface_limit if_limits[] = { +@@ -960,6 +961,18 @@ static void ath9k_set_hw_capab(struct at + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + } + ++static void ath_get_initial_entropy(struct ath_softc *sc) ++{ ++ struct ath_hw *ah = sc->sc_ah; ++ char buf[256]; ++ ++ /* reuse last channel initialized by the tx power test */ ++ ath9k_hw_reset(ah, ah->curchan, NULL, false); ++ ++ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf)); ++ add_device_randomness(buf, sizeof(buf)); ++} ++ + int ath9k_init_device(u16 devid, struct ath_softc *sc, + const struct ath_bus_ops *bus_ops) + { +@@ -1005,6 +1018,8 @@ int ath9k_init_device(u16 devid, struct + ARRAY_SIZE(ath9k_tpt_blink)); + #endif + ++ ath_get_initial_entropy(sc); ++ + /* Register with mac80211 */ + error = ieee80211_register_hw(hw); + if (error) +--- a/drivers/net/wireless/ath/ath9k/hw-ops.h ++++ b/drivers/net/wireless/ath/ath9k/hw-ops.h +@@ -100,6 +100,12 @@ static inline void ath9k_hw_tx99_set_txp + ath9k_hw_ops(ah)->tx99_set_txpower(ah, power); + } + ++static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah, ++ u8 *buf, size_t len) ++{ ++ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len); ++} ++ + #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT + + static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) +--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c +@@ -1322,9 +1322,30 @@ void ar5008_hw_init_rate_txpower(struct + } + } + ++static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len) ++{ ++ int i, j; ++ ++ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1); ++ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); ++ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0); ++ ++ memset(buf, 0, len); ++ for (i = 0; i < len; i++) { ++ for (j = 0; j < 4; j++) { ++ u32 regval = REG_READ(ah, AR_PHY_TST_ADC); ++ ++ buf[i] <<= 2; ++ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8); ++ udelay(1); ++ } ++ } ++} ++ + int ar5008_hw_attach_phy_ops(struct ath_hw *ah) + { + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); ++ struct ath_hw_ops *ops = ath9k_hw_ops(ah); + static const u32 ar5416_cca_regs[6] = { + AR_PHY_CCA, + AR_PHY_CH1_CCA, +@@ -1339,6 +1360,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ + if (ret) + return ret; + ++ ops->get_adc_entropy = ar5008_hw_get_adc_entropy; ++ + priv_ops->rf_set_freq = ar5008_hw_set_channel; + priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; + +--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h ++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h +@@ -20,6 +20,12 @@ + #define PHY_AGC_CLR 0x10000000 + #define RFSILENT_BB 0x00002000 + ++#define AR_PHY_TEST_BBB_OBS_SEL 0x780000 ++#define AR_PHY_TEST_BBB_OBS_SEL_S 19 ++ ++#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23 ++#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S) ++ + #define AR_PHY_TURBO 0x9804 + #define AR_PHY_FC_TURBO_MODE 0x00000001 + #define AR_PHY_FC_TURBO_SHORT 0x00000002 +@@ -36,6 +42,9 @@ + + #define AR_PHY_TEST2 0x9808 + ++#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00 ++#define AR_PHY_TEST2_RX_OBS_SEL_S 10 ++ + #define AR_PHY_TIMING2 0x9810 + #define AR_PHY_TIMING3 0x9814 + #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 +@@ -393,6 +402,8 @@ + #define AR_PHY_RFBUS_GRANT 0x9C20 + #define AR_PHY_RFBUS_GRANT_EN 0x00000001 + ++#define AR_PHY_TST_ADC 0x9C24 ++ + #define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4 + #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 + diff --git a/root/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch b/root/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch new file mode 100644 index 00000000..680bb6d5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch @@ -0,0 +1,79 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -246,6 +246,19 @@ void ath9k_hw_get_channel_centers(struct + centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT); + } + ++static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah) ++{ ++ /* On AR9330 and AR9340 devices, some PHY registers must be ++ * tuned to gain better stability/performance. These registers ++ * might be changed while doing wlan reset so the registers must ++ * be reprogrammed after each reset. ++ */ ++ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20)); ++ REG_RMW(ah, AR_PHY_USB_CTRL2, ++ (1 << 21) | (0xf << 22), ++ (1 << 21) | (0x3 << 22)); ++} ++ + /******************/ + /* Chip Revisions */ + /******************/ +@@ -1414,6 +1427,9 @@ static bool ath9k_hw_set_reset(struct at + udelay(50); + } + ++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) ++ ath9k_hw_disable_pll_lock_detect(ah); ++ + return true; + } + +@@ -1513,6 +1529,9 @@ static bool ath9k_hw_chip_reset(struct a + ar9003_hw_internal_regulator_apply(ah); + ath9k_hw_init_pll(ah, chan); + ++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) ++ ath9k_hw_disable_pll_lock_detect(ah); ++ + return true; + } + +@@ -1820,8 +1839,14 @@ static int ath9k_hw_do_fastcc(struct ath + if (AR_SREV_9271(ah)) + ar9002_hw_load_ani_reg(ah, chan); + ++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) ++ ath9k_hw_disable_pll_lock_detect(ah); ++ + return 0; + fail: ++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) ++ ath9k_hw_disable_pll_lock_detect(ah); ++ + return -EINVAL; + } + +@@ -2075,6 +2100,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st + ath9k_hw_set_radar_params(ah); + } + ++ if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) ++ ath9k_hw_disable_pll_lock_detect(ah); ++ + return 0; + } + EXPORT_SYMBOL(ath9k_hw_reset); +--- a/drivers/net/wireless/ath/ath9k/phy.h ++++ b/drivers/net/wireless/ath/ath9k/phy.h +@@ -48,6 +48,9 @@ + #define AR_PHY_PLL_CONTROL 0x16180 + #define AR_PHY_PLL_MODE 0x16184 + ++#define AR_PHY_USB_CTRL1 0x16c84 ++#define AR_PHY_USB_CTRL2 0x16c88 ++ + enum ath9k_ant_div_comb_lna_conf { + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, + ATH_ANT_DIV_COMB_LNA2, diff --git a/root/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch b/root/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch new file mode 100644 index 00000000..22a2308a --- /dev/null +++ b/root/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch @@ -0,0 +1,155 @@ +--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c +@@ -951,55 +951,6 @@ static bool ar5008_hw_ani_control_new(st + * on == 0 means more noise imm + */ + u32 on = param ? 1 : 0; +- /* +- * make register setting for default +- * (weak sig detect ON) come from INI file +- */ +- int m1ThreshLow = on ? +- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; +- int m2ThreshLow = on ? +- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; +- int m1Thresh = on ? +- aniState->iniDef.m1Thresh : m1Thresh_off; +- int m2Thresh = on ? +- aniState->iniDef.m2Thresh : m2Thresh_off; +- int m2CountThr = on ? +- aniState->iniDef.m2CountThr : m2CountThr_off; +- int m2CountThrLow = on ? +- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; +- int m1ThreshLowExt = on ? +- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; +- int m2ThreshLowExt = on ? +- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; +- int m1ThreshExt = on ? +- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; +- int m2ThreshExt = on ? +- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; +- +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, +- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, +- m1ThreshLow); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, +- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, +- m2ThreshLow); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR, +- AR_PHY_SFCORR_M1_THRESH, m1Thresh); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR, +- AR_PHY_SFCORR_M2_THRESH, m2Thresh); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR, +- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, +- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, +- m2CountThrLow); +- +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); + + if (on) + REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -42,20 +42,6 @@ static const int cycpwrThr1_table[] = + /* level: 0 1 2 3 4 5 6 7 8 */ + { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ + +-/* +- * register values to turn OFDM weak signal detection OFF +- */ +-static const int m1ThreshLow_off = 127; +-static const int m2ThreshLow_off = 127; +-static const int m1Thresh_off = 127; +-static const int m2Thresh_off = 127; +-static const int m2CountThr_off = 31; +-static const int m2CountThrLow_off = 63; +-static const int m1ThreshLowExt_off = 127; +-static const int m2ThreshLowExt_off = 127; +-static const int m1ThreshExt_off = 127; +-static const int m2ThreshExt_off = 127; +- + static const u8 ofdm2pwr[] = { + ALL_TARGET_LEGACY_6_24, + ALL_TARGET_LEGACY_6_24, +@@ -1095,11 +1081,6 @@ static bool ar9003_hw_ani_control(struct + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_channel *chan = ah->curchan; + struct ar5416AniState *aniState = &ah->ani; +- int m1ThreshLow, m2ThreshLow; +- int m1Thresh, m2Thresh; +- int m2CountThr, m2CountThrLow; +- int m1ThreshLowExt, m2ThreshLowExt; +- int m1ThreshExt, m2ThreshExt; + s32 value, value2; + + switch (cmd & ah->ani_function) { +@@ -1113,61 +1094,6 @@ static bool ar9003_hw_ani_control(struct + */ + u32 on = param ? 1 : 0; + +- if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) +- goto skip_ws_det; +- +- m1ThreshLow = on ? +- aniState->iniDef.m1ThreshLow : m1ThreshLow_off; +- m2ThreshLow = on ? +- aniState->iniDef.m2ThreshLow : m2ThreshLow_off; +- m1Thresh = on ? +- aniState->iniDef.m1Thresh : m1Thresh_off; +- m2Thresh = on ? +- aniState->iniDef.m2Thresh : m2Thresh_off; +- m2CountThr = on ? +- aniState->iniDef.m2CountThr : m2CountThr_off; +- m2CountThrLow = on ? +- aniState->iniDef.m2CountThrLow : m2CountThrLow_off; +- m1ThreshLowExt = on ? +- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; +- m2ThreshLowExt = on ? +- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; +- m1ThreshExt = on ? +- aniState->iniDef.m1ThreshExt : m1ThreshExt_off; +- m2ThreshExt = on ? +- aniState->iniDef.m2ThreshExt : m2ThreshExt_off; +- +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, +- AR_PHY_SFCORR_LOW_M1_THRESH_LOW, +- m1ThreshLow); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, +- AR_PHY_SFCORR_LOW_M2_THRESH_LOW, +- m2ThreshLow); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR, +- AR_PHY_SFCORR_M1_THRESH, +- m1Thresh); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR, +- AR_PHY_SFCORR_M2_THRESH, +- m2Thresh); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR, +- AR_PHY_SFCORR_M2COUNT_THR, +- m2CountThr); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, +- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, +- m2CountThrLow); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, +- m1ThreshLowExt); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, +- m2ThreshLowExt); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M1_THRESH, +- m1ThreshExt); +- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, +- AR_PHY_SFCORR_EXT_M2_THRESH, +- m2ThreshExt); +-skip_ws_det: + if (on) + REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); diff --git a/root/package/kernel/mac80211/patches/547-ath9k_led_defstate_fix.patch b/root/package/kernel/mac80211/patches/547-ath9k_led_defstate_fix.patch new file mode 100644 index 00000000..5d84cf0c --- /dev/null +++ b/root/package/kernel/mac80211/patches/547-ath9k_led_defstate_fix.patch @@ -0,0 +1,29 @@ +From: Michal Cieslakiewicz +Date: Sun, 31 Jan 2016 20:48:49 +0100 +Subject: [PATCH v4 2/8] mac80211: ath9k: set default state for platform LEDs + +Support default state for platform LEDs connected to ath9k device. +Now LEDs are correctly set on or off at ath9k module initialization. +Very useful if power LED is connected to wireless chip. + +Signed-off-by: Michal Cieslakiewicz +--- + gpio.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -74,8 +74,11 @@ static int ath_add_led(struct ath_softc + ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + +- /* LED off */ +- ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); ++ /* Set default LED state */ ++ if (gpio->default_state == LEDS_GPIO_DEFSTATE_ON) ++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, !gpio->active_low); ++ else ++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); + + return 0; + } diff --git a/root/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch b/root/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch new file mode 100644 index 00000000..31dac29a --- /dev/null +++ b/root/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch @@ -0,0 +1,247 @@ +From: Michal Cieslakiewicz +Date: Sun, 31 Jan 2016 21:01:31 +0100 +Subject: [PATCH v4 4/8] mac80211: ath9k: enable access to GPIO + +Enable access to GPIO chip and its pins for Atheros AR92xx +wireless devices. For now AR9285 and AR9287 are supported. + +Signed-off-by: Michal Cieslakiewicz +Signed-off-by: Felix Fietkau +--- +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "common.h" + #include "debug.h" +@@ -1001,6 +1002,14 @@ struct ath_led { + struct led_classdev cdev; + }; + ++#ifdef CONFIG_GPIOLIB ++struct ath9k_gpio_chip { ++ struct ath_softc *sc; ++ char label[32]; ++ struct gpio_chip gchip; ++}; ++#endif ++ + struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; +@@ -1058,6 +1067,9 @@ struct ath_softc { + #ifdef CPTCFG_MAC80211_LEDS + const char *led_default_trigger; + struct list_head leds; ++#ifdef CONFIG_GPIOLIB ++ struct ath9k_gpio_chip *gpiochip; ++#endif + #endif + + #ifdef CPTCFG_ATH9K_DEBUGFS +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -16,13 +16,135 @@ + + #include "ath9k.h" + #include ++#include ++ ++#ifdef CPTCFG_MAC80211_LEDS ++ ++#ifdef CONFIG_GPIOLIB ++ ++/***************/ ++/* GPIO Chip */ ++/***************/ ++ ++/* gpio_chip handler : set GPIO to input */ ++static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset) ++{ ++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, ++ gchip); ++ ++ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio"); ++ ++ return 0; ++} ++ ++/* gpio_chip handler : set GPIO to output */ ++static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset, ++ int value) ++{ ++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, ++ gchip); ++ ++ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio", ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); ++ ++ return 0; ++} ++ ++/* gpio_chip handler : query GPIO direction (0=out, 1=in) */ ++static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset) ++{ ++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, ++ gchip); ++ struct ath_hw *ah = gc->sc->sc_ah; ++ ++ return !((REG_READ(ah, AR_GPIO_OE_OUT) >> (offset * 2)) & 3); ++} ++ ++/* gpio_chip handler : get GPIO pin value */ ++static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset) ++{ ++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, ++ gchip); ++ ++ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset); ++} ++ ++/* gpio_chip handler : set GPIO pin to value */ ++static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset, ++ int value) ++{ ++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, ++ gchip); ++ ++ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); ++} ++ ++/* register GPIO chip */ ++static void ath9k_register_gpio_chip(struct ath_softc *sc) ++{ ++ struct ath9k_gpio_chip *gc; ++ struct ath_hw *ah = sc->sc_ah; ++ ++ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL); ++ if (!gc) ++ return; ++ ++ gc->sc = sc; ++ snprintf(gc->label, sizeof(gc->label), "ath9k-%s", ++ wiphy_name(sc->hw->wiphy)); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) ++ gc->gchip.parent = sc->dev; ++#else ++ gc->gchip.dev = sc->dev; ++#endif ++ gc->gchip.label = gc->label; ++ gc->gchip.base = -1; /* determine base automatically */ ++ gc->gchip.ngpio = ah->caps.num_gpio_pins; ++ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input; ++ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output; ++ gc->gchip.get_direction = ath9k_gpio_pin_get_dir; ++ gc->gchip.get = ath9k_gpio_pin_get; ++ gc->gchip.set = ath9k_gpio_pin_set; ++ ++ if (gpiochip_add(&gc->gchip)) { ++ kfree(gc); ++ return; ++ } ++ ++ gc->gchip.owner = NULL; ++ sc->gpiochip = gc; ++} ++ ++/* remove GPIO chip */ ++static void ath9k_unregister_gpio_chip(struct ath_softc *sc) ++{ ++ struct ath9k_gpio_chip *gc = sc->gpiochip; ++ ++ if (!gc) ++ return; ++ ++ gpiochip_remove(&gc->gchip); ++ kfree(gc); ++ sc->gpiochip = NULL; ++} ++ ++#else /* CONFIG_GPIOLIB */ ++ ++static inline void ath9k_register_gpio_chip(struct ath_softc *sc) ++{ ++} ++ ++static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc) ++{ ++} ++ ++#endif /* CONFIG_GPIOLIB */ + + /********************************/ + /* LED functions */ + /********************************/ + +-#ifdef CPTCFG_MAC80211_LEDS +- + static void ath_fill_led_pin(struct ath_softc *sc) + { + struct ath_hw *ah = sc->sc_ah; +@@ -80,6 +202,12 @@ static int ath_add_led(struct ath_softc + else + ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); + ++#ifdef CONFIG_GPIOLIB ++ /* If there is GPIO chip configured, reserve LED pin */ ++ if (sc->gpiochip) ++ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name); ++#endif ++ + return 0; + } + +@@ -136,17 +264,24 @@ void ath_deinit_leds(struct ath_softc *s + + while (!list_empty(&sc->leds)) { + led = list_first_entry(&sc->leds, struct ath_led, list); ++#ifdef CONFIG_GPIOLIB ++ /* If there is GPIO chip configured, free LED pin */ ++ if (sc->gpiochip) ++ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio); ++#endif + list_del(&led->list); + ath_led_brightness(&led->cdev, LED_OFF); + led_classdev_unregister(&led->cdev); + ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); + kfree(led); + } ++ ath9k_unregister_gpio_chip(sc); + } + + void ath_init_leds(struct ath_softc *sc) + { + struct ath9k_platform_data *pdata = sc->dev->platform_data; ++ struct device_node *np = sc->dev->of_node; + char led_name[32]; + const char *trigger; + int i; +@@ -156,6 +291,15 @@ void ath_init_leds(struct ath_softc *sc) + if (AR_SREV_9100(sc->sc_ah)) + return; + ++ if (!np) ++ ath9k_register_gpio_chip(sc); ++ ++ /* setup gpio controller only if requested and skip the led_pin setup */ ++ if (of_property_read_bool(np, "gpio-controller")) { ++ ath9k_register_gpio_chip(sc); ++ return; ++ } ++ + ath_fill_led_pin(sc); + + if (pdata && pdata->leds && pdata->num_leds) +@@ -180,6 +324,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); + } ++ + #endif + + /*******************/ diff --git a/root/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch b/root/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch new file mode 100644 index 00000000..e86e3e38 --- /dev/null +++ b/root/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch @@ -0,0 +1,143 @@ +From: Michal Cieslakiewicz +Subject: [PATCH v5 5/8] mac80211: ath9k: enable GPIO buttons + +Enable platform-defined GPIO button support for ath9k device. +Key poller is activated for attached platform buttons. +Requires ath9k GPIO chip access. + +Signed-off-by: Michal Cieslakiewicz +Signed-off-by: Felix Fietkau +--- +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -1069,6 +1069,7 @@ struct ath_softc { + struct list_head leds; + #ifdef CONFIG_GPIOLIB + struct ath9k_gpio_chip *gpiochip; ++ struct platform_device *btnpdev; /* gpio-keys-polled */ + #endif + #endif + +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -17,6 +17,8 @@ + #include "ath9k.h" + #include + #include ++#include ++#include + + #ifdef CPTCFG_MAC80211_LEDS + +@@ -129,6 +131,67 @@ static void ath9k_unregister_gpio_chip(s + sc->gpiochip = NULL; + } + ++/******************/ ++/* GPIO Buttons */ ++/******************/ ++ ++/* add GPIO buttons */ ++static void ath9k_init_buttons(struct ath_softc *sc) ++{ ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; ++ struct platform_device *pdev; ++ struct gpio_keys_platform_data gkpdata; ++ struct gpio_keys_button *bt; ++ int i; ++ ++ if (!sc->gpiochip) ++ return; ++ ++ if (!pdata || !pdata->btns || !pdata->num_btns) ++ return; ++ ++ bt = devm_kmemdup(sc->dev, pdata->btns, ++ pdata->num_btns * sizeof(struct gpio_keys_button), ++ GFP_KERNEL); ++ if (!bt) ++ return; ++ ++ for (i = 0; i < pdata->num_btns; i++) { ++ if (pdata->btns[i].gpio == sc->sc_ah->led_pin) ++ sc->sc_ah->led_pin = -1; ++ ++ ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio, ++ "ath9k-gpio"); ++ bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio; ++ } ++ ++ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); ++ gkpdata.buttons = bt; ++ gkpdata.nbuttons = pdata->num_btns; ++ gkpdata.poll_interval = pdata->btn_poll_interval; ++ ++ pdev = platform_device_register_data(sc->dev, "gpio-keys-polled", ++ PLATFORM_DEVID_AUTO, &gkpdata, ++ sizeof(gkpdata)); ++ if (!IS_ERR_OR_NULL(pdev)) ++ sc->btnpdev = pdev; ++ else { ++ sc->btnpdev = NULL; ++ devm_kfree(sc->dev, bt); ++ } ++} ++ ++/* remove GPIO buttons */ ++static void ath9k_deinit_buttons(struct ath_softc *sc) ++{ ++ if (!sc->gpiochip || !sc->btnpdev) ++ return; ++ ++ platform_device_unregister(sc->btnpdev); ++ ++ sc->btnpdev = NULL; ++} ++ + #else /* CONFIG_GPIOLIB */ + + static inline void ath9k_register_gpio_chip(struct ath_softc *sc) +@@ -139,6 +202,14 @@ static inline void ath9k_unregister_gpio + { + } + ++static inline void ath9k_init_buttons(struct ath_softc *sc) ++{ ++} ++ ++static inline void ath9k_deinit_buttons(struct ath_softc *sc) ++{ ++} ++ + #endif /* CONFIG_GPIOLIB */ + + /********************************/ +@@ -262,6 +333,7 @@ void ath_deinit_leds(struct ath_softc *s + { + struct ath_led *led; + ++ ath9k_deinit_buttons(sc); + while (!list_empty(&sc->leds)) { + led = list_first_entry(&sc->leds, struct ath_led, list); + #ifdef CONFIG_GPIOLIB +@@ -301,6 +373,7 @@ void ath_init_leds(struct ath_softc *sc) + } + + ath_fill_led_pin(sc); ++ ath9k_init_buttons(sc); + + if (pdata && pdata->leds && pdata->num_leds) + for (i = 0; i < pdata->num_leds; i++) { +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -49,6 +49,10 @@ struct ath9k_platform_data { + + int num_leds; + const struct gpio_led *leds; ++ ++ unsigned num_btns; ++ const struct gpio_keys_button *btns; ++ unsigned btn_poll_interval; + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ diff --git a/root/package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch b/root/package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch new file mode 100644 index 00000000..55f040f1 --- /dev/null +++ b/root/package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch @@ -0,0 +1,15 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -571,6 +571,12 @@ static int ath9k_of_init(struct ath_soft + + ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); + ++ if (of_property_read_bool(np, "qca,disable-2ghz")) ++ ah->disable_2ghz = true; ++ ++ if (of_property_read_bool(np, "qca,disable-5ghz")) ++ ah->disable_5ghz = true; ++ + if (of_property_read_bool(np, "qca,no-eeprom")) { + /* ath9k-eeprom--.bin */ + scnprintf(eeprom_name, sizeof(eeprom_name), diff --git a/root/package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch b/root/package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch new file mode 100644 index 00000000..82b8109e --- /dev/null +++ b/root/package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch @@ -0,0 +1,418 @@ +--- a/drivers/net/wireless/ath/ath9k/channel.c ++++ b/drivers/net/wireless/ath/ath9k/channel.c +@@ -15,6 +15,8 @@ + */ + + #include "ath9k.h" ++#include ++#include "hsr.h" + + /* Set/change channels. If the channel is really being changed, it's done + * by reseting the chip. To accomplish this we must first cleanup any pending +@@ -22,6 +24,7 @@ + */ + static int ath_set_channel(struct ath_softc *sc) + { ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_hw *hw = sc->hw; +@@ -42,6 +45,11 @@ static int ath_set_channel(struct ath_so + ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n", + chan->center_freq, chandef->width); + ++ if (pdata && pdata->ubnt_hsr) { ++ ath9k_hsr_enable(ah, chandef->width, chan->center_freq); ++ ath9k_hsr_status(ah); ++ } ++ + /* update survey stats for the old channel before switching */ + spin_lock_irqsave(&common->cc_lock, flags); + ath_update_survey_stats(sc); +--- /dev/null ++++ b/drivers/net/wireless/ath/ath9k/hsr.c +@@ -0,0 +1,247 @@ ++/* ++ * ++ * The MIT License (MIT) ++ * ++ * Copyright (c) 2015 Kirill Berezin ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "hw.h" ++#include "ath9k.h" ++ ++#define HSR_GPIO_CSN 8 ++#define HSR_GPIO_CLK 6 ++#define HSR_GPIO_DOUT 7 ++#define HSR_GPIO_DIN 5 ++ ++/* delays are in useconds */ ++#define HSR_DELAY_HALF_TICK 100 ++#define HSR_DELAY_PRE_WRITE 75 ++#define HSR_DELAY_FINAL 20000 ++#define HSR_DELAY_TRAILING 200 ++ ++void ath9k_hsr_init(struct ath_hw *ah) ++{ ++ ath9k_hw_gpio_request_in(ah, HSR_GPIO_DIN, NULL); ++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CSN, NULL, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CLK, NULL, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ath9k_hw_gpio_request_out(ah, HSR_GPIO_DOUT, NULL, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); ++ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0); ++ ++ udelay(HSR_DELAY_TRAILING); ++} ++ ++static u32 ath9k_hsr_write_byte(struct ath_hw *ah, int delay, u32 value) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ int i; ++ u32 rval = 0; ++ ++ udelay(delay); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ for (i = 0; i < 8; ++i) { ++ rval = rval << 1; ++ ++ /* pattern is left to right, that is 7-th bit runs first */ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN); ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0); ++ udelay(HSR_DELAY_HALF_TICK); ++ } ++ ++ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1); ++ udelay(HSR_DELAY_HALF_TICK); ++ ++ ath_dbg(common, CONFIG, "ath9k_hsr_write_byte: write byte %d return value is %d %c\n", ++ value, rval, rval > 32 ? rval : '-'); ++ ++ return rval & 0xff; ++} ++ ++static int ath9k_hsr_write_a_chain(struct ath_hw *ah, char *chain, int items) ++{ ++ int status = 0; ++ int i = 0; ++ int err; ++ ++ /* a preamble */ ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ ++ /* clear HSR's reply buffer */ ++ if (status) { ++ int loop = 0; ++ ++ for (loop = 0; (loop < 42) && status; ++loop) ++ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, ++ 0); ++ ++ if (loop >= 42) { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_write_a_chain: can't clear an output buffer after a 42 cycles.\n"); ++ return -1; ++ } ++ } ++ ++ for (i = 0; (i < items) && (chain[i] != 0); ++i) ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]); ++ ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ mdelay(HSR_DELAY_FINAL / 1000); ++ ++ /* reply */ ++ memset(chain, 0, items); ++ ++ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ udelay(HSR_DELAY_TRAILING); ++ ++ for (i = 0; i < (items - 1); ++i) { ++ u32 ret; ++ ++ ret = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0); ++ if (ret != 0) ++ chain[i] = (char)ret; ++ else ++ break; ++ ++ udelay(HSR_DELAY_TRAILING); ++ } ++ ++ if (i <= 1) ++ return 0; ++ ++ err = kstrtoint(chain + 1, 10, &i); ++ if (err) ++ return err; ++ ++ return i; ++} ++ ++int ath9k_hsr_disable(struct ath_hw *ah) ++{ ++ char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0}; ++ int ret; ++ ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if ((ret > 0) && (*cmd == 'B')) ++ return 0; ++ ++ return -1; ++} ++ ++int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) ++{ ++ char cmd[10]; ++ int ret; ++ ++ /* Bandwidth argument is 0 sometimes. Assume default 802.11bgn ++ * 20MHz on invalid values ++ */ ++ if ((bw != 5) && (bw != 10) && (bw != 20) && (bw != 40)) ++ bw = 20; ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'b'; ++ snprintf(cmd + 1, 3, "%02d", bw); ++ ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if ((*cmd != 'B') || (ret != bw)) { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d)\n", ++ 'b', bw, *cmd, ret); ++ return -1; ++ } ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'x'; ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if (*cmd != 'X') { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed 'x' command -> reply (%d, %d)\n", ++ *cmd, ret); ++ return -1; ++ } ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'm'; ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if (*cmd != 'M') { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed 'm' command -> reply (%d, %d)\n", ++ *cmd, ret); ++ return -1; ++ } ++ ++ memset(cmd, 0, sizeof(cmd)); ++ *cmd = 'f'; ++ snprintf(cmd + 1, 6, "%05d", fq); ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if ((*cmd != 'F') && (ret != fq)) { ++ ATH_DBG_WARN(1, ++ "ath9k_hsr_enable: failed set frequency -> reply (%d, %d)\n", ++ *cmd, ret); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int ath9k_hsr_status(struct ath_hw *ah) ++{ ++ char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0}; ++ int ret; ++ ++ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd)); ++ if (*cmd != 'S') { ++ ATH_DBG_WARN(1, "ath9k_hsr_status: returned %d,%d\n", *cmd, ++ ret); ++ return -1; ++ } ++ ++ return 0; ++} +--- /dev/null ++++ b/drivers/net/wireless/ath/ath9k/hsr.h +@@ -0,0 +1,48 @@ ++/* ++ * The MIT License (MIT) ++ * ++ * Copyright (c) 2015 Kirill Berezin ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++#ifndef HSR_H ++#define HSR_H ++ ++#ifdef CPTCFG_ATH9K_UBNTHSR ++ ++void ath9k_hsr_init(struct ath_hw *ah); ++int ath9k_hsr_disable(struct ath_hw *ah); ++int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq); ++int ath9k_hsr_status(struct ath_hw *ah); ++ ++#else ++static inline void ath9k_hsr_init(struct ath_hw *ah) {} ++ ++static inline int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq) ++{ ++ return 0; ++} ++ ++static inline int ath9k_hsr_disable(struct ath_hw *ah) { return 0; } ++static inline int ath9k_hsr_status(struct ath_hw *ah) { return 0; } ++ ++#endif ++ ++#endif /* HSR_H */ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -16,8 +16,10 @@ + + #include + #include ++#include + #include "ath9k.h" + #include "btcoex.h" ++#include "hsr.h" + + u8 ath9k_parse_mpdudensity(u8 mpdudensity) + { +@@ -649,6 +651,7 @@ void ath_reset_work(struct work_struct * + static int ath9k_start(struct ieee80211_hw *hw) + { + struct ath_softc *sc = hw->priv; ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan; +@@ -727,6 +730,11 @@ static int ath9k_start(struct ieee80211_ + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + } + ++ if (pdata && pdata->ubnt_hsr) { ++ ath9k_hsr_init(ah); ++ ath9k_hsr_disable(ah); ++ } ++ + /* + * Reset key cache to sane defaults (all entries cleared) instead of + * semi-random values after suspend/resume. +--- a/drivers/net/wireless/ath/ath9k/Makefile ++++ b/drivers/net/wireless/ath/ath9k/Makefile +@@ -16,6 +16,7 @@ ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += d + ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o + ath9k-$(CPTCFG_ATH9K_WOW) += wow.o + ath9k-$(CPTCFG_ATH9K_HWRNG) += rng.o ++ath9k-$(CPTCFG_ATH9K_UBNTHSR) += hsr.o + + ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o + +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -53,6 +53,8 @@ struct ath9k_platform_data { + unsigned num_btns; + const struct gpio_keys_button *btns; + unsigned btn_poll_interval; ++ ++ bool ubnt_hsr; + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ +--- a/local-symbols ++++ b/local-symbols +@@ -114,6 +114,7 @@ ATH9K_WOW= + ATH9K_RFKILL= + ATH9K_CHANNEL_CONTEXT= + ATH9K_PCOEM= ++ATH9K_UBNTHSR= + ATH9K_HTC= + ATH9K_HTC_DEBUGFS= + ATH9K_HWRNG= +--- a/drivers/net/wireless/ath/ath9k/Kconfig ++++ b/drivers/net/wireless/ath/ath9k/Kconfig +@@ -59,6 +59,19 @@ config ATH9K_AHB + Say Y, if you have a SoC with a compatible built-in + wireless MAC. Say N if unsure. + ++config ATH9K_UBNTHSR ++ bool "Ubiquiti UniFi Outdoor Plus HSR support" ++ depends on ATH9K ++ ---help--- ++ This options enables code to control the HSR RF ++ filter in the receive path of the Ubiquiti UniFi ++ Outdoor Plus access point. ++ ++ Say Y if you want to use the access point. The ++ code will only be used if the device is detected, ++ so it does not harm other setup other than occupying ++ a bit of memory. ++ + config ATH9K_DEBUGFS + bool "Atheros ath9k debugging" + depends on ATH9K && DEBUG_FS diff --git a/root/package/kernel/mac80211/patches/552-ahb_of.patch b/root/package/kernel/mac80211/patches/552-ahb_of.patch new file mode 100644 index 00000000..8c20b00d --- /dev/null +++ b/root/package/kernel/mac80211/patches/552-ahb_of.patch @@ -0,0 +1,330 @@ +--- a/drivers/net/wireless/ath/ath9k/ahb.c ++++ b/drivers/net/wireless/ath/ath9k/ahb.c +@@ -19,7 +19,15 @@ + #include + #include + #include ++#include + #include "ath9k.h" ++#include ++ ++#ifdef CONFIG_OF ++#include ++#include ++#include ++#endif + + static const struct platform_device_id ath9k_platform_id_table[] = { + { +@@ -68,6 +76,235 @@ static const struct ath_bus_ops ath_ahb_ + .eeprom_read = ath_ahb_eeprom_read, + }; + ++#ifdef CONFIG_OF ++ ++#define QCA955X_DDR_CTL_CONFIG 0x108 ++#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23) ++ ++static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata) ++{ ++#ifdef CONFIG_MTD ++ struct device_node *mtd_np = NULL; ++ size_t retlen; ++ int size, ret; ++ struct mtd_info *mtd; ++ const char *part; ++ const __be32 *list; ++ phandle phandle; ++ ++ list = of_get_property(np, "mtd-cal-data", &size); ++ if (!list) ++ return 0; ++ ++ if (size != (2 * sizeof(*list))) ++ return 1; ++ ++ phandle = be32_to_cpup(list++); ++ if (phandle) ++ mtd_np = of_find_node_by_phandle(phandle); ++ ++ if (!mtd_np) ++ return 1; ++ ++ part = of_get_property(mtd_np, "label", NULL); ++ if (!part) ++ part = mtd_np->name; ++ ++ mtd = get_mtd_device_nm(part); ++ if (IS_ERR(mtd)) ++ return 1; ++ ++ ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data), ++ &retlen, (u8*)pdata->eeprom_data); ++ put_mtd_device(mtd); ++ ++#endif ++ return 0; ++} ++ ++static int ar913x_wmac_reset(void) ++{ ++ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); ++ mdelay(10); ++ ++ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); ++ mdelay(10); ++ ++ return 0; ++} ++ ++static int ar933x_wmac_reset(void) ++{ ++ int retries = 20; ++ ++ ath79_device_reset_set(AR933X_RESET_WMAC); ++ ath79_device_reset_clear(AR933X_RESET_WMAC); ++ ++ while (1) { ++ u32 bootstrap; ++ ++ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); ++ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0) ++ return 0; ++ ++ if (retries-- == 0) ++ break; ++ ++ udelay(10000); ++ } ++ ++ pr_err("ar933x: WMAC reset timed out"); ++ return -ETIMEDOUT; ++} ++ ++static int qca955x_wmac_reset(void) ++{ ++ int i; ++ ++ /* Try to wait for WMAC DDR activity to stop */ ++ for (i = 0; i < 10; i++) { ++ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) & ++ QCA955X_DDR_CTL_CONFIG_ACT_WMAC)) ++ break; ++ ++ udelay(10); ++ } ++ ++ ath79_device_reset_set(QCA955X_RESET_RTC); ++ udelay(10); ++ ath79_device_reset_clear(QCA955X_RESET_RTC); ++ udelay(10); ++ ++ return 0; ++} ++ ++enum { ++ AR913X_WMAC = 0, ++ AR933X_WMAC, ++ AR934X_WMAC, ++ QCA953X_WMAC, ++ QCA955X_WMAC, ++ QCA956X_WMAC, ++}; ++ ++static int ar9330_get_soc_revision(void) ++{ ++ if (ath79_soc_rev == 1) ++ return ath79_soc_rev; ++ ++ return 0; ++} ++ ++static int ath79_get_soc_revision(void) ++{ ++ return ath79_soc_rev; ++} ++ ++static const struct of_ath_ahb_data { ++ u16 dev_id; ++ u32 bootstrap_reg; ++ u32 bootstrap_ref; ++ ++ int (*soc_revision)(void); ++ int (*wmac_reset)(void); ++} of_ath_ahb_data[] = { ++ [AR913X_WMAC] = { ++ .dev_id = AR5416_AR9100_DEVID, ++ .wmac_reset = ar913x_wmac_reset, ++ ++ }, ++ [AR933X_WMAC] = { ++ .dev_id = AR9300_DEVID_AR9330, ++ .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP, ++ .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40, ++ .soc_revision = ar9330_get_soc_revision, ++ .wmac_reset = ar933x_wmac_reset, ++ }, ++ [AR934X_WMAC] = { ++ .dev_id = AR9300_DEVID_AR9340, ++ .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP, ++ .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40, ++ .soc_revision = ath79_get_soc_revision, ++ }, ++ [QCA953X_WMAC] = { ++ .dev_id = AR9300_DEVID_AR953X, ++ .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP, ++ .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40, ++ .soc_revision = ath79_get_soc_revision, ++ }, ++ [QCA955X_WMAC] = { ++ .dev_id = AR9300_DEVID_QCA955X, ++ .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP, ++ .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40, ++ .wmac_reset = qca955x_wmac_reset, ++ }, ++ [QCA956X_WMAC] = { ++ .dev_id = AR9300_DEVID_QCA956X, ++ .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP, ++ .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40, ++ .soc_revision = ath79_get_soc_revision, ++ }, ++}; ++ ++const struct of_device_id of_ath_ahb_match[] = { ++ { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] }, ++ { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] }, ++ { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] }, ++ { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] }, ++ { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] }, ++ { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, of_ath_ahb_match); ++ ++static int of_ath_ahb_probe(struct platform_device *pdev) ++{ ++ struct ath9k_platform_data *pdata; ++ const struct of_device_id *match; ++ const struct of_ath_ahb_data *data; ++ u8 led_pin; ++ ++ match = of_match_device(of_ath_ahb_match, &pdev->dev); ++ data = (const struct of_ath_ahb_data *)match->data; ++ ++ pdata = dev_get_platdata(&pdev->dev); ++ ++ if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin)) ++ pdata->led_pin = led_pin; ++ else ++ pdata->led_pin = -1; ++ ++ if (of_property_read_bool(pdev->dev.of_node, "qca,disable-2ghz")) ++ pdata->disable_2ghz = true; ++ ++ if (of_property_read_bool(pdev->dev.of_node, "qca,disable-5ghz")) ++ pdata->disable_5ghz = true; ++ ++ if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo")) ++ pdata->tx_gain_buffalo = true; ++ ++ if (data->wmac_reset) { ++ data->wmac_reset(); ++ pdata->external_reset = data->wmac_reset; ++ } ++ ++ if (data->bootstrap_reg && data->bootstrap_ref) { ++ u32 t = ath79_reset_rr(data->bootstrap_reg); ++ if (t & data->bootstrap_ref) ++ pdata->is_clk_25mhz = false; ++ else ++ pdata->is_clk_25mhz = true; ++ } ++ ++ pdata->get_mac_revision = data->soc_revision; ++ ++ if (of_get_wifi_cal(pdev->dev.of_node, pdata)) ++ dev_err(&pdev->dev, "failed to load calibration data from mtd device\n"); ++ ++ return data->dev_id; ++} ++#endif ++ + static int ath_ahb_probe(struct platform_device *pdev) + { + void __iomem *mem; +@@ -79,6 +316,17 @@ static int ath_ahb_probe(struct platform + int ret = 0; + struct ath_hw *ah; + char hw_name[64]; ++ u16 dev_id; ++ ++ if (id) ++ dev_id = id->driver_data; ++ ++#ifdef CONFIG_OF ++ if (pdev->dev.of_node) ++ pdev->dev.platform_data = devm_kzalloc(&pdev->dev, ++ sizeof(struct ath9k_platform_data), ++ GFP_KERNEL); ++#endif + + if (!dev_get_platdata(&pdev->dev)) { + dev_err(&pdev->dev, "no platform data specified\n"); +@@ -121,13 +369,16 @@ static int ath_ahb_probe(struct platform + sc->mem = mem; + sc->irq = irq; + ++#ifdef CONFIG_OF ++ dev_id = of_ath_ahb_probe(pdev); ++#endif + ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); + if (ret) { + dev_err(&pdev->dev, "request_irq failed\n"); + goto err_free_hw; + } + +- ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops); ++ ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops); + if (ret) { + dev_err(&pdev->dev, "failed to initialize device\n"); + goto err_irq; +@@ -158,6 +409,9 @@ static int ath_ahb_remove(struct platfor + free_irq(sc->irq, sc); + ieee80211_free_hw(sc->hw); + } ++#ifdef CONFIG_OF ++ pdev->dev.platform_data = NULL; ++#endif + + return 0; + } +@@ -167,6 +421,9 @@ static struct platform_driver ath_ahb_dr + .remove = ath_ahb_remove, + .driver = { + .name = "ath9k", ++#ifdef CONFIG_OF ++ .of_match_table = of_ath_ahb_match, ++#endif + }, + .id_table = ath9k_platform_id_table, + }; +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include "common.h" + #include "debug.h" +@@ -1023,6 +1024,9 @@ struct ath_softc { + struct ath_hw *sc_ah; + void __iomem *mem; + int irq; ++#ifdef CONFIG_OF ++ struct reset_control *reset; ++#endif + spinlock_t sc_serial_rw; + spinlock_t sc_pm_lock; + spinlock_t sc_pcu_lock; diff --git a/root/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/root/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch new file mode 100644 index 00000000..699989ba --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch @@ -0,0 +1,30 @@ +From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -210,7 +210,7 @@ endif + config RT2800SOC + tristate "Ralink WiSoC support" + depends on m +- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 + select RT2X00_LIB_SOC + select RT2X00_LIB_MMIO + select RT2X00_LIB_CRYPTO +@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI + + config RT2X00_LIB_SOC + tristate "RT2x00 SoC support" +- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620 ++ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620 + depends on m + select RT2X00_LIB + diff --git a/root/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/root/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch new file mode 100644 index 00000000..5127c5cf --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch @@ -0,0 +1,20 @@ +From 4f16582c93a71eba9d389e0f0a8aa9099a9587cd Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: enable support for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -9403,6 +9403,7 @@ static int rt2800_probe_rt(struct rt2x00 + case RT3390: + case RT3572: + case RT3593: ++ case RT3883: + case RT5350: + case RT5390: + case RT5392: diff --git a/root/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/root/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch new file mode 100644 index 00000000..60e57c1b --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch @@ -0,0 +1,112 @@ +From ecb394ccf248d8652c463133c4f404458a57a9c1 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add rf_vals for RF3853 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 4 +- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 65 +++++++++++++++++++++++++++++++ + 2 files changed, 68 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -48,7 +48,8 @@ + * RF2853 2.4G/5G 3T3R + * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) + * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) +- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) ++ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593) ++ * RF3853 2.4G/5G 3T3R(RT3883/RT3662) + * RF5592 2.4G/5G 2T2R + * RF3070 2.4G 1T1R + * RF5360 2.4G 1T1R +@@ -72,6 +73,7 @@ + #define RF5592 0x000f + #define RF3070 0x3070 + #define RF3290 0x3290 ++#define RF3853 0x3853 + #define RF5350 0x5350 + #define RF5360 0x5360 + #define RF5362 0x5362 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -8981,6 +8981,66 @@ static const struct rf_channel rf_vals_3 + {14, 0xF0, 2, 0x18}, + }; + ++static const struct rf_channel rf_vals_3853[] = { ++ {1, 241, 6, 2}, ++ {2, 241, 6, 7}, ++ {3, 242, 6, 2}, ++ {4, 242, 6, 7}, ++ {5, 243, 6, 2}, ++ {6, 243, 6, 7}, ++ {7, 244, 6, 2}, ++ {8, 244, 6, 7}, ++ {9, 245, 6, 2}, ++ {10, 245, 6, 7}, ++ {11, 246, 6, 2}, ++ {12, 246, 6, 7}, ++ {13, 247, 6, 2}, ++ {14, 248, 6, 4}, ++ ++ {36, 0x56, 8, 4}, ++ {38, 0x56, 8, 6}, ++ {40, 0x56, 8, 8}, ++ {44, 0x57, 8, 0}, ++ {46, 0x57, 8, 2}, ++ {48, 0x57, 8, 4}, ++ {52, 0x57, 8, 8}, ++ {54, 0x57, 8, 10}, ++ {56, 0x58, 8, 0}, ++ {60, 0x58, 8, 4}, ++ {62, 0x58, 8, 6}, ++ {64, 0x58, 8, 8}, ++ ++ {100, 0x5b, 8, 8}, ++ {102, 0x5b, 8, 10}, ++ {104, 0x5c, 8, 0}, ++ {108, 0x5c, 8, 4}, ++ {110, 0x5c, 8, 6}, ++ {112, 0x5c, 8, 8}, ++ {114, 0x5c, 8, 10}, ++ {116, 0x5d, 8, 0}, ++ {118, 0x5d, 8, 2}, ++ {120, 0x5d, 8, 4}, ++ {124, 0x5d, 8, 8}, ++ {126, 0x5d, 8, 10}, ++ {128, 0x5e, 8, 0}, ++ {132, 0x5e, 8, 4}, ++ {134, 0x5e, 8, 6}, ++ {136, 0x5e, 8, 8}, ++ {140, 0x5f, 8, 0}, ++ ++ {149, 0x5f, 8, 9}, ++ {151, 0x5f, 8, 11}, ++ {153, 0x60, 8, 1}, ++ {157, 0x60, 8, 5}, ++ {159, 0x60, 8, 7}, ++ {161, 0x60, 8, 9}, ++ {165, 0x61, 8, 1}, ++ {167, 0x61, 8, 3}, ++ {169, 0x61, 8, 5}, ++ {171, 0x61, 8, 7}, ++ {173, 0x61, 8, 9}, ++}; ++ + static const struct rf_channel rf_vals_5592_xtal20[] = { + /* Channel, N, K, mod, R */ + {1, 482, 4, 10, 3}, +@@ -9244,6 +9304,11 @@ static int rt2800_probe_hw_mode(struct r + spec->channels = rf_vals_3x; + break; + ++ case RF3853: ++ spec->num_channels = ARRAY_SIZE(rf_vals_3853); ++ spec->channels = rf_vals_3853; ++ break; ++ + case RF5592: + reg = rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX); + if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { diff --git a/root/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/root/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch new file mode 100644 index 00000000..def2c397 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch @@ -0,0 +1,28 @@ +From f8e3fcf18e1f2d7f9e6a9680c5452da090f33d88 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 1 Aug 2013 14:40:44 +0200 +Subject: [PATCH] rt2x00: rt2800lib: enable VCO calibration for RF3853 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4881,6 +4881,7 @@ void rt2800_vco_calibration(struct rt2x0 + case RF3053: + case RF3070: + case RF3290: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: +@@ -9426,6 +9427,7 @@ static int rt2800_probe_hw_mode(struct r + case RF3053: + case RF3070: + case RF3290: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: diff --git a/root/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch b/root/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch new file mode 100644 index 00000000..1d6e3120 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch @@ -0,0 +1,235 @@ +From 6e3a17190815c6aa4dc53c2cfe9125fb1154f187 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:27 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add channel configuration function for + RF3853 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 208 +++++++++++++++++++++++++++++++ + 1 file changed, 208 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -2713,6 +2713,211 @@ static void rt2800_config_channel_rf3053 + } + } + ++static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_conf *conf, ++ struct rf_channel *rf, ++ struct channel_info *info) ++{ ++ u8 rfcsr; ++ u8 bbp; ++ u8 pwr1, pwr2, pwr3; ++ ++ const bool txbf_enabled = false; /* TODO */ ++ ++ /* TODO: add band selection */ ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ else if (rf->channel < 132) ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x80); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ ++ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); ++ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x46); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x52); ++ ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); ++ ++ switch (rt2x00dev->default_ant.tx_chain_num) { ++ case 3: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); ++ /* fallthrough */ ++ case 2: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); ++ /* fallthrough */ ++ case 1: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); ++ break; ++ } ++ ++ switch (rt2x00dev->default_ant.rx_chain_num) { ++ case 3: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); ++ /* fallthrough */ ++ case 2: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); ++ /* fallthrough */ ++ case 1: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); ++ break; ++ } ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rt2800_freq_cal_mode1(rt2x00dev); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 30); ++ if (!conf_is_ht40(conf)) ++ rfcsr &= ~(0x06); ++ else ++ rfcsr |= 0x06; ++ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 31, 0xa0); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); ++ ++ if (conf_is_ht40(conf)) ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x3c); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); ++ ++ /* loopback RF_BS */ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 36); ++ if (rf->channel <= 14) ++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1); ++ else ++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0); ++ rt2800_rfcsr_write(rt2x00dev, 36, rfcsr); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0x23; ++ else if (rf->channel < 100) ++ rfcsr = 0x36; ++ else if (rf->channel < 132) ++ rfcsr = 0x32; ++ else ++ rfcsr = 0x30; ++ ++ if (txbf_enabled) ++ rfcsr |= 0x40; ++ ++ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x9b); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0xbb; ++ else if (rf->channel < 100) ++ rfcsr = 0xeb; ++ else if (rf->channel < 132) ++ rfcsr = 0xb3; ++ else ++ rfcsr = 0x9b; ++ rt2800_rfcsr_write(rt2x00dev, 45, rfcsr); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0x8e; ++ else ++ rfcsr = 0x8a; ++ ++ if (txbf_enabled) ++ rfcsr |= 0x20; ++ ++ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); ++ ++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 51); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x75); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 52); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x45); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); ++ ++ if (rf->channel <= 14) { ++ pwr1 = info->default_power1 & 0x1f; ++ pwr2 = info->default_power2 & 0x1f; ++ pwr3 = info->default_power3 & 0x1f; ++ } else { ++ pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) | ++ (info->default_power1 & 0x7); ++ pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) | ++ (info->default_power2 & 0x7); ++ pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) | ++ (info->default_power3 & 0x7); ++ } ++ ++ rt2800_rfcsr_write(rt2x00dev, 53, pwr1); ++ rt2800_rfcsr_write(rt2x00dev, 54, pwr2); ++ rt2800_rfcsr_write(rt2x00dev, 55, pwr3); ++ ++ rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n", ++ rf->channel, pwr1, pwr2, pwr3); ++ ++ bbp = (info->default_power1 >> 5) | ++ ((info->default_power2 & 0xe0) >> 1); ++ rt2800_bbp_write(rt2x00dev, 109, bbp); ++ ++ bbp = rt2800_bbp_read(rt2x00dev, 110); ++ bbp &= 0x0f; ++ bbp |= (info->default_power3 & 0xe0) >> 1; ++ rt2800_bbp_write(rt2x00dev, 110, bbp); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 57); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x6e); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); ++ ++ /* Enable RF tuning */ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 3); ++ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); ++ ++ udelay(2000); ++ ++ bbp = rt2800_bbp_read(rt2x00dev, 49); ++ /* clear update flag */ ++ rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe); ++ rt2800_bbp_write(rt2x00dev, 49, bbp); ++ ++ /* TODO: add calibration for TxBF */ ++} ++ + #define POWER_BOUND 0x27 + #define POWER_BOUND_5G 0x2b + +@@ -3570,6 +3775,9 @@ static void rt2800_config_channel(struct + case RF3322: + rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); + break; ++ case RF3853: ++ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); ++ break; + case RF3070: + case RF5350: + case RF5360: diff --git a/root/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch b/root/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch new file mode 100644 index 00000000..6476dc10 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch @@ -0,0 +1,20 @@ +From afd38ae82226551bf879b6c7c4b620c271fee9d2 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 1 Aug 2013 14:42:05 +0200 +Subject: [PATCH] rt2x00: rt2800lib: enable RF3853 support + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -8906,6 +8906,7 @@ static int rt2800_init_eeprom(struct rt2 + case RF3290: + case RF3320: + case RF3322: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: diff --git a/root/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch b/root/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch new file mode 100644 index 00000000..0a931e20 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch @@ -0,0 +1,62 @@ +From 0094872a5e8e4664c6ea1b2dfa487063d39ae363 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add MAC register initialization for + RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 14 ++++++++++++++ + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 19 ++++++++++++++++--- + 2 files changed, 30 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -1727,6 +1727,20 @@ + #define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff) + + /* ++ * TX_TXBF_CFG: ++ */ ++#define TX_TXBF_CFG_0 0x138c ++#define TX_TXBF_CFG_1 0x13a4 ++#define TX_TXBF_CFG_2 0x13a8 ++#define TX_TXBF_CFG_3 0x13ac ++ ++/* ++ * TX_FBK_CFG_3S: ++ */ ++#define TX_FBK_CFG_3S_0 0x13c4 ++#define TX_FBK_CFG_3S_1 0x13c8 ++ ++/* + * RX_FILTER_CFG: RX configuration register. + */ + #define RX_FILTER_CFG 0x1400 +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5509,6 +5509,12 @@ static int rt2800_init_registers(struct + rt2800_register_write(rt2x00dev, TX_SW_CFG2, + 0x00000000); + } ++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000); ++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); ++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT6352)) { +@@ -5722,6 +5728,11 @@ static int rt2800_init_registers(struct + reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); + ++ if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008); ++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413); ++ } ++ + reg = rt2800_register_read(rt2x00dev, TX_RTS_CFG); + rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 7); + rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, diff --git a/root/package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch b/root/package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch new file mode 100644 index 00000000..d68ad504 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch @@ -0,0 +1,30 @@ +From 6c2d32478159fffff0b85abb6817a21bb2338231 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:27 +0100 +Subject: [PATCH] rt2x00: rt2800soc: fix rt2800soc_disable_radio for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s + + static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev) + { ++ u32 reg; ++ + rt2800_disable_radio(rt2x00dev); + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); +- rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); ++ ++ reg = 0; ++ if (rt2x00_rt(rt2x00dev, RT3883)) ++ rt2x00_set_field32(®, TX_PIN_CFG_RFTR_EN, 1); ++ ++ rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg); + } + + static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev, diff --git a/root/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch b/root/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch new file mode 100644 index 00000000..99f57bcd --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch @@ -0,0 +1,71 @@ +From 84833056aa7dd25f5b097e31c78f2a0914c5160c Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:26 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add BBP register initialization for + RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -6349,6 +6349,47 @@ static void rt2800_init_bbp_3593(struct + rt2800_bbp_write(rt2x00dev, 103, 0xc0); + } + ++static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev) ++{ ++ rt2800_init_bbp_early(rt2x00dev); ++ ++ rt2800_bbp_write(rt2x00dev, 4, 0x50); ++ rt2800_bbp_write(rt2x00dev, 47, 0x48); ++ ++ rt2800_bbp_write(rt2x00dev, 86, 0x46); ++ rt2800_bbp_write(rt2x00dev, 88, 0x90); ++ ++ rt2800_bbp_write(rt2x00dev, 92, 0x02); ++ ++ rt2800_bbp_write(rt2x00dev, 103, 0xc0); ++ rt2800_bbp_write(rt2x00dev, 104, 0x92); ++ rt2800_bbp_write(rt2x00dev, 105, 0x34); ++ rt2800_bbp_write(rt2x00dev, 106, 0x12); ++ rt2800_bbp_write(rt2x00dev, 120, 0x50); ++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); ++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); ++ ++ /* Set ITxBF timeout to 0x9C40=1000msec */ ++ rt2800_bbp_write(rt2x00dev, 179, 0x02); ++ rt2800_bbp_write(rt2x00dev, 180, 0x00); ++ rt2800_bbp_write(rt2x00dev, 182, 0x40); ++ rt2800_bbp_write(rt2x00dev, 180, 0x01); ++ rt2800_bbp_write(rt2x00dev, 182, 0x9c); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x00); ++ ++ /* Reprogram the inband interface to put right values in RXWI */ ++ rt2800_bbp_write(rt2x00dev, 142, 0x04); ++ rt2800_bbp_write(rt2x00dev, 143, 0x3b); ++ rt2800_bbp_write(rt2x00dev, 142, 0x06); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa0); ++ rt2800_bbp_write(rt2x00dev, 142, 0x07); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa1); ++ rt2800_bbp_write(rt2x00dev, 142, 0x08); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa2); ++ rt2800_bbp_write(rt2x00dev, 148, 0xc8); ++} ++ + static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) + { + int ant, div_mode; +@@ -6792,6 +6833,9 @@ static void rt2800_init_bbp(struct rt2x0 + case RT3593: + rt2800_init_bbp_3593(rt2x00dev); + return; ++ case RT3883: ++ rt2800_init_bbp_3883(rt2x00dev); ++ return; + case RT5390: + case RT5392: + rt2800_init_bbp_53xx(rt2x00dev); diff --git a/root/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch b/root/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch new file mode 100644 index 00000000..c0f1f586 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch @@ -0,0 +1,178 @@ +From 99c659cf345640fd0f733cbcaf4583cc2c868ec0 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 29 Apr 2013 13:21:48 +0200 +Subject: [PATCH] rt2x00: rt2800lib: add RFCSR initialization for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 + + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 141 +++++++++++++++++++++++++++++++ + 2 files changed, 142 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -2311,6 +2311,7 @@ struct mac_iveiv_entry { + /* + * RFCSR 2: + */ ++#define RFCSR2_RESCAL_BP FIELD8(0x40) + #define RFCSR2_RESCAL_EN FIELD8(0x80) + #define RFCSR2_RX2_EN_MT7620 FIELD8(0x02) + #define RFCSR2_TX2_EN_MT7620 FIELD8(0x20) +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -7707,6 +7707,144 @@ static void rt2800_init_rfcsr_5350(struc + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } + ++static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev) ++{ ++ u8 rfcsr; ++ ++ /* TODO: get the actual ECO value from the SoC */ ++ const unsigned int eco = 5; ++ ++ rt2800_rf_init_calibration(rt2x00dev, 2); ++ ++ rt2800_rfcsr_write(rt2x00dev, 0, 0xe0); ++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50); ++ rt2800_rfcsr_write(rt2x00dev, 3, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 8, 0x5b); ++ rt2800_rfcsr_write(rt2x00dev, 9, 0x08); ++ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3); ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x00); ++ ++ /* RFCSR 17 will be initialized later based on the ++ * frequency offset stored in the EEPROM ++ */ ++ ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0xc0); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 30, 0x10); ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 38, 0x86); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x23); ++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 41, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); ++ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb); ++ rt2800_rfcsr_write(rt2x00dev, 46, 0x60); ++ rt2800_rfcsr_write(rt2x00dev, 47, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 48, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 49, 0x8e); ++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); ++ rt2800_rfcsr_write(rt2x00dev, 53, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 55, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 56, 0xdb); ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); ++ rt2800_rfcsr_write(rt2x00dev, 58, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 59, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 60, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 61, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 62, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 63, 0x00); ++ ++ /* TODO: rx filter calibration? */ ++ ++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); ++ ++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); ++ ++ rt2800_bbp_write(rt2x00dev, 105, 0x05); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x02); ++ rt2800_bbp_write(rt2x00dev, 180, 0x00); ++ rt2800_bbp_write(rt2x00dev, 182, 0x40); ++ rt2800_bbp_write(rt2x00dev, 180, 0x01); ++ rt2800_bbp_write(rt2x00dev, 182, 0x9c); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x00); ++ ++ rt2800_bbp_write(rt2x00dev, 142, 0x04); ++ rt2800_bbp_write(rt2x00dev, 143, 0x3b); ++ rt2800_bbp_write(rt2x00dev, 142, 0x06); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa0); ++ rt2800_bbp_write(rt2x00dev, 142, 0x07); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa1); ++ rt2800_bbp_write(rt2x00dev, 142, 0x08); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa2); ++ rt2800_bbp_write(rt2x00dev, 148, 0xc8); ++ ++ if (eco == 5) { ++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x32); ++ } ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 2); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ msleep(1); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 6); ++ rfcsr |= 0xc0; ++ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 22); ++ rfcsr |= 0x20; ++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 46); ++ rfcsr |= 0x20; ++ rt2800_rfcsr_write(rt2x00dev, 46, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 20); ++ rfcsr &= ~0xee; ++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); ++} ++ + static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) + { + rt2800_rf_init_calibration(rt2x00dev, 2); +@@ -8549,6 +8687,9 @@ static void rt2800_init_rfcsr(struct rt2 + case RT3390: + rt2800_init_rfcsr_3390(rt2x00dev); + break; ++ case RT3883: ++ rt2800_init_rfcsr_3883(rt2x00dev); ++ break; + case RT3572: + rt2800_init_rfcsr_3572(rt2x00dev); + break; diff --git a/root/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch b/root/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch new file mode 100644 index 00000000..e74f399e --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch @@ -0,0 +1,22 @@ +From 86022438ffeb1b87dfcd018bf477fdbb43076691 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 8 May 2013 19:35:33 +0200 +Subject: [PATCH] rt2x00: rt2800lib: use the extended EEPROM map for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -381,7 +381,8 @@ static unsigned int rt2800_eeprom_word_i + wiphy_name(rt2x00dev->hw->wiphy), word)) + return 0; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + map = rt2800_eeprom_map_ext; + else + map = rt2800_eeprom_map; diff --git a/root/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch b/root/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch new file mode 100644 index 00000000..2e917c8e --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch @@ -0,0 +1,21 @@ +From 4cf5403f02fa65dc2207f61d223cffa9ae50e907 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 1 Aug 2013 14:48:21 +0200 +Subject: [PATCH] rt2x00: rt2800lib: force rf type to RF3853 on RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -9083,6 +9083,8 @@ static int rt2800_init_eeprom(struct rt2 + rf = rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID); + else if (rt2x00_rt(rt2x00dev, RT3352)) + rf = RF3322; ++ else if (rt2x00_rt(rt2x00dev, RT3883)) ++ rf = RF3853; + else if (rt2x00_rt(rt2x00dev, RT5350)) + rf = RF5350; + else diff --git a/root/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch b/root/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch new file mode 100644 index 00000000..0bb2d335 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch @@ -0,0 +1,136 @@ +From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:28 +0100 +Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 72 +++++++++++++++++++++++++++++-- + 1 file changed, 69 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3738,6 +3738,36 @@ static char rt2800_txpower_to_dev(struct + return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); + } + ++static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev, ++ struct rf_channel *rf) ++{ ++ u8 bbp; ++ ++ bbp = (rf->channel > 14) ? 0x48 : 0x38; ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp); ++ ++ rt2800_bbp_write(rt2x00dev, 69, 0x12); ++ ++ if (rf->channel <= 14) { ++ rt2800_bbp_write(rt2x00dev, 70, 0x0a); ++ } else { ++ /* Disable CCK packet detection */ ++ rt2800_bbp_write(rt2x00dev, 70, 0x00); ++ } ++ ++ rt2800_bbp_write(rt2x00dev, 73, 0x10); ++ ++ if (rf->channel > 14) { ++ rt2800_bbp_write(rt2x00dev, 62, 0x1d); ++ rt2800_bbp_write(rt2x00dev, 63, 0x1d); ++ rt2800_bbp_write(rt2x00dev, 64, 0x1d); ++ } else { ++ rt2800_bbp_write(rt2x00dev, 62, 0x2d); ++ rt2800_bbp_write(rt2x00dev, 63, 0x2d); ++ rt2800_bbp_write(rt2x00dev, 64, 0x2d); ++ } ++} ++ + static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, +@@ -3756,6 +3786,12 @@ static void rt2800_config_channel(struct + rt2800_txpower_to_dev(rt2x00dev, rf->channel, + info->default_power3); + ++ switch (rt2x00dev->chip.rt) { ++ case RT3883: ++ rt3883_bbp_adjust(rt2x00dev, rf); ++ break; ++ } ++ + switch (rt2x00dev->chip.rf) { + case RF2020: + case RF3020: +@@ -3860,6 +3896,15 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 77, 0x98); ++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); ++ ++ if (rt2x00dev->default_ant.rx_chain_num > 1) ++ rt2800_bbp_write(rt2x00dev, 86, 0x46); ++ else ++ rt2800_bbp_write(rt2x00dev, 86, 0); + } else { + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); +@@ -3873,6 +3918,7 @@ static void rt2800_config_channel(struct + !rt2x00_rt(rt2x00dev, RT6352)) { + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_bbp_write(rt2x00dev, 82, 0x62); ++ rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 75, 0x46); + } else { + if (rt2x00_rt(rt2x00dev, RT3593)) +@@ -3881,19 +3927,22 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 82, 0x84); + rt2800_bbp_write(rt2x00dev, 75, 0x50); + } +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 83, 0x8a); + } + + } else { + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_bbp_write(rt2x00dev, 82, 0x94); +- else if (rt2x00_rt(rt2x00dev, RT3593)) ++ else if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 82, 0x82); + else if (!rt2x00_rt(rt2x00dev, RT6352)) + rt2800_bbp_write(rt2x00dev, 82, 0xf2); + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 83, 0x9a); + + if (rt2x00_has_cap_external_lna_a(rt2x00dev)) +@@ -4019,6 +4068,23 @@ static void rt2800_config_channel(struct + + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); + ++ usleep_range(1000, 1500); ++ } ++ ++ if (rt2x00_rt(rt2x00dev, RT3883)) { ++ if (!conf_is_ht40(conf)) ++ rt2800_bbp_write(rt2x00dev, 105, 0x34); ++ else ++ rt2800_bbp_write(rt2x00dev, 105, 0x04); ++ ++ /* AGC init */ ++ if (rf->channel <= 14) ++ reg = 0x2e + rt2x00dev->lna_gain; ++ else ++ reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3); ++ ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); ++ + usleep_range(1000, 1500); + } + diff --git a/root/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch b/root/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch new file mode 100644 index 00000000..56157510 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch @@ -0,0 +1,30 @@ +From e37d93abaabe3ab72b0332a18092acc162307274 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 30 Sep 2013 13:57:26 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix txpower_to_dev function for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3725,13 +3725,15 @@ static char rt2800_txpower_to_dev(struct + unsigned int channel, + char txpower) + { +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC); + + if (channel <= 14) + return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER); + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return clamp_t(char, txpower, MIN_A_TXPOWER_3593, + MAX_A_TXPOWER_3593); + else diff --git a/root/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch b/root/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch new file mode 100644 index 00000000..c1409bcf --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch @@ -0,0 +1,23 @@ +From c4d79e344bd580d85821390d49f92dced7d8e125 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:29 +0100 +Subject: [PATCH] rt2x00: rt2800lib: use correct txpower calculation function + for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5111,7 +5111,8 @@ static void rt2800_config_txpower(struct + struct ieee80211_channel *chan, + int power_level) + { +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); + else if (rt2x00_rt(rt2x00dev, RT6352)) + rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level); diff --git a/root/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch b/root/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch new file mode 100644 index 00000000..a4ccb285 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch @@ -0,0 +1,33 @@ +From caea0671cd8fd9ade4f5969cbe0ee545e94ae105 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sat, 24 Aug 2013 11:49:55 +0200 +Subject: [PATCH] rt2x00: rt2800lib: hardcode txmixer gain values to zero for + RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -8965,7 +8965,8 @@ static u8 rt2800_get_txmixer_gain_24g(st + { + u16 word; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return 0; + + word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG); +@@ -8979,7 +8980,8 @@ static u8 rt2800_get_txmixer_gain_5g(str + { + u16 word; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return 0; + + word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A); diff --git a/root/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch b/root/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch new file mode 100644 index 00000000..197aabd7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch @@ -0,0 +1,20 @@ +From 11c40fb47c4a4dd6ad060c2ae127ced89ffb9fe1 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Thu, 18 Apr 2013 14:33:33 +0200 +Subject: [PATCH] rt2x00: rt2800lib: use correct [RT]XWI size for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -591,6 +591,7 @@ void rt2800_get_txwi_rxwi_size(struct rt + { + switch (rt2x00dev->chip.rt) { + case RT3593: ++ case RT3883: + *txwi_size = TXWI_DESC_SIZE_4WORDS; + *rxwi_size = RXWI_DESC_SIZE_5WORDS; + break; diff --git a/root/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch b/root/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch new file mode 100644 index 00000000..24c0ef91 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch @@ -0,0 +1,22 @@ +From fa5ad9c025610c22048add2f0ad03f62b6ca1e74 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 30 Sep 2013 16:53:33 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix antenna configuration for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -2017,7 +2017,8 @@ void rt2800_config_ant(struct rt2x00_dev + rt2800_bbp_write(rt2x00dev, 3, r3); + rt2800_bbp_write(rt2x00dev, 1, r1); + +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + if (ant->rx_chain_num == 1) + rt2800_bbp_write(rt2x00dev, 86, 0x00); + else diff --git a/root/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch b/root/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch new file mode 100644 index 00000000..52733ffe --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch @@ -0,0 +1,32 @@ +From 6d668fef3a1baa60bdd715ee062ddb6333d2647c Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Mon, 30 Sep 2013 16:58:23 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix LNA gain configuration for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -2040,7 +2040,8 @@ static void rt2800_config_lna_gain(struc + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_LNA); + lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); + } else if (libconf->rf.channel <= 128) { +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); + lna_gain = rt2x00_get_field16(eeprom, + EEPROM_EXT_LNA2_A1); +@@ -2050,7 +2051,8 @@ static void rt2800_config_lna_gain(struc + EEPROM_RSSI_BG2_LNA_A1); + } + } else { +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); + lna_gain = rt2x00_get_field16(eeprom, + EEPROM_EXT_LNA2_A2); diff --git a/root/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch b/root/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch new file mode 100644 index 00000000..301928d2 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch @@ -0,0 +1,44 @@ +From c49b2d829aa1c816a46a577cdec6d2ff14d9f06e Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 1 Oct 2013 15:40:08 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix VGC setup for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5364,7 +5364,8 @@ static u8 rt2800_get_default_vgc(struct + else + vgc = 0x2e + rt2x00dev->lna_gain; + } else { /* 5GHZ band */ +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; + else if (rt2x00_rt(rt2x00dev, RT5592)) + vgc = 0x24 + (2 * rt2x00dev->lna_gain); +@@ -5384,7 +5385,8 @@ static inline void rt2800_set_vgc(struct + { + if (qual->vgc_level != vgc_level) { + if (rt2x00_rt(rt2x00dev, RT3572) || +- rt2x00_rt(rt2x00dev, RT3593)) { ++ rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, + vgc_level); + } else if (rt2x00_rt(rt2x00dev, RT5592)) { +@@ -5431,6 +5433,11 @@ void rt2800_link_tuner(struct rt2x00_dev + } + break; + ++ case RT3883: ++ if (qual->rssi > -65) ++ vgc += 0x10; ++ break; ++ + case RT5592: + if (qual->rssi > -65) + vgc += 0x20; diff --git a/root/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch b/root/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch new file mode 100644 index 00000000..4bbc7ae4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch @@ -0,0 +1,42 @@ +From 1616650aea676541d4dc8adc6f4219856d193c8b Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Tue, 1 Oct 2013 17:27:57 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix EEPROM LNA validation for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -9098,7 +9098,8 @@ static int rt2800_validate_eeprom(struct + word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2); + if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) + rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); +- if (!rt2x00_rt(rt2x00dev, RT3593)) { ++ if (!rt2x00_rt(rt2x00dev, RT3593) && ++ !rt2x00_rt(rt2x00dev, RT3883)) { + if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || + rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) + rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, +@@ -9118,7 +9119,8 @@ static int rt2800_validate_eeprom(struct + word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2); + if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) + rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); +- if (!rt2x00_rt(rt2x00dev, RT3593)) { ++ if (!rt2x00_rt(rt2x00dev, RT3593) && ++ !rt2x00_rt(rt2x00dev, RT3883)) { + if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || + rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) + rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, +@@ -9126,7 +9128,8 @@ static int rt2800_validate_eeprom(struct + } + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); + +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + word = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); + if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 || + rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff) diff --git a/root/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch b/root/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch new file mode 100644 index 00000000..e752efd0 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch @@ -0,0 +1,22 @@ +From e3871034a0e7c8a95152dc3eafbcc4535398cbdc Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 2 Oct 2013 10:11:59 +0200 +Subject: [PATCH] rt2x00: rt2800lib: fix txpower compensation for RT3883 + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4354,6 +4354,9 @@ static u8 rt2800_compensate_txpower(stru + if (rt2x00_rt(rt2x00dev, RT3593)) + return min_t(u8, txpower, 0xc); + ++ if (rt2x00_rt(rt2x00dev, RT3883)) ++ return min_t(u8, txpower, 0xf); ++ + if (rt2x00_has_cap_power_limit(rt2x00dev)) { + /* + * Check if eirp txpower exceed txpower_limit. diff --git a/root/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch b/root/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch new file mode 100644 index 00000000..342174f8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch @@ -0,0 +1,136 @@ +From 5e67d4f8a46d19748b501c2ef86de3f50d3cfd51 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Sun, 24 Mar 2013 19:26:27 +0100 +Subject: [PATCH] rt2x00: rt2800mmio: add a workaround for spurious + TX_FIFO_STATUS interrupts + +Signed-off-by: Gabor Juhos +--- + drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 72 +++++++++++++++++++++++++----- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 5 +++ + 2 files changed, 65 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -424,9 +424,9 @@ void rt2800mmio_autowake_tasklet(unsigne + } + EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); + +-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) ++static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev, ++ u32 status) + { +- u32 status; + int i; + + /* +@@ -447,29 +447,77 @@ static void rt2800mmio_txstatus_interrup + * Since we have only one producer and one consumer we don't + * need to lock the kfifo. + */ +- for (i = 0; i < rt2x00dev->tx->limit; i++) { +- status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO); +- +- if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) +- break; +- ++ i = 0; ++ do { + if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) { +- rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); ++ rt2x00_warn(rt2x00dev, ++ "TX status FIFO overrun, drop TX status report\n"); + break; + } +- } ++ ++ if (++i >= rt2x00dev->tx->limit) ++ break; ++ ++ status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO); ++ } while (rt2x00_get_field32(status, TX_STA_FIFO_VALID)); + + /* Schedule the tasklet for processing the tx status. */ + tasklet_schedule(&rt2x00dev->txstatus_tasklet); + } + ++#define RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES 4 ++ ++static bool rt2800mmio_txstatus_is_spurious(struct rt2x00_dev *rt2x00dev, ++ u32 txstatus) ++{ ++ if (likely(rt2x00_get_field32(txstatus, TX_STA_FIFO_VALID))) { ++ rt2x00dev->txstatus_irq_retries = 0; ++ return false; ++ } ++ ++ rt2x00dev->txstatus_irq_retries++; ++ ++ /* Ensure that we don't go into an infinite IRQ loop. */ ++ if (rt2x00dev->txstatus_irq_retries >= ++ RT2800MMIO_TXSTATUS_IRQ_MAX_RETRIES) { ++ rt2x00_warn(rt2x00dev, ++ "%u spurious TX_FIFO_STATUS interrupt(s)\n", ++ rt2x00dev->txstatus_irq_retries); ++ rt2x00dev->txstatus_irq_retries = 0; ++ return false; ++ } ++ ++ return true; ++} ++ + irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) + { + struct rt2x00_dev *rt2x00dev = dev_instance; + u32 reg, mask; ++ u32 txstatus = 0; + +- /* Read status and ACK all interrupts */ ++ /* Read status */ + reg = rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR); ++ ++ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { ++ /* Due to unknown reason the hardware generates a ++ * TX_FIFO_STATUS interrupt before the TX_STA_FIFO ++ * register contain valid data. Read the TX status ++ * here to see if we have to process the actual ++ * request. ++ */ ++ txstatus = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO); ++ if (rt2800mmio_txstatus_is_spurious(rt2x00dev, txstatus)) { ++ /* Remove the TX_FIFO_STATUS bit so it won't be ++ * processed in this turn. The hardware will ++ * generate another IRQ for us. ++ */ ++ rt2x00_set_field32(®, ++ INT_SOURCE_CSR_TX_FIFO_STATUS, 0); ++ } ++ } ++ ++ /* ACK interrupts */ + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + + if (!reg) +@@ -486,7 +534,7 @@ irqreturn_t rt2800mmio_interrupt(int irq + mask = ~reg; + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { +- rt2800mmio_txstatus_interrupt(rt2x00dev); ++ rt2800mmio_txstatus_interrupt(rt2x00dev, txstatus); + /* + * Never disable the TX_FIFO_STATUS interrupt. + */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -1000,6 +1000,11 @@ struct rt2x00_dev { + int rf_channel; + + /* ++ * Counter for tx status irq retries (rt2800pci). ++ */ ++ unsigned int txstatus_irq_retries; ++ ++ /* + * Protect the interrupt mask register. + */ + spinlock_t irqmask_lock; diff --git a/root/package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch b/root/package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch new file mode 100644 index 00000000..9d47076f --- /dev/null +++ b/root/package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch @@ -0,0 +1,32 @@ +--- /dev/null ++++ b/include/linux/rt2x00_platform.h +@@ -0,0 +1,19 @@ ++/* ++ * Platform data definition for the rt2x00 driver ++ * ++ * Copyright (C) 2011 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef _RT2X00_PLATFORM_H ++#define _RT2X00_PLATFORM_H ++ ++struct rt2x00_platform_data { ++ char *eeprom_file_name; ++}; ++ ++#endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include + diff --git a/root/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch b/root/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch new file mode 100644 index 00000000..86a95a09 --- /dev/null +++ b/root/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch @@ -0,0 +1,295 @@ +--- a/local-symbols ++++ b/local-symbols +@@ -299,6 +299,7 @@ RT2X00_LIB_FIRMWARE= + RT2X00_LIB_CRYPTO= + RT2X00_LIB_LEDS= + RT2X00_LIB_DEBUGFS= ++RT2X00_LIB_EEPROM= + RT2X00_DEBUG= + WLAN_VENDOR_REALTEK= + RTL8180= +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -69,6 +69,7 @@ config RT2800PCI + select RT2X00_LIB_MMIO + select RT2X00_LIB_PCI + select RT2X00_LIB_FIRMWARE ++ select RT2X00_LIB_EEPROM + select RT2X00_LIB_CRYPTO + depends on CRC_CCITT + depends on EEPROM_93CX6 +@@ -215,6 +216,7 @@ config RT2800SOC + select RT2X00_LIB_MMIO + select RT2X00_LIB_CRYPTO + select RT2X00_LIB_FIRMWARE ++ select RT2X00_LIB_EEPROM + select RT2800_LIB + select RT2800_LIB_MMIO + ---help--- +@@ -265,6 +267,9 @@ config RT2X00_LIB_FIRMWARE + config RT2X00_LIB_CRYPTO + bool + ++config RT2X00_LIB_EEPROM ++ boolean ++ + config RT2X00_LIB_LEDS + bool + default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) +--- a/drivers/net/wireless/ralink/rt2x00/Makefile ++++ b/drivers/net/wireless/ralink/rt2x00/Makefile +@@ -7,6 +7,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) + + rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o + rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o + rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o ++rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o + + obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o + obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -48,6 +48,8 @@ struct rt2800_drv_data { + struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE]; + }; + ++#include "rt2800.h" ++ + struct rt2800_ops { + u32 (*register_read)(struct rt2x00_dev *rt2x00dev, + const unsigned int offset); +@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str + { + const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; + ++ if (rt2x00dev->eeprom_file) { ++ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, ++ EEPROM_SIZE); ++ return 0; ++ } ++ ++ if (!rt2800ops->read_eeprom) ++ return -EINVAL; ++ + return rt2800ops->read_eeprom(rt2x00dev); + } + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st + return retval; + } + +-static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev) +-{ +- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); +- +- if (!base_addr) +- return -ENOMEM; +- +- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); +- +- iounmap(base_addr); +- return 0; +-} +- + /* Firmware functions */ + static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) + { +@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc + .register_multiread = rt2x00mmio_register_multiread, + .register_multiwrite = rt2x00mmio_register_multiwrite, + .regbusy_read = rt2x00mmio_regbusy_read, +- .read_eeprom = rt2800soc_read_eeprom, + .hwcrypt_disabled = rt2800soc_hwcrypt_disabled, + .drv_write_firmware = rt2800soc_write_firmware, + .drv_init_registers = rt2800mmio_init_registers, +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -702,6 +702,7 @@ enum rt2x00_capability_flags { + REQUIRE_HT_TX_DESC, + REQUIRE_PS_AUTOWAKE, + REQUIRE_DELAYED_RFKILL, ++ REQUIRE_EEPROM_FILE, + + /* + * Capabilities +@@ -977,6 +978,11 @@ struct rt2x00_dev { + const struct firmware *fw; + + /* ++ * EEPROM image. ++ */ ++ const struct firmware *eeprom_file; ++ ++ /* + * FIFO for storing tx status reports between isr and tasklet. + */ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1421,6 +1421,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de + INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); + INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); + ++ retval = rt2x00lib_load_eeprom_file(rt2x00dev); ++ if (retval) ++ goto exit; ++ + /* + * Let the driver probe the device to detect the capabilities. + */ +@@ -1562,6 +1566,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ + * Free the driver data. + */ + kfree(rt2x00dev->drv_data); ++ ++ /* ++ * Free EEPROM image. ++ */ ++ rt2x00lib_free_eeprom_file(rt2x00dev); + } + EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); + +--- /dev/null ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +@@ -0,0 +1,105 @@ ++/* ++ Copyright (C) 2004 - 2009 Ivo van Doorn ++ Copyright (C) 2004 - 2009 Gertjan van Wingerde ++ ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the ++ Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ Module: rt2x00lib ++ Abstract: rt2x00 eeprom file loading routines. ++ */ ++ ++#include ++#include ++ ++#include "rt2x00.h" ++#include "rt2x00lib.h" ++ ++static const char * ++rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) ++{ ++ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; ++ ++ if (pdata && pdata->eeprom_file_name) ++ return pdata->eeprom_file_name; ++ ++ return NULL ++} ++ ++static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ const struct firmware *ee; ++ const char *ee_name; ++ int retval; ++ ++ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); ++ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { ++ rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); ++ return -EINVAL; ++ } ++ ++ if (!ee_name) ++ return 0; ++ ++ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); ++ ++ retval = request_firmware(&ee, ee_name, rt2x00dev->dev); ++ if (retval) { ++ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n"); ++ return retval; ++ } ++ ++ if (!ee || !ee->size || !ee->data) { ++ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n"); ++ retval = -ENOENT; ++ goto err_exit; ++ } ++ ++ if (ee->size != rt2x00dev->ops->eeprom_size) { ++ rt2x00_err(rt2x00dev, ++ "EEPROM file size is invalid, it should be %d bytes\n", ++ rt2x00dev->ops->eeprom_size); ++ retval = -EINVAL; ++ goto err_release_ee; ++ } ++ ++ rt2x00dev->eeprom_file = ee; ++ return 0; ++ ++err_release_ee: ++ release_firmware(ee); ++err_exit: ++ return retval; ++} ++ ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ int retval; ++ ++ retval = rt2x00lib_request_eeprom_file(rt2x00dev); ++ if (retval) ++ return retval; ++ ++ return 0; ++} ++ ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ release_firmware(rt2x00dev->eeprom_file); ++ rt2x00dev->eeprom_file = NULL; ++} +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h +@@ -297,6 +297,22 @@ static inline void rt2x00lib_free_firmwa + #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */ + + /* ++ * EEPROM file handlers. ++ */ ++#ifdef CPTCFG_RT2X00_LIB_EEPROM ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev); ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev); ++#else ++static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ return 0; ++} ++static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++} ++#endif /* CPTCFG_RT2X00_LIB_EEPROM */ ++ ++/* + * Debugfs handlers. + */ + #ifdef CPTCFG_RT2X00_LIB_DEBUGFS +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c +@@ -97,6 +97,7 @@ int rt2x00soc_probe(struct platform_devi + if (IS_ERR(rt2x00dev->clk)) + rt2x00dev->clk = NULL; + ++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); + + retval = rt2x00soc_alloc_reg(rt2x00dev); diff --git a/root/package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch b/root/package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch new file mode 100644 index 00000000..9dffef18 --- /dev/null +++ b/root/package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch @@ -0,0 +1,33 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +@@ -26,6 +26,7 @@ + + #include + #include ++#include + + #include "rt2x00.h" + #include "rt2x00lib.h" +@@ -34,11 +35,21 @@ static const char * + rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) + { + struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; ++#ifdef CONFIG_OF ++ struct device_node *np; ++ const char *eep; ++#endif + + if (pdata && pdata->eeprom_file_name) + return pdata->eeprom_file_name; + +- return NULL ++#ifdef CONFIG_OF ++ np = rt2x00dev->dev->of_node; ++ if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0) ++ return eep; ++#endif ++ ++ return NULL; + } + + static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) diff --git a/root/package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/root/package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch new file mode 100644 index 00000000..a98b49c5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch @@ -0,0 +1,108 @@ +From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 17 Mar 2013 00:55:04 +0100 +Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside + OF + +Signed-off-by: John Crispin +--- + drivers/net/wireless/ralink/rt2x00/Kconfig | 1 + + drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 65 +++++++++++++++++++++++ + 2 files changed, 66 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/Kconfig ++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig +@@ -219,6 +219,7 @@ config RT2800SOC + select RT2X00_LIB_EEPROM + select RT2800_LIB + select RT2800_LIB_MMIO ++ select MTD if SOC_RT288X || SOC_RT305X + ---help--- + This adds support for Ralink WiSoC devices. + Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352. +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c +@@ -26,11 +26,73 @@ + + #include + #include ++#include ++#include + #include + + #include "rt2x00.h" + #include "rt2x00lib.h" + ++static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev) ++{ ++ int ret = -EINVAL; ++#ifdef CONFIG_OF ++ static struct firmware mtd_fw; ++ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL; ++ size_t retlen, len = rt2x00dev->ops->eeprom_size; ++ int i, size, offset = 0; ++ struct mtd_info *mtd; ++ const char *part; ++ const __be32 *list; ++ phandle phandle; ++ ++ list = of_get_property(np, "ralink,mtd-eeprom", &size); ++ if (!list) ++ return -ENOENT; ++ ++ phandle = be32_to_cpup(list++); ++ if (phandle) ++ mtd_np = of_find_node_by_phandle(phandle); ++ if (!mtd_np) { ++ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n"); ++ return -EINVAL; ++ } ++ ++ part = of_get_property(mtd_np, "label", NULL); ++ if (!part) ++ part = mtd_np->name; ++ ++ mtd = get_mtd_device_nm(part); ++ if (IS_ERR(mtd)) { ++ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part); ++ return PTR_ERR(mtd); ++ } ++ ++ if (size > sizeof(*list)) ++ offset = be32_to_cpup(list); ++ ++ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom); ++ put_mtd_device(mtd); ++ ++ if ((retlen != rt2x00dev->ops->eeprom_size) || ret) { ++ dev_err(rt2x00dev->dev, "failed to load eeprom from device \"%s\"\n", part); ++ return ret; ++ } ++ ++ if (of_find_property(np, "ralink,mtd-eeprom-swap", NULL)) ++ for (i = 0; i < len/sizeof(u16); i++) ++ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]); ++ ++ rt2x00dev->eeprom_file = &mtd_fw; ++ mtd_fw.size = len; ++ mtd_fw.data = (const u8 *) rt2x00dev->eeprom; ++ ++ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part); ++#endif ++ ++ return ret; ++} ++ + static const char * + rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) + { +@@ -58,6 +120,9 @@ static int rt2x00lib_request_eeprom_file + const char *ee_name; + int retval; + ++ if (!rt2800lib_read_eeprom_mtd(rt2x00dev)) ++ return 0; ++ + ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev); + if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) { + rt2x00_err(rt2x00dev, "Required EEPROM name is missing."); diff --git a/root/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/root/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch new file mode 100644 index 00000000..202dfc0b --- /dev/null +++ b/root/package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch @@ -0,0 +1,47 @@ +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,9 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ ++ int disable_2ghz; ++ int disable_5ghz; + }; + + #endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1026,6 +1026,22 @@ static int rt2x00lib_probe_hw_modes(stru + unsigned int num_rates; + unsigned int i; + ++ if (rt2x00dev->dev->platform_data) { ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata->disable_2ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; ++ if (pdata->disable_5ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; ++ } ++ ++ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) { ++ rt2x00_err(rt2x00dev, "No supported bands\n"); ++ return -EINVAL; ++ } ++ ++ + num_rates = 0; + if (spec->supported_rates & SUPPORT_RATE_CCK) + num_rates += 4; +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -409,6 +409,7 @@ struct hw_mode_spec { + unsigned int supported_bands; + #define SUPPORT_BAND_2GHZ 0x00000001 + #define SUPPORT_BAND_5GHZ 0x00000002 ++#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ) + + unsigned int supported_rates; + #define SUPPORT_RATE_CCK 0x00000001 diff --git a/root/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch b/root/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch new file mode 100644 index 00000000..b8b01880 --- /dev/null +++ b/root/package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch @@ -0,0 +1,26 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1004,8 +1004,13 @@ static void rt2x00lib_rate(struct ieee80 + + void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) + { ++ struct rt2x00_platform_data *pdata; + const char *mac_addr; + ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata && pdata->mac_address) ++ ether_addr_copy(eeprom_mac_addr, pdata->mac_address); ++ + mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); + if (mac_addr) + ether_addr_copy(eeprom_mac_addr, mac_addr); +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,7 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ const u8 *mac_address; + + int disable_2ghz; + int disable_5ghz; diff --git a/root/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch b/root/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch new file mode 100644 index 00000000..ca66aa8e --- /dev/null +++ b/root/package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch @@ -0,0 +1,19 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1030,6 +1030,16 @@ static int rt2x00lib_probe_hw_modes(stru + struct ieee80211_rate *rates; + unsigned int num_rates; + unsigned int i; ++#ifdef CONFIG_OF ++ struct device_node *np = rt2x00dev->dev->of_node; ++ unsigned int enabled; ++ if (!of_property_read_u32(np, "ralink,2ghz", ++ &enabled) && !enabled) ++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; ++ if (!of_property_read_u32(np, "ralink,5ghz", ++ &enabled) && !enabled) ++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; ++#endif /* CONFIG_OF */ + + if (rt2x00dev->dev->platform_data) { + struct rt2x00_platform_data *pdata; diff --git a/root/package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/root/package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch new file mode 100644 index 00000000..02b66e3b --- /dev/null +++ b/root/package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch @@ -0,0 +1,33 @@ +From 04dbd87265f6ba4a373b211ba324b437d224fb2d Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 17 Mar 2013 00:03:31 +0100 +Subject: [PATCH 21/38] rt2x00: make wmac loadable via OF on rt288x/305x SoC + +This patch ads the match table to allow loading the wmac support from a +devicetree. + +Signed-off-by: John Crispin +--- + drivers/net/wireless/ralink/rt2x00/rt2800pci.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -234,10 +234,17 @@ static int rt2800soc_probe(struct platfo + return rt2x00soc_probe(pdev, &rt2800soc_ops); + } + ++static const struct of_device_id rt2880_wmac_match[] = { ++ { .compatible = "ralink,rt2880-wmac" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rt2880_wmac_match); ++ + static struct platform_driver rt2800soc_driver = { + .driver = { + .name = "rt2800_wmac", + .mod_name = KBUILD_MODNAME, ++ .of_match_table = rt2880_wmac_match, + }, + .probe = rt2800soc_probe, + .remove = rt2x00soc_remove, diff --git a/root/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch b/root/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch new file mode 100644 index 00000000..ad70aa78 --- /dev/null +++ b/root/package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch @@ -0,0 +1,40 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include "rt2x00.h" + #include "rt2800lib.h" +@@ -9285,6 +9286,17 @@ static int rt2800_init_eeprom(struct rt2 + rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); + rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); + ++ { ++ struct device_node *np = rt2x00dev->dev->of_node; ++ unsigned int led_polarity; ++ ++ /* Allow overriding polarity from OF */ ++ if (!of_property_read_u32(np, "ralink,led-polarity", ++ &led_polarity)) ++ rt2x00_set_field16(&eeprom, EEPROM_FREQ_LED_POLARITY, ++ led_polarity); ++ } ++ + rt2x00dev->led_mcu_reg = eeprom; + #endif /* CPTCFG_RT2X00_LIB_LEDS */ + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c +@@ -109,6 +109,9 @@ static int rt2x00leds_register_led(struc + led->led_dev.name = name; + led->led_dev.brightness = LED_OFF; + ++ if (rt2x00_is_soc(rt2x00dev)) ++ led->led_dev.brightness_set(&led->led_dev, LED_OFF); ++ + retval = led_classdev_register(device, &led->led_dev); + if (retval) { + rt2x00_err(rt2x00dev, "Failed to register led handler\n"); diff --git a/root/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch b/root/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch new file mode 100644 index 00000000..062b18a6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1361,7 +1361,7 @@ static inline void rt2x00lib_set_if_comb + */ + if_limit = &rt2x00dev->if_limits_ap; + if_limit->max = rt2x00dev->ops->max_ap_intf; +- if_limit->types = BIT(NL80211_IFTYPE_AP); ++ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION); + #ifdef CPTCFG_MAC80211_MESH + if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); + #endif diff --git a/root/package/kernel/mac80211/patches/650-rt2x00-add-support-for-external-PA-on-MT7620.patch b/root/package/kernel/mac80211/patches/650-rt2x00-add-support-for-external-PA-on-MT7620.patch new file mode 100644 index 00000000..9fad80b6 --- /dev/null +++ b/root/package/kernel/mac80211/patches/650-rt2x00-add-support-for-external-PA-on-MT7620.patch @@ -0,0 +1,118 @@ +From 9782a7f7488443568fa4d6088b73c9aff7eb8510 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 19 Apr 2017 16:14:53 +0200 +Subject: [PATCH] rt2x00: add support for external PA on MT7620 +To: Stanislaw Gruszka +Cc: Helmut Schaa , + linux-wireless@vger.kernel.org, + Kalle Valo + +Signed-off-by: Daniel Golle +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 + + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 70 +++++++++++++++++++++++++- + 2 files changed, 70 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -2749,6 +2749,7 @@ enum rt2800_eeprom_word { + #define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f) + #define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0) + #define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600) ++#define EEPROM_NIC_CONF2_EXTERNAL_PA FIELD16(0xc000) + + /* + * EEPROM LNA +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4120,6 +4120,61 @@ static void rt2800_config_channel(struct + rt2800_iq_calibrate(rt2x00dev, rf->channel); + } + ++ if (rt2x00_rt(rt2x00dev, RT6352)) { ++ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, ++ &rt2x00dev->cap_flags)) { ++ rt2x00_warn(rt2x00dev, "Using incomplete support for " \ ++ "external PA\n"); ++ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3); ++ reg |= 0x00000101; ++ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg); ++ ++ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3); ++ reg |= 0x00000101; ++ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); ++ ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 43, 0x73); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 43, 0x73); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 44, 0x73); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 44, 0x73); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 45, 0x73); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0x73); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 46, 0x27); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 46, 0x27); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0xC8); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0xC8); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 48, 0xA4); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 48, 0xA4); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 49, 0x05); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 49, 0x05); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x27); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 55, 0xC8); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 55, 0xC8); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 56, 0xA4); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 56, 0xA4); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 57, 0x05); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 57, 0x05); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 58, 0x27); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 58, 0x27); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 59, 0xC8); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 59, 0xC8); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 60, 0xA4); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 60, 0xA4); ++ rt2800_rfcsr_write_bank(rt2x00dev, 4, 61, 0x05); ++ rt2800_rfcsr_write_bank(rt2x00dev, 6, 61, 0x05); ++ rt2800_rfcsr_write_bank(rt2x00dev, 5, 05, 0x00); ++ rt2800_rfcsr_write_bank(rt2x00dev, 7, 05, 0x00); ++ ++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, ++ 0x36303636); ++ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, ++ 0x6C6C6B6C); ++ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, ++ 0x6C6C6B6C); ++ } ++ } ++ + bbp = rt2800_bbp_read(rt2x00dev, 4); + rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); + rt2800_bbp_write(rt2x00dev, 4, bbp); +@@ -9314,7 +9369,8 @@ static int rt2800_init_eeprom(struct rt2 + */ + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1); + +- if (rt2x00_rt(rt2x00dev, RT3352)) { ++ if (rt2x00_rt(rt2x00dev, RT3352) || ++ rt2x00_rt(rt2x00dev, RT6352)) { + if (rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) + __set_bit(CAPABILITY_EXTERNAL_PA_TX0, +@@ -9325,6 +9381,18 @@ static int rt2800_init_eeprom(struct rt2 + &rt2x00dev->cap_flags); + } + ++ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF2); ++ ++ if (rt2x00_rt(rt2x00dev, RT6352) && eeprom != 0 && eeprom != 0xffff) { ++ if (rt2x00_get_field16(eeprom, ++ EEPROM_NIC_CONF2_EXTERNAL_PA)) { ++ __set_bit(CAPABILITY_EXTERNAL_PA_TX0, ++ &rt2x00dev->cap_flags); ++ __set_bit(CAPABILITY_EXTERNAL_PA_TX1, ++ &rt2x00dev->cap_flags); ++ } ++ } ++ + return 0; + } + diff --git a/root/package/kernel/mac80211/patches/651-rt2x00-remove-unneccesary-code.patch b/root/package/kernel/mac80211/patches/651-rt2x00-remove-unneccesary-code.patch new file mode 100644 index 00000000..475fcbc2 --- /dev/null +++ b/root/package/kernel/mac80211/patches/651-rt2x00-remove-unneccesary-code.patch @@ -0,0 +1,132 @@ +From pozega.tomislav@gmail.com Thu May 18 12:42:27 2017 +Return-path: +Envelope-to: daniel@makrotopia.org +Delivery-date: Thu, 18 May 2017 12:42:27 +0200 +Received: from mail by fudo.makrotopia.org with sa-checked (Exim 4.88) + (envelope-from ) + id 1dBIsy-00088b-PU + for daniel@makrotopia.org; Thu, 18 May 2017 12:42:27 +0200 +X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on fudo.makrotopia.org +X-Spam-Level: +X-Spam-Status: No, score=-0.8 required=2.5 tests=DKIM_SIGNED,DKIM_VALID, + DKIM_VALID_AU,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_LOW shortcircuit=no + autolearn=ham autolearn_force=no version=3.4.1 +Received: from mail-oi0-x22a.google.com ([2607:f8b0:4003:c06::22a]) + by fudo.makrotopia.org with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) + (Exim 4.88) + (envelope-from ) + id 1dBIsv-00088Q-Dq + for daniel@makrotopia.org; Thu, 18 May 2017 12:42:24 +0200 +Received: by mail-oi0-x22a.google.com with SMTP id w10so48782189oif.0 + for ; Thu, 18 May 2017 03:42:21 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20161025; + h=mime-version:from:date:message-id:subject:to; + bh=9dF7PHDassYY74+N6dAhmsL/B9i5oG3SEuMzHuazhJo=; + b=cBGJ44v+o4ASyCPmHCBRMmRYnJCv4Gx6lzDiScKn0XqYmNHYpZTPg5cAY1GZFUhHdz + 9QT5fzhJKFikBliSuJc/7/pI8KzvyEAdvawiWA7/5fbeiTZ+zjJnzRVGezqkYDKxjR6u + 7TsoJxR2/oFwo7bOFlThhee+Nwf7qaX8AVal7JdkqovekX79JQ5vsKAa4LapDp7Cl0wr + KCh0WRUHGEgpTLJFyQ3ThPmLqc8bhmu+6/V/LJ53VOY7uksZHMhvaKkk9vDCoOuPnBMK + Cj2/c7z9RTErz/xlHg6HxnBe/pPc31XUsuPJUleOEdZASczPsreEEKacKCONVlP1wjAB + iOkA== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20161025; + h=x-gm-message-state:mime-version:from:date:message-id:subject:to; + bh=9dF7PHDassYY74+N6dAhmsL/B9i5oG3SEuMzHuazhJo=; + b=LJAe4ZwS9aNJypROW7j+I9aNfRBWyDYy0c8ABnDbLrIoF9P2AA/Vs/Cli5f7GjaAxr + 1JCx602ach+7R7QjQq/nqNmLuhRCfSvB0TGrq4R4v+CJ4ADO541+PddnFiU1dlIXQRP2 + TE2FOydSO0FGJBMg+kY0eFiidBtYj1T5x7IHAhQzufiuiF6/1xZS8h61CYJjLzt/aR5y + JxOxsVvu3W2YQ0T5wKmAPlKtarFH6ZZgs446bRYt1MX5KAWzIoBM1+IPMMv7lSCpCaDR + fwH05aDyaJW2IzXH5R9Tq7gGYycYjx/SnO7JupJXJVvOzKgBJxp60JwJhCfqCwESDuuD + 8nNA== +X-Gm-Message-State: AODbwcDOpdFZgbxAxFsVsqFdCBN3pRGDvEclZ1heVg2byNZ9BuG5kqJg + GvZ9x4NGt0v8lVGa3esDw0N1KiJENg== +X-Received: by 10.157.17.217 with SMTP id y25mr1310632oty.137.1495104134863; + Thu, 18 May 2017 03:42:14 -0700 (PDT) +MIME-Version: 1.0 +Received: by 10.157.0.105 with HTTP; Thu, 18 May 2017 03:42:14 -0700 (PDT) +From: Tom Psyborg +Date: Thu, 18 May 2017 12:42:14 +0200 +Message-ID: +Subject: [PATCH] rt2x00: remove unneccesary code +To: linux-wireless , + Linux Kernel Mailing List , Arnd Bergmann , + Jes Sorensen , Stanislaw Gruszka , + David Miller , Helmut Schaa , + Kalle Valo , Daniel Golle , + Mathias Kresin , Johannes Berg , + Serge Vasilugin , Roman Yeryomin , + Networking +Content-Type: multipart/alternative; boundary="94eb2c1905d2dc6361054fca0e62" +Status: RO +Content-Length: 11079 +Lines: 178 + +--94eb2c1905d2dc6361054fca0e62 +Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + +Use chanreg and dccal helpers to reduce the size of ePA code. + +Signed-off-by: Tomislav Po=C5=BEega +Signed-off-by: Daniel Golle +[daniel@makrotopia.org: fixed white-space so patch applies] +--- + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -4133,38 +4133,22 @@ static void rt2800_config_channel(struct + reg |= 0x00000101; + rt2800_register_write(rt2x00dev, RF_BYPASS3, reg); + +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 43, 0x73); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 43, 0x73); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 44, 0x73); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 44, 0x73); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 45, 0x73); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0x73); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 46, 0x27); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 46, 0x27); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0xC8); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0xC8); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 48, 0xA4); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 48, 0xA4); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 49, 0x05); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 49, 0x05); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x27); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 55, 0xC8); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 55, 0xC8); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 56, 0xA4); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 56, 0xA4); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 57, 0x05); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 57, 0x05); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 58, 0x27); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 58, 0x27); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 59, 0xC8); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 59, 0xC8); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 60, 0xA4); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 60, 0xA4); +- rt2800_rfcsr_write_bank(rt2x00dev, 4, 61, 0x05); +- rt2800_rfcsr_write_bank(rt2x00dev, 6, 61, 0x05); +- rt2800_rfcsr_write_bank(rt2x00dev, 5, 05, 0x00); +- rt2800_rfcsr_write_bank(rt2x00dev, 7, 05, 0x00); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4); ++ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05); ++ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00); + + rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT, + 0x36303636); diff --git a/root/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch b/root/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch new file mode 100644 index 00000000..a901a44b --- /dev/null +++ b/root/package/kernel/mac80211/patches/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -0,0 +1,10 @@ +--- a/drivers/net/wireless/marvell/mwl8k.c ++++ b/drivers/net/wireless/marvell/mwl8k.c +@@ -5681,6 +5681,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") + MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); + + static const struct pci_device_id mwl8k_pci_id_table[] = { ++ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, diff --git a/root/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch b/root/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch new file mode 100644 index 00000000..885bc246 --- /dev/null +++ b/root/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch @@ -0,0 +1,21 @@ +--- a/drivers/net/wireless/marvell/libertas/cfg.c ++++ b/drivers/net/wireless/marvell/libertas/cfg.c +@@ -2040,6 +2040,8 @@ struct wireless_dev *lbs_cfg_alloc(struc + goto err_wiphy_new; + } + ++ set_wiphy_dev(wdev->wiphy, dev); ++ + return wdev; + + err_wiphy_new: +--- a/drivers/net/wireless/marvell/libertas/main.c ++++ b/drivers/net/wireless/marvell/libertas/main.c +@@ -930,6 +930,7 @@ struct lbs_private *lbs_add_card(void *c + goto err_adapter; + } + ++ dev_net_set(dev, wiphy_net(wdev->wiphy)); + dev->ieee80211_ptr = wdev; + dev->ml_priv = priv; + SET_NETDEV_DEV(dev, dmdev); diff --git a/root/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch b/root/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch new file mode 100644 index 00000000..089ad2fe --- /dev/null +++ b/root/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/marvell/libertas/cfg.c ++++ b/drivers/net/wireless/marvell/libertas/cfg.c +@@ -2116,6 +2116,8 @@ int lbs_cfg_register(struct lbs_private + wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + wdev->wiphy->reg_notifier = lbs_reg_notifier; + ++ memcpy(wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN); ++ + ret = wiphy_register(wdev->wiphy); + if (ret < 0) + pr_err("cannot register wiphy device\n"); diff --git a/root/package/kernel/mac80211/patches/810-b43-gpio-mask-module-option.patch b/root/package/kernel/mac80211/patches/810-b43-gpio-mask-module-option.patch new file mode 100644 index 00000000..5ce49d3a --- /dev/null +++ b/root/package/kernel/mac80211/patches/810-b43-gpio-mask-module-option.patch @@ -0,0 +1,37 @@ +--- a/drivers/net/wireless/broadcom/b43/b43.h ++++ b/drivers/net/wireless/broadcom/b43/b43.h +@@ -839,6 +839,7 @@ struct b43_wldev { + bool qos_enabled; /* TRUE, if QoS is used. */ + bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ + bool use_pio; /* TRUE if next init should use PIO */ ++ int gpiomask; /* GPIO LED mask as a module parameter */ + + /* PHY/Radio device. */ + struct b43_phy phy; +--- a/drivers/net/wireless/broadcom/b43/main.c ++++ b/drivers/net/wireless/broadcom/b43/main.c +@@ -85,6 +85,11 @@ MODULE_FIRMWARE("b43/ucode40.fw"); + MODULE_FIRMWARE("b43/ucode42.fw"); + MODULE_FIRMWARE("b43/ucode9.fw"); + ++static int modparam_gpiomask = 0x000F; ++module_param_named(gpiomask, modparam_gpiomask, int, 0444); ++MODULE_PARM_DESC(gpiomask, ++ "GPIO mask for LED control (default 0x000F)"); ++ + static int modparam_bad_frames_preempt; + module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); + MODULE_PARM_DESC(bad_frames_preempt, +@@ -2892,10 +2897,10 @@ static int b43_gpio_init(struct b43_wlde + u32 mask, set; + + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); +- b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); ++ b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, modparam_gpiomask); + + mask = 0x0000001F; +- set = 0x0000000F; ++ set = modparam_gpiomask; + if (dev->dev->chip_id == 0x4301) { + mask |= 0x0060; + set |= 0x0060; diff --git a/root/package/kernel/mac80211/patches/811-b43_no_pio.patch b/root/package/kernel/mac80211/patches/811-b43_no_pio.patch new file mode 100644 index 00000000..d23387c8 --- /dev/null +++ b/root/package/kernel/mac80211/patches/811-b43_no_pio.patch @@ -0,0 +1,86 @@ +--- a/drivers/net/wireless/broadcom/b43/Makefile ++++ b/drivers/net/wireless/broadcom/b43/Makefile +@@ -17,7 +17,7 @@ b43-$(CPTCFG_B43_PHY_AC) += phy_ac.o + b43-y += sysfs.o + b43-y += xmit.o + b43-y += dma.o +-b43-y += pio.o ++b43-$(CPTCFG_B43_PIO) += pio.o + b43-y += rfkill.o + b43-y += ppr.o + b43-$(CPTCFG_B43_LEDS) += leds.o +--- a/drivers/net/wireless/broadcom/b43/main.c ++++ b/drivers/net/wireless/broadcom/b43/main.c +@@ -2018,10 +2018,12 @@ static void b43_do_interrupt_thread(stru + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); ++#ifdef CPTCFG_B43_PIO + b43err(dev->wl, "This device does not support DMA " + "on your system. It will now be switched to PIO.\n"); + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; ++#endif + b43_controller_restart(dev, "DMA error"); + return; + } +--- a/drivers/net/wireless/broadcom/b43/pio.h ++++ b/drivers/net/wireless/broadcom/b43/pio.h +@@ -150,7 +150,7 @@ static inline void b43_piorx_write32(str + b43_write32(q->dev, q->mmio_base + offset, value); + } + +- ++#ifdef CPTCFG_B43_PIO + int b43_pio_init(struct b43_wldev *dev); + void b43_pio_free(struct b43_wldev *dev); + +@@ -161,5 +161,37 @@ void b43_pio_rx(struct b43_pio_rxqueue * + + void b43_pio_tx_suspend(struct b43_wldev *dev); + void b43_pio_tx_resume(struct b43_wldev *dev); ++#else ++static inline int b43_pio_init(struct b43_wldev *dev) ++{ ++ return 0; ++} ++ ++static inline void b43_pio_free(struct b43_wldev *dev) ++{ ++} ++ ++static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++static inline void b43_pio_handle_txstatus(struct b43_wldev *dev, ++ const struct b43_txstatus *status) ++{ ++} ++ ++static inline void b43_pio_rx(struct b43_pio_rxqueue *q) ++{ ++} ++ ++static inline void b43_pio_tx_suspend(struct b43_wldev *dev) ++{ ++} ++ ++static inline void b43_pio_tx_resume(struct b43_wldev *dev) ++{ ++} ++#endif /* CPTCFG_B43_PIO */ + + #endif /* B43_PIO_H_ */ +--- a/drivers/net/wireless/broadcom/b43/Kconfig ++++ b/drivers/net/wireless/broadcom/b43/Kconfig +@@ -98,7 +98,7 @@ config B43_BCMA_PIO + default y + + config B43_PIO +- bool ++ bool "Broadcom 43xx PIO support" + depends on B43 && B43_SSB + select SSB_BLOCKIO + default y diff --git a/root/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch b/root/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch new file mode 100644 index 00000000..932c83b4 --- /dev/null +++ b/root/package/kernel/mac80211/patches/812-b43-add-antenna-control.patch @@ -0,0 +1,131 @@ +--- a/drivers/net/wireless/broadcom/b43/main.c ++++ b/drivers/net/wireless/broadcom/b43/main.c +@@ -1658,7 +1658,7 @@ static void b43_write_beacon_template(st + len, ram_offset, shm_size_offset, rate); + + /* Write the PHY TX control parameters. */ +- antenna = B43_ANTENNA_DEFAULT; ++ antenna = dev->tx_antenna; + antenna = b43_antenna_to_phyctl(antenna); + ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); + /* We can't send beacons with short preamble. Would get PHY errors. */ +@@ -3307,8 +3307,8 @@ static int b43_chip_init(struct b43_wlde + + /* Select the antennae */ + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT); +- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + + if (phy->type == B43_PHYTYPE_B) { + value16 = b43_read16(dev, 0x005E); +@@ -4008,7 +4008,6 @@ static int b43_op_config(struct ieee8021 + struct b43_wldev *dev = wl->current_dev; + struct b43_phy *phy = &dev->phy; + struct ieee80211_conf *conf = &hw->conf; +- int antenna; + int err = 0; + + mutex_lock(&wl->mutex); +@@ -4051,11 +4050,9 @@ static int b43_op_config(struct ieee8021 + } + + /* Antennas for RX and management frame TX. */ +- antenna = B43_ANTENNA_DEFAULT; +- b43_mgmtframe_txantenna(dev, antenna); +- antenna = B43_ANTENNA_DEFAULT; ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, antenna); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); + + if (wl->radio_enabled != phy->radio_on) { + if (wl->radio_enabled) { +@@ -5199,6 +5196,47 @@ static int b43_op_get_survey(struct ieee + return 0; + } + ++static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ if (tx_ant == 1 && rx_ant == 1) { ++ dev->tx_antenna = B43_ANTENNA0; ++ dev->rx_antenna = B43_ANTENNA0; ++ } ++ else if (tx_ant == 2 && rx_ant == 2) { ++ dev->tx_antenna = B43_ANTENNA1; ++ dev->rx_antenna = B43_ANTENNA1; ++ } ++ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) { ++ dev->tx_antenna = B43_ANTENNA_DEFAULT; ++ dev->rx_antenna = B43_ANTENNA_DEFAULT; ++ } ++ else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++ ++static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ switch (dev->tx_antenna) { ++ case B43_ANTENNA0: ++ *tx_ant = 1; *rx_ant = 1; break; ++ case B43_ANTENNA1: ++ *tx_ant = 2; *rx_ant = 2; break; ++ case B43_ANTENNA_DEFAULT: ++ *tx_ant = 3; *rx_ant = 3; break; ++ } ++ return 0; ++} ++ + static const struct ieee80211_ops b43_hw_ops = { + .tx = b43_op_tx, + .conf_tx = b43_op_conf_tx, +@@ -5220,6 +5258,8 @@ static const struct ieee80211_ops b43_hw + .sw_scan_complete = b43_op_sw_scan_complete_notifier, + .get_survey = b43_op_get_survey, + .rfkill_poll = b43_rfkill_poll, ++ .set_antenna = b43_op_set_antenna, ++ .get_antenna = b43_op_get_antenna, + }; + + /* Hard-reset the chip. Do not call this directly. +@@ -5523,6 +5563,8 @@ static int b43_one_core_attach(struct b4 + if (!wldev) + goto out; + ++ wldev->rx_antenna = B43_ANTENNA_DEFAULT; ++ wldev->tx_antenna = B43_ANTENNA_DEFAULT; + wldev->use_pio = b43_modparam_pio; + wldev->dev = dev; + wldev->wl = wl; +@@ -5617,6 +5659,9 @@ static struct b43_wl *b43_wireless_init( + + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + ++ hw->wiphy->available_antennas_rx = 0x3; ++ hw->wiphy->available_antennas_tx = 0x3; ++ + wl->hw_registred = false; + hw->max_rates = 2; + SET_IEEE80211_DEV(hw, dev->dev); +--- a/drivers/net/wireless/broadcom/b43/b43.h ++++ b/drivers/net/wireless/broadcom/b43/b43.h +@@ -840,6 +840,8 @@ struct b43_wldev { + bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ + bool use_pio; /* TRUE if next init should use PIO */ + int gpiomask; /* GPIO LED mask as a module parameter */ ++ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */ ++ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */ + + /* PHY/Radio device. */ + struct b43_phy phy; diff --git a/root/package/kernel/mac80211/patches/813-b43-reduce-number-of-RX-slots.patch b/root/package/kernel/mac80211/patches/813-b43-reduce-number-of-RX-slots.patch new file mode 100644 index 00000000..58997068 --- /dev/null +++ b/root/package/kernel/mac80211/patches/813-b43-reduce-number-of-RX-slots.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/broadcom/b43/dma.h ++++ b/drivers/net/wireless/broadcom/b43/dma.h +@@ -169,7 +169,7 @@ struct b43_dmadesc_generic { + + /* DMA engine tuning knobs */ + #define B43_TXRING_SLOTS 256 +-#define B43_RXRING_SLOTS 256 ++#define B43_RXRING_SLOTS 32 + #define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN) + #define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN) + diff --git a/root/package/kernel/mac80211/patches/814-b43-only-use-gpio-0-1-for-led.patch b/root/package/kernel/mac80211/patches/814-b43-only-use-gpio-0-1-for-led.patch new file mode 100644 index 00000000..03f4524c --- /dev/null +++ b/root/package/kernel/mac80211/patches/814-b43-only-use-gpio-0-1-for-led.patch @@ -0,0 +1,17 @@ +--- a/drivers/net/wireless/broadcom/b43/main.c ++++ b/drivers/net/wireless/broadcom/b43/main.c +@@ -2909,6 +2909,14 @@ static int b43_gpio_init(struct b43_wlde + } else if (dev->dev->chip_id == 0x5354) { + /* Don't allow overtaking buttons GPIOs */ + set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ ++ } else if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 || ++ dev->dev->chip_id == BCMA_CHIP_ID_BCM47162 || ++ dev->dev->chip_id == BCMA_CHIP_ID_BCM5356 || ++ dev->dev->chip_id == BCMA_CHIP_ID_BCM5357 || ++ dev->dev->chip_id == BCMA_CHIP_ID_BCM53572) { ++ /* just use gpio 0 and 1 for 2.4 GHz wifi led */ ++ set &= 0x3; ++ mask &= 0x3; + } + + if (0 /* FIXME: conditional unknown */ ) { diff --git a/root/package/kernel/mac80211/patches/815-b43-always-take-overlapping-devs.patch b/root/package/kernel/mac80211/patches/815-b43-always-take-overlapping-devs.patch new file mode 100644 index 00000000..f07151aa --- /dev/null +++ b/root/package/kernel/mac80211/patches/815-b43-always-take-overlapping-devs.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/broadcom/b43/main.c ++++ b/drivers/net/wireless/broadcom/b43/main.c +@@ -127,7 +127,7 @@ static int b43_modparam_pio = 0; + module_param_named(pio, b43_modparam_pio, int, 0644); + MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); + +-static int modparam_allhwsupport = !IS_ENABLED(CPTCFG_BRCMSMAC); ++static int modparam_allhwsupport = 1; + module_param_named(allhwsupport, modparam_allhwsupport, int, 0444); + MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)"); + diff --git a/root/package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch b/root/package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch new file mode 100644 index 00000000..3c93386b --- /dev/null +++ b/root/package/kernel/mac80211/patches/850-brcmsmac-remove-extra-regulation-restriction.patch @@ -0,0 +1,27 @@ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c +@@ -58,19 +58,12 @@ + (((c) < 149) ? 3 : 4)))) + + #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) +-#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ +- NL80211_RRF_NO_IR) ++#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, 0) + +-#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ +- NL80211_RRF_NO_IR) +-#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ +- NL80211_RRF_DFS | \ +- NL80211_RRF_NO_IR) +-#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ +- NL80211_RRF_DFS | \ +- NL80211_RRF_NO_IR) +-#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ +- NL80211_RRF_NO_IR) ++#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, 0) ++#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, 0) ++#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, 0) ++#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, 0) + + static const struct ieee80211_regdomain brcms_regdom_x2 = { + .n_reg_rules = 6, diff --git a/root/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch b/root/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch new file mode 100644 index 00000000..3afffc0f --- /dev/null +++ b/root/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch @@ -0,0 +1,66 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 8 Jun 2015 16:11:40 +0200 +Subject: [PATCH] brcmfmac: register wiphy(s) during module_init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is needed by OpenWrt which expects all PHYs to be created after +module loads successfully. + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1314,6 +1314,7 @@ int __init brcmf_core_init(void) + { + if (!schedule_work(&brcmf_driver_work)) + return -EBUSY; ++ flush_work(&brcmf_driver_work); + + return 0; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -441,6 +441,7 @@ struct brcmf_fw { + struct brcmf_fw_request *req; + u32 curpos; + void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); ++ struct completion *completion; + }; + + static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); +@@ -589,6 +590,8 @@ fail: + fwctx->req = NULL; + done: + fwctx->done(fwctx->dev, ret, fwctx->req); ++ if (fwctx->completion) ++ complete(fwctx->completion); + kfree(fwctx); + } + +@@ -612,6 +615,8 @@ int brcmf_fw_get_firmwares(struct device + struct brcmf_fw_request *req)) + { + struct brcmf_fw *fwctx; ++ struct completion completion; ++ int err; + + brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); + if (!fw_cb) +@@ -628,7 +633,14 @@ int brcmf_fw_get_firmwares(struct device + fwctx->req = req; + fwctx->done = fw_cb; + ++ init_completion(&completion); ++ fwctx->completion = &completion; ++ + brcmf_fw_request_next_item(fwctx, true); ++ ++ wait_for_completion_timeout(fwctx->completion, msecs_to_jiffies(5000)); ++ fwctx->completion = NULL; ++ + return 0; + } + diff --git a/root/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/root/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch new file mode 100644 index 00000000..1345e85f --- /dev/null +++ b/root/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch @@ -0,0 +1,50 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 9 Jul 2015 00:07:59 +0200 +Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +--- + +--- 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; + struct wireless_dev *wdev; + int err; + ++ /* ++ * There is a bug with in-firmware BSS management. When adding virtual ++ * interface brcmfmac first tells firmware to create new BSS and then ++ * it creates new struct net_device. ++ * ++ * If creating/registering netdev(ice) fails, BSS remains in some bugged ++ * state. It conflicts with existing BSSes by overtaking their auth ++ * requests. ++ * ++ * It results in one BSS (addresss X) sending beacons and another BSS ++ * (address Y) replying to authentication requests. This makes interface ++ * unusable as AP. ++ * ++ * To workaround this bug we may try to guess if register_netdev(ice) ++ * will fail. The most obvious case is using interface name that already ++ * exists. This is actually quite likely with brcmfmac & some user space ++ * scripts as brcmfmac doesn't allow deleting virtual interfaces. ++ * So this bug can be triggered even by something trivial like: ++ * iw dev wlan0 delete ++ * iw phy phy0 interface add wlan0 type __ap ++ */ ++ dev = dev_get_by_name(&init_net, name); ++ if (dev) { ++ dev_put(dev); ++ return ERR_PTR(-ENFILE); ++ } ++ + brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); + err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); + if (err) { diff --git a/root/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch b/root/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch new file mode 100644 index 00000000..9b360590 --- /dev/null +++ b/root/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch @@ -0,0 +1,27 @@ +From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 9 Mar 2016 17:25:59 +0000 +Subject: [PATCH] brcmfmac: Disable power management + +Disable wireless power saving in the brcmfmac WLAN driver. This is a +temporary measure until the connectivity loss resulting from power +saving is resolved. + +Signed-off-by: Phil Elwell +--- + drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- 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 + * preference in cfg struct to apply this to + * FW later while initializing the dongle + */ ++#if defined(CONFIG_ARCH_BCM2835) ++ brcmf_dbg(INFO, "power management disabled\n"); ++ enabled = false; ++#endif + cfg->pwr_save = enabled; + if (!check_vif_up(ifp->vif)) { + diff --git a/root/package/kernel/mac80211/patches/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/root/package/kernel/mac80211/patches/863-brcmfmac-add-in-driver-tables-with-country-codes.patch new file mode 100644 index 00000000..e7551c3a --- /dev/null +++ b/root/package/kernel/mac80211/patches/863-brcmfmac-add-in-driver-tables-with-country-codes.patch @@ -0,0 +1,60 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Subject: [PATCH] brcmfmac: add in-driver tables with country codes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds early support for changing region. Ideally this data should +be stored in DT as all these mappings are devices specific. + +Signed-off-by: RafaÅ‚ MiÅ‚ecki +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -23,6 +23,36 @@ + #include "common.h" + #include "of.h" + ++/* TODO: FIXME: Use DT */ ++static void brcmf_of_probe_cc(struct device *dev, ++ struct brcmf_mp_device *settings) ++{ ++ static struct brcmfmac_pd_cc_entry netgear_r8000_cc_ent[] = { ++ { "JP", "JP", 78 }, ++ { "US", "Q2", 86 }, ++ }; ++ struct brcmfmac_pd_cc_entry *cc_ent = NULL; ++ int table_size = 0; ++ ++ if (of_machine_is_compatible("netgear,r8000")) { ++ cc_ent = netgear_r8000_cc_ent; ++ table_size = ARRAY_SIZE(netgear_r8000_cc_ent); ++ } ++ ++ if (cc_ent && table_size) { ++ struct brcmfmac_pd_cc *cc; ++ size_t memsize; ++ ++ memsize = table_size * sizeof(struct brcmfmac_pd_cc_entry); ++ cc = devm_kzalloc(dev, sizeof(*cc) + memsize, GFP_KERNEL); ++ if (!cc) ++ return; ++ cc->table_size = table_size; ++ memcpy(cc->table, cc_ent, memsize); ++ settings->country_codes = cc; ++ } ++} ++ + void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) + { +@@ -32,6 +62,8 @@ void brcmf_of_probe(struct device *dev, + u32 irqf; + u32 val; + ++ brcmf_of_probe_cc(dev, settings); ++ + if (!np || bus_type != BRCMF_BUSTYPE_SDIO || + !of_device_is_compatible(np, "brcm,bcm4329-fmac")) + return; diff --git a/root/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch b/root/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch new file mode 100644 index 00000000..8d5dbfc7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch @@ -0,0 +1,23 @@ +brcmfmac: do not use internal roaming engine by default + +Some evidence of curing disconnects with this disabled, so make it a default. +Can be overridden with module parameter roamoff=0 +See: http://projectable.me/optimize-my-pi-wi-fi/ + +Signed-off-by: Phil Elwell +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -72,7 +72,11 @@ static int brcmf_fcmode; + module_param_named(fcmode, brcmf_fcmode, int, 0); + MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); + ++#if defined(CONFIG_ARCH_BCM2835) ++static int brcmf_roamoff = 1; ++#else + static int brcmf_roamoff; ++#endif + module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR); + MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); + diff --git a/root/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch b/root/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch new file mode 100644 index 00000000..2c466a30 --- /dev/null +++ b/root/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch @@ -0,0 +1,33 @@ +From: Sven Eckelmann +Date: Tue, 18 Nov 2014 12:29:28 +0100 +Subject: [PATCH] ath10k: Don't initialize devices asynchronously + +OpenWrt requires all PHYs to be initialized to create the configuration files +during bootup. ath10k violates this because it delays the creation of the PHY +to a not well defined point in the future. + +Forcing the work to be done immediately works around this problem but may also +delay the boot when firmware images cannot be found. + +Signed-off-by: Sven Eckelmann +--- + +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -2494,6 +2494,16 @@ int ath10k_core_register(struct ath10k * + ar->chip_id = chip_id; + queue_work(ar->workqueue, &ar->register_work); + ++ /* OpenWrt requires all PHYs to be initialized to create the ++ * configuration files during bootup. ath10k violates this ++ * because it delays the creation of the PHY to a not well defined ++ * point in the future. ++ * ++ * Forcing the work to be done immediately works around this problem ++ * but may also delay the boot when firmware images cannot be found. ++ */ ++ flush_workqueue(ar->workqueue); ++ + return 0; + } + EXPORT_SYMBOL(ath10k_core_register); diff --git a/root/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch b/root/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch new file mode 100644 index 00000000..21e7359b --- /dev/null +++ b/root/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch @@ -0,0 +1,37 @@ +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -8080,6 +8080,21 @@ static int ath10k_mac_init_rd(struct ath + return 0; + } + ++#ifdef CPTCFG_MAC80211_LEDS ++static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = { ++ { .throughput = 0 * 1024, .blink_time = 334 }, ++ { .throughput = 1 * 1024, .blink_time = 260 }, ++ { .throughput = 2 * 1024, .blink_time = 220 }, ++ { .throughput = 5 * 1024, .blink_time = 190 }, ++ { .throughput = 10 * 1024, .blink_time = 170 }, ++ { .throughput = 25 * 1024, .blink_time = 150 }, ++ { .throughput = 54 * 1024, .blink_time = 130 }, ++ { .throughput = 120 * 1024, .blink_time = 110 }, ++ { .throughput = 265 * 1024, .blink_time = 80 }, ++ { .throughput = 586 * 1024, .blink_time = 50 }, ++}; ++#endif ++ + int ath10k_mac_register(struct ath10k *ar) + { + static const u32 cipher_suites[] = { +@@ -8352,6 +8367,12 @@ int ath10k_mac_register(struct ath10k *a + + wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + ++#ifdef CPTCFG_MAC80211_LEDS ++ ieee80211_create_tpt_led_trigger(ar->hw, ++ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, ++ ARRAY_SIZE(ath10k_tpt_blink)); ++#endif ++ + ret = ieee80211_register_hw(ar->hw); + if (ret) { + ath10k_err(ar, "failed to register ieee80211: %d\n", ret); diff --git a/root/package/kernel/mac80211/patches/936-ath10k-fix-otp-failure-result.patch b/root/package/kernel/mac80211/patches/936-ath10k-fix-otp-failure-result.patch new file mode 100644 index 00000000..ea30a9df --- /dev/null +++ b/root/package/kernel/mac80211/patches/936-ath10k-fix-otp-failure-result.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -770,7 +770,7 @@ static int ath10k_core_get_board_id_from + if (ret) { + ath10k_err(ar, "could not execute otp for board id check: %d\n", + ret); +- return ret; ++ return -EOPNOTSUPP; + } + + board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP); diff --git a/root/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch b/root/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch new file mode 100644 index 00000000..a958c78b --- /dev/null +++ b/root/package/kernel/mac80211/patches/940-mwl8k_init_devices_synchronously.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/wireless/marvell/mwl8k.c ++++ b/drivers/net/wireless/marvell/mwl8k.c +@@ -6266,6 +6266,8 @@ static int mwl8k_probe(struct pci_dev *p + + priv->running_bsses = 0; + ++ wait_for_completion(&priv->firmware_loading_complete); ++ + return rc; + + err_stop_firmware: +@@ -6299,8 +6301,6 @@ static void mwl8k_remove(struct pci_dev + return; + priv = hw->priv; + +- wait_for_completion(&priv->firmware_loading_complete); +- + if (priv->fw_state == FW_STATE_ERROR) { + mwl8k_hw_reset(priv); + goto unmap; diff --git a/root/package/kernel/mac80211/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch b/root/package/kernel/mac80211/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch new file mode 100644 index 00000000..914472aa --- /dev/null +++ b/root/package/kernel/mac80211/patches/960-0010-ath10k-limit-htt-rx-ring-size.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath10k/htt.h ++++ b/drivers/net/wireless/ath/ath10k/htt.h +@@ -200,7 +200,7 @@ enum htt_rx_ring_flags { + }; + + #define HTT_RX_RING_SIZE_MIN 128 +-#define HTT_RX_RING_SIZE_MAX 2048 ++#define HTT_RX_RING_SIZE_MAX 512 + + struct htt_rx_ring_setup_ring { + __le32 fw_idx_shadow_reg_paddr; diff --git a/root/package/kernel/mac80211/patches/960-0011-ath10k-limit-pci-buffer-size.patch b/root/package/kernel/mac80211/patches/960-0011-ath10k-limit-pci-buffer-size.patch new file mode 100644 index 00000000..a101282d --- /dev/null +++ b/root/package/kernel/mac80211/patches/960-0011-ath10k-limit-pci-buffer-size.patch @@ -0,0 +1,38 @@ +--- a/drivers/net/wireless/ath/ath10k/pci.c ++++ b/drivers/net/wireless/ath/ath10k/pci.c +@@ -128,7 +128,7 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, +- .dest_nentries = 512, ++ .dest_nentries = 128, + .recv_cb = ath10k_pci_htt_htc_rx_cb, + }, + +@@ -137,7 +137,7 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, +- .dest_nentries = 128, ++ .dest_nentries = 64, + .recv_cb = ath10k_pci_htc_rx_cb, + }, + +@@ -164,7 +164,7 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 512, +- .dest_nentries = 512, ++ .dest_nentries = 128, + .recv_cb = ath10k_pci_htt_rx_cb, + }, + +@@ -189,7 +189,7 @@ static struct ce_attr host_ce_config_wla + .flags = CE_ATTR_FLAGS, + .src_nentries = 0, + .src_sz_max = 2048, +- .dest_nentries = 128, ++ .dest_nentries = 96, + .recv_cb = ath10k_pci_pktlog_rx_cb, + }, + diff --git a/root/package/kernel/mac80211/patches/970-rsi-fix-kbuild-reported-build-errors-with-CONFIG_PM-off b/root/package/kernel/mac80211/patches/970-rsi-fix-kbuild-reported-build-errors-with-CONFIG_PM-off new file mode 100644 index 00000000..3b139ee3 --- /dev/null +++ b/root/package/kernel/mac80211/patches/970-rsi-fix-kbuild-reported-build-errors-with-CONFIG_PM-off @@ -0,0 +1,93 @@ +From e6b3b2ed3d270b3c7080c9cf7d28636dc74b0387 Mon Sep 17 00:00:00 2001 +From: Amitkumar Karwar +Date: Wed, 1 Nov 2017 17:42:45 +0530 +Subject: rsi: fix kbuild reported build errors with CONFIG_PM off + +Some wowlan related code was outside CONFIG_PM flag which caused these +build errors. They are fixed by moving that code under CONFIG_PM flag. + +Reported-by: kbuild test robot +Fixes: ef71ed0608c ("rsi: sdio: Add WOWLAN support for S5 shutdown state") +Fixes: a24e35fcee0 ("rsi: sdio: Add WOWLAN support for S4 hibernate state") +Fixes: e1ced6422a3 ("rsi: sdio: add WOWLAN support for S3 suspend state") +Signed-off-by: Amitkumar Karwar +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/rsi/rsi_91x_mac80211.c | 5 ++++- + drivers/net/wireless/rsi/rsi_91x_mgmt.c | 2 ++ + drivers/net/wireless/rsi/rsi_common.h | 2 ++ + drivers/net/wireless/rsi/rsi_mgmt.h | 2 ++ + 4 files changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c ++++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c +@@ -1752,6 +1752,7 @@ static int rsi_mac80211_cancel_roc(struc + return 0; + } + ++#ifdef CONFIG_PM + static const struct wiphy_wowlan_support rsi_wowlan_support = { + .flags = WIPHY_WOWLAN_ANY | + WIPHY_WOWLAN_MAGIC_PKT | +@@ -1824,7 +1825,6 @@ int rsi_config_wowlan(struct rsi_hw *ada + } + EXPORT_SYMBOL(rsi_config_wowlan); + +-#ifdef CONFIG_PM + static int rsi_mac80211_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan) + { +@@ -1977,7 +1977,10 @@ int rsi_mac80211_attach(struct rsi_commo + wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; + wiphy->reg_notifier = rsi_reg_notify; + ++#ifdef CONFIG_PM + wiphy->wowlan = &rsi_wowlan_support; ++#endif ++ + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + + /* Wi-Fi direct parameters */ +--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c ++++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c +@@ -1597,6 +1597,7 @@ static int rsi_send_beacon(struct rsi_co + return 0; + } + ++#ifdef CONFIG_PM + int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, + u16 sleep_status) + { +@@ -1630,6 +1631,7 @@ int rsi_send_wowlan_request(struct rsi_c + + return rsi_send_internal_mgmt_frame(common, skb); + } ++#endif + + /** + * rsi_handle_ta_confirm_type() - This function handles the confirm frames. +--- a/drivers/net/wireless/rsi/rsi_common.h ++++ b/drivers/net/wireless/rsi/rsi_common.h +@@ -83,7 +83,9 @@ u16 rsi_get_connected_channel(struct iee + struct rsi_hw *rsi_91x_init(void); + void rsi_91x_deinit(struct rsi_hw *adapter); + int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len); ++#ifdef CONFIG_PM + int rsi_config_wowlan(struct rsi_hw *adapter, struct cfg80211_wowlan *wowlan); ++#endif + struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr); + struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac); + void rsi_roc_timeout(struct timer_list *t); +--- a/drivers/net/wireless/rsi/rsi_mgmt.h ++++ b/drivers/net/wireless/rsi/rsi_mgmt.h +@@ -668,8 +668,10 @@ int rsi_band_check(struct rsi_common *co + int rsi_send_rx_filter_frame(struct rsi_common *common, u16 rx_filter_word); + int rsi_send_radio_params_update(struct rsi_common *common); + int rsi_set_antenna(struct rsi_common *common, u8 antenna); ++#ifdef CONFIG_PM + int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, + u16 sleep_status); ++#endif + int rsi_send_ps_request(struct rsi_hw *adapter, bool enable, + struct ieee80211_vif *vif); + #endif diff --git a/root/package/kernel/mac80211/patches/971-rsi-move-rsi_sdio_reinit_device-out-of-CONFIG_PM.patch b/root/package/kernel/mac80211/patches/971-rsi-move-rsi_sdio_reinit_device-out-of-CONFIG_PM.patch new file mode 100644 index 00000000..499b4ee7 --- /dev/null +++ b/root/package/kernel/mac80211/patches/971-rsi-move-rsi_sdio_reinit_device-out-of-CONFIG_PM.patch @@ -0,0 +1,96 @@ +From 39f1332c526cd9d6de59a72520e8334e54b62cda Mon Sep 17 00:00:00 2001 +From: Amitkumar Karwar +Date: Wed, 1 Nov 2017 17:42:44 +0530 +Subject: rsi: move rsi_sdio_reinit_device() out of CONFIG_PM + +This function is generic. It doesn't contain wowlan specific code. +It should not be under CONFIG_PM. This patch resolves compilation +errors observed when CONFIG_PM flag is disabled. + +Reported-by: kbuild test robot +Fixes: ef71ed0608c ("rsi: sdio: Add WOWLAN support for S5 shutdown state") +Fixes: a24e35fcee0 ("rsi: sdio: Add WOWLAN support for S4 hibernate state") +Fixes: e1ced6422a3 ("rsi: sdio: add WOWLAN support for S3 suspend state") +Signed-off-by: Amitkumar Karwar +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/rsi/rsi_91x_sdio.c | 52 ++++++++++++++++----------------- + drivers/net/wireless/rsi/rsi_sdio.h | 1 - + 2 files changed, 26 insertions(+), 27 deletions(-) + +--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c ++++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c +@@ -871,6 +871,32 @@ fail: + return status; + } + ++static int rsi_sdio_reinit_device(struct rsi_hw *adapter) ++{ ++ struct rsi_91x_sdiodev *sdev = adapter->rsi_dev; ++ struct sdio_func *pfunction = sdev->pfunction; ++ int ii; ++ ++ for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) ++ skb_queue_purge(&adapter->priv->tx_queue[ii]); ++ ++ /* Initialize device again */ ++ sdio_claim_host(pfunction); ++ ++ sdio_release_irq(pfunction); ++ rsi_reset_card(pfunction); ++ ++ sdio_enable_func(pfunction); ++ rsi_setupcard(adapter); ++ rsi_init_sdio_slave_regs(adapter); ++ sdio_claim_irq(pfunction, rsi_handle_interrupt); ++ rsi_hal_device_init(adapter); ++ ++ sdio_release_host(pfunction); ++ ++ return 0; ++} ++ + static struct rsi_host_intf_ops sdio_host_intf_ops = { + .write_pkt = rsi_sdio_host_intf_write_pkt, + .read_pkt = rsi_sdio_host_intf_read_pkt, +@@ -1281,32 +1307,6 @@ static void rsi_shutdown(struct device * + rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n"); + } + +-int rsi_sdio_reinit_device(struct rsi_hw *adapter) +-{ +- struct rsi_91x_sdiodev *sdev = adapter->rsi_dev; +- struct sdio_func *pfunction = sdev->pfunction; +- int ii; +- +- for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) +- skb_queue_purge(&adapter->priv->tx_queue[ii]); +- +- /* Initialize device again */ +- sdio_claim_host(pfunction); +- +- sdio_release_irq(pfunction); +- rsi_reset_card(pfunction); +- +- sdio_enable_func(pfunction); +- rsi_setupcard(adapter); +- rsi_init_sdio_slave_regs(adapter); +- sdio_claim_irq(pfunction, rsi_handle_interrupt); +- rsi_hal_device_init(adapter); +- +- sdio_release_host(pfunction); +- +- return 0; +-} +- + static int rsi_restore(struct device *dev) + { + struct sdio_func *pfunction = dev_to_sdio_func(dev); +--- a/drivers/net/wireless/rsi/rsi_sdio.h ++++ b/drivers/net/wireless/rsi/rsi_sdio.h +@@ -131,5 +131,4 @@ int rsi_sdio_master_access_msword(struct + void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit); + int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter); + int rsi_sdio_check_buffer_status(struct rsi_hw *adapter, u8 q_num); +-int rsi_sdio_reinit_device(struct rsi_hw *adapter); + #endif diff --git a/root/package/kernel/mac80211/patches/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch b/root/package/kernel/mac80211/patches/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch new file mode 100644 index 00000000..9dceea8f --- /dev/null +++ b/root/package/kernel/mac80211/patches/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch @@ -0,0 +1,132 @@ +From: Sebastian Gottschall + +current handling of peer_bw_rxnss_override parameter is based on guessing the +VHT160/8080 capability by rx rate. this is wrong and may lead +to a non initialized peer_bw_rxnss_override parameter which is required since +VHT160 operation mode only supports 2x2 chainmasks in addition the original code +initialized the parameter with wrong masked values. +This patch uses the peer phymode and peer nss information for correct +initialisation of the peer_bw_rxnss_override parameter. +if this peer information is not available, we initialize the parameter by +minimum nss which is suggested by QCA as temporary workaround according +to the QCA sourcecodes. + +Signed-off-by: Sebastian Gottschall + +v2: remove debug messages +v3: apply some cosmetics, update documentation +v4: fix compile warning and truncate nss to maximum of 2x2 since current +chipsets only support 2x2 at vht160 +v5: handle maximum nss for chipsets supportig vht160 with 1x1 only +v7: use more simple code variant and take care about hw/sw chainmask +configuration +--- + drivers/net/wireless/ath/ath10k/mac.c | 40 +++++++++++++++------------ + drivers/net/wireless/ath/ath10k/wmi.c | 7 +---- + drivers/net/wireless/ath/ath10k/wmi.h | 14 +++++++++- + 3 files changed, 36 insertions(+), 25 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -2466,7 +2466,7 @@ static void ath10k_peer_assoc_h_vht(stru + const u16 *vht_mcs_mask; + u8 ampdu_factor; + u8 max_nss, vht_mcs; +- int i; ++ int i, nss160; + + if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) + return; +@@ -2526,23 +2526,27 @@ static void ath10k_peer_assoc_h_vht(stru + __le16_to_cpu(vht_cap->vht_mcs.tx_highest); + arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit( + __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask); ++ arg->peer_bw_rxnss_override = 0; ++ nss160 = 1; /* 1x1 default config for VHT160 */ + +- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", +- sta->addr, arg->peer_max_mpdu, arg->peer_flags); +- +- if (arg->peer_vht_rates.rx_max_rate && +- (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) { +- switch (arg->peer_vht_rates.rx_max_rate) { +- case 1560: +- /* Must be 2x2 at 160Mhz is all it can do. */ +- arg->peer_bw_rxnss_override = 2; +- break; +- case 780: +- /* Can only do 1x1 at 160Mhz (Long Guard Interval) */ +- arg->peer_bw_rxnss_override = 1; +- break; +- } ++ /* only 4x4 configuration do support 2x2 for VHT160, everything else must use 1x1 */ ++ if (ar->cfg_rx_chainmask == 15) ++ nss160 = arg->peer_num_spatial_streams <= 2 ? arg->peer_num_spatial_streams : 2; ++ ++ /* in case if peer is connected with vht160 or vht80+80, we need to properly adjust rxnss parameters otherwise firmware will raise a assert */ ++ switch(arg->peer_phymode) { ++ case MODE_11AC_VHT80_80: ++ arg->peer_bw_rxnss_override = BW_NSS_FWCONF_80_80(nss160); ++ /* fall through */ ++ case MODE_11AC_VHT160: ++ arg->peer_bw_rxnss_override |= BW_NSS_FWCONF_160(nss160); ++ break; ++ default: ++ break; + } ++ ++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x peer_bw_rxnss_override 0x%x\n", ++ sta->addr, arg->peer_max_mpdu, arg->peer_flags, arg->peer_bw_rxnss_override); + } + + static void ath10k_peer_assoc_h_qos(struct ath10k *ar, +@@ -2694,9 +2698,9 @@ static int ath10k_peer_assoc_prepare(str + ath10k_peer_assoc_h_crypto(ar, vif, sta, arg); + ath10k_peer_assoc_h_rates(ar, vif, sta, arg); + ath10k_peer_assoc_h_ht(ar, vif, sta, arg); ++ ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); + ath10k_peer_assoc_h_vht(ar, vif, sta, arg); + ath10k_peer_assoc_h_qos(ar, vif, sta, arg); +- ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); + + return 0; + } +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -6760,12 +6760,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a + struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf; + + ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg); +- if (arg->peer_bw_rxnss_override) +- cmd->peer_bw_rxnss_override = +- __cpu_to_le32((arg->peer_bw_rxnss_override - 1) | +- BIT(PEER_BW_RXNSS_OVERRIDE_OFFSET)); +- else +- cmd->peer_bw_rxnss_override = 0; ++ cmd->peer_bw_rxnss_override = __cpu_to_le32(arg->peer_bw_rxnss_override); + } + + static int +--- a/drivers/net/wireless/ath/ath10k/wmi.h ++++ b/drivers/net/wireless/ath/ath10k/wmi.h +@@ -6209,7 +6209,19 @@ struct wmi_10_2_peer_assoc_complete_cmd + __le32 info0; /* WMI_PEER_ASSOC_INFO0_ */ + } __packed; + +-#define PEER_BW_RXNSS_OVERRIDE_OFFSET 31 ++#define BW_NSS_FWCONF_MAP_ENABLE (1 << 31) ++#define BW_NSS_FWCONF_MAP_160MHZ_S (0) ++#define BW_NSS_FWCONF_MAP_160MHZ_M (0x00000007) ++#define BW_NSS_FWCONF_MAP_80_80MHZ_S (3) ++#define BW_NSS_FWCONF_MAP_80_80MHZ_M (0x00000038) ++#define BW_NSS_FWCONF_MAP_M (0x0000003F) ++ ++#define GET_BW_NSS_FWCONF_160(x) ((((x) & BW_NSS_FWCONF_MAP_160MHZ_M) >> BW_NSS_FWCONF_MAP_160MHZ_S) + 1) ++#define GET_BW_NSS_FWCONF_80_80(x) ((((x) & BW_NSS_FWCONF_MAP_80_80MHZ_M) >> BW_NSS_FWCONF_MAP_80_80MHZ_S) + 1) ++ ++/* Values defined to set 160 MHz Bandwidth NSS Mapping into FW*/ ++#define BW_NSS_FWCONF_160(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_160MHZ_S) & BW_NSS_FWCONF_MAP_160MHZ_M)) ++#define BW_NSS_FWCONF_80_80(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_80_80MHZ_S) & BW_NSS_FWCONF_MAP_80_80MHZ_M)) + + struct wmi_10_4_peer_assoc_complete_cmd { + struct wmi_10_2_peer_assoc_complete_cmd cmd; diff --git a/root/package/kernel/mac80211/patches/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch b/root/package/kernel/mac80211/patches/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch new file mode 100644 index 00000000..657b31f5 --- /dev/null +++ b/root/package/kernel/mac80211/patches/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch @@ -0,0 +1,50 @@ +From: Sebastian Gottschall + +starting with firmware 10.4.3.4.x series QCA changed the handling of the channel property band_center_freq1 and band_center_freq2 in vht160 operation mode +likelly for backward compatiblity with vht80 only capable clients. +this patch adjusts the handling to get vht160 to work again with official qca firmwares newer than 3.3 +consider that this patch will not work with older firmwares anymore. to avoid undefined behaviour this we disable vht160 capability for outdated firmwares +--- + drivers/net/wireless/ath/ath10k/mac.c | 7 ------- + drivers/net/wireless/ath/ath10k/wmi.c | 11 ++++++++--- + 2 files changed, 8 insertions(+), 10 deletions(-) +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -4415,13 +4415,6 @@ static struct ieee80211_sta_vht_cap ath1 + vht_cap.cap |= val; + } + +- /* Currently the firmware seems to be buggy, don't enable 80+80 +- * mode until that's resolved. +- */ +- if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) && +- (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0) +- vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; +- + mcs_map = 0; + for (i = 0; i < 8; i++) { + if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i))) +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -1660,13 +1660,18 @@ void ath10k_wmi_put_wmi_channel(struct w + flags |= WMI_CHAN_FLAG_HT40_PLUS; + if (arg->chan_radar) + flags |= WMI_CHAN_FLAG_DFS; +- ++ ch->band_center_freq2 = 0; + ch->mhz = __cpu_to_le32(arg->freq); + ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1); + if (arg->mode == MODE_11AC_VHT80_80) + ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2); +- else +- ch->band_center_freq2 = 0; ++ if (arg->mode == MODE_11AC_VHT160) { ++ if (arg->freq < arg->band_center_freq1) ++ ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1 - 40); ++ else ++ ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1 + 40); ++ ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq1); ++ } + ch->min_power = arg->min_power; + ch->max_power = arg->max_power; + ch->reg_power = arg->max_reg_power; diff --git a/root/package/kernel/mac80211/patches/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/root/package/kernel/mac80211/patches/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch new file mode 100644 index 00000000..7b17e111 --- /dev/null +++ b/root/package/kernel/mac80211/patches/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch @@ -0,0 +1,617 @@ +From: Sebastian Gottschall + +Adds LED and GPIO Control support for 988x, 9887, 9888, 99x0, 9984 based +chipsets with on chipset connected led's using WMI Firmware API. The LED +device will get available named as "ath10k-phyX" at sysfs and can be controlled +with various triggers. adds also debugfs interface for gpio control. + +This patch is specific for OpenWRt base, as is use old backported package +with old wireless source. Support for QCA9984 is removed and a simbol +is added to local-simbol file to export the actually compile the code +with the ATH10K_LEDS simbol. + + +Signed-off-by: Sebastian Gottschall +Reviewed-by: Steve deRosier +[kvalo: major reorg and cleanup] +Signed-off-by: Kalle Valo +Signed-off-by: Ansuel Smith +--- + +v13: + +* only compile tested! + +* fix all checkpatch warnings + +* fix commit log + +* sizeof(struct ath10k_gpiocontrol) -> sizeof(*gpio) + +* unsigned -> unsigned int + +* remove GPIOLIB code, that should be added in a separate patch + +* rename gpio.c to leds.c + +* add leds.h + +* rename some functions: + + ath10k_attach_led() -> ath10k_leds_register() + ath10k_unregister_led() -> ath10k_leds_unregister() + ath10k_reset_led_pin() -> ath10k_leds_start() + +* call ath10k_leds_unregister() before ath10k_thermal_unregister() to preserve ordering + +* call ath10k_leds_start() only from ath10k_core_start() and not from mac.c + +* rename struct ath10k_gpiocontrol as anonymous function under struct + ath10k::leds, no need for memory allocation + +* merge ath10k_add_led() to ath10k_attach_led(), which is it's only caller + +* remove #if IS_ENABLED() checks from most of places, memory savings from those were not worth it + +* Kconfig help text improvement and move it lower in the menu, also don't enable it by default + +* switch to set_brightness_blocking() so that the callback can sleep, + then no need to use ath10k_wmi_cmd_send_nowait() and can take mutex + to access ar->state + +* don't touch ath10k_wmi_pdev_get_temperature() + +* as QCA6174/QCA9377 are not (yet) supported don't add the command to WMI-TLV interface + +* remove debugfs interface, that should be added in another patch + +* cleanup includes + + + drivers/net/wireless/ath/ath10k/Kconfig | 10 +++ + drivers/net/wireless/ath/ath10k/Makefile | 1 + + drivers/net/wireless/ath/ath10k/core.c | 22 +++++++ + drivers/net/wireless/ath/ath10k/core.h | 9 ++- + drivers/net/wireless/ath/ath10k/hw.h | 1 + + drivers/net/wireless/ath/ath10k/leds.c | 103 ++++++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath10k/leds.h | 45 +++++++++++++ + drivers/net/wireless/ath/ath10k/mac.c | 1 + + drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 ++++++++++ + drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 + + drivers/net/wireless/ath/ath10k/wmi.c | 54 ++++++++++++++++ + drivers/net/wireless/ath/ath10k/wmi.h | 35 ++++++++++ + 12 files changed, 314 insertions(+), 1 deletion(-) + create mode 100644 drivers/net/wireless/ath/ath10k/leds.c + create mode 100644 drivers/net/wireless/ath/ath10k/leds.h +--- a/drivers/net/wireless/ath/ath10k/Kconfig ++++ b/drivers/net/wireless/ath/ath10k/Kconfig +@@ -56,6 +56,16 @@ config ATH10K_DEBUGFS + + If unsure, say Y to make it easier to debug problems. + ++config ATH10K_LEDS ++ bool "Atheros ath10k LED support" ++ depends on ATH10K ++ select MAC80211_LEDS ++ select LEDS_CLASS ++ select NEW_LEDS ++ default y ++ ---help--- ++ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N. ++ + config ATH10K_SPECTRAL + bool "Atheros ath10k spectral scan support" + depends on ATH10K_DEBUGFS +--- a/drivers/net/wireless/ath/ath10k/Makefile ++++ b/drivers/net/wireless/ath/ath10k/Makefile +@@ -18,6 +18,7 @@ ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += + ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o + ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o + ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o ++ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o + ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o + ath10k_core-$(CONFIG_PM) += wow.o + +--- a/local-symbols ++++ b/local-symbols +@@ -144,6 +144,7 @@ ATH10K_DEBUG= + ATH10K_DEBUGFS= + ATH10K_SPECTRAL= + ATH10K_THERMAL= ++ATH10K_LEDS= + ATH10K_TRACING= + ATH10K_DFS_CERTIFIED= + WCN36XX= +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -32,6 +32,7 @@ + #include "htt.h" + #include "testmode.h" + #include "wmi-ops.h" ++#include "leds.h" + + unsigned int ath10k_debug_mask; + static unsigned int ath10k_cryptmode_param; +@@ -56,6 +57,7 @@ static const struct ath10k_hw_params ath + .id = QCA988X_HW_2_0_VERSION, + .dev_id = QCA988X_2_0_DEVICE_ID, + .name = "qca988x hw2.0", ++ .led_pin = 1, + .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +@@ -80,6 +82,7 @@ static const struct ath10k_hw_params ath + .id = QCA9887_HW_1_0_VERSION, + .dev_id = QCA9887_1_0_DEVICE_ID, + .name = "qca9887 hw1.0", ++ .led_pin = 1, + .patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL, +@@ -199,6 +202,7 @@ static const struct ath10k_hw_params ath + .id = QCA99X0_HW_2_0_DEV_VERSION, + .dev_id = QCA99X0_2_0_DEVICE_ID, + .name = "qca99x0 hw2.0", ++ .led_pin = 17, + .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .otp_exe_param = 0x00000700, +@@ -228,6 +232,7 @@ static const struct ath10k_hw_params ath + .id = QCA9984_HW_1_0_DEV_VERSION, + .dev_id = QCA9984_1_0_DEVICE_ID, + .name = "qca9984/qca9994 hw1.0", ++ .led_pin = 17, + .patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +@@ -262,6 +267,7 @@ static const struct ath10k_hw_params ath + .id = QCA9888_HW_2_0_DEV_VERSION, + .dev_id = QCA9888_2_0_DEVICE_ID, + .name = "qca9888 hw2.0", ++ .led_pin = 17, + .patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR, + .uart_pin = 7, + .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH, +@@ -2254,6 +2260,10 @@ int ath10k_core_start(struct ath10k *ar, + if (status) + goto err_hif_stop; + ++ status = ath10k_leds_start(ar); ++ if (status) ++ goto err_hif_stop; ++ + return 0; + + err_hif_stop: +@@ -2471,9 +2481,18 @@ static void ath10k_core_register_work(st + goto err_spectral_destroy; + } + ++ status = ath10k_leds_register(ar); ++ if (status) { ++ ath10k_err(ar, "could not register leds: %d\n", ++ status); ++ goto err_thermal_unregister; ++ } ++ + set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); + return; + ++err_thermal_unregister: ++ ath10k_thermal_unregister(ar); + err_spectral_destroy: + ath10k_spectral_destroy(ar); + err_debug_destroy: +@@ -2515,6 +2534,8 @@ void ath10k_core_unregister(struct ath10 + if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) + return; + ++ ath10k_leds_unregister(ar); ++ + ath10k_thermal_unregister(ar); + /* Stop spectral before unregistering from mac80211 to remove the + * relayfs debugfs file cleanly. Otherwise the parent debugfs tree +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include "htt.h" + #include "htc.h" +@@ -789,7 +790,6 @@ struct ath10k { + u32 low_5ghz_chan; + u32 high_5ghz_chan; + bool ani_enabled; +- + bool p2p; + + struct { +@@ -972,6 +972,13 @@ struct ath10k { + } testmode; + + struct { ++ struct gpio_led wifi_led; ++ struct led_classdev cdev; ++ char label[48]; ++ u32 gpio_state_pin; ++ } leds; ++ ++ struct { + /* protected by data_lock */ + u32 fw_crash_counter; + u32 fw_warm_reset_counter; +--- a/drivers/net/wireless/ath/ath10k/hw.h ++++ b/drivers/net/wireless/ath/ath10k/hw.h +@@ -490,6 +490,7 @@ struct ath10k_hw_params { + const char *name; + u32 patch_load_addr; + int uart_pin; ++ int led_pin; + u32 otp_exe_param; + + /* Type of hw cycle counter wraparound logic, for more info +--- /dev/null ++++ b/drivers/net/wireless/ath/ath10k/leds.c +@@ -0,0 +1,103 @@ ++/* ++ * Copyright (c) 2005-2011 Atheros Communications Inc. ++ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. ++ * Copyright (c) 2018 Sebastian Gottschall ++ * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++ ++#include "core.h" ++#include "wmi.h" ++#include "wmi-ops.h" ++ ++#include "leds.h" ++ ++static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev, ++ enum led_brightness brightness) ++{ ++ struct ath10k *ar = container_of(led_cdev, struct ath10k, ++ leds.cdev); ++ struct gpio_led *led = &ar->leds.wifi_led; ++ ++ mutex_lock(&ar->conf_mutex); ++ ++ if (ar->state != ATH10K_STATE_ON) ++ goto out; ++ ++ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low; ++ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin); ++ ++out: ++ mutex_unlock(&ar->conf_mutex); ++ ++ return 0; ++} ++ ++int ath10k_leds_start(struct ath10k *ar) ++{ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return 0; ++ ++ /* under some circumstances, the gpio pin gets reconfigured ++ * to default state by the firmware, so we need to ++ * reconfigure it this behaviour has only ben seen on ++ * QCA9984 and QCA99XX devices so far ++ */ ++ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0, ++ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE); ++ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1); ++ ++ return 0; ++} ++ ++int ath10k_leds_register(struct ath10k *ar) ++{ ++ int ret; ++ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return 0; ++ ++ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s", ++ wiphy_name(ar->hw->wiphy)); ++ ar->leds.wifi_led.active_low = 1; ++ ar->leds.wifi_led.gpio = ar->hw_params.led_pin; ++ ar->leds.wifi_led.name = ar->leds.label; ++ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP; ++ ++ ar->leds.cdev.name = ar->leds.label; ++ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; ++ ++ /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ ++ ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; ++ ++ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++void ath10k_leds_unregister(struct ath10k *ar) ++{ ++ if (ar->hw_params.led_pin == 0) ++ /* leds not supported */ ++ return; ++ ++ led_classdev_unregister(&ar->leds.cdev); ++} ++ +--- /dev/null ++++ b/drivers/net/wireless/ath/ath10k/leds.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) 2018, The Linux Foundation. All rights reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#ifndef _LEDS_H_ ++#define _LEDS_H_ ++ ++#include "core.h" ++ ++#ifdef CPTCFG_ATH10K_LEDS ++void ath10k_leds_unregister(struct ath10k *ar); ++int ath10k_leds_start(struct ath10k *ar); ++int ath10k_leds_register(struct ath10k *ar); ++#else ++static inline void ath10k_leds_unregister(struct ath10k *ar) ++{ ++} ++ ++static inline int ath10k_leds_start(struct ath10k *ar) ++{ ++ return 0; ++} ++ ++static inline int ath10k_leds_register(struct ath10k *ar) ++{ ++ return 0; ++} ++ ++#endif ++#endif /* _LEDS_H_ */ +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -32,6 +32,7 @@ + #include "wmi-tlv.h" + #include "wmi-ops.h" + #include "wow.h" ++#include "leds.h" + + /*********/ + /* Rates */ +--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h ++++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h +@@ -197,6 +197,10 @@ struct wmi_ops { + (struct ath10k *ar, + enum wmi_bss_survey_req_type type); + struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value); ++ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num, ++ u32 input, u32 pull_type, u32 intr_mode); ++ ++ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set); + }; + + int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); +@@ -951,6 +955,35 @@ ath10k_wmi_force_fw_hang(struct ath10k * + return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); + } + ++static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num, ++ u32 input, u32 pull_type, u32 intr_mode) ++{ ++ struct sk_buff *skb; ++ ++ if (!ar->wmi.ops->gen_gpio_config) ++ return -EOPNOTSUPP; ++ ++ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode); ++ if (IS_ERR(skb)) ++ return PTR_ERR(skb); ++ ++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid); ++} ++ ++static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set) ++{ ++ struct sk_buff *skb; ++ ++ if (!ar->wmi.ops->gen_gpio_config) ++ return -EOPNOTSUPP; ++ ++ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set); ++ if (IS_ERR(skb)) ++ return PTR_ERR(skb); ++ ++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid); ++} ++ + static inline int + ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level) + { +--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c ++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c +@@ -3619,6 +3619,8 @@ static const struct wmi_ops wmi_tlv_ops + .gen_echo = ath10k_wmi_tlv_op_gen_echo, + .gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf, + .gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable, ++ /* .gen_gpio_config not implemented */ ++ /* .gen_gpio_output not implemented */ + }; + + static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { +--- a/drivers/net/wireless/ath/ath10k/wmi.c ++++ b/drivers/net/wireless/ath/ath10k/wmi.c +@@ -6580,6 +6580,49 @@ ath10k_wmi_op_gen_peer_set_param(struct + return skb; + } + ++static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar, ++ u32 gpio_num, u32 input, ++ u32 pull_type, u32 intr_mode) ++{ ++ struct wmi_gpio_config_cmd *cmd; ++ struct sk_buff *skb; ++ ++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); ++ if (!skb) ++ return ERR_PTR(-ENOMEM); ++ ++ cmd = (struct wmi_gpio_config_cmd *)skb->data; ++ cmd->pull_type = __cpu_to_le32(pull_type); ++ cmd->gpio_num = __cpu_to_le32(gpio_num); ++ cmd->input = __cpu_to_le32(input); ++ cmd->intr_mode = __cpu_to_le32(intr_mode); ++ ++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n", ++ gpio_num, input, pull_type, intr_mode); ++ ++ return skb; ++} ++ ++static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar, ++ u32 gpio_num, u32 set) ++{ ++ struct wmi_gpio_output_cmd *cmd; ++ struct sk_buff *skb; ++ ++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); ++ if (!skb) ++ return ERR_PTR(-ENOMEM); ++ ++ cmd = (struct wmi_gpio_output_cmd *)skb->data; ++ cmd->gpio_num = __cpu_to_le32(gpio_num); ++ cmd->set = __cpu_to_le32(set); ++ ++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n", ++ gpio_num, set); ++ ++ return skb; ++} ++ + static struct sk_buff * + ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, + enum wmi_sta_ps_mode psmode) +@@ -8081,6 +8124,9 @@ static const struct wmi_ops wmi_ops = { + .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, ++ + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -8151,6 +8197,8 @@ static const struct wmi_ops wmi_10_1_ops + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, + .gen_echo = ath10k_wmi_op_gen_echo, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -8222,6 +8270,8 @@ static const struct wmi_ops wmi_10_2_ops + .gen_delba_send = ath10k_wmi_op_gen_delba_send, + .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, + .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_pdev_enable_adaptive_cca not implemented */ + }; + +@@ -8292,6 +8342,8 @@ static const struct wmi_ops wmi_10_2_4_o + .gen_pdev_enable_adaptive_cca = + ath10k_wmi_op_gen_pdev_enable_adaptive_cca, + .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + /* .gen_bcn_tmpl not implemented */ + /* .gen_prb_tmpl not implemented */ + /* .gen_p2p_go_bcn_ie not implemented */ +@@ -8367,6 +8419,8 @@ static const struct wmi_ops wmi_10_4_ops + .gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info, + .gen_echo = ath10k_wmi_op_gen_echo, + .gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config, ++ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config, ++ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output, + }; + + int ath10k_wmi_attach(struct ath10k *ar) +--- a/drivers/net/wireless/ath/ath10k/wmi.h ++++ b/drivers/net/wireless/ath/ath10k/wmi.h +@@ -2899,6 +2899,41 @@ enum wmi_10_4_feature_mask { + + }; + ++/* WMI_GPIO_CONFIG_CMDID */ ++enum { ++ WMI_GPIO_PULL_NONE, ++ WMI_GPIO_PULL_UP, ++ WMI_GPIO_PULL_DOWN, ++}; ++ ++enum { ++ WMI_GPIO_INTTYPE_DISABLE, ++ WMI_GPIO_INTTYPE_RISING_EDGE, ++ WMI_GPIO_INTTYPE_FALLING_EDGE, ++ WMI_GPIO_INTTYPE_BOTH_EDGE, ++ WMI_GPIO_INTTYPE_LEVEL_LOW, ++ WMI_GPIO_INTTYPE_LEVEL_HIGH ++}; ++ ++/* WMI_GPIO_CONFIG_CMDID */ ++struct wmi_gpio_config_cmd { ++ __le32 gpio_num; /* GPIO number to be setup */ ++ __le32 input; /* 0 - Output/ 1 - Input */ ++ __le32 pull_type; /* Pull type defined above */ ++ __le32 intr_mode; /* Interrupt mode defined above (Input) */ ++} __packed; ++ ++/* WMI_GPIO_OUTPUT_CMDID */ ++struct wmi_gpio_output_cmd { ++ __le32 gpio_num; /* GPIO number to be setup */ ++ __le32 set; /* Set the GPIO pin*/ ++} __packed; ++ ++/* WMI_GPIO_INPUT_EVENTID */ ++struct wmi_gpio_input_event { ++ __le32 gpio_num; /* GPIO number which changed state */ ++} __packed; ++ + struct wmi_ext_resource_config_10_4_cmd { + /* contains enum wmi_host_platform_type */ + __le32 host_platform_config; diff --git a/root/package/kernel/mac80211/patches/975-ath10k-use-tpt-trigger-by-default.patch b/root/package/kernel/mac80211/patches/975-ath10k-use-tpt-trigger-by-default.patch new file mode 100644 index 00000000..2b34b706 --- /dev/null +++ b/root/package/kernel/mac80211/patches/975-ath10k-use-tpt-trigger-by-default.patch @@ -0,0 +1,53 @@ +From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001 +From: Mathias Kresin +Date: Fri, 22 Jun 2018 18:59:44 +0200 +Subject: [PATCH] ath10k: use tpt LED trigger by default + +Use the tpt LED trigger for each created phy led. Ths way LEDs attached +to the ath10k GPIO pins are indicating the phy status and blink on +traffic. + +Signed-off-by: Mathias Kresin +--- + drivers/net/wireless/ath/ath10k/core.h | 4 ++++ + drivers/net/wireless/ath/ath10k/leds.c | 4 +--- + drivers/net/wireless/ath/ath10k/mac.c | 2 +- + 3 files changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -1010,6 +1010,10 @@ struct ath10k { + + void *ce_priv; + ++#ifdef CPTCFG_MAC80211_LEDS ++ const char *led_default_trigger; ++#endif ++ + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); + }; +--- a/drivers/net/wireless/ath/ath10k/leds.c ++++ b/drivers/net/wireless/ath/ath10k/leds.c +@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k * + + ar->leds.cdev.name = ar->leds.label; + ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking; +- +- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */ +- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger; ++ ar->leds.cdev.default_trigger = ar->led_default_trigger; + + ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev); + if (ret) +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -8366,7 +8366,7 @@ int ath10k_mac_register(struct ath10k *a + wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + + #ifdef CPTCFG_MAC80211_LEDS +- ieee80211_create_tpt_led_trigger(ar->hw, ++ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, + ARRAY_SIZE(ath10k_tpt_blink)); + #endif diff --git a/root/package/kernel/mac80211/scripts/import-backports.sh b/root/package/kernel/mac80211/scripts/import-backports.sh new file mode 100755 index 00000000..d056eb6d --- /dev/null +++ b/root/package/kernel/mac80211/scripts/import-backports.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +BASE=$1; shift + +usage() { + echo "Usage: $0 NNN ..." + exit 1 +} + +check_number() { + case "$1" in + [0-9][0-9][0-9]) return 0;; + esac + return 1; +} + +patch_header() +{ + awk ' + /^(---|\*\*\*|Index:)[ \t][^ \t]|^diff -/ \ + { exit } + { print } + ' +} + +strip_diffstat() +{ + awk ' + /#? .* \| / \ + { eat = eat $0 "\n" + next } + /^#? .* files? changed(, .* insertions?\(\+\))?(, .* deletions?\(-\))?/ \ + { eat = "" + next } + { print eat $0 + eat = "" } + ' +} + +strip_trailing_whitespace() { + sed -e 's:[ '$'\t'']*$::' +} + +fixup_header() { + awk ' + /^From / { next } + /^Subject: / { + sub("Subject: \\[[^\]]*\\]", "Subject: [PATCH]") + } + { print } + ' +} + +check_number "$BASE" || usage + +quilt series > /dev/null || { + echo "Not in quilt directory" + exit 2 +} + +get_next() { + NEW=$BASE + quilt series | while read CUR; do + [ -n "$CUR" ] || break + CUR=${CUR%%-*} + check_number "$CUR" || continue + [ "$CUR" -lt "$NEW" ] && continue + [ "$CUR" -ge "$(($BASE + 100))" ] && continue + NEW="$(($CUR + 1))" + echo $NEW + done | tail -n1 +} + +CUR=`get_next` +CUR="${CUR:-$BASE}" + +while [ -n "$1" ]; do + FILE="$1"; shift + NAME="$(basename $FILE)" + NAME="${NAME#[0-9]*-}" + echo -n "Processing patch $NAME: " + + [ -e "$FILE" ] || { + echo "file $FILE not found" + exit 1 + } + + grep -qE "$NAME$" patches/series && { + echo "already applied" + continue + } + + quilt new "$CUR-$NAME" || exit 1 + patch_header < "$FILE" | + strip_diffstat | + strip_trailing_whitespace | + fixup_header > "patches/$CUR-$NAME" + + quilt fold < "$FILE" || { + cp "$FILE" ./cur_patch + echo "patch $FILE failed to apply, copied to ./cur_patch" + exit 1 + } + + quilt refresh -p ab --no-index --no-timestamps + + CUR="$(($CUR + 1))" +done + +exit 0 diff --git a/root/package/network/services/hostapd/Config.in b/root/package/network/services/hostapd/Config.in new file mode 100644 index 00000000..222cfb7f --- /dev/null +++ b/root/package/network/services/hostapd/Config.in @@ -0,0 +1,96 @@ +# wpa_supplicant config +config WPA_SUPPLICANT_NO_TIMESTAMP_CHECK + bool "Disable timestamp check" + depends on PACKAGE_wpa-supplicant || \ + PACKAGE_wpa-supplicant-openssl || \ + PACKAGE_wpa-supplicant-wolfssl || \ + PACKAGE_wpa-supplicant-mesh-openssl || \ + PACKAGE_wpa-supplicant-mesh-wolfssl || \ + PACKAGE_wpa-supplicant-mini || \ + PACKAGE_wpa-supplicant-p2p || \ + PACKAGE_wpad || \ + PACKAGE_wpad-openssl || \ + PACKAGE_wpad-wolfssl || \ + PACKAGE_wpad-mini || \ + PACKAGE_wpad-mesh-openssl || \ + PACKAGE_wpad-mesh-wolfssl + default n + help + This disables the timestamp check for certificates in wpa_supplicant + Useful for devices without RTC that cannot reliably get the real date/time + +config WPA_RFKILL_SUPPORT + bool "Add rfkill support" + depends on PACKAGE_wpa-supplicant || \ + PACKAGE_wpa-supplicant-openssl || \ + PACKAGE_wpa-supplicant-wolfssl || \ + PACKAGE_wpa-supplicant-mesh-openssl || \ + PACKAGE_wpa-supplicant-mesh-wolfssl || \ + PACKAGE_wpa-supplicant-mini || \ + PACKAGE_wpa-supplicant-p2p || \ + PACKAGE_wpad || \ + PACKAGE_wpad-openssl || \ + PACKAGE_wpad-wolfssl || \ + PACKAGE_wpad-mini || \ + PACKAGE_wpad-mesh-openssl || \ + PACKAGE_wpad-mesh-wolfssl + default n + +config WPA_MSG_MIN_PRIORITY + int "Minimum debug message priority" + depends on PACKAGE_wpa-supplicant || \ + PACKAGE_wpa-supplicant-openssl || \ + PACKAGE_wpa-supplicant-wolfssl || \ + PACKAGE_wpa-supplicant-mesh-openssl || \ + PACKAGE_wpa-supplicant-mesh-wolfssl || \ + PACKAGE_wpa-supplicant-mini || \ + PACKAGE_wpa-supplicant-p2p || \ + PACKAGE_wpad || \ + PACKAGE_wpad-openssl || \ + PACKAGE_wpad-wolfssl || \ + PACKAGE_wpad-mini || \ + PACKAGE_wpad-mesh-openssl || \ + PACKAGE_wpad-mesh-wolfssl + default 3 + help + Useful values are: + 0 = all messages + 1 = raw message dumps + 2 = most debugging messages + 3 = info messages + 4 = warnings + 5 = errors + +config WPA_WOLFSSL + bool + default PACKAGE_wpa-supplicant-wolfssl ||\ + PACKAGE_wpad-wolfssl ||\ + PACKAGE_wpad-mesh-wolfssl ||\ + PACKAGE_eapol-test-wolfssl + select PACKAGE_libwolfssl + select WOLFSSL_HAS_AES_CCM + select WOLFSSL_HAS_AES_GCM + select WOLFSSL_HAS_ARC4 + select WOLFSSL_HAS_DES3 + select WOLFSSL_HAS_DH + select WOLFSSL_HAS_ECC + select WOLFSSL_HAS_OCSP + select WOLFSSL_HAS_PSK + select WOLFSSL_HAS_SESSION_TICKET + select WOLFSSL_HAS_WPAS + +config DRIVER_WEXT_SUPPORT + bool + default n + +config DRIVER_11N_SUPPORT + bool + default n + +config DRIVER_11AC_SUPPORT + bool + default n + +config DRIVER_11W_SUPPORT + bool + default n diff --git a/root/package/network/services/hostapd/Makefile b/root/package/network/services/hostapd/Makefile new file mode 100644 index 00000000..5edc513e --- /dev/null +++ b/root/package/network/services/hostapd/Makefile @@ -0,0 +1,644 @@ +# Copyright (C) 2006-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=hostapd +PKG_RELEASE:=4 + +PKG_SOURCE_URL:=http://w1.fi/hostap.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2018-05-21 +PKG_SOURCE_VERSION:=62566bc23d041e88f8e35933d5fd8c2fd0f7cf2a +PKG_MIRROR_HASH:=f234b24f9471ae9cb34460feec6d6614641691544101535673595272c91448eb + +PKG_MAINTAINER:=Felix Fietkau +PKG_LICENSE:=BSD-3-Clause +PKG_CPE_ID:=cpe:/a:w1.fi:hostapd + +PKG_BUILD_PARALLEL:=1 + +PKG_CONFIG_DEPENDS:= \ + CONFIG_WPA_SUPPLICANT_NO_TIMESTAMP_CHECK \ + CONFIG_PACKAGE_kmod-ath9k \ + CONFIG_PACKAGE_kmod-cfg80211 \ + CONFIG_PACKAGE_hostapd \ + CONFIG_PACKAGE_hostapd-mini \ + CONFIG_WPA_RFKILL_SUPPORT \ + CONFIG_DRIVER_WEXT_SUPPORT \ + CONFIG_DRIVER_11N_SUPPORT \ + CONFIG_DRIVER_11AC_SUPPORT \ + +WPAD_PROVIDERS:=wpad-mini wpad wpad-openssl wpad-wolfssl \ + wpad-mesh-openssl wpad-mesh-wolfssl + +SUPPLICANT_ONLY_PROVIDERS:=wpa-supplicant-mini wpa-supplicant-p2p \ + wpa-supplicant wpa-supplicant-openssl wpa-supplicant-wolfssl \ + wpa-supplicant-mesh-openssl wpa-supplicant-mesh-wolfssl + +HOSTAPD_ONLY_PROVIDERS:=hostapd-mini hostapd hostapd-openssl hostapd-wolfssl + +EAPOL_TEST_PROVIDERS:=eapol-test eapol-test-openssl eapol-test-wolfssl + +SUPPLICANT_PROVIDERS:=$(WPAD_PROVIDERS) $(SUPPLICANT_ONLY_PROVIDERS) +HOSTAPD_PROVIDERS:=$(WPAD_PROVIDERS) $(HOSTAPD_ONLY_PROVIDERS) +ANY_SUPPLICANT_PROVIDERS:=$(WPAD_PROVIDERS) $(SUPPLICANT_ONLY_PROVIDERS) +ANY_HOSTAPD_PROVIDERS:=$(WPAD_PROVIDERS) $(HOSTAPD_ONLY_PROVIDERS) +ANY_PROVIDERS:=$(WPAD_PROVIDERS) $(SUPPLICANT_ONLY_PROVIDERS) $(HOSTAPD_ONLY_PROVIDERS) + +LOCAL_TYPE=$(strip \ + $(if $(findstring wpad,$(BUILD_VARIANT)),wpad, \ + $(if $(findstring supplicant,$(BUILD_VARIANT)),supplicant, \ + hostapd \ + ))) + +LOCAL_AND_LIB_VARIANT=$(patsubst hostapd-%,%,\ + $(patsubst wpad-%,%,\ + $(patsubst supplicant-%,%,\ + $(BUILD_VARIANT)\ + ))) + +LOCAL_VARIANT=$(patsubst %-internal,%,\ + $(patsubst %-openssl,%,\ + $(patsubst %-wolfssl,%,\ + $(LOCAL_AND_LIB_VARIANT)\ + ))) + +SSL_VARIANT=$(strip \ + $(if $(findstring openssl,$(LOCAL_AND_LIB_VARIANT)),openssl,\ + $(if $(findstring wolfssl,$(LOCAL_AND_LIB_VARIANT)),wolfssl,\ + internal\ + ))) + +CONFIG_VARIANT:=$(LOCAL_VARIANT) +ifeq ($(LOCAL_VARIANT),mesh) + CONFIG_VARIANT:=full +endif + +PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +STAMP_CONFIGURED:=$(STAMP_CONFIGURED)_$(CONFIG_WPA_MSG_MIN_PRIORITY) + + +ifneq ($(CONFIG_DRIVER_11N_SUPPORT),) + HOSTAPD_IEEE80211N:=y +endif + +ifneq ($(CONFIG_DRIVER_11AC_SUPPORT),) + HOSTAPD_IEEE80211AC:=y +endif + +DRIVER_MAKEOPTS= \ + CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \ + CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ + CONFIG_IEEE80211N=$(HOSTAPD_IEEE80211N) \ + CONFIG_IEEE80211AC=$(HOSTAPD_IEEE80211AC) \ + CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \ + +space := +space += + +ifeq ($(LOCAL_VARIANT),full) + DRIVER_MAKEOPTS += CONFIG_IEEE80211W=$(CONFIG_DRIVER_11W_SUPPORT) +endif + +ifeq ($(LOCAL_VARIANT),full) + ifeq ($(SSL_VARIANT),openssl) + DRIVER_MAKEOPTS += CONFIG_TLS=openssl + TARGET_LDFLAGS += -lcrypto -lssl + endif + ifeq ($(SSL_VARIANT),wolfssl) + DRIVER_MAKEOPTS += CONFIG_TLS=wolfssl CONFIG_WPS_NFC=1 + TARGET_LDFLAGS += -lwolfssl + endif +endif + +ifneq ($(LOCAL_TYPE),hostapd) + ifeq ($(LOCAL_VARIANT),mesh) + ifeq ($(SSL_VARIANT),openssl) + DRIVER_MAKEOPTS += CONFIG_TLS=openssl CONFIG_AP=y CONFIG_SAE=y CONFIG_MESH=y + TARGET_LDFLAGS += -lcrypto -lssl + endif + ifeq ($(SSL_VARIANT),wolfssl) + DRIVER_MAKEOPTS += CONFIG_TLS=wolfssl CONFIG_WPS_NFC=1 CONFIG_AP=y CONFIG_SAE=y CONFIG_MESH=y + TARGET_LDFLAGS += -lwolfssl + endif + endif + + ifdef CONFIG_WPA_SUPPLICANT_NO_TIMESTAMP_CHECK + TARGET_CFLAGS += -DNO_TIMESTAMP_CHECK + endif + ifdef CONFIG_WPA_RFKILL_SUPPORT + DRIVER_MAKEOPTS += NEED_RFKILL=y + endif + DRIVER_MAKEOPTS += \ + CONFIG_DRIVER_ROBOSWITCH=$(CONFIG_PACKAGE_kmod-switch) +endif + +ifdef CONFIG_USE_GLIBC + TARGET_LDFLAGS += -lrt + TARGET_LDFLAGS_C += -lrt +endif + +DRV_DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny + +define Package/hostapd/Default + SECTION:=net + CATEGORY:=Network + TITLE:=IEEE 802.1x Authenticator + URL:=http://hostap.epitest.fi/ + DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus +endef + +define Package/hostapd +$(call Package/hostapd/Default) + TITLE+= (full) + VARIANT:=full-internal +endef + +define Package/hostapd-openssl +$(call Package/hostapd/Default) + TITLE+= (full) + VARIANT:=full-openssl + DEPENDS+=+libopenssl + CONFLICTS:=$(filter-out hostapd-openssl ,$(HOSTAPD_ONLY_PROVIDERS)) + PROVIDES:=hostapd +endef + +define Package/hostapd-wolfssl +$(call Package/hostapd/Default) + TITLE+= (full) + VARIANT:=full-wolfssl + DEPENDS+=+libwolfssl + CONFLICTS:=$(filter-out hostapd-openssl ,$(filter-out hostapd-wolfssl ,$(HOSTAPD_ONLY_PROVIDERS))) + PROVIDES:=hostapd +endef + +define Package/hostapd/description + This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS + Authenticator. +endef + +Package/hostapd-openssl/description = $(Package/hostapd/description) +Package/hostapd-wolfssl/description = $(Package/hostapd/description) + +define Package/hostapd-mini +$(call Package/hostapd/Default) + TITLE+= (WPA-PSK only) + VARIANT:=mini + CONFLICTS:=$(filter-out hostapd-wolfssl ,$(filter-out hostapd-openssl ,$(filter-out hostapd-mini ,$(HOSTAPD_ONLY_PROVIDERS)))) + PROVIDES:=hostapd +endef + +define Package/hostapd-mini/description + This package contains a minimal IEEE 802.1x/WPA Authenticator (WPA-PSK only). +endef + + +define Package/hostapd-utils + $(call Package/hostapd/Default) + TITLE+= (utils) + DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(ANY_HOSTAPD_PROVIDERS),PACKAGE_$(pkg))) +endef + +define Package/hostapd-utils/description + This package contains a command line utility to control the + IEEE 802.1x/WPA/EAP/RADIUS Authenticator. +endef + +define Package/wpad/Default + SECTION:=net + CATEGORY:=Network + TITLE:=IEEE 802.1x Authenticator/Supplicant + DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus + URL:=http://hostap.epitest.fi/ + PROVIDES:=hostapd wpa-supplicant +endef + +define Package/wpad +$(call Package/wpad/Default) + TITLE+= (full) + VARIANT:=wpad-full-internal + CONFLICTS:=$(filter-out wpad-mesh-wolfssl,\ + $(filter-out wpad-mesh-openssl ,\ + $(filter-out wpad-openssl ,\ + $(filter-out wpad-wolfssl ,\ + $(filter-out wpad-wolfssl ,\ + $(filter-out wpad ,\ + $(ANY_PROVIDERS)\ + )))))) +endef + +define Package/wpad-openssl +$(call Package/wpad/Default) + TITLE+= (full) + VARIANT:=wpad-full-openssl + DEPENDS+=+libopenssl + CONFLICTS:=$(filter-out wpad-mesh-wolfssl,\ + $(filter-out wpad-mesh-openssl ,\ + $(filter-out wpad-openssl ,\ + $(ANY_PROVIDERS)))) +endef + +define Package/wpad-wolfssl +$(call Package/wpad/Default) + TITLE+= (full) + VARIANT:=wpad-full-wolfssl + DEPENDS+=+libwolfssl + CONFLICTS:=$(filter-out wpad-mesh-wolfssl ,\ + $(filter-out wpad-mesh-openssl ,\ + $(filter-out wpad-openssl ,\ + $(filter-out wpad-wolfssl ,\ + $(ANY_PROVIDERS))))) +endef + +define Package/wpad/description + This package contains a full featured IEEE 802.1x/WPA/EAP/RADIUS + Authenticator and Supplicant +endef + +Package/wpad-openssl/description = $(Package/wpad/description) +Package/wpad-wolfssl/description = $(Package/wpad/description) + +define Package/wpad-mini +$(call Package/wpad/Default) + TITLE+= (WPA-PSK only) + VARIANT:=wpad-mini + CONFLICTS:=$(SUPPLICANT_ONLY_PROVIDERS) +endef + +define Package/wpad-mini/description + This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (WPA-PSK only). +endef + +define Package/wpad-mesh-openssl +$(call Package/wpad/Default) + TITLE+= (with 802.11s mesh and SAE support) + DEPENDS+=@PACKAGE_kmod-cfg80211 @(!TARGET_uml||BROKEN) +libopenssl + VARIANT:=wpad-mesh-openssl + CONFLICTS:=$(filter-out wpad-mesh-openssl ,$(ANY_PROVIDERS)) + PROVIDES+=wpa-supplicant-mesh wpad-mesh +endef + +define Package/wpad-mesh-wolfssl +$(call Package/wpad/Default) + TITLE+= (with 802.11s mesh and SAE support) + DEPENDS+=@PACKAGE_kmod-cfg80211 @(!TARGET_uml||BROKEN) +libwolfssl + VARIANT:=wpad-mesh-wolfssl + CONFLICTS:=$(filter-out wpad-mesh-openssl ,$(filter-out wpad-mesh-wolfssl ,$(ANY_PROVIDERS))) + PROVIDES+=wpa-supplicant-mesh wpad-mesh +endef + +define Package/wpad-mesh/description + This package contains a minimal IEEE 802.1x/WPA Authenticator and Supplicant (with 802.11s mesh and SAE support). +endef + +Package/wpad-mesh-openssl/description = $(Package/wpad-mesh/description) +Package/wpad-mesh-wolfssl/description = $(Package/wpad-mesh/description) + +define Package/wpa-supplicant/Default + SECTION:=net + CATEGORY:=Network + TITLE:=WPA Supplicant + URL:=http://hostap.epitest.fi/wpa_supplicant/ + DEPENDS:=$(DRV_DEPENDS) +endef + +define Package/wpa-supplicant + $(Package/wpa-supplicant/Default) + VARIANT:=supplicant-full-internal + CONFLICTS:=wpa-supplicant-mini +endef + +define Package/wpa-supplicant-openssl + $(Package/wpa-supplicant/Default) + CONFLICTS:=$(filter-out wpa-supplicant-wolfssl ,\ + $(filter-out wpa-supplicant-openssl ,\ + $(filter-out wpa-supplicant-mesh-openssl ,\ + $(filter-out wpa-supplicant-mesh-wolfssl ,\ + $(SUPPLICANT_ONLY_PROVIDERS)\ + )))) + VARIANT:=supplicant-full-openssl + DEPENDS+=+libopenssl + PROVIDES:=wpa-supplicant +endef + +define Package/wpa-supplicant-wolfssl + $(Package/wpa-supplicant/Default) + CONFLICTS:=$(filter-out wpa-supplicant-wolfssl ,\ + $(filter-out wpa-supplicant-openssl ,\ + $(filter-out wpa-supplicant-mesh-openssl ,\ + $(filter-out wpa-supplicant-mesh-wolfssl ,\ + $(SUPPLICANT_ONLY_PROVIDERS)\ + )))) + VARIANT:=supplicant-full-wolfssl + DEPENDS+=+libwolfssl + PROVIDES:=wpa-supplicant +endef + +define Package/wpa-supplicant/config + source "$(SOURCE)/Config.in" +endef + +define Package/wpa-supplicant-p2p + $(Package/wpa-supplicant) + TITLE:=WPA Supplicant (with Wi-Fi P2P support) + DEPENDS:=$(DRV_DEPENDS) @PACKAGE_kmod-cfg80211 + CONFLICTS:=$(filter-out wpa-supplicant-openssl ,\ + $(filter-out wpa-supplicant-wolfssl ,\ + $(filter-out wpa-supplicant-p2p ,\ + $(filter-out wpa-supplicant-mesh-openssl ,\ + $(filter-out wpa-supplicant-mesh-wolfssl ,\ + $(SUPPLICANT_ONLY_PROVIDERS)\ + ))))) + VARIANT:=supplicant-p2p-internal + PROVIDES:=wpa-supplicant +endef + +define Package/wpa-supplicant-mesh/Default + $(Package/wpa-supplicant/Default) + TITLE:=WPA Supplicant (with 802.11s and SAE) + DEPENDS:=$(DRV_DEPENDS) @PACKAGE_kmod-cfg80211 @(!TARGET_uml||BROKEN) + PROVIDES:=wpa-supplicant wpa-supplicant-mesh +endef + +define Package/wpa-supplicant-mesh-openssl + $(Package/wpa-supplicant-mesh/Default) + VARIANT:=supplicant-mesh-openssl + CONFLICTS:=$(filter-out wpa-supplicant-mesh-openssl ,$(SUPPLICANT_ONLY_PROVIDERS)) + DEPENDS+=+libopenssl +endef + +define Package/wpa-supplicant-mesh-wolfssl + $(Package/wpa-supplicant-mesh/Default) + VARIANT:=supplicant-mesh-wolfssl + CONFLICTS:=$(filter-out wpa-supplicant-mesh-openssl ,$(filter-out wpa-supplicant-mesh-wolfssl ,$(SUPPLICANT_ONLY_PROVIDERS))) + DEPENDS+=+libwolfssl +endef + +define Package/wpa-supplicant-mini + $(Package/wpa-supplicant/Default) + TITLE:=WPA Supplicant (minimal version) + DEPENDS:=$(DRV_DEPENDS) + VARIANT:=supplicant-mini + PROVIDES:=wpa-supplicant +endef + +define Package/wpa-cli + SECTION:=net + CATEGORY:=Network + DEPENDS:=@$(subst $(space),||,$(foreach pkg,$(ANY_SUPPLICANT_PROVIDERS),PACKAGE_$(pkg))) + TITLE:=WPA Supplicant command line control utility +endef + +define Package/hostapd-common + TITLE:=hostapd/wpa_supplicant common support files + SECTION:=net + CATEGORY:=Network +endef + +define Package/eapol-test + TITLE:=802.1x authentication test utility + SECTION:=net + CATEGORY:=Network + VARIANT:=supplicant-full-internal + DEPENDS:=$(DRV_DEPENDS) +endef + +define Package/eapol-test-openssl + TITLE:=802.1x authentication test utility + SECTION:=net + CATEGORY:=Network + VARIANT:=supplicant-full-openssl + CONFLICTS:=$(filter-out eapol-test-openssl ,$(EAPOL_TEST_PROVIDERS)) + DEPENDS:=$(DRV_DEPENDS) +libopenssl + PROVIDES:=eapol-test +endef + +define Package/eapol-test-wolfssl + TITLE:=802.1x authentication test utility + SECTION:=net + CATEGORY:=Network + VARIANT:=supplicant-full-wolfssl + CONFLICTS:=$(filter-out eapol-test-openssl ,$(filter-out eapol-test-wolfssl ,$(EAPOL_TEST_PROVIDERS))) + DEPENDS:=$(DRV_DEPENDS) +libwolfssl + PROVIDES:=eapol-test +endef + + +ifneq ($(wildcard $(PKG_BUILD_DIR)/.config_*),$(subst .configured_,.config_,$(STAMP_CONFIGURED))) + define Build/Configure/rebuild + $(FIND) $(PKG_BUILD_DIR) -name \*.o -or -name \*.a | $(XARGS) rm -f + rm -f $(PKG_BUILD_DIR)/hostapd/hostapd + rm -f $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant + rm -f $(PKG_BUILD_DIR)/.config_* + touch $(subst .configured_,.config_,$(STAMP_CONFIGURED)) + endef +endif + +define Build/Configure + $(Build/Configure/rebuild) + $(if $(wildcard ./files/hostapd-$(CONFIG_VARIANT).config), \ + $(CP) ./files/hostapd-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/hostapd/.config \ + ) + $(CP) ./files/wpa_supplicant-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/wpa_supplicant/.config +endef + +TARGET_CPPFLAGS := \ + -I$(STAGING_DIR)/usr/include/libnl-tiny \ + -I$(PKG_BUILD_DIR)/src/crypto \ + $(TARGET_CPPFLAGS) \ + -DCONFIG_LIBNL20 \ + -D_GNU_SOURCE \ + $(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) + +TARGET_CFLAGS += -ffunction-sections -fdata-sections +TARGET_LDFLAGS += -Wl,--gc-sections +ifeq ($(findstring supplicant,$(BUILD_VARIANT)),) + TARGET_LDFLAGS += -lubox -lubus +endif + +ifdef CONFIG_PACKAGE_kmod-cfg80211 + TARGET_LDFLAGS += -lm -lnl-tiny +endif + +define Build/RunMake + CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ + $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(1) \ + $(TARGET_CONFIGURE_OPTS) \ + $(DRIVER_MAKEOPTS) \ + LIBS="$(TARGET_LDFLAGS)" \ + LIBS_c="$(TARGET_LDFLAGS_C)" \ + BCHECK= \ + $(2) +endef + +define Build/Compile/wpad + echo ` \ + $(call Build/RunMake,hostapd,-s MULTICALL=1 dump_cflags); \ + $(call Build/RunMake,wpa_supplicant,-s MULTICALL=1 dump_cflags) | \ + sed -e 's,-n ,,g' -e 's^$(TARGET_CFLAGS)^^' \ + ` > $(PKG_BUILD_DIR)/.cflags + sed -i 's/"/\\"/g' $(PKG_BUILD_DIR)/.cflags + +$(call Build/RunMake,hostapd, \ + CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \ + MULTICALL=1 \ + hostapd_cli hostapd_multi.a \ + ) + +$(call Build/RunMake,wpa_supplicant, \ + CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \ + MULTICALL=1 \ + wpa_cli wpa_supplicant_multi.a \ + ) + $(TARGET_CC) -o $(PKG_BUILD_DIR)/wpad \ + $(TARGET_CFLAGS) \ + ./files/multicall.c \ + $(PKG_BUILD_DIR)/hostapd/hostapd_multi.a \ + $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant_multi.a \ + $(TARGET_LDFLAGS) +endef + +define Build/Compile/hostapd + +$(call Build/RunMake,hostapd, \ + hostapd hostapd_cli \ + ) +endef + +define Build/Compile/supplicant + +$(call Build/RunMake,wpa_supplicant, \ + wpa_cli wpa_supplicant \ + ) +endef + +define Build/Compile/supplicant-full-internal + +$(call Build/RunMake,wpa_supplicant, \ + eapol_test \ + ) +endef + +define Build/Compile/supplicant-full-openssl + +$(call Build/RunMake,wpa_supplicant, \ + eapol_test \ + ) +endef + +define Build/Compile/supplicant-full-wolfssl + +$(call Build/RunMake,wpa_supplicant, \ + eapol_test \ + ) +endef + +define Build/Compile + $(Build/Compile/$(LOCAL_TYPE)) + $(Build/Compile/$(BUILD_VARIANT)) +endef + +define Install/hostapd + $(INSTALL_DIR) $(1)/usr/sbin +endef + +define Install/supplicant + $(INSTALL_DIR) $(1)/usr/sbin +endef + +define Package/hostapd-common/install + $(INSTALL_DIR) $(1)/lib/netifd + $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh +endef + +define Package/hostapd/install + $(call Install/hostapd,$(1)) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd $(1)/usr/sbin/ +endef +Package/hostapd-mini/install = $(Package/hostapd/install) +Package/hostapd-openssl/install = $(Package/hostapd/install) +Package/hostapd-wolfssl/install = $(Package/hostapd/install) + +ifneq ($(LOCAL_TYPE),supplicant) + define Package/hostapd-utils/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/rc.button + $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_cli $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps + endef +endif + +define Package/wpad/install + $(call Install/hostapd,$(1)) + $(call Install/supplicant,$(1)) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpad $(1)/usr/sbin/ + $(LN) wpad $(1)/usr/sbin/hostapd + $(LN) wpad $(1)/usr/sbin/wpa_supplicant +endef +Package/wpad-mini/install = $(Package/wpad/install) +Package/wpad-openssl/install = $(Package/wpad/install) +Package/wpad-wolfssl/install = $(Package/wpad/install) +Package/wpad-mesh-openssl/install = $(Package/wpad/install) +Package/wpad-mesh-wolfssl/install = $(Package/wpad/install) + +define Package/wpa-supplicant/install + $(call Install/supplicant,$(1)) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_supplicant $(1)/usr/sbin/ +endef +Package/wpa-supplicant-mini/install = $(Package/wpa-supplicant/install) +Package/wpa-supplicant-p2p/install = $(Package/wpa-supplicant/install) +Package/wpa-supplicant-openssl/install = $(Package/wpa-supplicant/install) +Package/wpa-supplicant-wolfssl/install = $(Package/wpa-supplicant/install) +Package/wpa-supplicant-mesh-openssl/install = $(Package/wpa-supplicant/install) +Package/wpa-supplicant-mesh-wolfssl/install = $(Package/wpa-supplicant/install) + +ifneq ($(LOCAL_TYPE),hostapd) + define Package/wpa-cli/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/wpa_cli $(1)/usr/sbin/ + endef +endif + +ifeq ($(BUILD_VARIANT),supplicant-full-internal) + define Package/eapol-test/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ + endef +endif + +ifeq ($(BUILD_VARIANT),supplicant-full-openssl) + define Package/eapol-test-openssl/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ + endef +endif + +ifeq ($(BUILD_VARIANT),supplicant-full-wolfssl) + define Package/eapol-test-wolfssl/install + $(INSTALL_DIR) $(1)/usr/sbin + $(CP) $(PKG_BUILD_DIR)/wpa_supplicant/eapol_test $(1)/usr/sbin/ + endef +endif + +$(eval $(call BuildPackage,hostapd)) +$(eval $(call BuildPackage,hostapd-mini)) +$(eval $(call BuildPackage,hostapd-openssl)) +$(eval $(call BuildPackage,hostapd-wolfssl)) +$(eval $(call BuildPackage,wpad)) +$(eval $(call BuildPackage,wpad-mesh-openssl)) +$(eval $(call BuildPackage,wpad-mesh-wolfssl)) +$(eval $(call BuildPackage,wpad-mini)) +$(eval $(call BuildPackage,wpad-openssl)) +$(eval $(call BuildPackage,wpad-wolfssl)) +$(eval $(call BuildPackage,wpa-supplicant)) +$(eval $(call BuildPackage,wpa-supplicant-mesh-openssl)) +$(eval $(call BuildPackage,wpa-supplicant-mesh-wolfssl)) +$(eval $(call BuildPackage,wpa-supplicant-mini)) +$(eval $(call BuildPackage,wpa-supplicant-p2p)) +$(eval $(call BuildPackage,wpa-supplicant-openssl)) +$(eval $(call BuildPackage,wpa-supplicant-wolfssl)) +$(eval $(call BuildPackage,wpa-cli)) +$(eval $(call BuildPackage,hostapd-utils)) +$(eval $(call BuildPackage,hostapd-common)) +$(eval $(call BuildPackage,eapol-test)) +$(eval $(call BuildPackage,eapol-test-openssl)) +$(eval $(call BuildPackage,eapol-test-wolfssl)) diff --git a/root/package/network/services/hostapd/files/hostapd-full.config b/root/package/network/services/hostapd/files/hostapd-full.config new file mode 100644 index 00000000..355a70b9 --- /dev/null +++ b/root/package/network/services/hostapd/files/hostapd-full.config @@ -0,0 +1,380 @@ +# Example hostapd build time configuration +# +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +# Driver interface for Host AP driver +#CONFIG_DRIVER_HOSTAP=y + +# Driver interface for wired authenticator +CONFIG_DRIVER_WIRED=y + +# Driver interface for drivers using the nl80211 kernel interface +CONFIG_DRIVER_NL80211=y + +# QCA vendor extensions to nl80211 +#CONFIG_DRIVER_NL80211_QCA=y + +# driver_nl80211.c requires libnl. If you are compiling it yourself +# you may need to point hostapd to your version of libnl. +# +#CFLAGS += -I$ +#LIBS += -L$ + +# Use libnl v2.0 (or 3.0) libraries. +#CONFIG_LIBNL20=y + +# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) +#CONFIG_LIBNL32=y + + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib +#LIBS_p += -L/usr/local/lib +#LIBS_c += -L/usr/local/lib + +# Driver interface for no driver (e.g., RADIUS server only) +#CONFIG_DRIVER_NONE=y + +# IEEE 802.11F/IAPP +CONFIG_IAPP=y + +# WPA2/IEEE 802.11i RSN pre-authentication +CONFIG_RSN_PREAUTH=y + +# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS) +CONFIG_PEERKEY=y + +# IEEE 802.11w (management frame protection) +# Driver support is also needed for IEEE 802.11w. +#CONFIG_IEEE80211W=y + +# Integrated EAP server +CONFIG_EAP=y + +# EAP Re-authentication Protocol (ERP) in integrated EAP server +#CONFIG_ERP=y + +# EAP-MD5 for the integrated EAP server +CONFIG_EAP_MD5=y + +# EAP-TLS for the integrated EAP server +CONFIG_EAP_TLS=y + +# EAP-MSCHAPv2 for the integrated EAP server +CONFIG_EAP_MSCHAPV2=y + +# EAP-PEAP for the integrated EAP server +CONFIG_EAP_PEAP=y + +# EAP-GTC for the integrated EAP server +CONFIG_EAP_GTC=y + +# EAP-TTLS for the integrated EAP server +CONFIG_EAP_TTLS=y + +# EAP-SIM for the integrated EAP server +#CONFIG_EAP_SIM=y + +# EAP-AKA for the integrated EAP server +#CONFIG_EAP_AKA=y + +# EAP-AKA' for the integrated EAP server +# This requires CONFIG_EAP_AKA to be enabled, too. +#CONFIG_EAP_AKA_PRIME=y + +# EAP-PAX for the integrated EAP server +#CONFIG_EAP_PAX=y + +# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# EAP-pwd for the integrated EAP server (secure authentication with a password) +#CONFIG_EAP_PWD=y + +# EAP-SAKE for the integrated EAP server +#CONFIG_EAP_SAKE=y + +# EAP-GPSK for the integrated EAP server +#CONFIG_EAP_GPSK=y +# Include support for optional SHA256 cipher suite in EAP-GPSK +#CONFIG_EAP_GPSK_SHA256=y + +# EAP-FAST for the integrated EAP server +# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed +# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g., +# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions. +CONFIG_EAP_FAST=y + +# Wi-Fi Protected Setup (WPS) +CONFIG_WPS=y +# Enable UPnP support for external WPS Registrars +#CONFIG_WPS_UPNP=y +# Enable WPS support with NFC config method +#CONFIG_WPS_NFC=y + +# EAP-IKEv2 +#CONFIG_EAP_IKEV2=y + +# Trusted Network Connect (EAP-TNC) +#CONFIG_EAP_TNC=y + +# EAP-EKE for the integrated EAP server +#CONFIG_EAP_EKE=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +CONFIG_PKCS12=y + +# RADIUS authentication server. This provides access to the integrated EAP +# server from external hosts using RADIUS. +#CONFIG_RADIUS_SERVER=y + +# Build IPv6 support for RADIUS operations +CONFIG_IPV6=y + +# IEEE Std 802.11r-2008 (Fast BSS Transition) +CONFIG_IEEE80211R=y + +# Use the hostapd's IEEE 802.11 authentication (ACL), but without +# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) +#CONFIG_DRIVER_RADIUS_ACL=y + +# IEEE 802.11n (High Throughput) support +CONFIG_IEEE80211N=y + +# Wireless Network Management (IEEE Std 802.11v-2011) +# Note: This is experimental and not complete implementation. +CONFIG_WNM=y + +# IEEE 802.11ac (Very High Throughput) support +CONFIG_IEEE80211AC=y + +# IEEE 802.11ax HE support +# Note: This is experimental and work in progress. The definitions are still +# subject to change and this should not be expected to interoperate with the +# final IEEE 802.11ax version. +#CONFIG_IEEE80211AX=y + +# Remove debugging code that is printing out debug messages to stdout. +# This can be used to reduce the size of the hostapd considerably if debugging +# code is not needed. +#CONFIG_NO_STDOUT_DEBUG=y + +# Add support for writing debug log to a file: -f /tmp/hostapd.log +# Disabled by default. +#CONFIG_DEBUG_FILE=y + +# Send debug messages to syslog instead of stdout +CONFIG_DEBUG_SYSLOG=y + +# Add support for sending all debug messages (regardless of debug verbosity) +# to the Linux kernel tracing facility. This helps debug the entire stack by +# making it easy to record everything happening from the driver up into the +# same file, e.g., using trace-cmd. +#CONFIG_DEBUG_LINUX_TRACING=y + +# Remove support for RADIUS accounting +#CONFIG_NO_ACCOUNTING=y + +# Remove support for RADIUS +#CONFIG_NO_RADIUS=y + +# Remove support for VLANs +#CONFIG_NO_VLAN=y + +# Enable support for fully dynamic VLANs. This enables hostapd to +# automatically create bridge and VLAN interfaces if necessary. +CONFIG_FULL_DYNAMIC_VLAN=y + +# Use netlink-based kernel API for VLAN operations instead of ioctl() +# Note: This requires libnl 3.1 or newer. +#CONFIG_VLAN_NETLINK=y + +# Remove support for dumping internal state through control interface commands +# This can be used to reduce binary size at the cost of disabling a debugging +# option. +CONFIG_NO_DUMP_STATE=y + +# Enable tracing code for developer debugging +# This tracks use of memory allocations and other registrations and reports +# incorrect use with a backtrace of call (or allocation) location. +#CONFIG_WPA_TRACE=y +# For BSD, comment out these. +#LIBS += -lexecinfo +#LIBS_p += -lexecinfo +#LIBS_c += -lexecinfo + +# Use libbfd to get more details for developer debugging +# This enables use of libbfd to get more detailed symbols for the backtraces +# generated by CONFIG_WPA_TRACE=y. +#CONFIG_WPA_TRACE_BFD=y +# For BSD, comment out these. +#LIBS += -lbfd -liberty -lz +#LIBS_p += -lbfd -liberty -lz +#LIBS_c += -lbfd -liberty -lz + +# hostapd depends on strong random number generation being available from the +# operating system. os_get_random() function is used to fetch random data when +# needed, e.g., for key generation. On Linux and BSD systems, this works by +# reading /dev/urandom. It should be noted that the OS entropy pool needs to be +# properly initialized before hostapd is started. This is important especially +# on embedded devices that do not have a hardware random number generator and +# may by default start up with minimal entropy available for random number +# generation. +# +# As a safety net, hostapd is by default trying to internally collect +# additional entropy for generating random data to mix in with the data +# fetched from the OS. This by itself is not considered to be very strong, but +# it may help in cases where the system pool is not initialized properly. +# However, it is very strongly recommended that the system pool is initialized +# with enough entropy either by using hardware assisted random number +# generator or by storing state over device reboots. +# +# hostapd can be configured to maintain its own entropy store over restarts to +# enhance random number generation. This is not perfect, but it is much more +# secure than using the same sequence of random numbers after every reboot. +# This can be enabled with -e command line option. The specified +# file needs to be readable and writable by hostapd. +# +# If the os_get_random() is known to provide strong random data (e.g., on +# Linux/BSD, the board in question is known to have reliable source of random +# data from /dev/urandom), the internal hostapd random pool can be disabled. +# This will save some in binary size and CPU use. However, this should only be +# considered for builds that are known to be used on devices that meet the +# requirements described above. +CONFIG_NO_RANDOM_POOL=y + +# Should we use poll instead of select? Select is used by default. +#CONFIG_ELOOP_POLL=y + +# Should we use epoll instead of select? Select is used by default. +#CONFIG_ELOOP_EPOLL=y + +# Should we use kqueue instead of select? Select is used by default. +#CONFIG_ELOOP_KQUEUE=y + +# Select TLS implementation +# openssl = OpenSSL (default) +# gnutls = GnuTLS +# internal = Internal TLSv1 implementation (experimental) +# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) +# none = Empty template +CONFIG_TLS=internal + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) +# can be enabled to get a stronger construction of messages when block ciphers +# are used. +#CONFIG_TLSV11=y + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) +# can be enabled to enable use of stronger crypto algorithms. +#CONFIG_TLSV12=y + +# Select which ciphers to use by default with OpenSSL if the user does not +# specify them. +#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" + +# If CONFIG_TLS=internal is used, additional library and include paths are +# needed for LibTomMath. Alternatively, an integrated, minimal version of +# LibTomMath can be used. See beginning of libtommath.c for details on benefits +# and drawbacks of this option. +CONFIG_INTERNAL_LIBTOMMATH=y +#ifndef CONFIG_INTERNAL_LIBTOMMATH +#LTM_PATH=/usr/src/libtommath-0.39 +#CFLAGS += -I$(LTM_PATH) +#LIBS += -L$(LTM_PATH) +#LIBS_p += -L$(LTM_PATH) +#endif +# At the cost of about 4 kB of additional binary size, the internal LibTomMath +# can be configured to include faster routines for exptmod, sqr, and div to +# speed up DH and RSA calculation considerably +#CONFIG_INTERNAL_LIBTOMMATH_FAST=y + +# Interworking (IEEE 802.11u) +# This can be used to enable functionality to improve interworking with +# external networks. +#CONFIG_INTERWORKING=y + +# Hotspot 2.0 +#CONFIG_HS20=y + +# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file +#CONFIG_SQLITE=y + +# Enable Fast Session Transfer (FST) +#CONFIG_FST=y + +# Enable CLI commands for FST testing +#CONFIG_FST_TEST=y + +# Testing options +# This can be used to enable some testing options (see also the example +# configuration file) that are really useful only for testing clients that +# connect to this hostapd. These options allow, for example, to drop a +# certain percentage of probe requests or auth/(re)assoc frames. +# +#CONFIG_TESTING_OPTIONS=y + +# Automatic Channel Selection +# This will allow hostapd to pick the channel automatically when channel is set +# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in +# similar way. +# +# Automatic selection is currently only done through initialization, later on +# we hope to do background checks to keep us moving to more ideal channels as +# time goes by. ACS is currently only supported through the nl80211 driver and +# your driver must have survey dump capability that is filled by the driver +# during scanning. +# +# You can customize the ACS survey algorithm with the hostapd.conf variable +# acs_num_scans. +# +# Supported ACS drivers: +# * ath9k +# * ath5k +# * ath10k +# +# For more details refer to: +# http://wireless.kernel.org/en/users/Documentation/acs +# +#CONFIG_ACS=y + +# Multiband Operation support +# These extentions facilitate efficient use of multiple frequency bands +# available to the AP and the devices that may associate with it. +#CONFIG_MBO=y + +# Client Taxonomy +# Has the AP retain the Probe Request and (Re)Association Request frames from +# a client, from which a signature can be produced which can identify the model +# of client device like "Nexus 6P" or "iPhone 5s". +CONFIG_TAXONOMY=y + +# Fast Initial Link Setup (FILS) (IEEE 802.11ai) +# Note: This is an experimental and not yet complete implementation. This +# should not be enabled for production use. +#CONFIG_FILS=y +# FILS shared key authentication with PFS +#CONFIG_FILS_SK_PFS=y + +# Include internal line edit mode in hostapd_cli. This can be used to provide +# limited command line editing and history support. +#CONFIG_WPA_CLI_EDIT=y + +# Opportunistic Wireless Encryption (OWE) +# Experimental implementation of draft-harkins-owe-07.txt +#CONFIG_OWE=y + +# uBus IPC/RPC System +# Services can connect to the bus and provide methods +# that can be called by other services or clients. +CONFIG_UBUS=y diff --git a/root/package/network/services/hostapd/files/hostapd-mini.config b/root/package/network/services/hostapd/files/hostapd-mini.config new file mode 100644 index 00000000..661983a9 --- /dev/null +++ b/root/package/network/services/hostapd/files/hostapd-mini.config @@ -0,0 +1,380 @@ +# Example hostapd build time configuration +# +# This file lists the configuration options that are used when building the +# hostapd binary. All lines starting with # are ignored. Configuration option +# lines must be commented out complete, if they are not to be included, i.e., +# just setting VARIABLE=n is not disabling that variable. +# +# This file is included in Makefile, so variables like CFLAGS and LIBS can also +# be modified from here. In most cass, these lines should use += in order not +# to override previous values of the variables. + +# Driver interface for Host AP driver +#CONFIG_DRIVER_HOSTAP=y + +# Driver interface for wired authenticator +CONFIG_DRIVER_WIRED=y + +# Driver interface for drivers using the nl80211 kernel interface +CONFIG_DRIVER_NL80211=y + +# QCA vendor extensions to nl80211 +#CONFIG_DRIVER_NL80211_QCA=y + +# driver_nl80211.c requires libnl. If you are compiling it yourself +# you may need to point hostapd to your version of libnl. +# +#CFLAGS += -I$ +#LIBS += -L$ + +# Use libnl v2.0 (or 3.0) libraries. +#CONFIG_LIBNL20=y + +# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored) +#CONFIG_LIBNL32=y + + +# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver) +#CONFIG_DRIVER_BSD=y +#CFLAGS += -I/usr/local/include +#LIBS += -L/usr/local/lib +#LIBS_p += -L/usr/local/lib +#LIBS_c += -L/usr/local/lib + +# Driver interface for no driver (e.g., RADIUS server only) +#CONFIG_DRIVER_NONE=y + +# IEEE 802.11F/IAPP +#CONFIG_IAPP=y + +# WPA2/IEEE 802.11i RSN pre-authentication +CONFIG_RSN_PREAUTH=y + +# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS) +CONFIG_PEERKEY=y + +# IEEE 802.11w (management frame protection) +# Driver support is also needed for IEEE 802.11w. +#CONFIG_IEEE80211W=y + +# Integrated EAP server +#CONFIG_EAP=y + +# EAP Re-authentication Protocol (ERP) in integrated EAP server +#CONFIG_ERP=y + +# EAP-MD5 for the integrated EAP server +#CONFIG_EAP_MD5=y + +# EAP-TLS for the integrated EAP server +#CONFIG_EAP_TLS=y + +# EAP-MSCHAPv2 for the integrated EAP server +#CONFIG_EAP_MSCHAPV2=y + +# EAP-PEAP for the integrated EAP server +#CONFIG_EAP_PEAP=y + +# EAP-GTC for the integrated EAP server +#CONFIG_EAP_GTC=y + +# EAP-TTLS for the integrated EAP server +#CONFIG_EAP_TTLS=y + +# EAP-SIM for the integrated EAP server +#CONFIG_EAP_SIM=y + +# EAP-AKA for the integrated EAP server +#CONFIG_EAP_AKA=y + +# EAP-AKA' for the integrated EAP server +# This requires CONFIG_EAP_AKA to be enabled, too. +#CONFIG_EAP_AKA_PRIME=y + +# EAP-PAX for the integrated EAP server +#CONFIG_EAP_PAX=y + +# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) +#CONFIG_EAP_PSK=y + +# EAP-pwd for the integrated EAP server (secure authentication with a password) +#CONFIG_EAP_PWD=y + +# EAP-SAKE for the integrated EAP server +#CONFIG_EAP_SAKE=y + +# EAP-GPSK for the integrated EAP server +#CONFIG_EAP_GPSK=y +# Include support for optional SHA256 cipher suite in EAP-GPSK +#CONFIG_EAP_GPSK_SHA256=y + +# EAP-FAST for the integrated EAP server +# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed +# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g., +# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions. +#CONFIG_EAP_FAST=y + +# Wi-Fi Protected Setup (WPS) +#CONFIG_WPS=y +# Enable UPnP support for external WPS Registrars +#CONFIG_WPS_UPNP=y +# Enable WPS support with NFC config method +#CONFIG_WPS_NFC=y + +# EAP-IKEv2 +#CONFIG_EAP_IKEV2=y + +# Trusted Network Connect (EAP-TNC) +#CONFIG_EAP_TNC=y + +# EAP-EKE for the integrated EAP server +#CONFIG_EAP_EKE=y + +# PKCS#12 (PFX) support (used to read private key and certificate file from +# a file that usually has extension .p12 or .pfx) +#CONFIG_PKCS12=y + +# RADIUS authentication server. This provides access to the integrated EAP +# server from external hosts using RADIUS. +#CONFIG_RADIUS_SERVER=y + +# Build IPv6 support for RADIUS operations +#CONFIG_IPV6=y + +# IEEE Std 802.11r-2008 (Fast BSS Transition) +#CONFIG_IEEE80211R=y + +# Use the hostapd's IEEE 802.11 authentication (ACL), but without +# the IEEE 802.11 Management capability (e.g., FreeBSD/net80211) +#CONFIG_DRIVER_RADIUS_ACL=y + +# IEEE 802.11n (High Throughput) support +CONFIG_IEEE80211N=y + +# Wireless Network Management (IEEE Std 802.11v-2011) +# Note: This is experimental and not complete implementation. +#CONFIG_WNM=y + +# IEEE 802.11ac (Very High Throughput) support +CONFIG_IEEE80211AC=y + +# IEEE 802.11ax HE support +# Note: This is experimental and work in progress. The definitions are still +# subject to change and this should not be expected to interoperate with the +# final IEEE 802.11ax version. +#CONFIG_IEEE80211AX=y + +# Remove debugging code that is printing out debug messages to stdout. +# This can be used to reduce the size of the hostapd considerably if debugging +# code is not needed. +#CONFIG_NO_STDOUT_DEBUG=y + +# Add support for writing debug log to a file: -f /tmp/hostapd.log +# Disabled by default. +#CONFIG_DEBUG_FILE=y + +# Send debug messages to syslog instead of stdout +CONFIG_DEBUG_SYSLOG=y + +# Add support for sending all debug messages (regardless of debug verbosity) +# to the Linux kernel tracing facility. This helps debug the entire stack by +# making it easy to record everything happening from the driver up into the +# same file, e.g., using trace-cmd. +#CONFIG_DEBUG_LINUX_TRACING=y + +# Remove support for RADIUS accounting +CONFIG_NO_ACCOUNTING=y + +# Remove support for RADIUS +CONFIG_NO_RADIUS=y + +# Remove support for VLANs +#CONFIG_NO_VLAN=y + +# Enable support for fully dynamic VLANs. This enables hostapd to +# automatically create bridge and VLAN interfaces if necessary. +#CONFIG_FULL_DYNAMIC_VLAN=y + +# Use netlink-based kernel API for VLAN operations instead of ioctl() +# Note: This requires libnl 3.1 or newer. +#CONFIG_VLAN_NETLINK=y + +# Remove support for dumping internal state through control interface commands +# This can be used to reduce binary size at the cost of disabling a debugging +# option. +CONFIG_NO_DUMP_STATE=y + +# Enable tracing code for developer debugging +# This tracks use of memory allocations and other registrations and reports +# incorrect use with a backtrace of call (or allocation) location. +#CONFIG_WPA_TRACE=y +# For BSD, comment out these. +#LIBS += -lexecinfo +#LIBS_p += -lexecinfo +#LIBS_c += -lexecinfo + +# Use libbfd to get more details for developer debugging +# This enables use of libbfd to get more detailed symbols for the backtraces +# generated by CONFIG_WPA_TRACE=y. +#CONFIG_WPA_TRACE_BFD=y +# For BSD, comment out these. +#LIBS += -lbfd -liberty -lz +#LIBS_p += -lbfd -liberty -lz +#LIBS_c += -lbfd -liberty -lz + +# hostapd depends on strong random number generation being available from the +# operating system. os_get_random() function is used to fetch random data when +# needed, e.g., for key generation. On Linux and BSD systems, this works by +# reading /dev/urandom. It should be noted that the OS entropy pool needs to be +# properly initialized before hostapd is started. This is important especially +# on embedded devices that do not have a hardware random number generator and +# may by default start up with minimal entropy available for random number +# generation. +# +# As a safety net, hostapd is by default trying to internally collect +# additional entropy for generating random data to mix in with the data +# fetched from the OS. This by itself is not considered to be very strong, but +# it may help in cases where the system pool is not initialized properly. +# However, it is very strongly recommended that the system pool is initialized +# with enough entropy either by using hardware assisted random number +# generator or by storing state over device reboots. +# +# hostapd can be configured to maintain its own entropy store over restarts to +# enhance random number generation. This is not perfect, but it is much more +# secure than using the same sequence of random numbers after every reboot. +# This can be enabled with -e command line option. The specified +# file needs to be readable and writable by hostapd. +# +# If the os_get_random() is known to provide strong random data (e.g., on +# Linux/BSD, the board in question is known to have reliable source of random +# data from /dev/urandom), the internal hostapd random pool can be disabled. +# This will save some in binary size and CPU use. However, this should only be +# considered for builds that are known to be used on devices that meet the +# requirements described above. +CONFIG_NO_RANDOM_POOL=y + +# Should we use poll instead of select? Select is used by default. +#CONFIG_ELOOP_POLL=y + +# Should we use epoll instead of select? Select is used by default. +#CONFIG_ELOOP_EPOLL=y + +# Should we use kqueue instead of select? Select is used by default. +#CONFIG_ELOOP_KQUEUE=y + +# Select TLS implementation +# openssl = OpenSSL (default) +# gnutls = GnuTLS +# internal = Internal TLSv1 implementation (experimental) +# linux = Linux kernel AF_ALG and internal TLSv1 implementation (experimental) +# none = Empty template +CONFIG_TLS=internal + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1) +# can be enabled to get a stronger construction of messages when block ciphers +# are used. +#CONFIG_TLSV11=y + +# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2) +# can be enabled to enable use of stronger crypto algorithms. +#CONFIG_TLSV12=y + +# Select which ciphers to use by default with OpenSSL if the user does not +# specify them. +#CONFIG_TLS_DEFAULT_CIPHERS="DEFAULT:!EXP:!LOW" + +# If CONFIG_TLS=internal is used, additional library and include paths are +# needed for LibTomMath. Alternatively, an integrated, minimal version of +# LibTomMath can be used. See beginning of libtommath.c for details on benefits +# and drawbacks of this option. +#CONFIG_INTERNAL_LIBTOMMATH=y +#ifndef CONFIG_INTERNAL_LIBTOMMATH +#LTM_PATH=/usr/src/libtommath-0.39 +#CFLAGS += -I$(LTM_PATH) +#LIBS += -L$(LTM_PATH) +#LIBS_p += -L$(LTM_PATH) +#endif +# At the cost of about 4 kB of additional binary size, the internal LibTomMath +# can be configured to include faster routines for exptmod, sqr, and div to +# speed up DH and RSA calculation considerably +#CONFIG_INTERNAL_LIBTOMMATH_FAST=y + +# Interworking (IEEE 802.11u) +# This can be used to enable functionality to improve interworking with +# external networks. +#CONFIG_INTERWORKING=y + +# Hotspot 2.0 +#CONFIG_HS20=y + +# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file +#CONFIG_SQLITE=y + +# Enable Fast Session Transfer (FST) +#CONFIG_FST=y + +# Enable CLI commands for FST testing +#CONFIG_FST_TEST=y + +# Testing options +# This can be used to enable some testing options (see also the example +# configuration file) that are really useful only for testing clients that +# connect to this hostapd. These options allow, for example, to drop a +# certain percentage of probe requests or auth/(re)assoc frames. +# +#CONFIG_TESTING_OPTIONS=y + +# Automatic Channel Selection +# This will allow hostapd to pick the channel automatically when channel is set +# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in +# similar way. +# +# Automatic selection is currently only done through initialization, later on +# we hope to do background checks to keep us moving to more ideal channels as +# time goes by. ACS is currently only supported through the nl80211 driver and +# your driver must have survey dump capability that is filled by the driver +# during scanning. +# +# You can customize the ACS survey algorithm with the hostapd.conf variable +# acs_num_scans. +# +# Supported ACS drivers: +# * ath9k +# * ath5k +# * ath10k +# +# For more details refer to: +# http://wireless.kernel.org/en/users/Documentation/acs +# +#CONFIG_ACS=y + +# Multiband Operation support +# These extentions facilitate efficient use of multiple frequency bands +# available to the AP and the devices that may associate with it. +#CONFIG_MBO=y + +# Client Taxonomy +# Has the AP retain the Probe Request and (Re)Association Request frames from +# a client, from which a signature can be produced which can identify the model +# of client device like "Nexus 6P" or "iPhone 5s". +#CONFIG_TAXONOMY=y + +# Fast Initial Link Setup (FILS) (IEEE 802.11ai) +# Note: This is an experimental and not yet complete implementation. This +# should not be enabled for production use. +#CONFIG_FILS=y +# FILS shared key authentication with PFS +#CONFIG_FILS_SK_PFS=y + +# Include internal line edit mode in hostapd_cli. This can be used to provide +# limited command line editing and history support. +#CONFIG_WPA_CLI_EDIT=y + +# Opportunistic Wireless Encryption (OWE) +# Experimental implementation of draft-harkins-owe-07.txt +#CONFIG_OWE=y + +# uBus IPC/RPC System +# Services can connect to the bus and provide methods +# that can be called by other services or clients. +CONFIG_UBUS=y diff --git a/root/package/network/services/hostapd/files/hostapd.sh b/root/package/network/services/hostapd/files/hostapd.sh new file mode 100644 index 00000000..f50081bb --- /dev/null +++ b/root/package/network/services/hostapd/files/hostapd.sh @@ -0,0 +1,856 @@ +. /lib/functions/network.sh + +wpa_supplicant_add_rate() { + local var="$1" + local val="$(($2 / 1000))" + local sub="$((($2 / 100) % 10))" + append $var "$val" "," + [ $sub -gt 0 ] && append $var "." +} + +hostapd_add_rate() { + local var="$1" + local val="$(($2 / 100))" + append $var "$val" " " +} + +hostapd_append_wep_key() { + local var="$1" + + wep_keyidx=0 + set_default key 1 + case "$key" in + [1234]) + for idx in 1 2 3 4; do + local zidx + zidx=$(($idx - 1)) + json_get_var ckey "key${idx}" + [ -n "$ckey" ] && \ + append $var "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N$T" + done + wep_keyidx=$((key - 1)) + ;; + *) + append $var "wep_key0=$(prepare_key_wep "$key")" "$N$T" + ;; + esac +} + +hostapd_append_wpa_key_mgmt() { + local auth_type="$(echo $auth_type | tr 'a-z' 'A-Z')" + + append wpa_key_mgmt "WPA-$auth_type" + [ "${ieee80211r:-0}" -gt 0 ] && append wpa_key_mgmt "FT-${auth_type}" + [ "${ieee80211w:-0}" -gt 0 ] && append wpa_key_mgmt "WPA-${auth_type}-SHA256" +} + +hostapd_add_log_config() { + config_add_boolean \ + log_80211 \ + log_8021x \ + log_radius \ + log_wpa \ + log_driver \ + log_iapp \ + log_mlme + + config_add_int log_level +} + +hostapd_common_add_device_config() { + config_add_array basic_rate + config_add_array supported_rates + + config_add_string country + config_add_boolean country_ie doth + config_add_string require_mode + config_add_boolean legacy_rates + + config_add_string acs_chan_bias + config_add_array hostapd_options + + hostapd_add_log_config +} + +hostapd_prepare_device_config() { + local config="$1" + local driver="$2" + + local base="${config%%.conf}" + local base_cfg= + + json_get_vars country country_ie beacon_int:100 doth require_mode legacy_rates acs_chan_bias + + hostapd_set_log_options base_cfg + + set_default country_ie 1 + set_default doth 1 + set_default legacy_rates 1 + + [ "$hwmode" = "b" ] && legacy_rates=1 + + [ -n "$country" ] && { + append base_cfg "country_code=$country" "$N" + + [ "$country_ie" -gt 0 ] && append base_cfg "ieee80211d=1" "$N" + [ "$hwmode" = "a" -a "$doth" -gt 0 ] && append base_cfg "ieee80211h=1" "$N" + } + + [ -n "$acs_chan_bias" ] && append base_cfg "acs_chan_bias=$acs_chan_bias" "$N" + + local brlist= br + json_get_values basic_rate_list basic_rate + local rlist= r + json_get_values rate_list supported_rates + + [ -n "$hwmode" ] && append base_cfg "hw_mode=$hwmode" "$N" + [ "$legacy_rates" -eq 0 ] && set_default require_mode g + + [ "$hwmode" = "g" ] && { + [ "$legacy_rates" -eq 0 ] && set_default rate_list "6000 9000 12000 18000 24000 36000 48000 54000" + [ -n "$require_mode" ] && set_default basic_rate_list "6000 12000 24000" + } + + case "$require_mode" in + n) append base_cfg "require_ht=1" "$N";; + ac) append base_cfg "require_vht=1" "$N";; + esac + + for r in $rate_list; do + hostapd_add_rate rlist "$r" + done + + for br in $basic_rate_list; do + hostapd_add_rate brlist "$br" + done + + [ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N" + [ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N" + append base_cfg "beacon_int=$beacon_int" "$N" + + json_get_values opts hostapd_options + for val in $opts; do + append base_cfg "$val" "$N" + done + + cat > "$config" <