mac80211: update to wireless-testing 2017-01-31
authorFelix Fietkau <nbd@nbd.name>
Thu, 2 Feb 2017 11:02:22 +0000 (12:02 +0100)
committerFelix Fietkau <nbd@nbd.name>
Mon, 6 Feb 2017 11:27:12 +0000 (12:27 +0100)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
260 files changed:
package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/002-change_allconfig.patch
package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch [deleted file]
package/kernel/mac80211/patches/004-kconfig_backport_fix.patch [new file with mode: 0644]
package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch [deleted file]
package/kernel/mac80211/patches/005-revert-devcoredump.patch [new file with mode: 0644]
package/kernel/mac80211/patches/006-revert-ktime-changes.patch [new file with mode: 0644]
package/kernel/mac80211/patches/007-revert-genetlink-changes.patch [new file with mode: 0644]
package/kernel/mac80211/patches/008-revert-ndo_stats64-cleanup.patch [new file with mode: 0644]
package/kernel/mac80211/patches/009-revert-mtu-changes.patch [new file with mode: 0644]
package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch
package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch
package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch
package/kernel/mac80211/patches/130-mac80211-hwsim-hrtimer-clock.patch
package/kernel/mac80211/patches/150-disable_addr_notifier.patch
package/kernel/mac80211/patches/210-ap_scan.patch
package/kernel/mac80211/patches/300-ath9k-Switch-to-using-mac80211-intermediate-software.patch [deleted file]
package/kernel/mac80211/patches/300-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch [new file with mode: 0644]
package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch [deleted file]
package/kernel/mac80211/patches/301-ath9k_hw-issue-external-reset-for-QCA955x.patch [new file with mode: 0644]
package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch [deleted file]
package/kernel/mac80211/patches/302-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch [new file with mode: 0644]
package/kernel/mac80211/patches/303-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch [deleted file]
package/kernel/mac80211/patches/303-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch [new file with mode: 0644]
package/kernel/mac80211/patches/304-ath9k-force-rx_clear-when-disabling-rx.patch [new file with mode: 0644]
package/kernel/mac80211/patches/304-mac80211-add-hdrlen-to-ieee80211_tx_data.patch [deleted file]
package/kernel/mac80211/patches/305-ath9k-limit-retries-for-powersave-response-frames.patch [new file with mode: 0644]
package/kernel/mac80211/patches/305-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch [deleted file]
package/kernel/mac80211/patches/306-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch [new file with mode: 0644]
package/kernel/mac80211/patches/306-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch [deleted file]
package/kernel/mac80211/patches/307-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch [deleted file]
package/kernel/mac80211/patches/307-mac80211-add-hdrlen-to-ieee80211_tx_data.patch [new file with mode: 0644]
package/kernel/mac80211/patches/308-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch [deleted file]
package/kernel/mac80211/patches/308-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch [new file with mode: 0644]
package/kernel/mac80211/patches/309-ath9k-report-tx-status-on-EOSP.patch [deleted file]
package/kernel/mac80211/patches/309-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch [new file with mode: 0644]
package/kernel/mac80211/patches/310-ath9k-fix-block-ack-window-tracking-issues.patch [deleted file]
package/kernel/mac80211/patches/310-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch [new file with mode: 0644]
package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch [deleted file]
package/kernel/mac80211/patches/311-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch [new file with mode: 0644]
package/kernel/mac80211/patches/312-ath9k-report-tx-status-on-EOSP.patch [new file with mode: 0644]
package/kernel/mac80211/patches/312-mac80211-Use-rhltable-instead-of-rhashtable.patch [deleted file]
package/kernel/mac80211/patches/313-ath9k-fix-block-ack-window-tracking-issues.patch [new file with mode: 0644]
package/kernel/mac80211/patches/313-mac80211-fix-sequence-number-allocation-regression.patch [deleted file]
package/kernel/mac80211/patches/314-ath9k-rename-tx_complete_work-to-hw_check_work.patch [new file with mode: 0644]
package/kernel/mac80211/patches/314-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch [deleted file]
package/kernel/mac80211/patches/315-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch [new file with mode: 0644]
package/kernel/mac80211/patches/315-ath9k_hw-issue-external-reset-for-QCA955x.patch [deleted file]
package/kernel/mac80211/patches/316-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch [new file with mode: 0644]
package/kernel/mac80211/patches/316-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch [deleted file]
package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch [deleted file]
package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch [new file with mode: 0644]
package/kernel/mac80211/patches/318-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch [new file with mode: 0644]
package/kernel/mac80211/patches/318-mac80211-fix-up-mismerge-of-ieee80211_tx_dequeue.patch [deleted file]
package/kernel/mac80211/patches/319-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch [new file with mode: 0644]
package/kernel/mac80211/patches/319-mac80211-avoid-extra-memcpy-in-A-MSDU-head-creation.patch [deleted file]
package/kernel/mac80211/patches/320-mac80211-fix-A-MSDU-outer-SA-DA.patch [deleted file]
package/kernel/mac80211/patches/321-Revert-mac80211-allow-using-AP_LINK_PS-with-mac80211.patch [deleted file]
package/kernel/mac80211/patches/322-mac80211-update-A-MPDU-flag-on-tx-dequeue.patch [deleted file]
package/kernel/mac80211/patches/323-mac80211-remove-bogus-skb-vif-assignment.patch [deleted file]
package/kernel/mac80211/patches/324-mac80211-fix-A-MSDU-aggregation-with-fast-xmit-txq.patch [deleted file]
package/kernel/mac80211/patches/325-ath9k-fix-ath9k_hw_gpio_get-to-return-0-or-1-on-succ.patch [deleted file]
package/kernel/mac80211/patches/326-Documentation-dt-net-add-ath9k-wireless-device-bindi.patch [deleted file]
package/kernel/mac80211/patches/327-ath9k-add-a-helper-to-get-the-string-representation-.patch [deleted file]
package/kernel/mac80211/patches/328-ath9k-parse-the-device-configuration-from-an-OF-node.patch [deleted file]
package/kernel/mac80211/patches/329-ath9k-unlock-rcu-read-when-returning-early.patch [deleted file]
package/kernel/mac80211/patches/330-ath10k-wmi-alloc-chunk-should-use-DMA_BIDIRECTIONAL.patch [deleted file]
package/kernel/mac80211/patches/331-ath10k-free-host-mem-with-DMA_BIRECTIONAL-flag.patch [deleted file]
package/kernel/mac80211/patches/332-ath10k-Fix-failure-to-send-NULL-func-frame-for-10.4.patch [deleted file]
package/kernel/mac80211/patches/333-ath10k-Fix-soft-lockup-during-firmware-crash-hw-rest.patch [deleted file]
package/kernel/mac80211/patches/334-mac80211-minstrel_ht-move-supported-bitrate-mask-out.patch [deleted file]
package/kernel/mac80211/patches/335-mac80211-minstrel_ht-move-short-preamble-check-out-o.patch [deleted file]
package/kernel/mac80211/patches/336-mac80211-minstrel_ht-make-att_hist-and-succ_hist-u32.patch [deleted file]
package/kernel/mac80211/patches/337-mac80211-check-for-MCS-in-ieee80211_duration-before-.patch [deleted file]
package/kernel/mac80211/patches/338-mac80211-minstrel-remove-cur_prob-from-debugfs.patch [deleted file]
package/kernel/mac80211/patches/339-mac80211-minstrel-reduce-MINSTREL_SCALE.patch [deleted file]
package/kernel/mac80211/patches/340-mac80211-minstrel-store-probability-variance-instead.patch [deleted file]
package/kernel/mac80211/patches/341-mac80211-minstrel-make-prob_ewma-u16-instead-of-u32.patch [deleted file]
package/kernel/mac80211/patches/342-mac80211-minstrel_ht-remove-obsolete-if-for-3-stream.patch [deleted file]
package/kernel/mac80211/patches/343-cfg80211-limit-scan-results-cache-size.patch [deleted file]
package/kernel/mac80211/patches/344-ath9k-Introduce-airtime-fairness-scheduling-between-.patch [deleted file]
package/kernel/mac80211/patches/345-ath9k-Turn-ath_txq_lock-unlock-into-static-inlines.patch [deleted file]
package/kernel/mac80211/patches/346-ath5k-drop-bogus-warning-on-drv_set_key-with-unsuppo.patch [deleted file]
package/kernel/mac80211/patches/347-0001-cfg80211-move-function-checking-range-fit-to-util.c.patch [deleted file]
package/kernel/mac80211/patches/347-0002-cfg80211-support-ieee80211-freq-limit-DT-property.patch [deleted file]
package/kernel/mac80211/patches/347-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch [deleted file]
package/kernel/mac80211/patches/348-mac80211-initialize-SMPS-field-in-HT-capabilities.patch [deleted file]
package/kernel/mac80211/patches/349-mac80211-fix-legacy-invalid-rxrate.patch [deleted file]
package/kernel/mac80211/patches/350-mac80211-init-fastxmit-later.patch [deleted file]
package/kernel/mac80211/patches/351-mac80211-fix-tid-agg-null.patch [deleted file]
package/kernel/mac80211/patches/352-mac80211-prevent-skb-txq-mismatch.patch [deleted file]
package/kernel/mac80211/patches/354-ath9k-rename-tx_complete_work-to-hw_check_work.patch [deleted file]
package/kernel/mac80211/patches/355-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch [deleted file]
package/kernel/mac80211/patches/356-0001-brcmfmac-avoid-maybe-uninitialized-warning-in-brcmf_.patch [deleted file]
package/kernel/mac80211/patches/356-0002-brcmfmac-proto-add-callback-for-queuing-TX-data.patch [deleted file]
package/kernel/mac80211/patches/356-0003-brcmfmac-print-name-of-connect-status-event.patch [deleted file]
package/kernel/mac80211/patches/356-0004-brcmfmac-update-beacon-IE-after-bss-up-and-clear-whe.patch [deleted file]
package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch [deleted file]
package/kernel/mac80211/patches/357-0001-brcmfmac-add-pcie-host-dongle-interface-rev6-support.patch [deleted file]
package/kernel/mac80211/patches/357-0002-brcmfmac-add-support-for-43341-chip.patch [deleted file]
package/kernel/mac80211/patches/357-0003-brcmfmac-move-pno-helper-functions-in-separate-sourc.patch [deleted file]
package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch [deleted file]
package/kernel/mac80211/patches/357-0005-brcmfmac-change-prototype-for-brcmf_do_escan.patch [deleted file]
package/kernel/mac80211/patches/357-0006-brcmfmac-make-internal-escan-more-generic.patch [deleted file]
package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch [deleted file]
package/kernel/mac80211/patches/357-0008-brcmfmac-move-scheduled-scan-activation-to-pno-sourc.patch [deleted file]
package/kernel/mac80211/patches/357-0009-brcmfmac-use-provided-channels-for-scheduled-scan.patch [deleted file]
package/kernel/mac80211/patches/357-0010-brcmfmac-remove-restriction-from-.sched_scan_start-c.patch [deleted file]
package/kernel/mac80211/patches/357-0011-brcmfmac-use-requested-scan-interval-in-scheduled-sc.patch [deleted file]
package/kernel/mac80211/patches/357-0012-brcmfmac-fix-scheduled-scan-result-handling-for-newe.patch [deleted file]
package/kernel/mac80211/patches/358-0001-brcmfmac-fix-memory-leak-in-brcmf_cfg80211_attach.patch [deleted file]
package/kernel/mac80211/patches/358-0002-brcmfmac-fix-uninitialized-field-in-scheduled-scan-s.patch [deleted file]
package/kernel/mac80211/patches/359-0001-brcmfmac-fix-spelling-mistakes-on-Ivalid.patch [deleted file]
package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch [deleted file]
package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch [deleted file]
package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch [deleted file]
package/kernel/mac80211/patches/361-0001-brcmfmac-make-brcmf_of_probe-more-generic.patch [deleted file]
package/kernel/mac80211/patches/361-0002-brcmfmac-add-support-for-BCM43455-with-modalias-sdio.patch [deleted file]
package/kernel/mac80211/patches/361-0003-brcmfmac-fix-incorrect-event-channel-deduction.patch [deleted file]
package/kernel/mac80211/patches/362-0001-brcmfmac-drop-unneeded-function-declarations-from-he.patch [deleted file]
package/kernel/mac80211/patches/362-0002-brcmfmac-move-brcmf_c_set_joinpref_default-declarati.patch [deleted file]
package/kernel/mac80211/patches/362-0003-brcmfmac-drop-brcmf_bus_detach-and-inline-its-code.patch [deleted file]
package/kernel/mac80211/patches/362-0004-brcmfmac-rename-brcmf_bus_start-function-to-brcmf_bu.patch [deleted file]
package/kernel/mac80211/patches/363-brcmfmac-drop-duplicated-core-selection-from-brcmf_p.patch [deleted file]
package/kernel/mac80211/patches/364-0001-brcmfmac-provide-a-value-for-struct-wowlan_support-m.patch [deleted file]
package/kernel/mac80211/patches/364-0002-brcmfmac-fix-handling-firmware-results-for-wowl-netd.patch [deleted file]
package/kernel/mac80211/patches/364-0003-brcmfmac-allow-wowlan-support-to-be-per-device.patch [deleted file]
package/kernel/mac80211/patches/365-0001-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch [deleted file]
package/kernel/mac80211/patches/365-0002-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch [deleted file]
package/kernel/mac80211/patches/400-ath_move_debug_code.patch
package/kernel/mac80211/patches/402-ath_regd_optional.patch
package/kernel/mac80211/patches/406-ath_relax_default_regd.patch
package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch
package/kernel/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
package/kernel/mac80211/patches/501-ath9k_ahb_init.patch
package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch
package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch
package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
package/kernel/mac80211/patches/550-ath9k-Add-a-define-for-the-EEPROM-eepmisc-endianness.patch [deleted file]
package/kernel/mac80211/patches/550-ath9k-disable-bands-via-dt.patch [new file with mode: 0644]
package/kernel/mac80211/patches/551-ath9k-indicate-that-the-AR9003-EEPROM-template-value.patch [deleted file]
package/kernel/mac80211/patches/551-ath9k_ubnt_uap_plus_hsr.patch [new file with mode: 0644]
package/kernel/mac80211/patches/552-ath9k-Add-an-eeprom_ops-callback-for-retrieving-the-.patch [deleted file]
package/kernel/mac80211/patches/553-ath9k-replace-eeprom_param-EEP_MINOR_REV-with-get_ee.patch [deleted file]
package/kernel/mac80211/patches/554-ath9k-consistently-use-get_eeprom_rev-ah.patch [deleted file]
package/kernel/mac80211/patches/555-ath9k-Make-the-EEPROM-swapping-check-use-the-eepmisc.patch [deleted file]
package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch [deleted file]
package/kernel/mac80211/patches/557-ath9k-disable-bands-via-dt.patch [deleted file]
package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch [deleted file]
package/kernel/mac80211/patches/600-0001-rt2x00-rt2800lib-move-rt2800_drv_data-declaration-in.patch [deleted file]
package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch [deleted file]
package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch [deleted file]
package/kernel/mac80211/patches/600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch [deleted file]
package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch [deleted file]
package/kernel/mac80211/patches/600-0006-rt2x00-rt2800lib-init-additional-beacon-offset-regis.patch [deleted file]
package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch [deleted file]
package/kernel/mac80211/patches/600-0008-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch [deleted file]
package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch [deleted file]
package/kernel/mac80211/patches/600-0012-rt2x00-rt2800lib-add-channel-configuration-function-.patch [deleted file]
package/kernel/mac80211/patches/600-0013-rt2x00-rt2800lib-enable-RF3853-support.patch [deleted file]
package/kernel/mac80211/patches/600-0014-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch [deleted file]
package/kernel/mac80211/patches/600-0015-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch [deleted file]
package/kernel/mac80211/patches/600-0016-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch [deleted file]
package/kernel/mac80211/patches/600-0017-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0018-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch [deleted file]
package/kernel/mac80211/patches/600-0019-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0020-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch [deleted file]
package/kernel/mac80211/patches/600-0021-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch [deleted file]
package/kernel/mac80211/patches/600-0022-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch [deleted file]
package/kernel/mac80211/patches/600-0023-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch [deleted file]
package/kernel/mac80211/patches/600-0024-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0025-rt2x00-rt2800lib-use-correct-beacon-base-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0027-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch [deleted file]
package/kernel/mac80211/patches/600-0028-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch [deleted file]
package/kernel/mac80211/patches/600-0029-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0030-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch [deleted file]
package/kernel/mac80211/patches/600-0031-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch [deleted file]
package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch [deleted file]
package/kernel/mac80211/patches/600-0033-rt2x00-rt2800lib-use-high-memory-for-beacons-on-RT38.patch [deleted file]
package/kernel/mac80211/patches/600-0034-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch [deleted file]
package/kernel/mac80211/patches/600-01-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-02-rt2x00-rt2800lib-enable-support-for-RT3883.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-03-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-04-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-05-rt2x00-rt2800lib-add-channel-configuration-function-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-06-rt2x00-rt2800lib-enable-RF3853-support.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-07-rt2x00-rt2800lib-add-MAC-register-initialization-for.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-08-rt2x00-rt2800soc-fix-rt2800soc_disable_radio-for-RT3.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-09-rt2x00-rt2800lib-add-BBP-register-initialization-for.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-10-rt2x00-rt2800lib-add-RFCSR-initialization-for-RT3883.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-11-rt2x00-rt2800lib-use-the-extended-EEPROM-map-for-RT3.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-12-rt2x00-rt2800lib-force-rf-type-to-RF3853-on-RT3883.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-13-rt2x00-rt2800lib-add-channel-configuration-code-for-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-14-rt2x00-rt2800lib-fix-txpower_to_dev-function-for-RT3.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-15-rt2x00-rt2800lib-use-correct-txpower-calculation-fun.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-16-rt2x00-rt2800lib-hardcode-txmixer-gain-values-to-zer.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-17-rt2x00-rt2800lib-use-correct-RT-XWI-size-for-RT3883.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-18-rt2x00-rt2800lib-fix-antenna-configuration-for-RT388.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-19-rt2x00-rt2800lib-fix-LNA-gain-configuration-for-RT38.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-20-rt2x00-rt2800lib-fix-VGC-setup-for-RT3883.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-21-rt2x00-rt2800lib-fix-EEPROM-LNA-validation-for-RT388.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-22-rt2x00-rt2800lib-fix-txpower-compensation-for-RT3883.patch [new file with mode: 0644]
package/kernel/mac80211/patches/600-23-rt2x00-rt2800mmio-add-a-workaround-for-spurious-TX_F.patch [new file with mode: 0644]
package/kernel/mac80211/patches/601-rt2x00-introduce-rt2x00_platform_h.patch [new file with mode: 0644]
package/kernel/mac80211/patches/601-rt2x00-set_pci_mwi.patch [deleted file]
package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch [deleted file]
package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00eeprom.patch [new file with mode: 0644]
package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch [deleted file]
package/kernel/mac80211/patches/603-rt2x00-of_load_eeprom_filename.patch [new file with mode: 0644]
package/kernel/mac80211/patches/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/604-rt2x00-of_load_eeprom_filename.patch [deleted file]
package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch [deleted file]
package/kernel/mac80211/patches/606-rt2x00-allow_disabling_bands_through_platform_data.patch [new file with mode: 0644]
package/kernel/mac80211/patches/607-rt2x00-add_platform_data_mac_addr.patch [new file with mode: 0644]
package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch [deleted file]
package/kernel/mac80211/patches/608-00-rt2x00-get-mac-from-device-tree.patch [deleted file]
package/kernel/mac80211/patches/608-01-rt2x00-add_platform_data_mac_addr.patch [deleted file]
package/kernel/mac80211/patches/608-rt2x00-allow_disabling_bands_through_dts.patch [new file with mode: 0644]
package/kernel/mac80211/patches/609-rt2x00-allow_disabling_bands_through_dts.patch [deleted file]
package/kernel/mac80211/patches/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch [new file with mode: 0644]
package/kernel/mac80211/patches/610-rt2x00-change-led-polarity-from-OF.patch [new file with mode: 0644]
package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch [deleted file]
package/kernel/mac80211/patches/611-rt2x00-add-AP+STA-support.patch [new file with mode: 0644]
package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch [deleted file]
package/kernel/mac80211/patches/612-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch [deleted file]
package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch [deleted file]
package/kernel/mac80211/patches/619-rt2x00-change-led-polarity-from-OF.patch [deleted file]
package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch [deleted file]
package/kernel/mac80211/patches/620-rt2x00-enable-rt2800soc-for-mt7620.patch [new file with mode: 0644]
package/kernel/mac80211/patches/620-rt2x00-rt3352-rf-id.patch [deleted file]
package/kernel/mac80211/patches/621-rt2x00-add-support-for-mt7620.patch [new file with mode: 0644]
package/kernel/mac80211/patches/621-rt2x00-ht20_40_fix.patch [deleted file]
package/kernel/mac80211/patches/622-rt2x00-fix-beacon-bit-balance.patch [deleted file]
package/kernel/mac80211/patches/650-0001-rtl8xxxu-Fix-memory-leak-in-handling-rxdesc16-packet.patch [deleted file]
package/kernel/mac80211/patches/650-0002-rtl8xxxu-Fix-big-endian-problem-reporting-mactime.patch [deleted file]
package/kernel/mac80211/patches/651-0001-rtl8xxxu-Fix-rtl8723bu-driver-reload-issue.patch [deleted file]
package/kernel/mac80211/patches/651-0002-rtl8xxxu-Fix-rtl8192eu-driver-reload-issue.patch [deleted file]
package/kernel/mac80211/patches/652-0001-rtl8xxxu-Obtain-RTS-rates-from-mac80211.patch [deleted file]
package/kernel/mac80211/patches/652-0002-rtl8xxxu-Pass-tx_info-to-fill_txdesc-in-order-to-hav.patch [deleted file]
package/kernel/mac80211/patches/653-0002-rtl8xxxu-Add-initial-code-to-detect-8188eu-devices.patch
package/kernel/mac80211/patches/653-0035-rtl8xxxu-Implement-rtl8xxxu_fill_txdesc_v3-for-8188e.patch
package/kernel/mac80211/patches/653-0041-rtl8xxxu-8188eu-set-REG_OFDM0_XA_AGC_CORE1-to-match-.patch
package/kernel/mac80211/patches/653-0045-rtl8xxxu-Add-rtl8188etv-to-USB-device-list.patch
package/kernel/mac80211/patches/653-0046-rtl8xxxu-Add-sitecom-dongle-to-USB-device-list.patch
package/kernel/mac80211/patches/653-0049-rtl8xxxu-Add-rtl8188eu-USB-ID-for-D-Link-USB-GO-N150.patch
package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
package/kernel/mac80211/patches/812-b43-add-antenna-control.patch
package/kernel/mac80211/patches/840-brcmfmac-use-wiphy_read_of_freq_limits.patch [new file with mode: 0644]
package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch [deleted file]
package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch
package/kernel/mac80211/patches/910-00-rt2x00-enable-rt2800soc-for-mt7620.patch [deleted file]
package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch [deleted file]
package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch
package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch
package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch

index 2451143..5a591e4 100644 (file)
@@ -10,13 +10,13 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2016-10-08
+PKG_VERSION:=2017-01-31
 PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_BACKPORT_VERSION:=
-PKG_HASH:=4f6350e3b75815060bfdf47ef266ad613c7bfea5b7b1dc4552dee69e1bebe4fb
+PKG_HASH:=75e6d39e34cf156212a2509172a4a62b673b69eb4a1d9aaa565f7fa719fa2317
 
-PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
+PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.xz
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
 PKG_BUILD_PARALLEL:=1
 
index bd5bebf..a071ae6 100644 (file)
@@ -1,6 +1,6 @@
 --- a/kconf/conf.c
 +++ b/kconf/conf.c
-@@ -593,40 +593,12 @@ int main(int ac, char **av)
+@@ -594,40 +594,12 @@ int main(int ac, char **av)
        case oldconfig:
        case listnewconfig:
        case olddefconfig:
@@ -44,7 +44,7 @@
                break;
 --- a/kconf/confdata.c
 +++ b/kconf/confdata.c
-@@ -1169,6 +1169,8 @@ bool conf_set_all_new_symbols(enum conf_
+@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_
        }
        bool has_changed = false;
  
