From 09eb0166d0fd83b140318de191857998076dc950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 9 Jan 2016 18:38:01 +0000 Subject: mac80211: rename patches to use all prefixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After last commit we got few unuset slots (prefixes). Use all available numbers one by one to allow more backports. This doesn't change a single patch (or order), only renames files. Signed-off-by: Rafał Miłecki git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@48164 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- ...51-ath9k-fix-DMA-stop-sequence-for-AR9003.patch | 33 +++ ...pport-NVRAMs-containing-pci-devpaths-inst.patch | 56 ++++ ...t-wiphy-perm_addr-to-hardware-MAC-address.patch | 23 ++ ...e-direct-data-pointer-in-NVRAM-parser-str.patch | 144 +++++++++ ...port-for-14e4-4321-PCI-dev-with-BCM4321-c.patch | 32 ++ ...56-ath9k-force-rx_clear-when-disabling-rx.patch | 31 ++ ...cmfmac-Update-msgbuf-read-pointer-quicker.patch | 109 +++++++ ...02-brcmfmac-remove-chipinfo-debugfs-entry.patch | 39 +++ ...move-watchdog-reset-from-brcmf_pcie_busco.patch | 53 ++++ ...e-debugfs_create_devm_seqfile-helper-func.patch | 69 +++++ ...8-ath9k_hw-fix-device-ID-check-for-AR956x.patch | 20 ++ ...1-brcmfmac-Check-if-firmware-supports-p2p.patch | 42 +++ ...ild-wiphy-mode-and-interface-combinations.patch | 198 +++++++++++++ ...003-brcmfmac-rework-.get_station-callback.patch | 326 +++++++++++++++++++++ ...ve-sdio-return-EIO-when-device-communicat.patch | 56 ++++ ...make-DMA-stop-related-messages-debug-only.patch | 74 +++++ ...ee-ifp-for-non-netdev-interface-in-p2p-mo.patch | 44 +++ ...brcmfmac-move-p2p-attach-detach-functions.patch | 225 ++++++++++++++ ...sure-p2pdev-is-unregistered-upon-driver-u.patch | 63 ++++ ...mfmac-fix-double-free-of-p2pdev-interface.patch | 27 ++ ...ac-make-brcmf_p2p_detach-call-conditional.patch | 29 ++ ...t-wiphy-s-addresses-to-provide-valid-MACs.patch | 67 +++++ ...d_sdio.c-use-existing-atomic_or-primitive.patch | 45 +++ ...eck-all-combinations-when-setting-wiphy-s.patch | 46 +++ ...cmfmac-correct-interface-combination-info.patch | 204 +++++++++++++ ...c-add-debugfs-entry-for-msgbuf-statistics.patch | 87 ++++++ ...c-make-use-of-cfg80211_check_combinations.patch | 83 ++++++ ...ock-the-correct-flowring-when-backup-queu.patch | 48 +++ ...mp-highest-event-number-for-4339-firmware.patch | 52 ++++ ...mac-consolidate-ifp-lookup-in-driver-core.patch | 138 +++++++++ ...ke-brcmf_proto_hdrpull-return-struct-brcm.patch | 222 ++++++++++++++ ...ange-parameters-for-brcmf_remove_interfac.patch | 87 ++++++ ...ly-call-brcmf_cfg80211_detach-when-attach.patch | 92 ++++++ ...rrect-detection-of-p2pdev-interface-event.patch | 105 +++++++ ...e-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch | 126 ++++++++ ...ss-struct-brcmf_if-instance-in-brcmf_txfi.patch | 122 ++++++++ ...d-mapping-for-interface-index-to-bsscfg-i.patch | 92 ++++++ ...d-dedicated-debug-level-for-firmware-cons.patch | 103 +++++++ ...move-ifidx-parameter-from-brcmf_fws_txsta.patch | 34 +++ ...ac-change-prototype-for-brcmf_fws_hdrpull.patch | 97 ++++++ ...mfmac-introduce-brcmf_net_detach-function.patch | 99 +++++++ ...fmac-Reset-PCIE-devices-after-recognition.patch | 193 ++++++++++++ ...DMA-related-firmware-crashes-on-multiple-.patch | 24 ++ ...-ath9k-declare-required-extra-tx-headroom.patch | 22 ++ ...itialize-tid-field-in-struct-ieee80211_tx.patch | 21 ++ ...79-ath9k-fix-DMA-stop-sequence-for-AR9003.patch | 33 --- ...pport-NVRAMs-containing-pci-devpaths-inst.patch | 56 ---- ...t-wiphy-perm_addr-to-hardware-MAC-address.patch | 23 -- ...e-direct-data-pointer-in-NVRAM-parser-str.patch | 144 --------- ...port-for-14e4-4321-PCI-dev-with-BCM4321-c.patch | 32 -- ...84-ath9k-force-rx_clear-when-disabling-rx.patch | 31 -- ...cmfmac-Update-msgbuf-read-pointer-quicker.patch | 109 ------- ...02-brcmfmac-remove-chipinfo-debugfs-entry.patch | 39 --- ...move-watchdog-reset-from-brcmf_pcie_busco.patch | 53 ---- ...e-debugfs_create_devm_seqfile-helper-func.patch | 69 ----- ...5-ath9k_hw-fix-device-ID-check-for-AR956x.patch | 20 -- ...1-brcmfmac-Check-if-firmware-supports-p2p.patch | 42 --- ...ild-wiphy-mode-and-interface-combinations.patch | 198 ------------- ...003-brcmfmac-rework-.get_station-callback.patch | 326 --------------------- ...ve-sdio-return-EIO-when-device-communicat.patch | 56 ---- ...make-DMA-stop-related-messages-debug-only.patch | 74 ----- ...ee-ifp-for-non-netdev-interface-in-p2p-mo.patch | 44 --- ...brcmfmac-move-p2p-attach-detach-functions.patch | 225 -------------- ...sure-p2pdev-is-unregistered-upon-driver-u.patch | 63 ---- ...mfmac-fix-double-free-of-p2pdev-interface.patch | 27 -- ...ac-make-brcmf_p2p_detach-call-conditional.patch | 29 -- ...t-wiphy-s-addresses-to-provide-valid-MACs.patch | 67 ----- ...d_sdio.c-use-existing-atomic_or-primitive.patch | 45 --- ...eck-all-combinations-when-setting-wiphy-s.patch | 46 --- ...cmfmac-correct-interface-combination-info.patch | 204 ------------- ...c-add-debugfs-entry-for-msgbuf-statistics.patch | 87 ------ ...c-make-use-of-cfg80211_check_combinations.patch | 83 ------ ...ock-the-correct-flowring-when-backup-queu.patch | 48 --- ...mp-highest-event-number-for-4339-firmware.patch | 52 ---- ...mac-consolidate-ifp-lookup-in-driver-core.patch | 138 --------- ...ke-brcmf_proto_hdrpull-return-struct-brcm.patch | 222 -------------- ...ange-parameters-for-brcmf_remove_interfac.patch | 87 ------ ...ly-call-brcmf_cfg80211_detach-when-attach.patch | 92 ------ ...rrect-detection-of-p2pdev-interface-event.patch | 105 ------- ...e-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch | 126 -------- ...ss-struct-brcmf_if-instance-in-brcmf_txfi.patch | 122 -------- ...d-mapping-for-interface-index-to-bsscfg-i.patch | 92 ------ ...d-dedicated-debug-level-for-firmware-cons.patch | 103 ------- ...move-ifidx-parameter-from-brcmf_fws_txsta.patch | 34 --- ...ac-change-prototype-for-brcmf_fws_hdrpull.patch | 97 ------ ...mfmac-introduce-brcmf_net_detach-function.patch | 99 ------- ...fmac-Reset-PCIE-devices-after-recognition.patch | 193 ------------ ...DMA-related-firmware-crashes-on-multiple-.patch | 24 -- ...-ath9k-declare-required-extra-tx-headroom.patch | 22 -- ...itialize-tid-field-in-struct-ieee80211_tx.patch | 21 -- 90 files changed, 3902 insertions(+), 3902 deletions(-) create mode 100644 package/kernel/mac80211/patches/351-ath9k-fix-DMA-stop-sequence-for-AR9003.patch create mode 100644 package/kernel/mac80211/patches/352-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch create mode 100644 package/kernel/mac80211/patches/353-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch create mode 100644 package/kernel/mac80211/patches/354-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch create mode 100644 package/kernel/mac80211/patches/355-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch create mode 100644 package/kernel/mac80211/patches/356-ath9k-force-rx_clear-when-disabling-rx.patch create mode 100644 package/kernel/mac80211/patches/357-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch create mode 100644 package/kernel/mac80211/patches/357-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch create mode 100644 package/kernel/mac80211/patches/357-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch create mode 100644 package/kernel/mac80211/patches/357-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch create mode 100644 package/kernel/mac80211/patches/358-ath9k_hw-fix-device-ID-check-for-AR956x.patch create mode 100644 package/kernel/mac80211/patches/359-0001-brcmfmac-Check-if-firmware-supports-p2p.patch create mode 100644 package/kernel/mac80211/patches/359-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch create mode 100644 package/kernel/mac80211/patches/359-0003-brcmfmac-rework-.get_station-callback.patch create mode 100644 package/kernel/mac80211/patches/359-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch create mode 100644 package/kernel/mac80211/patches/359-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch create mode 100644 package/kernel/mac80211/patches/359-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch create mode 100644 package/kernel/mac80211/patches/359-0007-brcmfmac-move-p2p-attach-detach-functions.patch create mode 100644 package/kernel/mac80211/patches/359-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch create mode 100644 package/kernel/mac80211/patches/360-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch create mode 100644 package/kernel/mac80211/patches/360-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch create mode 100644 package/kernel/mac80211/patches/361-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch create mode 100644 package/kernel/mac80211/patches/362-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch create mode 100644 package/kernel/mac80211/patches/363-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch create mode 100644 package/kernel/mac80211/patches/363-0002-brcmfmac-correct-interface-combination-info.patch create mode 100644 package/kernel/mac80211/patches/363-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch create mode 100644 package/kernel/mac80211/patches/363-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch create mode 100644 package/kernel/mac80211/patches/363-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch create mode 100644 package/kernel/mac80211/patches/363-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch create mode 100644 package/kernel/mac80211/patches/365-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch create mode 100644 package/kernel/mac80211/patches/365-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch create mode 100644 package/kernel/mac80211/patches/365-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch create mode 100644 package/kernel/mac80211/patches/365-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch create mode 100644 package/kernel/mac80211/patches/365-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch create mode 100644 package/kernel/mac80211/patches/365-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch create mode 100644 package/kernel/mac80211/patches/365-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch create mode 100644 package/kernel/mac80211/patches/365-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch create mode 100644 package/kernel/mac80211/patches/365-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch create mode 100644 package/kernel/mac80211/patches/365-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch create mode 100644 package/kernel/mac80211/patches/365-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch create mode 100644 package/kernel/mac80211/patches/365-0012-brcmfmac-introduce-brcmf_net_detach-function.patch create mode 100644 package/kernel/mac80211/patches/366-brcmfmac-Reset-PCIE-devices-after-recognition.patch create mode 100644 package/kernel/mac80211/patches/367-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch create mode 100644 package/kernel/mac80211/patches/368-ath9k-declare-required-extra-tx-headroom.patch create mode 100644 package/kernel/mac80211/patches/369-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch delete mode 100644 package/kernel/mac80211/patches/379-ath9k-fix-DMA-stop-sequence-for-AR9003.patch delete mode 100644 package/kernel/mac80211/patches/380-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch delete mode 100644 package/kernel/mac80211/patches/381-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch delete mode 100644 package/kernel/mac80211/patches/382-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch delete mode 100644 package/kernel/mac80211/patches/383-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch delete mode 100644 package/kernel/mac80211/patches/384-ath9k-force-rx_clear-when-disabling-rx.patch delete mode 100644 package/kernel/mac80211/patches/385-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch delete mode 100644 package/kernel/mac80211/patches/385-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch delete mode 100644 package/kernel/mac80211/patches/385-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch delete mode 100644 package/kernel/mac80211/patches/385-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch delete mode 100644 package/kernel/mac80211/patches/385-ath9k_hw-fix-device-ID-check-for-AR956x.patch delete mode 100644 package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch delete mode 100644 package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch delete mode 100644 package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch delete mode 100644 package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch delete mode 100644 package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch delete mode 100644 package/kernel/mac80211/patches/389-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch delete mode 100644 package/kernel/mac80211/patches/389-0007-brcmfmac-move-p2p-attach-detach-functions.patch delete mode 100644 package/kernel/mac80211/patches/389-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch delete mode 100644 package/kernel/mac80211/patches/390-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch delete mode 100644 package/kernel/mac80211/patches/390-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch delete mode 100644 package/kernel/mac80211/patches/391-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch delete mode 100644 package/kernel/mac80211/patches/392-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch delete mode 100644 package/kernel/mac80211/patches/393-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch delete mode 100644 package/kernel/mac80211/patches/393-0002-brcmfmac-correct-interface-combination-info.patch delete mode 100644 package/kernel/mac80211/patches/393-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch delete mode 100644 package/kernel/mac80211/patches/393-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch delete mode 100644 package/kernel/mac80211/patches/393-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch delete mode 100644 package/kernel/mac80211/patches/393-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch delete mode 100644 package/kernel/mac80211/patches/394-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch delete mode 100644 package/kernel/mac80211/patches/394-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch delete mode 100644 package/kernel/mac80211/patches/394-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch delete mode 100644 package/kernel/mac80211/patches/394-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch delete mode 100644 package/kernel/mac80211/patches/394-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch delete mode 100644 package/kernel/mac80211/patches/394-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch delete mode 100644 package/kernel/mac80211/patches/394-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch delete mode 100644 package/kernel/mac80211/patches/394-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch delete mode 100644 package/kernel/mac80211/patches/394-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch delete mode 100644 package/kernel/mac80211/patches/394-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch delete mode 100644 package/kernel/mac80211/patches/394-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch delete mode 100644 package/kernel/mac80211/patches/394-0012-brcmfmac-introduce-brcmf_net_detach-function.patch delete mode 100644 package/kernel/mac80211/patches/395-brcmfmac-Reset-PCIE-devices-after-recognition.patch delete mode 100644 package/kernel/mac80211/patches/396-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch delete mode 100644 package/kernel/mac80211/patches/397-ath9k-declare-required-extra-tx-headroom.patch delete mode 100644 package/kernel/mac80211/patches/398-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch diff --git a/package/kernel/mac80211/patches/351-ath9k-fix-DMA-stop-sequence-for-AR9003.patch b/package/kernel/mac80211/patches/351-ath9k-fix-DMA-stop-sequence-for-AR9003.patch new file mode 100644 index 0000000000..814b0d7a4a --- /dev/null +++ b/package/kernel/mac80211/patches/351-ath9k-fix-DMA-stop-sequence-for-AR9003.patch @@ -0,0 +1,33 @@ +From: Felix Fietkau +Date: Tue, 2 Jun 2015 10:35:46 +0200 +Subject: [PATCH] ath9k: fix DMA stop sequence for AR9003+ + +AR93xx and newer needs to stop rx before tx to avoid getting the DMA +engine or MAC into a stuck state. +This should reduce/fix the occurence of "Failed to stop Tx DMA" logspam. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -216,11 +216,13 @@ static bool ath_prepare_reset(struct ath + ath_stop_ani(sc); + ath9k_hw_disable_interrupts(ah); + +- if (!ath_drain_all_txq(sc)) +- ret = false; +- +- if (!ath_stoprecv(sc)) +- ret = false; ++ if (AR_SREV_9300_20_OR_LATER(ah)) { ++ ret &= ath_stoprecv(sc); ++ ret &= ath_drain_all_txq(sc); ++ } else { ++ ret &= ath_drain_all_txq(sc); ++ ret &= ath_stoprecv(sc); ++ } + + return ret; + } diff --git a/package/kernel/mac80211/patches/352-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch b/package/kernel/mac80211/patches/352-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch new file mode 100644 index 0000000000..7bbd57e15e --- /dev/null +++ b/package/kernel/mac80211/patches/352-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch @@ -0,0 +1,56 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 28 May 2015 14:19:21 +0200 +Subject: [PATCH] brcmfmac: support NVRAMs containing pci devpaths (instead of + pcie) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Recently Broadcom added support for NVRAMs with entries for multiple +PCIe devices. One of the supported formats is based on prefixes defined +like: devpath0=pcie/1/4/ and entries like 0:foo=bar 0:baz=qux etc. + +Unfortunately there are also a bit older devices using different way of +defining prefixes, e.g. SmartRG SR400ac (2 x BCM43602) with entries: +devpath0=pci/1/1/ +devpath1=pci/2/1 +Broadcom stated this old format will never be used/supported by brcmfmac +but given the simplicity of this patch I'll insist on supporting it. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +@@ -232,6 +232,8 @@ static void brcmf_fw_strip_multi_v1(stru + u16 bus_nr) + { + /* Device path with a leading '=' key-value separator */ ++ char pci_path[] = "=pci/?/?"; ++ size_t pci_len; + char pcie_path[] = "=pcie/?/?"; + size_t pcie_len; + +@@ -251,6 +253,9 @@ static void brcmf_fw_strip_multi_v1(stru + /* First search for the devpathX and see if it is the configuration + * for domain_nr/bus_nr. Search complete nvp + */ ++ snprintf(pci_path, sizeof(pci_path), "=pci/%d/%d", domain_nr, ++ bus_nr); ++ pci_len = strlen(pci_path); + snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr, + bus_nr); + pcie_len = strlen(pcie_path); +@@ -260,8 +265,9 @@ static void brcmf_fw_strip_multi_v1(stru + /* Format: devpathX=pcie/Y/Z/ + * Y = domain_nr, Z = bus_nr, X = virtual ID + */ +- if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && +- (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) { ++ if (strncmp(&nvp->nvram[i], "devpath", 7) == 0 && ++ (!strncmp(&nvp->nvram[i + 8], pci_path, pci_len) || ++ !strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len))) { + id = nvp->nvram[i + 7] - '0'; + found = true; + break; diff --git a/package/kernel/mac80211/patches/353-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch b/package/kernel/mac80211/patches/353-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch new file mode 100644 index 0000000000..1eff6ed83a --- /dev/null +++ b/package/kernel/mac80211/patches/353-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch @@ -0,0 +1,23 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 31 May 2015 02:52:26 +0200 +Subject: [PATCH] brcmfmac: set wiphy perm_addr to hardware MAC address +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This allows e.g. user space to use /sys/class/ieee80211/*/macaddress + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -6070,6 +6070,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + brcmf_err("Could not allocate wiphy device\n"); + return NULL; + } ++ memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN); + set_wiphy_dev(wiphy, busdev); + + cfg = wiphy_priv(wiphy); diff --git a/package/kernel/mac80211/patches/354-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch b/package/kernel/mac80211/patches/354-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch new file mode 100644 index 0000000000..c6e83ddd29 --- /dev/null +++ b/package/kernel/mac80211/patches/354-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch @@ -0,0 +1,144 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 4 Jun 2015 22:11:07 +0200 +Subject: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As we plan to add support for platform NVRAM we should store direct +data pointer without the extra struct firmware layer. This will allow +us to support other sources with the only requirement being u8 buffer. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c +@@ -43,7 +43,7 @@ enum nvram_parser_state { + * struct nvram_parser - internal info for parser. + * + * @state: current parser state. +- * @fwnv: input buffer being parsed. ++ * @data: input buffer being parsed. + * @nvram: output buffer with parse result. + * @nvram_len: lenght of parse result. + * @line: current line. +@@ -55,7 +55,7 @@ enum nvram_parser_state { + */ + struct nvram_parser { + enum nvram_parser_state state; +- const struct firmware *fwnv; ++ const u8 *data; + u8 *nvram; + u32 nvram_len; + u32 line; +@@ -91,7 +91,7 @@ static enum nvram_parser_state brcmf_nvr + { + char c; + +- c = nvp->fwnv->data[nvp->pos]; ++ c = nvp->data[nvp->pos]; + if (c == '\n') + return COMMENT; + if (is_whitespace(c)) +@@ -115,16 +115,16 @@ static enum nvram_parser_state brcmf_nvr + enum nvram_parser_state st = nvp->state; + char c; + +- c = nvp->fwnv->data[nvp->pos]; ++ c = nvp->data[nvp->pos]; + if (c == '=') { + /* ignore RAW1 by treating as comment */ +- if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0) ++ if (strncmp(&nvp->data[nvp->entry], "RAW1", 4) == 0) + st = COMMENT; + else + st = VALUE; +- if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) ++ if (strncmp(&nvp->data[nvp->entry], "devpath", 7) == 0) + nvp->multi_dev_v1 = true; +- if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) ++ if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) + nvp->multi_dev_v2 = true; + } else if (!is_nvram_char(c) || c == ' ') { + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", +@@ -145,11 +145,11 @@ brcmf_nvram_handle_value(struct nvram_pa + char *ekv; + u32 cplen; + +- c = nvp->fwnv->data[nvp->pos]; ++ c = nvp->data[nvp->pos]; + if (!is_nvram_char(c)) { + /* key,value pair complete */ +- ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; +- skv = (u8 *)&nvp->fwnv->data[nvp->entry]; ++ ekv = (u8 *)&nvp->data[nvp->pos]; ++ skv = (u8 *)&nvp->data[nvp->entry]; + cplen = ekv - skv; + if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE) + return END; +@@ -170,7 +170,7 @@ brcmf_nvram_handle_comment(struct nvram_ + { + char *eoc, *sol; + +- sol = (char *)&nvp->fwnv->data[nvp->pos]; ++ sol = (char *)&nvp->data[nvp->pos]; + eoc = strchr(sol, '\n'); + if (!eoc) { + eoc = strchr(sol, '\0'); +@@ -201,17 +201,17 @@ static enum nvram_parser_state + }; + + static int brcmf_init_nvram_parser(struct nvram_parser *nvp, +- const struct firmware *nv) ++ const u8 *data, size_t data_len) + { + size_t size; + + memset(nvp, 0, sizeof(*nvp)); +- nvp->fwnv = nv; ++ nvp->data = data; + /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ +- if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE) ++ if (data_len > BRCMF_FW_MAX_NVRAM_SIZE) + size = BRCMF_FW_MAX_NVRAM_SIZE; + else +- size = nv->size; ++ size = data_len; + /* Alloc for extra 0 byte + roundup by 4 + length field */ + size += 1 + 3 + sizeof(u32); + nvp->nvram = kzalloc(size, GFP_KERNEL); +@@ -362,18 +362,18 @@ fail: + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. + * End of buffer is completed with token identifying length of buffer. + */ +-static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length, +- u16 domain_nr, u16 bus_nr) ++static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len, ++ u32 *new_length, u16 domain_nr, u16 bus_nr) + { + struct nvram_parser nvp; + u32 pad; + u32 token; + __le32 token_le; + +- if (brcmf_init_nvram_parser(&nvp, nv) < 0) ++ if (brcmf_init_nvram_parser(&nvp, data, data_len) < 0) + return NULL; + +- while (nvp.pos < nv->size) { ++ while (nvp.pos < data_len) { + nvp.state = nv_parser_states[nvp.state](&nvp); + if (nvp.state == END) + break; +@@ -432,7 +432,7 @@ static void brcmf_fw_request_nvram_done( + goto fail; + + if (fw) { +- nvram = brcmf_fw_nvram_strip(fw, &nvram_length, ++ nvram = brcmf_fw_nvram_strip(fw->data, fw->size, &nvram_length, + fwctx->domain_nr, fwctx->bus_nr); + release_firmware(fw); + if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) diff --git a/package/kernel/mac80211/patches/355-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch b/package/kernel/mac80211/patches/355-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch new file mode 100644 index 0000000000..4ecef3b5af --- /dev/null +++ b/package/kernel/mac80211/patches/355-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch @@ -0,0 +1,32 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sat, 6 Jun 2015 22:45:59 +0200 +Subject: [PATCH] b43: fix support for 14e4:4321 PCI dev with BCM4321 chipset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It seems Broadcom released two devices with conflicting device id. There +are for sure 14e4:4321 PCI devices with BCM4321 (N-PHY) chipset, they +can be found in routers, e.g. Netgear WNR834Bv2. However, according to +Broadcom public sources 0x4321 is also used for 5 GHz BCM4306 (G-PHY). +It's unsure if they meant PCI device id, or "virtual" id (from SPROM). +To distinguish these devices lets check PHY type (G vs. N). + +Signed-off-by: Rafał Miłecki +Cc: # 3.16+ +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -5365,6 +5365,10 @@ static void b43_supported_bands(struct b + *have_5ghz_phy = true; + return; + case 0x4321: /* BCM4306 */ ++ /* There are 14e4:4321 PCI devs with 2.4 GHz BCM4321 (N-PHY) */ ++ if (dev->phy.type != B43_PHYTYPE_G) ++ break; ++ /* fall through */ + case 0x4313: /* BCM4311 */ + case 0x431a: /* BCM4318 */ + case 0x432a: /* BCM4321 */ diff --git a/package/kernel/mac80211/patches/356-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/356-ath9k-force-rx_clear-when-disabling-rx.patch new file mode 100644 index 0000000000..bddb15ad1a --- /dev/null +++ b/package/kernel/mac80211/patches/356-ath9k-force-rx_clear-when-disabling-rx.patch @@ -0,0 +1,31 @@ +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 + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -677,13 +677,15 @@ 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); ++ REG_SET_BIT(ah, AR_DIAG_SW, ++ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); + + ath9k_hw_disable_mib_counters(ah); + } diff --git a/package/kernel/mac80211/patches/357-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch b/package/kernel/mac80211/patches/357-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch new file mode 100644 index 0000000000..74df9f93f7 --- /dev/null +++ b/package/kernel/mac80211/patches/357-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch @@ -0,0 +1,109 @@ +From: Hante Meuleman +Date: Mon, 8 Jun 2015 14:38:32 +0200 +Subject: [PATCH] brcmfmac: Update msgbuf read pointer quicker. + +On device to host data using msgbuf the read pointer gets updated +once all data is processed. Updating this pointer more frequently +allows the firmware to add more data quicker. This will result in +slightly higher and more stable throughput on CPU bounded host +processors. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c +@@ -223,8 +223,6 @@ void brcmf_commonring_write_cancel(struc + void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, + u16 *n_items) + { +- void *ret_addr; +- + if (commonring->cr_update_wptr) + commonring->cr_update_wptr(commonring->cr_ctx); + +@@ -235,19 +233,18 @@ void *brcmf_commonring_get_read_ptr(stru + if (*n_items == 0) + return NULL; + +- ret_addr = commonring->buf_addr + +- (commonring->r_ptr * commonring->item_len); +- +- commonring->r_ptr += *n_items; +- if (commonring->r_ptr == commonring->depth) +- commonring->r_ptr = 0; +- +- return ret_addr; ++ return commonring->buf_addr + ++ (commonring->r_ptr * commonring->item_len); + } + + +-int brcmf_commonring_read_complete(struct brcmf_commonring *commonring) ++int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, ++ u16 n_items) + { ++ commonring->r_ptr += n_items; ++ if (commonring->r_ptr == commonring->depth) ++ commonring->r_ptr = 0; ++ + if (commonring->cr_write_rptr) + return commonring->cr_write_rptr(commonring->cr_ctx); + +--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h +@@ -62,7 +62,8 @@ void brcmf_commonring_write_cancel(struc + u16 n_items); + void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, + u16 *n_items); +-int brcmf_commonring_read_complete(struct brcmf_commonring *commonring); ++int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, ++ u16 n_items); + + #define brcmf_commonring_n_items(commonring) (commonring->depth) + #define brcmf_commonring_len_item(commonring) (commonring->item_len) +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -75,6 +75,8 @@ + + #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96 + #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 ++#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48 ++ + + struct msgbuf_common_hdr { + u8 msgtype; +@@ -1257,19 +1259,27 @@ static void brcmf_msgbuf_process_rx(stru + { + void *buf; + u16 count; ++ u16 processed; + + again: + buf = brcmf_commonring_get_read_ptr(commonring, &count); + if (buf == NULL) + return; + ++ processed = 0; + while (count) { + brcmf_msgbuf_process_msgtype(msgbuf, + buf + msgbuf->rx_dataoffset); + buf += brcmf_commonring_len_item(commonring); ++ processed++; ++ if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) { ++ brcmf_commonring_read_complete(commonring, processed); ++ processed = 0; ++ } + count--; + } +- brcmf_commonring_read_complete(commonring); ++ if (processed) ++ brcmf_commonring_read_complete(commonring, processed); + + if (commonring->r_ptr == 0) + goto again; diff --git a/package/kernel/mac80211/patches/357-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch b/package/kernel/mac80211/patches/357-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch new file mode 100644 index 0000000000..9e5b48608d --- /dev/null +++ b/package/kernel/mac80211/patches/357-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch @@ -0,0 +1,39 @@ +From: Arend van Spriel +Date: Mon, 8 Jun 2015 14:38:33 +0200 +Subject: [PATCH] brcmfmac: remove chipinfo debugfs entry + +The information provided by chipinfo is also provided by the +revinfo debugfs entry. Removing it from debugfs. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c +@@ -41,15 +41,6 @@ void brcmf_debugfs_exit(void) + root_folder = NULL; + } + +-static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data) +-{ +- struct brcmf_bus *bus = dev_get_drvdata(seq->private); +- +- seq_printf(seq, "chip: %x(%u) rev %u\n", +- bus->chip, bus->chip, bus->chiprev); +- return 0; +-} +- + int brcmf_debugfs_attach(struct brcmf_pub *drvr) + { + struct device *dev = drvr->bus_if->dev; +@@ -58,7 +49,6 @@ int brcmf_debugfs_attach(struct brcmf_pu + return -ENODEV; + + drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); +- brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read); + + return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); + } diff --git a/package/kernel/mac80211/patches/357-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch b/package/kernel/mac80211/patches/357-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch new file mode 100644 index 0000000000..c38b2cd150 --- /dev/null +++ b/package/kernel/mac80211/patches/357-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch @@ -0,0 +1,53 @@ +From: Arend van Spriel +Date: Mon, 8 Jun 2015 14:38:34 +0200 +Subject: [PATCH] brcmfmac: remove watchdog reset from + brcmf_pcie_buscoreprep() + +The watchdog reset as done in brcmf_pcie_buscoreprep() is not +sufficient. It needs to modify PCIe core registers as well +which is properly done by brcmf_pcie_reset_device() after the +chip recognition is done. So the faulty watchdog reset can be +removed as it was causing driver reload to fail and hang the +system requiring a power-cycle. Instead the call to to the +brcmf_pcie_reset_device() function is done twice in the unload. + +Reviewed-by: Hante Meuleman +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -1629,20 +1629,7 @@ static void brcmf_pcie_buscore_write32(v + + static int brcmf_pcie_buscoreprep(void *ctx) + { +- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; +- int err; +- +- err = brcmf_pcie_get_resource(devinfo); +- if (err == 0) { +- /* Set CC watchdog to reset all the cores on the chip to bring +- * back dongle to a sane state. +- */ +- brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE, +- watchdog), 4); +- msleep(100); +- } +- +- return err; ++ return brcmf_pcie_get_resource(ctx); + } + + +@@ -1824,6 +1811,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) + brcmf_pcie_intr_disable(devinfo); + + brcmf_detach(&pdev->dev); ++ brcmf_pcie_reset_device(devinfo); + + kfree(bus->bus_priv.pcie); + kfree(bus->msgbuf->flowrings); diff --git a/package/kernel/mac80211/patches/357-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch b/package/kernel/mac80211/patches/357-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch new file mode 100644 index 0000000000..756fbb2cb7 --- /dev/null +++ b/package/kernel/mac80211/patches/357-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch @@ -0,0 +1,69 @@ +From: Arend van Spriel +Date: Mon, 8 Jun 2015 14:38:35 +0200 +Subject: [PATCH] brcmfmac: use debugfs_create_devm_seqfile() helper + function + +Some time ago the function debugfs_create_devm_seqfile() was +introduced in debugfs. The caller simply needs to provide a +device pointer and read function. The function brcmf_debugfs_add_entry() +is now simply a wrapper only doing the work for CONFIG_BRCMDBG. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c +@@ -64,44 +64,12 @@ struct dentry *brcmf_debugfs_get_devdir( + return drvr->dbgfs_dir; + } + +-struct brcmf_debugfs_entry { +- int (*read)(struct seq_file *seq, void *data); +- struct brcmf_pub *drvr; +-}; +- +-static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f) +-{ +- struct brcmf_debugfs_entry *entry = inode->i_private; +- +- return single_open(f, entry->read, entry->drvr->bus_if->dev); +-} +- +-static const struct file_operations brcmf_debugfs_def_ops = { +- .owner = THIS_MODULE, +- .open = brcmf_debugfs_entry_open, +- .release = single_release, +- .read = seq_read, +- .llseek = seq_lseek +-}; +- + int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, + int (*read_fn)(struct seq_file *seq, void *data)) + { +- struct dentry *dentry = drvr->dbgfs_dir; +- struct brcmf_debugfs_entry *entry; +- +- if (IS_ERR_OR_NULL(dentry)) +- return -ENOENT; +- +- entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL); +- if (!entry) +- return -ENOMEM; +- +- entry->read = read_fn; +- entry->drvr = drvr; +- +- dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry, +- &brcmf_debugfs_def_ops); ++ struct dentry *e; + +- return PTR_ERR_OR_ZERO(dentry); ++ e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, ++ drvr->dbgfs_dir, read_fn); ++ return PTR_ERR_OR_ZERO(e); + } diff --git a/package/kernel/mac80211/patches/358-ath9k_hw-fix-device-ID-check-for-AR956x.patch b/package/kernel/mac80211/patches/358-ath9k_hw-fix-device-ID-check-for-AR956x.patch new file mode 100644 index 0000000000..2674efb91f --- /dev/null +++ b/package/kernel/mac80211/patches/358-ath9k_hw-fix-device-ID-check-for-AR956x.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +Date: Sun, 21 Jun 2015 19:45:59 +0200 +Subject: [PATCH] ath9k_hw: fix device ID check for AR956x + +Because of the missing return, the macVersion value was being +overwritten with an invalid register read + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -278,6 +278,7 @@ static void ath9k_hw_read_revisions(stru + return; + case AR9300_DEVID_QCA956X: + ah->hw_version.macVersion = AR_SREV_VERSION_9561; ++ return; + } + + val = REG_READ(ah, AR_SREV) & AR_SREV_ID; diff --git a/package/kernel/mac80211/patches/359-0001-brcmfmac-Check-if-firmware-supports-p2p.patch b/package/kernel/mac80211/patches/359-0001-brcmfmac-Check-if-firmware-supports-p2p.patch new file mode 100644 index 0000000000..ff24a4a06f --- /dev/null +++ b/package/kernel/mac80211/patches/359-0001-brcmfmac-Check-if-firmware-supports-p2p.patch @@ -0,0 +1,42 @@ +From: Pontus Fuchs +Date: Thu, 11 Jun 2015 00:12:17 +0200 +Subject: [PATCH] brcmfmac: Check if firmware supports p2p + +Add a feature flag to reflect the firmware's p2p capability. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Reviewed-by: Arend Van Spriel +Signed-off-by: Pontus Fuchs +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c +@@ -129,6 +129,7 @@ void brcmf_feat_attach(struct brcmf_pub + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); + if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) + brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); ++ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p"); + + /* set chip related quirks */ + switch (drvr->bus_if->chip) { +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h +@@ -23,12 +23,14 @@ + * MCHAN: multi-channel for concurrent P2P. + * PNO: preferred network offload. + * WOWL: Wake-On-WLAN. ++ * P2P: peer-to-peer + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ + BRCMF_FEAT_DEF(MCHAN) \ + BRCMF_FEAT_DEF(PNO) \ +- BRCMF_FEAT_DEF(WOWL) ++ BRCMF_FEAT_DEF(WOWL) \ ++ BRCMF_FEAT_DEF(P2P) + /* + * Quirks: + * diff --git a/package/kernel/mac80211/patches/359-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch b/package/kernel/mac80211/patches/359-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch new file mode 100644 index 0000000000..3876ba01da --- /dev/null +++ b/package/kernel/mac80211/patches/359-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch @@ -0,0 +1,198 @@ +From: Pontus Fuchs +Date: Thu, 11 Jun 2015 00:12:18 +0200 +Subject: [PATCH] brcmfmac: Build wiphy mode and interface combinations + dynamically + +Switch from using semi hard coded interface combinations. This makes +it easier to announce what the firmware actually supports. This fixes +the case where brcmfmac announces p2p but the firmware doesn't +support it. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Reviewed-by: Arend Van Spriel +Signed-off-by: Pontus Fuchs +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -52,8 +52,6 @@ + #define BRCMF_PNO_SCAN_COMPLETE 1 + #define BRCMF_PNO_SCAN_INCOMPLETE 0 + +-#define BRCMF_IFACE_MAX_CNT 3 +- + #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ + #define WPA_OUI_TYPE 1 + #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ +@@ -5639,53 +5637,6 @@ static int brcmf_setup_wiphybands(struct + return 0; + } + +-static const struct ieee80211_iface_limit brcmf_iface_limits_mbss[] = { +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_STATION) | +- BIT(NL80211_IFTYPE_ADHOC) +- }, +- { +- .max = 4, +- .types = BIT(NL80211_IFTYPE_AP) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) +- } +-}; +- +-static const struct ieee80211_iface_limit brcmf_iface_limits_sbss[] = { +- { +- .max = 2, +- .types = BIT(NL80211_IFTYPE_STATION) | +- BIT(NL80211_IFTYPE_ADHOC) | +- BIT(NL80211_IFTYPE_AP) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) +- } +-}; +-static struct ieee80211_iface_combination brcmf_iface_combos[] = { +- { +- .max_interfaces = BRCMF_IFACE_MAX_CNT, +- .num_different_channels = 1, +- .n_limits = ARRAY_SIZE(brcmf_iface_limits_sbss), +- .limits = brcmf_iface_limits_sbss, +- } +-}; +- + static const struct ieee80211_txrx_stypes + brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { +@@ -5715,6 +5666,67 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = + } + }; + ++static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) ++{ ++ struct ieee80211_iface_combination *combo = NULL; ++ struct ieee80211_iface_limit *limits = NULL; ++ int i = 0, max_iface_cnt; ++ ++ combo = kzalloc(sizeof(*combo), GFP_KERNEL); ++ if (!combo) ++ goto err; ++ ++ limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL); ++ if (!limits) ++ goto err; ++ ++ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | ++ BIT(NL80211_IFTYPE_ADHOC) | ++ BIT(NL80211_IFTYPE_AP); ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) ++ combo->num_different_channels = 2; ++ else ++ combo->num_different_channels = 1; ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { ++ limits[i].max = 1; ++ limits[i++].types = BIT(NL80211_IFTYPE_STATION); ++ limits[i].max = 4; ++ limits[i++].types = BIT(NL80211_IFTYPE_AP); ++ max_iface_cnt = 5; ++ } else { ++ limits[i].max = 2; ++ limits[i++].types = BIT(NL80211_IFTYPE_STATION) | ++ BIT(NL80211_IFTYPE_AP); ++ max_iface_cnt = 2; ++ } ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) { ++ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO) | ++ BIT(NL80211_IFTYPE_P2P_DEVICE); ++ limits[i].max = 1; ++ limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO); ++ limits[i].max = 1; ++ limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); ++ max_iface_cnt += 2; ++ } ++ combo->max_interfaces = max_iface_cnt; ++ combo->limits = limits; ++ combo->n_limits = i; ++ ++ wiphy->iface_combinations = combo; ++ wiphy->n_iface_combinations = 1; ++ return 0; ++ ++err: ++ kfree(limits); ++ kfree(combo); ++ return -ENOMEM; ++} ++ + static void brcmf_wiphy_pno_params(struct wiphy *wiphy) + { + /* scheduled scan settings */ +@@ -5745,7 +5757,6 @@ static void brcmf_wiphy_wowl_params(stru + static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + { + struct ieee80211_supported_band *band; +- struct ieee80211_iface_combination ifc_combo; + __le32 bandlist[3]; + u32 n_bands; + int err, i; +@@ -5753,24 +5764,11 @@ static int brcmf_setup_wiphy(struct wiph + wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; + wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; + wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; +- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | +- BIT(NL80211_IFTYPE_ADHOC) | +- BIT(NL80211_IFTYPE_AP) | +- BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO) | +- BIT(NL80211_IFTYPE_P2P_DEVICE); +- /* need VSDB firmware feature for concurrent channels */ +- ifc_combo = brcmf_iface_combos[0]; +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) +- ifc_combo.num_different_channels = 2; +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { +- ifc_combo.n_limits = ARRAY_SIZE(brcmf_iface_limits_mbss), +- ifc_combo.limits = brcmf_iface_limits_mbss; +- } +- wiphy->iface_combinations = kmemdup(&ifc_combo, +- sizeof(ifc_combo), +- GFP_KERNEL); +- wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); ++ ++ err = brcmf_setup_ifmodes(wiphy, ifp); ++ if (err) ++ return err; ++ + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + wiphy->cipher_suites = __wl_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); +@@ -6035,6 +6033,8 @@ static void brcmf_free_wiphy(struct wiph + if (!wiphy) + return; + ++ if (wiphy->iface_combinations) ++ kfree(wiphy->iface_combinations->limits); + kfree(wiphy->iface_combinations); + if (wiphy->bands[IEEE80211_BAND_2GHZ]) { + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/359-0003-brcmfmac-rework-.get_station-callback.patch b/package/kernel/mac80211/patches/359-0003-brcmfmac-rework-.get_station-callback.patch new file mode 100644 index 0000000000..7bd06869da --- /dev/null +++ b/package/kernel/mac80211/patches/359-0003-brcmfmac-rework-.get_station-callback.patch @@ -0,0 +1,326 @@ +From: Arend van Spriel +Date: Thu, 11 Jun 2015 00:12:19 +0200 +Subject: [PATCH] brcmfmac: rework .get_station() callback + +The .get_station() cfg80211 callback is used in several scenarios. In +managed mode it can obtain information about the access-point and its +BSS parameters. In managed mode it can also obtain information about +TDLS peers. In AP mode it can obtain information about connected +clients. + +Reviewed-by: Hante Meuleman +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -2395,27 +2395,80 @@ brcmf_cfg80211_reconfigure_wep(struct br + brcmf_err("set wsec error (%d)\n", err); + } + ++static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si) ++{ ++ struct nl80211_sta_flag_update *sfu; ++ ++ brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags); ++ si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS); ++ sfu = &si->sta_flags; ++ sfu->mask = BIT(NL80211_STA_FLAG_WME) | ++ BIT(NL80211_STA_FLAG_AUTHENTICATED) | ++ BIT(NL80211_STA_FLAG_ASSOCIATED) | ++ BIT(NL80211_STA_FLAG_AUTHORIZED); ++ if (fw_sta_flags & BRCMF_STA_WME) ++ sfu->set |= BIT(NL80211_STA_FLAG_WME); ++ if (fw_sta_flags & BRCMF_STA_AUTHE) ++ sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); ++ if (fw_sta_flags & BRCMF_STA_ASSOC) ++ sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED); ++ if (fw_sta_flags & BRCMF_STA_AUTHO) ++ sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED); ++} ++ ++static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si) ++{ ++ struct { ++ __le32 len; ++ struct brcmf_bss_info_le bss_le; ++ } *buf; ++ u16 capability; ++ int err; ++ ++ buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); ++ if (!buf) ++ return; ++ ++ buf->len = cpu_to_le32(WL_BSS_INFO_MAX); ++ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf, ++ WL_BSS_INFO_MAX); ++ if (err) { ++ brcmf_err("Failed to get bss info (%d)\n", err); ++ return; ++ } ++ si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); ++ si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period); ++ si->bss_param.dtim_period = buf->bss_le.dtim_period; ++ capability = le16_to_cpu(buf->bss_le.capability); ++ if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT) ++ si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; ++ if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE) ++ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; ++ if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) ++ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; ++} ++ + static s32 + brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, + const u8 *mac, struct station_info *sinfo) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; +- struct brcmf_scb_val_le scb_val; +- int rssi; +- s32 rate; + s32 err = 0; +- u8 *bssid = profile->bssid; + struct brcmf_sta_info_le sta_info_le; +- u32 beacon_period; +- u32 dtim_period; ++ u32 sta_flags; ++ u32 is_tdls_peer; + + brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac); + if (!check_vif_up(ifp->vif)) + return -EIO; + +- if (brcmf_is_apmode(ifp->vif)) { +- memcpy(&sta_info_le, mac, ETH_ALEN); ++ memset(&sta_info_le, 0, sizeof(sta_info_le)); ++ memcpy(&sta_info_le, mac, ETH_ALEN); ++ err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info", ++ &sta_info_le, ++ sizeof(sta_info_le)); ++ is_tdls_peer = !err; ++ if (err) { + err = brcmf_fil_iovar_data_get(ifp, "sta_info", + &sta_info_le, + sizeof(sta_info_le)); +@@ -2423,73 +2476,48 @@ brcmf_cfg80211_get_station(struct wiphy + brcmf_err("GET STA INFO failed, %d\n", err); + goto done; + } +- sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); +- sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; +- if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { +- sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); +- sinfo->connected_time = le32_to_cpu(sta_info_le.in); +- } +- brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", +- sinfo->inactive_time, sinfo->connected_time); +- } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) { +- if (memcmp(mac, bssid, ETH_ALEN)) { +- brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", +- mac, bssid); +- err = -ENOENT; +- goto done; +- } +- /* Report the current tx rate */ +- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); +- if (err) { +- brcmf_err("Could not get rate (%d)\n", err); +- goto done; +- } else { ++ } ++ brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver)); ++ sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); ++ sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; ++ sta_flags = le32_to_cpu(sta_info_le.flags); ++ brcmf_convert_sta_flags(sta_flags, sinfo); ++ sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER); ++ if (is_tdls_peer) ++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); ++ else ++ sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); ++ if (sta_flags & BRCMF_STA_ASSOC) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); ++ sinfo->connected_time = le32_to_cpu(sta_info_le.in); ++ brcmf_fill_bss_param(ifp, sinfo); ++ } ++ if (sta_flags & BRCMF_STA_SCBSTATS) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); ++ sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures); ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); ++ sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts); ++ sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts); ++ sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); ++ sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts); ++ sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts); ++ if (sinfo->tx_packets) { + sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); +- sinfo->txrate.legacy = rate * 5; +- brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); ++ sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate); ++ sinfo->txrate.legacy /= 100; + } +- +- if (test_bit(BRCMF_VIF_STATUS_CONNECTED, +- &ifp->vif->sme_state)) { +- memset(&scb_val, 0, sizeof(scb_val)); +- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, +- &scb_val, sizeof(scb_val)); +- if (err) { +- brcmf_err("Could not get rssi (%d)\n", err); +- goto done; +- } else { +- rssi = le32_to_cpu(scb_val.val); +- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); +- sinfo->signal = rssi; +- brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); +- } +- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD, +- &beacon_period); +- if (err) { +- brcmf_err("Could not get beacon period (%d)\n", +- err); +- goto done; +- } else { +- sinfo->bss_param.beacon_interval = +- beacon_period; +- brcmf_dbg(CONN, "Beacon peroid %d\n", +- beacon_period); +- } +- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD, +- &dtim_period); +- if (err) { +- brcmf_err("Could not get DTIM period (%d)\n", +- err); +- goto done; +- } else { +- sinfo->bss_param.dtim_period = dtim_period; +- brcmf_dbg(CONN, "DTIM peroid %d\n", +- dtim_period); +- } +- sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); ++ if (sinfo->rx_packets) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); ++ sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate); ++ sinfo->rxrate.legacy /= 100; ++ } ++ if (le16_to_cpu(sta_info_le.ver) >= 4) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES); ++ sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes); ++ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES); ++ sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes); + } +- } else +- err = -EPERM; ++ } + done: + brcmf_dbg(TRACE, "Exit\n"); + return err; +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h +@@ -32,7 +32,11 @@ + #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ + #define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 + +-#define BRCMF_STA_ASSOC 0x10 /* Associated */ ++#define BRCMF_STA_WME 0x00000002 /* WMM association */ ++#define BRCMF_STA_AUTHE 0x00000008 /* Authenticated */ ++#define BRCMF_STA_ASSOC 0x00000010 /* Associated */ ++#define BRCMF_STA_AUTHO 0x00000020 /* Authorized */ ++#define BRCMF_STA_SCBSTATS 0x00004000 /* Per STA debug stats */ + + /* size of brcmf_scan_params not including variable length array */ + #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 +@@ -113,6 +117,7 @@ + #define BRCMF_WOWL_MAXPATTERNSIZE 128 + + #define BRCMF_COUNTRY_BUF_SZ 4 ++#define BRCMF_ANT_MAX 4 + + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { +@@ -456,25 +461,61 @@ struct brcmf_channel_info_le { + }; + + struct brcmf_sta_info_le { +- __le16 ver; /* version of this struct */ +- __le16 len; /* length in bytes of this structure */ +- __le16 cap; /* sta's advertised capabilities */ +- __le32 flags; /* flags defined below */ +- __le32 idle; /* time since data pkt rx'd from sta */ +- u8 ea[ETH_ALEN]; /* Station address */ +- __le32 count; /* # rates in this set */ +- u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ ++ __le16 ver; /* version of this struct */ ++ __le16 len; /* length in bytes of this structure */ ++ __le16 cap; /* sta's advertised capabilities */ ++ __le32 flags; /* flags defined below */ ++ __le32 idle; /* time since data pkt rx'd from sta */ ++ u8 ea[ETH_ALEN]; /* Station address */ ++ __le32 count; /* # rates in this set */ ++ u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ + /* w/hi bit set if basic */ +- __le32 in; /* seconds elapsed since associated */ +- __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ +- __le32 tx_pkts; /* # of packets transmitted */ +- __le32 tx_failures; /* # of packets failed */ +- __le32 rx_ucast_pkts; /* # of unicast packets received */ +- __le32 rx_mcast_pkts; /* # of multicast packets received */ +- __le32 tx_rate; /* Rate of last successful tx frame */ +- __le32 rx_rate; /* Rate of last successful rx frame */ +- __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ +- __le32 rx_decrypt_failures; /* # of packet decrypted failed */ ++ __le32 in; /* seconds elapsed since associated */ ++ __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ ++ __le32 tx_pkts; /* # of packets transmitted */ ++ __le32 tx_failures; /* # of packets failed */ ++ __le32 rx_ucast_pkts; /* # of unicast packets received */ ++ __le32 rx_mcast_pkts; /* # of multicast packets received */ ++ __le32 tx_rate; /* Rate of last successful tx frame */ ++ __le32 rx_rate; /* Rate of last successful rx frame */ ++ __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ ++ __le32 rx_decrypt_failures; /* # of packet decrypted failed */ ++ __le32 tx_tot_pkts; /* # of tx pkts (ucast + mcast) */ ++ __le32 rx_tot_pkts; /* # of data packets recvd (uni + mcast) */ ++ __le32 tx_mcast_pkts; /* # of mcast pkts txed */ ++ __le64 tx_tot_bytes; /* data bytes txed (ucast + mcast) */ ++ __le64 rx_tot_bytes; /* data bytes recvd (ucast + mcast) */ ++ __le64 tx_ucast_bytes; /* data bytes txed (ucast) */ ++ __le64 tx_mcast_bytes; /* # data bytes txed (mcast) */ ++ __le64 rx_ucast_bytes; /* data bytes recvd (ucast) */ ++ __le64 rx_mcast_bytes; /* data bytes recvd (mcast) */ ++ s8 rssi[BRCMF_ANT_MAX]; /* per antenna rssi */ ++ s8 nf[BRCMF_ANT_MAX]; /* per antenna noise floor */ ++ __le16 aid; /* association ID */ ++ __le16 ht_capabilities; /* advertised ht caps */ ++ __le16 vht_flags; /* converted vht flags */ ++ __le32 tx_pkts_retry_cnt; /* # of frames where a retry was ++ * exhausted. ++ */ ++ __le32 tx_pkts_retry_exhausted; /* # of user frames where a retry ++ * was exhausted ++ */ ++ s8 rx_lastpkt_rssi[BRCMF_ANT_MAX]; /* Per antenna RSSI of last ++ * received data frame. ++ */ ++ /* TX WLAN retry/failure statistics: ++ * Separated for host requested frames and locally generated frames. ++ * Include unicast frame only where the retries/failures can be counted. ++ */ ++ __le32 tx_pkts_total; /* # user frames sent successfully */ ++ __le32 tx_pkts_retries; /* # user frames retries */ ++ __le32 tx_pkts_fw_total; /* # FW generated sent successfully */ ++ __le32 tx_pkts_fw_retries; /* # retries for FW generated frames */ ++ __le32 tx_pkts_fw_retry_exhausted; /* # FW generated where a retry ++ * was exhausted ++ */ ++ __le32 rx_pkts_retried; /* # rx with retry bit set */ ++ __le32 tx_rate_fallback; /* lowest fallback TX rate */ + }; + + struct brcmf_chanspec_list { diff --git a/package/kernel/mac80211/patches/359-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch b/package/kernel/mac80211/patches/359-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch new file mode 100644 index 0000000000..302bc3ed15 --- /dev/null +++ b/package/kernel/mac80211/patches/359-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch @@ -0,0 +1,56 @@ +From: Arend van Spriel +Date: Thu, 11 Jun 2015 00:12:20 +0200 +Subject: [PATCH] brcmfmac: have sdio return -EIO when device communication + is not possible + +The bus interface functions txctl and rxctl may be used while the device +can not be accessed, eg. upon driver .remove() callback. This patch will +immediately return -EIO when this is the case which speeds up the module +unload. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -988,6 +988,7 @@ static void brcmf_sdiod_freezer_detach(s + + static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) + { ++ sdiodev->state = BRCMF_SDIOD_DOWN; + if (sdiodev->bus) { + brcmf_sdio_remove(sdiodev->bus); + sdiodev->bus = NULL; +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -2820,6 +2820,8 @@ static int brcmf_sdio_bus_txdata(struct + struct brcmf_sdio *bus = sdiodev->bus; + + brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len); ++ if (sdiodev->state != BRCMF_SDIOD_DATA) ++ return -EIO; + + /* Add space for the header */ + skb_push(pkt, bus->tx_hdrlen); +@@ -2948,6 +2950,8 @@ brcmf_sdio_bus_txctl(struct device *dev, + int ret; + + brcmf_dbg(TRACE, "Enter\n"); ++ if (sdiodev->state != BRCMF_SDIOD_DATA) ++ return -EIO; + + /* Send from dpc */ + bus->ctrl_frame_buf = msg; +@@ -3238,6 +3242,8 @@ brcmf_sdio_bus_rxctl(struct device *dev, + struct brcmf_sdio *bus = sdiodev->bus; + + brcmf_dbg(TRACE, "Enter\n"); ++ if (sdiodev->state != BRCMF_SDIOD_DATA) ++ return -EIO; + + /* Wait until control frame is available */ + timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending); diff --git a/package/kernel/mac80211/patches/359-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch b/package/kernel/mac80211/patches/359-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch new file mode 100644 index 0000000000..34af6d2acf --- /dev/null +++ b/package/kernel/mac80211/patches/359-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch @@ -0,0 +1,74 @@ +From: Felix Fietkau +Date: Thu, 2 Jul 2015 13:35:05 +0200 +Subject: [PATCH] ath9k: make DMA stop related messages debug-only + +A long time ago, ath9k had issues during reset where the DMA engine +would stay active and could potentially corrupt memory. +To debug those issues, the driver would print warnings whenever they +occur. + +Nowadays, these issues are gone and the primary cause of these messages +is if the MAC is stuck during reset or busy processing a long +transmission. This is fairly harmless, yet these messages continue to +worry users. + +To reduce the number of bogus bug reports, turn these messages into +debug messages and count their occurence in the "reset" debugfs file. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -765,6 +765,8 @@ static int read_file_reset(struct seq_fi + [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", + [RESET_TYPE_MCI] = "MCI Reset", + [RESET_TYPE_CALIBRATION] = "Calibration error", ++ [RESET_TX_DMA_ERROR] = "Tx DMA stop error", ++ [RESET_RX_DMA_ERROR] = "Rx DMA stop error", + }; + int i; + +--- a/drivers/net/wireless/ath/ath9k/debug.h ++++ b/drivers/net/wireless/ath/ath9k/debug.h +@@ -50,6 +50,8 @@ enum ath_reset_type { + RESET_TYPE_BEACON_STUCK, + RESET_TYPE_MCI, + RESET_TYPE_CALIBRATION, ++ RESET_TX_DMA_ERROR, ++ RESET_RX_DMA_ERROR, + __RESET_TYPE_MAX + }; + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -496,10 +496,9 @@ bool ath_stoprecv(struct ath_softc *sc) + + if (!(ah->ah_flags & AH_UNPLUGGED) && + unlikely(!stopped)) { +- ath_err(ath9k_hw_common(sc->sc_ah), +- "Could not stop RX, we could be " +- "confusing the DMA engine when we start RX up\n"); +- ATH_DBG_WARN_ON_ONCE(!stopped); ++ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, ++ "Failed to stop Rx DMA\n"); ++ RESET_STAT_INC(sc, RESET_RX_DMA_ERROR); + } + return stopped && !reset; + } +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1896,8 +1896,11 @@ bool ath_drain_all_txq(struct ath_softc + npend |= BIT(i); + } + +- if (npend) +- ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend); ++ if (npend) { ++ RESET_STAT_INC(sc, RESET_TX_DMA_ERROR); ++ ath_dbg(common, RESET, ++ "Failed to stop TX DMA, queues=0x%03x!\n", npend); ++ } + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) diff --git a/package/kernel/mac80211/patches/359-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch b/package/kernel/mac80211/patches/359-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch new file mode 100644 index 0000000000..06f2dce83f --- /dev/null +++ b/package/kernel/mac80211/patches/359-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch @@ -0,0 +1,44 @@ +From: Arend van Spriel +Date: Thu, 11 Jun 2015 00:12:21 +0200 +Subject: [PATCH] brcmfmac: free ifp for non-netdev interface in p2p module + +Making it more clear by freeing the ifp in same place where the +vif object is freed. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -867,8 +867,6 @@ static void brcmf_del_if(struct brcmf_pu + } + /* unregister will take care of freeing it */ + unregister_netdev(ifp->ndev); +- } else { +- kfree(ifp); + } + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +@@ -2238,6 +2238,7 @@ static void brcmf_p2p_delete_p2pdev(stru + { + cfg80211_unregister_wdev(&vif->wdev); + p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; ++ kfree(vif->ifp); + brcmf_free_vif(vif); + } + +@@ -2361,6 +2362,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph + break; + + case NL80211_IFTYPE_P2P_DEVICE: ++ brcmf_p2p_cancel_remain_on_channel(vif->ifp); ++ brcmf_p2p_deinit_discovery(p2p); + brcmf_p2p_delete_p2pdev(p2p, vif); + return 0; + default: diff --git a/package/kernel/mac80211/patches/359-0007-brcmfmac-move-p2p-attach-detach-functions.patch b/package/kernel/mac80211/patches/359-0007-brcmfmac-move-p2p-attach-detach-functions.patch new file mode 100644 index 0000000000..0a6e093512 --- /dev/null +++ b/package/kernel/mac80211/patches/359-0007-brcmfmac-move-p2p-attach-detach-functions.patch @@ -0,0 +1,225 @@ +From: Arend van Spriel +Date: Thu, 11 Jun 2015 00:12:22 +0200 +Subject: [PATCH] brcmfmac: move p2p attach/detach functions + +Moving two functions in p2p.c as is so next change will be +easier to review. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +@@ -1908,105 +1908,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere + + + /** +- * brcmf_p2p_attach() - attach for P2P. +- * +- * @cfg: driver private data for cfg80211 interface. +- */ +-s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg) +-{ +- struct brcmf_if *pri_ifp; +- struct brcmf_if *p2p_ifp; +- struct brcmf_cfg80211_vif *p2p_vif; +- struct brcmf_p2p_info *p2p; +- struct brcmf_pub *drvr; +- s32 bssidx; +- s32 err = 0; +- +- p2p = &cfg->p2p; +- p2p->cfg = cfg; +- +- drvr = cfg->pub; +- +- pri_ifp = drvr->iflist[0]; +- p2p_ifp = drvr->iflist[1]; +- +- p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif; +- +- if (p2p_ifp) { +- p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE, +- false); +- if (IS_ERR(p2p_vif)) { +- brcmf_err("could not create discovery vif\n"); +- err = -ENOMEM; +- goto exit; +- } +- +- p2p_vif->ifp = p2p_ifp; +- p2p_ifp->vif = p2p_vif; +- p2p_vif->wdev.netdev = p2p_ifp->ndev; +- p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev; +- SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy)); +- +- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif; +- +- brcmf_p2p_generate_bss_mac(p2p, NULL); +- memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN); +- brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); +- +- /* Initialize P2P Discovery in the firmware */ +- err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); +- if (err < 0) { +- brcmf_err("set p2p_disc error\n"); +- brcmf_free_vif(p2p_vif); +- goto exit; +- } +- /* obtain bsscfg index for P2P discovery */ +- err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); +- if (err < 0) { +- brcmf_err("retrieving discover bsscfg index failed\n"); +- brcmf_free_vif(p2p_vif); +- goto exit; +- } +- /* Verify that firmware uses same bssidx as driver !! */ +- if (p2p_ifp->bssidx != bssidx) { +- brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", +- bssidx, p2p_ifp->bssidx); +- brcmf_free_vif(p2p_vif); +- goto exit; +- } +- +- init_completion(&p2p->send_af_done); +- INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler); +- init_completion(&p2p->afx_hdl.act_frm_scan); +- init_completion(&p2p->wait_next_af); +- } +-exit: +- return err; +-} +- +- +-/** +- * brcmf_p2p_detach() - detach P2P. +- * +- * @p2p: P2P specific data. +- */ +-void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) +-{ +- struct brcmf_cfg80211_vif *vif; +- +- vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; +- if (vif != NULL) { +- brcmf_p2p_cancel_remain_on_channel(vif->ifp); +- brcmf_p2p_deinit_discovery(p2p); +- /* remove discovery interface */ +- brcmf_free_vif(vif); +- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; +- } +- /* just set it all to zero */ +- memset(p2p, 0, sizeof(*p2p)); +-} +- +-/** + * brcmf_p2p_get_current_chanspec() - Get current operation channel. + * + * @p2p: P2P specific data. +@@ -2425,3 +2326,102 @@ void brcmf_p2p_stop_device(struct wiphy + clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state); + mutex_unlock(&cfg->usr_sync); + } ++ ++/** ++ * brcmf_p2p_attach() - attach for P2P. ++ * ++ * @cfg: driver private data for cfg80211 interface. ++ */ ++s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg) ++{ ++ struct brcmf_if *pri_ifp; ++ struct brcmf_if *p2p_ifp; ++ struct brcmf_cfg80211_vif *p2p_vif; ++ struct brcmf_p2p_info *p2p; ++ struct brcmf_pub *drvr; ++ s32 bssidx; ++ s32 err = 0; ++ ++ p2p = &cfg->p2p; ++ p2p->cfg = cfg; ++ ++ drvr = cfg->pub; ++ ++ pri_ifp = drvr->iflist[0]; ++ p2p_ifp = drvr->iflist[1]; ++ ++ p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif; ++ ++ if (p2p_ifp) { ++ p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE, ++ false); ++ if (IS_ERR(p2p_vif)) { ++ brcmf_err("could not create discovery vif\n"); ++ err = -ENOMEM; ++ goto exit; ++ } ++ ++ p2p_vif->ifp = p2p_ifp; ++ p2p_ifp->vif = p2p_vif; ++ p2p_vif->wdev.netdev = p2p_ifp->ndev; ++ p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev; ++ SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy)); ++ ++ p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif; ++ ++ brcmf_p2p_generate_bss_mac(p2p, NULL); ++ memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN); ++ brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); ++ ++ /* Initialize P2P Discovery in the firmware */ ++ err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); ++ if (err < 0) { ++ brcmf_err("set p2p_disc error\n"); ++ brcmf_free_vif(p2p_vif); ++ goto exit; ++ } ++ /* obtain bsscfg index for P2P discovery */ ++ err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); ++ if (err < 0) { ++ brcmf_err("retrieving discover bsscfg index failed\n"); ++ brcmf_free_vif(p2p_vif); ++ goto exit; ++ } ++ /* Verify that firmware uses same bssidx as driver !! */ ++ if (p2p_ifp->bssidx != bssidx) { ++ brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", ++ bssidx, p2p_ifp->bssidx); ++ brcmf_free_vif(p2p_vif); ++ goto exit; ++ } ++ ++ init_completion(&p2p->send_af_done); ++ INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler); ++ init_completion(&p2p->afx_hdl.act_frm_scan); ++ init_completion(&p2p->wait_next_af); ++ } ++exit: ++ return err; ++} ++ ++/** ++ * brcmf_p2p_detach() - detach P2P. ++ * ++ * @p2p: P2P specific data. ++ */ ++void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) ++{ ++ struct brcmf_cfg80211_vif *vif; ++ ++ vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; ++ if (vif != NULL) { ++ brcmf_p2p_cancel_remain_on_channel(vif->ifp); ++ brcmf_p2p_deinit_discovery(p2p); ++ /* remove discovery interface */ ++ brcmf_free_vif(vif); ++ p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; ++ } ++ /* just set it all to zero */ ++ memset(p2p, 0, sizeof(*p2p)); ++} ++ diff --git a/package/kernel/mac80211/patches/359-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch b/package/kernel/mac80211/patches/359-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch new file mode 100644 index 0000000000..72e8eed61b --- /dev/null +++ b/package/kernel/mac80211/patches/359-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch @@ -0,0 +1,63 @@ +From: Arend van Spriel +Date: Thu, 11 Jun 2015 00:12:23 +0200 +Subject: [PATCH] brcmfmac: assure p2pdev is unregistered upon driver + unload + +When unloading the driver with a p2pdev interface it resulted in +a warning upon calling wiphy_unregister() and subsequently a crash +in the driver. This patch assures the p2pdev is unregistered calling +unregister_wdev() before doing the wiphy_unregister(). + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -6206,10 +6206,8 @@ void brcmf_cfg80211_detach(struct brcmf_ + if (!cfg) + return; + +- WARN_ON(!list_empty(&cfg->vif_list)); +- wiphy_unregister(cfg->wiphy); + brcmf_btcoex_detach(cfg); +- brcmf_p2p_detach(&cfg->p2p); ++ wiphy_unregister(cfg->wiphy); + wl_deinit_priv(cfg); + brcmf_free_wiphy(cfg->wiphy); + } +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -1098,6 +1098,7 @@ void brcmf_detach(struct device *dev) + + /* stop firmware event handling */ + brcmf_fweh_detach(drvr); ++ brcmf_p2p_detach(&drvr->config->p2p); + + brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); + +--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -2418,8 +2419,9 @@ void brcmf_p2p_detach(struct brcmf_p2p_i + brcmf_p2p_cancel_remain_on_channel(vif->ifp); + brcmf_p2p_deinit_discovery(p2p); + /* remove discovery interface */ +- brcmf_free_vif(vif); +- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; ++ rtnl_lock(); ++ brcmf_p2p_delete_p2pdev(p2p, vif); ++ rtnl_unlock(); + } + /* just set it all to zero */ + memset(p2p, 0, sizeof(*p2p)); diff --git a/package/kernel/mac80211/patches/360-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch b/package/kernel/mac80211/patches/360-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch new file mode 100644 index 0000000000..179c77e9df --- /dev/null +++ b/package/kernel/mac80211/patches/360-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch @@ -0,0 +1,27 @@ +From: Arend van Spriel +Date: Mon, 15 Jun 2015 22:48:38 +0200 +Subject: [PATCH] brcmfmac: fix double free of p2pdev interface + +When freeing the driver ifp pointer it should also be removed from +the driver interface list, which is what brcmf_remove_interface() +does. Otherwise, the ifp pointer will be freed twice triggering +a kernel oops. + +Fixes: f37d69a4babc ("brcmfmac: free ifp for non-netdev interface in p2p module") +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru + { + cfg80211_unregister_wdev(&vif->wdev); + p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; +- kfree(vif->ifp); ++ brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx); + brcmf_free_vif(vif); + } + diff --git a/package/kernel/mac80211/patches/360-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch b/package/kernel/mac80211/patches/360-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch new file mode 100644 index 0000000000..e4f88b5022 --- /dev/null +++ b/package/kernel/mac80211/patches/360-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch @@ -0,0 +1,29 @@ +From: Arend van Spriel +Date: Mon, 15 Jun 2015 22:48:39 +0200 +Subject: [PATCH] brcmfmac: make brcmf_p2p_detach() call conditional + +During verification of error handling in brcmf_cfg80211_attach() a +null pointer dereference occurred upon calling brcmf_p2p_detach() +from brcmf_detach(). This should only be called when the +brcmf_cfg80211_attach() has succeeded. + +Fixes: f7a40873d2fa ("brcmfmac: assure p2pdev is unregistered upon driver unload") +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -1098,7 +1098,8 @@ void brcmf_detach(struct device *dev) + + /* stop firmware event handling */ + brcmf_fweh_detach(drvr); +- brcmf_p2p_detach(&drvr->config->p2p); ++ if (drvr->config) ++ brcmf_p2p_detach(&drvr->config->p2p); + + brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); + diff --git a/package/kernel/mac80211/patches/361-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch b/package/kernel/mac80211/patches/361-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch new file mode 100644 index 0000000000..0a81237a28 --- /dev/null +++ b/package/kernel/mac80211/patches/361-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch @@ -0,0 +1,67 @@ +From: Rafa? Mi?ecki +Date: Thu, 9 Jul 2015 17:07:08 +0200 +Subject: [PATCH] brcmfmac: set wiphy's addresses to provide valid MACs + +Broadcom's firmware requires every BSS to use MAC address with unique +last few bits. The amount of bits may depend on a particular firmware, +it was verified to be 2 for BCM43602 one. +If this condition won't be fulfilled firmware will reject such MAC: +brcmfmac: _brcmf_set_mac_address: Setting cur_etheraddr failed, -52 + +We don't want to simply set addr_mask as it would also disallow using +locally administrated bit. Instead let's build a list of addresses +manually enabling 0x2 bit for extra interfaces. + +Signed-off-by: Rafa? Mi?ecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -5784,6 +5784,7 @@ static void brcmf_wiphy_wowl_params(stru + + static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct ieee80211_supported_band *band; + __le32 bandlist[3]; + u32 n_bands; +@@ -5797,6 +5798,19 @@ static int brcmf_setup_wiphy(struct wiph + if (err) + return err; + ++ for (i = 0; i < wiphy->iface_combinations->max_interfaces && ++ i < ARRAY_SIZE(drvr->addresses); i++) { ++ u8 *addr = drvr->addresses[i].addr; ++ ++ memcpy(addr, drvr->mac, ETH_ALEN); ++ if (i) { ++ addr[0] |= BIT(1); ++ addr[ETH_ALEN - 1] ^= i; ++ } ++ } ++ wiphy->addresses = drvr->addresses; ++ wiphy->n_addresses = i; ++ + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + wiphy->cipher_suites = __wl_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h +@@ -21,6 +21,7 @@ + #ifndef BRCMFMAC_CORE_H + #define BRCMFMAC_CORE_H + ++#include + #include "fweh.h" + + #define TOE_TX_CSUM_OL 0x00000001 +@@ -118,6 +119,8 @@ struct brcmf_pub { + /* Multicast data packets sent to dongle */ + unsigned long tx_multicast; + ++ struct mac_address addresses[BRCMF_MAX_IFS]; ++ + struct brcmf_if *iflist[BRCMF_MAX_IFS]; + + struct mutex proto_block; diff --git a/package/kernel/mac80211/patches/362-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch b/package/kernel/mac80211/patches/362-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch new file mode 100644 index 0000000000..e44f121ea3 --- /dev/null +++ b/package/kernel/mac80211/patches/362-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch @@ -0,0 +1,45 @@ +From: Vineet Gupta +Date: Thu, 9 Jul 2015 13:43:18 +0530 +Subject: [PATCH] brcmfmac: dhd_sdio.c: use existing atomic_or primitive + +There's already a generic implementation so use that instead. + +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -2564,15 +2564,6 @@ static inline void brcmf_sdio_clrintr(st + } + } + +-static void atomic_orr(int val, atomic_t *v) +-{ +- int old_val; +- +- old_val = atomic_read(v); +- while (atomic_cmpxchg(v, old_val, val | old_val) != old_val) +- old_val = atomic_read(v); +-} +- + static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) + { + struct brcmf_core *buscore; +@@ -2595,7 +2586,7 @@ static int brcmf_sdio_intr_rstatus(struc + if (val) { + brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); + bus->sdcnt.f1regdata++; +- atomic_orr(val, &bus->intstatus); ++ atomic_or(val, &bus->intstatus); + } + + return ret; +@@ -2712,7 +2703,7 @@ static void brcmf_sdio_dpc(struct brcmf_ + + /* Keep still-pending events for next scheduling */ + if (intstatus) +- atomic_orr(intstatus, &bus->intstatus); ++ atomic_or(intstatus, &bus->intstatus); + + brcmf_sdio_clrintr(bus); + diff --git a/package/kernel/mac80211/patches/363-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch b/package/kernel/mac80211/patches/363-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch new file mode 100644 index 0000000000..76ca143df5 --- /dev/null +++ b/package/kernel/mac80211/patches/363-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch @@ -0,0 +1,46 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 20 Aug 2015 00:16:42 +0200 +Subject: [PATCH] brcmfmac: check all combinations when setting wiphy's + addresses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Broadcom is working on better reflection of interface combinations. With +upcoming patches we may have 1st combination supporting less interfaces +than others. +To don't run out of addresses check all combinations to find the one +with the greatest max_interfaces value. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -5785,7 +5785,9 @@ static void brcmf_wiphy_wowl_params(stru + static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + { + struct brcmf_pub *drvr = ifp->drvr; ++ const struct ieee80211_iface_combination *combo; + struct ieee80211_supported_band *band; ++ u16 max_interfaces = 0; + __le32 bandlist[3]; + u32 n_bands; + int err, i; +@@ -5798,8 +5800,13 @@ static int brcmf_setup_wiphy(struct wiph + if (err) + return err; + +- for (i = 0; i < wiphy->iface_combinations->max_interfaces && +- i < ARRAY_SIZE(drvr->addresses); i++) { ++ for (i = 0, combo = wiphy->iface_combinations; ++ i < wiphy->n_iface_combinations; i++, combo++) { ++ max_interfaces = max(max_interfaces, combo->max_interfaces); ++ } ++ ++ for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses); ++ i++) { + u8 *addr = drvr->addresses[i].addr; + + memcpy(addr, drvr->mac, ETH_ALEN); diff --git a/package/kernel/mac80211/patches/363-0002-brcmfmac-correct-interface-combination-info.patch b/package/kernel/mac80211/patches/363-0002-brcmfmac-correct-interface-combination-info.patch new file mode 100644 index 0000000000..c4a0720b35 --- /dev/null +++ b/package/kernel/mac80211/patches/363-0002-brcmfmac-correct-interface-combination-info.patch @@ -0,0 +1,204 @@ +From: Arend van Spriel +Date: Thu, 20 Aug 2015 22:06:03 +0200 +Subject: [PATCH] brcmfmac: correct interface combination info + +The interface combination provided by brcmfmac did not truly reflect +the combinations supported by driver and/or firmware. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Pontus Fuchs +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -5694,63 +5694,132 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = + } + }; + ++/** ++ * brcmf_setup_ifmodes() - determine interface modes and combinations. ++ * ++ * @wiphy: wiphy object. ++ * @ifp: interface object needed for feat module api. ++ * ++ * The interface modes and combinations are determined dynamically here ++ * based on firmware functionality. ++ * ++ * no p2p and no mbss: ++ * ++ * #STA <= 1, #AP <= 1, channels = 1, 2 total ++ * ++ * no p2p and mbss: ++ * ++ * #STA <= 1, #AP <= 1, channels = 1, 2 total ++ * #AP <= 4, matching BI, channels = 1, 4 total ++ * ++ * p2p, no mchan, and mbss: ++ * ++ * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total ++ * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total ++ * #AP <= 4, matching BI, channels = 1, 4 total ++ * ++ * p2p, mchan, and mbss: ++ * ++ * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total ++ * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total ++ * #AP <= 4, matching BI, channels = 1, 4 total ++ */ + static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) + { + struct ieee80211_iface_combination *combo = NULL; +- struct ieee80211_iface_limit *limits = NULL; +- int i = 0, max_iface_cnt; ++ struct ieee80211_iface_limit *c0_limits = NULL; ++ struct ieee80211_iface_limit *p2p_limits = NULL; ++ struct ieee80211_iface_limit *mbss_limits = NULL; ++ bool mbss, p2p; ++ int i, c, n_combos; + +- combo = kzalloc(sizeof(*combo), GFP_KERNEL); ++ mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS); ++ p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P); ++ ++ n_combos = 1 + !!p2p + !!mbss; ++ combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL); + if (!combo) + goto err; + +- limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL); +- if (!limits) ++ c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); ++ if (!c0_limits) + goto err; + ++ if (p2p) { ++ p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); ++ if (!p2p_limits) ++ goto err; ++ } ++ ++ if (mbss) { ++ mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); ++ if (!mbss_limits) ++ goto err; ++ } ++ + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); + +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) +- combo->num_different_channels = 2; +- else +- combo->num_different_channels = 1; +- +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { +- limits[i].max = 1; +- limits[i++].types = BIT(NL80211_IFTYPE_STATION); +- limits[i].max = 4; +- limits[i++].types = BIT(NL80211_IFTYPE_AP); +- max_iface_cnt = 5; +- } else { +- limits[i].max = 2; +- limits[i++].types = BIT(NL80211_IFTYPE_STATION) | +- BIT(NL80211_IFTYPE_AP); +- max_iface_cnt = 2; +- } +- +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) { ++ c = 0; ++ i = 0; ++ combo[c].num_different_channels = 1; ++ c0_limits[i].max = 1; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); ++ if (p2p) { ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) ++ combo[c].num_different_channels = 2; + wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_DEVICE); +- limits[i].max = 1; +- limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO); +- limits[i].max = 1; +- limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); +- max_iface_cnt += 2; +- } +- combo->max_interfaces = max_iface_cnt; +- combo->limits = limits; +- combo->n_limits = i; ++ c0_limits[i].max = 1; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); ++ c0_limits[i].max = 1; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO); ++ } else { ++ c0_limits[i].max = 1; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); ++ } ++ combo[c].max_interfaces = i; ++ combo[c].n_limits = i; ++ combo[c].limits = c0_limits; ++ ++ if (p2p) { ++ c++; ++ i = 0; ++ combo[c].num_different_channels = 1; ++ p2p_limits[i].max = 1; ++ p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); ++ p2p_limits[i].max = 1; ++ p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP); ++ p2p_limits[i].max = 1; ++ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); ++ p2p_limits[i].max = 1; ++ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); ++ combo[c].max_interfaces = i; ++ combo[c].n_limits = i; ++ combo[c].limits = p2p_limits; ++ } + ++ if (mbss) { ++ c++; ++ combo[c].beacon_int_infra_match = true; ++ combo[c].num_different_channels = 1; ++ mbss_limits[0].max = 4; ++ mbss_limits[0].types = BIT(NL80211_IFTYPE_AP); ++ combo[c].max_interfaces = 4; ++ combo[c].n_limits = 1; ++ combo[c].limits = mbss_limits; ++ } ++ wiphy->n_iface_combinations = n_combos; + wiphy->iface_combinations = combo; +- wiphy->n_iface_combinations = 1; + return 0; + + err: +- kfree(limits); ++ kfree(c0_limits); ++ kfree(p2p_limits); ++ kfree(mbss_limits); + kfree(combo); + return -ENOMEM; + } +@@ -6079,11 +6148,15 @@ static void brcmf_cfg80211_reg_notifier( + + static void brcmf_free_wiphy(struct wiphy *wiphy) + { ++ int i; ++ + if (!wiphy) + return; + +- if (wiphy->iface_combinations) +- kfree(wiphy->iface_combinations->limits); ++ if (wiphy->iface_combinations) { ++ for (i = 0; i < wiphy->n_iface_combinations; i++) ++ kfree(wiphy->iface_combinations[i].limits); ++ } + kfree(wiphy->iface_combinations); + if (wiphy->bands[IEEE80211_BAND_2GHZ]) { + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/363-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch b/package/kernel/mac80211/patches/363-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch new file mode 100644 index 0000000000..9768ef2771 --- /dev/null +++ b/package/kernel/mac80211/patches/363-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch @@ -0,0 +1,87 @@ +From: Franky Lin +Date: Thu, 20 Aug 2015 22:06:04 +0200 +Subject: [PATCH] brcmfmac: add debugfs entry for msgbuf statistics + +Expose ring buffer read/write pointers and other useful statistics +through debugfs. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -1360,6 +1360,60 @@ void brcmf_msgbuf_delete_flowring(struct + } + } + ++#ifdef DEBUG ++static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; ++ struct brcmf_commonring *commonring; ++ u16 i; ++ struct brcmf_flowring_ring *ring; ++ struct brcmf_flowring_hash *hash; ++ ++ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT]; ++ seq_printf(seq, "h2d_ctl_submit: rp %4u, wp %4u, depth %4u\n", ++ commonring->r_ptr, commonring->w_ptr, commonring->depth); ++ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT]; ++ seq_printf(seq, "h2d_rx_submit: rp %4u, wp %4u, depth %4u\n", ++ commonring->r_ptr, commonring->w_ptr, commonring->depth); ++ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE]; ++ seq_printf(seq, "d2h_ctl_cmplt: rp %4u, wp %4u, depth %4u\n", ++ commonring->r_ptr, commonring->w_ptr, commonring->depth); ++ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE]; ++ seq_printf(seq, "d2h_tx_cmplt: rp %4u, wp %4u, depth %4u\n", ++ commonring->r_ptr, commonring->w_ptr, commonring->depth); ++ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE]; ++ seq_printf(seq, "d2h_rx_cmplt: rp %4u, wp %4u, depth %4u\n", ++ commonring->r_ptr, commonring->w_ptr, commonring->depth); ++ ++ seq_printf(seq, "\nh2d_flowrings: depth %u\n", ++ BRCMF_H2D_TXFLOWRING_MAX_ITEM); ++ seq_puts(seq, "Active flowrings:\n"); ++ hash = msgbuf->flow->hash; ++ for (i = 0; i < msgbuf->flow->nrofrings; i++) { ++ if (!msgbuf->flow->rings[i]) ++ continue; ++ ring = msgbuf->flow->rings[i]; ++ if (ring->status != RING_OPEN) ++ continue; ++ commonring = msgbuf->flowrings[i]; ++ hash = &msgbuf->flow->hash[ring->hash_id]; ++ seq_printf(seq, "id %3u: rp %4u, wp %4u, qlen %4u, blocked %u\n" ++ " ifidx %u, fifo %u, da %pM\n", ++ i, commonring->r_ptr, commonring->w_ptr, ++ skb_queue_len(&ring->skblist), ring->blocked, ++ hash->ifidx, hash->fifo, hash->mac); ++ } ++ ++ return 0; ++} ++#else ++static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data) ++{ ++ return 0; ++} ++#endif + + int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) + { +@@ -1460,6 +1514,8 @@ 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: diff --git a/package/kernel/mac80211/patches/363-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch b/package/kernel/mac80211/patches/363-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch new file mode 100644 index 0000000000..2b84cf9fcd --- /dev/null +++ b/package/kernel/mac80211/patches/363-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch @@ -0,0 +1,83 @@ +From: Arend van Spriel +Date: Thu, 20 Aug 2015 22:06:05 +0200 +Subject: [PATCH] brcmfmac: make use of cfg80211_check_combinations() + +Use cfg80211_check_combinations() so we can bail out early when an +interface add or change results in an invalid combination. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -469,6 +469,36 @@ brcmf_find_wpsie(const u8 *parse, u32 le + return NULL; + } + ++static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg, ++ struct brcmf_cfg80211_vif *vif, ++ enum nl80211_iftype new_type) ++{ ++ int iftype_num[NUM_NL80211_IFTYPES]; ++ struct brcmf_cfg80211_vif *pos; ++ ++ memset(&iftype_num[0], 0, sizeof(iftype_num)); ++ list_for_each_entry(pos, &cfg->vif_list, list) ++ if (pos == vif) ++ iftype_num[new_type]++; ++ else ++ iftype_num[pos->wdev.iftype]++; ++ ++ return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num); ++} ++ ++static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg, ++ enum nl80211_iftype new_type) ++{ ++ int iftype_num[NUM_NL80211_IFTYPES]; ++ struct brcmf_cfg80211_vif *pos; ++ ++ memset(&iftype_num[0], 0, sizeof(iftype_num)); ++ list_for_each_entry(pos, &cfg->vif_list, list) ++ iftype_num[pos->wdev.iftype]++; ++ ++ iftype_num[new_type]++; ++ return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num); ++} + + static void convert_key_from_CPU(struct brcmf_wsec_key *key, + struct brcmf_wsec_key_le *key_le) +@@ -662,8 +692,14 @@ static struct wireless_dev *brcmf_cfg802 + struct vif_params *params) + { + struct wireless_dev *wdev; ++ int err; + + brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); ++ err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); ++ if (err) { ++ brcmf_err("iface validation failed: err=%d\n", err); ++ return ERR_PTR(err); ++ } + switch (type) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: +@@ -822,8 +858,12 @@ brcmf_cfg80211_change_iface(struct wiphy + s32 ap = 0; + s32 err = 0; + +- brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type); +- ++ brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type); ++ err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type); ++ if (err) { ++ brcmf_err("iface validation failed: err=%d\n", err); ++ return err; ++ } + switch (type) { + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_WDS: diff --git a/package/kernel/mac80211/patches/363-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch b/package/kernel/mac80211/patches/363-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch new file mode 100644 index 0000000000..2d5f7b9be7 --- /dev/null +++ b/package/kernel/mac80211/patches/363-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch @@ -0,0 +1,48 @@ +From: Franky Lin +Date: Thu, 20 Aug 2015 22:06:06 +0200 +Subject: [PATCH] brcmfmac: block the correct flowring when backup queue + overflow + +brcmf_flowring_block blocks the last active flowring under the same +interface instead of the one provided by caller. This could lead to a +dead lock of netif stop if there are more than one flowring under the +interface and the traffic is high enough so brcmf_flowring_enqueue can +not unblock the ring right away. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c +@@ -194,11 +194,15 @@ static void brcmf_flowring_block(struct + spin_lock_irqsave(&flow->block_lock, flags); + + ring = flow->rings[flowid]; ++ if (ring->blocked == blocked) { ++ spin_unlock_irqrestore(&flow->block_lock, flags); ++ return; ++ } + ifidx = brcmf_flowring_ifidx_get(flow, flowid); + + currently_blocked = false; + for (i = 0; i < flow->nrofrings; i++) { +- if (flow->rings[i]) { ++ if ((flow->rings[i]) && (i != flowid)) { + ring = flow->rings[i]; + if ((ring->status == RING_OPEN) && + (brcmf_flowring_ifidx_get(flow, i) == ifidx)) { +@@ -209,8 +213,8 @@ static void brcmf_flowring_block(struct + } + } + } +- ring->blocked = blocked; +- if (currently_blocked == blocked) { ++ flow->rings[flowid]->blocked = blocked; ++ if (currently_blocked) { + spin_unlock_irqrestore(&flow->block_lock, flags); + return; + } diff --git a/package/kernel/mac80211/patches/363-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch b/package/kernel/mac80211/patches/363-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch new file mode 100644 index 0000000000..7378401c52 --- /dev/null +++ b/package/kernel/mac80211/patches/363-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch @@ -0,0 +1,52 @@ +From: Arend van Spriel +Date: Thu, 20 Aug 2015 22:06:07 +0200 +Subject: [PATCH] brcmfmac: bump highest event number for 4339 firmware + +The event mask length is determined by the highest event number +that is specified in the driver. When this length is shorter than +firmware expects setting event mask will fail and device becomes +pretty useless. This issue was reported with bcm4339 firmware that +was recently released. + +Reported-by: Pontus Fuchs +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Pontus Fuchs +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h +@@ -85,7 +85,6 @@ struct brcmf_event; + BRCMF_ENUM_DEF(IF, 54) \ + BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \ + BRCMF_ENUM_DEF(RSSI, 56) \ +- BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \ + BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \ + BRCMF_ENUM_DEF(ACTION_FRAME, 59) \ + BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \ +@@ -103,8 +102,7 @@ struct brcmf_event; + BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ + BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ + BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \ +- BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ +- BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128) ++ BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) + + #define BRCMF_ENUM_DEF(id, val) \ + BRCMF_E_##id = (val), +@@ -112,7 +110,11 @@ struct brcmf_event; + /* firmware event codes sent by the dongle */ + enum brcmf_fweh_event_code { + BRCMF_FWEH_EVENT_ENUM_DEFLIST +- BRCMF_E_LAST ++ /* this determines event mask length which must match ++ * minimum length check in device firmware so it is ++ * hard-coded here. ++ */ ++ BRCMF_E_LAST = 139 + }; + #undef BRCMF_ENUM_DEF + diff --git a/package/kernel/mac80211/patches/365-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch b/package/kernel/mac80211/patches/365-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch new file mode 100644 index 0000000000..97444b3c0d --- /dev/null +++ b/package/kernel/mac80211/patches/365-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch @@ -0,0 +1,138 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:14:53 +0200 +Subject: [PATCH] brcmfmac: consolidate ifp lookup in driver core + +In rx path the firmware provide an interface index which is used to +map to a struct brcmf_if instance. However, this involves some trick +that is done in two places. This is changed by having driver core +providing brcmf_get_ifp() function. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +@@ -276,6 +276,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + struct sk_buff *pktbuf) + { + struct brcmf_proto_bcdc_header *h; ++ struct brcmf_if *ifp; + + brcmf_dbg(BCDC, "Enter\n"); + +@@ -289,30 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + trace_brcmf_bcdchdr(pktbuf->data); + h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); + +- *ifidx = BCDC_GET_IF_IDX(h); +- if (*ifidx >= BRCMF_MAX_IFS) { +- brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); ++ ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h)); ++ if (IS_ERR_OR_NULL(ifp)) { ++ brcmf_dbg(INFO, "no matching ifp found\n"); + return -EBADE; + } +- /* The ifidx is the idx to map to matching netdev/ifp. When receiving +- * events this is easy because it contains the bssidx which maps +- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. +- * bssidx 1 is used for p2p0 and no data can be received or +- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 +- */ +- if (*ifidx) +- (*ifidx)++; +- + if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != + BCDC_PROTO_VER) { + brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", +- brcmf_ifname(drvr, *ifidx), h->flags); ++ brcmf_ifname(drvr, ifp->ifidx), h->flags); + return -EBADE; + } + + if (h->flags & BCDC_FLAG_SUM_GOOD) { + brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n", +- brcmf_ifname(drvr, *ifidx), h->flags); ++ brcmf_ifname(drvr, ifp->ifidx), h->flags); + pktbuf->ip_summed = CHECKSUM_UNNECESSARY; + } + +@@ -320,12 +312,15 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + + skb_pull(pktbuf, BCDC_HEADER_LEN); + if (do_fws) +- brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); ++ brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2, ++ pktbuf); + else + skb_pull(pktbuf, h->data_offset << 2); + + if (pktbuf->len == 0) + return -ENODATA; ++ ++ *ifidx = ifp->ifidx; + return 0; + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -83,6 +83,25 @@ char *brcmf_ifname(struct brcmf_pub *drv + return ""; + } + ++struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx) ++{ ++ if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { ++ brcmf_err("ifidx %d out of range\n", ifidx); ++ return ERR_PTR(-ERANGE); ++ } ++ ++ /* The ifidx is the idx to map to matching netdev/ifp. When receiving ++ * events this is easy because it contains the bssidx which maps ++ * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. ++ * bssidx 1 is used for p2p0 and no data can be received or ++ * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 ++ */ ++ if (ifidx) ++ ifidx++; ++ ++ return drvr->iflist[ifidx]; ++} ++ + static void _brcmf_set_multicast_list(struct work_struct *work) + { + struct brcmf_if *ifp; +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h +@@ -202,7 +202,7 @@ int brcmf_netdev_wait_pend8021x(struct b + + /* Return pointer to interface name */ + char *brcmf_ifname(struct brcmf_pub *drvr, int idx); +- ++struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); + int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, + char *name, u8 *mac_addr); +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -1081,16 +1081,8 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf + { + struct brcmf_if *ifp; + +- /* The ifidx is the idx to map to matching netdev/ifp. When receiving +- * events this is easy because it contains the bssidx which maps +- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. +- * bssidx 1 is used for p2p0 and no data can be received or +- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 +- */ +- if (ifidx) +- (ifidx)++; +- ifp = msgbuf->drvr->iflist[ifidx]; +- if (!ifp || !ifp->ndev) { ++ ifp = brcmf_get_ifp(msgbuf->drvr, ifidx); ++ if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) { + brcmf_err("Received pkt for invalid ifidx %d\n", ifidx); + brcmu_pkt_buf_free_skb(skb); + return; diff --git a/package/kernel/mac80211/patches/365-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch b/package/kernel/mac80211/patches/365-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch new file mode 100644 index 0000000000..632714ce24 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch @@ -0,0 +1,222 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:14:54 +0200 +Subject: [PATCH] brcmfmac: make brcmf_proto_hdrpull() return struct + brcmf_if instance + +Avoid spreading the ifidx in the driver, but have it return the +struct brcmf_if instance. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +@@ -272,11 +272,11 @@ brcmf_proto_bcdc_hdrpush(struct brcmf_pu + } + + static int +-brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, +- struct sk_buff *pktbuf) ++brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, ++ struct sk_buff *pktbuf, struct brcmf_if **ifp) + { + struct brcmf_proto_bcdc_header *h; +- struct brcmf_if *ifp; ++ struct brcmf_if *tmp_if; + + brcmf_dbg(BCDC, "Enter\n"); + +@@ -290,21 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + trace_brcmf_bcdchdr(pktbuf->data); + h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); + +- ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h)); +- if (IS_ERR_OR_NULL(ifp)) { ++ tmp_if = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h)); ++ if (!tmp_if) { + brcmf_dbg(INFO, "no matching ifp found\n"); + return -EBADE; + } + if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != + BCDC_PROTO_VER) { + brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", +- brcmf_ifname(drvr, ifp->ifidx), h->flags); ++ brcmf_ifname(drvr, tmp_if->ifidx), h->flags); + return -EBADE; + } + + if (h->flags & BCDC_FLAG_SUM_GOOD) { + brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n", +- brcmf_ifname(drvr, ifp->ifidx), h->flags); ++ brcmf_ifname(drvr, tmp_if->ifidx), h->flags); + pktbuf->ip_summed = CHECKSUM_UNNECESSARY; + } + +@@ -312,7 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + + skb_pull(pktbuf, BCDC_HEADER_LEN); + if (do_fws) +- brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2, ++ brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2, + pktbuf); + else + skb_pull(pktbuf, h->data_offset << 2); +@@ -320,7 +320,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + if (pktbuf->len == 0) + return -ENODATA; + +- *ifidx = ifp->ifidx; ++ *ifp = tmp_if; + return 0; + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -87,7 +87,7 @@ struct brcmf_if *brcmf_get_ifp(struct br + { + if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { + brcmf_err("ifidx %d out of range\n", ifidx); +- return ERR_PTR(-ERANGE); ++ return NULL; + } + + /* The ifidx is the idx to map to matching netdev/ifp. When receiving +@@ -539,17 +539,15 @@ void brcmf_rx_frame(struct device *dev, + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; + struct brcmf_skb_reorder_data *rd; +- u8 ifidx; + int ret; + + brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); + + /* process and remove protocol-specific header */ +- ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb); +- ifp = drvr->iflist[ifidx]; ++ ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); + + if (ret || !ifp || !ifp->ndev) { +- if ((ret != -ENODATA) && ifp) ++ if (ret != -ENODATA && ifp) + ifp->stats.rx_errors++; + brcmu_pkt_buf_free_skb(skb); + return; +@@ -592,17 +590,17 @@ void brcmf_txcomplete(struct device *dev + { + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; +- u8 ifidx; ++ struct brcmf_if *ifp; + + /* await txstatus signal for firmware if active */ + if (brcmf_fws_fc_active(drvr->fws)) { + if (!success) + brcmf_fws_bustxfail(drvr->fws, txp); + } else { +- if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp)) ++ if (brcmf_proto_hdrpull(drvr, false, txp, &ifp)) + brcmu_pkt_buf_free_skb(txp); + else +- brcmf_txfinalize(drvr, txp, ifidx, success); ++ brcmf_txfinalize(drvr, txp, ifp->ifidx, success); + } + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +@@ -1448,7 +1448,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i + struct sk_buff *skb; + struct brcmf_skbuff_cb *skcb; + struct brcmf_fws_mac_descriptor *entry = NULL; +- u8 ifidx; ++ struct brcmf_if *ifp; + + brcmf_dbg(DATA, "flags %d\n", flags); + +@@ -1497,15 +1497,16 @@ brcmf_fws_txs_process(struct brcmf_fws_i + } + brcmf_fws_macdesc_return_req_credit(skb); + +- if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) { ++ ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp); ++ if (ret) { + brcmu_pkt_buf_free_skb(skb); + return -EINVAL; + } + if (!remove_from_hanger) +- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx, ++ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx, + genbit, seq); + if (remove_from_hanger || ret) +- brcmf_txfinalize(fws->drvr, skb, ifidx, true); ++ brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true); + + return 0; + } +@@ -1848,7 +1849,7 @@ static int brcmf_fws_commit_skb(struct b + entry->transit_count--; + if (entry->suppressed) + entry->suppr_transit_count--; +- brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); ++ (void)brcmf_proto_hdrpull(fws->drvr, false, skb, NULL); + goto rollback; + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -522,7 +522,7 @@ static int brcmf_msgbuf_set_dcmd(struct + + + static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws, +- u8 *ifidx, struct sk_buff *skb) ++ struct sk_buff *skb, struct brcmf_if **ifp) + { + return -ENODEV; + } +@@ -1082,7 +1082,7 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf + struct brcmf_if *ifp; + + ifp = brcmf_get_ifp(msgbuf->drvr, ifidx); +- if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) { ++ if (!ifp || !ifp->ndev) { + brcmf_err("Received pkt for invalid ifidx %d\n", ifidx); + brcmu_pkt_buf_free_skb(skb); + return; +--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h +@@ -24,8 +24,8 @@ enum proto_addr_mode { + + + struct brcmf_proto { +- int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, +- struct sk_buff *skb); ++ 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); + int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, +@@ -46,9 +46,19 @@ int brcmf_proto_attach(struct brcmf_pub + void brcmf_proto_detach(struct brcmf_pub *drvr); + + static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, +- u8 *ifidx, struct sk_buff *skb) ++ struct sk_buff *skb, ++ struct brcmf_if **ifp) + { +- return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb); ++ struct brcmf_if *tmp = NULL; ++ ++ /* assure protocol is always called with ++ * non-null initialized pointer. ++ */ ++ if (ifp) ++ *ifp = NULL; ++ else ++ ifp = &tmp; ++ 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) diff --git a/package/kernel/mac80211/patches/365-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch b/package/kernel/mac80211/patches/365-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch new file mode 100644 index 0000000000..2d15a77154 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch @@ -0,0 +1,87 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:14:55 +0200 +Subject: [PATCH] brcmfmac: change parameters for + brcmf_remove_interface() + +Just pass the interface to be removed, ie. the struct brcmf_if instance. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -4982,7 +4982,7 @@ brcmf_notify_connect_status_ap(struct br + brcmf_dbg(CONN, "AP mode link down\n"); + complete(&cfg->vif_disabled); + if (ifp->vif->mbss) +- brcmf_remove_interface(ifp->drvr, ifp->bssidx); ++ brcmf_remove_interface(ifp); + return 0; + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -887,12 +887,13 @@ static void brcmf_del_if(struct brcmf_pu + } + } + +-void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx) ++void brcmf_remove_interface(struct brcmf_if *ifp) + { +- if (drvr->iflist[bssidx]) { +- brcmf_fws_del_interface(drvr->iflist[bssidx]); +- brcmf_del_if(drvr, bssidx); +- } ++ if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp)) ++ return; ++ ++ brcmf_fws_del_interface(ifp); ++ brcmf_del_if(ifp->drvr, ifp->bssidx); + } + + int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr) +@@ -1122,7 +1123,7 @@ void brcmf_detach(struct device *dev) + + /* make sure primary interface removed last */ + for (i = BRCMF_MAX_IFS-1; i > -1; i--) +- brcmf_remove_interface(drvr, i); ++ brcmf_remove_interface(drvr->iflist[i]); + + brcmf_cfg80211_detach(drvr->config); + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h +@@ -206,7 +206,7 @@ struct brcmf_if *brcmf_get_ifp(struct br + int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, + char *name, u8 *mac_addr); +-void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx); ++void brcmf_remove_interface(struct brcmf_if *ifp); + int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr); + void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state); +--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +@@ -222,7 +222,7 @@ static void brcmf_fweh_handle_if_event(s + err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); + + if (ifp && ifevent->action == BRCMF_E_IF_DEL) +- brcmf_remove_interface(drvr, ifevent->bssidx); ++ brcmf_remove_interface(ifp); + } + + /** +--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru + { + cfg80211_unregister_wdev(&vif->wdev); + p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; +- brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx); ++ brcmf_remove_interface(vif->ifp); + brcmf_free_vif(vif); + } + diff --git a/package/kernel/mac80211/patches/365-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch b/package/kernel/mac80211/patches/365-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch new file mode 100644 index 0000000000..2b61f4eda5 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch @@ -0,0 +1,92 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:14:56 +0200 +Subject: [PATCH] brcmfmac: only call brcmf_cfg80211_detach() when attach + was successful + +In brcmf_bus_start() the function brcmf_cfg80211_attach() is called which +may fail. If this happens we should not call brcmf_cfg80211_detach() in +the failure path as it will result in NULL pointer dereference: + + brcmf_fweh_activate_events: Set event_msgs error (-5) + brcmf_bus_start: failed: -5 + brcmf_sdio_firmware_callback: dongle is not responding + BUG: unable to handle kernel NULL pointer dereference at 0000000000000068 + IP: [] kernfs_find_ns+0x18/0xd0 + PGD 0 + Oops: 0000 [#1] SMP + Modules linked in: brcmfmac(O) brcmutil(O) cfg80211 auth_rpcgss + CPU: 1 PID: 45 Comm: kworker/1:1 Tainted: G O + Hardware name: Dell Inc. Latitude E6410/07XJP9, BIOS A07 02/15/2011 + Workqueue: events request_firmware_work_func + task: ffff880036c09ac0 ti: ffff880036dd4000 task.ti: ffff880036dd4000 + RIP: 0010:[] [] kernfs_find_ns+0x18/0xd0 + RSP: 0018:ffff880036dd7a28 EFLAGS: 00010246 + RAX: ffff880036c09ac0 RBX: 0000000000000000 RCX: 000000007fffffff + RDX: 0000000000000000 RSI: ffffffff816578b9 RDI: 0000000000000000 + RBP: ffff880036dd7a48 R08: 0000000000000000 R09: ffff880036c0b340 + R10: 00000000000002ec R11: ffff880036dd7b08 R12: ffffffff816578b9 + R13: 0000000000000000 R14: ffffffff816578b9 R15: ffff8800c6c87000 + FS: 0000000000000000(0000) GS:ffff88012bc40000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b + CR2: 0000000000000068 CR3: 0000000001a0b000 CR4: 00000000000006e0 + Stack: + 0000000000000000 ffffffff816578b9 0000000000000000 ffff8800c0d003c8 + ffff880036dd7a78 ffffffff811e8ff5 0000000ffffffff1 ffffffff81a9b060 + ffff8800c789f880 ffff8800c0d00000 ffff880036dd7a98 ffffffff811ebe0d + Call Trace: + [] kernfs_find_and_get_ns+0x35/0x60 + [] sysfs_unmerge_group+0x1d/0x60 + [] dpm_sysfs_remove+0x22/0x60 + [] device_del+0x49/0x240 + [] rfkill_unregister+0x58/0xc0 + [] wiphy_unregister+0xab/0x2f0 [cfg80211] + [] brcmf_cfg80211_detach+0x23/0x50 [brcmfmac] + [] brcmf_detach+0x86/0xe0 [brcmfmac] + [] brcmf_sdio_remove+0x48/0x120 [brcmfmac] + [] brcmf_sdiod_remove+0x29/0xd0 [brcmfmac] + [] brcmf_ops_sdio_remove+0xb1/0x110 [brcmfmac] + [] sdio_bus_remove+0x37/0x100 [mmc_core] + [] __device_release_driver+0x96/0x130 + [] device_release_driver+0x23/0x30 + [] brcmf_sdio_firmware_callback+0x2a8/0x5d0 [brcmfmac] + [] brcmf_fw_request_nvram_done+0x15f/0x5e0 [brcmfmac] + [] ? devres_add+0x3f/0x50 + [] ? usermodehelper_read_unlock+0x15/0x20 + [] ? platform_match+0x70/0xa0 + [] request_firmware_work_func+0x30/0x60 + [] process_one_work+0x14c/0x3d0 + [] worker_thread+0x11a/0x450 + [] ? process_one_work+0x3d0/0x3d0 + [] kthread+0xd2/0xf0 + [] ? kthread_create_on_node+0x180/0x180 + [] ret_from_fork+0x3f/0x70 + [] ? kthread_create_on_node+0x180/0x180 + Code: e9 40 fe ff ff 48 89 d8 eb 87 66 0f 1f 84 00 00 00 00 00 66 66 66 66 + 90 55 48 89 e5 41 56 49 89 f6 41 55 49 89 d5 31 d2 41 54 53 <0f> b7 + 47 68 48 8b 5f 48 66 c1 e8 05 83 e0 01 4d 85 ed 0f b6 c8 + RIP [] kernfs_find_ns+0x18/0xd0 + RSP + CR2: 0000000000000068 + ---[ end trace 87d6ec0d3fe46740 ]--- + +Reported-by: Daniel (Deognyoun) Kim +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -1049,7 +1049,10 @@ int brcmf_bus_start(struct device *dev) + fail: + if (ret < 0) { + brcmf_err("failed: %d\n", ret); +- brcmf_cfg80211_detach(drvr->config); ++ if (drvr->config) { ++ brcmf_cfg80211_detach(drvr->config); ++ drvr->config = NULL; ++ } + if (drvr->fws) { + brcmf_fws_del_interface(ifp); + brcmf_fws_deinit(drvr); diff --git a/package/kernel/mac80211/patches/365-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch b/package/kernel/mac80211/patches/365-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch new file mode 100644 index 0000000000..868b0a82e6 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch @@ -0,0 +1,105 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:14:57 +0200 +Subject: [PATCH] brcmfmac: correct detection of p2pdev interface event + +The p2pdev interface is setup in firmware resulting in a interface +event. This event has role and no-if flag. When role is p2p client +and no-if flag is set it indicates that this is the p2pdev interface. +This info is used in handling the event and adding interface in the +driver. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -795,7 +795,7 @@ fail: + } + + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, +- char *name, u8 *mac_addr) ++ bool is_p2pdev, char *name, u8 *mac_addr) + { + struct brcmf_if *ifp; + struct net_device *ndev; +@@ -821,7 +821,7 @@ struct brcmf_if *brcmf_add_if(struct brc + } + } + +- if (!brcmf_p2p_enable && bssidx == 1) { ++ if (!brcmf_p2p_enable && is_p2pdev) { + /* this is P2P_DEVICE interface */ + brcmf_dbg(INFO, "allocate non-netdev interface\n"); + ifp = kzalloc(sizeof(*ifp), GFP_KERNEL); +@@ -999,12 +999,12 @@ int brcmf_bus_start(struct device *dev) + brcmf_dbg(TRACE, "\n"); + + /* add primary networking interface */ +- ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL); ++ ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", NULL); + if (IS_ERR(ifp)) + return PTR_ERR(ifp); + + if (brcmf_p2p_enable) +- p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL); ++ p2p_ifp = brcmf_add_if(drvr, 1, 0, false, "p2p%d", NULL); + else + p2p_ifp = NULL; + if (IS_ERR(p2p_ifp)) +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h +@@ -205,7 +205,7 @@ char *brcmf_ifname(struct brcmf_pub *drv + struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); + int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, +- char *name, u8 *mac_addr); ++ bool is_p2pdev, char *name, u8 *mac_addr); + void brcmf_remove_interface(struct brcmf_if *ifp); + int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr); + void brcmf_txflowblock_if(struct brcmf_if *ifp, +--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +@@ -179,6 +179,7 @@ static void brcmf_fweh_handle_if_event(s + { + struct brcmf_if_event *ifevent = data; + struct brcmf_if *ifp; ++ bool is_p2pdev; + int err = 0; + + brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u role: %u\n", +@@ -186,18 +187,16 @@ static void brcmf_fweh_handle_if_event(s + ifevent->flags, ifevent->role); + + /* The P2P Device interface event must not be ignored +- * contrary to what firmware tells us. The only way to +- * distinguish the P2P Device is by looking at the ifidx +- * and bssidx received. ++ * contrary to what firmware tells us. + */ +- if (!(ifevent->ifidx == 0 && ifevent->bssidx == 1) && +- (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) { ++ is_p2pdev = (ifevent->flags & BRCMF_E_IF_FLAG_NOIF) && ++ ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT; ++ if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) { + brcmf_dbg(EVENT, "event can be ignored\n"); + return; + } + if (ifevent->ifidx >= BRCMF_MAX_IFS) { +- brcmf_err("invalid interface index: %u\n", +- ifevent->ifidx); ++ brcmf_err("invalid interface index: %u\n", ifevent->ifidx); + return; + } + +@@ -207,7 +206,7 @@ static void brcmf_fweh_handle_if_event(s + brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, + emsg->addr); + ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx, +- emsg->ifname, emsg->addr); ++ is_p2pdev, emsg->ifname, emsg->addr); + if (IS_ERR(ifp)) + return; + brcmf_fws_add_interface(ifp); diff --git a/package/kernel/mac80211/patches/365-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch b/package/kernel/mac80211/patches/365-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch new file mode 100644 index 0000000000..aebbfa6c49 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch @@ -0,0 +1,126 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:14:58 +0200 +Subject: [PATCH] brcmfmac: use brcmf_get_ifp() to map ifidx to struct + brcmf_if instance + +The knowledge on how to map the interface index to a struct brcmf_if +instance is in brcmf_get_ifp() so use that function when only the +interface index is known instead of accessing brcmf_pub::iflist +directly. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c +@@ -149,7 +149,7 @@ static s32 brcmf_btcoex_params_read(stru + static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci, + bool trump_sco) + { +- struct brcmf_if *ifp = btci->cfg->pub->iflist[0]; ++ struct brcmf_if *ifp = brcmf_get_ifp(btci->cfg->pub, 0); + + if (trump_sco && !btci->saved_regs_part2) { + /* this should reduce eSCO agressive +@@ -468,7 +468,7 @@ int brcmf_btcoex_set_mode(struct brcmf_c + { + struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy); + struct brcmf_btcoex_info *btci = cfg->btcoex; +- struct brcmf_if *ifp = cfg->pub->iflist[0]; ++ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + + switch (mode) { + case BRCMF_BTCOEX_DISABLED: +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -6212,7 +6212,7 @@ static void brcmf_free_wiphy(struct wiph + struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, + struct device *busdev) + { +- struct net_device *ndev = drvr->iflist[0]->ndev; ++ struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; + struct brcmf_cfg80211_info *cfg; + struct wiphy *wiphy; + struct brcmf_cfg80211_vif *vif; +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c +@@ -121,7 +121,7 @@ static void brcmf_feat_iovar_int_set(str + + void brcmf_feat_attach(struct brcmf_pub *drvr) + { +- struct brcmf_if *ifp = drvr->iflist[0]; ++ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan"); + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); +--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c +@@ -221,7 +221,7 @@ static void brcmf_flowring_block(struct + + bus_if = dev_get_drvdata(flow->dev); + drvr = bus_if->drvr; +- ifp = drvr->iflist[ifidx]; ++ ifp = brcmf_get_ifp(drvr, ifidx); + brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, blocked); + + spin_unlock_irqrestore(&flow->block_lock, flags); +--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +@@ -334,7 +334,7 @@ void brcmf_fweh_attach(struct brcmf_pub + void brcmf_fweh_detach(struct brcmf_pub *drvr) + { + struct brcmf_fweh_info *fweh = &drvr->fweh; +- struct brcmf_if *ifp = drvr->iflist[0]; ++ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + + if (ifp) { +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +@@ -972,7 +972,7 @@ static void + brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq, + u8 if_id) + { +- struct brcmf_if *ifp = fws->drvr->iflist[!if_id ? 0 : if_id + 1]; ++ struct brcmf_if *ifp = brcmf_get_ifp(fws->drvr, if_id); + + if (WARN_ON(!ifp)) + return; +@@ -2118,6 +2118,7 @@ static int brcmf_debugfs_fws_stats_read( + int brcmf_fws_init(struct brcmf_pub *drvr) + { + struct brcmf_fws_info *fws; ++ struct brcmf_if *ifp; + u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS; + int rc; + u32 mode; +@@ -2177,21 +2178,22 @@ int brcmf_fws_init(struct brcmf_pub *drv + * continue. Set mode back to none indicating not enabled. + */ + fws->fw_signals = true; +- if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) { ++ ifp = brcmf_get_ifp(drvr, 0); ++ if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) { + brcmf_err("failed to set bdcv2 tlv signaling\n"); + fws->fcmode = BRCMF_FWS_FCMODE_NONE; + fws->fw_signals = false; + } + +- if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1)) ++ if (brcmf_fil_iovar_int_set(ifp, "ampdu_hostreorder", 1)) + brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n"); + + /* Enable seq number reuse, if supported */ +- if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) { ++ if (brcmf_fil_iovar_int_get(ifp, "wlfc_mode", &mode) == 0) { + if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) { + mode = 0; + BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1); +- if (brcmf_fil_iovar_int_set(drvr->iflist[0], ++ if (brcmf_fil_iovar_int_set(ifp, + "wlfc_mode", mode) == 0) { + BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1); + } diff --git a/package/kernel/mac80211/patches/365-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch b/package/kernel/mac80211/patches/365-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch new file mode 100644 index 0000000000..23a7b6f1c8 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch @@ -0,0 +1,122 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:14:59 +0200 +Subject: [PATCH] brcmfmac: pass struct brcmf_if instance in + brcmf_txfinalize() + +Most call sites of brcmf_txfinalize already have struct brcmf_if +instance so pass that to brcmf_txfinalize() as the function +needs it anyway. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -560,17 +560,11 @@ void brcmf_rx_frame(struct device *dev, + brcmf_netif_rx(ifp, skb); + } + +-void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, +- bool success) ++void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) + { +- struct brcmf_if *ifp; + struct ethhdr *eh; + u16 type; + +- ifp = drvr->iflist[ifidx]; +- if (!ifp) +- goto done; +- + eh = (struct ethhdr *)(txp->data); + type = ntohs(eh->h_proto); + +@@ -582,7 +576,7 @@ void brcmf_txfinalize(struct brcmf_pub * + + if (!success) + ifp->stats.tx_errors++; +-done: ++ + brcmu_pkt_buf_free_skb(txp); + } + +@@ -600,7 +594,7 @@ void brcmf_txcomplete(struct device *dev + if (brcmf_proto_hdrpull(drvr, false, txp, &ifp)) + brcmu_pkt_buf_free_skb(txp); + else +- brcmf_txfinalize(drvr, txp, ifp->ifidx, success); ++ brcmf_txfinalize(ifp, txp, success); + } + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h +@@ -210,8 +210,7 @@ void brcmf_remove_interface(struct brcmf + int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr); + void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state); +-void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, +- bool success); ++void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); + void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); + + /* Sets dongle media info (drv_version, mac address). */ +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +@@ -1506,7 +1506,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i + ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx, + genbit, seq); + if (remove_from_hanger || ret) +- brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true); ++ brcmf_txfinalize(ifp, skb, true); + + return 0; + } +@@ -1905,7 +1905,7 @@ int brcmf_fws_process_skb(struct brcmf_i + if (fws->avoid_queueing) { + rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb); + if (rc < 0) +- brcmf_txfinalize(drvr, skb, ifp->ifidx, false); ++ brcmf_txfinalize(ifp, skb, false); + return rc; + } + +@@ -1929,7 +1929,7 @@ int brcmf_fws_process_skb(struct brcmf_i + brcmf_fws_schedule_deq(fws); + } else { + brcmf_err("drop skb: no hanger slot\n"); +- brcmf_txfinalize(drvr, skb, ifp->ifidx, false); ++ brcmf_txfinalize(ifp, skb, false); + rc = -ENOMEM; + } + brcmf_fws_unlock(fws); +@@ -2009,8 +2009,9 @@ static void brcmf_fws_dequeue_worker(str + ret = brcmf_proto_txdata(drvr, ifidx, 0, skb); + brcmf_fws_lock(fws); + if (ret < 0) +- brcmf_txfinalize(drvr, skb, ifidx, +- false); ++ brcmf_txfinalize(brcmf_get_ifp(drvr, ++ ifidx), ++ skb, false); + if (fws->bus_flow_blocked) + break; + } +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -873,7 +873,11 @@ brcmf_msgbuf_process_txstatus(struct brc + commonring = msgbuf->flowrings[flowid]; + atomic_dec(&commonring->outstanding_tx); + +- brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true); ++ /* Hante: i believe this was a bug as tx_status->msg.ifidx was used ++ * in brcmf_txfinalize as index in drvr->iflist. Can you confirm/deny? ++ */ ++ brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx), ++ skb, true); + } + + diff --git a/package/kernel/mac80211/patches/365-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch b/package/kernel/mac80211/patches/365-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch new file mode 100644 index 0000000000..8ddc0a6eef --- /dev/null +++ b/package/kernel/mac80211/patches/365-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch @@ -0,0 +1,92 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:15:00 +0200 +Subject: [PATCH] brcmfmac: add mapping for interface index to bsscfg + index + +Because the P2P Device interface in firmware uses the same interface +index as the primary interface we use the bsscfg index as index in the +struct brcmf_pub::iflist. However, in the data path we get the interface +index and not the bsscfg index. So we need a mapping of interface index +to bsscfg index, which can be determined upon handle adding the interface. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -85,21 +85,20 @@ char *brcmf_ifname(struct brcmf_pub *drv + + struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx) + { ++ struct brcmf_if *ifp; ++ s32 bssidx; ++ + if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { + brcmf_err("ifidx %d out of range\n", ifidx); + return NULL; + } + +- /* The ifidx is the idx to map to matching netdev/ifp. When receiving +- * events this is easy because it contains the bssidx which maps +- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. +- * bssidx 1 is used for p2p0 and no data can be received or +- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 +- */ +- if (ifidx) +- ifidx++; ++ ifp = NULL; ++ bssidx = drvr->if2bss[ifidx]; ++ if (bssidx >= 0) ++ ifp = drvr->iflist[bssidx]; + +- return drvr->iflist[ifidx]; ++ return ifp; + } + + static void _brcmf_set_multicast_list(struct work_struct *work) +@@ -831,6 +830,8 @@ struct brcmf_if *brcmf_add_if(struct brc + + ifp = netdev_priv(ndev); + ifp->ndev = ndev; ++ /* store mapping ifidx to bssidx */ ++ drvr->if2bss[ifidx] = bssidx; + } + + ifp->drvr = drvr; +@@ -855,6 +856,7 @@ static void brcmf_del_if(struct brcmf_pu + struct brcmf_if *ifp; + + ifp = drvr->iflist[bssidx]; ++ drvr->if2bss[ifp->ifidx] = -1; + drvr->iflist[bssidx] = NULL; + if (!ifp) { + brcmf_err("Null interface, idx=%d\n", bssidx); +@@ -862,6 +864,7 @@ static void brcmf_del_if(struct brcmf_pu + } + brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx); + if (ifp->ndev) { ++ drvr->if2bss[ifp->ifidx] = -1; + if (bssidx == 0) { + if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { + rtnl_lock(); +@@ -926,6 +929,7 @@ int brcmf_attach(struct device *dev) + if (!drvr) + return -ENOMEM; + ++ memset(drvr->if2bss, 0xFF, sizeof(drvr->if2bss)); + mutex_init(&drvr->proto_block); + + /* Link to bus module */ +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h +@@ -122,6 +122,7 @@ struct brcmf_pub { + struct mac_address addresses[BRCMF_MAX_IFS]; + + struct brcmf_if *iflist[BRCMF_MAX_IFS]; ++ s32 if2bss[BRCMF_MAX_IFS]; + + struct mutex proto_block; + unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; diff --git a/package/kernel/mac80211/patches/365-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch b/package/kernel/mac80211/patches/365-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch new file mode 100644 index 0000000000..a0a798be93 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch @@ -0,0 +1,103 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:15:01 +0200 +Subject: [PATCH] brcmfmac: add dedicated debug level for firmware + console logging + +Both PCIe and SDIO devices have the possibility to log the firmware +console output in kernel log. For PCIe it is logged when PCIE debug +level is enabled. For SDIO it is logged when user specifies a non-zero +console interval through debugfs. This patch tries to make it a +bit more consistent. The firmware console output is only logged when +FWCON debug level is enabled. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Pontus Fuchs +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h +@@ -37,6 +37,7 @@ + #define BRCMF_SDIO_VAL 0x00020000 + #define BRCMF_MSGBUF_VAL 0x00040000 + #define BRCMF_PCIE_VAL 0x00080000 ++#define BRCMF_FWCON_VAL 0x00100000 + + /* set default print format */ + #undef pr_fmt +@@ -78,6 +79,7 @@ do { \ + #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) + #define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL) + #define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL) ++#define BRCMF_FWCON_ON() (brcmf_msg_level & BRCMF_FWCON_VAL) + + #else /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */ + +@@ -90,6 +92,7 @@ do { \ + #define BRCMF_GLOM_ON() 0 + #define BRCMF_EVENT_ON() 0 + #define BRCMF_FIL_ON() 0 ++#define BRCMF_FWCON_ON() 0 + + #endif /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */ + +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -644,7 +644,7 @@ static void brcmf_pcie_bus_console_init( + addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET; + console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr); + +- brcmf_dbg(PCIE, "Console: base %x, buf %x, size %d\n", ++ brcmf_dbg(FWCON, "Console: base %x, buf %x, size %d\n", + console->base_addr, console->buf_addr, console->bufsize); + } + +@@ -656,6 +656,9 @@ static void brcmf_pcie_bus_console_read( + u8 ch; + u32 newidx; + ++ if (!BRCMF_FWCON_ON()) ++ return; ++ + console = &devinfo->shared.console; + addr = console->base_addr + BRCMF_CONSOLE_WRITEIDX_OFFSET; + newidx = brcmf_pcie_read_tcm32(devinfo, addr); +@@ -677,7 +680,7 @@ static void brcmf_pcie_bus_console_read( + } + if (ch == '\n') { + console->log_str[console->log_idx] = 0; +- brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str); ++ pr_debug("CONSOLE: %s", console->log_str); + console->log_idx = 0; + } + } +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -123,6 +123,7 @@ struct rte_console { + + #define BRCMF_FIRSTREAD (1 << 6) + ++#define BRCMF_CONSOLE 10 /* watchdog interval to poll console */ + + /* SBSDIO_DEVICE_CTL */ + +@@ -3204,6 +3205,8 @@ static void brcmf_sdio_debugfs_create(st + if (IS_ERR_OR_NULL(dentry)) + return; + ++ bus->console_interval = BRCMF_CONSOLE; ++ + brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read); + brcmf_debugfs_add_entry(drvr, "counters", + brcmf_debugfs_sdio_count_read); +@@ -3613,7 +3616,7 @@ static void brcmf_sdio_bus_watchdog(stru + } + #ifdef DEBUG + /* Poll for console output periodically */ +- if (bus->sdiodev->state == BRCMF_SDIOD_DATA && ++ if (bus->sdiodev->state == BRCMF_SDIOD_DATA && BRCMF_FWCON_ON() && + bus->console_interval != 0) { + bus->console.count += BRCMF_WD_POLL_MS; + if (bus->console.count >= bus->console_interval) { diff --git a/package/kernel/mac80211/patches/365-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch b/package/kernel/mac80211/patches/365-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch new file mode 100644 index 0000000000..53e7edeee7 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch @@ -0,0 +1,34 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:15:02 +0200 +Subject: [PATCH] brcmfmac: remove ifidx parameter from + brcmf_fws_txstatus_suppressed() + +The brcmf_fws_txstatus_suppressed() function prototype specifies an +ifidx parameter which is not used within the function implementation. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +@@ -1398,7 +1398,7 @@ done: + } + + static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, +- struct sk_buff *skb, u8 ifidx, ++ struct sk_buff *skb, + u32 genbit, u16 seq) + { + struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; +@@ -1503,7 +1503,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i + return -EINVAL; + } + if (!remove_from_hanger) +- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx, ++ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, + genbit, seq); + if (remove_from_hanger || ret) + brcmf_txfinalize(ifp, skb, true); diff --git a/package/kernel/mac80211/patches/365-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch b/package/kernel/mac80211/patches/365-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch new file mode 100644 index 0000000000..bb05235cf4 --- /dev/null +++ b/package/kernel/mac80211/patches/365-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch @@ -0,0 +1,97 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:15:03 +0200 +Subject: [PATCH] brcmfmac: change prototype for brcmf_fws_hdrpull() + +Instead of passing ifidx and drvr just pass struct brcmf_if pointer +which holds both parameters. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +@@ -312,8 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + + skb_pull(pktbuf, BCDC_HEADER_LEN); + if (do_fws) +- brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2, +- pktbuf); ++ brcmf_fws_hdrpull(tmp_if, h->data_offset << 2, pktbuf); + else + skb_pull(pktbuf, h->data_offset << 2); + +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +@@ -1616,11 +1616,10 @@ static int brcmf_fws_notify_bcmc_credit_ + return 0; + } + +-int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, +- struct sk_buff *skb) ++void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb) + { + struct brcmf_skb_reorder_data *rd; +- struct brcmf_fws_info *fws = drvr->fws; ++ struct brcmf_fws_info *fws = ifp->drvr->fws; + u8 *signal_data; + s16 data_len; + u8 type; +@@ -1630,20 +1629,20 @@ int brcmf_fws_hdrpull(struct brcmf_pub * + s32 err; + + brcmf_dbg(HDRS, "enter: ifidx %d, skblen %u, sig %d\n", +- ifidx, skb->len, signal_len); ++ ifp->ifidx, skb->len, siglen); + +- WARN_ON(signal_len > skb->len); ++ WARN_ON(siglen > skb->len); + +- if (!signal_len) +- return 0; ++ if (!siglen) ++ return; + /* if flow control disabled, skip to packet data and leave */ + if ((!fws) || (!fws->fw_signals)) { +- skb_pull(skb, signal_len); +- return 0; ++ skb_pull(skb, siglen); ++ return; + } + + fws->stats.header_pulls++; +- data_len = signal_len; ++ data_len = siglen; + signal_data = skb->data; + + status = BRCMF_FWS_RET_OK_NOSCHEDULE; +@@ -1731,14 +1730,12 @@ int brcmf_fws_hdrpull(struct brcmf_pub * + /* signalling processing result does + * not affect the actual ethernet packet. + */ +- skb_pull(skb, signal_len); ++ skb_pull(skb, siglen); + + /* this may be a signal-only packet + */ + if (skb->len == 0) + fws->stats.header_only_pkt++; +- +- return 0; + } + + static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h +@@ -21,8 +21,7 @@ + int brcmf_fws_init(struct brcmf_pub *drvr); + void brcmf_fws_deinit(struct brcmf_pub *drvr); + bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); +-int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, +- struct sk_buff *skb); ++void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); + int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb); + + void brcmf_fws_reset_interface(struct brcmf_if *ifp); diff --git a/package/kernel/mac80211/patches/365-0012-brcmfmac-introduce-brcmf_net_detach-function.patch b/package/kernel/mac80211/patches/365-0012-brcmfmac-introduce-brcmf_net_detach-function.patch new file mode 100644 index 0000000000..ba92c6749b --- /dev/null +++ b/package/kernel/mac80211/patches/365-0012-brcmfmac-introduce-brcmf_net_detach-function.patch @@ -0,0 +1,99 @@ +From: Arend van Spriel +Date: Wed, 26 Aug 2015 22:15:04 +0200 +Subject: [PATCH] brcmfmac: introduce brcmf_net_detach() function + +In case of error during brcmf_bus_start() the network interfaces were +freed using free_netdev(). However, the interfaces may have additional +memory allocated which is not freed. The netdev has destructor set to +brcmf_cfg80211_free_netdev() which frees the additional memory if +allocated and call free_netdev(). The brcmf_net_detach() either calls +brcmf_cfg80211_free_netdev() directly or uses unregister_netdev() when +struct net_device::reg_state indicates the netdev was registered. + +Reported-by: Daniel (Deognyoun) Kim +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -4746,7 +4746,8 @@ void brcmf_cfg80211_free_netdev(struct n + ifp = netdev_priv(ndev); + vif = ifp->vif; + +- brcmf_free_vif(vif); ++ if (vif) ++ brcmf_free_vif(vif); + free_netdev(ndev); + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -718,8 +718,6 @@ int brcmf_net_attach(struct brcmf_if *if + } + + brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); +- +- ndev->destructor = brcmf_cfg80211_free_netdev; + return 0; + + fail: +@@ -729,6 +727,14 @@ fail: + return -EBADE; + } + ++static void brcmf_net_detach(struct net_device *ndev) ++{ ++ if (ndev->reg_state == NETREG_REGISTERED) ++ unregister_netdev(ndev); ++ else ++ brcmf_cfg80211_free_netdev(ndev); ++} ++ + static int brcmf_net_p2p_open(struct net_device *ndev) + { + brcmf_dbg(TRACE, "Enter\n"); +@@ -805,8 +811,7 @@ struct brcmf_if *brcmf_add_if(struct brc + ifp->ndev->name); + if (ifidx) { + netif_stop_queue(ifp->ndev); +- unregister_netdev(ifp->ndev); +- free_netdev(ifp->ndev); ++ brcmf_net_detach(ifp->ndev); + drvr->iflist[bssidx] = NULL; + } else { + brcmf_err("ignore IF event\n"); +@@ -828,6 +833,7 @@ struct brcmf_if *brcmf_add_if(struct brc + if (!ndev) + return ERR_PTR(-ENOMEM); + ++ ndev->destructor = brcmf_cfg80211_free_netdev; + ifp = netdev_priv(ndev); + ifp->ndev = ndev; + /* store mapping ifidx to bssidx */ +@@ -879,8 +885,7 @@ static void brcmf_del_if(struct brcmf_pu + cancel_work_sync(&ifp->setmacaddr_work); + cancel_work_sync(&ifp->multicast_work); + } +- /* unregister will take care of freeing it */ +- unregister_netdev(ifp->ndev); ++ brcmf_net_detach(ifp->ndev); + } + } + +@@ -1056,11 +1061,11 @@ fail: + brcmf_fws_deinit(drvr); + } + if (drvr->iflist[0]) { +- free_netdev(ifp->ndev); ++ brcmf_net_detach(ifp->ndev); + drvr->iflist[0] = NULL; + } + if (p2p_ifp) { +- free_netdev(p2p_ifp->ndev); ++ brcmf_net_detach(p2p_ifp->ndev); + drvr->iflist[1] = NULL; + } + return ret; diff --git a/package/kernel/mac80211/patches/366-brcmfmac-Reset-PCIE-devices-after-recognition.patch b/package/kernel/mac80211/patches/366-brcmfmac-Reset-PCIE-devices-after-recognition.patch new file mode 100644 index 0000000000..5a7e447e25 --- /dev/null +++ b/package/kernel/mac80211/patches/366-brcmfmac-Reset-PCIE-devices-after-recognition.patch @@ -0,0 +1,193 @@ +From: Hante Meuleman +Date: Thu, 27 Aug 2015 16:14:06 +0200 +Subject: [PATCH] brcmfmac: Reset PCIE devices after recognition. + +When PCIE type devices are being FW reloaded without being properly +reset then the device ends up in a locked state, requiring the +device to be completely powered down. This patch adds a reset +through watchdog at the moment the device (cores) has been +recognized. This will solve warm reboot issues. + +Cc: Rafal Milecki +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -101,6 +101,9 @@ + /* ARM Cortex M3 core, ID 0x82a */ + #define BCM4329_CORE_ARM_BASE 0x18002000 + ++/* Max possibly supported memory size (limited by IO mapped memory) */ ++#define BRCMF_CHIP_MAX_MEMSIZE (4 * 1024 * 1024) ++ + #define CORE_SB(base, field) \ + (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) + #define SBCOREREV(sbidh) \ +@@ -687,6 +690,12 @@ static int brcmf_chip_get_raminfo(struct + brcmf_err("RAM size is undetermined\n"); + return -ENOMEM; + } ++ ++ if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) { ++ brcmf_err("RAM size is incorrect\n"); ++ return -ENOMEM; ++ } ++ + return 0; + } + +@@ -899,6 +908,15 @@ static int brcmf_chip_recognition(struct + + /* assure chip is passive for core access */ + brcmf_chip_set_passive(&ci->pub); ++ ++ /* Call bus specific reset function now. Cores have been determined ++ * but further access may require a chip specific reset at this point. ++ */ ++ if (ci->ops->reset) { ++ ci->ops->reset(ci->ctx, &ci->pub); ++ brcmf_chip_set_passive(&ci->pub); ++ } ++ + return brcmf_chip_get_raminfo(ci); + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h +@@ -73,6 +73,7 @@ struct brcmf_buscore_ops { + u32 (*read32)(void *ctx, u32 addr); + void (*write32)(void *ctx, u32 addr, u32 value); + int (*prepare)(void *ctx); ++ int (*reset)(void *ctx, struct brcmf_chip *chip); + int (*setup)(void *ctx, struct brcmf_chip *chip); + void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); + }; +--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +@@ -74,6 +74,8 @@ enum brcmf_pcie_state { + #define BRCMF_PCIE_REG_INTMASK 0x94 + #define BRCMF_PCIE_REG_SBMBX 0x98 + ++#define BRCMF_PCIE_REG_LINK_STATUS_CTRL 0xBC ++ + #define BRCMF_PCIE_PCIE2REG_INTMASK 0x24 + #define BRCMF_PCIE_PCIE2REG_MAILBOXINT 0x48 + #define BRCMF_PCIE_PCIE2REG_MAILBOXMASK 0x4C +@@ -466,6 +468,7 @@ brcmf_pcie_select_core(struct brcmf_pcie + + static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo) + { ++ struct brcmf_core *core; + u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD, + BRCMF_PCIE_CFGREG_PM_CSR, + BRCMF_PCIE_CFGREG_MSI_CAP, +@@ -484,32 +487,38 @@ static void brcmf_pcie_reset_device(stru + if (!devinfo->ci) + return; + ++ /* Disable ASPM */ + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, +- BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL); +- lsc = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA); ++ pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL, ++ &lsc); + val = lsc & (~BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB); +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, val); ++ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL, ++ val); + ++ /* Watchdog reset */ + brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON); + WRITECC32(devinfo, watchdog, 4); + msleep(100); + ++ /* Restore ASPM */ + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, +- BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL); +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, lsc); ++ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL, ++ lsc); + +- brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); +- for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) { +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, +- cfg_offset[i]); +- val = brcmf_pcie_read_reg32(devinfo, +- BRCMF_PCIE_PCIE2REG_CONFIGDATA); +- brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n", +- cfg_offset[i], val); +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, +- val); ++ core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2); ++ if (core->rev <= 13) { ++ for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) { ++ brcmf_pcie_write_reg32(devinfo, ++ BRCMF_PCIE_PCIE2REG_CONFIGADDR, ++ cfg_offset[i]); ++ val = brcmf_pcie_read_reg32(devinfo, ++ BRCMF_PCIE_PCIE2REG_CONFIGDATA); ++ brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n", ++ cfg_offset[i], val); ++ brcmf_pcie_write_reg32(devinfo, ++ BRCMF_PCIE_PCIE2REG_CONFIGDATA, ++ val); ++ } + } + } + +@@ -519,8 +528,6 @@ static void brcmf_pcie_attach(struct brc + u32 config; + + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); +- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) +- brcmf_pcie_reset_device(devinfo); + /* BAR1 window may not be sized properly */ + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); + brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0); +@@ -1636,6 +1643,23 @@ static int brcmf_pcie_buscoreprep(void * + } + + ++static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip) ++{ ++ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; ++ u32 val; ++ ++ devinfo->ci = chip; ++ brcmf_pcie_reset_device(devinfo); ++ ++ val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); ++ if (val != 0xffffffff) ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, ++ val); ++ ++ return 0; ++} ++ ++ + static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip, + u32 rstvec) + { +@@ -1647,6 +1671,7 @@ static void brcmf_pcie_buscore_activate( + + static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { + .prepare = brcmf_pcie_buscoreprep, ++ .reset = brcmf_pcie_buscore_reset, + .activate = brcmf_pcie_buscore_activate, + .read32 = brcmf_pcie_buscore_read32, + .write32 = brcmf_pcie_buscore_write32, +@@ -1814,7 +1839,6 @@ brcmf_pcie_remove(struct pci_dev *pdev) + brcmf_pcie_intr_disable(devinfo); + + brcmf_detach(&pdev->dev); +- brcmf_pcie_reset_device(devinfo); + + kfree(bus->bus_priv.pcie); + kfree(bus->msgbuf->flowrings); diff --git a/package/kernel/mac80211/patches/367-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch b/package/kernel/mac80211/patches/367-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch new file mode 100644 index 0000000000..f7b3e40b66 --- /dev/null +++ b/package/kernel/mac80211/patches/367-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch @@ -0,0 +1,24 @@ +From: Felix Fietkau +Date: Sun, 13 Sep 2015 22:26:10 +0200 +Subject: [PATCH] ath10k: fix DMA related firmware crashes on multiple devices + +Some platforms really don't like DMA bursts of 256 bytes, and this +causes the firmware to crash when sending beacons. +Also, changing this based on the firmware version does not seem to make +much sense, so use 128 bytes for all versions. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath10k/hw.h ++++ b/drivers/net/wireless/ath/ath10k/hw.h +@@ -253,7 +253,7 @@ struct ath10k_pktlog_hdr { + #define TARGET_10X_MAX_FRAG_ENTRIES 0 + + /* 10.2 parameters */ +-#define TARGET_10_2_DMA_BURST_SIZE 1 ++#define TARGET_10_2_DMA_BURST_SIZE 0 + + /* Target specific defines for WMI-TLV firmware */ + #define TARGET_TLV_NUM_VDEVS 3 diff --git a/package/kernel/mac80211/patches/368-ath9k-declare-required-extra-tx-headroom.patch b/package/kernel/mac80211/patches/368-ath9k-declare-required-extra-tx-headroom.patch new file mode 100644 index 0000000000..c420d20bae --- /dev/null +++ b/package/kernel/mac80211/patches/368-ath9k-declare-required-extra-tx-headroom.patch @@ -0,0 +1,22 @@ +From: Felix Fietkau +Date: Thu, 24 Sep 2015 16:57:37 +0200 +Subject: [PATCH] ath9k: declare required extra tx headroom + +ath9k inserts padding between the 802.11 header and the data area (to +align it). Since it didn't declare this extra required headroom, this +led to some nasty issues like randomly dropped packets in some setups. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -867,6 +867,7 @@ static void ath9k_set_hw_capab(struct at + hw->max_rate_tries = 10; + hw->sta_data_size = sizeof(struct ath_node); + hw->vif_data_size = sizeof(struct ath_vif); ++ hw->extra_tx_headroom = 4; + + hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; + hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1; diff --git a/package/kernel/mac80211/patches/369-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch b/package/kernel/mac80211/patches/369-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch new file mode 100644 index 0000000000..1478efae77 --- /dev/null +++ b/package/kernel/mac80211/patches/369-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Mon, 5 Oct 2015 17:41:25 +0200 +Subject: [PATCH] mac80211: initialize tid field in struct ieee80211_txq + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -3323,9 +3323,11 @@ void ieee80211_init_tx_queue(struct ieee + if (sta) { + txqi->txq.sta = &sta->sta; + sta->sta.txq[tid] = &txqi->txq; ++ txqi->txq.tid = tid; + txqi->txq.ac = ieee802_1d_to_ac[tid & 7]; + } else { + sdata->vif.txq = &txqi->txq; ++ txqi->txq.tid = 0; + txqi->txq.ac = IEEE80211_AC_BE; + } + } diff --git a/package/kernel/mac80211/patches/379-ath9k-fix-DMA-stop-sequence-for-AR9003.patch b/package/kernel/mac80211/patches/379-ath9k-fix-DMA-stop-sequence-for-AR9003.patch deleted file mode 100644 index 814b0d7a4a..0000000000 --- a/package/kernel/mac80211/patches/379-ath9k-fix-DMA-stop-sequence-for-AR9003.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Felix Fietkau -Date: Tue, 2 Jun 2015 10:35:46 +0200 -Subject: [PATCH] ath9k: fix DMA stop sequence for AR9003+ - -AR93xx and newer needs to stop rx before tx to avoid getting the DMA -engine or MAC into a stuck state. -This should reduce/fix the occurence of "Failed to stop Tx DMA" logspam. - -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -216,11 +216,13 @@ static bool ath_prepare_reset(struct ath - ath_stop_ani(sc); - ath9k_hw_disable_interrupts(ah); - -- if (!ath_drain_all_txq(sc)) -- ret = false; -- -- if (!ath_stoprecv(sc)) -- ret = false; -+ if (AR_SREV_9300_20_OR_LATER(ah)) { -+ ret &= ath_stoprecv(sc); -+ ret &= ath_drain_all_txq(sc); -+ } else { -+ ret &= ath_drain_all_txq(sc); -+ ret &= ath_stoprecv(sc); -+ } - - return ret; - } diff --git a/package/kernel/mac80211/patches/380-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch b/package/kernel/mac80211/patches/380-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch deleted file mode 100644 index 7bbd57e15e..0000000000 --- a/package/kernel/mac80211/patches/380-brcmfmac-support-NVRAMs-containing-pci-devpaths-inst.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 28 May 2015 14:19:21 +0200 -Subject: [PATCH] brcmfmac: support NVRAMs containing pci devpaths (instead of - pcie) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Recently Broadcom added support for NVRAMs with entries for multiple -PCIe devices. One of the supported formats is based on prefixes defined -like: devpath0=pcie/1/4/ and entries like 0:foo=bar 0:baz=qux etc. - -Unfortunately there are also a bit older devices using different way of -defining prefixes, e.g. SmartRG SR400ac (2 x BCM43602) with entries: -devpath0=pci/1/1/ -devpath1=pci/2/1 -Broadcom stated this old format will never be used/supported by brcmfmac -but given the simplicity of this patch I'll insist on supporting it. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -232,6 +232,8 @@ static void brcmf_fw_strip_multi_v1(stru - u16 bus_nr) - { - /* Device path with a leading '=' key-value separator */ -+ char pci_path[] = "=pci/?/?"; -+ size_t pci_len; - char pcie_path[] = "=pcie/?/?"; - size_t pcie_len; - -@@ -251,6 +253,9 @@ static void brcmf_fw_strip_multi_v1(stru - /* First search for the devpathX and see if it is the configuration - * for domain_nr/bus_nr. Search complete nvp - */ -+ snprintf(pci_path, sizeof(pci_path), "=pci/%d/%d", domain_nr, -+ bus_nr); -+ pci_len = strlen(pci_path); - snprintf(pcie_path, sizeof(pcie_path), "=pcie/%d/%d", domain_nr, - bus_nr); - pcie_len = strlen(pcie_path); -@@ -260,8 +265,9 @@ static void brcmf_fw_strip_multi_v1(stru - /* Format: devpathX=pcie/Y/Z/ - * Y = domain_nr, Z = bus_nr, X = virtual ID - */ -- if ((strncmp(&nvp->nvram[i], "devpath", 7) == 0) && -- (strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len) == 0)) { -+ if (strncmp(&nvp->nvram[i], "devpath", 7) == 0 && -+ (!strncmp(&nvp->nvram[i + 8], pci_path, pci_len) || -+ !strncmp(&nvp->nvram[i + 8], pcie_path, pcie_len))) { - id = nvp->nvram[i + 7] - '0'; - found = true; - break; diff --git a/package/kernel/mac80211/patches/381-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch b/package/kernel/mac80211/patches/381-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch deleted file mode 100644 index 1eff6ed83a..0000000000 --- a/package/kernel/mac80211/patches/381-brcmfmac-set-wiphy-perm_addr-to-hardware-MAC-address.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 31 May 2015 02:52:26 +0200 -Subject: [PATCH] brcmfmac: set wiphy perm_addr to hardware MAC address -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows e.g. user space to use /sys/class/ieee80211/*/macaddress - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -6070,6 +6070,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 - brcmf_err("Could not allocate wiphy device\n"); - return NULL; - } -+ memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN); - set_wiphy_dev(wiphy, busdev); - - cfg = wiphy_priv(wiphy); diff --git a/package/kernel/mac80211/patches/382-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch b/package/kernel/mac80211/patches/382-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch deleted file mode 100644 index c6e83ddd29..0000000000 --- a/package/kernel/mac80211/patches/382-brcmfmac-use-direct-data-pointer-in-NVRAM-parser-str.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 4 Jun 2015 22:11:07 +0200 -Subject: [PATCH] brcmfmac: use direct data pointer in NVRAM parser struct -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As we plan to add support for platform NVRAM we should store direct -data pointer without the extra struct firmware layer. This will allow -us to support other sources with the only requirement being u8 buffer. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c -@@ -43,7 +43,7 @@ enum nvram_parser_state { - * struct nvram_parser - internal info for parser. - * - * @state: current parser state. -- * @fwnv: input buffer being parsed. -+ * @data: input buffer being parsed. - * @nvram: output buffer with parse result. - * @nvram_len: lenght of parse result. - * @line: current line. -@@ -55,7 +55,7 @@ enum nvram_parser_state { - */ - struct nvram_parser { - enum nvram_parser_state state; -- const struct firmware *fwnv; -+ const u8 *data; - u8 *nvram; - u32 nvram_len; - u32 line; -@@ -91,7 +91,7 @@ static enum nvram_parser_state brcmf_nvr - { - char c; - -- c = nvp->fwnv->data[nvp->pos]; -+ c = nvp->data[nvp->pos]; - if (c == '\n') - return COMMENT; - if (is_whitespace(c)) -@@ -115,16 +115,16 @@ static enum nvram_parser_state brcmf_nvr - enum nvram_parser_state st = nvp->state; - char c; - -- c = nvp->fwnv->data[nvp->pos]; -+ c = nvp->data[nvp->pos]; - if (c == '=') { - /* ignore RAW1 by treating as comment */ -- if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0) -+ if (strncmp(&nvp->data[nvp->entry], "RAW1", 4) == 0) - st = COMMENT; - else - st = VALUE; -- if (strncmp(&nvp->fwnv->data[nvp->entry], "devpath", 7) == 0) -+ if (strncmp(&nvp->data[nvp->entry], "devpath", 7) == 0) - nvp->multi_dev_v1 = true; -- if (strncmp(&nvp->fwnv->data[nvp->entry], "pcie/", 5) == 0) -+ if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) - nvp->multi_dev_v2 = true; - } else if (!is_nvram_char(c) || c == ' ') { - brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", -@@ -145,11 +145,11 @@ brcmf_nvram_handle_value(struct nvram_pa - char *ekv; - u32 cplen; - -- c = nvp->fwnv->data[nvp->pos]; -+ c = nvp->data[nvp->pos]; - if (!is_nvram_char(c)) { - /* key,value pair complete */ -- ekv = (u8 *)&nvp->fwnv->data[nvp->pos]; -- skv = (u8 *)&nvp->fwnv->data[nvp->entry]; -+ ekv = (u8 *)&nvp->data[nvp->pos]; -+ skv = (u8 *)&nvp->data[nvp->entry]; - cplen = ekv - skv; - if (nvp->nvram_len + cplen + 1 >= BRCMF_FW_MAX_NVRAM_SIZE) - return END; -@@ -170,7 +170,7 @@ brcmf_nvram_handle_comment(struct nvram_ - { - char *eoc, *sol; - -- sol = (char *)&nvp->fwnv->data[nvp->pos]; -+ sol = (char *)&nvp->data[nvp->pos]; - eoc = strchr(sol, '\n'); - if (!eoc) { - eoc = strchr(sol, '\0'); -@@ -201,17 +201,17 @@ static enum nvram_parser_state - }; - - static int brcmf_init_nvram_parser(struct nvram_parser *nvp, -- const struct firmware *nv) -+ const u8 *data, size_t data_len) - { - size_t size; - - memset(nvp, 0, sizeof(*nvp)); -- nvp->fwnv = nv; -+ nvp->data = data; - /* Limit size to MAX_NVRAM_SIZE, some files contain lot of comment */ -- if (nv->size > BRCMF_FW_MAX_NVRAM_SIZE) -+ if (data_len > BRCMF_FW_MAX_NVRAM_SIZE) - size = BRCMF_FW_MAX_NVRAM_SIZE; - else -- size = nv->size; -+ size = data_len; - /* Alloc for extra 0 byte + roundup by 4 + length field */ - size += 1 + 3 + sizeof(u32); - nvp->nvram = kzalloc(size, GFP_KERNEL); -@@ -362,18 +362,18 @@ fail: - * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. - * End of buffer is completed with token identifying length of buffer. - */ --static void *brcmf_fw_nvram_strip(const struct firmware *nv, u32 *new_length, -- u16 domain_nr, u16 bus_nr) -+static void *brcmf_fw_nvram_strip(const u8 *data, size_t data_len, -+ u32 *new_length, u16 domain_nr, u16 bus_nr) - { - struct nvram_parser nvp; - u32 pad; - u32 token; - __le32 token_le; - -- if (brcmf_init_nvram_parser(&nvp, nv) < 0) -+ if (brcmf_init_nvram_parser(&nvp, data, data_len) < 0) - return NULL; - -- while (nvp.pos < nv->size) { -+ while (nvp.pos < data_len) { - nvp.state = nv_parser_states[nvp.state](&nvp); - if (nvp.state == END) - break; -@@ -432,7 +432,7 @@ static void brcmf_fw_request_nvram_done( - goto fail; - - if (fw) { -- nvram = brcmf_fw_nvram_strip(fw, &nvram_length, -+ nvram = brcmf_fw_nvram_strip(fw->data, fw->size, &nvram_length, - fwctx->domain_nr, fwctx->bus_nr); - release_firmware(fw); - if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL)) diff --git a/package/kernel/mac80211/patches/383-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch b/package/kernel/mac80211/patches/383-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch deleted file mode 100644 index 4ecef3b5af..0000000000 --- a/package/kernel/mac80211/patches/383-b43-fix-support-for-14e4-4321-PCI-dev-with-BCM4321-c.patch +++ /dev/null @@ -1,32 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 6 Jun 2015 22:45:59 +0200 -Subject: [PATCH] b43: fix support for 14e4:4321 PCI dev with BCM4321 chipset -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It seems Broadcom released two devices with conflicting device id. There -are for sure 14e4:4321 PCI devices with BCM4321 (N-PHY) chipset, they -can be found in routers, e.g. Netgear WNR834Bv2. However, according to -Broadcom public sources 0x4321 is also used for 5 GHz BCM4306 (G-PHY). -It's unsure if they meant PCI device id, or "virtual" id (from SPROM). -To distinguish these devices lets check PHY type (G vs. N). - -Signed-off-by: Rafał Miłecki -Cc: # 3.16+ -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/b43/main.c -+++ b/drivers/net/wireless/b43/main.c -@@ -5365,6 +5365,10 @@ static void b43_supported_bands(struct b - *have_5ghz_phy = true; - return; - case 0x4321: /* BCM4306 */ -+ /* There are 14e4:4321 PCI devs with 2.4 GHz BCM4321 (N-PHY) */ -+ if (dev->phy.type != B43_PHYTYPE_G) -+ break; -+ /* fall through */ - case 0x4313: /* BCM4311 */ - case 0x431a: /* BCM4318 */ - case 0x432a: /* BCM4321 */ diff --git a/package/kernel/mac80211/patches/384-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/384-ath9k-force-rx_clear-when-disabling-rx.patch deleted file mode 100644 index bddb15ad1a..0000000000 --- a/package/kernel/mac80211/patches/384-ath9k-force-rx_clear-when-disabling-rx.patch +++ /dev/null @@ -1,31 +0,0 @@ -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 - -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/mac.c -+++ b/drivers/net/wireless/ath/ath9k/mac.c -@@ -677,13 +677,15 @@ 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); -+ REG_SET_BIT(ah, AR_DIAG_SW, -+ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); - - ath9k_hw_disable_mib_counters(ah); - } diff --git a/package/kernel/mac80211/patches/385-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch b/package/kernel/mac80211/patches/385-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch deleted file mode 100644 index 74df9f93f7..0000000000 --- a/package/kernel/mac80211/patches/385-0001-brcmfmac-Update-msgbuf-read-pointer-quicker.patch +++ /dev/null @@ -1,109 +0,0 @@ -From: Hante Meuleman -Date: Mon, 8 Jun 2015 14:38:32 +0200 -Subject: [PATCH] brcmfmac: Update msgbuf read pointer quicker. - -On device to host data using msgbuf the read pointer gets updated -once all data is processed. Updating this pointer more frequently -allows the firmware to add more data quicker. This will result in -slightly higher and more stable throughput on CPU bounded host -processors. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.c -@@ -223,8 +223,6 @@ void brcmf_commonring_write_cancel(struc - void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, - u16 *n_items) - { -- void *ret_addr; -- - if (commonring->cr_update_wptr) - commonring->cr_update_wptr(commonring->cr_ctx); - -@@ -235,19 +233,18 @@ void *brcmf_commonring_get_read_ptr(stru - if (*n_items == 0) - return NULL; - -- ret_addr = commonring->buf_addr + -- (commonring->r_ptr * commonring->item_len); -- -- commonring->r_ptr += *n_items; -- if (commonring->r_ptr == commonring->depth) -- commonring->r_ptr = 0; -- -- return ret_addr; -+ return commonring->buf_addr + -+ (commonring->r_ptr * commonring->item_len); - } - - --int brcmf_commonring_read_complete(struct brcmf_commonring *commonring) -+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, -+ u16 n_items) - { -+ commonring->r_ptr += n_items; -+ if (commonring->r_ptr == commonring->depth) -+ commonring->r_ptr = 0; -+ - if (commonring->cr_write_rptr) - return commonring->cr_write_rptr(commonring->cr_ctx); - ---- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h -@@ -62,7 +62,8 @@ void brcmf_commonring_write_cancel(struc - u16 n_items); - void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring, - u16 *n_items); --int brcmf_commonring_read_complete(struct brcmf_commonring *commonring); -+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring, -+ u16 n_items); - - #define brcmf_commonring_n_items(commonring) (commonring->depth) - #define brcmf_commonring_len_item(commonring) (commonring->item_len) ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -75,6 +75,8 @@ - - #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 96 - #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32 -+#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS 48 -+ - - struct msgbuf_common_hdr { - u8 msgtype; -@@ -1257,19 +1259,27 @@ static void brcmf_msgbuf_process_rx(stru - { - void *buf; - u16 count; -+ u16 processed; - - again: - buf = brcmf_commonring_get_read_ptr(commonring, &count); - if (buf == NULL) - return; - -+ processed = 0; - while (count) { - brcmf_msgbuf_process_msgtype(msgbuf, - buf + msgbuf->rx_dataoffset); - buf += brcmf_commonring_len_item(commonring); -+ processed++; -+ if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) { -+ brcmf_commonring_read_complete(commonring, processed); -+ processed = 0; -+ } - count--; - } -- brcmf_commonring_read_complete(commonring); -+ if (processed) -+ brcmf_commonring_read_complete(commonring, processed); - - if (commonring->r_ptr == 0) - goto again; diff --git a/package/kernel/mac80211/patches/385-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch b/package/kernel/mac80211/patches/385-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch deleted file mode 100644 index 9e5b48608d..0000000000 --- a/package/kernel/mac80211/patches/385-0002-brcmfmac-remove-chipinfo-debugfs-entry.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Arend van Spriel -Date: Mon, 8 Jun 2015 14:38:33 +0200 -Subject: [PATCH] brcmfmac: remove chipinfo debugfs entry - -The information provided by chipinfo is also provided by the -revinfo debugfs entry. Removing it from debugfs. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c -@@ -41,15 +41,6 @@ void brcmf_debugfs_exit(void) - root_folder = NULL; - } - --static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data) --{ -- struct brcmf_bus *bus = dev_get_drvdata(seq->private); -- -- seq_printf(seq, "chip: %x(%u) rev %u\n", -- bus->chip, bus->chip, bus->chiprev); -- return 0; --} -- - int brcmf_debugfs_attach(struct brcmf_pub *drvr) - { - struct device *dev = drvr->bus_if->dev; -@@ -58,7 +49,6 @@ int brcmf_debugfs_attach(struct brcmf_pu - return -ENODEV; - - drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); -- brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read); - - return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); - } diff --git a/package/kernel/mac80211/patches/385-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch b/package/kernel/mac80211/patches/385-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch deleted file mode 100644 index c38b2cd150..0000000000 --- a/package/kernel/mac80211/patches/385-0003-brcmfmac-remove-watchdog-reset-from-brcmf_pcie_busco.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Arend van Spriel -Date: Mon, 8 Jun 2015 14:38:34 +0200 -Subject: [PATCH] brcmfmac: remove watchdog reset from - brcmf_pcie_buscoreprep() - -The watchdog reset as done in brcmf_pcie_buscoreprep() is not -sufficient. It needs to modify PCIe core registers as well -which is properly done by brcmf_pcie_reset_device() after the -chip recognition is done. So the faulty watchdog reset can be -removed as it was causing driver reload to fail and hang the -system requiring a power-cycle. Instead the call to to the -brcmf_pcie_reset_device() function is done twice in the unload. - -Reviewed-by: Hante Meuleman -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -1629,20 +1629,7 @@ static void brcmf_pcie_buscore_write32(v - - static int brcmf_pcie_buscoreprep(void *ctx) - { -- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; -- int err; -- -- err = brcmf_pcie_get_resource(devinfo); -- if (err == 0) { -- /* Set CC watchdog to reset all the cores on the chip to bring -- * back dongle to a sane state. -- */ -- brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE, -- watchdog), 4); -- msleep(100); -- } -- -- return err; -+ return brcmf_pcie_get_resource(ctx); - } - - -@@ -1824,6 +1811,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) - brcmf_pcie_intr_disable(devinfo); - - brcmf_detach(&pdev->dev); -+ brcmf_pcie_reset_device(devinfo); - - kfree(bus->bus_priv.pcie); - kfree(bus->msgbuf->flowrings); diff --git a/package/kernel/mac80211/patches/385-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch b/package/kernel/mac80211/patches/385-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch deleted file mode 100644 index 756fbb2cb7..0000000000 --- a/package/kernel/mac80211/patches/385-0004-brcmfmac-use-debugfs_create_devm_seqfile-helper-func.patch +++ /dev/null @@ -1,69 +0,0 @@ -From: Arend van Spriel -Date: Mon, 8 Jun 2015 14:38:35 +0200 -Subject: [PATCH] brcmfmac: use debugfs_create_devm_seqfile() helper - function - -Some time ago the function debugfs_create_devm_seqfile() was -introduced in debugfs. The caller simply needs to provide a -device pointer and read function. The function brcmf_debugfs_add_entry() -is now simply a wrapper only doing the work for CONFIG_BRCMDBG. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c -@@ -64,44 +64,12 @@ struct dentry *brcmf_debugfs_get_devdir( - return drvr->dbgfs_dir; - } - --struct brcmf_debugfs_entry { -- int (*read)(struct seq_file *seq, void *data); -- struct brcmf_pub *drvr; --}; -- --static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f) --{ -- struct brcmf_debugfs_entry *entry = inode->i_private; -- -- return single_open(f, entry->read, entry->drvr->bus_if->dev); --} -- --static const struct file_operations brcmf_debugfs_def_ops = { -- .owner = THIS_MODULE, -- .open = brcmf_debugfs_entry_open, -- .release = single_release, -- .read = seq_read, -- .llseek = seq_lseek --}; -- - int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, - int (*read_fn)(struct seq_file *seq, void *data)) - { -- struct dentry *dentry = drvr->dbgfs_dir; -- struct brcmf_debugfs_entry *entry; -- -- if (IS_ERR_OR_NULL(dentry)) -- return -ENOENT; -- -- entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL); -- if (!entry) -- return -ENOMEM; -- -- entry->read = read_fn; -- entry->drvr = drvr; -- -- dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry, -- &brcmf_debugfs_def_ops); -+ struct dentry *e; - -- return PTR_ERR_OR_ZERO(dentry); -+ e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn, -+ drvr->dbgfs_dir, read_fn); -+ return PTR_ERR_OR_ZERO(e); - } diff --git a/package/kernel/mac80211/patches/385-ath9k_hw-fix-device-ID-check-for-AR956x.patch b/package/kernel/mac80211/patches/385-ath9k_hw-fix-device-ID-check-for-AR956x.patch deleted file mode 100644 index 2674efb91f..0000000000 --- a/package/kernel/mac80211/patches/385-ath9k_hw-fix-device-ID-check-for-AR956x.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Date: Sun, 21 Jun 2015 19:45:59 +0200 -Subject: [PATCH] ath9k_hw: fix device ID check for AR956x - -Because of the missing return, the macVersion value was being -overwritten with an invalid register read - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -278,6 +278,7 @@ static void ath9k_hw_read_revisions(stru - return; - case AR9300_DEVID_QCA956X: - ah->hw_version.macVersion = AR_SREV_VERSION_9561; -+ return; - } - - val = REG_READ(ah, AR_SREV) & AR_SREV_ID; diff --git a/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch b/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch deleted file mode 100644 index ff24a4a06f..0000000000 --- a/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Pontus Fuchs -Date: Thu, 11 Jun 2015 00:12:17 +0200 -Subject: [PATCH] brcmfmac: Check if firmware supports p2p - -Add a feature flag to reflect the firmware's p2p capability. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Reviewed-by: Arend Van Spriel -Signed-off-by: Pontus Fuchs -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c -@@ -129,6 +129,7 @@ void brcmf_feat_attach(struct brcmf_pub - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); - if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) - brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); -+ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p"); - - /* set chip related quirks */ - switch (drvr->bus_if->chip) { ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h -@@ -23,12 +23,14 @@ - * MCHAN: multi-channel for concurrent P2P. - * PNO: preferred network offload. - * WOWL: Wake-On-WLAN. -+ * P2P: peer-to-peer - */ - #define BRCMF_FEAT_LIST \ - BRCMF_FEAT_DEF(MBSS) \ - BRCMF_FEAT_DEF(MCHAN) \ - BRCMF_FEAT_DEF(PNO) \ -- BRCMF_FEAT_DEF(WOWL) -+ BRCMF_FEAT_DEF(WOWL) \ -+ BRCMF_FEAT_DEF(P2P) - /* - * Quirks: - * diff --git a/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch b/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch deleted file mode 100644 index 3876ba01da..0000000000 --- a/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch +++ /dev/null @@ -1,198 +0,0 @@ -From: Pontus Fuchs -Date: Thu, 11 Jun 2015 00:12:18 +0200 -Subject: [PATCH] brcmfmac: Build wiphy mode and interface combinations - dynamically - -Switch from using semi hard coded interface combinations. This makes -it easier to announce what the firmware actually supports. This fixes -the case where brcmfmac announces p2p but the firmware doesn't -support it. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Reviewed-by: Arend Van Spriel -Signed-off-by: Pontus Fuchs -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -52,8 +52,6 @@ - #define BRCMF_PNO_SCAN_COMPLETE 1 - #define BRCMF_PNO_SCAN_INCOMPLETE 0 - --#define BRCMF_IFACE_MAX_CNT 3 -- - #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ - #define WPA_OUI_TYPE 1 - #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ -@@ -5639,53 +5637,6 @@ static int brcmf_setup_wiphybands(struct - return 0; - } - --static const struct ieee80211_iface_limit brcmf_iface_limits_mbss[] = { -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_ADHOC) -- }, -- { -- .max = 4, -- .types = BIT(NL80211_IFTYPE_AP) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) -- } --}; -- --static const struct ieee80211_iface_limit brcmf_iface_limits_sbss[] = { -- { -- .max = 2, -- .types = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_ADHOC) | -- BIT(NL80211_IFTYPE_AP) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) -- } --}; --static struct ieee80211_iface_combination brcmf_iface_combos[] = { -- { -- .max_interfaces = BRCMF_IFACE_MAX_CNT, -- .num_different_channels = 1, -- .n_limits = ARRAY_SIZE(brcmf_iface_limits_sbss), -- .limits = brcmf_iface_limits_sbss, -- } --}; -- - static const struct ieee80211_txrx_stypes - brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { - [NL80211_IFTYPE_STATION] = { -@@ -5715,6 +5666,67 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = - } - }; - -+static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) -+{ -+ struct ieee80211_iface_combination *combo = NULL; -+ struct ieee80211_iface_limit *limits = NULL; -+ int i = 0, max_iface_cnt; -+ -+ combo = kzalloc(sizeof(*combo), GFP_KERNEL); -+ if (!combo) -+ goto err; -+ -+ limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL); -+ if (!limits) -+ goto err; -+ -+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | -+ BIT(NL80211_IFTYPE_ADHOC) | -+ BIT(NL80211_IFTYPE_AP); -+ -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) -+ combo->num_different_channels = 2; -+ else -+ combo->num_different_channels = 1; -+ -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { -+ limits[i].max = 1; -+ limits[i++].types = BIT(NL80211_IFTYPE_STATION); -+ limits[i].max = 4; -+ limits[i++].types = BIT(NL80211_IFTYPE_AP); -+ max_iface_cnt = 5; -+ } else { -+ limits[i].max = 2; -+ limits[i++].types = BIT(NL80211_IFTYPE_STATION) | -+ BIT(NL80211_IFTYPE_AP); -+ max_iface_cnt = 2; -+ } -+ -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) { -+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) | -+ BIT(NL80211_IFTYPE_P2P_DEVICE); -+ limits[i].max = 1; -+ limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO); -+ limits[i].max = 1; -+ limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); -+ max_iface_cnt += 2; -+ } -+ combo->max_interfaces = max_iface_cnt; -+ combo->limits = limits; -+ combo->n_limits = i; -+ -+ wiphy->iface_combinations = combo; -+ wiphy->n_iface_combinations = 1; -+ return 0; -+ -+err: -+ kfree(limits); -+ kfree(combo); -+ return -ENOMEM; -+} -+ - static void brcmf_wiphy_pno_params(struct wiphy *wiphy) - { - /* scheduled scan settings */ -@@ -5745,7 +5757,6 @@ static void brcmf_wiphy_wowl_params(stru - static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) - { - struct ieee80211_supported_band *band; -- struct ieee80211_iface_combination ifc_combo; - __le32 bandlist[3]; - u32 n_bands; - int err, i; -@@ -5753,24 +5764,11 @@ static int brcmf_setup_wiphy(struct wiph - wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; - wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; - wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; -- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_ADHOC) | -- BIT(NL80211_IFTYPE_AP) | -- BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO) | -- BIT(NL80211_IFTYPE_P2P_DEVICE); -- /* need VSDB firmware feature for concurrent channels */ -- ifc_combo = brcmf_iface_combos[0]; -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) -- ifc_combo.num_different_channels = 2; -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { -- ifc_combo.n_limits = ARRAY_SIZE(brcmf_iface_limits_mbss), -- ifc_combo.limits = brcmf_iface_limits_mbss; -- } -- wiphy->iface_combinations = kmemdup(&ifc_combo, -- sizeof(ifc_combo), -- GFP_KERNEL); -- wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); -+ -+ err = brcmf_setup_ifmodes(wiphy, ifp); -+ if (err) -+ return err; -+ - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->cipher_suites = __wl_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); -@@ -6035,6 +6033,8 @@ static void brcmf_free_wiphy(struct wiph - if (!wiphy) - return; - -+ if (wiphy->iface_combinations) -+ kfree(wiphy->iface_combinations->limits); - kfree(wiphy->iface_combinations); - if (wiphy->bands[IEEE80211_BAND_2GHZ]) { - kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch b/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch deleted file mode 100644 index 7bd06869da..0000000000 --- a/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch +++ /dev/null @@ -1,326 +0,0 @@ -From: Arend van Spriel -Date: Thu, 11 Jun 2015 00:12:19 +0200 -Subject: [PATCH] brcmfmac: rework .get_station() callback - -The .get_station() cfg80211 callback is used in several scenarios. In -managed mode it can obtain information about the access-point and its -BSS parameters. In managed mode it can also obtain information about -TDLS peers. In AP mode it can obtain information about connected -clients. - -Reviewed-by: Hante Meuleman -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -2395,27 +2395,80 @@ brcmf_cfg80211_reconfigure_wep(struct br - brcmf_err("set wsec error (%d)\n", err); - } - -+static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si) -+{ -+ struct nl80211_sta_flag_update *sfu; -+ -+ brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags); -+ si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS); -+ sfu = &si->sta_flags; -+ sfu->mask = BIT(NL80211_STA_FLAG_WME) | -+ BIT(NL80211_STA_FLAG_AUTHENTICATED) | -+ BIT(NL80211_STA_FLAG_ASSOCIATED) | -+ BIT(NL80211_STA_FLAG_AUTHORIZED); -+ if (fw_sta_flags & BRCMF_STA_WME) -+ sfu->set |= BIT(NL80211_STA_FLAG_WME); -+ if (fw_sta_flags & BRCMF_STA_AUTHE) -+ sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); -+ if (fw_sta_flags & BRCMF_STA_ASSOC) -+ sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED); -+ if (fw_sta_flags & BRCMF_STA_AUTHO) -+ sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED); -+} -+ -+static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si) -+{ -+ struct { -+ __le32 len; -+ struct brcmf_bss_info_le bss_le; -+ } *buf; -+ u16 capability; -+ int err; -+ -+ buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); -+ if (!buf) -+ return; -+ -+ buf->len = cpu_to_le32(WL_BSS_INFO_MAX); -+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf, -+ WL_BSS_INFO_MAX); -+ if (err) { -+ brcmf_err("Failed to get bss info (%d)\n", err); -+ return; -+ } -+ si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); -+ si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period); -+ si->bss_param.dtim_period = buf->bss_le.dtim_period; -+ capability = le16_to_cpu(buf->bss_le.capability); -+ if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT) -+ si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; -+ if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE) -+ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; -+ if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) -+ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; -+} -+ - static s32 - brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, - const u8 *mac, struct station_info *sinfo) - { - struct brcmf_if *ifp = netdev_priv(ndev); -- struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; -- struct brcmf_scb_val_le scb_val; -- int rssi; -- s32 rate; - s32 err = 0; -- u8 *bssid = profile->bssid; - struct brcmf_sta_info_le sta_info_le; -- u32 beacon_period; -- u32 dtim_period; -+ u32 sta_flags; -+ u32 is_tdls_peer; - - brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac); - if (!check_vif_up(ifp->vif)) - return -EIO; - -- if (brcmf_is_apmode(ifp->vif)) { -- memcpy(&sta_info_le, mac, ETH_ALEN); -+ memset(&sta_info_le, 0, sizeof(sta_info_le)); -+ memcpy(&sta_info_le, mac, ETH_ALEN); -+ err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info", -+ &sta_info_le, -+ sizeof(sta_info_le)); -+ is_tdls_peer = !err; -+ if (err) { - err = brcmf_fil_iovar_data_get(ifp, "sta_info", - &sta_info_le, - sizeof(sta_info_le)); -@@ -2423,73 +2476,48 @@ brcmf_cfg80211_get_station(struct wiphy - brcmf_err("GET STA INFO failed, %d\n", err); - goto done; - } -- sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); -- sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; -- if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { -- sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); -- sinfo->connected_time = le32_to_cpu(sta_info_le.in); -- } -- brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", -- sinfo->inactive_time, sinfo->connected_time); -- } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) { -- if (memcmp(mac, bssid, ETH_ALEN)) { -- brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", -- mac, bssid); -- err = -ENOENT; -- goto done; -- } -- /* Report the current tx rate */ -- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); -- if (err) { -- brcmf_err("Could not get rate (%d)\n", err); -- goto done; -- } else { -+ } -+ brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver)); -+ sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); -+ sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; -+ sta_flags = le32_to_cpu(sta_info_le.flags); -+ brcmf_convert_sta_flags(sta_flags, sinfo); -+ sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER); -+ if (is_tdls_peer) -+ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); -+ else -+ sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); -+ if (sta_flags & BRCMF_STA_ASSOC) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); -+ sinfo->connected_time = le32_to_cpu(sta_info_le.in); -+ brcmf_fill_bss_param(ifp, sinfo); -+ } -+ if (sta_flags & BRCMF_STA_SCBSTATS) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); -+ sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures); -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); -+ sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts); -+ sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts); -+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); -+ sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts); -+ sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts); -+ if (sinfo->tx_packets) { - sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); -- sinfo->txrate.legacy = rate * 5; -- brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); -+ sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate); -+ sinfo->txrate.legacy /= 100; - } -- -- if (test_bit(BRCMF_VIF_STATUS_CONNECTED, -- &ifp->vif->sme_state)) { -- memset(&scb_val, 0, sizeof(scb_val)); -- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, -- &scb_val, sizeof(scb_val)); -- if (err) { -- brcmf_err("Could not get rssi (%d)\n", err); -- goto done; -- } else { -- rssi = le32_to_cpu(scb_val.val); -- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); -- sinfo->signal = rssi; -- brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); -- } -- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD, -- &beacon_period); -- if (err) { -- brcmf_err("Could not get beacon period (%d)\n", -- err); -- goto done; -- } else { -- sinfo->bss_param.beacon_interval = -- beacon_period; -- brcmf_dbg(CONN, "Beacon peroid %d\n", -- beacon_period); -- } -- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD, -- &dtim_period); -- if (err) { -- brcmf_err("Could not get DTIM period (%d)\n", -- err); -- goto done; -- } else { -- sinfo->bss_param.dtim_period = dtim_period; -- brcmf_dbg(CONN, "DTIM peroid %d\n", -- dtim_period); -- } -- sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); -+ if (sinfo->rx_packets) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); -+ sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate); -+ sinfo->rxrate.legacy /= 100; -+ } -+ if (le16_to_cpu(sta_info_le.ver) >= 4) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES); -+ sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes); -+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES); -+ sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes); - } -- } else -- err = -EPERM; -+ } - done: - brcmf_dbg(TRACE, "Exit\n"); - return err; ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h -@@ -32,7 +32,11 @@ - #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ - #define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 - --#define BRCMF_STA_ASSOC 0x10 /* Associated */ -+#define BRCMF_STA_WME 0x00000002 /* WMM association */ -+#define BRCMF_STA_AUTHE 0x00000008 /* Authenticated */ -+#define BRCMF_STA_ASSOC 0x00000010 /* Associated */ -+#define BRCMF_STA_AUTHO 0x00000020 /* Authorized */ -+#define BRCMF_STA_SCBSTATS 0x00004000 /* Per STA debug stats */ - - /* size of brcmf_scan_params not including variable length array */ - #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 -@@ -113,6 +117,7 @@ - #define BRCMF_WOWL_MAXPATTERNSIZE 128 - - #define BRCMF_COUNTRY_BUF_SZ 4 -+#define BRCMF_ANT_MAX 4 - - /* join preference types for join_pref iovar */ - enum brcmf_join_pref_types { -@@ -456,25 +461,61 @@ struct brcmf_channel_info_le { - }; - - struct brcmf_sta_info_le { -- __le16 ver; /* version of this struct */ -- __le16 len; /* length in bytes of this structure */ -- __le16 cap; /* sta's advertised capabilities */ -- __le32 flags; /* flags defined below */ -- __le32 idle; /* time since data pkt rx'd from sta */ -- u8 ea[ETH_ALEN]; /* Station address */ -- __le32 count; /* # rates in this set */ -- u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ -+ __le16 ver; /* version of this struct */ -+ __le16 len; /* length in bytes of this structure */ -+ __le16 cap; /* sta's advertised capabilities */ -+ __le32 flags; /* flags defined below */ -+ __le32 idle; /* time since data pkt rx'd from sta */ -+ u8 ea[ETH_ALEN]; /* Station address */ -+ __le32 count; /* # rates in this set */ -+ u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ - /* w/hi bit set if basic */ -- __le32 in; /* seconds elapsed since associated */ -- __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ -- __le32 tx_pkts; /* # of packets transmitted */ -- __le32 tx_failures; /* # of packets failed */ -- __le32 rx_ucast_pkts; /* # of unicast packets received */ -- __le32 rx_mcast_pkts; /* # of multicast packets received */ -- __le32 tx_rate; /* Rate of last successful tx frame */ -- __le32 rx_rate; /* Rate of last successful rx frame */ -- __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ -- __le32 rx_decrypt_failures; /* # of packet decrypted failed */ -+ __le32 in; /* seconds elapsed since associated */ -+ __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ -+ __le32 tx_pkts; /* # of packets transmitted */ -+ __le32 tx_failures; /* # of packets failed */ -+ __le32 rx_ucast_pkts; /* # of unicast packets received */ -+ __le32 rx_mcast_pkts; /* # of multicast packets received */ -+ __le32 tx_rate; /* Rate of last successful tx frame */ -+ __le32 rx_rate; /* Rate of last successful rx frame */ -+ __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ -+ __le32 rx_decrypt_failures; /* # of packet decrypted failed */ -+ __le32 tx_tot_pkts; /* # of tx pkts (ucast + mcast) */ -+ __le32 rx_tot_pkts; /* # of data packets recvd (uni + mcast) */ -+ __le32 tx_mcast_pkts; /* # of mcast pkts txed */ -+ __le64 tx_tot_bytes; /* data bytes txed (ucast + mcast) */ -+ __le64 rx_tot_bytes; /* data bytes recvd (ucast + mcast) */ -+ __le64 tx_ucast_bytes; /* data bytes txed (ucast) */ -+ __le64 tx_mcast_bytes; /* # data bytes txed (mcast) */ -+ __le64 rx_ucast_bytes; /* data bytes recvd (ucast) */ -+ __le64 rx_mcast_bytes; /* data bytes recvd (mcast) */ -+ s8 rssi[BRCMF_ANT_MAX]; /* per antenna rssi */ -+ s8 nf[BRCMF_ANT_MAX]; /* per antenna noise floor */ -+ __le16 aid; /* association ID */ -+ __le16 ht_capabilities; /* advertised ht caps */ -+ __le16 vht_flags; /* converted vht flags */ -+ __le32 tx_pkts_retry_cnt; /* # of frames where a retry was -+ * exhausted. -+ */ -+ __le32 tx_pkts_retry_exhausted; /* # of user frames where a retry -+ * was exhausted -+ */ -+ s8 rx_lastpkt_rssi[BRCMF_ANT_MAX]; /* Per antenna RSSI of last -+ * received data frame. -+ */ -+ /* TX WLAN retry/failure statistics: -+ * Separated for host requested frames and locally generated frames. -+ * Include unicast frame only where the retries/failures can be counted. -+ */ -+ __le32 tx_pkts_total; /* # user frames sent successfully */ -+ __le32 tx_pkts_retries; /* # user frames retries */ -+ __le32 tx_pkts_fw_total; /* # FW generated sent successfully */ -+ __le32 tx_pkts_fw_retries; /* # retries for FW generated frames */ -+ __le32 tx_pkts_fw_retry_exhausted; /* # FW generated where a retry -+ * was exhausted -+ */ -+ __le32 rx_pkts_retried; /* # rx with retry bit set */ -+ __le32 tx_rate_fallback; /* lowest fallback TX rate */ - }; - - struct brcmf_chanspec_list { diff --git a/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch b/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch deleted file mode 100644 index 302bc3ed15..0000000000 --- a/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Arend van Spriel -Date: Thu, 11 Jun 2015 00:12:20 +0200 -Subject: [PATCH] brcmfmac: have sdio return -EIO when device communication - is not possible - -The bus interface functions txctl and rxctl may be used while the device -can not be accessed, eg. upon driver .remove() callback. This patch will -immediately return -EIO when this is the case which speeds up the module -unload. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -988,6 +988,7 @@ static void brcmf_sdiod_freezer_detach(s - - static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) - { -+ sdiodev->state = BRCMF_SDIOD_DOWN; - if (sdiodev->bus) { - brcmf_sdio_remove(sdiodev->bus); - sdiodev->bus = NULL; ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -2820,6 +2820,8 @@ static int brcmf_sdio_bus_txdata(struct - struct brcmf_sdio *bus = sdiodev->bus; - - brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len); -+ if (sdiodev->state != BRCMF_SDIOD_DATA) -+ return -EIO; - - /* Add space for the header */ - skb_push(pkt, bus->tx_hdrlen); -@@ -2948,6 +2950,8 @@ brcmf_sdio_bus_txctl(struct device *dev, - int ret; - - brcmf_dbg(TRACE, "Enter\n"); -+ if (sdiodev->state != BRCMF_SDIOD_DATA) -+ return -EIO; - - /* Send from dpc */ - bus->ctrl_frame_buf = msg; -@@ -3238,6 +3242,8 @@ brcmf_sdio_bus_rxctl(struct device *dev, - struct brcmf_sdio *bus = sdiodev->bus; - - brcmf_dbg(TRACE, "Enter\n"); -+ if (sdiodev->state != BRCMF_SDIOD_DATA) -+ return -EIO; - - /* Wait until control frame is available */ - timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending); diff --git a/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch b/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch deleted file mode 100644 index 34af6d2acf..0000000000 --- a/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Felix Fietkau -Date: Thu, 2 Jul 2015 13:35:05 +0200 -Subject: [PATCH] ath9k: make DMA stop related messages debug-only - -A long time ago, ath9k had issues during reset where the DMA engine -would stay active and could potentially corrupt memory. -To debug those issues, the driver would print warnings whenever they -occur. - -Nowadays, these issues are gone and the primary cause of these messages -is if the MAC is stuck during reset or busy processing a long -transmission. This is fairly harmless, yet these messages continue to -worry users. - -To reduce the number of bogus bug reports, turn these messages into -debug messages and count their occurence in the "reset" debugfs file. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -765,6 +765,8 @@ static int read_file_reset(struct seq_fi - [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", - [RESET_TYPE_MCI] = "MCI Reset", - [RESET_TYPE_CALIBRATION] = "Calibration error", -+ [RESET_TX_DMA_ERROR] = "Tx DMA stop error", -+ [RESET_RX_DMA_ERROR] = "Rx DMA stop error", - }; - int i; - ---- a/drivers/net/wireless/ath/ath9k/debug.h -+++ b/drivers/net/wireless/ath/ath9k/debug.h -@@ -50,6 +50,8 @@ enum ath_reset_type { - RESET_TYPE_BEACON_STUCK, - RESET_TYPE_MCI, - RESET_TYPE_CALIBRATION, -+ RESET_TX_DMA_ERROR, -+ RESET_RX_DMA_ERROR, - __RESET_TYPE_MAX - }; - ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -496,10 +496,9 @@ bool ath_stoprecv(struct ath_softc *sc) - - if (!(ah->ah_flags & AH_UNPLUGGED) && - unlikely(!stopped)) { -- ath_err(ath9k_hw_common(sc->sc_ah), -- "Could not stop RX, we could be " -- "confusing the DMA engine when we start RX up\n"); -- ATH_DBG_WARN_ON_ONCE(!stopped); -+ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, -+ "Failed to stop Rx DMA\n"); -+ RESET_STAT_INC(sc, RESET_RX_DMA_ERROR); - } - return stopped && !reset; - } ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -1896,8 +1896,11 @@ bool ath_drain_all_txq(struct ath_softc - npend |= BIT(i); - } - -- if (npend) -- ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend); -+ if (npend) { -+ RESET_STAT_INC(sc, RESET_TX_DMA_ERROR); -+ ath_dbg(common, RESET, -+ "Failed to stop TX DMA, queues=0x%03x!\n", npend); -+ } - - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (!ATH_TXQ_SETUP(sc, i)) diff --git a/package/kernel/mac80211/patches/389-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch b/package/kernel/mac80211/patches/389-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch deleted file mode 100644 index 06f2dce83f..0000000000 --- a/package/kernel/mac80211/patches/389-0006-brcmfmac-free-ifp-for-non-netdev-interface-in-p2p-mo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Arend van Spriel -Date: Thu, 11 Jun 2015 00:12:21 +0200 -Subject: [PATCH] brcmfmac: free ifp for non-netdev interface in p2p module - -Making it more clear by freeing the ifp in same place where the -vif object is freed. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -867,8 +867,6 @@ static void brcmf_del_if(struct brcmf_pu - } - /* unregister will take care of freeing it */ - unregister_netdev(ifp->ndev); -- } else { -- kfree(ifp); - } - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -@@ -2238,6 +2238,7 @@ static void brcmf_p2p_delete_p2pdev(stru - { - cfg80211_unregister_wdev(&vif->wdev); - p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; -+ kfree(vif->ifp); - brcmf_free_vif(vif); - } - -@@ -2361,6 +2362,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph - break; - - case NL80211_IFTYPE_P2P_DEVICE: -+ brcmf_p2p_cancel_remain_on_channel(vif->ifp); -+ brcmf_p2p_deinit_discovery(p2p); - brcmf_p2p_delete_p2pdev(p2p, vif); - return 0; - default: diff --git a/package/kernel/mac80211/patches/389-0007-brcmfmac-move-p2p-attach-detach-functions.patch b/package/kernel/mac80211/patches/389-0007-brcmfmac-move-p2p-attach-detach-functions.patch deleted file mode 100644 index 0a6e093512..0000000000 --- a/package/kernel/mac80211/patches/389-0007-brcmfmac-move-p2p-attach-detach-functions.patch +++ /dev/null @@ -1,225 +0,0 @@ -From: Arend van Spriel -Date: Thu, 11 Jun 2015 00:12:22 +0200 -Subject: [PATCH] brcmfmac: move p2p attach/detach functions - -Moving two functions in p2p.c as is so next change will be -easier to review. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -@@ -1908,105 +1908,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere - - - /** -- * brcmf_p2p_attach() - attach for P2P. -- * -- * @cfg: driver private data for cfg80211 interface. -- */ --s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg) --{ -- struct brcmf_if *pri_ifp; -- struct brcmf_if *p2p_ifp; -- struct brcmf_cfg80211_vif *p2p_vif; -- struct brcmf_p2p_info *p2p; -- struct brcmf_pub *drvr; -- s32 bssidx; -- s32 err = 0; -- -- p2p = &cfg->p2p; -- p2p->cfg = cfg; -- -- drvr = cfg->pub; -- -- pri_ifp = drvr->iflist[0]; -- p2p_ifp = drvr->iflist[1]; -- -- p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif; -- -- if (p2p_ifp) { -- p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE, -- false); -- if (IS_ERR(p2p_vif)) { -- brcmf_err("could not create discovery vif\n"); -- err = -ENOMEM; -- goto exit; -- } -- -- p2p_vif->ifp = p2p_ifp; -- p2p_ifp->vif = p2p_vif; -- p2p_vif->wdev.netdev = p2p_ifp->ndev; -- p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev; -- SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy)); -- -- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif; -- -- brcmf_p2p_generate_bss_mac(p2p, NULL); -- memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN); -- brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); -- -- /* Initialize P2P Discovery in the firmware */ -- err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); -- if (err < 0) { -- brcmf_err("set p2p_disc error\n"); -- brcmf_free_vif(p2p_vif); -- goto exit; -- } -- /* obtain bsscfg index for P2P discovery */ -- err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); -- if (err < 0) { -- brcmf_err("retrieving discover bsscfg index failed\n"); -- brcmf_free_vif(p2p_vif); -- goto exit; -- } -- /* Verify that firmware uses same bssidx as driver !! */ -- if (p2p_ifp->bssidx != bssidx) { -- brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", -- bssidx, p2p_ifp->bssidx); -- brcmf_free_vif(p2p_vif); -- goto exit; -- } -- -- init_completion(&p2p->send_af_done); -- INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler); -- init_completion(&p2p->afx_hdl.act_frm_scan); -- init_completion(&p2p->wait_next_af); -- } --exit: -- return err; --} -- -- --/** -- * brcmf_p2p_detach() - detach P2P. -- * -- * @p2p: P2P specific data. -- */ --void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) --{ -- struct brcmf_cfg80211_vif *vif; -- -- vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; -- if (vif != NULL) { -- brcmf_p2p_cancel_remain_on_channel(vif->ifp); -- brcmf_p2p_deinit_discovery(p2p); -- /* remove discovery interface */ -- brcmf_free_vif(vif); -- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; -- } -- /* just set it all to zero */ -- memset(p2p, 0, sizeof(*p2p)); --} -- --/** - * brcmf_p2p_get_current_chanspec() - Get current operation channel. - * - * @p2p: P2P specific data. -@@ -2425,3 +2326,102 @@ void brcmf_p2p_stop_device(struct wiphy - clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state); - mutex_unlock(&cfg->usr_sync); - } -+ -+/** -+ * brcmf_p2p_attach() - attach for P2P. -+ * -+ * @cfg: driver private data for cfg80211 interface. -+ */ -+s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg) -+{ -+ struct brcmf_if *pri_ifp; -+ struct brcmf_if *p2p_ifp; -+ struct brcmf_cfg80211_vif *p2p_vif; -+ struct brcmf_p2p_info *p2p; -+ struct brcmf_pub *drvr; -+ s32 bssidx; -+ s32 err = 0; -+ -+ p2p = &cfg->p2p; -+ p2p->cfg = cfg; -+ -+ drvr = cfg->pub; -+ -+ pri_ifp = drvr->iflist[0]; -+ p2p_ifp = drvr->iflist[1]; -+ -+ p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif; -+ -+ if (p2p_ifp) { -+ p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE, -+ false); -+ if (IS_ERR(p2p_vif)) { -+ brcmf_err("could not create discovery vif\n"); -+ err = -ENOMEM; -+ goto exit; -+ } -+ -+ p2p_vif->ifp = p2p_ifp; -+ p2p_ifp->vif = p2p_vif; -+ p2p_vif->wdev.netdev = p2p_ifp->ndev; -+ p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev; -+ SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy)); -+ -+ p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif; -+ -+ brcmf_p2p_generate_bss_mac(p2p, NULL); -+ memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN); -+ brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr); -+ -+ /* Initialize P2P Discovery in the firmware */ -+ err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); -+ if (err < 0) { -+ brcmf_err("set p2p_disc error\n"); -+ brcmf_free_vif(p2p_vif); -+ goto exit; -+ } -+ /* obtain bsscfg index for P2P discovery */ -+ err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); -+ if (err < 0) { -+ brcmf_err("retrieving discover bsscfg index failed\n"); -+ brcmf_free_vif(p2p_vif); -+ goto exit; -+ } -+ /* Verify that firmware uses same bssidx as driver !! */ -+ if (p2p_ifp->bssidx != bssidx) { -+ brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", -+ bssidx, p2p_ifp->bssidx); -+ brcmf_free_vif(p2p_vif); -+ goto exit; -+ } -+ -+ init_completion(&p2p->send_af_done); -+ INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler); -+ init_completion(&p2p->afx_hdl.act_frm_scan); -+ init_completion(&p2p->wait_next_af); -+ } -+exit: -+ return err; -+} -+ -+/** -+ * brcmf_p2p_detach() - detach P2P. -+ * -+ * @p2p: P2P specific data. -+ */ -+void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) -+{ -+ struct brcmf_cfg80211_vif *vif; -+ -+ vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; -+ if (vif != NULL) { -+ brcmf_p2p_cancel_remain_on_channel(vif->ifp); -+ brcmf_p2p_deinit_discovery(p2p); -+ /* remove discovery interface */ -+ brcmf_free_vif(vif); -+ p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; -+ } -+ /* just set it all to zero */ -+ memset(p2p, 0, sizeof(*p2p)); -+} -+ diff --git a/package/kernel/mac80211/patches/389-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch b/package/kernel/mac80211/patches/389-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch deleted file mode 100644 index 72e8eed61b..0000000000 --- a/package/kernel/mac80211/patches/389-0008-brcmfmac-assure-p2pdev-is-unregistered-upon-driver-u.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Arend van Spriel -Date: Thu, 11 Jun 2015 00:12:23 +0200 -Subject: [PATCH] brcmfmac: assure p2pdev is unregistered upon driver - unload - -When unloading the driver with a p2pdev interface it resulted in -a warning upon calling wiphy_unregister() and subsequently a crash -in the driver. This patch assures the p2pdev is unregistered calling -unregister_wdev() before doing the wiphy_unregister(). - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -6206,10 +6206,8 @@ void brcmf_cfg80211_detach(struct brcmf_ - if (!cfg) - return; - -- WARN_ON(!list_empty(&cfg->vif_list)); -- wiphy_unregister(cfg->wiphy); - brcmf_btcoex_detach(cfg); -- brcmf_p2p_detach(&cfg->p2p); -+ wiphy_unregister(cfg->wiphy); - wl_deinit_priv(cfg); - brcmf_free_wiphy(cfg->wiphy); - } ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -1098,6 +1098,7 @@ void brcmf_detach(struct device *dev) - - /* stop firmware event handling */ - brcmf_fweh_detach(drvr); -+ brcmf_p2p_detach(&drvr->config->p2p); - - brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); - ---- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -2418,8 +2419,9 @@ void brcmf_p2p_detach(struct brcmf_p2p_i - brcmf_p2p_cancel_remain_on_channel(vif->ifp); - brcmf_p2p_deinit_discovery(p2p); - /* remove discovery interface */ -- brcmf_free_vif(vif); -- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; -+ rtnl_lock(); -+ brcmf_p2p_delete_p2pdev(p2p, vif); -+ rtnl_unlock(); - } - /* just set it all to zero */ - memset(p2p, 0, sizeof(*p2p)); diff --git a/package/kernel/mac80211/patches/390-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch b/package/kernel/mac80211/patches/390-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch deleted file mode 100644 index 179c77e9df..0000000000 --- a/package/kernel/mac80211/patches/390-0001-brcmfmac-fix-double-free-of-p2pdev-interface.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Arend van Spriel -Date: Mon, 15 Jun 2015 22:48:38 +0200 -Subject: [PATCH] brcmfmac: fix double free of p2pdev interface - -When freeing the driver ifp pointer it should also be removed from -the driver interface list, which is what brcmf_remove_interface() -does. Otherwise, the ifp pointer will be freed twice triggering -a kernel oops. - -Fixes: f37d69a4babc ("brcmfmac: free ifp for non-netdev interface in p2p module") -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru - { - cfg80211_unregister_wdev(&vif->wdev); - p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; -- kfree(vif->ifp); -+ brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx); - brcmf_free_vif(vif); - } - diff --git a/package/kernel/mac80211/patches/390-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch b/package/kernel/mac80211/patches/390-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch deleted file mode 100644 index e4f88b5022..0000000000 --- a/package/kernel/mac80211/patches/390-0002-brcmfmac-make-brcmf_p2p_detach-call-conditional.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Arend van Spriel -Date: Mon, 15 Jun 2015 22:48:39 +0200 -Subject: [PATCH] brcmfmac: make brcmf_p2p_detach() call conditional - -During verification of error handling in brcmf_cfg80211_attach() a -null pointer dereference occurred upon calling brcmf_p2p_detach() -from brcmf_detach(). This should only be called when the -brcmf_cfg80211_attach() has succeeded. - -Fixes: f7a40873d2fa ("brcmfmac: assure p2pdev is unregistered upon driver unload") -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -1098,7 +1098,8 @@ void brcmf_detach(struct device *dev) - - /* stop firmware event handling */ - brcmf_fweh_detach(drvr); -- brcmf_p2p_detach(&drvr->config->p2p); -+ if (drvr->config) -+ brcmf_p2p_detach(&drvr->config->p2p); - - brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); - diff --git a/package/kernel/mac80211/patches/391-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch b/package/kernel/mac80211/patches/391-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch deleted file mode 100644 index 0a81237a28..0000000000 --- a/package/kernel/mac80211/patches/391-brcmfmac-set-wiphy-s-addresses-to-provide-valid-MACs.patch +++ /dev/null @@ -1,67 +0,0 @@ -From: Rafa? Mi?ecki -Date: Thu, 9 Jul 2015 17:07:08 +0200 -Subject: [PATCH] brcmfmac: set wiphy's addresses to provide valid MACs - -Broadcom's firmware requires every BSS to use MAC address with unique -last few bits. The amount of bits may depend on a particular firmware, -it was verified to be 2 for BCM43602 one. -If this condition won't be fulfilled firmware will reject such MAC: -brcmfmac: _brcmf_set_mac_address: Setting cur_etheraddr failed, -52 - -We don't want to simply set addr_mask as it would also disallow using -locally administrated bit. Instead let's build a list of addresses -manually enabling 0x2 bit for extra interfaces. - -Signed-off-by: Rafa? Mi?ecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -5784,6 +5784,7 @@ static void brcmf_wiphy_wowl_params(stru - - static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) - { -+ struct brcmf_pub *drvr = ifp->drvr; - struct ieee80211_supported_band *band; - __le32 bandlist[3]; - u32 n_bands; -@@ -5797,6 +5798,19 @@ static int brcmf_setup_wiphy(struct wiph - if (err) - return err; - -+ for (i = 0; i < wiphy->iface_combinations->max_interfaces && -+ i < ARRAY_SIZE(drvr->addresses); i++) { -+ u8 *addr = drvr->addresses[i].addr; -+ -+ memcpy(addr, drvr->mac, ETH_ALEN); -+ if (i) { -+ addr[0] |= BIT(1); -+ addr[ETH_ALEN - 1] ^= i; -+ } -+ } -+ wiphy->addresses = drvr->addresses; -+ wiphy->n_addresses = i; -+ - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->cipher_suites = __wl_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h -@@ -21,6 +21,7 @@ - #ifndef BRCMFMAC_CORE_H - #define BRCMFMAC_CORE_H - -+#include - #include "fweh.h" - - #define TOE_TX_CSUM_OL 0x00000001 -@@ -118,6 +119,8 @@ struct brcmf_pub { - /* Multicast data packets sent to dongle */ - unsigned long tx_multicast; - -+ struct mac_address addresses[BRCMF_MAX_IFS]; -+ - struct brcmf_if *iflist[BRCMF_MAX_IFS]; - - struct mutex proto_block; diff --git a/package/kernel/mac80211/patches/392-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch b/package/kernel/mac80211/patches/392-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch deleted file mode 100644 index e44f121ea3..0000000000 --- a/package/kernel/mac80211/patches/392-brcmfmac-dhd_sdio.c-use-existing-atomic_or-primitive.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Vineet Gupta -Date: Thu, 9 Jul 2015 13:43:18 +0530 -Subject: [PATCH] brcmfmac: dhd_sdio.c: use existing atomic_or primitive - -There's already a generic implementation so use that instead. - -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -2564,15 +2564,6 @@ static inline void brcmf_sdio_clrintr(st - } - } - --static void atomic_orr(int val, atomic_t *v) --{ -- int old_val; -- -- old_val = atomic_read(v); -- while (atomic_cmpxchg(v, old_val, val | old_val) != old_val) -- old_val = atomic_read(v); --} -- - static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) - { - struct brcmf_core *buscore; -@@ -2595,7 +2586,7 @@ static int brcmf_sdio_intr_rstatus(struc - if (val) { - brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); - bus->sdcnt.f1regdata++; -- atomic_orr(val, &bus->intstatus); -+ atomic_or(val, &bus->intstatus); - } - - return ret; -@@ -2712,7 +2703,7 @@ static void brcmf_sdio_dpc(struct brcmf_ - - /* Keep still-pending events for next scheduling */ - if (intstatus) -- atomic_orr(intstatus, &bus->intstatus); -+ atomic_or(intstatus, &bus->intstatus); - - brcmf_sdio_clrintr(bus); - diff --git a/package/kernel/mac80211/patches/393-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch b/package/kernel/mac80211/patches/393-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch deleted file mode 100644 index 76ca143df5..0000000000 --- a/package/kernel/mac80211/patches/393-0001-brcmfmac-check-all-combinations-when-setting-wiphy-s.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 20 Aug 2015 00:16:42 +0200 -Subject: [PATCH] brcmfmac: check all combinations when setting wiphy's - addresses -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Broadcom is working on better reflection of interface combinations. With -upcoming patches we may have 1st combination supporting less interfaces -than others. -To don't run out of addresses check all combinations to find the one -with the greatest max_interfaces value. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -5785,7 +5785,9 @@ static void brcmf_wiphy_wowl_params(stru - static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) - { - struct brcmf_pub *drvr = ifp->drvr; -+ const struct ieee80211_iface_combination *combo; - struct ieee80211_supported_band *band; -+ u16 max_interfaces = 0; - __le32 bandlist[3]; - u32 n_bands; - int err, i; -@@ -5798,8 +5800,13 @@ static int brcmf_setup_wiphy(struct wiph - if (err) - return err; - -- for (i = 0; i < wiphy->iface_combinations->max_interfaces && -- i < ARRAY_SIZE(drvr->addresses); i++) { -+ for (i = 0, combo = wiphy->iface_combinations; -+ i < wiphy->n_iface_combinations; i++, combo++) { -+ max_interfaces = max(max_interfaces, combo->max_interfaces); -+ } -+ -+ for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses); -+ i++) { - u8 *addr = drvr->addresses[i].addr; - - memcpy(addr, drvr->mac, ETH_ALEN); diff --git a/package/kernel/mac80211/patches/393-0002-brcmfmac-correct-interface-combination-info.patch b/package/kernel/mac80211/patches/393-0002-brcmfmac-correct-interface-combination-info.patch deleted file mode 100644 index c4a0720b35..0000000000 --- a/package/kernel/mac80211/patches/393-0002-brcmfmac-correct-interface-combination-info.patch +++ /dev/null @@ -1,204 +0,0 @@ -From: Arend van Spriel -Date: Thu, 20 Aug 2015 22:06:03 +0200 -Subject: [PATCH] brcmfmac: correct interface combination info - -The interface combination provided by brcmfmac did not truly reflect -the combinations supported by driver and/or firmware. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Pontus Fuchs -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -5694,63 +5694,132 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = - } - }; - -+/** -+ * brcmf_setup_ifmodes() - determine interface modes and combinations. -+ * -+ * @wiphy: wiphy object. -+ * @ifp: interface object needed for feat module api. -+ * -+ * The interface modes and combinations are determined dynamically here -+ * based on firmware functionality. -+ * -+ * no p2p and no mbss: -+ * -+ * #STA <= 1, #AP <= 1, channels = 1, 2 total -+ * -+ * no p2p and mbss: -+ * -+ * #STA <= 1, #AP <= 1, channels = 1, 2 total -+ * #AP <= 4, matching BI, channels = 1, 4 total -+ * -+ * p2p, no mchan, and mbss: -+ * -+ * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total -+ * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total -+ * #AP <= 4, matching BI, channels = 1, 4 total -+ * -+ * p2p, mchan, and mbss: -+ * -+ * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total -+ * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total -+ * #AP <= 4, matching BI, channels = 1, 4 total -+ */ - static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) - { - struct ieee80211_iface_combination *combo = NULL; -- struct ieee80211_iface_limit *limits = NULL; -- int i = 0, max_iface_cnt; -+ struct ieee80211_iface_limit *c0_limits = NULL; -+ struct ieee80211_iface_limit *p2p_limits = NULL; -+ struct ieee80211_iface_limit *mbss_limits = NULL; -+ bool mbss, p2p; -+ int i, c, n_combos; - -- combo = kzalloc(sizeof(*combo), GFP_KERNEL); -+ mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS); -+ p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P); -+ -+ n_combos = 1 + !!p2p + !!mbss; -+ combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL); - if (!combo) - goto err; - -- limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL); -- if (!limits) -+ c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); -+ if (!c0_limits) - goto err; - -+ if (p2p) { -+ p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); -+ if (!p2p_limits) -+ goto err; -+ } -+ -+ if (mbss) { -+ mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); -+ if (!mbss_limits) -+ goto err; -+ } -+ - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); - -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) -- combo->num_different_channels = 2; -- else -- combo->num_different_channels = 1; -- -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { -- limits[i].max = 1; -- limits[i++].types = BIT(NL80211_IFTYPE_STATION); -- limits[i].max = 4; -- limits[i++].types = BIT(NL80211_IFTYPE_AP); -- max_iface_cnt = 5; -- } else { -- limits[i].max = 2; -- limits[i++].types = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_AP); -- max_iface_cnt = 2; -- } -- -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) { -+ c = 0; -+ i = 0; -+ combo[c].num_different_channels = 1; -+ c0_limits[i].max = 1; -+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); -+ if (p2p) { -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) -+ combo[c].num_different_channels = 2; - wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_DEVICE); -- limits[i].max = 1; -- limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO); -- limits[i].max = 1; -- limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); -- max_iface_cnt += 2; -- } -- combo->max_interfaces = max_iface_cnt; -- combo->limits = limits; -- combo->n_limits = i; -+ c0_limits[i].max = 1; -+ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); -+ c0_limits[i].max = 1; -+ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO); -+ } else { -+ c0_limits[i].max = 1; -+ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); -+ } -+ combo[c].max_interfaces = i; -+ combo[c].n_limits = i; -+ combo[c].limits = c0_limits; -+ -+ if (p2p) { -+ c++; -+ i = 0; -+ combo[c].num_different_channels = 1; -+ p2p_limits[i].max = 1; -+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); -+ p2p_limits[i].max = 1; -+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP); -+ p2p_limits[i].max = 1; -+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); -+ p2p_limits[i].max = 1; -+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); -+ combo[c].max_interfaces = i; -+ combo[c].n_limits = i; -+ combo[c].limits = p2p_limits; -+ } - -+ if (mbss) { -+ c++; -+ combo[c].beacon_int_infra_match = true; -+ combo[c].num_different_channels = 1; -+ mbss_limits[0].max = 4; -+ mbss_limits[0].types = BIT(NL80211_IFTYPE_AP); -+ combo[c].max_interfaces = 4; -+ combo[c].n_limits = 1; -+ combo[c].limits = mbss_limits; -+ } -+ wiphy->n_iface_combinations = n_combos; - wiphy->iface_combinations = combo; -- wiphy->n_iface_combinations = 1; - return 0; - - err: -- kfree(limits); -+ kfree(c0_limits); -+ kfree(p2p_limits); -+ kfree(mbss_limits); - kfree(combo); - return -ENOMEM; - } -@@ -6079,11 +6148,15 @@ static void brcmf_cfg80211_reg_notifier( - - static void brcmf_free_wiphy(struct wiphy *wiphy) - { -+ int i; -+ - if (!wiphy) - return; - -- if (wiphy->iface_combinations) -- kfree(wiphy->iface_combinations->limits); -+ if (wiphy->iface_combinations) { -+ for (i = 0; i < wiphy->n_iface_combinations; i++) -+ kfree(wiphy->iface_combinations[i].limits); -+ } - kfree(wiphy->iface_combinations); - if (wiphy->bands[IEEE80211_BAND_2GHZ]) { - kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/393-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch b/package/kernel/mac80211/patches/393-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch deleted file mode 100644 index 9768ef2771..0000000000 --- a/package/kernel/mac80211/patches/393-0003-brcmfmac-add-debugfs-entry-for-msgbuf-statistics.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Franky Lin -Date: Thu, 20 Aug 2015 22:06:04 +0200 -Subject: [PATCH] brcmfmac: add debugfs entry for msgbuf statistics - -Expose ring buffer read/write pointers and other useful statistics -through debugfs. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -1360,6 +1360,60 @@ void brcmf_msgbuf_delete_flowring(struct - } - } - -+#ifdef DEBUG -+static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data) -+{ -+ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); -+ struct brcmf_pub *drvr = bus_if->drvr; -+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; -+ struct brcmf_commonring *commonring; -+ u16 i; -+ struct brcmf_flowring_ring *ring; -+ struct brcmf_flowring_hash *hash; -+ -+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT]; -+ seq_printf(seq, "h2d_ctl_submit: rp %4u, wp %4u, depth %4u\n", -+ commonring->r_ptr, commonring->w_ptr, commonring->depth); -+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT]; -+ seq_printf(seq, "h2d_rx_submit: rp %4u, wp %4u, depth %4u\n", -+ commonring->r_ptr, commonring->w_ptr, commonring->depth); -+ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE]; -+ seq_printf(seq, "d2h_ctl_cmplt: rp %4u, wp %4u, depth %4u\n", -+ commonring->r_ptr, commonring->w_ptr, commonring->depth); -+ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE]; -+ seq_printf(seq, "d2h_tx_cmplt: rp %4u, wp %4u, depth %4u\n", -+ commonring->r_ptr, commonring->w_ptr, commonring->depth); -+ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE]; -+ seq_printf(seq, "d2h_rx_cmplt: rp %4u, wp %4u, depth %4u\n", -+ commonring->r_ptr, commonring->w_ptr, commonring->depth); -+ -+ seq_printf(seq, "\nh2d_flowrings: depth %u\n", -+ BRCMF_H2D_TXFLOWRING_MAX_ITEM); -+ seq_puts(seq, "Active flowrings:\n"); -+ hash = msgbuf->flow->hash; -+ for (i = 0; i < msgbuf->flow->nrofrings; i++) { -+ if (!msgbuf->flow->rings[i]) -+ continue; -+ ring = msgbuf->flow->rings[i]; -+ if (ring->status != RING_OPEN) -+ continue; -+ commonring = msgbuf->flowrings[i]; -+ hash = &msgbuf->flow->hash[ring->hash_id]; -+ seq_printf(seq, "id %3u: rp %4u, wp %4u, qlen %4u, blocked %u\n" -+ " ifidx %u, fifo %u, da %pM\n", -+ i, commonring->r_ptr, commonring->w_ptr, -+ skb_queue_len(&ring->skblist), ring->blocked, -+ hash->ifidx, hash->fifo, hash->mac); -+ } -+ -+ return 0; -+} -+#else -+static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data) -+{ -+ return 0; -+} -+#endif - - int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) - { -@@ -1460,6 +1514,8 @@ 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: diff --git a/package/kernel/mac80211/patches/393-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch b/package/kernel/mac80211/patches/393-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch deleted file mode 100644 index 2b84cf9fcd..0000000000 --- a/package/kernel/mac80211/patches/393-0004-brcmfmac-make-use-of-cfg80211_check_combinations.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: Arend van Spriel -Date: Thu, 20 Aug 2015 22:06:05 +0200 -Subject: [PATCH] brcmfmac: make use of cfg80211_check_combinations() - -Use cfg80211_check_combinations() so we can bail out early when an -interface add or change results in an invalid combination. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -469,6 +469,36 @@ brcmf_find_wpsie(const u8 *parse, u32 le - return NULL; - } - -+static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg, -+ struct brcmf_cfg80211_vif *vif, -+ enum nl80211_iftype new_type) -+{ -+ int iftype_num[NUM_NL80211_IFTYPES]; -+ struct brcmf_cfg80211_vif *pos; -+ -+ memset(&iftype_num[0], 0, sizeof(iftype_num)); -+ list_for_each_entry(pos, &cfg->vif_list, list) -+ if (pos == vif) -+ iftype_num[new_type]++; -+ else -+ iftype_num[pos->wdev.iftype]++; -+ -+ return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num); -+} -+ -+static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg, -+ enum nl80211_iftype new_type) -+{ -+ int iftype_num[NUM_NL80211_IFTYPES]; -+ struct brcmf_cfg80211_vif *pos; -+ -+ memset(&iftype_num[0], 0, sizeof(iftype_num)); -+ list_for_each_entry(pos, &cfg->vif_list, list) -+ iftype_num[pos->wdev.iftype]++; -+ -+ iftype_num[new_type]++; -+ return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num); -+} - - static void convert_key_from_CPU(struct brcmf_wsec_key *key, - struct brcmf_wsec_key_le *key_le) -@@ -662,8 +692,14 @@ static struct wireless_dev *brcmf_cfg802 - struct vif_params *params) - { - struct wireless_dev *wdev; -+ int err; - - brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); -+ err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); -+ if (err) { -+ brcmf_err("iface validation failed: err=%d\n", err); -+ return ERR_PTR(err); -+ } - switch (type) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_STATION: -@@ -822,8 +858,12 @@ brcmf_cfg80211_change_iface(struct wiphy - s32 ap = 0; - s32 err = 0; - -- brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type); -- -+ brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type); -+ err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type); -+ if (err) { -+ brcmf_err("iface validation failed: err=%d\n", err); -+ return err; -+ } - switch (type) { - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_WDS: diff --git a/package/kernel/mac80211/patches/393-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch b/package/kernel/mac80211/patches/393-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch deleted file mode 100644 index 2d5f7b9be7..0000000000 --- a/package/kernel/mac80211/patches/393-0005-brcmfmac-block-the-correct-flowring-when-backup-queu.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: Franky Lin -Date: Thu, 20 Aug 2015 22:06:06 +0200 -Subject: [PATCH] brcmfmac: block the correct flowring when backup queue - overflow - -brcmf_flowring_block blocks the last active flowring under the same -interface instead of the one provided by caller. This could lead to a -dead lock of netif stop if there are more than one flowring under the -interface and the traffic is high enough so brcmf_flowring_enqueue can -not unblock the ring right away. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Signed-off-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c -@@ -194,11 +194,15 @@ static void brcmf_flowring_block(struct - spin_lock_irqsave(&flow->block_lock, flags); - - ring = flow->rings[flowid]; -+ if (ring->blocked == blocked) { -+ spin_unlock_irqrestore(&flow->block_lock, flags); -+ return; -+ } - ifidx = brcmf_flowring_ifidx_get(flow, flowid); - - currently_blocked = false; - for (i = 0; i < flow->nrofrings; i++) { -- if (flow->rings[i]) { -+ if ((flow->rings[i]) && (i != flowid)) { - ring = flow->rings[i]; - if ((ring->status == RING_OPEN) && - (brcmf_flowring_ifidx_get(flow, i) == ifidx)) { -@@ -209,8 +213,8 @@ static void brcmf_flowring_block(struct - } - } - } -- ring->blocked = blocked; -- if (currently_blocked == blocked) { -+ flow->rings[flowid]->blocked = blocked; -+ if (currently_blocked) { - spin_unlock_irqrestore(&flow->block_lock, flags); - return; - } diff --git a/package/kernel/mac80211/patches/393-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch b/package/kernel/mac80211/patches/393-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch deleted file mode 100644 index 7378401c52..0000000000 --- a/package/kernel/mac80211/patches/393-0006-brcmfmac-bump-highest-event-number-for-4339-firmware.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Arend van Spriel -Date: Thu, 20 Aug 2015 22:06:07 +0200 -Subject: [PATCH] brcmfmac: bump highest event number for 4339 firmware - -The event mask length is determined by the highest event number -that is specified in the driver. When this length is shorter than -firmware expects setting event mask will fail and device becomes -pretty useless. This issue was reported with bcm4339 firmware that -was recently released. - -Reported-by: Pontus Fuchs -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Pontus Fuchs -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h -@@ -85,7 +85,6 @@ struct brcmf_event; - BRCMF_ENUM_DEF(IF, 54) \ - BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \ - BRCMF_ENUM_DEF(RSSI, 56) \ -- BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \ - BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \ - BRCMF_ENUM_DEF(ACTION_FRAME, 59) \ - BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \ -@@ -103,8 +102,7 @@ struct brcmf_event; - BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ - BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ - BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \ -- BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ -- BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128) -+ BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) - - #define BRCMF_ENUM_DEF(id, val) \ - BRCMF_E_##id = (val), -@@ -112,7 +110,11 @@ struct brcmf_event; - /* firmware event codes sent by the dongle */ - enum brcmf_fweh_event_code { - BRCMF_FWEH_EVENT_ENUM_DEFLIST -- BRCMF_E_LAST -+ /* this determines event mask length which must match -+ * minimum length check in device firmware so it is -+ * hard-coded here. -+ */ -+ BRCMF_E_LAST = 139 - }; - #undef BRCMF_ENUM_DEF - diff --git a/package/kernel/mac80211/patches/394-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch b/package/kernel/mac80211/patches/394-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch deleted file mode 100644 index 97444b3c0d..0000000000 --- a/package/kernel/mac80211/patches/394-0001-brcmfmac-consolidate-ifp-lookup-in-driver-core.patch +++ /dev/null @@ -1,138 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:14:53 +0200 -Subject: [PATCH] brcmfmac: consolidate ifp lookup in driver core - -In rx path the firmware provide an interface index which is used to -map to a struct brcmf_if instance. However, this involves some trick -that is done in two places. This is changed by having driver core -providing brcmf_get_ifp() function. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c -@@ -276,6 +276,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - struct sk_buff *pktbuf) - { - struct brcmf_proto_bcdc_header *h; -+ struct brcmf_if *ifp; - - brcmf_dbg(BCDC, "Enter\n"); - -@@ -289,30 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - trace_brcmf_bcdchdr(pktbuf->data); - h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); - -- *ifidx = BCDC_GET_IF_IDX(h); -- if (*ifidx >= BRCMF_MAX_IFS) { -- brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); -+ ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h)); -+ if (IS_ERR_OR_NULL(ifp)) { -+ brcmf_dbg(INFO, "no matching ifp found\n"); - return -EBADE; - } -- /* The ifidx is the idx to map to matching netdev/ifp. When receiving -- * events this is easy because it contains the bssidx which maps -- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. -- * bssidx 1 is used for p2p0 and no data can be received or -- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 -- */ -- if (*ifidx) -- (*ifidx)++; -- - if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != - BCDC_PROTO_VER) { - brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", -- brcmf_ifname(drvr, *ifidx), h->flags); -+ brcmf_ifname(drvr, ifp->ifidx), h->flags); - return -EBADE; - } - - if (h->flags & BCDC_FLAG_SUM_GOOD) { - brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n", -- brcmf_ifname(drvr, *ifidx), h->flags); -+ brcmf_ifname(drvr, ifp->ifidx), h->flags); - pktbuf->ip_summed = CHECKSUM_UNNECESSARY; - } - -@@ -320,12 +312,15 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - - skb_pull(pktbuf, BCDC_HEADER_LEN); - if (do_fws) -- brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); -+ brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2, -+ pktbuf); - else - skb_pull(pktbuf, h->data_offset << 2); - - if (pktbuf->len == 0) - return -ENODATA; -+ -+ *ifidx = ifp->ifidx; - return 0; - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -83,6 +83,25 @@ char *brcmf_ifname(struct brcmf_pub *drv - return ""; - } - -+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx) -+{ -+ if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { -+ brcmf_err("ifidx %d out of range\n", ifidx); -+ return ERR_PTR(-ERANGE); -+ } -+ -+ /* The ifidx is the idx to map to matching netdev/ifp. When receiving -+ * events this is easy because it contains the bssidx which maps -+ * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. -+ * bssidx 1 is used for p2p0 and no data can be received or -+ * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 -+ */ -+ if (ifidx) -+ ifidx++; -+ -+ return drvr->iflist[ifidx]; -+} -+ - static void _brcmf_set_multicast_list(struct work_struct *work) - { - struct brcmf_if *ifp; ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h -@@ -202,7 +202,7 @@ int brcmf_netdev_wait_pend8021x(struct b - - /* Return pointer to interface name */ - char *brcmf_ifname(struct brcmf_pub *drvr, int idx); -- -+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); - int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); - struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, - char *name, u8 *mac_addr); ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -1081,16 +1081,8 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf - { - struct brcmf_if *ifp; - -- /* The ifidx is the idx to map to matching netdev/ifp. When receiving -- * events this is easy because it contains the bssidx which maps -- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. -- * bssidx 1 is used for p2p0 and no data can be received or -- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 -- */ -- if (ifidx) -- (ifidx)++; -- ifp = msgbuf->drvr->iflist[ifidx]; -- if (!ifp || !ifp->ndev) { -+ ifp = brcmf_get_ifp(msgbuf->drvr, ifidx); -+ if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) { - brcmf_err("Received pkt for invalid ifidx %d\n", ifidx); - brcmu_pkt_buf_free_skb(skb); - return; diff --git a/package/kernel/mac80211/patches/394-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch b/package/kernel/mac80211/patches/394-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch deleted file mode 100644 index 632714ce24..0000000000 --- a/package/kernel/mac80211/patches/394-0002-brcmfmac-make-brcmf_proto_hdrpull-return-struct-brcm.patch +++ /dev/null @@ -1,222 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:14:54 +0200 -Subject: [PATCH] brcmfmac: make brcmf_proto_hdrpull() return struct - brcmf_if instance - -Avoid spreading the ifidx in the driver, but have it return the -struct brcmf_if instance. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c -@@ -272,11 +272,11 @@ brcmf_proto_bcdc_hdrpush(struct brcmf_pu - } - - static int --brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, -- struct sk_buff *pktbuf) -+brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, -+ struct sk_buff *pktbuf, struct brcmf_if **ifp) - { - struct brcmf_proto_bcdc_header *h; -- struct brcmf_if *ifp; -+ struct brcmf_if *tmp_if; - - brcmf_dbg(BCDC, "Enter\n"); - -@@ -290,21 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - trace_brcmf_bcdchdr(pktbuf->data); - h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); - -- ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h)); -- if (IS_ERR_OR_NULL(ifp)) { -+ tmp_if = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h)); -+ if (!tmp_if) { - brcmf_dbg(INFO, "no matching ifp found\n"); - return -EBADE; - } - if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != - BCDC_PROTO_VER) { - brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", -- brcmf_ifname(drvr, ifp->ifidx), h->flags); -+ brcmf_ifname(drvr, tmp_if->ifidx), h->flags); - return -EBADE; - } - - if (h->flags & BCDC_FLAG_SUM_GOOD) { - brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n", -- brcmf_ifname(drvr, ifp->ifidx), h->flags); -+ brcmf_ifname(drvr, tmp_if->ifidx), h->flags); - pktbuf->ip_summed = CHECKSUM_UNNECESSARY; - } - -@@ -312,7 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - - skb_pull(pktbuf, BCDC_HEADER_LEN); - if (do_fws) -- brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2, -+ brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2, - pktbuf); - else - skb_pull(pktbuf, h->data_offset << 2); -@@ -320,7 +320,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - if (pktbuf->len == 0) - return -ENODATA; - -- *ifidx = ifp->ifidx; -+ *ifp = tmp_if; - return 0; - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -87,7 +87,7 @@ struct brcmf_if *brcmf_get_ifp(struct br - { - if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { - brcmf_err("ifidx %d out of range\n", ifidx); -- return ERR_PTR(-ERANGE); -+ return NULL; - } - - /* The ifidx is the idx to map to matching netdev/ifp. When receiving -@@ -539,17 +539,15 @@ void brcmf_rx_frame(struct device *dev, - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_pub *drvr = bus_if->drvr; - struct brcmf_skb_reorder_data *rd; -- u8 ifidx; - int ret; - - brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); - - /* process and remove protocol-specific header */ -- ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb); -- ifp = drvr->iflist[ifidx]; -+ ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); - - if (ret || !ifp || !ifp->ndev) { -- if ((ret != -ENODATA) && ifp) -+ if (ret != -ENODATA && ifp) - ifp->stats.rx_errors++; - brcmu_pkt_buf_free_skb(skb); - return; -@@ -592,17 +590,17 @@ void brcmf_txcomplete(struct device *dev - { - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_pub *drvr = bus_if->drvr; -- u8 ifidx; -+ struct brcmf_if *ifp; - - /* await txstatus signal for firmware if active */ - if (brcmf_fws_fc_active(drvr->fws)) { - if (!success) - brcmf_fws_bustxfail(drvr->fws, txp); - } else { -- if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp)) -+ if (brcmf_proto_hdrpull(drvr, false, txp, &ifp)) - brcmu_pkt_buf_free_skb(txp); - else -- brcmf_txfinalize(drvr, txp, ifidx, success); -+ brcmf_txfinalize(drvr, txp, ifp->ifidx, success); - } - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -@@ -1448,7 +1448,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i - struct sk_buff *skb; - struct brcmf_skbuff_cb *skcb; - struct brcmf_fws_mac_descriptor *entry = NULL; -- u8 ifidx; -+ struct brcmf_if *ifp; - - brcmf_dbg(DATA, "flags %d\n", flags); - -@@ -1497,15 +1497,16 @@ brcmf_fws_txs_process(struct brcmf_fws_i - } - brcmf_fws_macdesc_return_req_credit(skb); - -- if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) { -+ ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp); -+ if (ret) { - brcmu_pkt_buf_free_skb(skb); - return -EINVAL; - } - if (!remove_from_hanger) -- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx, -+ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx, - genbit, seq); - if (remove_from_hanger || ret) -- brcmf_txfinalize(fws->drvr, skb, ifidx, true); -+ brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true); - - return 0; - } -@@ -1848,7 +1849,7 @@ static int brcmf_fws_commit_skb(struct b - entry->transit_count--; - if (entry->suppressed) - entry->suppr_transit_count--; -- brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); -+ (void)brcmf_proto_hdrpull(fws->drvr, false, skb, NULL); - goto rollback; - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -522,7 +522,7 @@ static int brcmf_msgbuf_set_dcmd(struct - - - static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws, -- u8 *ifidx, struct sk_buff *skb) -+ struct sk_buff *skb, struct brcmf_if **ifp) - { - return -ENODEV; - } -@@ -1082,7 +1082,7 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf - struct brcmf_if *ifp; - - ifp = brcmf_get_ifp(msgbuf->drvr, ifidx); -- if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) { -+ if (!ifp || !ifp->ndev) { - brcmf_err("Received pkt for invalid ifidx %d\n", ifidx); - brcmu_pkt_buf_free_skb(skb); - return; ---- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h -@@ -24,8 +24,8 @@ enum proto_addr_mode { - - - struct brcmf_proto { -- int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, -- struct sk_buff *skb); -+ 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); - int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, -@@ -46,9 +46,19 @@ int brcmf_proto_attach(struct brcmf_pub - void brcmf_proto_detach(struct brcmf_pub *drvr); - - static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, -- u8 *ifidx, struct sk_buff *skb) -+ struct sk_buff *skb, -+ struct brcmf_if **ifp) - { -- return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb); -+ struct brcmf_if *tmp = NULL; -+ -+ /* assure protocol is always called with -+ * non-null initialized pointer. -+ */ -+ if (ifp) -+ *ifp = NULL; -+ else -+ ifp = &tmp; -+ 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) diff --git a/package/kernel/mac80211/patches/394-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch b/package/kernel/mac80211/patches/394-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch deleted file mode 100644 index 2d15a77154..0000000000 --- a/package/kernel/mac80211/patches/394-0003-brcmfmac-change-parameters-for-brcmf_remove_interfac.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:14:55 +0200 -Subject: [PATCH] brcmfmac: change parameters for - brcmf_remove_interface() - -Just pass the interface to be removed, ie. the struct brcmf_if instance. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -4982,7 +4982,7 @@ brcmf_notify_connect_status_ap(struct br - brcmf_dbg(CONN, "AP mode link down\n"); - complete(&cfg->vif_disabled); - if (ifp->vif->mbss) -- brcmf_remove_interface(ifp->drvr, ifp->bssidx); -+ brcmf_remove_interface(ifp); - return 0; - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -887,12 +887,13 @@ static void brcmf_del_if(struct brcmf_pu - } - } - --void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx) -+void brcmf_remove_interface(struct brcmf_if *ifp) - { -- if (drvr->iflist[bssidx]) { -- brcmf_fws_del_interface(drvr->iflist[bssidx]); -- brcmf_del_if(drvr, bssidx); -- } -+ if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp)) -+ return; -+ -+ brcmf_fws_del_interface(ifp); -+ brcmf_del_if(ifp->drvr, ifp->bssidx); - } - - int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr) -@@ -1122,7 +1123,7 @@ void brcmf_detach(struct device *dev) - - /* make sure primary interface removed last */ - for (i = BRCMF_MAX_IFS-1; i > -1; i--) -- brcmf_remove_interface(drvr, i); -+ brcmf_remove_interface(drvr->iflist[i]); - - brcmf_cfg80211_detach(drvr->config); - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h -@@ -206,7 +206,7 @@ struct brcmf_if *brcmf_get_ifp(struct br - int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); - struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, - char *name, u8 *mac_addr); --void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx); -+void brcmf_remove_interface(struct brcmf_if *ifp); - int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr); - void brcmf_txflowblock_if(struct brcmf_if *ifp, - enum brcmf_netif_stop_reason reason, bool state); ---- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c -@@ -222,7 +222,7 @@ static void brcmf_fweh_handle_if_event(s - err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); - - if (ifp && ifevent->action == BRCMF_E_IF_DEL) -- brcmf_remove_interface(drvr, ifevent->bssidx); -+ brcmf_remove_interface(ifp); - } - - /** ---- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c -@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru - { - cfg80211_unregister_wdev(&vif->wdev); - p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; -- brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx); -+ brcmf_remove_interface(vif->ifp); - brcmf_free_vif(vif); - } - diff --git a/package/kernel/mac80211/patches/394-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch b/package/kernel/mac80211/patches/394-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch deleted file mode 100644 index 2b61f4eda5..0000000000 --- a/package/kernel/mac80211/patches/394-0004-brcmfmac-only-call-brcmf_cfg80211_detach-when-attach.patch +++ /dev/null @@ -1,92 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:14:56 +0200 -Subject: [PATCH] brcmfmac: only call brcmf_cfg80211_detach() when attach - was successful - -In brcmf_bus_start() the function brcmf_cfg80211_attach() is called which -may fail. If this happens we should not call brcmf_cfg80211_detach() in -the failure path as it will result in NULL pointer dereference: - - brcmf_fweh_activate_events: Set event_msgs error (-5) - brcmf_bus_start: failed: -5 - brcmf_sdio_firmware_callback: dongle is not responding - BUG: unable to handle kernel NULL pointer dereference at 0000000000000068 - IP: [] kernfs_find_ns+0x18/0xd0 - PGD 0 - Oops: 0000 [#1] SMP - Modules linked in: brcmfmac(O) brcmutil(O) cfg80211 auth_rpcgss - CPU: 1 PID: 45 Comm: kworker/1:1 Tainted: G O - Hardware name: Dell Inc. Latitude E6410/07XJP9, BIOS A07 02/15/2011 - Workqueue: events request_firmware_work_func - task: ffff880036c09ac0 ti: ffff880036dd4000 task.ti: ffff880036dd4000 - RIP: 0010:[] [] kernfs_find_ns+0x18/0xd0 - RSP: 0018:ffff880036dd7a28 EFLAGS: 00010246 - RAX: ffff880036c09ac0 RBX: 0000000000000000 RCX: 000000007fffffff - RDX: 0000000000000000 RSI: ffffffff816578b9 RDI: 0000000000000000 - RBP: ffff880036dd7a48 R08: 0000000000000000 R09: ffff880036c0b340 - R10: 00000000000002ec R11: ffff880036dd7b08 R12: ffffffff816578b9 - R13: 0000000000000000 R14: ffffffff816578b9 R15: ffff8800c6c87000 - FS: 0000000000000000(0000) GS:ffff88012bc40000(0000) knlGS:0000000000000000 - CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b - CR2: 0000000000000068 CR3: 0000000001a0b000 CR4: 00000000000006e0 - Stack: - 0000000000000000 ffffffff816578b9 0000000000000000 ffff8800c0d003c8 - ffff880036dd7a78 ffffffff811e8ff5 0000000ffffffff1 ffffffff81a9b060 - ffff8800c789f880 ffff8800c0d00000 ffff880036dd7a98 ffffffff811ebe0d - Call Trace: - [] kernfs_find_and_get_ns+0x35/0x60 - [] sysfs_unmerge_group+0x1d/0x60 - [] dpm_sysfs_remove+0x22/0x60 - [] device_del+0x49/0x240 - [] rfkill_unregister+0x58/0xc0 - [] wiphy_unregister+0xab/0x2f0 [cfg80211] - [] brcmf_cfg80211_detach+0x23/0x50 [brcmfmac] - [] brcmf_detach+0x86/0xe0 [brcmfmac] - [] brcmf_sdio_remove+0x48/0x120 [brcmfmac] - [] brcmf_sdiod_remove+0x29/0xd0 [brcmfmac] - [] brcmf_ops_sdio_remove+0xb1/0x110 [brcmfmac] - [] sdio_bus_remove+0x37/0x100 [mmc_core] - [] __device_release_driver+0x96/0x130 - [] device_release_driver+0x23/0x30 - [] brcmf_sdio_firmware_callback+0x2a8/0x5d0 [brcmfmac] - [] brcmf_fw_request_nvram_done+0x15f/0x5e0 [brcmfmac] - [] ? devres_add+0x3f/0x50 - [] ? usermodehelper_read_unlock+0x15/0x20 - [] ? platform_match+0x70/0xa0 - [] request_firmware_work_func+0x30/0x60 - [] process_one_work+0x14c/0x3d0 - [] worker_thread+0x11a/0x450 - [] ? process_one_work+0x3d0/0x3d0 - [] kthread+0xd2/0xf0 - [] ? kthread_create_on_node+0x180/0x180 - [] ret_from_fork+0x3f/0x70 - [] ? kthread_create_on_node+0x180/0x180 - Code: e9 40 fe ff ff 48 89 d8 eb 87 66 0f 1f 84 00 00 00 00 00 66 66 66 66 - 90 55 48 89 e5 41 56 49 89 f6 41 55 49 89 d5 31 d2 41 54 53 <0f> b7 - 47 68 48 8b 5f 48 66 c1 e8 05 83 e0 01 4d 85 ed 0f b6 c8 - RIP [] kernfs_find_ns+0x18/0xd0 - RSP - CR2: 0000000000000068 - ---[ end trace 87d6ec0d3fe46740 ]--- - -Reported-by: Daniel (Deognyoun) Kim -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -1049,7 +1049,10 @@ int brcmf_bus_start(struct device *dev) - fail: - if (ret < 0) { - brcmf_err("failed: %d\n", ret); -- brcmf_cfg80211_detach(drvr->config); -+ if (drvr->config) { -+ brcmf_cfg80211_detach(drvr->config); -+ drvr->config = NULL; -+ } - if (drvr->fws) { - brcmf_fws_del_interface(ifp); - brcmf_fws_deinit(drvr); diff --git a/package/kernel/mac80211/patches/394-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch b/package/kernel/mac80211/patches/394-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch deleted file mode 100644 index 868b0a82e6..0000000000 --- a/package/kernel/mac80211/patches/394-0005-brcmfmac-correct-detection-of-p2pdev-interface-event.patch +++ /dev/null @@ -1,105 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:14:57 +0200 -Subject: [PATCH] brcmfmac: correct detection of p2pdev interface event - -The p2pdev interface is setup in firmware resulting in a interface -event. This event has role and no-if flag. When role is p2p client -and no-if flag is set it indicates that this is the p2pdev interface. -This info is used in handling the event and adding interface in the -driver. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -795,7 +795,7 @@ fail: - } - - struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, -- char *name, u8 *mac_addr) -+ bool is_p2pdev, char *name, u8 *mac_addr) - { - struct brcmf_if *ifp; - struct net_device *ndev; -@@ -821,7 +821,7 @@ struct brcmf_if *brcmf_add_if(struct brc - } - } - -- if (!brcmf_p2p_enable && bssidx == 1) { -+ if (!brcmf_p2p_enable && is_p2pdev) { - /* this is P2P_DEVICE interface */ - brcmf_dbg(INFO, "allocate non-netdev interface\n"); - ifp = kzalloc(sizeof(*ifp), GFP_KERNEL); -@@ -999,12 +999,12 @@ int brcmf_bus_start(struct device *dev) - brcmf_dbg(TRACE, "\n"); - - /* add primary networking interface */ -- ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL); -+ ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", NULL); - if (IS_ERR(ifp)) - return PTR_ERR(ifp); - - if (brcmf_p2p_enable) -- p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL); -+ p2p_ifp = brcmf_add_if(drvr, 1, 0, false, "p2p%d", NULL); - else - p2p_ifp = NULL; - if (IS_ERR(p2p_ifp)) ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h -@@ -205,7 +205,7 @@ char *brcmf_ifname(struct brcmf_pub *drv - struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); - int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); - struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, -- char *name, u8 *mac_addr); -+ bool is_p2pdev, char *name, u8 *mac_addr); - void brcmf_remove_interface(struct brcmf_if *ifp); - int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr); - void brcmf_txflowblock_if(struct brcmf_if *ifp, ---- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c -@@ -179,6 +179,7 @@ static void brcmf_fweh_handle_if_event(s - { - struct brcmf_if_event *ifevent = data; - struct brcmf_if *ifp; -+ bool is_p2pdev; - int err = 0; - - brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u role: %u\n", -@@ -186,18 +187,16 @@ static void brcmf_fweh_handle_if_event(s - ifevent->flags, ifevent->role); - - /* The P2P Device interface event must not be ignored -- * contrary to what firmware tells us. The only way to -- * distinguish the P2P Device is by looking at the ifidx -- * and bssidx received. -+ * contrary to what firmware tells us. - */ -- if (!(ifevent->ifidx == 0 && ifevent->bssidx == 1) && -- (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) { -+ is_p2pdev = (ifevent->flags & BRCMF_E_IF_FLAG_NOIF) && -+ ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT; -+ if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) { - brcmf_dbg(EVENT, "event can be ignored\n"); - return; - } - if (ifevent->ifidx >= BRCMF_MAX_IFS) { -- brcmf_err("invalid interface index: %u\n", -- ifevent->ifidx); -+ brcmf_err("invalid interface index: %u\n", ifevent->ifidx); - return; - } - -@@ -207,7 +206,7 @@ static void brcmf_fweh_handle_if_event(s - brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, - emsg->addr); - ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx, -- emsg->ifname, emsg->addr); -+ is_p2pdev, emsg->ifname, emsg->addr); - if (IS_ERR(ifp)) - return; - brcmf_fws_add_interface(ifp); diff --git a/package/kernel/mac80211/patches/394-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch b/package/kernel/mac80211/patches/394-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch deleted file mode 100644 index aebbfa6c49..0000000000 --- a/package/kernel/mac80211/patches/394-0006-brcmfmac-use-brcmf_get_ifp-to-map-ifidx-to-struct-br.patch +++ /dev/null @@ -1,126 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:14:58 +0200 -Subject: [PATCH] brcmfmac: use brcmf_get_ifp() to map ifidx to struct - brcmf_if instance - -The knowledge on how to map the interface index to a struct brcmf_if -instance is in brcmf_get_ifp() so use that function when only the -interface index is known instead of accessing brcmf_pub::iflist -directly. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c -@@ -149,7 +149,7 @@ static s32 brcmf_btcoex_params_read(stru - static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci, - bool trump_sco) - { -- struct brcmf_if *ifp = btci->cfg->pub->iflist[0]; -+ struct brcmf_if *ifp = brcmf_get_ifp(btci->cfg->pub, 0); - - if (trump_sco && !btci->saved_regs_part2) { - /* this should reduce eSCO agressive -@@ -468,7 +468,7 @@ int brcmf_btcoex_set_mode(struct brcmf_c - { - struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy); - struct brcmf_btcoex_info *btci = cfg->btcoex; -- struct brcmf_if *ifp = cfg->pub->iflist[0]; -+ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); - - switch (mode) { - case BRCMF_BTCOEX_DISABLED: ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -6212,7 +6212,7 @@ static void brcmf_free_wiphy(struct wiph - struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, - struct device *busdev) - { -- struct net_device *ndev = drvr->iflist[0]->ndev; -+ struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; - struct brcmf_cfg80211_info *cfg; - struct wiphy *wiphy; - struct brcmf_cfg80211_vif *vif; ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c -@@ -121,7 +121,7 @@ static void brcmf_feat_iovar_int_set(str - - void brcmf_feat_attach(struct brcmf_pub *drvr) - { -- struct brcmf_if *ifp = drvr->iflist[0]; -+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); - - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan"); - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); ---- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c -@@ -221,7 +221,7 @@ static void brcmf_flowring_block(struct - - bus_if = dev_get_drvdata(flow->dev); - drvr = bus_if->drvr; -- ifp = drvr->iflist[ifidx]; -+ ifp = brcmf_get_ifp(drvr, ifidx); - brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, blocked); - - spin_unlock_irqrestore(&flow->block_lock, flags); ---- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c -@@ -334,7 +334,7 @@ void brcmf_fweh_attach(struct brcmf_pub - void brcmf_fweh_detach(struct brcmf_pub *drvr) - { - struct brcmf_fweh_info *fweh = &drvr->fweh; -- struct brcmf_if *ifp = drvr->iflist[0]; -+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - - if (ifp) { ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -@@ -972,7 +972,7 @@ static void - brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq, - u8 if_id) - { -- struct brcmf_if *ifp = fws->drvr->iflist[!if_id ? 0 : if_id + 1]; -+ struct brcmf_if *ifp = brcmf_get_ifp(fws->drvr, if_id); - - if (WARN_ON(!ifp)) - return; -@@ -2118,6 +2118,7 @@ static int brcmf_debugfs_fws_stats_read( - int brcmf_fws_init(struct brcmf_pub *drvr) - { - struct brcmf_fws_info *fws; -+ struct brcmf_if *ifp; - u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS; - int rc; - u32 mode; -@@ -2177,21 +2178,22 @@ int brcmf_fws_init(struct brcmf_pub *drv - * continue. Set mode back to none indicating not enabled. - */ - fws->fw_signals = true; -- if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) { -+ ifp = brcmf_get_ifp(drvr, 0); -+ if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) { - brcmf_err("failed to set bdcv2 tlv signaling\n"); - fws->fcmode = BRCMF_FWS_FCMODE_NONE; - fws->fw_signals = false; - } - -- if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1)) -+ if (brcmf_fil_iovar_int_set(ifp, "ampdu_hostreorder", 1)) - brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n"); - - /* Enable seq number reuse, if supported */ -- if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) { -+ if (brcmf_fil_iovar_int_get(ifp, "wlfc_mode", &mode) == 0) { - if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) { - mode = 0; - BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1); -- if (brcmf_fil_iovar_int_set(drvr->iflist[0], -+ if (brcmf_fil_iovar_int_set(ifp, - "wlfc_mode", mode) == 0) { - BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1); - } diff --git a/package/kernel/mac80211/patches/394-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch b/package/kernel/mac80211/patches/394-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch deleted file mode 100644 index 23a7b6f1c8..0000000000 --- a/package/kernel/mac80211/patches/394-0007-brcmfmac-pass-struct-brcmf_if-instance-in-brcmf_txfi.patch +++ /dev/null @@ -1,122 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:14:59 +0200 -Subject: [PATCH] brcmfmac: pass struct brcmf_if instance in - brcmf_txfinalize() - -Most call sites of brcmf_txfinalize already have struct brcmf_if -instance so pass that to brcmf_txfinalize() as the function -needs it anyway. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -560,17 +560,11 @@ void brcmf_rx_frame(struct device *dev, - brcmf_netif_rx(ifp, skb); - } - --void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, -- bool success) -+void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) - { -- struct brcmf_if *ifp; - struct ethhdr *eh; - u16 type; - -- ifp = drvr->iflist[ifidx]; -- if (!ifp) -- goto done; -- - eh = (struct ethhdr *)(txp->data); - type = ntohs(eh->h_proto); - -@@ -582,7 +576,7 @@ void brcmf_txfinalize(struct brcmf_pub * - - if (!success) - ifp->stats.tx_errors++; --done: -+ - brcmu_pkt_buf_free_skb(txp); - } - -@@ -600,7 +594,7 @@ void brcmf_txcomplete(struct device *dev - if (brcmf_proto_hdrpull(drvr, false, txp, &ifp)) - brcmu_pkt_buf_free_skb(txp); - else -- brcmf_txfinalize(drvr, txp, ifp->ifidx, success); -+ brcmf_txfinalize(ifp, txp, success); - } - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h -@@ -210,8 +210,7 @@ void brcmf_remove_interface(struct brcmf - int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr); - void brcmf_txflowblock_if(struct brcmf_if *ifp, - enum brcmf_netif_stop_reason reason, bool state); --void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx, -- bool success); -+void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); - void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); - - /* Sets dongle media info (drv_version, mac address). */ ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -@@ -1506,7 +1506,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i - ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx, - genbit, seq); - if (remove_from_hanger || ret) -- brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true); -+ brcmf_txfinalize(ifp, skb, true); - - return 0; - } -@@ -1905,7 +1905,7 @@ int brcmf_fws_process_skb(struct brcmf_i - if (fws->avoid_queueing) { - rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb); - if (rc < 0) -- brcmf_txfinalize(drvr, skb, ifp->ifidx, false); -+ brcmf_txfinalize(ifp, skb, false); - return rc; - } - -@@ -1929,7 +1929,7 @@ int brcmf_fws_process_skb(struct brcmf_i - brcmf_fws_schedule_deq(fws); - } else { - brcmf_err("drop skb: no hanger slot\n"); -- brcmf_txfinalize(drvr, skb, ifp->ifidx, false); -+ brcmf_txfinalize(ifp, skb, false); - rc = -ENOMEM; - } - brcmf_fws_unlock(fws); -@@ -2009,8 +2009,9 @@ static void brcmf_fws_dequeue_worker(str - ret = brcmf_proto_txdata(drvr, ifidx, 0, skb); - brcmf_fws_lock(fws); - if (ret < 0) -- brcmf_txfinalize(drvr, skb, ifidx, -- false); -+ brcmf_txfinalize(brcmf_get_ifp(drvr, -+ ifidx), -+ skb, false); - if (fws->bus_flow_blocked) - break; - } ---- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c -@@ -873,7 +873,11 @@ brcmf_msgbuf_process_txstatus(struct brc - commonring = msgbuf->flowrings[flowid]; - atomic_dec(&commonring->outstanding_tx); - -- brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true); -+ /* Hante: i believe this was a bug as tx_status->msg.ifidx was used -+ * in brcmf_txfinalize as index in drvr->iflist. Can you confirm/deny? -+ */ -+ brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx), -+ skb, true); - } - - diff --git a/package/kernel/mac80211/patches/394-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch b/package/kernel/mac80211/patches/394-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch deleted file mode 100644 index 8ddc0a6eef..0000000000 --- a/package/kernel/mac80211/patches/394-0008-brcmfmac-add-mapping-for-interface-index-to-bsscfg-i.patch +++ /dev/null @@ -1,92 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:15:00 +0200 -Subject: [PATCH] brcmfmac: add mapping for interface index to bsscfg - index - -Because the P2P Device interface in firmware uses the same interface -index as the primary interface we use the bsscfg index as index in the -struct brcmf_pub::iflist. However, in the data path we get the interface -index and not the bsscfg index. So we need a mapping of interface index -to bsscfg index, which can be determined upon handle adding the interface. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -85,21 +85,20 @@ char *brcmf_ifname(struct brcmf_pub *drv - - struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx) - { -+ struct brcmf_if *ifp; -+ s32 bssidx; -+ - if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { - brcmf_err("ifidx %d out of range\n", ifidx); - return NULL; - } - -- /* The ifidx is the idx to map to matching netdev/ifp. When receiving -- * events this is easy because it contains the bssidx which maps -- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. -- * bssidx 1 is used for p2p0 and no data can be received or -- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 -- */ -- if (ifidx) -- ifidx++; -+ ifp = NULL; -+ bssidx = drvr->if2bss[ifidx]; -+ if (bssidx >= 0) -+ ifp = drvr->iflist[bssidx]; - -- return drvr->iflist[ifidx]; -+ return ifp; - } - - static void _brcmf_set_multicast_list(struct work_struct *work) -@@ -831,6 +830,8 @@ struct brcmf_if *brcmf_add_if(struct brc - - ifp = netdev_priv(ndev); - ifp->ndev = ndev; -+ /* store mapping ifidx to bssidx */ -+ drvr->if2bss[ifidx] = bssidx; - } - - ifp->drvr = drvr; -@@ -855,6 +856,7 @@ static void brcmf_del_if(struct brcmf_pu - struct brcmf_if *ifp; - - ifp = drvr->iflist[bssidx]; -+ drvr->if2bss[ifp->ifidx] = -1; - drvr->iflist[bssidx] = NULL; - if (!ifp) { - brcmf_err("Null interface, idx=%d\n", bssidx); -@@ -862,6 +864,7 @@ static void brcmf_del_if(struct brcmf_pu - } - brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx); - if (ifp->ndev) { -+ drvr->if2bss[ifp->ifidx] = -1; - if (bssidx == 0) { - if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { - rtnl_lock(); -@@ -926,6 +929,7 @@ int brcmf_attach(struct device *dev) - if (!drvr) - return -ENOMEM; - -+ memset(drvr->if2bss, 0xFF, sizeof(drvr->if2bss)); - mutex_init(&drvr->proto_block); - - /* Link to bus module */ ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h -@@ -122,6 +122,7 @@ struct brcmf_pub { - struct mac_address addresses[BRCMF_MAX_IFS]; - - struct brcmf_if *iflist[BRCMF_MAX_IFS]; -+ s32 if2bss[BRCMF_MAX_IFS]; - - struct mutex proto_block; - unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; diff --git a/package/kernel/mac80211/patches/394-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch b/package/kernel/mac80211/patches/394-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch deleted file mode 100644 index a0a798be93..0000000000 --- a/package/kernel/mac80211/patches/394-0009-brcmfmac-add-dedicated-debug-level-for-firmware-cons.patch +++ /dev/null @@ -1,103 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:15:01 +0200 -Subject: [PATCH] brcmfmac: add dedicated debug level for firmware - console logging - -Both PCIe and SDIO devices have the possibility to log the firmware -console output in kernel log. For PCIe it is logged when PCIE debug -level is enabled. For SDIO it is logged when user specifies a non-zero -console interval through debugfs. This patch tries to make it a -bit more consistent. The firmware console output is only logged when -FWCON debug level is enabled. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Pontus Fuchs -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h -@@ -37,6 +37,7 @@ - #define BRCMF_SDIO_VAL 0x00020000 - #define BRCMF_MSGBUF_VAL 0x00040000 - #define BRCMF_PCIE_VAL 0x00080000 -+#define BRCMF_FWCON_VAL 0x00100000 - - /* set default print format */ - #undef pr_fmt -@@ -78,6 +79,7 @@ do { \ - #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) - #define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL) - #define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL) -+#define BRCMF_FWCON_ON() (brcmf_msg_level & BRCMF_FWCON_VAL) - - #else /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */ - -@@ -90,6 +92,7 @@ do { \ - #define BRCMF_GLOM_ON() 0 - #define BRCMF_EVENT_ON() 0 - #define BRCMF_FIL_ON() 0 -+#define BRCMF_FWCON_ON() 0 - - #endif /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */ - ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -644,7 +644,7 @@ static void brcmf_pcie_bus_console_init( - addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET; - console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr); - -- brcmf_dbg(PCIE, "Console: base %x, buf %x, size %d\n", -+ brcmf_dbg(FWCON, "Console: base %x, buf %x, size %d\n", - console->base_addr, console->buf_addr, console->bufsize); - } - -@@ -656,6 +656,9 @@ static void brcmf_pcie_bus_console_read( - u8 ch; - u32 newidx; - -+ if (!BRCMF_FWCON_ON()) -+ return; -+ - console = &devinfo->shared.console; - addr = console->base_addr + BRCMF_CONSOLE_WRITEIDX_OFFSET; - newidx = brcmf_pcie_read_tcm32(devinfo, addr); -@@ -677,7 +680,7 @@ static void brcmf_pcie_bus_console_read( - } - if (ch == '\n') { - console->log_str[console->log_idx] = 0; -- brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str); -+ pr_debug("CONSOLE: %s", console->log_str); - console->log_idx = 0; - } - } ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -123,6 +123,7 @@ struct rte_console { - - #define BRCMF_FIRSTREAD (1 << 6) - -+#define BRCMF_CONSOLE 10 /* watchdog interval to poll console */ - - /* SBSDIO_DEVICE_CTL */ - -@@ -3204,6 +3205,8 @@ static void brcmf_sdio_debugfs_create(st - if (IS_ERR_OR_NULL(dentry)) - return; - -+ bus->console_interval = BRCMF_CONSOLE; -+ - brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read); - brcmf_debugfs_add_entry(drvr, "counters", - brcmf_debugfs_sdio_count_read); -@@ -3613,7 +3616,7 @@ static void brcmf_sdio_bus_watchdog(stru - } - #ifdef DEBUG - /* Poll for console output periodically */ -- if (bus->sdiodev->state == BRCMF_SDIOD_DATA && -+ if (bus->sdiodev->state == BRCMF_SDIOD_DATA && BRCMF_FWCON_ON() && - bus->console_interval != 0) { - bus->console.count += BRCMF_WD_POLL_MS; - if (bus->console.count >= bus->console_interval) { diff --git a/package/kernel/mac80211/patches/394-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch b/package/kernel/mac80211/patches/394-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch deleted file mode 100644 index 53e7edeee7..0000000000 --- a/package/kernel/mac80211/patches/394-0010-brcmfmac-remove-ifidx-parameter-from-brcmf_fws_txsta.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:15:02 +0200 -Subject: [PATCH] brcmfmac: remove ifidx parameter from - brcmf_fws_txstatus_suppressed() - -The brcmf_fws_txstatus_suppressed() function prototype specifies an -ifidx parameter which is not used within the function implementation. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -@@ -1398,7 +1398,7 @@ done: - } - - static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, -- struct sk_buff *skb, u8 ifidx, -+ struct sk_buff *skb, - u32 genbit, u16 seq) - { - struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; -@@ -1503,7 +1503,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i - return -EINVAL; - } - if (!remove_from_hanger) -- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx, -+ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, - genbit, seq); - if (remove_from_hanger || ret) - brcmf_txfinalize(ifp, skb, true); diff --git a/package/kernel/mac80211/patches/394-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch b/package/kernel/mac80211/patches/394-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch deleted file mode 100644 index bb05235cf4..0000000000 --- a/package/kernel/mac80211/patches/394-0011-brcmfmac-change-prototype-for-brcmf_fws_hdrpull.patch +++ /dev/null @@ -1,97 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:15:03 +0200 -Subject: [PATCH] brcmfmac: change prototype for brcmf_fws_hdrpull() - -Instead of passing ifidx and drvr just pass struct brcmf_if pointer -which holds both parameters. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c -@@ -312,8 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu - - skb_pull(pktbuf, BCDC_HEADER_LEN); - if (do_fws) -- brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2, -- pktbuf); -+ brcmf_fws_hdrpull(tmp_if, h->data_offset << 2, pktbuf); - else - skb_pull(pktbuf, h->data_offset << 2); - ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c -@@ -1616,11 +1616,10 @@ static int brcmf_fws_notify_bcmc_credit_ - return 0; - } - --int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, -- struct sk_buff *skb) -+void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb) - { - struct brcmf_skb_reorder_data *rd; -- struct brcmf_fws_info *fws = drvr->fws; -+ struct brcmf_fws_info *fws = ifp->drvr->fws; - u8 *signal_data; - s16 data_len; - u8 type; -@@ -1630,20 +1629,20 @@ int brcmf_fws_hdrpull(struct brcmf_pub * - s32 err; - - brcmf_dbg(HDRS, "enter: ifidx %d, skblen %u, sig %d\n", -- ifidx, skb->len, signal_len); -+ ifp->ifidx, skb->len, siglen); - -- WARN_ON(signal_len > skb->len); -+ WARN_ON(siglen > skb->len); - -- if (!signal_len) -- return 0; -+ if (!siglen) -+ return; - /* if flow control disabled, skip to packet data and leave */ - if ((!fws) || (!fws->fw_signals)) { -- skb_pull(skb, signal_len); -- return 0; -+ skb_pull(skb, siglen); -+ return; - } - - fws->stats.header_pulls++; -- data_len = signal_len; -+ data_len = siglen; - signal_data = skb->data; - - status = BRCMF_FWS_RET_OK_NOSCHEDULE; -@@ -1731,14 +1730,12 @@ int brcmf_fws_hdrpull(struct brcmf_pub * - /* signalling processing result does - * not affect the actual ethernet packet. - */ -- skb_pull(skb, signal_len); -+ skb_pull(skb, siglen); - - /* this may be a signal-only packet - */ - if (skb->len == 0) - fws->stats.header_only_pkt++; -- -- return 0; - } - - static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h -@@ -21,8 +21,7 @@ - int brcmf_fws_init(struct brcmf_pub *drvr); - void brcmf_fws_deinit(struct brcmf_pub *drvr); - bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); --int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, -- struct sk_buff *skb); -+void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb); - int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb); - - void brcmf_fws_reset_interface(struct brcmf_if *ifp); diff --git a/package/kernel/mac80211/patches/394-0012-brcmfmac-introduce-brcmf_net_detach-function.patch b/package/kernel/mac80211/patches/394-0012-brcmfmac-introduce-brcmf_net_detach-function.patch deleted file mode 100644 index ba92c6749b..0000000000 --- a/package/kernel/mac80211/patches/394-0012-brcmfmac-introduce-brcmf_net_detach-function.patch +++ /dev/null @@ -1,99 +0,0 @@ -From: Arend van Spriel -Date: Wed, 26 Aug 2015 22:15:04 +0200 -Subject: [PATCH] brcmfmac: introduce brcmf_net_detach() function - -In case of error during brcmf_bus_start() the network interfaces were -freed using free_netdev(). However, the interfaces may have additional -memory allocated which is not freed. The netdev has destructor set to -brcmf_cfg80211_free_netdev() which frees the additional memory if -allocated and call free_netdev(). The brcmf_net_detach() either calls -brcmf_cfg80211_free_netdev() directly or uses unregister_netdev() when -struct net_device::reg_state indicates the netdev was registered. - -Reported-by: Daniel (Deognyoun) Kim -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -4746,7 +4746,8 @@ void brcmf_cfg80211_free_netdev(struct n - ifp = netdev_priv(ndev); - vif = ifp->vif; - -- brcmf_free_vif(vif); -+ if (vif) -+ brcmf_free_vif(vif); - free_netdev(ndev); - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c -@@ -718,8 +718,6 @@ int brcmf_net_attach(struct brcmf_if *if - } - - brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); -- -- ndev->destructor = brcmf_cfg80211_free_netdev; - return 0; - - fail: -@@ -729,6 +727,14 @@ fail: - return -EBADE; - } - -+static void brcmf_net_detach(struct net_device *ndev) -+{ -+ if (ndev->reg_state == NETREG_REGISTERED) -+ unregister_netdev(ndev); -+ else -+ brcmf_cfg80211_free_netdev(ndev); -+} -+ - static int brcmf_net_p2p_open(struct net_device *ndev) - { - brcmf_dbg(TRACE, "Enter\n"); -@@ -805,8 +811,7 @@ struct brcmf_if *brcmf_add_if(struct brc - ifp->ndev->name); - if (ifidx) { - netif_stop_queue(ifp->ndev); -- unregister_netdev(ifp->ndev); -- free_netdev(ifp->ndev); -+ brcmf_net_detach(ifp->ndev); - drvr->iflist[bssidx] = NULL; - } else { - brcmf_err("ignore IF event\n"); -@@ -828,6 +833,7 @@ struct brcmf_if *brcmf_add_if(struct brc - if (!ndev) - return ERR_PTR(-ENOMEM); - -+ ndev->destructor = brcmf_cfg80211_free_netdev; - ifp = netdev_priv(ndev); - ifp->ndev = ndev; - /* store mapping ifidx to bssidx */ -@@ -879,8 +885,7 @@ static void brcmf_del_if(struct brcmf_pu - cancel_work_sync(&ifp->setmacaddr_work); - cancel_work_sync(&ifp->multicast_work); - } -- /* unregister will take care of freeing it */ -- unregister_netdev(ifp->ndev); -+ brcmf_net_detach(ifp->ndev); - } - } - -@@ -1056,11 +1061,11 @@ fail: - brcmf_fws_deinit(drvr); - } - if (drvr->iflist[0]) { -- free_netdev(ifp->ndev); -+ brcmf_net_detach(ifp->ndev); - drvr->iflist[0] = NULL; - } - if (p2p_ifp) { -- free_netdev(p2p_ifp->ndev); -+ brcmf_net_detach(p2p_ifp->ndev); - drvr->iflist[1] = NULL; - } - return ret; diff --git a/package/kernel/mac80211/patches/395-brcmfmac-Reset-PCIE-devices-after-recognition.patch b/package/kernel/mac80211/patches/395-brcmfmac-Reset-PCIE-devices-after-recognition.patch deleted file mode 100644 index 5a7e447e25..0000000000 --- a/package/kernel/mac80211/patches/395-brcmfmac-Reset-PCIE-devices-after-recognition.patch +++ /dev/null @@ -1,193 +0,0 @@ -From: Hante Meuleman -Date: Thu, 27 Aug 2015 16:14:06 +0200 -Subject: [PATCH] brcmfmac: Reset PCIE devices after recognition. - -When PCIE type devices are being FW reloaded without being properly -reset then the device ends up in a locked state, requiring the -device to be completely powered down. This patch adds a reset -through watchdog at the moment the device (cores) has been -recognized. This will solve warm reboot issues. - -Cc: Rafal Milecki -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c -@@ -101,6 +101,9 @@ - /* ARM Cortex M3 core, ID 0x82a */ - #define BCM4329_CORE_ARM_BASE 0x18002000 - -+/* Max possibly supported memory size (limited by IO mapped memory) */ -+#define BRCMF_CHIP_MAX_MEMSIZE (4 * 1024 * 1024) -+ - #define CORE_SB(base, field) \ - (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) - #define SBCOREREV(sbidh) \ -@@ -687,6 +690,12 @@ static int brcmf_chip_get_raminfo(struct - brcmf_err("RAM size is undetermined\n"); - return -ENOMEM; - } -+ -+ if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) { -+ brcmf_err("RAM size is incorrect\n"); -+ return -ENOMEM; -+ } -+ - return 0; - } - -@@ -899,6 +908,15 @@ static int brcmf_chip_recognition(struct - - /* assure chip is passive for core access */ - brcmf_chip_set_passive(&ci->pub); -+ -+ /* Call bus specific reset function now. Cores have been determined -+ * but further access may require a chip specific reset at this point. -+ */ -+ if (ci->ops->reset) { -+ ci->ops->reset(ci->ctx, &ci->pub); -+ brcmf_chip_set_passive(&ci->pub); -+ } -+ - return brcmf_chip_get_raminfo(ci); - } - ---- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h -@@ -73,6 +73,7 @@ struct brcmf_buscore_ops { - u32 (*read32)(void *ctx, u32 addr); - void (*write32)(void *ctx, u32 addr, u32 value); - int (*prepare)(void *ctx); -+ int (*reset)(void *ctx, struct brcmf_chip *chip); - int (*setup)(void *ctx, struct brcmf_chip *chip); - void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); - }; ---- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c -@@ -74,6 +74,8 @@ enum brcmf_pcie_state { - #define BRCMF_PCIE_REG_INTMASK 0x94 - #define BRCMF_PCIE_REG_SBMBX 0x98 - -+#define BRCMF_PCIE_REG_LINK_STATUS_CTRL 0xBC -+ - #define BRCMF_PCIE_PCIE2REG_INTMASK 0x24 - #define BRCMF_PCIE_PCIE2REG_MAILBOXINT 0x48 - #define BRCMF_PCIE_PCIE2REG_MAILBOXMASK 0x4C -@@ -466,6 +468,7 @@ brcmf_pcie_select_core(struct brcmf_pcie - - static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo) - { -+ struct brcmf_core *core; - u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD, - BRCMF_PCIE_CFGREG_PM_CSR, - BRCMF_PCIE_CFGREG_MSI_CAP, -@@ -484,32 +487,38 @@ static void brcmf_pcie_reset_device(stru - if (!devinfo->ci) - return; - -+ /* Disable ASPM */ - brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); -- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, -- BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL); -- lsc = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA); -+ pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL, -+ &lsc); - val = lsc & (~BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB); -- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, val); -+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL, -+ val); - -+ /* Watchdog reset */ - brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON); - WRITECC32(devinfo, watchdog, 4); - msleep(100); - -+ /* Restore ASPM */ - brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); -- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, -- BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL); -- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, lsc); -+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL, -+ lsc); - -- brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); -- for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) { -- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, -- cfg_offset[i]); -- val = brcmf_pcie_read_reg32(devinfo, -- BRCMF_PCIE_PCIE2REG_CONFIGDATA); -- brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n", -- cfg_offset[i], val); -- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, -- val); -+ core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2); -+ if (core->rev <= 13) { -+ for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) { -+ brcmf_pcie_write_reg32(devinfo, -+ BRCMF_PCIE_PCIE2REG_CONFIGADDR, -+ cfg_offset[i]); -+ val = brcmf_pcie_read_reg32(devinfo, -+ BRCMF_PCIE_PCIE2REG_CONFIGDATA); -+ brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n", -+ cfg_offset[i], val); -+ brcmf_pcie_write_reg32(devinfo, -+ BRCMF_PCIE_PCIE2REG_CONFIGDATA, -+ val); -+ } - } - } - -@@ -519,8 +528,6 @@ static void brcmf_pcie_attach(struct brc - u32 config; - - brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); -- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) -- brcmf_pcie_reset_device(devinfo); - /* BAR1 window may not be sized properly */ - brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); - brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0); -@@ -1636,6 +1643,23 @@ static int brcmf_pcie_buscoreprep(void * - } - - -+static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip) -+{ -+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; -+ u32 val; -+ -+ devinfo->ci = chip; -+ brcmf_pcie_reset_device(devinfo); -+ -+ val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); -+ if (val != 0xffffffff) -+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, -+ val); -+ -+ return 0; -+} -+ -+ - static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip, - u32 rstvec) - { -@@ -1647,6 +1671,7 @@ static void brcmf_pcie_buscore_activate( - - static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { - .prepare = brcmf_pcie_buscoreprep, -+ .reset = brcmf_pcie_buscore_reset, - .activate = brcmf_pcie_buscore_activate, - .read32 = brcmf_pcie_buscore_read32, - .write32 = brcmf_pcie_buscore_write32, -@@ -1814,7 +1839,6 @@ brcmf_pcie_remove(struct pci_dev *pdev) - brcmf_pcie_intr_disable(devinfo); - - brcmf_detach(&pdev->dev); -- brcmf_pcie_reset_device(devinfo); - - kfree(bus->bus_priv.pcie); - kfree(bus->msgbuf->flowrings); diff --git a/package/kernel/mac80211/patches/396-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch b/package/kernel/mac80211/patches/396-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch deleted file mode 100644 index f7b3e40b66..0000000000 --- a/package/kernel/mac80211/patches/396-ath10k-fix-DMA-related-firmware-crashes-on-multiple-.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Felix Fietkau -Date: Sun, 13 Sep 2015 22:26:10 +0200 -Subject: [PATCH] ath10k: fix DMA related firmware crashes on multiple devices - -Some platforms really don't like DMA bursts of 256 bytes, and this -causes the firmware to crash when sending beacons. -Also, changing this based on the firmware version does not seem to make -much sense, so use 128 bytes for all versions. - -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath10k/hw.h -+++ b/drivers/net/wireless/ath/ath10k/hw.h -@@ -253,7 +253,7 @@ struct ath10k_pktlog_hdr { - #define TARGET_10X_MAX_FRAG_ENTRIES 0 - - /* 10.2 parameters */ --#define TARGET_10_2_DMA_BURST_SIZE 1 -+#define TARGET_10_2_DMA_BURST_SIZE 0 - - /* Target specific defines for WMI-TLV firmware */ - #define TARGET_TLV_NUM_VDEVS 3 diff --git a/package/kernel/mac80211/patches/397-ath9k-declare-required-extra-tx-headroom.patch b/package/kernel/mac80211/patches/397-ath9k-declare-required-extra-tx-headroom.patch deleted file mode 100644 index c420d20bae..0000000000 --- a/package/kernel/mac80211/patches/397-ath9k-declare-required-extra-tx-headroom.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Date: Thu, 24 Sep 2015 16:57:37 +0200 -Subject: [PATCH] ath9k: declare required extra tx headroom - -ath9k inserts padding between the 802.11 header and the data area (to -align it). Since it didn't declare this extra required headroom, this -led to some nasty issues like randomly dropped packets in some setups. - -Cc: stable@vger.kernel.org -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -867,6 +867,7 @@ static void ath9k_set_hw_capab(struct at - hw->max_rate_tries = 10; - hw->sta_data_size = sizeof(struct ath_node); - hw->vif_data_size = sizeof(struct ath_vif); -+ hw->extra_tx_headroom = 4; - - hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; - hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1; diff --git a/package/kernel/mac80211/patches/398-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch b/package/kernel/mac80211/patches/398-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch deleted file mode 100644 index 1478efae77..0000000000 --- a/package/kernel/mac80211/patches/398-mac80211-initialize-tid-field-in-struct-ieee80211_tx.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -Date: Mon, 5 Oct 2015 17:41:25 +0200 -Subject: [PATCH] mac80211: initialize tid field in struct ieee80211_txq - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -3323,9 +3323,11 @@ void ieee80211_init_tx_queue(struct ieee - if (sta) { - txqi->txq.sta = &sta->sta; - sta->sta.txq[tid] = &txqi->txq; -+ txqi->txq.tid = tid; - txqi->txq.ac = ieee802_1d_to_ac[tid & 7]; - } else { - sdata->vif.txq = &txqi->txq; -+ txqi->txq.tid = 0; - txqi->txq.ac = IEEE80211_AC_BE; - } - } -- cgit v1.2.3