@@ -53,7 +53,7 @@
        for_all_symbols(i, sym) {
                if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
                        continue;
-@@ -1212,8 +1214,6 @@ bool conf_set_all_new_symbols(enum conf_
+@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_
  
        }
  
diff --git a/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch b/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch
deleted file mode 100644 (file)
index 38b3179..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/compat/Makefile
-+++ b/compat/Makefile
-@@ -35,8 +35,6 @@ compat-$(CPTCFG_KERNEL_4_6) += backport-
- compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o
- compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o
--skcipher-objs += crypto-skcipher.o
--obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o
- compat-$(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP) += drivers-base-devcoredump.o
- compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o
- cordic-objs += lib-cordic.o
diff --git a/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch b/package/kernel/mac80211/patches/004-kconfig_backport_fix.patch
new file mode 100644 (file)
index 0000000..f110298
--- /dev/null
@@ -0,0 +1,28 @@
+--- a/backport-include/linux/kconfig.h
++++ b/backport-include/linux/kconfig.h
+@@ -5,6 +5,8 @@
+ #include_next <linux/kconfig.h>
+ #endif
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
++
+ #ifndef __ARG_PLACEHOLDER_1
+ #define __ARG_PLACEHOLDER_1 0,
+ #define config_enabled(cfg) _config_enabled(cfg)
+@@ -16,6 +18,7 @@
+  * 3.1 - 3.3 had a broken version of this, so undef
+  * (they didn't have __ARG_PLACEHOLDER_1)
+  */
++
+ #undef IS_ENABLED
+ #define IS_ENABLED(option) \
+         (config_enabled(option) || config_enabled(option##_MODULE))
+@@ -24,6 +27,8 @@
+ #undef IS_BUILTIN
+ #define IS_BUILTIN(option) config_enabled(option)
++#endif
++
+ #ifndef IS_REACHABLE
+ /*
+  * IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled
diff --git a/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch b/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch
deleted file mode 100644 (file)
index 29bccc1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/backport-include/linux/skbuff.h
-+++ b/backport-include/linux/skbuff.h
-@@ -305,6 +305,19 @@ static inline void skb_free_frag(void *d
- {
-       put_page(virt_to_head_page(data));
- }
-+
-+#include <net/flow_keys.h>
-+#include <linux/jhash.h>
-+
-+static inline u32 skb_get_hash_perturb(struct sk_buff *skb, u32 key)
-+{
-+      struct flow_keys keys;
-+
-+      skb_flow_dissect(skb, &keys);
-+      return jhash_3words((__force u32)keys.dst,
-+                          (__force u32)keys.src ^ keys.ip_proto,
-+                          (__force u32)keys.ports, key);
-+}
- #endif
- #endif /* __BACKPORT_SKBUFF_H */
diff --git a/package/kernel/mac80211/patches/005-revert-devcoredump.patch b/package/kernel/mac80211/patches/005-revert-devcoredump.patch
new file mode 100644 (file)
index 0000000..ff46090
--- /dev/null
@@ -0,0 +1,152 @@
+--- a/compat/Makefile
++++ b/compat/Makefile
+@@ -35,8 +35,6 @@ compat-$(CPTCFG_KERNEL_4_6) += backport-
+ compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o
+ compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o
+-skcipher-objs += crypto-skcipher.o
+-obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o
+ compat-$(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP) += drivers-base-devcoredump.o
+ compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o
+ cordic-objs += lib-cordic.o
+--- a/compat/drivers-base-devcoredump.c
++++ b/compat/drivers-base-devcoredump.c
+@@ -31,6 +31,7 @@
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+ #include <linux/workqueue.h>
++#include "backports.h"
+ static struct class devcd_class;
+@@ -40,6 +41,10 @@ static bool devcd_disabled;
+ /* if data isn't read by userspace after 5 minutes then delete it */
+ #define DEVCD_TIMEOUT (HZ * 60 * 5)
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
++static struct bin_attribute devcd_attr_data;
++#endif
++
+ struct devcd_entry {
+       struct device devcd_dev;
+       void *data;
+@@ -69,8 +74,7 @@ static void devcd_dev_release(struct dev
+        * a struct device to know when it goes away?
+        */
+       if (devcd->failing_dev->kobj.sd)
+-              sysfs_delete_link(&devcd->failing_dev->kobj, &dev->kobj,
+-                                "devcoredump");
++              sysfs_remove_link(&devcd->failing_dev->kobj, "devcoredump");
+       put_device(devcd->failing_dev);
+       kfree(devcd);
+@@ -82,6 +86,9 @@ static void devcd_del(struct work_struct
+       devcd = container_of(wk, struct devcd_entry, del_wk.work);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
++      device_remove_bin_file(&devcd->devcd_dev, &devcd_attr_data);
++#endif
+       device_del(&devcd->devcd_dev);
+       put_device(&devcd->devcd_dev);
+ }
+@@ -115,6 +122,7 @@ static struct bin_attribute devcd_attr_d
+       .write = devcd_data_write,
+ };
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
+ static struct bin_attribute *devcd_dev_bin_attrs[] = {
+       &devcd_attr_data, NULL,
+ };
+@@ -126,6 +134,7 @@ static const struct attribute_group devc
+ static const struct attribute_group *devcd_dev_groups[] = {
+       &devcd_dev_group, NULL,
+ };
++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0) */
+ static int devcd_free(struct device *dev, void *data)
+ {
+@@ -160,18 +169,11 @@ static ssize_t disabled_store(struct cla
+       return count;
+ }
+-static CLASS_ATTR_RW(disabled);
+-static struct attribute *devcd_class_attrs[] = {
+-      &class_attr_disabled.attr,
+-      NULL,
++static struct class_attribute devcd_class_attrs[] = {
++      __ATTR_RW(disabled),
++      __ATTR_NULL
+ };
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
+-ATTRIBUTE_GROUPS(devcd_class);
+-#else
+-#define BP_ATTR_GRP_STRUCT device_attribute
+-ATTRIBUTE_GROUPS_BACKPORT(devcd_class);
+-#endif
+ static struct class devcd_class = {
+       .name           = "devcoredump",
+@@ -179,10 +181,8 @@ static struct class devcd_class = {
+       .dev_release    = devcd_dev_release,
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
+       .dev_groups     = devcd_dev_groups,
+-#else
+-      .dev_attrs = devcd_class_dev_attrs,
+ #endif
+-      .class_groups   = devcd_class_groups,
++      .class_attrs    = devcd_class_attrs,
+ };
+ static ssize_t devcd_readv(char *buffer, loff_t offset, size_t count,
+@@ -325,6 +325,11 @@ void dev_coredumpm(struct device *dev, s
+       if (device_add(&devcd->devcd_dev))
+               goto put_device;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)
++      if (device_create_bin_file(&devcd->devcd_dev, &devcd_attr_data))
++              goto put_device;
++#endif
++
+       if (sysfs_create_link(&devcd->devcd_dev.kobj, &dev->kobj,
+                             "failing_device"))
+               /* nothing - symlink will be missing */;
+@@ -367,16 +372,13 @@ void dev_coredumpsg(struct device *dev,
+ }
+ EXPORT_SYMBOL_GPL(dev_coredumpsg);
+-static int __init devcoredump_init(void)
++int __init devcoredump_init(void)
+ {
+-      init_devcd_class_attrs();
+       return class_register(&devcd_class);
+ }
+-__initcall(devcoredump_init);
+-static void __exit devcoredump_exit(void)
++void __exit devcoredump_exit(void)
+ {
+       class_for_each_device(&devcd_class, NULL, NULL, devcd_free);
+       class_unregister(&devcd_class);
+ }
+-__exitcall(devcoredump_exit);
+--- a/include/linux/backport-devcoredump.h
++++ b/include/linux/backport-devcoredump.h
+@@ -66,7 +66,7 @@ static inline void _devcd_free_sgtable(s
+ }
+-#ifdef CONFIG_DEV_COREDUMP
++#ifdef CPTCFG_BPAUTO_WANT_DEV_COREDUMP
+ void dev_coredumpv(struct device *dev, void *data, size_t datalen,
+                  gfp_t gfp);
+@@ -100,6 +100,6 @@ static inline void dev_coredumpsg(struct
+ {
+       _devcd_free_sgtable(table);
+ }
+-#endif /* CONFIG_DEV_COREDUMP */
++#endif /* CPTCFG_BPAUTO_WANT_DEV_COREDUMP */
+ #endif /* __DEVCOREDUMP_H */
diff --git a/package/kernel/mac80211/patches/006-revert-ktime-changes.patch b/package/kernel/mac80211/patches/006-revert-ktime-changes.patch
new file mode 100644 (file)
index 0000000..b839eb4
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+@@ -177,7 +177,7 @@ static bool rt2800usb_tx_sta_fifo_read_c
+       if (rt2800usb_txstatus_pending(rt2x00dev)) {
+               /* Read register after 1 ms */
+               hrtimer_start(&rt2x00dev->txstatus_timer,
+-                            TXSTATUS_READ_INTERVAL,
++                            ktime_set(0, TXSTATUS_READ_INTERVAL),
+                             HRTIMER_MODE_REL);
+               return false;
+       }
+@@ -204,7 +204,7 @@ static void rt2800usb_async_read_tx_stat
+       /* Read TX_STA_FIFO register after 2 ms */
+       hrtimer_start(&rt2x00dev->txstatus_timer,
+-                    2 * TXSTATUS_READ_INTERVAL,
++                    ktime_set(0, 2*TXSTATUS_READ_INTERVAL),
+                     HRTIMER_MODE_REL);
+ }
diff --git a/package/kernel/mac80211/patches/007-revert-genetlink-changes.patch b/package/kernel/mac80211/patches/007-revert-genetlink-changes.patch
new file mode 100644 (file)
index 0000000..1a85106
--- /dev/null
@@ -0,0 +1,266 @@
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -32,8 +32,22 @@ static int nl80211_crypto_settings(struc
+                                  struct cfg80211_crypto_settings *settings,
+                                  int cipher_limit);
++static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
++                          struct genl_info *info);
++static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
++                            struct genl_info *info);
++
+ /* the netlink family */
+-static struct genl_family nl80211_fam;
++static struct genl_family nl80211_fam = {
++      .id = GENL_ID_GENERATE,         /* don't bother with a hardcoded ID */
++      .name = NL80211_GENL_NAME,      /* have users key off the name instead */
++      .hdrsize = 0,                   /* no private header */
++      .version = 1,                   /* no particular meaning now */
++      .maxattr = NL80211_ATTR_MAX,
++      .netnsok = true,
++      .pre_doit = nl80211_pre_doit,
++      .post_doit = nl80211_post_doit,
++};
+ /* multicast groups */
+ enum nl80211_multicast_groups {
+@@ -549,14 +563,13 @@ static int nl80211_prepare_wdev_dump(str
+       if (!cb->args[0]) {
+               err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
+-                                genl_family_attrbuf(&nl80211_fam),
+-                                nl80211_fam.maxattr, nl80211_policy);
++                                nl80211_fam.attrbuf, nl80211_fam.maxattr,
++                                nl80211_policy);
+               if (err)
+                       goto out_unlock;
+-              *wdev = __cfg80211_wdev_from_attrs(
+-                                      sock_net(skb->sk),
+-                                      genl_family_attrbuf(&nl80211_fam));
++              *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
++                                                 nl80211_fam.attrbuf);
+               if (IS_ERR(*wdev)) {
+                       err = PTR_ERR(*wdev);
+                       goto out_unlock;
+@@ -1903,7 +1916,7 @@ static int nl80211_dump_wiphy_parse(stru
+                                   struct netlink_callback *cb,
+                                   struct nl80211_dump_wiphy_state *state)
+ {
+-      struct nlattr **tb = genl_family_attrbuf(&nl80211_fam);
++      struct nlattr **tb = nl80211_fam.attrbuf;
+       int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
+                             tb, nl80211_fam.maxattr, nl80211_policy);
+       /* ignore parse errors for backward compatibility */
+@@ -7733,7 +7746,6 @@ static int nl80211_send_survey(struct sk
+ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
+ {
+-      struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
+       struct survey_info survey;
+       struct cfg80211_registered_device *rdev;
+       struct wireless_dev *wdev;
+@@ -7746,7 +7758,7 @@ static int nl80211_dump_survey(struct sk
+               return res;
+       /* prepare_wdev_dump parsed the attributes */
+-      radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
++      radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
+       if (!wdev->netdev) {
+               res = -EINVAL;
+@@ -8594,14 +8606,14 @@ static int nl80211_testmode_dump(struct
+                */
+               phy_idx = cb->args[0] - 1;
+       } else {
+-              struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
+-
+               err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
+-                                attrbuf, nl80211_fam.maxattr, nl80211_policy);
++                                nl80211_fam.attrbuf, nl80211_fam.maxattr,
++                                nl80211_policy);
+               if (err)
+                       goto out_err;
+-              rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
++              rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
++                                                nl80211_fam.attrbuf);
+               if (IS_ERR(rdev)) {
+                       err = PTR_ERR(rdev);
+                       goto out_err;
+@@ -8609,8 +8621,9 @@ static int nl80211_testmode_dump(struct
+               phy_idx = rdev->wiphy_idx;
+               rdev = NULL;
+-              if (attrbuf[NL80211_ATTR_TESTDATA])
+-                      cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
++              if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
++                      cb->args[1] =
++                              (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
+       }
+       if (cb->args[1]) {
+@@ -10814,7 +10827,8 @@ static int handle_nan_filter(struct nlat
+       i = 0;
+       nla_for_each_nested(attr, attr_filter, rem) {
+-              filter[i].filter = nla_memdup(attr, GFP_KERNEL);
++              filter[i].filter = kmemdup(nla_data(attr), nla_len(attr),
++                                         GFP_KERNEL);
+               filter[i].len = nla_len(attr);
+               i++;
+       }
+@@ -11450,7 +11464,6 @@ static int nl80211_prepare_vendor_dump(s
+                                      struct cfg80211_registered_device **rdev,
+                                      struct wireless_dev **wdev)
+ {
+-      struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
+       u32 vid, subcmd;
+       unsigned int i;
+       int vcmd_idx = -1;
+@@ -11486,28 +11499,31 @@ static int nl80211_prepare_vendor_dump(s
+       }
+       err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
+-                        attrbuf, nl80211_fam.maxattr, nl80211_policy);
++                        nl80211_fam.attrbuf, nl80211_fam.maxattr,
++                        nl80211_policy);
+       if (err)
+               goto out_unlock;
+-      if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
+-          !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
++      if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] ||
++          !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
+               err = -EINVAL;
+               goto out_unlock;
+       }
+-      *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
++      *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
++                                         nl80211_fam.attrbuf);
+       if (IS_ERR(*wdev))
+               *wdev = NULL;
+-      *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
++      *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
++                                         nl80211_fam.attrbuf);
+       if (IS_ERR(*rdev)) {
+               err = PTR_ERR(*rdev);
+               goto out_unlock;
+       }
+-      vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
+-      subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
++      vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]);
++      subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
+       for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
+               const struct wiphy_vendor_command *vcmd;
+@@ -11531,9 +11547,9 @@ static int nl80211_prepare_vendor_dump(s
+               goto out_unlock;
+       }
+-      if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
+-              data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
+-              data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
++      if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) {
++              data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
++              data_len = nla_len(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
+       }
+       /* 0 is the first index - add 1 to parse only once */
+@@ -12795,21 +12811,6 @@ static __genl_const struct genl_ops nl80
+       },
+ };
+-static struct genl_family nl80211_fam __ro_after_init = {
+-      .name = NL80211_GENL_NAME,      /* have users key off the name instead */
+-      .hdrsize = 0,                   /* no private header */
+-      .version = 1,                   /* no particular meaning now */
+-      .maxattr = NL80211_ATTR_MAX,
+-      .netnsok = true,
+-      .pre_doit = nl80211_pre_doit,
+-      .post_doit = nl80211_post_doit,
+-      .module = THIS_MODULE,
+-      .ops = nl80211_ops,
+-      .n_ops = ARRAY_SIZE(nl80211_ops),
+-      .mcgrps = nl80211_mcgrps,
+-      .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
+-};
+-
+ /* notification functions */
+ void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
+@@ -14759,11 +14760,12 @@ void nl80211_send_ap_stopped(struct wire
+ /* initialisation/exit functions */
+-int __init nl80211_init(void)
++int nl80211_init(void)
+ {
+       int err;
+-      err = genl_register_family(&nl80211_fam);
++      err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
++                                                 nl80211_mcgrps);
+       if (err)
+               return err;
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -587,8 +587,15 @@ struct hwsim_radiotap_ack_hdr {
+       __le16 rt_chbitmask;
+ } __packed;
+-/* MAC80211_HWSIM netlink family */
+-static struct genl_family hwsim_genl_family;
++/* MAC80211_HWSIM netlinf family */
++static struct genl_family hwsim_genl_family = {
++      .id = GENL_ID_GENERATE,
++      .hdrsize = 0,
++      .name = "MAC80211_HWSIM",
++      .version = 1,
++      .maxattr = HWSIM_ATTR_MAX,
++      .netnsok = true,
++};
+ enum hwsim_multicast_groups {
+       HWSIM_MCGRP_CONFIG,
+@@ -3250,18 +3257,6 @@ static __genl_const struct genl_ops hwsi
+       },
+ };
+-static struct genl_family hwsim_genl_family __ro_after_init = {
+-      .name = "MAC80211_HWSIM",
+-      .version = 1,
+-      .maxattr = HWSIM_ATTR_MAX,
+-      .netnsok = true,
+-      .module = THIS_MODULE,
+-      .ops = hwsim_ops,
+-      .n_ops = ARRAY_SIZE(hwsim_ops),
+-      .mcgrps = hwsim_mcgrps,
+-      .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
+-};
+-
+ static void destroy_radio(struct work_struct *work)
+ {
+       struct mac80211_hwsim_data *data =
+@@ -3309,13 +3304,15 @@ static struct notifier_block hwsim_netli
+       .notifier_call = mac80211_hwsim_netlink_notify,
+ };
+-static int __init hwsim_init_netlink(void)
++static int hwsim_init_netlink(void)
+ {
+       int rc;
+       printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
+-      rc = genl_register_family(&hwsim_genl_family);
++      rc = genl_register_family_with_ops_groups(&hwsim_genl_family,
++                                                hwsim_ops,
++                                                hwsim_mcgrps);
+       if (rc)
+               goto failure;
diff --git a/package/kernel/mac80211/patches/008-revert-ndo_stats64-cleanup.patch b/package/kernel/mac80211/patches/008-revert-ndo_stats64-cleanup.patch
new file mode 100644 (file)
index 0000000..0f6f0f9
--- /dev/null
@@ -0,0 +1,20 @@
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -1133,7 +1133,7 @@ static u16 ieee80211_netdev_select_queue
+       return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
+ }
+-static void
++static struct rtnl_link_stats64 *
+ ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
+ {
+       int i;
+@@ -1158,6 +1158,8 @@ ieee80211_get_stats64(struct net_device
+               stats->rx_bytes   += rx_bytes;
+               stats->tx_bytes   += tx_bytes;
+       }
++
++      return stats;
+ }
+ static const struct net_device_ops ieee80211_dataif_ops = {
diff --git a/package/kernel/mac80211/patches/009-revert-mtu-changes.patch b/package/kernel/mac80211/patches/009-revert-mtu-changes.patch
new file mode 100644 (file)
index 0000000..f5e2757
--- /dev/null
@@ -0,0 +1,338 @@
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -151,6 +151,15 @@ void ieee80211_recalc_idle(struct ieee80
+               ieee80211_hw_config(local, change);
+ }
++static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
++{
++      if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN)
++              return -EINVAL;
++
++      dev->mtu = new_mtu;
++      return 0;
++}
++
+ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
+                               bool check_dup)
+ {
+@@ -1168,6 +1177,7 @@ static const struct net_device_ops ieee8
+       .ndo_uninit             = ieee80211_uninit,
+       .ndo_start_xmit         = ieee80211_subif_start_xmit,
+       .ndo_set_rx_mode        = ieee80211_set_multicast_list,
++      .ndo_change_mtu         = ieee80211_change_mtu,
+       .ndo_set_mac_address    = ieee80211_change_mac,
+       .ndo_select_queue       = ieee80211_netdev_select_queue,
+       .ndo_get_stats64        = ieee80211_get_stats64,
+@@ -1211,6 +1221,7 @@ static const struct net_device_ops ieee8
+       .ndo_uninit             = ieee80211_uninit,
+       .ndo_start_xmit         = ieee80211_monitor_start_xmit,
+       .ndo_set_rx_mode        = ieee80211_set_multicast_list,
++      .ndo_change_mtu         = ieee80211_change_mtu,
+       .ndo_set_mac_address    = ieee80211_change_mac,
+       .ndo_select_queue       = ieee80211_monitor_select_queue,
+       .ndo_get_stats64        = ieee80211_get_stats64,
+@@ -1919,10 +1930,6 @@ int ieee80211_if_add(struct ieee80211_lo
+               netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
+-              /* MTU range: 256 - 2304 */
+-              ndev->min_mtu = 256;
+-              ndev->max_mtu = IEEE80211_MAX_DATA_LEN;
+-
+               ret = register_netdevice(ndev);
+               if (ret) {
+                       ieee80211_if_free(ndev);
+--- a/drivers/net/wireless/ath/wil6210/netdev.c
++++ b/drivers/net/wireless/ath/wil6210/netdev.c
+@@ -42,6 +42,21 @@ static int wil_stop(struct net_device *n
+       return wil_down(wil);
+ }
++static int wil_change_mtu(struct net_device *ndev, int new_mtu)
++{
++      struct wil6210_priv *wil = ndev_to_wil(ndev);
++
++      if (new_mtu < 68 || new_mtu > mtu_max) {
++              wil_err(wil, "invalid MTU %d\n", new_mtu);
++              return -EINVAL;
++      }
++
++      wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu);
++      ndev->mtu = new_mtu;
++
++      return 0;
++}
++
+ static int wil_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
+ {
+       struct wil6210_priv *wil = ndev_to_wil(ndev);
+@@ -55,6 +70,7 @@ static const struct net_device_ops wil_n
+       .ndo_start_xmit         = wil_start_xmit,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
++      .ndo_change_mtu         = wil_change_mtu,
+       .ndo_do_ioctl           = wil_do_ioctl,
+ };
+@@ -111,7 +127,6 @@ static int wil6210_netdev_poll_tx(struct
+ static void wil_dev_setup(struct net_device *dev)
+ {
+       ether_setup(dev);
+-      dev->max_mtu = mtu_max;
+       dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
+ }
+--- a/drivers/net/wireless/atmel/atmel.c
++++ b/drivers/net/wireless/atmel/atmel.c
+@@ -1295,6 +1295,14 @@ static struct iw_statistics *atmel_get_w
+       return &priv->wstats;
+ }
++static int atmel_change_mtu(struct net_device *dev, int new_mtu)
++{
++      if ((new_mtu < 68) || (new_mtu > 2312))
++              return -EINVAL;
++      dev->mtu = new_mtu;
++      return 0;
++}
++
+ static int atmel_set_mac_address(struct net_device *dev, void *p)
+ {
+       struct sockaddr *addr = p;
+@@ -1498,6 +1506,7 @@ static const struct file_operations atme
+ static const struct net_device_ops atmel_netdev_ops = {
+       .ndo_open               = atmel_open,
+       .ndo_stop               = atmel_close,
++      .ndo_change_mtu         = atmel_change_mtu,
+       .ndo_set_mac_address    = atmel_set_mac_address,
+       .ndo_start_xmit         = start_tx,
+       .ndo_do_ioctl           = atmel_ioctl,
+@@ -1591,10 +1600,6 @@ struct net_device *init_atmel_card(unsig
+       dev->irq = irq;
+       dev->base_addr = port;
+-      /* MTU range: 68 - 2312 */
+-      dev->min_mtu = 68;
+-      dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
+-
+       SET_NETDEV_DEV(dev, sys_dev);
+       if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
+--- a/drivers/net/wireless/cisco/airo.c
++++ b/drivers/net/wireless/cisco/airo.c
+@@ -2329,6 +2329,14 @@ static int airo_set_mac_address(struct n
+       return 0;
+ }
++static int airo_change_mtu(struct net_device *dev, int new_mtu)
++{
++      if ((new_mtu < 68) || (new_mtu > 2400))
++              return -EINVAL;
++      dev->mtu = new_mtu;
++      return 0;
++}
++
+ static LIST_HEAD(airo_devices);
+ static void add_airo_dev(struct airo_info *ai)
+@@ -2648,6 +2656,7 @@ static const struct net_device_ops airo1
+       .ndo_get_stats          = airo_get_stats,
+       .ndo_set_mac_address    = airo_set_mac_address,
+       .ndo_do_ioctl           = airo_ioctl,
++      .ndo_change_mtu         = airo_change_mtu,
+ };
+ static void wifi_setup(struct net_device *dev)
+@@ -2659,8 +2668,6 @@ static void wifi_setup(struct net_device
+       dev->type               = ARPHRD_IEEE80211;
+       dev->hard_header_len    = ETH_HLEN;
+       dev->mtu                = AIRO_DEF_MTU;
+-      dev->min_mtu            = 68;
+-      dev->max_mtu            = MIC_MSGLEN_MAX;
+       dev->addr_len           = ETH_ALEN;
+       dev->tx_queue_len       = 100; 
+@@ -2747,6 +2754,7 @@ static const struct net_device_ops airo_
+       .ndo_set_rx_mode        = airo_set_multicast_list,
+       .ndo_set_mac_address    = airo_set_mac_address,
+       .ndo_do_ioctl           = airo_ioctl,
++      .ndo_change_mtu         = airo_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+ };
+@@ -2758,6 +2766,7 @@ static const struct net_device_ops mpi_n
+       .ndo_set_rx_mode        = airo_set_multicast_list,
+       .ndo_set_mac_address    = airo_set_mac_address,
+       .ndo_do_ioctl           = airo_ioctl,
++      .ndo_change_mtu         = airo_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+ };
+@@ -2813,7 +2822,6 @@ static struct net_device *_init_airo_car
+       dev->irq = irq;
+       dev->base_addr = port;
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+-      dev->max_mtu = MIC_MSGLEN_MAX;
+       SET_NETDEV_DEV(dev, dmdev);
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -6039,6 +6039,7 @@ static const struct net_device_ops ipw21
+       .ndo_open               = ipw2100_open,
+       .ndo_stop               = ipw2100_close,
+       .ndo_start_xmit         = libipw_xmit,
++      .ndo_change_mtu         = libipw_change_mtu,
+       .ndo_tx_timeout         = ipw2100_tx_timeout,
+       .ndo_set_mac_address    = ipw2100_set_address,
+       .ndo_validate_addr      = eth_validate_addr,
+@@ -6074,8 +6075,6 @@ static struct net_device *ipw2100_alloc_
+       dev->wireless_data = &priv->wireless_data;
+       dev->watchdog_timeo = 3 * HZ;
+       dev->irq = 0;
+-      dev->min_mtu = 68;
+-      dev->max_mtu = LIBIPW_DATA_LEN;
+       /* NOTE: We don't use the wireless_handlers hook
+        * in dev as the system will start throwing WX requests
+--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+@@ -11561,6 +11561,7 @@ static const struct net_device_ops ipw_p
+       .ndo_open               = ipw_prom_open,
+       .ndo_stop               = ipw_prom_stop,
+       .ndo_start_xmit         = ipw_prom_hard_start_xmit,
++      .ndo_change_mtu         = libipw_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+ };
+@@ -11586,9 +11587,6 @@ static int ipw_prom_alloc(struct ipw_pri
+       priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+       priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
+-      priv->prom_net_dev->min_mtu = 68;
+-      priv->prom_net_dev->max_mtu = LIBIPW_DATA_LEN;
+-
+       priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
+       SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
+@@ -11621,6 +11619,7 @@ static const struct net_device_ops ipw_n
+       .ndo_set_rx_mode        = ipw_net_set_multicast_list,
+       .ndo_set_mac_address    = ipw_net_set_mac_address,
+       .ndo_start_xmit         = libipw_xmit,
++      .ndo_change_mtu         = libipw_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+ };
+@@ -11730,9 +11729,6 @@ static int ipw_pci_probe(struct pci_dev
+       net_dev->wireless_handlers = &ipw_wx_handler_def;
+       net_dev->ethtool_ops = &ipw_ethtool_ops;
+-      net_dev->min_mtu = 68;
+-      net_dev->max_mtu = LIBIPW_DATA_LEN;
+-
+       err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
+       if (err) {
+               IPW_ERROR("failed to create sysfs device attributes\n");
+--- a/drivers/net/wireless/intel/ipw2x00/libipw.h
++++ b/drivers/net/wireless/intel/ipw2x00/libipw.h
+@@ -948,6 +948,7 @@ static inline int libipw_is_cck_rate(u8
+ /* libipw.c */
+ void free_libipw(struct net_device *dev, int monitor);
+ struct net_device *alloc_libipw(int sizeof_priv, int monitor);
++int libipw_change_mtu(struct net_device *dev, int new_mtu);
+ void libipw_networks_age(struct libipw_device *ieee, unsigned long age_secs);
+--- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c
++++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
+@@ -118,6 +118,15 @@ static void libipw_networks_initialize(s
+                             &ieee->network_free_list);
+ }
++int libipw_change_mtu(struct net_device *dev, int new_mtu)
++{
++      if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
++              return -EINVAL;
++      dev->mtu = new_mtu;
++      return 0;
++}
++EXPORT_SYMBOL(libipw_change_mtu);
++
+ struct net_device *alloc_libipw(int sizeof_priv, int monitor)
+ {
+       struct libipw_device *ieee;
+--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
++++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
+@@ -765,6 +765,16 @@ static void hostap_set_multicast_list(st
+ }
++static int prism2_change_mtu(struct net_device *dev, int new_mtu)
++{
++      if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU)
++              return -EINVAL;
++
++      dev->mtu = new_mtu;
++      return 0;
++}
++
++
+ static void prism2_tx_timeout(struct net_device *dev)
+ {
+       struct hostap_interface *iface;
+@@ -803,6 +813,7 @@ static const struct net_device_ops hosta
+       .ndo_do_ioctl           = hostap_ioctl,
+       .ndo_set_mac_address    = prism2_set_mac_address,
+       .ndo_set_rx_mode        = hostap_set_multicast_list,
++      .ndo_change_mtu         = prism2_change_mtu,
+       .ndo_tx_timeout         = prism2_tx_timeout,
+       .ndo_validate_addr      = eth_validate_addr,
+ };
+@@ -815,6 +826,7 @@ static const struct net_device_ops hosta
+       .ndo_do_ioctl           = hostap_ioctl,
+       .ndo_set_mac_address    = prism2_set_mac_address,
+       .ndo_set_rx_mode        = hostap_set_multicast_list,
++      .ndo_change_mtu         = prism2_change_mtu,
+       .ndo_tx_timeout         = prism2_tx_timeout,
+       .ndo_validate_addr      = eth_validate_addr,
+ };
+@@ -827,6 +839,7 @@ static const struct net_device_ops hosta
+       .ndo_do_ioctl           = hostap_ioctl,
+       .ndo_set_mac_address    = prism2_set_mac_address,
+       .ndo_set_rx_mode        = hostap_set_multicast_list,
++      .ndo_change_mtu         = prism2_change_mtu,
+       .ndo_tx_timeout         = prism2_tx_timeout,
+       .ndo_validate_addr      = eth_validate_addr,
+ };
+@@ -838,8 +851,6 @@ void hostap_setup_dev(struct net_device
+       iface = netdev_priv(dev);
+       ether_setup(dev);
+-      dev->min_mtu = PRISM2_MIN_MTU;
+-      dev->max_mtu = PRISM2_MAX_MTU;
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+       /* kernel callbacks */
+--- a/drivers/net/wireless/intersil/orinoco/main.c
++++ b/drivers/net/wireless/intersil/orinoco/main.c
+@@ -322,6 +322,9 @@ int orinoco_change_mtu(struct net_device
+ {
+       struct orinoco_private *priv = ndev_priv(dev);
++      if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
++              return -EINVAL;
++
+       /* MTU + encapsulation + header length */
+       if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
+            (priv->nicbuf_size - ETH_HLEN))
+@@ -2285,9 +2288,6 @@ int orinoco_if_add(struct orinoco_privat
+       dev->base_addr = base_addr;
+       dev->irq = irq;
+-      dev->min_mtu = ORINOCO_MIN_MTU;
+-      dev->max_mtu = ORINOCO_MAX_MTU;
+-
+       SET_NETDEV_DEV(dev, priv->dev);
+       ret = register_netdev(dev);
+       if (ret)
index 4df5ac5..527938f 100644 (file)
@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -477,45 +477,6 @@ USB_IPHETH=
+@@ -482,45 +482,6 @@ USB_IPHETH=
  USB_SIERRA_NET=
  USB_VL600=
  USB_NET_CH9200=
@@ -88,7 +88,7 @@
        gpiodev = bus->chipco.dev ? : pcidev;
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
-@@ -43,6 +43,6 @@ brcmsmac-y := \
+@@ -42,6 +42,6 @@ brcmsmac-y := \
        brcms_trace_events.o \
        debug.o
  
index fbe22e5..7eb3d99 100644 (file)
 -      aes_gcm.o \
        aes_cmac.o \
 -      aes_gmac.o \
+       fils_aead.o \
        cfg.o \
        ethtool.o \
-       rx.o \
 --- a/net/mac80211/aes_ccm.c
 +++ b/net/mac80211/aes_ccm.c
-@@ -13,89 +13,132 @@
+@@ -13,103 +13,132 @@
  #include <linux/types.h>
  #include <linux/err.h>
  #include <crypto/aead.h>
  #include "key.h"
  #include "aes_ccm.h"
  
--void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
--                             u8 *data, size_t data_len, u8 *mic,
--                             size_t mic_len)
+-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic,
+-                            size_t mic_len)
 +static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
 +                          u8 *a, u8 *b)
  {
 -      struct scatterlist sg[3];
+-      struct aead_request *aead_req;
+-      int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
+-      u8 *__aad;
 +      int i;
-+
+-      aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
+-      if (!aead_req)
+-              return -ENOMEM;
 +      crypto_cipher_encrypt_one(tfm, b, b_0);
-+
+-      __aad = (u8 *)aead_req + reqsize;
+-      memcpy(__aad, aad, CCM_AAD_LEN);
 +      /* Extra Authenticate-only data (always two AES blocks) */
 +      for (i = 0; i < AES_BLOCK_SIZE; i++)
 +              aad[i] ^= b[i];
 +      crypto_cipher_encrypt_one(tfm, b, aad);
-+
+-      sg_init_table(sg, 3);
+-      sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
+-      sg_set_buf(&sg[1], data, data_len);
+-      sg_set_buf(&sg[2], mic, mic_len);
 +      aad += AES_BLOCK_SIZE;
-+
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
+-      aead_request_set_ad(aead_req, sg[0].length);
 +      for (i = 0; i < AES_BLOCK_SIZE; i++)
 +              aad[i] ^= b[i];
 +      crypto_cipher_encrypt_one(tfm, a, aad);
  
--      char aead_req_data[sizeof(struct aead_request) +
--                         crypto_aead_reqsize(tfm)]
--              __aligned(__alignof__(struct aead_request));
--      struct aead_request *aead_req = (void *) aead_req_data;
+-      crypto_aead_encrypt(aead_req);
+-      kzfree(aead_req);
 +      /* Mask out bits from auth-only-b_0 */
 +      b_0[0] &= 0x07;
  
--      memset(aead_req, 0, sizeof(aead_req_data));
+-      return 0;
 +      /* S_0 is used to encrypt T (= MIC) */
 +      b_0[14] = 0;
 +      b_0[15] = 0;
 +      crypto_cipher_encrypt_one(tfm, s_0, b_0);
-+}
--      sg_init_table(sg, 3);
--      sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
--      sg_set_buf(&sg[1], data, data_len);
--      sg_set_buf(&sg[2], mic, mic_len);
+ }
  
--      aead_request_set_tfm(aead_req, tfm);
--      aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
--      aead_request_set_ad(aead_req, sg[0].length);
+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic,
+-                            size_t mic_len)
++
 +void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
 +                             u8 *data, size_t data_len, u8 *mic,
 +                             size_t mic_len)
-+{
+ {
+-      struct scatterlist sg[3];
+-      struct aead_request *aead_req;
+-      int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
+-      u8 *__aad;
+-      int err;
 +      int i, j, last_len, num_blocks;
 +      u8 b[AES_BLOCK_SIZE];
 +      u8 s_0[AES_BLOCK_SIZE];
 +      u8 e[AES_BLOCK_SIZE];
 +      u8 *pos, *cpos;
-+
+-      if (data_len == 0)
+-              return -EINVAL;
 +      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
 +      last_len = data_len % AES_BLOCK_SIZE;
 +      aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
-+
+-      aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
+-      if (!aead_req)
+-              return -ENOMEM;
 +      /* Process payload blocks */
 +      pos = data;
 +      cpos = data;
 +      for (j = 1; j <= num_blocks; j++) {
 +              int blen = (j == num_blocks && last_len) ?
 +                      last_len : AES_BLOCK_SIZE;
-+
+-      __aad = (u8 *)aead_req + reqsize;
+-      memcpy(__aad, aad, CCM_AAD_LEN);
 +              /* Authentication followed by encryption */
 +              for (i = 0; i < blen; i++)
 +                      b[i] ^= pos[i];
 +              crypto_cipher_encrypt_one(tfm, b, b);
-+
+-      sg_init_table(sg, 3);
+-      sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
+-      sg_set_buf(&sg[1], data, data_len);
+-      sg_set_buf(&sg[2], mic, mic_len);
 +              b_0[14] = (j >> 8) & 0xff;
 +              b_0[15] = j & 0xff;
 +              crypto_cipher_encrypt_one(tfm, e, b_0);
 +                      *cpos++ = *pos++ ^ e[i];
 +      }
  
--      crypto_aead_encrypt(aead_req);
+-      aead_request_set_tfm(aead_req, tfm);
+-      aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
+-      aead_request_set_ad(aead_req, sg[0].length);
 +      for (i = 0; i < mic_len; i++)
 +              mic[i] = b[i] ^ s_0[i];
- }
++}
  
--int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-      err = crypto_aead_decrypt(aead_req);
+-      kzfree(aead_req);
 +int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-                             u8 *data, size_t data_len, u8 *mic,
-                             size_t mic_len)
- {
--      struct scatterlist sg[3];
--      char aead_req_data[sizeof(struct aead_request) +
--                         crypto_aead_reqsize(tfm)]
--              __aligned(__alignof__(struct aead_request));
--      struct aead_request *aead_req = (void *) aead_req_data;
--
--      if (data_len == 0)
--              return -EINVAL;
--
--      memset(aead_req, 0, sizeof(aead_req_data));
--
--      sg_init_table(sg, 3);
--      sg_set_buf(&sg[0], &aad[2], be16_to_cpup((__be16 *)aad));
--      sg_set_buf(&sg[1], data, data_len);
--      sg_set_buf(&sg[2], mic, mic_len);
--
--      aead_request_set_tfm(aead_req, tfm);
--      aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
--      aead_request_set_ad(aead_req, sg[0].length);
++                            u8 *data, size_t data_len, u8 *mic,
++                            size_t mic_len)
++{
 +      int i, j, last_len, num_blocks;
 +      u8 *pos, *cpos;
 +      u8 a[AES_BLOCK_SIZE];
 +      u8 b[AES_BLOCK_SIZE];
 +      u8 s_0[AES_BLOCK_SIZE];
-+
+-      return err;
 +      num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
 +      last_len = data_len % AES_BLOCK_SIZE;
 +      aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
 +              if ((mic[i] ^ s_0[i]) != a[i])
 +                      return -1;
 +      }
--      return crypto_aead_decrypt(aead_req);
++
 +      return 0;
  }
  
  {
 -      struct crypto_aead *tfm;
 -      int err;
-+      struct crypto_cipher *tfm;
+-
 -      tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
 -      if (IS_ERR(tfm))
 -              return tfm;
--
++      struct crypto_cipher *tfm;
 -      err = crypto_aead_setkey(tfm, key, key_len);
 -      if (err)
 -              goto free_aead;
 -      crypto_free_aead(tfm);
 +      crypto_free_cipher(tfm);
  }
---- a/net/mac80211/aes_ccm.h
-+++ b/net/mac80211/aes_ccm.h
-@@ -12,15 +12,15 @@
- #include <linux/crypto.h>
--struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
--                                                  size_t key_len,
--                                                  size_t mic_len);
--void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
-+                                                    size_t key_len,
-+                                                    size_t mic_len);
-+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-                              u8 *data, size_t data_len, u8 *mic,
-                              size_t mic_len);
--int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
-+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
-                             u8 *data, size_t data_len, u8 *mic,
-                             size_t mic_len);
--void ieee80211_aes_key_free(struct crypto_aead *tfm);
-+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
- #endif /* AES_CCM_H */
---- a/net/mac80211/aes_gcm.h
-+++ b/net/mac80211/aes_gcm.h
-@@ -11,12 +11,28 @@
- #include <linux/crypto.h>
--void ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
--                             u8 *data, size_t data_len, u8 *mic);
--int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
--                            u8 *data, size_t data_len, u8 *mic);
--struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
--                                                      size_t key_len);
--void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
-+static inline void
-+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-+                        u8 *data, size_t data_len, u8 *mic)
-+{
-+}
-+
-+static inline int
-+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
-+                        u8 *data, size_t data_len, u8 *mic)
-+{
-+    return -EOPNOTSUPP;
-+}
-+
-+static inline struct crypto_aead *
-+ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
-+{
-+    return NULL;
-+}
-+
-+static inline void
-+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
-+{
-+}
- #endif /* AES_GCM_H */
 --- a/net/mac80211/aes_gmac.h
 +++ b/net/mac80211/aes_gmac.h
-@@ -11,10 +11,22 @@
- #include <linux/crypto.h>
+@@ -15,10 +15,22 @@
+ #define GMAC_MIC_LEN  16
+ #define GMAC_NONCE_LEN        12
  
 -struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
 -                                               size_t key_len);
                struct {
 --- a/net/mac80211/wpa.c
 +++ b/net/mac80211/wpa.c
-@@ -304,7 +304,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
+@@ -305,7 +305,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
  }
  
  
  {
        __le16 mask_fc;
        int a4_included, mgmt;
-@@ -334,14 +335,8 @@ static void ccmp_special_blocks(struct s
+@@ -335,14 +336,8 @@ static void ccmp_special_blocks(struct s
        else
                qos_tid = 0;
  
  
        /* Nonce: Nonce Flags | A2 | PN
         * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
-@@ -349,6 +344,8 @@ static void ccmp_special_blocks(struct s
+@@ -350,6 +345,8 @@ static void ccmp_special_blocks(struct s
        b_0[1] = qos_tid | (mgmt << 4);
        memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
        memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
  
        /* AAD (extra authenticate-only data) / masked 802.11 header
         * FC | A1 | A2 | A3 | SC | [A4] | [QC] */
-@@ -460,7 +457,7 @@ static int ccmp_encrypt_skb(struct ieee8
+@@ -406,7 +403,7 @@ static int ccmp_encrypt_skb(struct ieee8
+       u8 *pos;
+       u8 pn[6];
+       u64 pn64;
+-      u8 aad[CCM_AAD_LEN];
++      u8 aad[2 * AES_BLOCK_SIZE];
+       u8 b_0[AES_BLOCK_SIZE];
+       if (info->control.hw_key &&
+@@ -461,9 +458,11 @@ static int ccmp_encrypt_skb(struct ieee8
                return 0;
  
        pos += IEEE80211_CCMP_HDR_LEN;
 -      ccmp_special_blocks(skb, pn, b_0, aad);
+-      return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
+-                                       skb_put(skb, mic_len), mic_len);
 +      ccmp_special_blocks(skb, pn, b_0, aad, len);
-       ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
-                                 skb_put(skb, mic_len), mic_len);
++      ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
++                                skb_put(skb, mic_len), mic_len);
++
++      return 0;
+ }
  
-@@ -537,7 +534,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
+@@ -536,7 +535,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
                        u8 aad[2 * AES_BLOCK_SIZE];
                        u8 b_0[AES_BLOCK_SIZE];
                        /* hardware didn't decrypt/verify MIC */
  
                        if (ieee80211_aes_ccm_decrypt(
                                    key->u.ccmp.tfm, b_0, aad,
+@@ -638,7 +637,7 @@ static int gcmp_encrypt_skb(struct ieee8
+       u8 *pos;
+       u8 pn[6];
+       u64 pn64;
+-      u8 aad[GCM_AAD_LEN];
++      u8 aad[2 * AES_BLOCK_SIZE];
+       u8 j_0[AES_BLOCK_SIZE];
+       if (info->control.hw_key &&
+@@ -695,8 +694,10 @@ static int gcmp_encrypt_skb(struct ieee8
+       pos += IEEE80211_GCMP_HDR_LEN;
+       gcmp_special_blocks(skb, pn, j_0, aad);
+-      return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
+-                                       skb_put(skb, IEEE80211_GCMP_MIC_LEN));
++      ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
++                                skb_put(skb, IEEE80211_GCMP_MIC_LEN));
++
++      return 0;
+ }
+ ieee80211_tx_result
+@@ -1120,9 +1121,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct
+       struct ieee80211_key *key = tx->key;
+       struct ieee80211_mmie_16 *mmie;
+       struct ieee80211_hdr *hdr;
+-      u8 aad[GMAC_AAD_LEN];
++      u8 aad[20];
+       u64 pn64;
+-      u8 nonce[GMAC_NONCE_LEN];
++      u8 nonce[12];
+       if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
+               return TX_DROP;
+@@ -1168,7 +1169,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       struct ieee80211_key *key = rx->key;
+       struct ieee80211_mmie_16 *mmie;
+-      u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN];
++      u8 aad[20], mic[16], ipn[6], nonce[12];
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       if (!ieee80211_is_mgmt(hdr->frame_control))
+--- a/net/mac80211/aes_ccm.h
++++ b/net/mac80211/aes_ccm.h
+@@ -12,17 +12,15 @@
+ #include <linux/crypto.h>
+-#define CCM_AAD_LEN   32
+-
+-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
+-                                                  size_t key_len,
+-                                                  size_t mic_len);
+-int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic,
+-                            size_t mic_len);
+-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
++struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
++                                                    size_t key_len,
++                                                    size_t mic_len);
++void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
++                             u8 *data, size_t data_len, u8 *mic,
++                             size_t mic_len);
++int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
+                             u8 *data, size_t data_len, u8 *mic,
+                             size_t mic_len);
+-void ieee80211_aes_key_free(struct crypto_aead *tfm);
++void ieee80211_aes_key_free(struct crypto_cipher *tfm);
+ #endif /* AES_CCM_H */
+--- a/net/mac80211/aes_gcm.h
++++ b/net/mac80211/aes_gcm.h
+@@ -11,14 +11,28 @@
+ #include <linux/crypto.h>
+-#define GCM_AAD_LEN   32
++static inline void
++ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
++                        u8 *data, size_t data_len, u8 *mic)
++{
++}
+-int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic);
+-int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
+-                            u8 *data, size_t data_len, u8 *mic);
+-struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
+-                                                      size_t key_len);
+-void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
++static inline int
++ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
++                        u8 *data, size_t data_len, u8 *mic)
++{
++    return -EOPNOTSUPP;
++}
++
++static inline struct crypto_aead *
++ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
++{
++    return NULL;
++}
++
++static inline void
++ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
++{
++}
+ #endif /* AES_GCM_H */
index c42b17d..ff61912 100644 (file)
@@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
 
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1016,7 +1016,6 @@ static int ieee80211_stop_ap(struct wiph
+@@ -1014,7 +1014,6 @@ static int ieee80211_stop_ap(struct wiph
        sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
  
        __sta_info_flush(sdata, true);
index 29d7034..828ed83 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/mac80211_hwsim.c
 +++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -2662,7 +2662,7 @@ static int mac80211_hwsim_new_radio(stru
+@@ -2678,7 +2678,7 @@ static int mac80211_hwsim_new_radio(stru
  
        tasklet_hrtimer_init(&data->beacon_timer,
                             mac80211_hwsim_beacon,
index f4cb41c..ca1e53f 100644 (file)
@@ -18,7 +18,7 @@
  static int ieee80211_ifa6_changed(struct notifier_block *nb,
                                  unsigned long data, void *arg)
  {
-@@ -1101,14 +1101,14 @@ int ieee80211_register_hw(struct ieee802
+@@ -1111,14 +1111,14 @@ int ieee80211_register_hw(struct ieee802
        if (result)
                goto fail_flows;
  
@@ -35,7 +35,7 @@
        local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
        result = register_inet6addr_notifier(&local->ifa6_notifier);
        if (result)
-@@ -1117,13 +1117,13 @@ int ieee80211_register_hw(struct ieee802
+@@ -1127,13 +1127,13 @@ int ieee80211_register_hw(struct ieee802
  
        return 0;
  
@@ -52,7 +52,7 @@
   fail_ifa:
  #endif
        ieee80211_txq_teardown_flows(local);
-@@ -1153,10 +1153,10 @@ void ieee80211_unregister_hw(struct ieee
+@@ -1163,10 +1163,10 @@ void ieee80211_unregister_hw(struct ieee
        tasklet_kill(&local->tx_pending_tasklet);
        tasklet_kill(&local->tasklet);
  
index 94f5f39..3b613bb 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2175,7 +2175,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -2165,7 +2165,7 @@ static int ieee80211_scan(struct wiphy *
                 * the  frames sent while scanning on other channel will be
                 * lost)
                 */
diff --git a/package/kernel/mac80211/patches/300-ath9k-Switch-to-using-mac80211-intermediate-software.patch b/package/kernel/mac80211/patches/300-ath9k-Switch-to-using-mac80211-intermediate-software.patch
deleted file mode 100644 (file)
index b93d116..0000000
+++ /dev/null
@@ -1,953 +0,0 @@
-From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk>
-Date: Fri, 2 Sep 2016 16:00:30 +0200
-Subject: [PATCH] ath9k: Switch to using mac80211 intermediate software
- queues.
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This switches ath9k over to using the mac80211 intermediate software
-queueing mechanism for data packets. It removes the queueing inside the
-driver, except for the retry queue, and instead pulls from mac80211 when
-a packet is needed. The retry queue is used to store a packet that was
-pulled but can't be sent immediately.
-
-The old code path in ath_tx_start that would queue packets has been
-removed completely, as has the qlen limit tunables (since there's no
-longer a queue in the driver to limit).
-
-Based on Tim's original patch set, but reworked quite thoroughly.
-
-Cc: Tim Shepard <shep@alum.mit.edu>
-Cc: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
----
-
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -91,7 +91,6 @@ int ath_descdma_setup(struct ath_softc *
- #define ATH_RXBUF               512
- #define ATH_TXBUF               512
- #define ATH_TXBUF_RESERVE       5
--#define ATH_MAX_QDEPTH          (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
- #define ATH_TXMAXTRY            13
- #define ATH_MAX_SW_RETRIES      30
-@@ -145,7 +144,7 @@ int ath_descdma_setup(struct ath_softc *
- #define BAW_WITHIN(_start, _bawsz, _seqno) \
-       ((((_seqno) - (_start)) & 4095) < (_bawsz))
--#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
-+#define ATH_AN_2_TID(_an, _tidno) ath_node_to_tid(_an, _tidno)
- #define IS_HT_RATE(rate)   (rate & 0x80)
- #define IS_CCK_RATE(rate)  ((rate >= 0x18) && (rate <= 0x1e))
-@@ -164,7 +163,6 @@ struct ath_txq {
-       spinlock_t axq_lock;
-       u32 axq_depth;
-       u32 axq_ampdu_depth;
--      bool stopped;
-       bool axq_tx_inprogress;
-       struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
-       u8 txq_headidx;
-@@ -232,7 +230,6 @@ struct ath_buf {
- struct ath_atx_tid {
-       struct list_head list;
--      struct sk_buff_head buf_q;
-       struct sk_buff_head retry_q;
-       struct ath_node *an;
-       struct ath_txq *txq;
-@@ -247,13 +244,13 @@ struct ath_atx_tid {
-       s8 bar_index;
-       bool active;
-       bool clear_ps_filter;
-+      bool has_queued;
- };
- struct ath_node {
-       struct ath_softc *sc;
-       struct ieee80211_sta *sta; /* station struct we're part of */
-       struct ieee80211_vif *vif; /* interface with which we're associated */
--      struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
-       u16 maxampdu;
-       u8 mpdudensity;
-@@ -276,7 +273,6 @@ struct ath_tx_control {
-       struct ath_node *an;
-       struct ieee80211_sta *sta;
-       u8 paprd;
--      bool force_channel;
- };
-@@ -293,7 +289,6 @@ struct ath_tx {
-       struct ath_descdma txdma;
-       struct ath_txq *txq_map[IEEE80211_NUM_ACS];
-       struct ath_txq *uapsdq;
--      u32 txq_max_pending[IEEE80211_NUM_ACS];
-       u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32];
- };
-@@ -421,6 +416,22 @@ struct ath_offchannel {
-       int duration;
- };
-+static inline struct ath_atx_tid *
-+ath_node_to_tid(struct ath_node *an, u8 tidno)
-+{
-+      struct ieee80211_sta *sta = an->sta;
-+      struct ieee80211_vif *vif = an->vif;
-+      struct ieee80211_txq *txq;
-+
-+      BUG_ON(!vif);
-+      if (sta)
-+              txq = sta->txq[tidno % ARRAY_SIZE(sta->txq)];
-+      else
-+              txq = vif->txq;
-+
-+      return (struct ath_atx_tid *) txq->drv_priv;
-+}
-+
- #define case_rtn_string(val) case val: return #val
- #define ath_for_each_chanctx(_sc, _ctx)                             \
-@@ -575,7 +586,6 @@ void ath_tx_edma_tasklet(struct ath_soft
- int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-                     u16 tid, u16 *ssn);
- void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
--void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
- void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
- void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
-@@ -585,6 +595,7 @@ void ath9k_release_buffered_frames(struc
-                                  u16 tids, int nframes,
-                                  enum ieee80211_frame_release_type reason,
-                                  bool more_data);
-+void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue);
- /********/
- /* VIFs */
---- a/drivers/net/wireless/ath/ath9k/channel.c
-+++ b/drivers/net/wireless/ath/ath9k/channel.c
-@@ -1010,7 +1010,6 @@ static void ath_scan_send_probe(struct a
-               goto error;
-       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
--      txctl.force_channel = true;
-       if (ath_tx_start(sc->hw, skb, &txctl))
-               goto error;
-@@ -1133,7 +1132,6 @@ ath_chanctx_send_vif_ps_frame(struct ath
-       memset(&txctl, 0, sizeof(txctl));
-       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
-       txctl.sta = sta;
--      txctl.force_channel = true;
-       if (ath_tx_start(sc->hw, skb, &txctl)) {
-               ieee80211_free_txskb(sc->hw, skb);
-               return false;
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -600,7 +600,6 @@ static int read_file_xmit(struct seq_fil
-       PR("MPDUs XRetried:  ", xretries);
-       PR("Aggregates:      ", a_aggr);
-       PR("AMPDUs Queued HW:", a_queued_hw);
--      PR("AMPDUs Queued SW:", a_queued_sw);
-       PR("AMPDUs Completed:", a_completed);
-       PR("AMPDUs Retried:  ", a_retries);
-       PR("AMPDUs XRetried: ", a_xretries);
-@@ -629,8 +628,7 @@ static void print_queue(struct ath_softc
-       seq_printf(file, "%s: %d ", "qnum", txq->axq_qnum);
-       seq_printf(file, "%s: %2d ", "qdepth", txq->axq_depth);
-       seq_printf(file, "%s: %2d ", "ampdu-depth", txq->axq_ampdu_depth);
--      seq_printf(file, "%s: %3d ", "pending", txq->pending_frames);
--      seq_printf(file, "%s: %d\n", "stopped", txq->stopped);
-+      seq_printf(file, "%s: %3d\n", "pending", txq->pending_frames);
-       ath_txq_unlock(sc, txq);
- }
-@@ -1208,7 +1206,6 @@ static const char ath9k_gstrings_stats[]
-       AMKSTR(d_tx_mpdu_xretries),
-       AMKSTR(d_tx_aggregates),
-       AMKSTR(d_tx_ampdus_queued_hw),
--      AMKSTR(d_tx_ampdus_queued_sw),
-       AMKSTR(d_tx_ampdus_completed),
-       AMKSTR(d_tx_ampdu_retries),
-       AMKSTR(d_tx_ampdu_xretries),
-@@ -1288,7 +1285,6 @@ void ath9k_get_et_stats(struct ieee80211
-       AWDATA(xretries);
-       AWDATA(a_aggr);
-       AWDATA(a_queued_hw);
--      AWDATA(a_queued_sw);
-       AWDATA(a_completed);
-       AWDATA(a_retries);
-       AWDATA(a_xretries);
-@@ -1346,14 +1342,6 @@ int ath9k_init_debug(struct ath_hw *ah)
-                                   read_file_xmit);
-       debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy,
-                                   read_file_queues);
--      debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
--                         &sc->tx.txq_max_pending[IEEE80211_AC_BK]);
--      debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
--                         &sc->tx.txq_max_pending[IEEE80211_AC_BE]);
--      debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
--                         &sc->tx.txq_max_pending[IEEE80211_AC_VI]);
--      debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
--                         &sc->tx.txq_max_pending[IEEE80211_AC_VO]);
-       debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy,
-                                   read_file_misc);
-       debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy,
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -147,7 +147,6 @@ struct ath_interrupt_stats {
-  * @completed: Total MPDUs (non-aggr) completed
-  * @a_aggr: Total no. of aggregates queued
-  * @a_queued_hw: Total AMPDUs queued to hardware
-- * @a_queued_sw: Total AMPDUs queued to software queues
-  * @a_completed: Total AMPDUs completed
-  * @a_retries: No. of AMPDUs retried (SW)
-  * @a_xretries: No. of AMPDUs dropped due to xretries
-@@ -174,7 +173,6 @@ struct ath_tx_stats {
-       u32 xretries;
-       u32 a_aggr;
-       u32 a_queued_hw;
--      u32 a_queued_sw;
-       u32 a_completed;
-       u32 a_retries;
-       u32 a_xretries;
---- a/drivers/net/wireless/ath/ath9k/debug_sta.c
-+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c
-@@ -52,8 +52,8 @@ static ssize_t read_file_node_aggr(struc
-                        "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
-                        "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
--      for (tidno = 0, tid = &an->tid[tidno];
--           tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
-+      for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
-+              tid = ath_node_to_tid(an, tidno);
-               txq = tid->txq;
-               ath_txq_lock(sc, txq);
-               if (tid->active) {
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -358,7 +358,6 @@ static int ath9k_init_queues(struct ath_
-       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-               sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
-               sc->tx.txq_map[i]->mac80211_qnum = i;
--              sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH;
-       }
-       return 0;
- }
-@@ -877,6 +876,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->txq_data_size = sizeof(struct ath_atx_tid);
-       hw->extra_tx_headroom = 4;
-       hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1902,9 +1902,11 @@ static int ath9k_ampdu_action(struct iee
-       bool flush = false;
-       int ret = 0;
-       struct ieee80211_sta *sta = params->sta;
-+      struct ath_node *an = (struct ath_node *)sta->drv_priv;
-       enum ieee80211_ampdu_mlme_action action = params->action;
-       u16 tid = params->tid;
-       u16 *ssn = &params->ssn;
-+      struct ath_atx_tid *atid;
-       mutex_lock(&sc->mutex);
-@@ -1937,9 +1939,9 @@ static int ath9k_ampdu_action(struct iee
-               ath9k_ps_restore(sc);
-               break;
-       case IEEE80211_AMPDU_TX_OPERATIONAL:
--              ath9k_ps_wakeup(sc);
--              ath_tx_aggr_resume(sc, sta, tid);
--              ath9k_ps_restore(sc);
-+              atid = ath_node_to_tid(an, tid);
-+              atid->baw_size = IEEE80211_MIN_AMPDU_BUF <<
-+                              sta->ht_cap.ampdu_factor;
-               break;
-       default:
-               ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
-@@ -2701,4 +2703,5 @@ struct ieee80211_ops ath9k_ops = {
-       .sw_scan_start      = ath9k_sw_scan_start,
-       .sw_scan_complete   = ath9k_sw_scan_complete,
-       .get_txpower        = ath9k_get_txpower,
-+      .wake_tx_queue      = ath9k_wake_tx_queue,
- };
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -67,6 +67,8 @@ static struct ath_buf *ath_tx_setup_buff
-                                          struct ath_txq *txq,
-                                          struct ath_atx_tid *tid,
-                                          struct sk_buff *skb);
-+static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb,
-+                        struct ath_tx_control *txctl);
- enum {
-       MCS_HT20,
-@@ -137,6 +139,26 @@ static void ath_tx_queue_tid(struct ath_
-               list_add_tail(&tid->list, list);
- }
-+void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
-+{
-+      struct ath_softc *sc = hw->priv;
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+      struct ath_atx_tid *tid = (struct ath_atx_tid *) queue->drv_priv;
-+      struct ath_txq *txq = tid->txq;
-+
-+      ath_dbg(common, QUEUE, "Waking TX queue: %pM (%d)\n",
-+              queue->sta ? queue->sta->addr : queue->vif->addr,
-+              tid->tidno);
-+
-+      ath_txq_lock(sc, txq);
-+
-+      tid->has_queued = true;
-+      ath_tx_queue_tid(sc, txq, tid);
-+      ath_txq_schedule(sc, txq);
-+
-+      ath_txq_unlock(sc, txq);
-+}
-+
- static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
- {
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-@@ -164,7 +186,6 @@ static void ath_set_rates(struct ieee802
- static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
-                            struct sk_buff *skb)
- {
--      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath_frame_info *fi = get_frame_info(skb);
-       int q = fi->txq;
-@@ -175,14 +196,6 @@ static void ath_txq_skb_done(struct ath_
-       if (WARN_ON(--txq->pending_frames < 0))
-               txq->pending_frames = 0;
--      if (txq->stopped &&
--          txq->pending_frames < sc->tx.txq_max_pending[q]) {
--              if (ath9k_is_chanctx_enabled())
--                      ieee80211_wake_queue(sc->hw, info->hw_queue);
--              else
--                      ieee80211_wake_queue(sc->hw, q);
--              txq->stopped = false;
--      }
- }
- static struct ath_atx_tid *
-@@ -192,9 +205,48 @@ ath_get_skb_tid(struct ath_softc *sc, st
-       return ATH_AN_2_TID(an, tidno);
- }
-+static struct sk_buff *
-+ath_tid_pull(struct ath_atx_tid *tid)
-+{
-+      struct ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv);
-+      struct ath_softc *sc = tid->an->sc;
-+      struct ieee80211_hw *hw = sc->hw;
-+      struct ath_tx_control txctl = {
-+              .txq = tid->txq,
-+              .sta = tid->an->sta,
-+      };
-+      struct sk_buff *skb;
-+      struct ath_frame_info *fi;
-+      int q;
-+
-+      if (!tid->has_queued)
-+              return NULL;
-+
-+      skb = ieee80211_tx_dequeue(hw, txq);
-+      if (!skb) {
-+              tid->has_queued = false;
-+              return NULL;
-+      }
-+
-+      if (ath_tx_prepare(hw, skb, &txctl)) {
-+              ieee80211_free_txskb(hw, skb);
-+              return NULL;
-+      }
-+
-+      q = skb_get_queue_mapping(skb);
-+      if (tid->txq == sc->tx.txq_map[q]) {
-+              fi = get_frame_info(skb);
-+              fi->txq = q;
-+              ++tid->txq->pending_frames;
-+      }
-+
-+      return skb;
-+ }
-+
-+
- static bool ath_tid_has_buffered(struct ath_atx_tid *tid)
- {
--      return !skb_queue_empty(&tid->buf_q) || !skb_queue_empty(&tid->retry_q);
-+      return !skb_queue_empty(&tid->retry_q) || tid->has_queued;
- }
- static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid)
-@@ -203,46 +255,11 @@ static struct sk_buff *ath_tid_dequeue(s
-       skb = __skb_dequeue(&tid->retry_q);
-       if (!skb)
--              skb = __skb_dequeue(&tid->buf_q);
-+              skb = ath_tid_pull(tid);
-       return skb;
- }
--/*
-- * ath_tx_tid_change_state:
-- * - clears a-mpdu flag of previous session
-- * - force sequence number allocation to fix next BlockAck Window
-- */
--static void
--ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid)
--{
--      struct ath_txq *txq = tid->txq;
--      struct ieee80211_tx_info *tx_info;
--      struct sk_buff *skb, *tskb;
--      struct ath_buf *bf;
--      struct ath_frame_info *fi;
--
--      skb_queue_walk_safe(&tid->buf_q, skb, tskb) {
--              fi = get_frame_info(skb);
--              bf = fi->bf;
--
--              tx_info = IEEE80211_SKB_CB(skb);
--              tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU;
--
--              if (bf)
--                      continue;
--
--              bf = ath_tx_setup_buffer(sc, txq, tid, skb);
--              if (!bf) {
--                      __skb_unlink(skb, &tid->buf_q);
--                      ath_txq_skb_done(sc, txq, skb);
--                      ieee80211_free_txskb(sc->hw, skb);
--                      continue;
--              }
--      }
--
--}
--
- static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
- {
-       struct ath_txq *txq = tid->txq;
-@@ -883,20 +900,16 @@ static int ath_compute_num_delims(struct
- static struct ath_buf *
- ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq,
--                      struct ath_atx_tid *tid, struct sk_buff_head **q)
-+                      struct ath_atx_tid *tid)
- {
-       struct ieee80211_tx_info *tx_info;
-       struct ath_frame_info *fi;
--      struct sk_buff *skb;
-+      struct sk_buff *skb, *first_skb = NULL;
-       struct ath_buf *bf;
-       u16 seqno;
-       while (1) {
--              *q = &tid->retry_q;
--              if (skb_queue_empty(*q))
--                      *q = &tid->buf_q;
--
--              skb = skb_peek(*q);
-+              skb = ath_tid_dequeue(tid);
-               if (!skb)
-                       break;
-@@ -908,7 +921,6 @@ ath_tx_get_tid_subframe(struct ath_softc
-                       bf->bf_state.stale = false;
-               if (!bf) {
--                      __skb_unlink(skb, *q);
-                       ath_txq_skb_done(sc, txq, skb);
-                       ieee80211_free_txskb(sc->hw, skb);
-                       continue;
-@@ -937,8 +949,20 @@ ath_tx_get_tid_subframe(struct ath_softc
-               seqno = bf->bf_state.seqno;
-               /* do not step over block-ack window */
--              if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno))
-+              if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
-+                      __skb_queue_tail(&tid->retry_q, skb);
-+
-+                      /* If there are other skbs in the retry q, they are
-+                       * probably within the BAW, so loop immediately to get
-+                       * one of them. Otherwise the queue can get stuck. */
-+                      if (!skb_queue_is_first(&tid->retry_q, skb) &&
-+                          !WARN_ON(skb == first_skb)) {
-+                              if(!first_skb) /* infinite loop prevention */
-+                                      first_skb = skb;
-+                              continue;
-+                      }
-                       break;
-+              }
-               if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) {
-                       struct ath_tx_status ts = {};
-@@ -946,7 +970,6 @@ ath_tx_get_tid_subframe(struct ath_softc
-                       INIT_LIST_HEAD(&bf_head);
-                       list_add(&bf->list, &bf_head);
--                      __skb_unlink(skb, *q);
-                       ath_tx_update_baw(sc, tid, seqno);
-                       ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
-                       continue;
-@@ -958,11 +981,10 @@ ath_tx_get_tid_subframe(struct ath_softc
-       return NULL;
- }
--static bool
-+static int
- ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq,
-                struct ath_atx_tid *tid, struct list_head *bf_q,
--               struct ath_buf *bf_first, struct sk_buff_head *tid_q,
--               int *aggr_len)
-+               struct ath_buf *bf_first)
- {
- #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
-       struct ath_buf *bf = bf_first, *bf_prev = NULL;
-@@ -972,12 +994,13 @@ ath_tx_form_aggr(struct ath_softc *sc, s
-       struct ieee80211_tx_info *tx_info;
-       struct ath_frame_info *fi;
-       struct sk_buff *skb;
--      bool closed = false;
-+
-       bf = bf_first;
-       aggr_limit = ath_lookup_rate(sc, bf, tid);
--      do {
-+      while (bf)
-+      {
-               skb = bf->bf_mpdu;
-               fi = get_frame_info(skb);
-@@ -986,12 +1009,12 @@ ath_tx_form_aggr(struct ath_softc *sc, s
-               if (nframes) {
-                       if (aggr_limit < al + bpad + al_delta ||
-                           ath_lookup_legacy(bf) || nframes >= h_baw)
--                              break;
-+                              goto stop;
-                       tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
-                       if ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) ||
-                           !(tx_info->flags & IEEE80211_TX_CTL_AMPDU))
--                              break;
-+                              goto stop;
-               }
-               /* add padding for previous frame to aggregation length */
-@@ -1013,20 +1036,18 @@ ath_tx_form_aggr(struct ath_softc *sc, s
-                       ath_tx_addto_baw(sc, tid, bf);
-               bf->bf_state.ndelim = ndelim;
--              __skb_unlink(skb, tid_q);
-               list_add_tail(&bf->list, bf_q);
-               if (bf_prev)
-                       bf_prev->bf_next = bf;
-               bf_prev = bf;
--              bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
--              if (!bf) {
--                      closed = true;
--                      break;
--              }
--      } while (ath_tid_has_buffered(tid));
--
-+              bf = ath_tx_get_tid_subframe(sc, txq, tid);
-+      }
-+      goto finish;
-+stop:
-+      __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
-+finish:
-       bf = bf_first;
-       bf->bf_lastbf = bf_prev;
-@@ -1037,9 +1058,7 @@ ath_tx_form_aggr(struct ath_softc *sc, s
-               TX_STAT_INC(txq->axq_qnum, a_aggr);
-       }
--      *aggr_len = al;
--
--      return closed;
-+      return al;
- #undef PADBYTES
- }
-@@ -1416,18 +1435,15 @@ static void ath_tx_fill_desc(struct ath_
- static void
- ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
-                 struct ath_atx_tid *tid, struct list_head *bf_q,
--                struct ath_buf *bf_first, struct sk_buff_head *tid_q)
-+                struct ath_buf *bf_first)
- {
-       struct ath_buf *bf = bf_first, *bf_prev = NULL;
--      struct sk_buff *skb;
-       int nframes = 0;
-       do {
-               struct ieee80211_tx_info *tx_info;
--              skb = bf->bf_mpdu;
-               nframes++;
--              __skb_unlink(skb, tid_q);
-               list_add_tail(&bf->list, bf_q);
-               if (bf_prev)
-                       bf_prev->bf_next = bf;
-@@ -1436,13 +1452,15 @@ ath_tx_form_burst(struct ath_softc *sc,
-               if (nframes >= 2)
-                       break;
--              bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
-+              bf = ath_tx_get_tid_subframe(sc, txq, tid);
-               if (!bf)
-                       break;
-               tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
--              if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
-+              if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
-+                      __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
-                       break;
-+              }
-               ath_set_rates(tid->an->vif, tid->an->sta, bf);
-       } while (1);
-@@ -1453,34 +1471,33 @@ static bool ath_tx_sched_aggr(struct ath
- {
-       struct ath_buf *bf;
-       struct ieee80211_tx_info *tx_info;
--      struct sk_buff_head *tid_q;
-       struct list_head bf_q;
-       int aggr_len = 0;
--      bool aggr, last = true;
-+      bool aggr;
-       if (!ath_tid_has_buffered(tid))
-               return false;
-       INIT_LIST_HEAD(&bf_q);
--      bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q);
-+      bf = ath_tx_get_tid_subframe(sc, txq, tid);
-       if (!bf)
-               return false;
-       tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
-       aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
-       if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) ||
--              (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
-+          (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
-+              __skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
-               *stop = true;
-               return false;
-       }
-       ath_set_rates(tid->an->vif, tid->an->sta, bf);
-       if (aggr)
--              last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
--                                      tid_q, &aggr_len);
-+              aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf);
-       else
--              ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q);
-+              ath_tx_form_burst(sc, txq, tid, &bf_q, bf);
-       if (list_empty(&bf_q))
-               return false;
-@@ -1523,9 +1540,6 @@ int ath_tx_aggr_start(struct ath_softc *
-               an->mpdudensity = density;
-       }
--      /* force sequence number allocation for pending frames */
--      ath_tx_tid_change_state(sc, txtid);
--
-       txtid->active = true;
-       *ssn = txtid->seq_start = txtid->seq_next;
-       txtid->bar_index = -1;
-@@ -1550,7 +1564,6 @@ void ath_tx_aggr_stop(struct ath_softc *
-       ath_txq_lock(sc, txq);
-       txtid->active = false;
-       ath_tx_flush_tid(sc, txtid);
--      ath_tx_tid_change_state(sc, txtid);
-       ath_txq_unlock_complete(sc, txq);
- }
-@@ -1560,14 +1573,12 @@ void ath_tx_aggr_sleep(struct ieee80211_
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_atx_tid *tid;
-       struct ath_txq *txq;
--      bool buffered;
-       int tidno;
-       ath_dbg(common, XMIT, "%s called\n", __func__);
--      for (tidno = 0, tid = &an->tid[tidno];
--           tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
--
-+      for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
-+              tid = ath_node_to_tid(an, tidno);
-               txq = tid->txq;
-               ath_txq_lock(sc, txq);
-@@ -1577,13 +1588,12 @@ void ath_tx_aggr_sleep(struct ieee80211_
-                       continue;
-               }
--              buffered = ath_tid_has_buffered(tid);
-+              if (!skb_queue_empty(&tid->retry_q))
-+                      ieee80211_sta_set_buffered(sta, tid->tidno, true);
-               list_del_init(&tid->list);
-               ath_txq_unlock(sc, txq);
--
--              ieee80211_sta_set_buffered(sta, tidno, buffered);
-       }
- }
-@@ -1596,49 +1606,20 @@ void ath_tx_aggr_wakeup(struct ath_softc
-       ath_dbg(common, XMIT, "%s called\n", __func__);
--      for (tidno = 0, tid = &an->tid[tidno];
--           tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
--
-+      for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
-+              tid = ath_node_to_tid(an, tidno);
-               txq = tid->txq;
-               ath_txq_lock(sc, txq);
-               tid->clear_ps_filter = true;
--
-               if (ath_tid_has_buffered(tid)) {
-                       ath_tx_queue_tid(sc, txq, tid);
-                       ath_txq_schedule(sc, txq);
-               }
--
-               ath_txq_unlock_complete(sc, txq);
-       }
- }
--void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
--                      u16 tidno)
--{
--      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--      struct ath_atx_tid *tid;
--      struct ath_node *an;
--      struct ath_txq *txq;
--
--      ath_dbg(common, XMIT, "%s called\n", __func__);
--
--      an = (struct ath_node *)sta->drv_priv;
--      tid = ATH_AN_2_TID(an, tidno);
--      txq = tid->txq;
--
--      ath_txq_lock(sc, txq);
--
--      tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
--
--      if (ath_tid_has_buffered(tid)) {
--              ath_tx_queue_tid(sc, txq, tid);
--              ath_txq_schedule(sc, txq);
--      }
--
--      ath_txq_unlock_complete(sc, txq);
--}
--
- void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
-                                  struct ieee80211_sta *sta,
-                                  u16 tids, int nframes,
-@@ -1651,7 +1632,6 @@ void ath9k_release_buffered_frames(struc
-       struct ieee80211_tx_info *info;
-       struct list_head bf_q;
-       struct ath_buf *bf_tail = NULL, *bf;
--      struct sk_buff_head *tid_q;
-       int sent = 0;
-       int i;
-@@ -1666,11 +1646,10 @@ void ath9k_release_buffered_frames(struc
-               ath_txq_lock(sc, tid->txq);
-               while (nframes > 0) {
--                      bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q);
-+                      bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid);
-                       if (!bf)
-                               break;
--                      __skb_unlink(bf->bf_mpdu, tid_q);
-                       list_add_tail(&bf->list, &bf_q);
-                       ath_set_rates(tid->an->vif, tid->an->sta, bf);
-                       if (bf_isampdu(bf)) {
-@@ -1685,7 +1664,7 @@ void ath9k_release_buffered_frames(struc
-                       sent++;
-                       TX_STAT_INC(txq->axq_qnum, a_queued_hw);
--                      if (an->sta && !ath_tid_has_buffered(tid))
-+                      if (an->sta && skb_queue_empty(&tid->retry_q))
-                               ieee80211_sta_set_buffered(an->sta, i, false);
-               }
-               ath_txq_unlock_complete(sc, tid->txq);
-@@ -1914,13 +1893,7 @@ bool ath_drain_all_txq(struct ath_softc
-               if (!ATH_TXQ_SETUP(sc, i))
-                       continue;
--              /*
--               * The caller will resume queues with ieee80211_wake_queues.
--               * Mark the queue as not stopped to prevent ath_tx_complete
--               * from waking the queue too early.
--               */
-               txq = &sc->tx.txq[i];
--              txq->stopped = false;
-               ath_draintxq(sc, txq);
-       }
-@@ -2319,16 +2292,14 @@ int ath_tx_start(struct ieee80211_hw *hw
-       struct ath_softc *sc = hw->priv;
-       struct ath_txq *txq = txctl->txq;
-       struct ath_atx_tid *tid = NULL;
-+      struct ath_node *an = NULL;
-       struct ath_buf *bf;
--      bool queue, skip_uapsd = false, ps_resp;
-+      bool ps_resp;
-       int q, ret;
-       if (vif)
-               avp = (void *)vif->drv_priv;
--      if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
--              txctl->force_channel = true;
--
-       ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE);
-       ret = ath_tx_prepare(hw, skb, txctl);
-@@ -2343,63 +2314,18 @@ int ath_tx_start(struct ieee80211_hw *hw
-       q = skb_get_queue_mapping(skb);
--      ath_txq_lock(sc, txq);
--      if (txq == sc->tx.txq_map[q]) {
--              fi->txq = q;
--              if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
--                  !txq->stopped) {
--                      if (ath9k_is_chanctx_enabled())
--                              ieee80211_stop_queue(sc->hw, info->hw_queue);
--                      else
--                              ieee80211_stop_queue(sc->hw, q);
--                      txq->stopped = true;
--              }
--      }
--
--      queue = ieee80211_is_data_present(hdr->frame_control);
--
--      /* If chanctx, queue all null frames while NOA could be there */
--      if (ath9k_is_chanctx_enabled() &&
--          ieee80211_is_nullfunc(hdr->frame_control) &&
--          !txctl->force_channel)
--              queue = true;
--
--      /* Force queueing of all frames that belong to a virtual interface on
--       * a different channel context, to ensure that they are sent on the
--       * correct channel.
--       */
--      if (((avp && avp->chanctx != sc->cur_chan) ||
--           sc->cur_chan->stopped) && !txctl->force_channel) {
--              if (!txctl->an)
--                      txctl->an = &avp->mcast_node;
--              queue = true;
--              skip_uapsd = true;
--      }
--
--      if (txctl->an && queue)
--              tid = ath_get_skb_tid(sc, txctl->an, skb);
--
--      if (!skip_uapsd && ps_resp) {
--              ath_txq_unlock(sc, txq);
-+      if (ps_resp)
-               txq = sc->tx.uapsdq;
--              ath_txq_lock(sc, txq);
--      } else if (txctl->an && queue) {
--              WARN_ON(tid->txq != txctl->txq);
--              if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
--                      tid->clear_ps_filter = true;
--
--              /*
--               * Add this frame to software queue for scheduling later
--               * for aggregation.
--               */
--              TX_STAT_INC(txq->axq_qnum, a_queued_sw);
--              __skb_queue_tail(&tid->buf_q, skb);
--              if (!txctl->an->sleeping)
--                      ath_tx_queue_tid(sc, txq, tid);
-+      if (txctl->sta) {
-+              an = (struct ath_node *) sta->drv_priv;
-+              tid = ath_get_skb_tid(sc, an, skb);
-+      }
--              ath_txq_schedule(sc, txq);
--              goto out;
-+      ath_txq_lock(sc, txq);
-+      if (txq == sc->tx.txq_map[q]) {
-+              fi->txq = q;
-+              ++txq->pending_frames;
-       }
-       bf = ath_tx_setup_buffer(sc, txq, tid, skb);
-@@ -2892,9 +2818,8 @@ void ath_tx_node_init(struct ath_softc *
-       struct ath_atx_tid *tid;
-       int tidno, acno;
--      for (tidno = 0, tid = &an->tid[tidno];
--           tidno < IEEE80211_NUM_TIDS;
--           tidno++, tid++) {
-+      for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
-+              tid = ath_node_to_tid(an, tidno);
-               tid->an        = an;
-               tid->tidno     = tidno;
-               tid->seq_start = tid->seq_next = 0;
-@@ -2902,11 +2827,14 @@ void ath_tx_node_init(struct ath_softc *
-               tid->baw_head  = tid->baw_tail = 0;
-               tid->active        = false;
-               tid->clear_ps_filter = true;
--              __skb_queue_head_init(&tid->buf_q);
-+              tid->has_queued  = false;
-               __skb_queue_head_init(&tid->retry_q);
-               INIT_LIST_HEAD(&tid->list);
-               acno = TID_TO_WME_AC(tidno);
-               tid->txq = sc->tx.txq_map[acno];
-+
-+              if (!an->sta)
-+                      break; /* just one multicast ath_atx_tid */
-       }
- }
-@@ -2916,9 +2844,8 @@ void ath_tx_node_cleanup(struct ath_soft
-       struct ath_txq *txq;
-       int tidno;
--      for (tidno = 0, tid = &an->tid[tidno];
--           tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
--
-+      for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
-+              tid = ath_node_to_tid(an, tidno);
-               txq = tid->txq;
-               ath_txq_lock(sc, txq);
-@@ -2930,6 +2857,9 @@ void ath_tx_node_cleanup(struct ath_soft
-               tid->active = false;
-               ath_txq_unlock(sc, txq);
-+
-+              if (!an->sta)
-+                      break; /* just one multicast ath_atx_tid */
-       }
- }
diff --git a/package/kernel/mac80211/patches/300-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/300-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch
new file mode 100644 (file)
index 0000000..a7bcfa5
--- /dev/null
@@ -0,0 +1,25 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 9 Jul 2016 15:25:24 +0200
+Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx
+
+Should fix a few stability issues
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1394,8 +1394,12 @@ static bool ath9k_hw_set_reset(struct at
+       if (!AR_SREV_9100(ah))
+               REG_WRITE(ah, AR_RC, 0);
+-      if (AR_SREV_9100(ah))
++      if (AR_SREV_9100(ah)) {
++              /* Reset the AHB-WMAC interface */
++              if (ah->external_reset)
++                      ah->external_reset();
+               udelay(50);
++      }
+       return true;
+ }
diff --git a/package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch
deleted file mode 100644 (file)
index 098bda7..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Sun, 7 Jun 2015 13:53:35 +0200
-Subject: [PATCH] ath9k: force rx_clear when disabling rx
-
-This makes stopping Rx more reliable and should reduce the frequency of
-Rx related DMA stop warnings. Don't use rx_clear in TX99 mode.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -677,13 +677,18 @@ void ath9k_hw_startpcureceive(struct ath
-       ath9k_ani_reset(ah, is_scanning);
--      REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-+      REG_CLR_BIT(ah, AR_DIAG_SW,
-+                  AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
- }
- EXPORT_SYMBOL(ath9k_hw_startpcureceive);
- void ath9k_hw_abortpcurecv(struct ath_hw *ah)
- {
--      REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
-+      u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT;
-+
-+      if (!config_enabled(CPTCFG_ATH9K_TX99))
-+              reg |= AR_DIAG_FORCE_RX_CLEAR;
-+      REG_SET_BIT(ah, AR_DIAG_SW, reg);
-       ath9k_hw_disable_mib_counters(ah);
- }
diff --git a/package/kernel/mac80211/patches/301-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/301-ath9k_hw-issue-external-reset-for-QCA955x.patch
new file mode 100644 (file)
index 0000000..34d7d3b
--- /dev/null
@@ -0,0 +1,126 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 9 Jul 2016 15:26:44 +0200
+Subject: [PATCH] ath9k_hw: issue external reset for QCA955x
+
+The RTC interface on the SoC needs to be reset along with the rest of
+the WMAC.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1271,39 +1271,56 @@ void ath9k_hw_get_delta_slope_vals(struc
+       *coef_exponent = coef_exp - 16;
+ }
+-/* AR9330 WAR:
+- * call external reset function to reset WMAC if:
+- * - doing a cold reset
+- * - we have pending frames in the TX queues.
+- */
+-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
++static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
+ {
+-      int i, npend = 0;
++      int i;
+-      for (i = 0; i < AR_NUM_QCU; i++) {
+-              npend = ath9k_hw_numtxpending(ah, i);
+-              if (npend)
+-                      break;
++      if (type == ATH9K_RESET_COLD)
++              return true;
++
++      if (AR_SREV_9550(ah))
++              return true;
++
++      /* AR9330 WAR:
++       * call external reset function to reset WMAC if:
++       * - doing a cold reset
++       * - we have pending frames in the TX queues.
++       */
++      if (AR_SREV_9330(ah)) {
++              for (i = 0; i < AR_NUM_QCU; i++) {
++                      if (ath9k_hw_numtxpending(ah, i))
++                              return true;
++              }
+       }
+-      if (ah->external_reset &&
+-          (npend || type == ATH9K_RESET_COLD)) {
+-              int reset_err = 0;
++      return false;
++}
+-              ath_dbg(ath9k_hw_common(ah), RESET,
+-                      "reset MAC via external reset\n");
++static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
++{
++      int err;
+-              reset_err = ah->external_reset();
+-              if (reset_err) {
+-                      ath_err(ath9k_hw_common(ah),
+-                              "External reset failed, err=%d\n",
+-                              reset_err);
+-                      return false;
+-              }
++      if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
++              return true;
+-              REG_WRITE(ah, AR_RTC_RESET, 1);
++      ath_dbg(ath9k_hw_common(ah), RESET,
++              "reset MAC via external reset\n");
++
++      err = ah->external_reset();
++      if (err) {
++              ath_err(ath9k_hw_common(ah),
++                      "External reset failed, err=%d\n", err);
++              return false;
++      }
++
++      if (AR_SREV_9550(ah)) {
++              REG_WRITE(ah, AR_RTC_RESET, 0);
++              udelay(10);
+       }
++      REG_WRITE(ah, AR_RTC_RESET, 1);
++      udelay(10);
++
+       return true;
+ }
+@@ -1356,24 +1373,24 @@ static bool ath9k_hw_set_reset(struct at
+                       rst_flags |= AR_RTC_RC_MAC_COLD;
+       }
+-      if (AR_SREV_9330(ah)) {
+-              if (!ath9k_hw_ar9330_reset_war(ah, type))
+-                      return false;
+-      }
+-
+       if (ath9k_hw_mci_is_enabled(ah))
+               ar9003_mci_check_gpm_offset(ah);
+       /* DMA HALT added to resolve ar9300 and ar9580 bus error during
+-       * RTC_RC reg read
++       * RTC_RC reg read. Also needed for AR9550 external reset
+        */
+-      if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
++      if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
+               REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
+               ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
+                             20 * AH_WAIT_TIMEOUT);
+-              REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
+       }
++      if (!AR_SREV_9100(ah))
++              ath9k_hw_external_reset(ah, type);
++
++      if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
++              REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
++
+       REG_WRITE(ah, AR_RTC_RC, rst_flags);
+       REGWRITE_BUFFER_FLUSH(ah);
diff --git a/package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch
deleted file mode 100644 (file)
index 8c19ea2..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Date: Thu, 2 Jul 2015 15:20:56 +0200
-Subject: [PATCH] ath9k: limit retries for powersave response frames
-
-In some cases, the channel might be busy enough that an ath9k AP's
-response to PS-Poll frames might be too slow and the station has already
-gone to sleep. To avoid wasting too much airtime on this, limit the
-number of retries on such frames and ensure that no sample rate gets
-used.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
-
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -177,10 +177,25 @@ static void ath_send_bar(struct ath_atx_
- }
- static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
--                        struct ath_buf *bf)
-+                        struct ath_buf *bf, bool ps)
- {
-+      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
-+
-+      if (ps) {
-+              /* Clear the first rate to avoid using a sample rate for PS frames */
-+              info->control.rates[0].idx = -1;
-+              info->control.rates[0].count = 0;
-+      }
-+
-       ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
-                              ARRAY_SIZE(bf->rates));
-+      if (!ps)
-+              return;
-+
-+      if (bf->rates[0].count > 2)
-+              bf->rates[0].count = 2;
-+
-+      bf->rates[1].idx = -1;
- }
- static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
-@@ -1462,7 +1477,7 @@ ath_tx_form_burst(struct ath_softc *sc,
-                       break;
-               }
--              ath_set_rates(tid->an->vif, tid->an->sta, bf);
-+              ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
-       } while (1);
- }
-@@ -1493,7 +1508,7 @@ static bool ath_tx_sched_aggr(struct ath
-               return false;
-       }
--      ath_set_rates(tid->an->vif, tid->an->sta, bf);
-+      ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
-       if (aggr)
-               aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf);
-       else
-@@ -1651,7 +1666,7 @@ void ath9k_release_buffered_frames(struc
-                               break;
-                       list_add_tail(&bf->list, &bf_q);
--                      ath_set_rates(tid->an->vif, tid->an->sta, bf);
-+                      ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
-                       if (bf_isampdu(bf)) {
-                               ath_tx_addto_baw(sc, tid, bf);
-                               bf->bf_state.bf_type &= ~BUF_AGGR;
-@@ -2343,7 +2358,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-       if (txctl->paprd)
-               bf->bf_state.bfs_paprd_timestamp = jiffies;
--      ath_set_rates(vif, sta, bf);
-+      ath_set_rates(vif, sta, bf, ps_resp);
-       ath_tx_send_normal(sc, txq, tid, skb);
- out:
-@@ -2382,7 +2397,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
-                       break;
-               bf->bf_lastbf = bf;
--              ath_set_rates(vif, NULL, bf);
-+              ath_set_rates(vif, NULL, bf, false);
-               ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
-               duration += info.rates[0].PktDuration;
-               if (bf_tail)
-@@ -2898,7 +2913,7 @@ int ath9k_tx99_send(struct ath_softc *sc
-               return -EINVAL;
-       }
--      ath_set_rates(sc->tx99_vif, NULL, bf);
-+      ath_set_rates(sc->tx99_vif, NULL, bf, false);
-       ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
-       ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);
diff --git a/package/kernel/mac80211/patches/302-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch b/package/kernel/mac80211/patches/302-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch
new file mode 100644 (file)
index 0000000..dfe9aae
--- /dev/null
@@ -0,0 +1,21 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Mon, 11 Jul 2016 12:07:40 +0200
+Subject: [PATCH] ath9k_hw: set spectral scan enable bit on trigger for
+ AR9003+
+
+AR9002 code and QCA AR9003+ code do the same.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -1800,6 +1800,8 @@ static void ar9003_hw_spectral_scan_conf
+ static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah)
+ {
++      REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
++                  AR_PHY_SPECTRAL_SCAN_ENABLE);
+       /* Activate spectral scan */
+       REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+                   AR_PHY_SPECTRAL_SCAN_ACTIVE);
diff --git a/package/kernel/mac80211/patches/303-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/303-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch
deleted file mode 100644 (file)
index 57f45c1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 14 May 2016 14:51:02 +0200
-Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP
- domain"
-
-This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411.
----
-
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -2910,7 +2910,8 @@ void ath9k_hw_apply_txpower(struct ath_h
- {
-       struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
-       struct ieee80211_channel *channel;
--      int chan_pwr, new_pwr;
-+      int chan_pwr, new_pwr, max_gain;
-+      int ant_gain, ant_reduction = 0;
-       if (!chan)
-               return;
-@@ -2918,10 +2919,15 @@ void ath9k_hw_apply_txpower(struct ath_h
-       channel = chan->chan;
-       chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
-       new_pwr = min_t(int, chan_pwr, reg->power_limit);
-+      max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
-+
-+      ant_gain = get_antenna_gain(ah, chan);
-+      if (ant_gain > max_gain)
-+              ant_reduction = ant_gain - max_gain;
-       ah->eep_ops->set_txpower(ah, chan,
-                                ath9k_regd_get_ctl(reg, chan),
--                               get_antenna_gain(ah, chan), new_pwr, test);
-+                               ant_reduction, new_pwr, test);
- }
- void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
diff --git a/package/kernel/mac80211/patches/303-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch b/package/kernel/mac80211/patches/303-ath9k-don-t-run-periodic-and-nf-calibation-at-the-sa.patch
new file mode 100644 (file)
index 0000000..22f5154
--- /dev/null
@@ -0,0 +1,27 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 27 Dec 2016 23:16:23 +0100
+Subject: [PATCH] ath9k: don't run periodic and nf calibation at the same
+ time
+
+The checks already prevents periodic cal from being started while noise
+floor calibration runs. It is missing checks for the other way around.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+@@ -676,10 +676,10 @@ static int ar9002_hw_calibrate(struct at
+                       return 0;
+               ah->cal_list_curr = currCal = currCal->calNext;
+-              if (currCal->calState == CAL_WAITING) {
++              if (currCal->calState == CAL_WAITING)
+                       ath9k_hw_reset_calibration(ah, currCal);
+-                      return 0;
+-              }
++
++              return 0;
+       }
+       /* Do NF cal only at longer intervals */
diff --git a/package/kernel/mac80211/patches/304-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/304-ath9k-force-rx_clear-when-disabling-rx.patch
new file mode 100644 (file)
index 0000000..eb6862d
--- /dev/null
@@ -0,0 +1,35 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sun, 7 Jun 2015 13:53:35 +0200
+Subject: [PATCH] ath9k: force rx_clear when disabling rx
+
+This makes stopping Rx more reliable and should reduce the frequency of
+Rx related DMA stop warnings. Don't use rx_clear in TX99 mode.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -677,13 +677,18 @@ void ath9k_hw_startpcureceive(struct ath
+       ath9k_ani_reset(ah, is_scanning);
+-      REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
++      REG_CLR_BIT(ah, AR_DIAG_SW,
++                  AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
+ }
+ EXPORT_SYMBOL(ath9k_hw_startpcureceive);
+ void ath9k_hw_abortpcurecv(struct ath_hw *ah)
+ {
+-      REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
++      u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT;
++
++      if (!IS_ENABLED(CPTCFG_ATH9K_TX99))
++              reg |= AR_DIAG_FORCE_RX_CLEAR;
++      REG_SET_BIT(ah, AR_DIAG_SW, reg);
+       ath9k_hw_disable_mib_counters(ah);
+ }
diff --git a/package/kernel/mac80211/patches/304-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/304-mac80211-add-hdrlen-to-ieee80211_tx_data.patch
deleted file mode 100644 (file)
index 72e81ee..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-Date: Fri, 19 Feb 2016 11:01:49 +0100
-Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data
-
-Add hdrlen to ieee80211_tx_data and use this
-when wep/ccmd/tkip. This is preparation for
-aligned4 code.
-
-Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -175,6 +175,7 @@ struct ieee80211_tx_data {
-       struct ieee80211_tx_rate rate;
-       unsigned int flags;
-+      unsigned int hdrlen;
- };
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -955,7 +955,7 @@ ieee80211_tx_h_fragment(struct ieee80211
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr = (void *)skb->data;
-       int frag_threshold = tx->local->hw.wiphy->frag_threshold;
--      int hdrlen;
-+      int hdrlen = tx->hdrlen;
-       int fragnum;
-       /* no matter what happens, tx->skb moves to tx->skbs */
-@@ -976,8 +976,6 @@ ieee80211_tx_h_fragment(struct ieee80211
-       if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
-               return TX_DROP;
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
--
-       /* internal error, why isn't DONTFRAG set? */
-       if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
-               return TX_DROP;
-@@ -1209,6 +1207,8 @@ ieee80211_tx_prepare(struct ieee80211_su
-       hdr = (struct ieee80211_hdr *) skb->data;
-+      tx->hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+
-       if (likely(sta)) {
-               if (!IS_ERR(sta))
-                       tx->sta = sta;
-@@ -3414,6 +3414,7 @@ begin:
-       tx.local = local;
-       tx.skb = skb;
-       tx.sdata = vif_to_sdata(info->control.vif);
-+      tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control);
-       if (txq->sta)
-               tx.sta = container_of(txq->sta, struct sta_info, sta);
-@@ -3584,6 +3585,7 @@ ieee80211_build_data_template(struct iee
-       hdr = (void *)skb->data;
-       tx.sta = sta_info_get(sdata, hdr->addr1);
-       tx.skb = skb;
-+      tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control);
-       if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) {
-               rcu_read_unlock();
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -1227,6 +1227,7 @@ void ieee80211_send_auth(struct ieee8021
-       struct ieee80211_local *local = sdata->local;
-       struct sk_buff *skb;
-       struct ieee80211_mgmt *mgmt;
-+      unsigned int hdrlen;
-       int err;
-       /* 24 + 6 = header + auth_algo + auth_transaction + status_code */
-@@ -1251,8 +1252,10 @@ void ieee80211_send_auth(struct ieee8021
-               memcpy(skb_put(skb, extra_len), extra, extra_len);
-       if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
-+              hdrlen = ieee80211_hdrlen(mgmt->frame_control);
-               mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
--              err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
-+              err = ieee80211_wep_encrypt(local, skb, hdrlen, key,
-+                                          key_len, key_idx);
-               WARN_ON(err);
-       }
---- a/net/mac80211/wep.c
-+++ b/net/mac80211/wep.c
-@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct
- static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
-                               struct sk_buff *skb,
-+                              unsigned int hdrlen,
-                               int keylen, int keyidx)
- {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--      unsigned int hdrlen;
-       u8 *newhdr;
-       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i
-       if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
-               return NULL;
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
-       newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN);
-       memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen);
-@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr
-  */
- int ieee80211_wep_encrypt(struct ieee80211_local *local,
-                         struct sk_buff *skb,
-+                        unsigned int hdrlen,
-                         const u8 *key, int keylen, int keyidx)
- {
-       u8 *iv;
-@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802
-       if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN))
-               return -1;
--      iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx);
-+      iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx);
-       if (!iv)
-               return -1;
-@@ -306,13 +306,14 @@ static int wep_encrypt_skb(struct ieee80
-       struct ieee80211_key_conf *hw_key = info->control.hw_key;
-       if (!hw_key) {
--              if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
-+              if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen,
-+                                        tx->key->conf.key,
-                                         tx->key->conf.keylen,
-                                         tx->key->conf.keyidx))
-                       return -1;
-       } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
-                  (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
--              if (!ieee80211_wep_add_iv(tx->local, skb,
-+              if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen,
-                                         tx->key->conf.keylen,
-                                         tx->key->conf.keyidx))
-                       return -1;
---- a/net/mac80211/wep.h
-+++ b/net/mac80211/wep.h
-@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr
-                               size_t klen, u8 *data, size_t data_len);
- int ieee80211_wep_encrypt(struct ieee80211_local *local,
-                         struct sk_buff *skb,
-+                        unsigned int hdrlen,
-                         const u8 *key, int keylen, int keyidx);
- int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
-                              size_t klen, u8 *data, size_t data_len);
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -43,7 +43,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
-           skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
-               return TX_CONTINUE;
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+      hdrlen = tx->hdrlen;
-       if (skb->len < hdrlen)
-               return TX_DROP;
-@@ -186,7 +186,6 @@ mic_fail_no_key:
- static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
- {
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_key *key = tx->key;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       unsigned int hdrlen;
-@@ -201,7 +200,7 @@ static int tkip_encrypt_skb(struct ieee8
-               return 0;
-       }
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+      hdrlen = tx->hdrlen;
-       len = skb->len - hdrlen;
-       if (info->control.hw_key)
-@@ -418,7 +417,7 @@ static int ccmp_encrypt_skb(struct ieee8
-               return 0;
-       }
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+      hdrlen = tx->hdrlen;
-       len = skb->len - hdrlen;
-       if (info->control.hw_key)
-@@ -651,7 +650,7 @@ static int gcmp_encrypt_skb(struct ieee8
-               return 0;
-       }
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+      hdrlen = tx->hdrlen;
-       len = skb->len - hdrlen;
-       if (info->control.hw_key)
-@@ -791,7 +790,6 @@ static ieee80211_tx_result
- ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
-                           struct sk_buff *skb)
- {
--      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_key *key = tx->key;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       int hdrlen;
-@@ -807,8 +805,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8
-                    pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC)))
-               return TX_DROP;
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
--
-+      hdrlen = tx->hdrlen;
-       pos = skb_push(skb, iv_len);
-       memmove(pos, pos + iv_len, hdrlen);
diff --git a/package/kernel/mac80211/patches/305-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/305-ath9k-limit-retries-for-powersave-response-frames.patch
new file mode 100644 (file)
index 0000000..5923594
--- /dev/null
@@ -0,0 +1,96 @@
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Thu, 2 Jul 2015 15:20:56 +0200
+Subject: [PATCH] ath9k: limit retries for powersave response frames
+
+In some cases, the channel might be busy enough that an ath9k AP's
+response to PS-Poll frames might be too slow and the station has already
+gone to sleep. To avoid wasting too much airtime on this, limit the
+number of retries on such frames and ensure that no sample rate gets
+used.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -188,10 +188,25 @@ static void ath_send_bar(struct ath_atx_
+ }
+ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+-                        struct ath_buf *bf)
++                        struct ath_buf *bf, bool ps)
+ {
++      struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
++
++      if (ps) {
++              /* Clear the first rate to avoid using a sample rate for PS frames */
++              info->control.rates[0].idx = -1;
++              info->control.rates[0].count = 0;
++      }
++
+       ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
+                              ARRAY_SIZE(bf->rates));
++      if (!ps)
++              return;
++
++      if (bf->rates[0].count > 2)
++              bf->rates[0].count = 2;
++
++      bf->rates[1].idx = -1;
+ }
+ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
+@@ -1522,7 +1537,7 @@ ath_tx_form_burst(struct ath_softc *sc,
+                       break;
+               }
+-              ath_set_rates(tid->an->vif, tid->an->sta, bf);
++              ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
+       } while (1);
+ }
+@@ -1552,7 +1567,7 @@ static bool ath_tx_sched_aggr(struct ath
+               return false;
+       }
+-      ath_set_rates(tid->an->vif, tid->an->sta, bf);
++      ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
+       if (aggr)
+               aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf);
+       else
+@@ -1710,7 +1725,7 @@ void ath9k_release_buffered_frames(struc
+                               break;
+                       list_add_tail(&bf->list, &bf_q);
+-                      ath_set_rates(tid->an->vif, tid->an->sta, bf);
++                      ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
+                       if (bf_isampdu(bf)) {
+                               ath_tx_addto_baw(sc, tid, bf);
+                               bf->bf_state.bf_type &= ~BUF_AGGR;
+@@ -2410,7 +2425,7 @@ int ath_tx_start(struct ieee80211_hw *hw
+       if (txctl->paprd)
+               bf->bf_state.bfs_paprd_timestamp = jiffies;
+-      ath_set_rates(vif, sta, bf);
++      ath_set_rates(vif, sta, bf, ps_resp);
+       ath_tx_send_normal(sc, txq, tid, skb);
+ out:
+@@ -2449,7 +2464,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
+                       break;
+               bf->bf_lastbf = bf;
+-              ath_set_rates(vif, NULL, bf);
++              ath_set_rates(vif, NULL, bf, false);
+               ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
+               duration += info.rates[0].PktDuration;
+               if (bf_tail)
+@@ -2968,7 +2983,7 @@ int ath9k_tx99_send(struct ath_softc *sc
+               return -EINVAL;
+       }
+-      ath_set_rates(sc->tx99_vif, NULL, bf);
++      ath_set_rates(sc->tx99_vif, NULL, bf, false);
+       ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
+       ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);
diff --git a/package/kernel/mac80211/patches/305-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/305-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch
deleted file mode 100644 (file)
index 704e7f7..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
-Date: Fri, 19 Feb 2016 11:01:50 +0100
-Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag
-
-HW/driver should set NEED_ALIGNED4_SKBS flag in case
-require aligned skbs to four-byte boundaries.
-This affect only TX direction.
-
-Padding is added after ieee80211_hdr, before IV/LLC.
-
-Before we have to do memmove(hdrlen) twice in the
-dirver. Once before we pass this to HW and next
-in tx completion (to be sure monitor will report
-this tx frame correctly).
-
-With this patch we can skip this memmove() and save CPU.
-
-Currently this was tested with ath9k, both hw/sw crypt for
-wep/tkip/ccmp.
-
-Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -2025,6 +2025,9 @@ struct ieee80211_txq {
-  *    drivers, mac80211 packet loss mechanism will not be triggered and driver
-  *    is completely depending on firmware event for station kickout.
-  *
-+ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte.
-+ *    Padding will be added after ieee80211_hdr, before IV/LLC.
-+ *
-  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
-  */
- enum ieee80211_hw_flags {
-@@ -2066,6 +2069,7 @@ enum ieee80211_hw_flags {
-       IEEE80211_HW_TX_AMSDU,
-       IEEE80211_HW_TX_FRAG_LIST,
-       IEEE80211_HW_REPORTS_LOW_ACK,
-+      IEEE80211_HW_NEEDS_ALIGNED4_SKBS,
-       /* keep last, obviously */
-       NUM_IEEE80211_HW_FLAGS
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -210,6 +210,7 @@ static const char *hw_flag_names[] = {
-       FLAG(TX_AMSDU),
-       FLAG(TX_FRAG_LIST),
-       FLAG(REPORTS_LOW_ACK),
-+      FLAG(NEEDS_ALIGNED4_SKBS),
- #undef FLAG
- };
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1529,6 +1529,29 @@ ieee80211_have_rx_timestamp(struct ieee8
-       return false;
- }
-+static inline unsigned int
-+ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen)
-+{
-+      /*
-+       * While hdrlen is already aligned to two-byte boundaries,
-+       * simple check with & 2 will return correct padsize.
-+       */
-+      if (ieee80211_hw_check(hw, NEEDS_ALIGNED4_SKBS))
-+              return hdrlen & 2;
-+      return 0;
-+}
-+
-+static inline unsigned int
-+ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc)
-+{
-+      unsigned int hdrlen;
-+
-+      hdrlen = ieee80211_hdrlen(fc);
-+      hdrlen += ieee80211_hdr_padsize(hw, hdrlen);
-+
-+      return hdrlen;
-+}
-+
- u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
-                                    struct ieee80211_rx_status *status,
-                                    unsigned int mpdu_len,
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -282,7 +282,7 @@ struct ieee80211_fast_tx {
-       u8 hdr_len;
-       u8 sa_offs, da_offs, pn_offs;
-       u8 band;
--      u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
-+      u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
-              sizeof(rfc1042_header)] __aligned(2);
-       struct rcu_head rcu_head;
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -689,9 +689,22 @@ void ieee80211_tx_monitor(struct ieee802
-       struct sk_buff *skb2;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_sub_if_data *sdata;
-+      struct ieee80211_hdr *hdr = (void *)skb->data;
-       struct net_device *prev_dev = NULL;
-+      unsigned int hdrlen, padsize;
-       int rtap_len;
-+      /* Remove padding if was added */
-+      if (ieee80211_hw_check(&local->hw, NEEDS_ALIGNED4_SKBS)) {
-+              hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+              padsize = ieee80211_hdr_padsize(&local->hw, hdrlen);
-+
-+              if (padsize && skb->len > hdrlen + padsize) {
-+                      memmove(skb->data + padsize, skb->data, hdrlen);
-+                      skb_pull(skb, padsize);
-+              }
-+      }
-+
-       /* send frame to monitor interfaces now */
-       rtap_len = ieee80211_tx_radiotap_len(info);
-       if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
---- a/net/mac80211/tkip.c
-+++ b/net/mac80211/tkip.c
-@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8
- {
-       struct ieee80211_key *key = (struct ieee80211_key *)
-                       container_of(keyconf, struct ieee80211_key, conf);
-+      struct ieee80211_hw *hw = &key->local->hw;
-       const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
-       struct tkip_ctx *ctx = &key->u.tkip.tx;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
--      const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
-+      const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw,
-+                                                      hdr->frame_control);
-       u32 iv32 = get_unaligned_le32(&data[4]);
-       u16 iv16 = data[2] | (data[0] << 8);
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1206,8 +1206,7 @@ ieee80211_tx_prepare(struct ieee80211_su
-       info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING;
-       hdr = (struct ieee80211_hdr *) skb->data;
--
--      tx->hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+      tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control);
-       if (likely(sta)) {
-               if (!IS_ERR(sta))
-@@ -2158,7 +2157,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
-               goto fail;
-       hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
--      hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+      hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control);
-       if (skb->len < len_rthdr + hdrlen)
-               goto fail;
-@@ -2376,7 +2375,7 @@ static struct sk_buff *ieee80211_build_h
-       struct ieee80211_chanctx_conf *chanctx_conf;
-       struct ieee80211_sub_if_data *ap_sdata;
-       enum nl80211_band band;
--      int ret;
-+      int padsize, ret;
-       if (IS_ERR(sta))
-               sta = NULL;
-@@ -2596,6 +2595,9 @@ static struct sk_buff *ieee80211_build_h
-               hdrlen += 2;
-       }
-+      /* Check aligned4 skb required */
-+      padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen);
-+
-       /*
-        * Drop unicast frames to unauthorised stations unless they are
-        * EAPOL frames from the local station.
-@@ -2676,6 +2678,7 @@ static struct sk_buff *ieee80211_build_h
-       skb_pull(skb, skip_header_bytes);
-       head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
-+      head_need += padsize;
-       /*
-        * So we need to modify the skb header and hence need a copy of
-@@ -2708,6 +2711,9 @@ static struct sk_buff *ieee80211_build_h
-               memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
- #endif
-+      if (padsize)
-+              memset(skb_push(skb, padsize), 0, padsize);
-+
-       if (ieee80211_is_data_qos(fc)) {
-               __le16 *qos_control;
-@@ -2883,6 +2889,9 @@ void ieee80211_check_fast_xmit(struct st
-               fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
-       }
-+      /* Check aligned4 skb required */
-+      build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len);
-+
-       /* We store the key here so there's no point in using rcu_dereference()
-        * but that's fine because the code that changes the pointers will call
-        * this function after doing so. For a single CPU that would be enough,
-@@ -3436,7 +3445,7 @@ begin:
-               if (tx.key &&
-                   (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
--                      pn_offs = ieee80211_hdrlen(hdr->frame_control);
-+                      pn_offs = tx.hdrlen;
-               ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
-                                          tx.key, skb);
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -1225,6 +1225,7 @@ void ieee80211_send_auth(struct ieee8021
-                        u32 tx_flags)
- {
-       struct ieee80211_local *local = sdata->local;
-+      struct ieee80211_hw *hw = &local->hw;
-       struct sk_buff *skb;
-       struct ieee80211_mgmt *mgmt;
-       unsigned int hdrlen;
-@@ -1252,7 +1253,7 @@ void ieee80211_send_auth(struct ieee8021
-               memcpy(skb_put(skb, extra_len), extra, extra_len);
-       if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
--              hdrlen = ieee80211_hdrlen(mgmt->frame_control);
-+              hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control);
-               mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-               err = ieee80211_wep_encrypt(local, skb, hdrlen, key,
-                                           key_len, key_idx);
diff --git a/package/kernel/mac80211/patches/306-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/306-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch
new file mode 100644 (file)
index 0000000..956ab83
--- /dev/null
@@ -0,0 +1,37 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sat, 14 May 2016 14:51:02 +0200
+Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP
+ domain"
+
+This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411.
+---
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2931,7 +2931,8 @@ void ath9k_hw_apply_txpower(struct ath_h
+ {
+       struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       struct ieee80211_channel *channel;
+-      int chan_pwr, new_pwr;
++      int chan_pwr, new_pwr, max_gain;
++      int ant_gain, ant_reduction = 0;
+       if (!chan)
+               return;
+@@ -2939,10 +2940,15 @@ void ath9k_hw_apply_txpower(struct ath_h
+       channel = chan->chan;
+       chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
+       new_pwr = min_t(int, chan_pwr, reg->power_limit);
++      max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
++
++      ant_gain = get_antenna_gain(ah, chan);
++      if (ant_gain > max_gain)
++              ant_reduction = ant_gain - max_gain;
+       ah->eep_ops->set_txpower(ah, chan,
+                                ath9k_regd_get_ctl(reg, chan),
+-                               get_antenna_gain(ah, chan), new_pwr, test);
++                               ant_reduction, new_pwr, test);
+ }
+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
diff --git a/package/kernel/mac80211/patches/306-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/306-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch
deleted file mode 100644 (file)
index 6e7ecb9..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-From: Chaitanya T K <chaitanya.mgit@gmail.com>
-Date: Mon, 27 Jun 2016 15:23:26 +0530
-Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates
-
-If peer support reception of STBC and LDPC, enable them for better
-performance.
-
-Signed-off-by: Chaitanya TK <chaitanya.mgit@gmail.com>
----
-
---- a/include/linux/ieee80211.h
-+++ b/include/linux/ieee80211.h
-@@ -1551,6 +1551,7 @@ struct ieee80211_vht_operation {
- #define IEEE80211_VHT_CAP_RXSTBC_3                            0x00000300
- #define IEEE80211_VHT_CAP_RXSTBC_4                            0x00000400
- #define IEEE80211_VHT_CAP_RXSTBC_MASK                         0x00000700
-+#define IEEE80211_VHT_CAP_RXSTBC_SHIFT                                8
- #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE                       0x00000800
- #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE                       0x00001000
- #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT                  13
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -1166,13 +1166,14 @@ minstrel_ht_update_caps(void *priv, stru
-       struct minstrel_ht_sta_priv *msp = priv_sta;
-       struct minstrel_ht_sta *mi = &msp->ht;
-       struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
--      u16 sta_cap = sta->ht_cap.cap;
-+      u16 ht_cap = sta->ht_cap.cap;
-       struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
-       int use_vht;
-       int n_supported = 0;
-       int ack_dur;
-       int stbc;
-       int i;
-+      bool ldpc = false;
-       /* fall back to the old minstrel for legacy stations */
-       if (!sta->ht_cap.ht_supported)
-@@ -1210,16 +1211,24 @@ minstrel_ht_update_caps(void *priv, stru
-       }
-       mi->sample_tries = 4;
--      /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
-       if (!use_vht) {
--              stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
-+              stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >>
-                       IEEE80211_HT_CAP_RX_STBC_SHIFT;
--              mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
--              if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
--                      mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
-+              if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING)
-+                      ldpc = true;
-+      } else {
-+              stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >>
-+                      IEEE80211_VHT_CAP_RXSTBC_SHIFT;
-+
-+              if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)
-+                      ldpc = true;
-       }
-+      mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
-+      if (ldpc)
-+              mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
-+
-       for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
-               u32 gflags = minstrel_mcs_groups[i].flags;
-               int bw, nss;
-@@ -1232,10 +1241,10 @@ minstrel_ht_update_caps(void *priv, stru
-               if (gflags & IEEE80211_TX_RC_SHORT_GI) {
-                       if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
--                              if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
-+                              if (!(ht_cap & IEEE80211_HT_CAP_SGI_40))
-                                       continue;
-                       } else {
--                              if (!(sta_cap & IEEE80211_HT_CAP_SGI_20))
-+                              if (!(ht_cap & IEEE80211_HT_CAP_SGI_20))
-                                       continue;
-                       }
-               }
diff --git a/package/kernel/mac80211/patches/307-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch b/package/kernel/mac80211/patches/307-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch
deleted file mode 100644 (file)
index 4fc6dc1..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 28 Aug 2016 13:13:01 +0200
-Subject: [PATCH] ath9k: fix moredata bit in PS buffered frame release
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -1635,6 +1635,22 @@ void ath_tx_aggr_wakeup(struct ath_softc
-       }
- }
-+
-+static void
-+ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val)
-+{
-+      struct ieee80211_hdr *hdr;
-+      u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-+      u16 mask_val = mask * val;
-+
-+      hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
-+      if ((hdr->frame_control & mask) != mask_val) {
-+              hdr->frame_control = (hdr->frame_control & ~mask) | mask_val;
-+              dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
-+                      sizeof(*hdr), DMA_TO_DEVICE);
-+      }
-+}
-+
- void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
-                                  struct ieee80211_sta *sta,
-                                  u16 tids, int nframes,
-@@ -1665,6 +1681,7 @@ void ath9k_release_buffered_frames(struc
-                       if (!bf)
-                               break;
-+                      ath9k_set_moredata(sc, bf, true);
-                       list_add_tail(&bf->list, &bf_q);
-                       ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
-                       if (bf_isampdu(bf)) {
-@@ -1688,6 +1705,9 @@ void ath9k_release_buffered_frames(struc
-       if (list_empty(&bf_q))
-               return;
-+      if (!more_data)
-+              ath9k_set_moredata(sc, bf_tail, false);
-+
-       info = IEEE80211_SKB_CB(bf_tail->bf_mpdu);
-       info->flags |= IEEE80211_TX_STATUS_EOSP;
diff --git a/package/kernel/mac80211/patches/307-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/307-mac80211-add-hdrlen-to-ieee80211_tx_data.patch
new file mode 100644 (file)
index 0000000..1a6fd84
--- /dev/null
@@ -0,0 +1,219 @@
+From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+Date: Fri, 19 Feb 2016 11:01:49 +0100
+Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data
+
+Add hdrlen to ieee80211_tx_data and use this
+when wep/ccmd/tkip. This is preparation for
+aligned4 code.
+
+Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+---
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -177,6 +177,7 @@ struct ieee80211_tx_data {
+       struct ieee80211_tx_rate rate;
+       unsigned int flags;
++      unsigned int hdrlen;
+ };
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -925,7 +925,7 @@ ieee80211_tx_h_fragment(struct ieee80211
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr = (void *)skb->data;
+       int frag_threshold = tx->local->hw.wiphy->frag_threshold;
+-      int hdrlen;
++      int hdrlen = tx->hdrlen;
+       int fragnum;
+       /* no matter what happens, tx->skb moves to tx->skbs */
+@@ -946,8 +946,6 @@ ieee80211_tx_h_fragment(struct ieee80211
+       if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
+               return TX_DROP;
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
+-
+       /* internal error, why isn't DONTFRAG set? */
+       if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
+               return TX_DROP;
+@@ -1179,6 +1177,8 @@ ieee80211_tx_prepare(struct ieee80211_su
+       hdr = (struct ieee80211_hdr *) skb->data;
++      tx->hdrlen = ieee80211_hdrlen(hdr->frame_control);
++
+       if (likely(sta)) {
+               if (!IS_ERR(sta))
+                       tx->sta = sta;
+@@ -3437,6 +3437,7 @@ begin:
+       tx.local = local;
+       tx.skb = skb;
+       tx.sdata = vif_to_sdata(info->control.vif);
++      tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control);
+       if (txq->sta)
+               tx.sta = container_of(txq->sta, struct sta_info, sta);
+@@ -3731,6 +3732,7 @@ ieee80211_build_data_template(struct iee
+       hdr = (void *)skb->data;
+       tx.sta = sta_info_get(sdata, hdr->addr1);
+       tx.skb = skb;
++      tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control);
+       if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) {
+               rcu_read_unlock();
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1227,6 +1227,7 @@ void ieee80211_send_auth(struct ieee8021
+       struct ieee80211_local *local = sdata->local;
+       struct sk_buff *skb;
+       struct ieee80211_mgmt *mgmt;
++      unsigned int hdrlen;
+       int err;
+       /* 24 + 6 = header + auth_algo + auth_transaction + status_code */
+@@ -1251,8 +1252,10 @@ void ieee80211_send_auth(struct ieee8021
+               memcpy(skb_put(skb, extra_len), extra, extra_len);
+       if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
++              hdrlen = ieee80211_hdrlen(mgmt->frame_control);
+               mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+-              err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
++              err = ieee80211_wep_encrypt(local, skb, hdrlen, key,
++                                          key_len, key_idx);
+               WARN_ON(err);
+       }
+--- a/net/mac80211/wep.c
++++ b/net/mac80211/wep.c
+@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct
+ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
+                               struct sk_buff *skb,
++                              unsigned int hdrlen,
+                               int keylen, int keyidx)
+ {
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+-      unsigned int hdrlen;
+       u8 *newhdr;
+       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i
+       if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
+               return NULL;
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
+       newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN);
+       memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen);
+@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr
+  */
+ int ieee80211_wep_encrypt(struct ieee80211_local *local,
+                         struct sk_buff *skb,
++                        unsigned int hdrlen,
+                         const u8 *key, int keylen, int keyidx)
+ {
+       u8 *iv;
+@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802
+       if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN))
+               return -1;
+-      iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx);
++      iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx);
+       if (!iv)
+               return -1;
+@@ -307,13 +307,14 @@ static int wep_encrypt_skb(struct ieee80
+       struct ieee80211_key_conf *hw_key = info->control.hw_key;
+       if (!hw_key) {
+-              if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
++              if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen,
++                                        tx->key->conf.key,
+                                         tx->key->conf.keylen,
+                                         tx->key->conf.keyidx))
+                       return -1;
+       } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
+                  (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
+-              if (!ieee80211_wep_add_iv(tx->local, skb,
++              if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen,
+                                         tx->key->conf.keylen,
+                                         tx->key->conf.keyidx))
+                       return -1;
+--- a/net/mac80211/wep.h
++++ b/net/mac80211/wep.h
+@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr
+                               size_t klen, u8 *data, size_t data_len);
+ int ieee80211_wep_encrypt(struct ieee80211_local *local,
+                         struct sk_buff *skb,
++                        unsigned int hdrlen,
+                         const u8 *key, int keylen, int keyidx);
+ int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
+                              size_t klen, u8 *data, size_t data_len);
+--- a/net/mac80211/wpa.c
++++ b/net/mac80211/wpa.c
+@@ -43,7 +43,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
+           skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control))
+               return TX_CONTINUE;
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
++      hdrlen = tx->hdrlen;
+       if (skb->len < hdrlen)
+               return TX_DROP;
+@@ -186,7 +186,6 @@ mic_fail_no_key:
+ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
+ {
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_key *key = tx->key;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       unsigned int hdrlen;
+@@ -201,7 +200,7 @@ static int tkip_encrypt_skb(struct ieee8
+               return 0;
+       }
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
++      hdrlen = tx->hdrlen;
+       len = skb->len - hdrlen;
+       if (info->control.hw_key)
+@@ -419,7 +418,7 @@ static int ccmp_encrypt_skb(struct ieee8
+               return 0;
+       }
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
++      hdrlen = tx->hdrlen;
+       len = skb->len - hdrlen;
+       if (info->control.hw_key)
+@@ -652,7 +651,7 @@ static int gcmp_encrypt_skb(struct ieee8
+               return 0;
+       }
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
++      hdrlen = tx->hdrlen;
+       len = skb->len - hdrlen;
+       if (info->control.hw_key)
+@@ -792,7 +791,6 @@ static ieee80211_tx_result
+ ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
+                           struct sk_buff *skb)
+ {
+-      struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_key *key = tx->key;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       int hdrlen;
+@@ -808,8 +806,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8
+                    pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC)))
+               return TX_DROP;
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
+-
++      hdrlen = tx->hdrlen;
+       pos = skb_push(skb, iv_len);
+       memmove(pos, pos + iv_len, hdrlen);
diff --git a/package/kernel/mac80211/patches/308-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch b/package/kernel/mac80211/patches/308-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch
deleted file mode 100644 (file)
index 929da25..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 28 Aug 2016 13:13:42 +0200
-Subject: [PATCH] ath9k: clear potentially stale EOSP status bit in
- intermediate queues
-
-Prevents spurious ieee80211_sta_eosp calls.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -945,7 +945,8 @@ ath_tx_get_tid_subframe(struct ath_softc
-               bf->bf_lastbf = bf;
-               tx_info = IEEE80211_SKB_CB(skb);
--              tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
-+              tx_info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
-+                                  IEEE80211_TX_STATUS_EOSP);
-               /*
-                * No aggregation session is running, but there may be frames
diff --git a/package/kernel/mac80211/patches/308-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/308-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch
new file mode 100644 (file)
index 0000000..4345577
--- /dev/null
@@ -0,0 +1,233 @@
+From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+Date: Fri, 19 Feb 2016 11:01:50 +0100
+Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag
+
+HW/driver should set NEED_ALIGNED4_SKBS flag in case
+require aligned skbs to four-byte boundaries.
+This affect only TX direction.
+
+Padding is added after ieee80211_hdr, before IV/LLC.
+
+Before we have to do memmove(hdrlen) twice in the
+dirver. Once before we pass this to HW and next
+in tx completion (to be sure monitor will report
+this tx frame correctly).
+
+With this patch we can skip this memmove() and save CPU.
+
+Currently this was tested with ath9k, both hw/sw crypt for
+wep/tkip/ccmp.
+
+Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
+---
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -2043,6 +2043,9 @@ struct ieee80211_txq {
+  *    The stack will not do fragmentation.
+  *    The callback for @set_frag_threshold should be set as well.
+  *
++ * @IEEE80211_HW_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte.
++ *    Padding will be added after ieee80211_hdr, before IV/LLC.
++ *
+  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
+  */
+ enum ieee80211_hw_flags {
+@@ -2085,6 +2088,7 @@ enum ieee80211_hw_flags {
+       IEEE80211_HW_TX_FRAG_LIST,
+       IEEE80211_HW_REPORTS_LOW_ACK,
+       IEEE80211_HW_SUPPORTS_TX_FRAG,
++      IEEE80211_HW_NEEDS_ALIGNED4_SKBS,
+       /* keep last, obviously */
+       NUM_IEEE80211_HW_FLAGS
+--- a/net/mac80211/debugfs.c
++++ b/net/mac80211/debugfs.c
+@@ -211,6 +211,7 @@ static const char *hw_flag_names[] = {
+       FLAG(TX_FRAG_LIST),
+       FLAG(REPORTS_LOW_ACK),
+       FLAG(SUPPORTS_TX_FRAG),
++      FLAG(NEEDS_ALIGNED4_SKBS),
+ #undef FLAG
+ };
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1553,6 +1553,29 @@ ieee80211_vif_get_num_mcast_if(struct ie
+       return -1;
+ }
++static inline unsigned int
++ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen)
++{
++      /*
++       * While hdrlen is already aligned to two-byte boundaries,
++       * simple check with & 2 will return correct padsize.
++       */
++      if (ieee80211_hw_check(hw, NEEDS_ALIGNED4_SKBS))
++              return hdrlen & 2;
++      return 0;
++}
++
++static inline unsigned int
++ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc)
++{
++      unsigned int hdrlen;
++
++      hdrlen = ieee80211_hdrlen(fc);
++      hdrlen += ieee80211_hdr_padsize(hw, hdrlen);
++
++      return hdrlen;
++}
++
+ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
+                                    struct ieee80211_rx_status *status,
+                                    unsigned int mpdu_len,
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -282,7 +282,7 @@ struct ieee80211_fast_tx {
+       u8 hdr_len;
+       u8 sa_offs, da_offs, pn_offs;
+       u8 band;
+-      u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
++      u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
+              sizeof(rfc1042_header)] __aligned(2);
+       struct rcu_head rcu_head;
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -693,9 +693,22 @@ void ieee80211_tx_monitor(struct ieee802
+       struct sk_buff *skb2;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_sub_if_data *sdata;
++      struct ieee80211_hdr *hdr = (void *)skb->data;
+       struct net_device *prev_dev = NULL;
++      unsigned int hdrlen, padsize;
+       int rtap_len;
++      /* Remove padding if was added */
++      if (ieee80211_hw_check(&local->hw, NEEDS_ALIGNED4_SKBS)) {
++              hdrlen = ieee80211_hdrlen(hdr->frame_control);
++              padsize = ieee80211_hdr_padsize(&local->hw, hdrlen);
++
++              if (padsize && skb->len > hdrlen + padsize) {
++                      memmove(skb->data + padsize, skb->data, hdrlen);
++                      skb_pull(skb, padsize);
++              }
++      }
++
+       /* send frame to monitor interfaces now */
+       rtap_len = ieee80211_tx_radiotap_len(info);
+       if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) {
+--- a/net/mac80211/tkip.c
++++ b/net/mac80211/tkip.c
+@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8
+ {
+       struct ieee80211_key *key = (struct ieee80211_key *)
+                       container_of(keyconf, struct ieee80211_key, conf);
++      struct ieee80211_hw *hw = &key->local->hw;
+       const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
+       struct tkip_ctx *ctx = &key->u.tkip.tx;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+-      const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
++      const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw,
++                                                      hdr->frame_control);
+       u32 iv32 = get_unaligned_le32(&data[4]);
+       u16 iv16 = data[2] | (data[0] << 8);
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1176,8 +1176,7 @@ ieee80211_tx_prepare(struct ieee80211_su
+       info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+       hdr = (struct ieee80211_hdr *) skb->data;
+-
+-      tx->hdrlen = ieee80211_hdrlen(hdr->frame_control);
++      tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control);
+       if (likely(sta)) {
+               if (!IS_ERR(sta))
+@@ -2152,7 +2151,7 @@ netdev_tx_t ieee80211_monitor_start_xmit
+               goto fail;
+       hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
+-      hdrlen = ieee80211_hdrlen(hdr->frame_control);
++      hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control);
+       if (skb->len < len_rthdr + hdrlen)
+               goto fail;
+@@ -2370,7 +2369,7 @@ static struct sk_buff *ieee80211_build_h
+       struct ieee80211_chanctx_conf *chanctx_conf;
+       struct ieee80211_sub_if_data *ap_sdata;
+       enum nl80211_band band;
+-      int ret;
++      int padsize, ret;
+       if (IS_ERR(sta))
+               sta = NULL;
+@@ -2590,6 +2589,9 @@ static struct sk_buff *ieee80211_build_h
+               hdrlen += 2;
+       }
++      /* Check aligned4 skb required */
++      padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen);
++
+       /*
+        * Drop unicast frames to unauthorised stations unless they are
+        * EAPOL frames from the local station.
+@@ -2670,6 +2672,7 @@ static struct sk_buff *ieee80211_build_h
+       skb_pull(skb, skip_header_bytes);
+       head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
++      head_need += padsize;
+       /*
+        * So we need to modify the skb header and hence need a copy of
+@@ -2702,6 +2705,9 @@ static struct sk_buff *ieee80211_build_h
+               memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
+ #endif
++      if (padsize)
++              memset(skb_push(skb, padsize), 0, padsize);
++
+       if (ieee80211_is_data_qos(fc)) {
+               __le16 *qos_control;
+@@ -2877,6 +2883,9 @@ void ieee80211_check_fast_xmit(struct st
+               fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
+       }
++      /* Check aligned4 skb required */
++      build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len);
++
+       /* We store the key here so there's no point in using rcu_dereference()
+        * but that's fine because the code that changes the pointers will call
+        * this function after doing so. For a single CPU that would be enough,
+@@ -3464,7 +3473,7 @@ begin:
+               if (tx.key &&
+                   (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
+-                      pn_offs = ieee80211_hdrlen(hdr->frame_control);
++                      pn_offs = tx.hdrlen;
+               ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
+                                          tx.key, skb);
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1225,6 +1225,7 @@ void ieee80211_send_auth(struct ieee8021
+                        u32 tx_flags)
+ {
+       struct ieee80211_local *local = sdata->local;
++      struct ieee80211_hw *hw = &local->hw;
+       struct sk_buff *skb;
+       struct ieee80211_mgmt *mgmt;
+       unsigned int hdrlen;
+@@ -1252,7 +1253,7 @@ void ieee80211_send_auth(struct ieee8021
+               memcpy(skb_put(skb, extra_len), extra, extra_len);
+       if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
+-              hdrlen = ieee80211_hdrlen(mgmt->frame_control);
++              hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control);
+               mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+               err = ieee80211_wep_encrypt(local, skb, hdrlen, key,
+                                           key_len, key_idx);
diff --git a/package/kernel/mac80211/patches/309-ath9k-report-tx-status-on-EOSP.patch b/package/kernel/mac80211/patches/309-ath9k-report-tx-status-on-EOSP.patch
deleted file mode 100644 (file)
index 80a3074..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 28 Aug 2016 13:23:27 +0200
-Subject: [PATCH] ath9k: report tx status on EOSP
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -86,7 +86,8 @@ static void ath_tx_status(struct ieee802
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_sta *sta = info->status.status_driver_data[0];
--      if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
-+      if (info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS |
-+                         IEEE80211_TX_STATUS_EOSP)) {
-               ieee80211_tx_status(hw, skb);
-               return;
-       }
diff --git a/package/kernel/mac80211/patches/309-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/309-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch
new file mode 100644 (file)
index 0000000..a62b1bb
--- /dev/null
@@ -0,0 +1,82 @@
+From: Chaitanya T K <chaitanya.mgit@gmail.com>
+Date: Mon, 27 Jun 2016 15:23:26 +0530
+Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates
+
+If peer support reception of STBC and LDPC, enable them for better
+performance.
+
+Signed-off-by: Chaitanya TK <chaitanya.mgit@gmail.com>
+---
+
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -1553,6 +1553,7 @@ struct ieee80211_vht_operation {
+ #define IEEE80211_VHT_CAP_RXSTBC_3                            0x00000300
+ #define IEEE80211_VHT_CAP_RXSTBC_4                            0x00000400
+ #define IEEE80211_VHT_CAP_RXSTBC_MASK                         0x00000700
++#define IEEE80211_VHT_CAP_RXSTBC_SHIFT                                8
+ #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE                       0x00000800
+ #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE                       0x00001000
+ #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT                  13
+--- a/net/mac80211/rc80211_minstrel_ht.c
++++ b/net/mac80211/rc80211_minstrel_ht.c
+@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, stru
+       struct minstrel_ht_sta_priv *msp = priv_sta;
+       struct minstrel_ht_sta *mi = &msp->ht;
+       struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
+-      u16 sta_cap = sta->ht_cap.cap;
++      u16 ht_cap = sta->ht_cap.cap;
+       struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
+       struct sta_info *sinfo = container_of(sta, struct sta_info, sta);
+       int use_vht;
+@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, stru
+       int ack_dur;
+       int stbc;
+       int i;
++      bool ldpc = false;
+       /* fall back to the old minstrel for legacy stations */
+       if (!sta->ht_cap.ht_supported)
+@@ -1175,16 +1176,24 @@ minstrel_ht_update_caps(void *priv, stru
+       }
+       mi->sample_tries = 4;
+-      /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */
+       if (!use_vht) {
+-              stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >>
++              stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >>
+                       IEEE80211_HT_CAP_RX_STBC_SHIFT;
+-              mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
+-              if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
+-                      mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
++              if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING)
++                      ldpc = true;
++      } else {
++              stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >>
++                      IEEE80211_VHT_CAP_RXSTBC_SHIFT;
++
++              if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)
++                      ldpc = true;
+       }
++      mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT;
++      if (ldpc)
++              mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
++
+       for (i = 0; i < ARRAY_SIZE(mi->groups); i++) {
+               u32 gflags = minstrel_mcs_groups[i].flags;
+               int bw, nss;
+@@ -1197,10 +1206,10 @@ minstrel_ht_update_caps(void *priv, stru
+               if (gflags & IEEE80211_TX_RC_SHORT_GI) {
+                       if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+-                              if (!(sta_cap & IEEE80211_HT_CAP_SGI_40))
++                              if (!(ht_cap & IEEE80211_HT_CAP_SGI_40))
+                                       continue;
+                       } else {
+-                              if (!(sta_cap & IEEE80211_HT_CAP_SGI_20))
++                              if (!(ht_cap & IEEE80211_HT_CAP_SGI_20))
+                                       continue;
+                       }
+               }
diff --git a/package/kernel/mac80211/patches/310-ath9k-fix-block-ack-window-tracking-issues.patch b/package/kernel/mac80211/patches/310-ath9k-fix-block-ack-window-tracking-issues.patch
deleted file mode 100644 (file)
index 2993cba..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 30 Aug 2016 12:44:08 +0200
-Subject: [PATCH] ath9k: fix block-ack window tracking issues
-
-Ensure that a buffer gets tracked as part of the block-ack window as
-soon as it's dequeued from the tid for the first time. Ensure that
-double calls to ath_tx_addto_baw (e.g. on retransmission) don't cause
-any issues.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -62,7 +62,7 @@ static void ath_tx_rc_status(struct ath_
-                            struct ath_tx_status *ts, int nframes, int nbad,
-                            int txok);
- static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
--                            int seqno);
-+                            struct ath_buf *bf);
- static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
-                                          struct ath_txq *txq,
-                                          struct ath_atx_tid *tid,
-@@ -300,7 +300,7 @@ static void ath_tx_flush_tid(struct ath_
-               }
-               if (fi->baw_tracked) {
--                      ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
-+                      ath_tx_update_baw(sc, tid, bf);
-                       sendbar = true;
-               }
-@@ -316,10 +316,15 @@ static void ath_tx_flush_tid(struct ath_
- }
- static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
--                            int seqno)
-+                            struct ath_buf *bf)
- {
-+      struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
-+      u16 seqno = bf->bf_state.seqno;
-       int index, cindex;
-+      if (!fi->baw_tracked)
-+              return;
-+
-       index  = ATH_BA_INDEX(tid->seq_start, seqno);
-       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-@@ -340,6 +345,9 @@ static void ath_tx_addto_baw(struct ath_
-       u16 seqno = bf->bf_state.seqno;
-       int index, cindex;
-+      if (fi->baw_tracked)
-+              return;
-+
-       index  = ATH_BA_INDEX(tid->seq_start, seqno);
-       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-       __set_bit(cindex, tid->tx_buf);
-@@ -616,7 +624,7 @@ static void ath_tx_complete_aggr(struct
-                        * complete the acked-ones/xretried ones; update
-                        * block-ack window
-                        */
--                      ath_tx_update_baw(sc, tid, seqno);
-+                      ath_tx_update_baw(sc, tid, bf);
-                       if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
-                               memcpy(tx_info->control.rates, rates, sizeof(rates));
-@@ -646,7 +654,7 @@ static void ath_tx_complete_aggr(struct
-                                * run out of tx buf.
-                                */
-                               if (!tbf) {
--                                      ath_tx_update_baw(sc, tid, seqno);
-+                                      ath_tx_update_baw(sc, tid, bf);
-                                       ath_tx_complete_buf(sc, bf, txq,
-                                                           &bf_head, NULL, ts,
-@@ -987,11 +995,14 @@ ath_tx_get_tid_subframe(struct ath_softc
-                       INIT_LIST_HEAD(&bf_head);
-                       list_add(&bf->list, &bf_head);
--                      ath_tx_update_baw(sc, tid, seqno);
-+                      ath_tx_update_baw(sc, tid, bf);
-                       ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
-                       continue;
-               }
-+              if (bf_isampdu(bf))
-+                      ath_tx_addto_baw(sc, tid, bf);
-+
-               return bf;
-       }
-@@ -1049,8 +1060,6 @@ ath_tx_form_aggr(struct ath_softc *sc, s
-               bf->bf_next = NULL;
-               /* link buffers of this frame to the aggregate */
--              if (!fi->baw_tracked)
--                      ath_tx_addto_baw(sc, tid, bf);
-               bf->bf_state.ndelim = ndelim;
-               list_add_tail(&bf->list, bf_q);
-@@ -1686,10 +1695,8 @@ void ath9k_release_buffered_frames(struc
-                       ath9k_set_moredata(sc, bf, true);
-                       list_add_tail(&bf->list, &bf_q);
-                       ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
--                      if (bf_isampdu(bf)) {
--                              ath_tx_addto_baw(sc, tid, bf);
-+                      if (bf_isampdu(bf))
-                               bf->bf_state.bf_type &= ~BUF_AGGR;
--                      }
-                       if (bf_tail)
-                               bf_tail->bf_next = bf;
diff --git a/package/kernel/mac80211/patches/310-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch b/package/kernel/mac80211/patches/310-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch
new file mode 100644 (file)
index 0000000..b2a74cc
--- /dev/null
@@ -0,0 +1,50 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 28 Aug 2016 13:13:01 +0200
+Subject: [PATCH] ath9k: fix moredata bit in PS buffered frame release
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1694,6 +1694,22 @@ void ath_tx_aggr_wakeup(struct ath_softc
+       }
+ }
++
++static void
++ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val)
++{
++      struct ieee80211_hdr *hdr;
++      u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA);
++      u16 mask_val = mask * val;
++
++      hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
++      if ((hdr->frame_control & mask) != mask_val) {
++              hdr->frame_control = (hdr->frame_control & ~mask) | mask_val;
++              dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
++                      sizeof(*hdr), DMA_TO_DEVICE);
++      }
++}
++
+ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
+                                  struct ieee80211_sta *sta,
+                                  u16 tids, int nframes,
+@@ -1724,6 +1740,7 @@ void ath9k_release_buffered_frames(struc
+                       if (!bf)
+                               break;
++                      ath9k_set_moredata(sc, bf, true);
+                       list_add_tail(&bf->list, &bf_q);
+                       ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
+                       if (bf_isampdu(bf)) {
+@@ -1747,6 +1764,9 @@ void ath9k_release_buffered_frames(struc
+       if (list_empty(&bf_q))
+               return;
++      if (!more_data)
++              ath9k_set_moredata(sc, bf_tail, false);
++
+       info = IEEE80211_SKB_CB(bf_tail->bf_mpdu);
+       info->flags |= IEEE80211_TX_STATUS_EOSP;
diff --git a/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch b/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch
deleted file mode 100644 (file)
index 372ce58..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-From: Ben Greear <greearb@candelatech.com>
-Date: Thu, 6 Oct 2016 17:34:14 -0700
-Subject: [PATCH] ath10k: Add support for 160Mhz.
-
-This patch was written by Sebastian Gottschall.
-
-Signed-off-by: Ben Greear <greearb@candelatech.com>
-Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/htt_rx.c
-+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
-@@ -702,6 +702,10 @@ static void ath10k_htt_rx_h_rates(struct
-               /* 80MHZ */
-               case 2:
-                       status->vht_flag |= RX_VHT_FLAG_80MHZ;
-+                      break;
-+              case 3:
-+                      status->vht_flag |= RX_VHT_FLAG_160MHZ;
-+                      break;
-               }
-               status->flag |= RX_FLAG_VHT;
-@@ -926,7 +930,7 @@ static void ath10k_process_rx(struct ath
-       *status = *rx_status;
-       ath10k_dbg(ar, ATH10K_DBG_DATA,
--                 "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
-+                 "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
-                  skb,
-                  skb->len,
-                  ieee80211_get_SA(hdr),
-@@ -940,6 +944,7 @@ static void ath10k_process_rx(struct ath
-                  status->flag & RX_FLAG_VHT ? "vht" : "",
-                  status->flag & RX_FLAG_40MHZ ? "40" : "",
-                  status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
-+                 status->vht_flag & RX_VHT_FLAG_160MHZ ? "160" : "",
-                  status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
-                  status->rate_idx,
-                  status->vht_nss,
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -568,10 +568,14 @@ chan_to_phymode(const struct cfg80211_ch
-               case NL80211_CHAN_WIDTH_80:
-                       phymode = MODE_11AC_VHT80;
-                       break;
-+              case NL80211_CHAN_WIDTH_160:
-+                      phymode = MODE_11AC_VHT160;
-+                      break;
-+              case NL80211_CHAN_WIDTH_80P80:
-+                      phymode = MODE_11AC_VHT80_80;
-+                      break;
-               case NL80211_CHAN_WIDTH_5:
-               case NL80211_CHAN_WIDTH_10:
--              case NL80211_CHAN_WIDTH_80P80:
--              case NL80211_CHAN_WIDTH_160:
-                       phymode = MODE_UNKNOWN;
-                       break;
-               }
-@@ -970,6 +974,7 @@ static int ath10k_monitor_vdev_start(str
-       arg.vdev_id = vdev_id;
-       arg.channel.freq = channel->center_freq;
-       arg.channel.band_center_freq1 = chandef->center_freq1;
-+      arg.channel.band_center_freq2 = chandef->center_freq2;
-       /* TODO setup this dynamically, what in case we
-          don't have any vifs? */
-@@ -1381,6 +1386,7 @@ static int ath10k_vdev_start_restart(str
-       arg.channel.freq = chandef->chan->center_freq;
-       arg.channel.band_center_freq1 = chandef->center_freq1;
-+      arg.channel.band_center_freq2 = chandef->center_freq2;
-       arg.channel.mode = chan_to_phymode(chandef);
-       arg.channel.min_power = 0;
-@@ -2444,6 +2450,9 @@ static void ath10k_peer_assoc_h_vht(stru
-       if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
-               arg->peer_flags |= ar->wmi.peer_flags->bw80;
-+      if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
-+              arg->peer_flags |= ar->wmi.peer_flags->bw160;
-+
-       arg->peer_vht_rates.rx_max_rate =
-               __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
-       arg->peer_vht_rates.rx_mcs_set =
-@@ -2545,7 +2554,17 @@ static void ath10k_peer_assoc_h_phymode(
-                   !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
-                       if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
-                               phymode = MODE_11AC_VHT80;
--                      else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
-+                      else if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
-+                              phymode = MODE_11AC_VHT160;
-+                              switch (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) {
-+                              case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
-+                                      phymode = MODE_11AC_VHT160;
-+                              break;
-+                              case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
-+                                      phymode = MODE_11AC_VHT80_80;
-+                              break;
-+                              }
-+                      } else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
-                               phymode = MODE_11AC_VHT40;
-                       else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
-                               phymode = MODE_11AC_VHT20;
-@@ -4277,6 +4296,10 @@ static struct ieee80211_sta_vht_cap ath1
-               vht_cap.cap |= val;
-       }
-+      if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) && !(ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) {
-+              vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
-+      }
-+
-       mcs_map = 0;
-       for (i = 0; i < 8; i++) {
-               if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
-@@ -6913,6 +6936,9 @@ static void ath10k_sta_rc_update(struct
-                       bw = WMI_PEER_CHWIDTH_80MHZ;
-                       break;
-               case IEEE80211_STA_RX_BW_160:
-+                      bw = WMI_PEER_CHWIDTH_160MHZ;
-+                      break;
-+              default:
-                       ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
-                                   sta->bandwidth, sta->addr);
-                       bw = WMI_PEER_CHWIDTH_20MHZ;
---- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
-+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
-@@ -3560,6 +3560,7 @@ static const struct wmi_peer_flags_map w
-       .vht = WMI_TLV_PEER_VHT,
-       .bw80 = WMI_TLV_PEER_80MHZ,
-       .pmf = WMI_TLV_PEER_PMF,
-+      .bw160 = WMI_TLV_PEER_160MHZ,
- };
- /************/
---- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
-+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
-@@ -543,6 +543,7 @@ enum wmi_tlv_peer_flags {
-       WMI_TLV_PEER_VHT = 0x02000000,
-       WMI_TLV_PEER_80MHZ = 0x04000000,
-       WMI_TLV_PEER_PMF = 0x08000000,
-+      WMI_TLV_PEER_160MHZ = 0x20000000,
- };
- enum wmi_tlv_tag {
---- a/drivers/net/wireless/ath/ath10k/wmi.c
-+++ b/drivers/net/wireless/ath/ath10k/wmi.c
-@@ -1576,6 +1576,7 @@ static const struct wmi_peer_flags_map w
-       .bw80 = WMI_PEER_80MHZ,
-       .vht_2g = WMI_PEER_VHT_2G,
-       .pmf = WMI_PEER_PMF,
-+      .bw160 = WMI_PEER_160MHZ,
- };
- static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = {
-@@ -1593,6 +1594,7 @@ static const struct wmi_peer_flags_map w
-       .spatial_mux = WMI_10X_PEER_SPATIAL_MUX,
-       .vht = WMI_10X_PEER_VHT,
-       .bw80 = WMI_10X_PEER_80MHZ,
-+      .bw160 = WMI_10X_PEER_160MHZ,
- };
- static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
-@@ -1612,6 +1614,7 @@ static const struct wmi_peer_flags_map w
-       .bw80 = WMI_10_2_PEER_80MHZ,
-       .vht_2g = WMI_10_2_PEER_VHT_2G,
-       .pmf = WMI_10_2_PEER_PMF,
-+      .bw160 = WMI_10_2_PEER_160MHZ,
- };
- void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
-@@ -1636,7 +1639,10 @@ void ath10k_wmi_put_wmi_channel(struct w
-       ch->mhz = __cpu_to_le32(arg->freq);
-       ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
--      ch->band_center_freq2 = 0;
-+      if (arg->mode == MODE_11AC_VHT80_80)
-+              ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2);
-+      else
-+              ch->band_center_freq2 = 0;
-       ch->min_power = arg->min_power;
-       ch->max_power = arg->max_power;
-       ch->reg_power = arg->max_reg_power;
---- a/drivers/net/wireless/ath/ath10k/wmi.h
-+++ b/drivers/net/wireless/ath/ath10k/wmi.h
-@@ -1728,8 +1728,10 @@ enum wmi_phy_mode {
-       MODE_11AC_VHT20_2G = 11,
-       MODE_11AC_VHT40_2G = 12,
-       MODE_11AC_VHT80_2G = 13,
--      MODE_UNKNOWN    = 14,
--      MODE_MAX        = 14
-+      MODE_11AC_VHT80_80 = 14,
-+      MODE_11AC_VHT160 = 15,
-+      MODE_UNKNOWN    = 16,
-+      MODE_MAX        = 16
- };
- static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode)
-@@ -1757,6 +1759,10 @@ static inline const char *ath10k_wmi_phy
-               return "11ac-vht40";
-       case MODE_11AC_VHT80:
-               return "11ac-vht80";
-+      case MODE_11AC_VHT160:
-+              return "11ac-vht160";
-+      case MODE_11AC_VHT80_80:
-+              return "11ac-vht80+80";
-       case MODE_11AC_VHT20_2G:
-               return "11ac-vht20-2g";
-       case MODE_11AC_VHT40_2G:
-@@ -1811,6 +1817,7 @@ struct wmi_channel {
- struct wmi_channel_arg {
-       u32 freq;
-       u32 band_center_freq1;
-+      u32 band_center_freq2;
-       bool passive;
-       bool allow_ibss;
-       bool allow_ht;
-@@ -1875,9 +1882,18 @@ enum wmi_channel_change_cause {
- #define WMI_VHT_CAP_MAX_MPDU_LEN_MASK            0x00000003
- #define WMI_VHT_CAP_RX_LDPC                      0x00000010
- #define WMI_VHT_CAP_SGI_80MHZ                    0x00000020
-+#define WMI_VHT_CAP_SGI_160MHZ                   0x00000040
- #define WMI_VHT_CAP_TX_STBC                      0x00000080
- #define WMI_VHT_CAP_RX_STBC_MASK                 0x00000300
- #define WMI_VHT_CAP_RX_STBC_MASK_SHIFT           8
-+#define WMI_VHT_CAP_SU_BFER                      0x00000800
-+#define WMI_VHT_CAP_SU_BFEE                      0x00001000
-+#define WMI_VHT_CAP_MAX_CS_ANT_MASK              0x0000E000
-+#define WMI_VHT_CAP_MAX_CS_ANT_MASK_SHIFT        13
-+#define WMI_VHT_CAP_MAX_SND_DIM_MASK             0x00070000
-+#define WMI_VHT_CAP_MAX_SND_DIM_MASK_SHIFT       16
-+#define WMI_VHT_CAP_MU_BFER                      0x00080000
-+#define WMI_VHT_CAP_MU_BFEE                      0x00100000
- #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP            0x03800000
- #define WMI_VHT_CAP_MAX_AMPDU_LEN_EXP_SHIFT      23
- #define WMI_VHT_CAP_RX_FIXED_ANT                 0x10000000
-@@ -1926,6 +1942,8 @@ enum {
-       REGDMN_MODE_11AC_VHT40PLUS   = 0x40000, /* 5Ghz, VHT40 + channels */
-       REGDMN_MODE_11AC_VHT40MINUS  = 0x80000, /* 5Ghz  VHT40 - channels */
-       REGDMN_MODE_11AC_VHT80       = 0x100000, /* 5Ghz, VHT80 channels */
-+      REGDMN_MODE_11AC_VHT160      = 0x200000,     /* 5Ghz, VHT160 channels */
-+      REGDMN_MODE_11AC_VHT80_80    = 0x400000,     /* 5Ghz, VHT80+80 channels */
-       REGDMN_MODE_ALL              = 0xffffffff
- };
-@@ -5769,6 +5787,7 @@ enum wmi_peer_chwidth {
-       WMI_PEER_CHWIDTH_20MHZ = 0,
-       WMI_PEER_CHWIDTH_40MHZ = 1,
-       WMI_PEER_CHWIDTH_80MHZ = 2,
-+      WMI_PEER_CHWIDTH_160MHZ = 3,
- };
- enum wmi_peer_param {
-@@ -5859,6 +5878,7 @@ struct wmi_peer_flags_map {
-       u32 bw80;
-       u32 vht_2g;
-       u32 pmf;
-+      u32 bw160;
- };
- enum wmi_peer_flags {
-@@ -5878,6 +5898,7 @@ enum wmi_peer_flags {
-       WMI_PEER_80MHZ = 0x04000000,
-       WMI_PEER_VHT_2G = 0x08000000,
-       WMI_PEER_PMF = 0x10000000,
-+      WMI_PEER_160MHZ = 0x20000000
- };
- enum wmi_10x_peer_flags {
-@@ -5895,6 +5916,7 @@ enum wmi_10x_peer_flags {
-       WMI_10X_PEER_SPATIAL_MUX = 0x00200000,
-       WMI_10X_PEER_VHT = 0x02000000,
-       WMI_10X_PEER_80MHZ = 0x04000000,
-+      WMI_10X_PEER_160MHZ = 0x20000000
- };
- enum wmi_10_2_peer_flags {
-@@ -5914,6 +5936,7 @@ enum wmi_10_2_peer_flags {
-       WMI_10_2_PEER_80MHZ = 0x04000000,
-       WMI_10_2_PEER_VHT_2G = 0x08000000,
-       WMI_10_2_PEER_PMF = 0x10000000,
-+      WMI_10_2_PEER_160MHZ = 0x20000000
- };
- /*
diff --git a/package/kernel/mac80211/patches/311-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch b/package/kernel/mac80211/patches/311-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch
new file mode 100644 (file)
index 0000000..9863dff
--- /dev/null
@@ -0,0 +1,22 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 28 Aug 2016 13:13:42 +0200
+Subject: [PATCH] ath9k: clear potentially stale EOSP status bit in
+ intermediate queues
+
+Prevents spurious ieee80211_sta_eosp calls.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -1004,7 +1004,8 @@ ath_tx_get_tid_subframe(struct ath_softc
+               bf->bf_lastbf = bf;
+               tx_info = IEEE80211_SKB_CB(skb);
+-              tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
++              tx_info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
++                                  IEEE80211_TX_STATUS_EOSP);
+               /*
+                * No aggregation session is running, but there may be frames
diff --git a/package/kernel/mac80211/patches/312-ath9k-report-tx-status-on-EOSP.patch b/package/kernel/mac80211/patches/312-ath9k-report-tx-status-on-EOSP.patch
new file mode 100644 (file)
index 0000000..80a3074
--- /dev/null
@@ -0,0 +1,19 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 28 Aug 2016 13:23:27 +0200
+Subject: [PATCH] ath9k: report tx status on EOSP
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -86,7 +86,8 @@ static void ath_tx_status(struct ieee802
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_sta *sta = info->status.status_driver_data[0];
+-      if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) {
++      if (info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS |
++                         IEEE80211_TX_STATUS_EOSP)) {
+               ieee80211_tx_status(hw, skb);
+               return;
+       }
diff --git a/package/kernel/mac80211/patches/312-mac80211-Use-rhltable-instead-of-rhashtable.patch b/package/kernel/mac80211/patches/312-mac80211-Use-rhltable-instead-of-rhashtable.patch
deleted file mode 100644 (file)
index 4c5fff1..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-From: Herbert Xu <herbert@gondor.apana.org.au>
-Date: Mon, 19 Sep 2016 19:00:10 +0800
-Subject: [PATCH] mac80211: Use rhltable instead of rhashtable
-
-mac80211 currently uses rhashtable with insecure_elasticity set
-to true.  The latter is because of duplicate objects.  What's
-more, mac80211 walks the rhashtable chains by hand which is broken
-as rhashtable may contain multiple tables due to resizing or
-rehashing.
-
-This patch fixes it by converting it to the newly added rhltable
-interface which is designed for use with duplicate objects.
-
-With rhltable a lookup returns a list of objects instead of a
-single one.  This is then fed into the existing for_each_sta_info
-macro.
-
-This patch also deletes the sta_addr_hash function since rhashtable
-defaults to jhash.
-
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
-
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1233,7 +1233,7 @@ struct ieee80211_local {
-       spinlock_t tim_lock;
-       unsigned long num_sta;
-       struct list_head sta_list;
--      struct rhashtable sta_hash;
-+      struct rhltable sta_hash;
-       struct timer_list sta_cleanup;
-       int sta_generation;
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -4004,7 +4004,7 @@ static void __ieee80211_rx_handle_packet
-       __le16 fc;
-       struct ieee80211_rx_data rx;
-       struct ieee80211_sub_if_data *prev;
--      struct rhash_head *tmp;
-+      struct rhlist_head *tmp;
-       int err = 0;
-       fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
-@@ -4047,13 +4047,10 @@ static void __ieee80211_rx_handle_packet
-               goto out;
-       } else if (ieee80211_is_data(fc)) {
-               struct sta_info *sta, *prev_sta;
--              const struct bucket_table *tbl;
-               prev_sta = NULL;
--              tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
--
--              for_each_sta_info(local, tbl, hdr->addr2, sta, tmp) {
-+              for_each_sta_info(local, hdr->addr2, sta, tmp) {
-                       if (!prev_sta) {
-                               prev_sta = sta;
-                               continue;
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -67,12 +67,10 @@
- static const struct rhashtable_params sta_rht_params = {
-       .nelem_hint = 3, /* start small */
--      .insecure_elasticity = true, /* Disable chain-length checks. */
-       .automatic_shrinking = true,
-       .head_offset = offsetof(struct sta_info, hash_node),
-       .key_offset = offsetof(struct sta_info, addr),
-       .key_len = ETH_ALEN,
--      .hashfn = sta_addr_hash,
-       .max_size = CPTCFG_MAC80211_STA_HASH_MAX_SIZE,
- };
-@@ -80,8 +78,8 @@ static const struct rhashtable_params st
- static int sta_info_hash_del(struct ieee80211_local *local,
-                            struct sta_info *sta)
- {
--      return rhashtable_remove_fast(&local->sta_hash, &sta->hash_node,
--                                    sta_rht_params);
-+      return rhltable_remove(&local->sta_hash, &sta->hash_node,
-+                             sta_rht_params);
- }
- static void __cleanup_single_sta(struct sta_info *sta)
-@@ -157,19 +155,22 @@ static void cleanup_single_sta(struct st
-       sta_info_free(local, sta);
- }
-+struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local,
-+                                       const u8 *addr)
-+{
-+      return rhltable_lookup(&local->sta_hash, addr, sta_rht_params);
-+}
-+
- /* protected by RCU */
- struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
-                             const u8 *addr)
- {
-       struct ieee80211_local *local = sdata->local;
-+      struct rhlist_head *tmp;
-       struct sta_info *sta;
--      struct rhash_head *tmp;
--      const struct bucket_table *tbl;
-       rcu_read_lock();
--      tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
--
--      for_each_sta_info(local, tbl, addr, sta, tmp) {
-+      for_each_sta_info(local, addr, sta, tmp) {
-               if (sta->sdata == sdata) {
-                       rcu_read_unlock();
-                       /* this is safe as the caller must already hold
-@@ -190,14 +191,11 @@ struct sta_info *sta_info_get_bss(struct
-                                 const u8 *addr)
- {
-       struct ieee80211_local *local = sdata->local;
-+      struct rhlist_head *tmp;
-       struct sta_info *sta;
--      struct rhash_head *tmp;
--      const struct bucket_table *tbl;
-       rcu_read_lock();
--      tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
--
--      for_each_sta_info(local, tbl, addr, sta, tmp) {
-+      for_each_sta_info(local, addr, sta, tmp) {
-               if (sta->sdata == sdata ||
-                   (sta->sdata->bss && sta->sdata->bss == sdata->bss)) {
-                       rcu_read_unlock();
-@@ -263,8 +261,8 @@ void sta_info_free(struct ieee80211_loca
- static int sta_info_hash_add(struct ieee80211_local *local,
-                            struct sta_info *sta)
- {
--      return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
--                                    sta_rht_params);
-+      return rhltable_insert(&local->sta_hash, &sta->hash_node,
-+                             sta_rht_params);
- }
- static void sta_deliver_ps_frames(struct work_struct *wk)
-@@ -453,9 +451,9 @@ static int sta_info_insert_check(struct
-                   is_multicast_ether_addr(sta->sta.addr)))
-               return -EINVAL;
--      /* Strictly speaking this isn't necessary as we hold the mutex, but
--       * the rhashtable code can't really deal with that distinction. We
--       * do require the mutex for correctness though.
-+      /* The RCU read lock is required by rhashtable due to
-+       * asynchronous resize/rehash.  We also require the mutex
-+       * for correctness.
-        */
-       rcu_read_lock();
-       lockdep_assert_held(&sdata->local->sta_mtx);
-@@ -1043,16 +1041,11 @@ static void sta_info_cleanup(unsigned lo
-                 round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL));
- }
--u32 sta_addr_hash(const void *key, u32 length, u32 seed)
--{
--      return jhash(key, ETH_ALEN, seed);
--}
--
- int sta_info_init(struct ieee80211_local *local)
- {
-       int err;
--      err = rhashtable_init(&local->sta_hash, &sta_rht_params);
-+      err = rhltable_init(&local->sta_hash, &sta_rht_params);
-       if (err)
-               return err;
-@@ -1068,7 +1061,7 @@ int sta_info_init(struct ieee80211_local
- void sta_info_stop(struct ieee80211_local *local)
- {
-       del_timer_sync(&local->sta_cleanup);
--      rhashtable_destroy(&local->sta_hash);
-+      rhltable_destroy(&local->sta_hash);
- }
-@@ -1138,17 +1131,14 @@ struct ieee80211_sta *ieee80211_find_sta
-                                                  const u8 *localaddr)
- {
-       struct ieee80211_local *local = hw_to_local(hw);
-+      struct rhlist_head *tmp;
-       struct sta_info *sta;
--      struct rhash_head *tmp;
--      const struct bucket_table *tbl;
--
--      tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
-       /*
-        * Just return a random station if localaddr is NULL
-        * ... first in list.
-        */
--      for_each_sta_info(local, tbl, addr, sta, tmp) {
-+      for_each_sta_info(local, addr, sta, tmp) {
-               if (localaddr &&
-                   !ether_addr_equal(sta->sdata->vif.addr, localaddr))
-                       continue;
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -455,7 +455,7 @@ struct sta_info {
-       /* General information, mostly static */
-       struct list_head list, free_list;
-       struct rcu_head rcu_head;
--      struct rhash_head hash_node;
-+      struct rhlist_head hash_node;
-       u8 addr[ETH_ALEN];
-       struct ieee80211_local *local;
-       struct ieee80211_sub_if_data *sdata;
-@@ -638,6 +638,9 @@ rcu_dereference_protected_tid_tx(struct
-  */
- #define STA_INFO_CLEANUP_INTERVAL (10 * HZ)
-+struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local,
-+                                       const u8 *addr);
-+
- /*
-  * Get a STA info, must be under RCU read lock.
-  */
-@@ -647,17 +650,9 @@ struct sta_info *sta_info_get(struct iee
- struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
-                                 const u8 *addr);
--u32 sta_addr_hash(const void *key, u32 length, u32 seed);
--
--#define _sta_bucket_idx(_tbl, _a)                                     \
--      rht_bucket_index(_tbl, sta_addr_hash(_a, ETH_ALEN, (_tbl)->hash_rnd))
--
--#define for_each_sta_info(local, tbl, _addr, _sta, _tmp)              \
--      rht_for_each_entry_rcu(_sta, _tmp, tbl,                         \
--                             _sta_bucket_idx(tbl, _addr),             \
--                             hash_node)                               \
--      /* compare address and run code only if it matches */           \
--      if (ether_addr_equal(_sta->addr, (_addr)))
-+#define for_each_sta_info(local, _addr, _sta, _tmp)                   \
-+      rhl_for_each_entry_rcu(_sta, _tmp,                              \
-+                             sta_info_hash_lookup(local, _addr), hash_node)
- /*
-  * Get STA info by index, BROKEN!
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -759,8 +759,8 @@ void ieee80211_tx_status(struct ieee8021
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       __le16 fc;
-       struct ieee80211_supported_band *sband;
-+      struct rhlist_head *tmp;
-       struct sta_info *sta;
--      struct rhash_head *tmp;
-       int retry_count;
-       int rates_idx;
-       bool send_to_cooked;
-@@ -768,7 +768,6 @@ void ieee80211_tx_status(struct ieee8021
-       struct ieee80211_bar *bar;
-       int shift = 0;
-       int tid = IEEE80211_NUM_TIDS;
--      const struct bucket_table *tbl;
-       rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
-@@ -777,9 +776,7 @@ void ieee80211_tx_status(struct ieee8021
-       sband = local->hw.wiphy->bands[info->band];
-       fc = hdr->frame_control;
--      tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
--
--      for_each_sta_info(local, tbl, hdr->addr1, sta, tmp) {
-+      for_each_sta_info(local, hdr->addr1, sta, tmp) {
-               /* skip wrong virtual interface */
-               if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr))
-                       continue;
diff --git a/package/kernel/mac80211/patches/313-ath9k-fix-block-ack-window-tracking-issues.patch b/package/kernel/mac80211/patches/313-ath9k-fix-block-ack-window-tracking-issues.patch
new file mode 100644 (file)
index 0000000..fb8df08
--- /dev/null
@@ -0,0 +1,114 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Tue, 30 Aug 2016 12:44:08 +0200
+Subject: [PATCH] ath9k: fix block-ack window tracking issues
+
+Ensure that a buffer gets tracked as part of the block-ack window as
+soon as it's dequeued from the tid for the first time. Ensure that
+double calls to ath_tx_addto_baw (e.g. on retransmission) don't cause
+any issues.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -62,7 +62,7 @@ static void ath_tx_rc_status(struct ath_
+                            struct ath_tx_status *ts, int nframes, int nbad,
+                            int txok);
+ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+-                            int seqno);
++                            struct ath_buf *bf);
+ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
+                                          struct ath_txq *txq,
+                                          struct ath_atx_tid *tid,
+@@ -311,7 +311,7 @@ static void ath_tx_flush_tid(struct ath_
+               }
+               if (fi->baw_tracked) {
+-                      ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
++                      ath_tx_update_baw(sc, tid, bf);
+                       sendbar = true;
+               }
+@@ -327,10 +327,15 @@ static void ath_tx_flush_tid(struct ath_
+ }
+ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+-                            int seqno)
++                            struct ath_buf *bf)
+ {
++      struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
++      u16 seqno = bf->bf_state.seqno;
+       int index, cindex;
++      if (!fi->baw_tracked)
++              return;
++
+       index  = ATH_BA_INDEX(tid->seq_start, seqno);
+       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
+@@ -351,6 +356,9 @@ static void ath_tx_addto_baw(struct ath_
+       u16 seqno = bf->bf_state.seqno;
+       int index, cindex;
++      if (fi->baw_tracked)
++              return;
++
+       index  = ATH_BA_INDEX(tid->seq_start, seqno);
+       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
+       __set_bit(cindex, tid->tx_buf);
+@@ -627,7 +635,7 @@ static void ath_tx_complete_aggr(struct
+                        * complete the acked-ones/xretried ones; update
+                        * block-ack window
+                        */
+-                      ath_tx_update_baw(sc, tid, seqno);
++                      ath_tx_update_baw(sc, tid, bf);
+                       if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
+                               memcpy(tx_info->control.rates, rates, sizeof(rates));
+@@ -657,7 +665,7 @@ static void ath_tx_complete_aggr(struct
+                                * run out of tx buf.
+                                */
+                               if (!tbf) {
+-                                      ath_tx_update_baw(sc, tid, seqno);
++                                      ath_tx_update_baw(sc, tid, bf);
+                                       ath_tx_complete_buf(sc, bf, txq,
+                                                           &bf_head, NULL, ts,
+@@ -1046,11 +1054,14 @@ ath_tx_get_tid_subframe(struct ath_softc
+                       INIT_LIST_HEAD(&bf_head);
+                       list_add(&bf->list, &bf_head);
+-                      ath_tx_update_baw(sc, tid, seqno);
++                      ath_tx_update_baw(sc, tid, bf);
+                       ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
+                       continue;
+               }
++              if (bf_isampdu(bf))
++                      ath_tx_addto_baw(sc, tid, bf);
++
+               return bf;
+       }
+@@ -1108,8 +1119,6 @@ ath_tx_form_aggr(struct ath_softc *sc, s
+               bf->bf_next = NULL;
+               /* link buffers of this frame to the aggregate */
+-              if (!fi->baw_tracked)
+-                      ath_tx_addto_baw(sc, tid, bf);
+               bf->bf_state.ndelim = ndelim;
+               list_add_tail(&bf->list, bf_q);
+@@ -1745,10 +1754,8 @@ void ath9k_release_buffered_frames(struc
+                       ath9k_set_moredata(sc, bf, true);
+                       list_add_tail(&bf->list, &bf_q);
+                       ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
+-                      if (bf_isampdu(bf)) {
+-                              ath_tx_addto_baw(sc, tid, bf);
++                      if (bf_isampdu(bf))
+                               bf->bf_state.bf_type &= ~BUF_AGGR;
+-                      }
+                       if (bf_tail)
+                               bf_tail->bf_next = bf;
diff --git a/package/kernel/mac80211/patches/313-mac80211-fix-sequence-number-allocation-regression.patch b/package/kernel/mac80211/patches/313-mac80211-fix-sequence-number-allocation-regression.patch
deleted file mode 100644 (file)
index c1548be..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 11 Oct 2016 11:24:07 +0200
-Subject: [PATCH] mac80211: fix sequence number allocation regression
-
-The recent commit that moved around TX handlers dropped the sequence
-number allocation at the end of ieee80211_tx_dequeue and calls
-ieee80211_tx_h_sequence instead (for the non-fast-xmit case).
-However, it did not change the fast-xmit sequence allocation condition
-in ieee80211_xmit_fast_finish, which skipped seqno alloc if intermediate
-tx queues are being used.
-
-Drop the now obsolete condition.
-
-Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3212,7 +3212,6 @@ static void ieee80211_xmit_fast_finish(s
-                                      struct sk_buff *skb)
- {
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
--      struct ieee80211_local *local = sdata->local;
-       struct ieee80211_hdr *hdr = (void *)skb->data;
-       u8 tid = IEEE80211_NUM_TIDS;
-@@ -3224,8 +3223,7 @@ static void ieee80211_xmit_fast_finish(s
-       if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
-               tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-               *ieee80211_get_qos_ctl(hdr) = tid;
--              if (!ieee80211_get_txq(local, &sdata->vif, &sta->sta, skb))
--                      hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
-+              hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
-       } else {
-               info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
-               hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number);
diff --git a/package/kernel/mac80211/patches/314-ath9k-rename-tx_complete_work-to-hw_check_work.patch b/package/kernel/mac80211/patches/314-ath9k-rename-tx_complete_work-to-hw_check_work.patch
new file mode 100644 (file)
index 0000000..5465df3
--- /dev/null
@@ -0,0 +1,175 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 25 Jan 2017 12:57:05 +0100
+Subject: [PATCH] ath9k: rename tx_complete_work to hw_check_work
+
+Also include common MAC alive check. This should make the hang checks
+more reliable for modes where beacons are not sent and is used as a
+starting point for further hang check improvements
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -108,7 +108,7 @@ int ath_descdma_setup(struct ath_softc *
+ #define ATH_AGGR_MIN_QDEPTH        2
+ /* minimum h/w qdepth for non-aggregated traffic */
+ #define ATH_NON_AGGR_MIN_QDEPTH    8
+-#define ATH_TX_COMPLETE_POLL_INT   1000
++#define ATH_HW_CHECK_POLL_INT      1000
+ #define ATH_TXFIFO_DEPTH           8
+ #define ATH_TX_ERROR               0x01
+@@ -745,7 +745,7 @@ void ath9k_csa_update(struct ath_softc *
+ #define ATH_PAPRD_TIMEOUT         100 /* msecs */
+ #define ATH_PLL_WORK_INTERVAL     100
+-void ath_tx_complete_poll_work(struct work_struct *work);
++void ath_hw_check_work(struct work_struct *work);
+ void ath_reset_work(struct work_struct *work);
+ bool ath_hw_check(struct ath_softc *sc);
+ void ath_hw_pll_work(struct work_struct *work);
+@@ -1053,7 +1053,7 @@ struct ath_softc {
+ #ifdef CPTCFG_ATH9K_DEBUGFS
+       struct ath9k_debug debug;
+ #endif
+-      struct delayed_work tx_complete_work;
++      struct delayed_work hw_check_work;
+       struct delayed_work hw_pll_work;
+       struct timer_list sleep_timer;
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -681,6 +681,7 @@ static int ath9k_init_softc(u16 devid, s
+       INIT_WORK(&sc->hw_reset_work, ath_reset_work);
+       INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
++      INIT_DELAYED_WORK(&sc->hw_check_work, ath_hw_check_work);
+       ath9k_init_channel_context(sc);
+--- a/drivers/net/wireless/ath/ath9k/link.c
++++ b/drivers/net/wireless/ath/ath9k/link.c
+@@ -20,20 +20,13 @@
+  * TX polling - checks if the TX engine is stuck somewhere
+  * and issues a chip reset if so.
+  */
+-void ath_tx_complete_poll_work(struct work_struct *work)
++static bool ath_tx_complete_check(struct ath_softc *sc)
+ {
+-      struct ath_softc *sc = container_of(work, struct ath_softc,
+-                                          tx_complete_work.work);
+       struct ath_txq *txq;
+       int i;
+-      bool needreset = false;
+-
+-      if (sc->tx99_state) {
+-              ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
+-                      "skip tx hung detection on tx99\n");
+-              return;
+-      }
++      if (sc->tx99_state)
++              return true;
+       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+               txq = sc->tx.txq_map[i];
+@@ -41,25 +34,36 @@ void ath_tx_complete_poll_work(struct wo
+               ath_txq_lock(sc, txq);
+               if (txq->axq_depth) {
+                       if (txq->axq_tx_inprogress) {
+-                              needreset = true;
+                               ath_txq_unlock(sc, txq);
+-                              break;
+-                      } else {
+-                              txq->axq_tx_inprogress = true;
++                              goto reset;
+                       }
++
++                      txq->axq_tx_inprogress = true;
+               }
+               ath_txq_unlock(sc, txq);
+       }
+-      if (needreset) {
+-              ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
+-                      "tx hung, resetting the chip\n");
+-              ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
++      return true;
++
++reset:
++      ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
++              "tx hung, resetting the chip\n");
++      ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
++      return false;
++
++}
++
++void ath_hw_check_work(struct work_struct *work)
++{
++      struct ath_softc *sc = container_of(work, struct ath_softc,
++                                          hw_check_work.work);
++
++      if (!ath_hw_check(sc) ||
++          !ath_tx_complete_check(sc))
+               return;
+-      }
+-      ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+-                                   msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
++      ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
++                                   msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
+ }
+ /*
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -181,7 +181,7 @@ void ath9k_ps_restore(struct ath_softc *
+ static void __ath_cancel_work(struct ath_softc *sc)
+ {
+       cancel_work_sync(&sc->paprd_work);
+-      cancel_delayed_work_sync(&sc->tx_complete_work);
++      cancel_delayed_work_sync(&sc->hw_check_work);
+       cancel_delayed_work_sync(&sc->hw_pll_work);
+ #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
+@@ -198,7 +198,8 @@ void ath_cancel_work(struct ath_softc *s
+ void ath_restart_work(struct ath_softc *sc)
+ {
+-      ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
++      ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
++                                   ATH_HW_CHECK_POLL_INT);
+       if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
+               ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
+@@ -2091,7 +2092,7 @@ void __ath9k_flush(struct ieee80211_hw *
+       int timeout;
+       bool drain_txq;
+-      cancel_delayed_work_sync(&sc->tx_complete_work);
++      cancel_delayed_work_sync(&sc->hw_check_work);
+       if (ah->ah_flags & AH_UNPLUGGED) {
+               ath_dbg(common, ANY, "Device has been unplugged!\n");
+@@ -2129,7 +2130,8 @@ void __ath9k_flush(struct ieee80211_hw *
+               ath9k_ps_restore(sc);
+       }
+-      ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
++      ieee80211_queue_delayed_work(hw, &sc->hw_check_work,
++                                   ATH_HW_CHECK_POLL_INT);
+ }
+ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -2916,8 +2916,6 @@ int ath_tx_init(struct ath_softc *sc, in
+               return error;
+       }
+-      INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
+-
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
+               error = ath_tx_edma_init(sc);
diff --git a/package/kernel/mac80211/patches/314-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/314-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch
deleted file mode 100644 (file)
index a7bcfa5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 9 Jul 2016 15:25:24 +0200
-Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx
-
-Should fix a few stability issues
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1394,8 +1394,12 @@ static bool ath9k_hw_set_reset(struct at
-       if (!AR_SREV_9100(ah))
-               REG_WRITE(ah, AR_RC, 0);
--      if (AR_SREV_9100(ah))
-+      if (AR_SREV_9100(ah)) {
-+              /* Reset the AHB-WMAC interface */
-+              if (ah->external_reset)
-+                      ah->external_reset();
-               udelay(50);
-+      }
-       return true;
- }
diff --git a/package/kernel/mac80211/patches/315-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch b/package/kernel/mac80211/patches/315-ath9k_hw-check-if-the-chip-failed-to-wake-up.patch
new file mode 100644 (file)
index 0000000..b0cb74a
--- /dev/null
@@ -0,0 +1,30 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 25 Jan 2017 12:58:17 +0100
+Subject: [PATCH] ath9k_hw: check if the chip failed to wake up
+
+In an RFC patch, Sven Eckelmann and Simon Wunderlich reported:
+
+"QCA 802.11n chips (especially AR9330/AR9340) sometimes end up in a
+state in which a read of AR_CFG always returns 0xdeadbeef.
+This should not happen when when the power_mode of the device is
+ATH9K_PM_AWAKE."
+
+Include the check for the default register state in the existing MAC
+hang check.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1624,6 +1624,10 @@ bool ath9k_hw_check_alive(struct ath_hw
+       int count = 50;
+       u32 reg, last_val;
++      /* Check if chip failed to wake up */
++      if (REG_READ(ah, AR_CFG) == 0xdeadbeef)
++              return false;
++
+       if (AR_SREV_9300(ah))
+               return !ath9k_hw_detect_mac_hang(ah);
diff --git a/package/kernel/mac80211/patches/315-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/315-ath9k_hw-issue-external-reset-for-QCA955x.patch
deleted file mode 100644 (file)
index 5eb69b8..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sat, 9 Jul 2016 15:26:44 +0200
-Subject: [PATCH] ath9k_hw: issue external reset for QCA955x
-
-The RTC interface on the SoC needs to be reset along with the rest of
-the WMAC.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1271,39 +1271,56 @@ void ath9k_hw_get_delta_slope_vals(struc
-       *coef_exponent = coef_exp - 16;
- }
--/* AR9330 WAR:
-- * call external reset function to reset WMAC if:
-- * - doing a cold reset
-- * - we have pending frames in the TX queues.
-- */
--static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
-+static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
- {
--      int i, npend = 0;
-+      int i;
--      for (i = 0; i < AR_NUM_QCU; i++) {
--              npend = ath9k_hw_numtxpending(ah, i);
--              if (npend)
--                      break;
--      }
--
--      if (ah->external_reset &&
--          (npend || type == ATH9K_RESET_COLD)) {
--              int reset_err = 0;
--
--              ath_dbg(ath9k_hw_common(ah), RESET,
--                      "reset MAC via external reset\n");
--
--              reset_err = ah->external_reset();
--              if (reset_err) {
--                      ath_err(ath9k_hw_common(ah),
--                              "External reset failed, err=%d\n",
--                              reset_err);
--                      return false;
-+      if (type == ATH9K_RESET_COLD)
-+              return true;
-+
-+      if (AR_SREV_9550(ah))
-+              return true;
-+
-+      /* AR9330 WAR:
-+       * call external reset function to reset WMAC if:
-+       * - doing a cold reset
-+       * - we have pending frames in the TX queues.
-+       */
-+      if (AR_SREV_9330(ah)) {
-+              for (i = 0; i < AR_NUM_QCU; i++) {
-+                      if (ath9k_hw_numtxpending(ah, i))
-+                              return true;
-               }
-+      }
-+
-+      return false;
-+}
-+
-+static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
-+{
-+      int err;
-+
-+      if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
-+              return true;
-+
-+      ath_dbg(ath9k_hw_common(ah), RESET,
-+              "reset MAC via external reset\n");
--              REG_WRITE(ah, AR_RTC_RESET, 1);
-+      err = ah->external_reset();
-+      if (err) {
-+              ath_err(ath9k_hw_common(ah),
-+                      "External reset failed, err=%d\n", err);
-+              return false;
-       }
-+      if (AR_SREV_9550(ah)) {
-+              REG_WRITE(ah, AR_RTC_RESET, 0);
-+              udelay(10);
-+      }
-+
-+      REG_WRITE(ah, AR_RTC_RESET, 1);
-+      udelay(10);
-+
-       return true;
- }
-@@ -1356,24 +1373,24 @@ static bool ath9k_hw_set_reset(struct at
-                       rst_flags |= AR_RTC_RC_MAC_COLD;
-       }
--      if (AR_SREV_9330(ah)) {
--              if (!ath9k_hw_ar9330_reset_war(ah, type))
--                      return false;
--      }
--
-       if (ath9k_hw_mci_is_enabled(ah))
-               ar9003_mci_check_gpm_offset(ah);
-       /* DMA HALT added to resolve ar9300 and ar9580 bus error during
--       * RTC_RC reg read
-+       * RTC_RC reg read. Also needed for AR9550 external reset
-        */
--      if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
-+      if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
-               REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
-               ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
-                             20 * AH_WAIT_TIMEOUT);
--              REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
-       }
-+      if (!AR_SREV_9100(ah))
-+              ath9k_hw_external_reset(ah, type);
-+
-+      if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
-+              REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
-+
-       REG_WRITE(ah, AR_RTC_RC, rst_flags);
-       REGWRITE_BUFFER_FLUSH(ah);
diff --git a/package/kernel/mac80211/patches/316-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch b/package/kernel/mac80211/patches/316-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch
new file mode 100644 (file)
index 0000000..7a41206
--- /dev/null
@@ -0,0 +1,197 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 25 Jan 2017 15:10:37 +0100
+Subject: [PATCH] ath9k: fix race condition in enabling/disabling IRQs
+
+The code currently relies on refcounting to disable IRQs from within the
+IRQ handler and re-enabling them again after the tasklet has run.
+
+However, due to race conditions sometimes the IRQ handler might be
+called twice, or the tasklet may not run at all (if interrupted in the
+middle of a reset).
+
+This can cause nasty imbalances in the irq-disable refcount which will
+get the driver permanently stuck until the entire radio has been stopped
+and started again (ath_reset will not recover from this).
+
+Instead of using this fragile logic, change the code to ensure that
+running the irq handler during tasklet processing is safe, and leave the
+refcount untouched.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -998,6 +998,7 @@ struct ath_softc {
+       struct survey_info *cur_survey;
+       struct survey_info survey[ATH9K_NUM_CHANNELS];
++      spinlock_t intr_lock;
+       struct tasklet_struct intr_tq;
+       struct tasklet_struct bcon_tasklet;
+       struct ath_hw *sc_ah;
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -669,6 +669,7 @@ static int ath9k_init_softc(u16 devid, s
+               common->bt_ant_diversity = 1;
+       spin_lock_init(&common->cc_lock);
++      spin_lock_init(&sc->intr_lock);
+       spin_lock_init(&sc->sc_serial_rw);
+       spin_lock_init(&sc->sc_pm_lock);
+       spin_lock_init(&sc->chan_lock);
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -810,21 +810,12 @@ void ath9k_hw_disable_interrupts(struct
+ }
+ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+-void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
+ {
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 sync_default = AR_INTR_SYNC_DEFAULT;
+       u32 async_mask;
+-      if (!(ah->imask & ATH9K_INT_GLOBAL))
+-              return;
+-
+-      if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
+-              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
+-                      atomic_read(&ah->intr_ref_cnt));
+-              return;
+-      }
+-
+       if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
+           AR_SREV_9561(ah))
+               sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+@@ -846,6 +837,39 @@ void ath9k_hw_enable_interrupts(struct a
+       ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+               REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+ }
++
++void ath9k_hw_resume_interrupts(struct ath_hw *ah)
++{
++      struct ath_common *common = ath9k_hw_common(ah);
++
++      if (!(ah->imask & ATH9K_INT_GLOBAL))
++              return;
++
++      if (atomic_read(&ah->intr_ref_cnt) != 0) {
++              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++                      atomic_read(&ah->intr_ref_cnt));
++              return;
++      }
++
++      __ath9k_hw_enable_interrupts(ah);
++}
++EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
++
++void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++{
++      struct ath_common *common = ath9k_hw_common(ah);
++
++      if (!(ah->imask & ATH9K_INT_GLOBAL))
++              return;
++
++      if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
++              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++                      atomic_read(&ah->intr_ref_cnt));
++              return;
++      }
++
++      __ath9k_hw_enable_interrupts(ah);
++}
+ EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+ void ath9k_hw_set_interrupts(struct ath_hw *ah)
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_disable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_kill_interrupts(struct ath_hw *ah);
++void ath9k_hw_resume_interrupts(struct ath_hw *ah);
+ void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -374,21 +374,20 @@ void ath9k_tasklet(unsigned long data)
+       struct ath_common *common = ath9k_hw_common(ah);
+       enum ath_reset_type type;
+       unsigned long flags;
+-      u32 status = sc->intrstatus;
++      u32 status;
+       u32 rxmask;
++      spin_lock_irqsave(&sc->intr_lock, flags);
++      status = sc->intrstatus;
++      sc->intrstatus = 0;
++      spin_unlock_irqrestore(&sc->intr_lock, flags);
++
+       ath9k_ps_wakeup(sc);
+       spin_lock(&sc->sc_pcu_lock);
+       if (status & ATH9K_INT_FATAL) {
+               type = RESET_TYPE_FATAL_INT;
+               ath9k_queue_reset(sc, type);
+-
+-              /*
+-               * Increment the ref. counter here so that
+-               * interrupts are enabled in the reset routine.
+-               */
+-              atomic_inc(&ah->intr_ref_cnt);
+               ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
+               goto out;
+       }
+@@ -404,11 +403,6 @@ void ath9k_tasklet(unsigned long data)
+                       type = RESET_TYPE_BB_WATCHDOG;
+                       ath9k_queue_reset(sc, type);
+-                      /*
+-                       * Increment the ref. counter here so that
+-                       * interrupts are enabled in the reset routine.
+-                       */
+-                      atomic_inc(&ah->intr_ref_cnt);
+                       ath_dbg(common, RESET,
+                               "BB_WATCHDOG: Skipping interrupts\n");
+                       goto out;
+@@ -421,7 +415,6 @@ void ath9k_tasklet(unsigned long data)
+               if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
+                       type = RESET_TYPE_TX_GTT;
+                       ath9k_queue_reset(sc, type);
+-                      atomic_inc(&ah->intr_ref_cnt);
+                       ath_dbg(common, RESET,
+                               "GTT: Skipping interrupts\n");
+                       goto out;
+@@ -478,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
+       ath9k_btcoex_handle_interrupt(sc, status);
+       /* re-enable hardware interrupt */
+-      ath9k_hw_enable_interrupts(ah);
++      ath9k_hw_resume_interrupts(ah);
+ out:
+       spin_unlock(&sc->sc_pcu_lock);
+       ath9k_ps_restore(sc);
+@@ -542,7 +535,9 @@ irqreturn_t ath_isr(int irq, void *dev)
+               return IRQ_NONE;
+       /* Cache the status */
+-      sc->intrstatus = status;
++      spin_lock(&sc->intr_lock);
++      sc->intrstatus |= status;
++      spin_unlock(&sc->intr_lock);
+       if (status & SCHED_INTR)
+               sched = true;
+@@ -588,7 +583,7 @@ chip_reset:
+       if (sched) {
+               /* turn off every interrupt */
+-              ath9k_hw_disable_interrupts(ah);
++              ath9k_hw_kill_interrupts(ah);
+               tasklet_schedule(&sc->intr_tq);
+       }
diff --git a/package/kernel/mac80211/patches/316-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch b/package/kernel/mac80211/patches/316-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch
deleted file mode 100644 (file)
index dfe9aae..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Mon, 11 Jul 2016 12:07:40 +0200
-Subject: [PATCH] ath9k_hw: set spectral scan enable bit on trigger for
- AR9003+
-
-AR9002 code and QCA AR9003+ code do the same.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
-@@ -1800,6 +1800,8 @@ static void ar9003_hw_spectral_scan_conf
- static void ar9003_hw_spectral_scan_trigger(struct ath_hw *ah)
- {
-+      REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
-+                  AR_PHY_SPECTRAL_SCAN_ENABLE);
-       /* Activate spectral scan */
-       REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
-                   AR_PHY_SPECTRAL_SCAN_ACTIVE);
diff --git a/package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch b/package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch
deleted file mode 100644 (file)
index 687df35..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 11 Oct 2016 19:45:41 +0200
-Subject: [PATCH] Revert "ath9k_hw: implement temperature compensation support
- for AR9003+"
-
-This reverts commit 171f6402e4aa5cd3b8407f82501f7ea21fa54ccc.
-Some users report that this commit causes a regression in performance
-under some conditions.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
-@@ -33,7 +33,6 @@ struct coeff {
- enum ar9003_cal_types {
-       IQ_MISMATCH_CAL = BIT(0),
--      TEMP_COMP_CAL = BIT(1),
- };
- static void ar9003_hw_setup_calibration(struct ath_hw *ah,
-@@ -59,12 +58,6 @@ static void ar9003_hw_setup_calibration(
-               /* Kick-off cal */
-               REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
-               break;
--      case TEMP_COMP_CAL:
--              ath_dbg(common, CALIBRATE,
--                      "starting Temperature Compensation Calibration\n");
--              REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_LOCAL);
--              REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_START);
--              break;
-       default:
-               ath_err(common, "Invalid calibration type\n");
-               break;
-@@ -93,8 +86,7 @@ static bool ar9003_hw_per_calibration(st
-               /*
-               * Accumulate cal measures for active chains
-               */
--              if (cur_caldata->calCollect)
--                      cur_caldata->calCollect(ah);
-+              cur_caldata->calCollect(ah);
-               ah->cal_samples++;
-               if (ah->cal_samples >= cur_caldata->calNumSamples) {
-@@ -107,8 +99,7 @@ static bool ar9003_hw_per_calibration(st
-                       /*
-                       * Process accumulated data
-                       */
--                      if (cur_caldata->calPostProc)
--                              cur_caldata->calPostProc(ah, numChains);
-+                      cur_caldata->calPostProc(ah, numChains);
-                       /* Calibration has finished. */
-                       caldata->CalValid |= cur_caldata->calType;
-@@ -323,16 +314,9 @@ static const struct ath9k_percal_data iq
-       ar9003_hw_iqcalibrate
- };
--static const struct ath9k_percal_data temp_cal_single_sample = {
--      TEMP_COMP_CAL,
--      MIN_CAL_SAMPLES,
--      PER_MAX_LOG_COUNT,
--};
--
- static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
- {
-       ah->iq_caldata.calData = &iq_cal_single_sample;
--      ah->temp_caldata.calData = &temp_cal_single_sample;
-       if (AR_SREV_9300_20_OR_LATER(ah)) {
-               ah->enabled_cals |= TX_IQ_CAL;
-@@ -340,7 +324,7 @@ static void ar9003_hw_init_cal_settings(
-                       ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
-       }
--      ah->supp_cals = IQ_MISMATCH_CAL | TEMP_COMP_CAL;
-+      ah->supp_cals = IQ_MISMATCH_CAL;
- }
- #define OFF_UPPER_LT 24
-@@ -1399,9 +1383,6 @@ static void ar9003_hw_init_cal_common(st
-       INIT_CAL(&ah->iq_caldata);
-       INSERT_CAL(ah, &ah->iq_caldata);
--      INIT_CAL(&ah->temp_caldata);
--      INSERT_CAL(ah, &ah->temp_caldata);
--
-       /* Initialize current pointer to first element in list */
-       ah->cal_list_curr = ah->cal_list;
---- a/drivers/net/wireless/ath/ath9k/hw.h
-+++ b/drivers/net/wireless/ath/ath9k/hw.h
-@@ -830,7 +830,6 @@ struct ath_hw {
-       /* Calibration */
-       u32 supp_cals;
-       struct ath9k_cal_list iq_caldata;
--      struct ath9k_cal_list temp_caldata;
-       struct ath9k_cal_list adcgain_caldata;
-       struct ath9k_cal_list adcdc_caldata;
-       struct ath9k_cal_list *cal_list;
diff --git a/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch b/package/kernel/mac80211/patches/317-rt2x00-avoid-introducing-a-USB-dependency-in-the-rt2.patch
new file mode 100644 (file)
index 0000000..c0274dd
--- /dev/null
@@ -0,0 +1,73 @@
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Thu, 2 Feb 2017 10:57:40 +0100
+Subject: [PATCH] rt2x00: avoid introducing a USB dependency in the
+ rt2x00lib module
+
+As reported by Felix:
+
+Though protected by an ifdef, introducing an usb symbol dependency in
+the rt2x00lib module is a major inconvenience for distributions that
+package kernel modules split into individual packages.
+
+Get rid of this unnecessary dependency by calling the usb related
+function from a more suitable place.
+
+Cc: Vishal Thanki <vishalthanki@gmail.com>
+Reported-by: Felix Fietkau <nbd@nbd.name>
+Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+---
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -1436,21 +1436,6 @@ void rt2x00lib_remove_dev(struct rt2x00_
+       cancel_work_sync(&rt2x00dev->intf_work);
+       cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+       cancel_work_sync(&rt2x00dev->sleep_work);
+-#if IS_ENABLED(CPTCFG_RT2X00_LIB_USB)
+-      if (rt2x00_is_usb(rt2x00dev)) {
+-              usb_kill_anchored_urbs(rt2x00dev->anchor);
+-              hrtimer_cancel(&rt2x00dev->txstatus_timer);
+-              cancel_work_sync(&rt2x00dev->rxdone_work);
+-              cancel_work_sync(&rt2x00dev->txdone_work);
+-      }
+-#endif
+-      if (rt2x00dev->workqueue)
+-              destroy_workqueue(rt2x00dev->workqueue);
+-
+-      /*
+-       * Free the tx status fifo.
+-       */
+-      kfifo_free(&rt2x00dev->txstatus_fifo);
+       /*
+        * Kill the tx status tasklet.
+@@ -1466,6 +1451,14 @@ void rt2x00lib_remove_dev(struct rt2x00_
+        */
+       rt2x00lib_uninitialize(rt2x00dev);
++      if (rt2x00dev->workqueue)
++              destroy_workqueue(rt2x00dev->workqueue);
++
++      /*
++       * Free the tx status fifo.
++       */
++      kfifo_free(&rt2x00dev->txstatus_fifo);
++
+       /*
+        * Free extra components
+        */
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+@@ -744,6 +744,11 @@ void rt2x00usb_uninitialize(struct rt2x0
+ {
+       struct data_queue *queue;
++      usb_kill_anchored_urbs(rt2x00dev->anchor);
++      hrtimer_cancel(&rt2x00dev->txstatus_timer);
++      cancel_work_sync(&rt2x00dev->rxdone_work);
++      cancel_work_sync(&rt2x00dev->txdone_work);
++
+       queue_for_each(rt2x00dev, queue)
+               rt2x00usb_free_entries(queue);
+ }
diff --git a/package/kernel/mac80211/patches/318-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch b/package/kernel/mac80211/patches/318-brcmfmac-check-brcmf_bus_get_memdump-result-for-erro.patch
new file mode 100644 (file)
index 0000000..4ae4c60
--- /dev/null
@@ -0,0 +1,52 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 30 Jan 2017 16:09:51 +0100
+Subject: [PATCH] brcmfmac: check brcmf_bus_get_memdump result for error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This method may be unsupported (see: USB bus) or may just fail (see:
+SDIO bus).
+While at it rework logic in brcmf_sdio_bus_get_memdump function to avoid
+too many conditional code nesting levels.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
+@@ -32,16 +32,25 @@ static int brcmf_debug_create_memdump(st
+ {
+       void *dump;
+       size_t ramsize;
++      int err;
+       ramsize = brcmf_bus_get_ramsize(bus);
+-      if (ramsize) {
+-              dump = vzalloc(len + ramsize);
+-              if (!dump)
+-                      return -ENOMEM;
+-              memcpy(dump, data, len);
+-              brcmf_bus_get_memdump(bus, dump + len, ramsize);
+-              dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
++      if (!ramsize)
++              return -ENOTSUPP;
++
++      dump = vzalloc(len + ramsize);
++      if (!dump)
++              return -ENOMEM;
++
++      memcpy(dump, data, len);
++      err = brcmf_bus_get_memdump(bus, dump + len, ramsize);
++      if (err) {
++              vfree(dump);
++              return err;
+       }
++
++      dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
++
+       return 0;
+ }
diff --git a/package/kernel/mac80211/patches/318-mac80211-fix-up-mismerge-of-ieee80211_tx_dequeue.patch b/package/kernel/mac80211/patches/318-mac80211-fix-up-mismerge-of-ieee80211_tx_dequeue.patch
deleted file mode 100644 (file)
index 2e742e4..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From: Bob Copeland <me@bobcopeland.com>
-Date: Wed, 12 Oct 2016 08:24:54 -0400
-Subject: [PATCH] mac80211: fix up mismerge of ieee80211_tx_dequeue
-
-Looks like this spinlock wound up on the wrong side of the
-linearize, and I also lost the part that re-enters the loop.
-Fix up to match mac80211-next.
-
-Signed-off-by: Bob Copeland <me@bobcopeland.com>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3457,17 +3457,17 @@ begin:
-                       skb_queue_splice_tail(&tx.skbs, &txqi->frags);
-       }
--out:
--      spin_unlock_bh(&fq->lock);
--
-       if (skb && skb_has_frag_list(skb) &&
-           !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) {
-               if (skb_linearize(skb)) {
-                       ieee80211_free_txskb(&local->hw, skb);
--                      return NULL;
-+                      goto begin;
-               }
-       }
-+out:
-+      spin_unlock_bh(&fq->lock);
-+
-       return skb;
- }
- EXPORT_SYMBOL(ieee80211_tx_dequeue);
diff --git a/package/kernel/mac80211/patches/319-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch b/package/kernel/mac80211/patches/319-brcmfmac-be-more-verbose-when-PSM-s-watchdog-fires.patch
new file mode 100644 (file)
index 0000000..2a3b838
--- /dev/null
@@ -0,0 +1,38 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 30 Jan 2017 16:09:52 +0100
+Subject: [PATCH] brcmfmac: be more verbose when PSM's watchdog fires
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It's important to inform user so he knows things went wrong. He may also
+want to get memory dump for further debugging purposes.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
+@@ -58,10 +58,18 @@ static int brcmf_debug_psm_watchdog_noti
+                                          const struct brcmf_event_msg *evtmsg,
+                                          void *data)
+ {
++      int err;
++
+       brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
+-      return brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
+-                                        evtmsg->datalen);
++      brcmf_err("PSM's watchdog has fired!\n");
++
++      err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
++                                       evtmsg->datalen);
++      if (err)
++              brcmf_err("Failed to get memory dump, %d\n", err);
++
++      return err;
+ }
+ void brcmf_debugfs_init(void)
diff --git a/package/kernel/mac80211/patches/319-mac80211-avoid-extra-memcpy-in-A-MSDU-head-creation.patch b/package/kernel/mac80211/patches/319-mac80211-avoid-extra-memcpy-in-A-MSDU-head-creation.patch
deleted file mode 100644 (file)
index 4668226..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From: Michael Braun <michael-dev@fami-braun.de>
-Date: Sat, 15 Oct 2016 13:28:18 +0200
-Subject: [PATCH] mac80211: avoid extra memcpy in A-MSDU head creation
-
-Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3069,11 +3069,11 @@ static bool ieee80211_amsdu_prepare_head
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr;
--      struct ethhdr amsdu_hdr;
-+      struct ethhdr *amsdu_hdr;
-       int hdr_len = fast_tx->hdr_len - sizeof(rfc1042_header);
-       int subframe_len = skb->len - hdr_len;
-       void *data;
--      u8 *qc;
-+      u8 *qc, *h_80211_src, *h_80211_dst;
-       if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
-               return false;
-@@ -3081,19 +3081,22 @@ static bool ieee80211_amsdu_prepare_head
-       if (info->control.flags & IEEE80211_TX_CTRL_AMSDU)
-               return true;
--      if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(amsdu_hdr),
-+      if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr),
-                                        &subframe_len))
-               return false;
--      amsdu_hdr.h_proto = cpu_to_be16(subframe_len);
--      memcpy(amsdu_hdr.h_source, skb->data + fast_tx->sa_offs, ETH_ALEN);
--      memcpy(amsdu_hdr.h_dest, skb->data + fast_tx->da_offs, ETH_ALEN);
--
--      data = skb_push(skb, sizeof(amsdu_hdr));
--      memmove(data, data + sizeof(amsdu_hdr), hdr_len);
--      memcpy(data + hdr_len, &amsdu_hdr, sizeof(amsdu_hdr));
--
-+      data = skb_push(skb, sizeof(*amsdu_hdr));
-+      memmove(data, data + sizeof(*amsdu_hdr), hdr_len);
-       hdr = data;
-+      amsdu_hdr = data + hdr_len;
-+      /* h_80211_src/dst is addr* field within hdr */
-+      h_80211_src = data + fast_tx->sa_offs;
-+      h_80211_dst = data + fast_tx->da_offs;
-+
-+      amsdu_hdr->h_proto = cpu_to_be16(subframe_len);
-+      ether_addr_copy(amsdu_hdr->h_source, h_80211_src);
-+      ether_addr_copy(amsdu_hdr->h_dest, h_80211_dst);
-+
-       qc = ieee80211_get_qos_ctl(hdr);
-       *qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
diff --git a/package/kernel/mac80211/patches/320-mac80211-fix-A-MSDU-outer-SA-DA.patch b/package/kernel/mac80211/patches/320-mac80211-fix-A-MSDU-outer-SA-DA.patch
deleted file mode 100644 (file)
index 7700254..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-From: Michael Braun <michael-dev@fami-braun.de>
-Date: Sat, 15 Oct 2016 13:28:19 +0200
-Subject: [PATCH] mac80211: fix A-MSDU outer SA/DA
-
-According to IEEE 802.11-2012 section 8.3.2 table 8-19, the outer SA/DA
-of A-MSDU frames need to be changed depending on FromDS/ToDS values.
-
-Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
-[use ether_addr_copy and add alignment annotations]
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1438,7 +1438,7 @@ enum ieee80211_vif_flags {
- struct ieee80211_vif {
-       enum nl80211_iftype type;
-       struct ieee80211_bss_conf bss_conf;
--      u8 addr[ETH_ALEN];
-+      u8 addr[ETH_ALEN] __aligned(2);
-       bool p2p;
-       bool csa_active;
-       bool mu_mimo_owner;
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -443,7 +443,7 @@ struct ieee80211_if_managed {
-       struct ieee80211_mgd_auth_data *auth_data;
-       struct ieee80211_mgd_assoc_data *assoc_data;
--      u8 bssid[ETH_ALEN];
-+      u8 bssid[ETH_ALEN] __aligned(2);
-       u16 aid;
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3074,6 +3074,7 @@ static bool ieee80211_amsdu_prepare_head
-       int subframe_len = skb->len - hdr_len;
-       void *data;
-       u8 *qc, *h_80211_src, *h_80211_dst;
-+      const u8 *bssid;
-       if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
-               return false;
-@@ -3097,6 +3098,28 @@ static bool ieee80211_amsdu_prepare_head
-       ether_addr_copy(amsdu_hdr->h_source, h_80211_src);
-       ether_addr_copy(amsdu_hdr->h_dest, h_80211_dst);
-+      /* according to IEEE 802.11-2012 8.3.2 table 8-19, the outer SA/DA
-+       * fields needs to be changed to BSSID for A-MSDU frames depending
-+       * on FromDS/ToDS values.
-+       */
-+      switch (sdata->vif.type) {
-+      case NL80211_IFTYPE_STATION:
-+              bssid = sdata->u.mgd.bssid;
-+              break;
-+      case NL80211_IFTYPE_AP:
-+      case NL80211_IFTYPE_AP_VLAN:
-+              bssid = sdata->vif.addr;
-+              break;
-+      default:
-+              bssid = NULL;
-+      }
-+
-+      if (bssid && ieee80211_has_fromds(hdr->frame_control))
-+              ether_addr_copy(h_80211_src, bssid);
-+
-+      if (bssid && ieee80211_has_tods(hdr->frame_control))
-+              ether_addr_copy(h_80211_dst, bssid);
-+
-       qc = ieee80211_get_qos_ctl(hdr);
-       *qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
diff --git a/package/kernel/mac80211/patches/321-Revert-mac80211-allow-using-AP_LINK_PS-with-mac80211.patch b/package/kernel/mac80211/patches/321-Revert-mac80211-allow-using-AP_LINK_PS-with-mac80211.patch
deleted file mode 100644 (file)
index ace20e7..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 3 Nov 2016 12:10:34 +0100
-Subject: [PATCH] Revert "mac80211: allow using AP_LINK_PS with
- mac80211-generated TIM IE"
-
-This reverts commit c68df2e7be0c1238ea3c281fd744a204ef3b15a0.
-
-__sta_info_recalc_tim turns into a no-op if local->ops->set_tim is not
-set. This prevents the beacon TIM bit from being set for all drivers
-that do not implement this op (almost all of them), thus thoroughly
-essential AP mode powersave functionality.
-
-Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-Fixes: c68df2e7be0c ("mac80211: allow using AP_LINK_PS with mac80211-generated TIM IE")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -688,7 +688,7 @@ static void __sta_info_recalc_tim(struct
-       }
-       /* No need to do anything if the driver does all */
--      if (!local->ops->set_tim)
-+      if (ieee80211_hw_check(&local->hw, AP_LINK_PS))
-               return;
-       if (sta->dead)
diff --git a/package/kernel/mac80211/patches/322-mac80211-update-A-MPDU-flag-on-tx-dequeue.patch b/package/kernel/mac80211/patches/322-mac80211-update-A-MPDU-flag-on-tx-dequeue.patch
deleted file mode 100644 (file)
index 1898d23..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Nov 2016 10:13:34 +0100
-Subject: [PATCH] mac80211: update A-MPDU flag on tx dequeue
-
-The sequence number counter is used to derive the starting sequence
-number. Since that counter is updated on tx dequeue, the A-MPDU flag
-needs to be up to date at the tme of dequeue as well.
-
-This patch prevents sending more A-MPDU frames after the session has
-been terminated and also ensures that aggregation starts right after the
-session has been established
-
-Fixes: bb42f2d13ffc ("mac80211: Move reorder-sensitive TX handlers to after TXQ dequeue")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -3462,6 +3462,11 @@ begin:
-               goto begin;
-       }
-+      if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags))
-+              info->flags |= IEEE80211_TX_CTL_AMPDU;
-+      else
-+              info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-+
-       if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
-               struct sta_info *sta = container_of(txq->sta, struct sta_info,
-                                                   sta);
diff --git a/package/kernel/mac80211/patches/323-mac80211-remove-bogus-skb-vif-assignment.patch b/package/kernel/mac80211/patches/323-mac80211-remove-bogus-skb-vif-assignment.patch
deleted file mode 100644 (file)
index 66449ac..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 4 Nov 2016 10:17:38 +0100
-Subject: [PATCH] mac80211: remove bogus skb vif assignment
-
-The call to ieee80211_txq_enqueue overwrites the vif pointer with the
-codel enqueue time, so setting it just before that call makes no sense.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -1500,7 +1500,6 @@ static bool ieee80211_queue_skb(struct i