mac80211: update to wireless-testing 2016-10-08
authorFelix Fietkau <nbd@nbd.name>
Sat, 8 Oct 2016 11:53:14 +0000 (13:53 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 13 Oct 2016 15:06:03 +0000 (17:06 +0200)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
292 files changed:
package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch
package/kernel/mac80211/patches/006-add-basic-register-field-manipulation-macros.patch [deleted file]
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 [new file with mode: 0644]
package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch [deleted file]
package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch [new file with mode: 0644]
package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch [deleted file]
package/kernel/mac80211/patches/302-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch [deleted file]
package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch [new file with mode: 0644]
package/kernel/mac80211/patches/303-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch [new file with mode: 0644]
package/kernel/mac80211/patches/303-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch [deleted file]
package/kernel/mac80211/patches/304-ath10k-Ensure-peer_map-references-are-cleaned-up.patch [deleted file]
package/kernel/mac80211/patches/304-mac80211-add-hdrlen-to-ieee80211_tx_data.patch [new file with mode: 0644]
package/kernel/mac80211/patches/305-ath10k-Clean-up-peer-when-sta-goes-away.patch [deleted file]
package/kernel/mac80211/patches/305-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch [new file with mode: 0644]
package/kernel/mac80211/patches/306-mac80211-add-hdrlen-to-ieee80211_tx_data.patch [deleted file]
package/kernel/mac80211/patches/306-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch [new file with mode: 0644]
package/kernel/mac80211/patches/307-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch [new file with mode: 0644]
package/kernel/mac80211/patches/307-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch [deleted file]
package/kernel/mac80211/patches/308-ath10k-Fix-sending-NULL-Qos-NULL-data-frames-for-QCA.patch [deleted file]
package/kernel/mac80211/patches/308-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch [new file with mode: 0644]
package/kernel/mac80211/patches/309-ath9k-report-tx-status-on-EOSP.patch [new file with mode: 0644]
package/kernel/mac80211/patches/309-cfg80211-fix-proto-in-ieee80211_data_to_8023-for-fra.patch [deleted file]
package/kernel/mac80211/patches/310-ath9k-fix-block-ack-window-tracking-issues.patch [new file with mode: 0644]
package/kernel/mac80211/patches/310-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch [deleted file]
package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch [new file with mode: 0644]
package/kernel/mac80211/patches/311-ath10k-disable-wake_tx_queue-for-older-devices.patch [deleted file]
package/kernel/mac80211/patches/312-ath9k-Correct-TSF-adjustment-to-align-the-beacon-tim.patch [deleted file]
package/kernel/mac80211/patches/312-mac80211-Use-rhltable-instead-of-rhashtable.patch [new file with mode: 0644]
package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch [deleted file]
package/kernel/mac80211/patches/313-mac80211-fix-sequence-number-allocation-regression.patch [new file with mode: 0644]
package/kernel/mac80211/patches/314-ath9k-Use-tsf-offset-helper-in-ath9k_hw_reset.patch [deleted file]
package/kernel/mac80211/patches/314-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch [new file with mode: 0644]
package/kernel/mac80211/patches/315-ath9k-Expose-tsf_adjustment-in-mac80211-tsf-getters-.patch [deleted file]
package/kernel/mac80211/patches/315-ath9k_hw-issue-external-reset-for-QCA955x.patch [new file with mode: 0644]
package/kernel/mac80211/patches/316-ath9k-Remove-some-defined-constants-to-decrease-verb.patch [deleted file]
package/kernel/mac80211/patches/316-ath9k_hw-set-spectral-scan-enable-bit-on-trigger-for.patch [new file with mode: 0644]
package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch [new file with mode: 0644]
package/kernel/mac80211/patches/317-ath9k-Fix-beacon-configuration-for-addition-removal-.patch [deleted file]
package/kernel/mac80211/patches/318-brcmfmac-slightly-simplify-building-interface-combin.patch [deleted file]
package/kernel/mac80211/patches/318-mac80211-fix-up-mismerge-of-ieee80211_tx_dequeue.patch [new file with mode: 0644]
package/kernel/mac80211/patches/319-0001-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch [deleted file]
package/kernel/mac80211/patches/319-0002-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch [deleted file]
package/kernel/mac80211/patches/319-0003-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch [deleted file]
package/kernel/mac80211/patches/319-0004-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch [deleted file]
package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch [deleted file]
package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch [deleted file]
package/kernel/mac80211/patches/319-0007-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch [deleted file]
package/kernel/mac80211/patches/319-0008-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch [deleted file]
package/kernel/mac80211/patches/319-0009-brcmfmac-defer-DPC-processing-during-probe.patch [deleted file]
package/kernel/mac80211/patches/319-0010-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch [deleted file]
package/kernel/mac80211/patches/319-0011-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch [deleted file]
package/kernel/mac80211/patches/319-0012-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch [deleted file]
package/kernel/mac80211/patches/319-0013-brcmfmac-Change-vif_event_lock-to-spinlock.patch [deleted file]
package/kernel/mac80211/patches/319-0014-brcmfmac-add-missing-header-dependencies.patch [deleted file]
package/kernel/mac80211/patches/319-0015-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch [deleted file]
package/kernel/mac80211/patches/319-0016-brcmfmac-fix-pmksa-bssid-usage.patch [deleted file]
package/kernel/mac80211/patches/319-0017-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch [deleted file]
package/kernel/mac80211/patches/319-0018-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch [deleted file]
package/kernel/mac80211/patches/319-0019-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch [deleted file]
package/kernel/mac80211/patches/319-0020-brcmfmac-ignore-11d-configuration-errors.patch [deleted file]
package/kernel/mac80211/patches/319-0021-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch [deleted file]
package/kernel/mac80211/patches/319-0022-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch [deleted file]
package/kernel/mac80211/patches/319-0023-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch [deleted file]
package/kernel/mac80211/patches/319-0024-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch [deleted file]
package/kernel/mac80211/patches/319-0025-brcmfmac-remove-unnecessary-null-pointer-check.patch [deleted file]
package/kernel/mac80211/patches/319-0026-brcmfmac-fix-clearing-entry-IPv6-address.patch [deleted file]
package/kernel/mac80211/patches/319-0027-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch [deleted file]
package/kernel/mac80211/patches/319-0028-brcmfmac-simplify-mapping-of-auth-type.patch [deleted file]
package/kernel/mac80211/patches/319-0029-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch [deleted file]
package/kernel/mac80211/patches/319-0030-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch [deleted file]
package/kernel/mac80211/patches/319-0031-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch [deleted file]
package/kernel/mac80211/patches/319-0032-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch [deleted file]
package/kernel/mac80211/patches/320-ath9k-fix-using-sta-drv_priv-before-initializing-it.patch [deleted file]
package/kernel/mac80211/patches/321-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch [deleted file]
package/kernel/mac80211/patches/322-ath9k_hw-issue-external-reset-for-QCA9550.patch [deleted file]
package/kernel/mac80211/patches/323-ath9k-Fix-programming-of-minCCA-power-threshold.patch [deleted file]
package/kernel/mac80211/patches/324-ath9k_hw-fix-spectral-scan-on-AR9285-and-newer.patch [deleted file]
package/kernel/mac80211/patches/325-ath9k_hw-fix-duplicate-and-partially-wrong-definitio.patch [deleted file]
package/kernel/mac80211/patches/326-ath9k_hw-simplify-ar9003_hw_per_calibration.patch [deleted file]
package/kernel/mac80211/patches/327-ath9k_hw-get-rid-of-some-duplicate-code-in-calibrati.patch [deleted file]
package/kernel/mac80211/patches/329-mac80211-fix-check-for-buffered-powersave-frames-wit.patch [deleted file]
package/kernel/mac80211/patches/330-ath10k-fix-rx-status-reporting-for-A-MSDU-subframes.patch [deleted file]
package/kernel/mac80211/patches/331-mac80211-End-the-MPSP-even-if-EOSP-frame-was-not-rec.patch [deleted file]
package/kernel/mac80211/patches/332-ath10k-implement-NAPI-support.patch [deleted file]
package/kernel/mac80211/patches/333-ath9k-fix-client-mode-beacon-configuration.patch [deleted file]
package/kernel/mac80211/patches/334-mac80211-fix-purging-multicast-PS-buffer-queue.patch [deleted file]
package/kernel/mac80211/patches/335-ath9k-use-ieee80211_tx_status_noskb-where-possible.patch [deleted file]
package/kernel/mac80211/patches/336-ath9k-improve-powersave-filter-handling.patch [deleted file]
package/kernel/mac80211/patches/337-ath9k-Switch-to-using-mac80211-intermediate-software.patch [deleted file]
package/kernel/mac80211/patches/338-mac80211-fix-tim-recalculation-after-PS-response.patch [deleted file]
package/kernel/mac80211/patches/339-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch [deleted file]
package/kernel/mac80211/patches/340-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch [deleted file]
package/kernel/mac80211/patches/341-ath9k-report-tx-status-on-EOSP.patch [deleted file]
package/kernel/mac80211/patches/342-ath9k-fix-block-ack-window-tracking-issues.patch [deleted file]
package/kernel/mac80211/patches/343-mac80211-send-delBA-on-unexpected-BlockAck-data-fram.patch [deleted file]
package/kernel/mac80211/patches/344-mac80211-send-delBA-on-unexpected-BlockAck-Request.patch [deleted file]
package/kernel/mac80211/patches/345-mac80211-Move-reorder-sensitive-TX-handlers-to-after.patch [deleted file]
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/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/531-ath9k_extra_platform_leds.patch
package/kernel/mac80211/patches/532-ath9k_get_led_polarity_from_platform_data.patch [deleted file]
package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch
package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch
package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch
package/kernel/mac80211/patches/650-0001-rtl8xxxu-Add-bit-definitions-for-REG_USB_SPECIAL_OPT.patch [deleted file]
package/kernel/mac80211/patches/650-0001-rtl8xxxu-Fix-memory-leak-in-handling-rxdesc16-packet.patch [new file with mode: 0644]
package/kernel/mac80211/patches/650-0002-rtl8xxxu-Add-additional-documentation-for-RX-DMA-reg.patch [deleted file]
package/kernel/mac80211/patches/650-0002-rtl8xxxu-Fix-big-endian-problem-reporting-mactime.patch [new file with mode: 0644]
package/kernel/mac80211/patches/650-0003-rtl8xxxu-tuse-ph-to-dump-buffers.patch [deleted file]
package/kernel/mac80211/patches/651-0001-rtl8xxxu-Fix-rtl8723bu-driver-reload-issue.patch [new file with mode: 0644]
package/kernel/mac80211/patches/651-0001-rtl8xxxu-remove-unneeded-assignments.patch [deleted file]
package/kernel/mac80211/patches/651-0002-rtl8xxxu-Fix-rtl8192eu-driver-reload-issue.patch [new file with mode: 0644]
package/kernel/mac80211/patches/651-0002-rtl8xxxu-Reduce-console-noise-when-removing-the-kern.patch [deleted file]
package/kernel/mac80211/patches/652-0001-rtl8xxxu-Obtain-RTS-rates-from-mac80211.patch [new file with mode: 0644]
package/kernel/mac80211/patches/652-0001-rtl8xxxu-Set-all-ieee80211_rx_status-values-in-parse.patch [deleted file]
package/kernel/mac80211/patches/652-0002-rtl8xxxu-Move-skb-delivery-into-parse_tx_desc-handle.patch [deleted file]
package/kernel/mac80211/patches/652-0002-rtl8xxxu-Pass-tx_info-to-fill_txdesc-in-order-to-hav.patch [new file with mode: 0644]
package/kernel/mac80211/patches/652-0003-rtl8xxxu-Obtain-ieee80211_rx_status-within-parse_rx_.patch [deleted file]
package/kernel/mac80211/patches/652-0004-rtl8xxxu-Correct-rxdesc16-definition.patch [deleted file]
package/kernel/mac80211/patches/652-0005-rtl8xxxu-Add-support-for-aggregated-RX-packets-on-ge.patch [deleted file]
package/kernel/mac80211/patches/652-0006-rtl8xxxu-Allocate-larger-RX-skbs-when-aggregation-is.patch [deleted file]
package/kernel/mac80211/patches/652-0007-rtl8xxxu-Adjust-RX-skb-size-to-include-space-for-phy.patch [deleted file]
package/kernel/mac80211/patches/652-0008-rtl8xxxu-Enable-aggregation-for-rtl8723au.patch [deleted file]
package/kernel/mac80211/patches/652-0009-rtl8xxxu-Enable-aggregation-for-rtl8192cu-rtl8188cu-.patch [deleted file]
package/kernel/mac80211/patches/652-0010-rtl8xxxu-Make-DMA-aggregation-optional-by-setting-a-.patch [deleted file]
package/kernel/mac80211/patches/652-0011-rtl8xxxu-gen1-Set-aggregation-timeout-REG_RXDMA_AGG_.patch [deleted file]
package/kernel/mac80211/patches/652-0012-rtl8xxxu-gen1-Add-module-parameters-to-adjust-DMA-ag.patch [deleted file]
package/kernel/mac80211/patches/653-0001-rtl8xxxu-Accept-firmware-signature-0x88e0.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0001-rtl8xxxu-Mark-0x20f4-0x648b-as-tested.patch [deleted file]
package/kernel/mac80211/patches/653-0002-rtl8xxxu-Add-initial-code-to-detect-8188eu-devices.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0002-rtl8xxxu-Mark-0x2001-0x3308-as-tested.patch [deleted file]
package/kernel/mac80211/patches/653-0003-rtl8xxxu-Add-initial-code-to-parse-8188eu-efuse.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0003-rtl8xxxu-Fix-error-handling-if-rtl8xxxu_init_device-.patch [deleted file]
package/kernel/mac80211/patches/653-0004-rtl8xxxu-Add-TP-Link-TL-WN823N-v2-to-list-of-support.patch [deleted file]
package/kernel/mac80211/patches/653-0004-rtl8xxxu-Detect-8188eu-parts-correctly.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0005-rtl8xxxu-Add-TX-page-defines-for-8723b.patch [deleted file]
package/kernel/mac80211/patches/653-0005-rtl8xxxu-First-stab-at-rtl8188e_power_on.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0006-rtl8xxxu-Add-rtl8188e_disabled_to_emu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0006-rtl8xxxu-Switch-8723a-to-use-new-rtl8xxxu_init_queue.patch [deleted file]
package/kernel/mac80211/patches/653-0007-rtl8xxxu-8188e-Enable-scheduler.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0007-rtl8xxxu-Switch-8192cu-8188cu-devices-to-use-rtl8xxx.patch [deleted file]
package/kernel/mac80211/patches/653-0008-rtl8xxxu-Add-rtl8188e_usb_quirk-for-enabling-MAC-TX-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0008-rtl8xxxu-Remove-now-obsolete-rtl8xxxu_old_init_queue.patch [deleted file]
package/kernel/mac80211/patches/653-0009-rtl8xxxu-8188e-add-REG_TXDMA_OFFSET_CHK-quirk.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0009-rtl8xxxu-Simplify-code-setting-TX-buffer-boundary.patch [deleted file]
package/kernel/mac80211/patches/653-0010-rtl8xxxu-Add-bit-definitions-for-REG_FPGA0_TX_INFO.patch [deleted file]
package/kernel/mac80211/patches/653-0010-rtl8xxxu-Add-reserved-page-init-parameters-for-8188e.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0011-rtl8xxxu-Add-interrupt-bit-definitions-for-gen2-part.patch [deleted file]
package/kernel/mac80211/patches/653-0011-rtl8xxxu-Correct-TX_TOTAL_PAGE_NUM-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0012-rtl8xxxu-Add-trxff_boundary-for-8188e.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0012-rtl8xxxu-Use-flag-to-indicate-whether-device-has-TX-.patch [deleted file]
package/kernel/mac80211/patches/653-0013-rtl8xxxu-8188eu-specify-firmware-block-size-and-set-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0013-rtl8xxxu-Convert-flags-in-rtl8xxxu_fileops-to-bitfla.patch [deleted file]
package/kernel/mac80211/patches/653-0014-rtl8xxxu-Add-8188e-mac-init-table.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0014-rtl8xxxu-Introduce-fops-bitflag-indicating-type-of-t.patch [deleted file]
package/kernel/mac80211/patches/653-0015-rtl8xxxu-Implement-rtl8188eu_init_phy_bb.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0015-rtl8xxxu-Simplify-calculating-of-hw-value-used-for-s.patch [deleted file]
package/kernel/mac80211/patches/653-0016-rtl8xxxu-Determine-the-need-for-SGI-before-handling-.patch [deleted file]
package/kernel/mac80211/patches/653-0016-rtl8xxxu-Implement-rtl8188eu_init_phy_rf.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0017-rtl8xxxu-Determine-need-for-shore-preamble-before-up.patch [deleted file]
package/kernel/mac80211/patches/653-0017-rtl8xxxu-Use-auto-LLT-init-for-8188e.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0018-rtl8xxxu-Do-not-set-REG_FPGA0_TX_INFO-on-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0018-rtl8xxxu-Split-filling-of-TX-descriptors-into-separa.patch [deleted file]
package/kernel/mac80211/patches/653-0019-rtl8xxxu-Do-not-mess-with-REG_FPGA0_XA_RF_INT_OE-eit.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0019-rtl8xxxu-gen1-Fix-non-static-symbol-warning.patch [deleted file]
package/kernel/mac80211/patches/653-0020-rtl8xxxu-Make-rtl8xxxu_ampdu_action-less-chatty.patch [deleted file]
package/kernel/mac80211/patches/653-0020-rtl8xxxu-Set-transfer-page-size-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0021-rtl8xxxu-Enable-TX-report-timer-on-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0022-rtl8xxxu-Setup-interrupts-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0023-rtl8xxxu-Use-rxdesc16-and-32-byte-tx-descriptors-for.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0024-rtl8xxxu-8188eu-use-same-ADDA-on-parameters-as-8723a.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0025-rtl8xxxu-Add-PHY-IQ-calibration-code-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0026-rtl8xxxu-8188eu-uses-the-gen2-thermal-meter.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0027-rtl8xxxu-Set-REG_USB_HRPWM-to-0-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0028-rtl8xxxu-Implement-rtl8188eu_config_channel.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0029-rtl8xxxu-Use-gen2-H2C-commands-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0030-rtl8xxxu-Initialize-GPIO-settings-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0031-rtl8xxxu-Add-simple-rtl8188eu_rf_on-routine.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0032-rtl8xxxu-Implement-rtl8188e_disable_rf.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0033-rtl8xxxu-Update-8188e-efuse-definition-for-power-val.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0034-rtl8xxxu-Implement-rtl8188e_set_tx_power.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0035-rtl8xxxu-Implement-rtl8xxxu_fill_txdesc_v3-for-8188e.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0036-rtl8xxxu-Add-some-8188eu-registers-and-update-CCK0_A.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0037-rtl8xxxu-Improve-register-description-for-REG_FPGA1_.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0038-rtl8xxxu-properly-detect-RTL8188EU-devices.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0039-rtl8xxxu-Implement-8188eu-specific-8051-reset-functi.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0040-rtl8xxxu-Disable-packet-DMA-aggregation-on-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0041-rtl8xxxu-8188eu-set-REG_OFDM0_XA_AGC_CORE1-to-match-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0042-rtl8xxxu-Fix-rtl8188eu-connection-fail.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0043-rtl8xxxu-Do-not-set-auto-rate-fallback-on-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0044-rtl8xxxu-Enable-8188eu-driver.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0045-rtl8xxxu-Add-rtl8188etv-to-USB-device-list.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0046-rtl8xxxu-Add-sitecom-dongle-to-USB-device-list.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0047-rtl8xxxu-Implement-rtl8188eu_active_to_emu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0048-rtl8xxxu-Implement-rtl8188eu_power_off.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0049-rtl8xxxu-Add-rtl8188eu-USB-ID-for-D-Link-USB-GO-N150.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0050-rtl8xxxu-Clear-SYS_FUNC_UPLL-during-power-up-on-8188.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0051-rtl8xxxu-Early-enable-of-WEP-TKIP-security-on-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0052-rtl8xxxu-Correct-power-down-sequence-for-8188eu.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0053-rtl8xxxu-Reset-8188eu-REG_GPIO_MUXCFG-on-power-off.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0054-rtl8xxxu-Handle-devices-with-a-smaller-LLT-buffer.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0055-rtl8xxxu-Fix-reloading-of-driver-for-8188eu-devices.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0056-rtl8xxxu-Make-sure-to-enable-OFDM-paths-for-8188eu-i.patch [new file with mode: 0644]
package/kernel/mac80211/patches/653-0057-rtl8xxxu-Add-rpt_sel-entry-to-struct-rtl8xxxu_rxdesc.patch [new file with mode: 0644]
package/kernel/mac80211/patches/654-0001-rtl8xxxu-Reset-device-on-module-unload-if-still-atta.patch [deleted file]
package/kernel/mac80211/patches/654-0002-rtl8xxxu-fix-spelling-mistake-firmare-firmware.patch [deleted file]
package/kernel/mac80211/patches/655-rtl8xxxu-Implement-8192e-specific-power-down-sequenc.patch [deleted file]
package/kernel/mac80211/patches/656-0001-rtl8xxxu-Fix-off-by-one-error-calculating-pubq.patch [deleted file]
package/kernel/mac80211/patches/656-0002-rtl8xxxu-Clean-up-llt_init-API.patch [deleted file]
package/kernel/mac80211/patches/656-0003-rtl8xxxu-Use-a-struct-rtl8xxxu_fileops-in-rtl8xxxu_i.patch [deleted file]
package/kernel/mac80211/patches/656-0004-rtl8xxxu-Stop-log-spam-from-each-successful-interrup.patch [deleted file]
package/kernel/mac80211/patches/657-0001-rtl8xxxu-Fix-memory-leak-in-handling-rxdesc16-packet.patch [deleted file]
package/kernel/mac80211/patches/657-0002-rtl8xxxu-Fix-big-endian-problem-reporting-mactime.patch [deleted file]
package/kernel/mac80211/patches/658-0001-rtl8xxxu-Fix-rtl8723bu-driver-reload-issue.patch [deleted file]
package/kernel/mac80211/patches/658-0002-rtl8xxxu-Fix-rtl8192eu-driver-reload-issue.patch [deleted file]
package/kernel/mac80211/patches/659-0001-rtl8xxxu-Obtain-RTS-rates-from-mac80211.patch [deleted file]
package/kernel/mac80211/patches/659-0002-rtl8xxxu-Pass-tx_info-to-fill_txdesc-in-order-to-hav.patch [deleted file]
package/kernel/mac80211/patches/660-0001-rtl8xxxu-Accept-firmware-signature-0x88e0.patch [deleted file]
package/kernel/mac80211/patches/660-0002-rtl8xxxu-Add-initial-code-to-detect-8188eu-devices.patch [deleted file]
package/kernel/mac80211/patches/660-0003-rtl8xxxu-Add-initial-code-to-parse-8188eu-efuse.patch [deleted file]
package/kernel/mac80211/patches/660-0004-rtl8xxxu-Detect-8188eu-parts-correctly.patch [deleted file]
package/kernel/mac80211/patches/660-0005-rtl8xxxu-First-stab-at-rtl8188e_power_on.patch [deleted file]
package/kernel/mac80211/patches/660-0006-rtl8xxxu-Add-rtl8188e_disabled_to_emu.patch [deleted file]
package/kernel/mac80211/patches/660-0007-rtl8xxxu-8188e-Enable-scheduler.patch [deleted file]
package/kernel/mac80211/patches/660-0008-rtl8xxxu-Add-rtl8188e_usb_quirk-for-enabling-MAC-TX-.patch [deleted file]
package/kernel/mac80211/patches/660-0009-rtl8xxxu-8188e-add-REG_TXDMA_OFFSET_CHK-quirk.patch [deleted file]
package/kernel/mac80211/patches/660-0010-rtl8xxxu-Add-reserved-page-init-parameters-for-8188e.patch [deleted file]
package/kernel/mac80211/patches/660-0011-rtl8xxxu-Correct-TX_TOTAL_PAGE_NUM-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0012-rtl8xxxu-Add-trxff_boundary-for-8188e.patch [deleted file]
package/kernel/mac80211/patches/660-0013-rtl8xxxu-8188eu-specify-firmware-block-size-and-set-.patch [deleted file]
package/kernel/mac80211/patches/660-0014-rtl8xxxu-Add-8188e-mac-init-table.patch [deleted file]
package/kernel/mac80211/patches/660-0015-rtl8xxxu-Implement-rtl8188eu_init_phy_bb.patch [deleted file]
package/kernel/mac80211/patches/660-0016-rtl8xxxu-Implement-rtl8188eu_init_phy_rf.patch [deleted file]
package/kernel/mac80211/patches/660-0017-rtl8xxxu-Use-auto-LLT-init-for-8188e.patch [deleted file]
package/kernel/mac80211/patches/660-0018-rtl8xxxu-Do-not-set-REG_FPGA0_TX_INFO-on-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0019-rtl8xxxu-Do-not-mess-with-REG_FPGA0_XA_RF_INT_OE-eit.patch [deleted file]
package/kernel/mac80211/patches/660-0020-rtl8xxxu-Set-transfer-page-size-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0021-rtl8xxxu-Enable-TX-report-timer-on-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0022-rtl8xxxu-Setup-interrupts-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0023-rtl8xxxu-Use-rxdesc16-and-32-byte-tx-descriptors-for.patch [deleted file]
package/kernel/mac80211/patches/660-0024-rtl8xxxu-8188eu-use-same-ADDA-on-parameters-as-8723a.patch [deleted file]
package/kernel/mac80211/patches/660-0025-rtl8xxxu-Add-PHY-IQ-calibration-code-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0026-rtl8xxxu-8188eu-uses-the-gen2-thermal-meter.patch [deleted file]
package/kernel/mac80211/patches/660-0027-rtl8xxxu-Set-REG_USB_HRPWM-to-0-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0028-rtl8xxxu-Implement-rtl8188eu_config_channel.patch [deleted file]
package/kernel/mac80211/patches/660-0029-rtl8xxxu-Use-gen2-H2C-commands-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0030-rtl8xxxu-Initialize-GPIO-settings-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0031-rtl8xxxu-Add-simple-rtl8188eu_rf_on-routine.patch [deleted file]
package/kernel/mac80211/patches/660-0032-rtl8xxxu-Implement-rtl8188e_disable_rf.patch [deleted file]
package/kernel/mac80211/patches/660-0033-rtl8xxxu-Update-8188e-efuse-definition-for-power-val.patch [deleted file]
package/kernel/mac80211/patches/660-0034-rtl8xxxu-Implement-rtl8188e_set_tx_power.patch [deleted file]
package/kernel/mac80211/patches/660-0035-rtl8xxxu-Implement-rtl8xxxu_fill_txdesc_v3-for-8188e.patch [deleted file]
package/kernel/mac80211/patches/660-0036-rtl8xxxu-Add-some-8188eu-registers-and-update-CCK0_A.patch [deleted file]
package/kernel/mac80211/patches/660-0037-rtl8xxxu-Improve-register-description-for-REG_FPGA1_.patch [deleted file]
package/kernel/mac80211/patches/660-0038-rtl8xxxu-properly-detect-RTL8188EU-devices.patch [deleted file]
package/kernel/mac80211/patches/660-0039-rtl8xxxu-Implement-8188eu-specific-8051-reset-functi.patch [deleted file]
package/kernel/mac80211/patches/660-0040-rtl8xxxu-Disable-packet-DMA-aggregation-on-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0041-rtl8xxxu-8188eu-set-REG_OFDM0_XA_AGC_CORE1-to-match-.patch [deleted file]
package/kernel/mac80211/patches/660-0042-rtl8xxxu-Fix-rtl8188eu-connection-fail.patch [deleted file]
package/kernel/mac80211/patches/660-0043-rtl8xxxu-Do-not-set-auto-rate-fallback-on-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0044-rtl8xxxu-Enable-8188eu-driver.patch [deleted file]
package/kernel/mac80211/patches/660-0045-rtl8xxxu-Add-rtl8188etv-to-USB-device-list.patch [deleted file]
package/kernel/mac80211/patches/660-0046-rtl8xxxu-Add-sitecom-dongle-to-USB-device-list.patch [deleted file]
package/kernel/mac80211/patches/660-0047-rtl8xxxu-Implement-rtl8188eu_active_to_emu.patch [deleted file]
package/kernel/mac80211/patches/660-0048-rtl8xxxu-Implement-rtl8188eu_power_off.patch [deleted file]
package/kernel/mac80211/patches/660-0049-rtl8xxxu-Add-rtl8188eu-USB-ID-for-D-Link-USB-GO-N150.patch [deleted file]
package/kernel/mac80211/patches/660-0050-rtl8xxxu-Clear-SYS_FUNC_UPLL-during-power-up-on-8188.patch [deleted file]
package/kernel/mac80211/patches/660-0051-rtl8xxxu-Early-enable-of-WEP-TKIP-security-on-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0052-rtl8xxxu-Correct-power-down-sequence-for-8188eu.patch [deleted file]
package/kernel/mac80211/patches/660-0053-rtl8xxxu-Reset-8188eu-REG_GPIO_MUXCFG-on-power-off.patch [deleted file]
package/kernel/mac80211/patches/660-0054-rtl8xxxu-Handle-devices-with-a-smaller-LLT-buffer.patch [deleted file]
package/kernel/mac80211/patches/660-0055-rtl8xxxu-Fix-reloading-of-driver-for-8188eu-devices.patch [deleted file]
package/kernel/mac80211/patches/660-0056-rtl8xxxu-Make-sure-to-enable-OFDM-paths-for-8188eu-i.patch [deleted file]
package/kernel/mac80211/patches/660-0057-rtl8xxxu-Add-rpt_sel-entry-to-struct-rtl8xxxu_rxdesc.patch [deleted file]
package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch
package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch
package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch
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 91c9362..f9f5093 100644 (file)
@@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2016-06-20
+PKG_VERSION:=2016-10-08
 PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_BACKPORT_VERSION:=
-PKG_MD5SUM:=29c79bdc3928ef5113b17042ebda9237
+PKG_MD5SUM:=4f6350e3b75815060bfdf47ef266ad613c7bfea5b7b1dc4552dee69e1bebe4fb
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
index 38b3179..22819f7 100644 (file)
@@ -1,6 +1,6 @@
 --- a/compat/Makefile
 +++ b/compat/Makefile
-@@ -35,8 +35,6 @@ compat-$(CPTCFG_KERNEL_4_6) += backport-
+@@ -36,8 +36,6 @@ compat-$(CPTCFG_KERNEL_4_7) += backport-
  
  compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o
  compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o
diff --git a/package/kernel/mac80211/patches/006-add-basic-register-field-manipulation-macros.patch b/package/kernel/mac80211/patches/006-add-basic-register-field-manipulation-macros.patch
deleted file mode 100644 (file)
index a51edf8..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-From: Jakub Kicinski <jakub.kicinski@netronome.com>
-Date: Wed, 31 Aug 2016 12:46:44 +0100
-Subject: [PATCH] add basic register-field manipulation macros
-
-Common approach to accessing register fields is to define
-structures or sets of macros containing mask and shift pair.
-Operations on the register are then performed as follows:
-
- field = (reg >> shift) & mask;
-
- reg &= ~(mask << shift);
- reg |= (field & mask) << shift;
-
-Defining shift and mask separately is tedious.  Ivo van Doorn
-came up with an idea of computing them at compilation time
-based on a single shifted mask (later refined by Felix) which
-can be used like this:
-
- #define REG_FIELD 0x000ff000
-
- field = FIELD_GET(REG_FIELD, reg);
-
- reg &= ~REG_FIELD;
- reg |= FIELD_PREP(REG_FIELD, field);
-
-FIELD_{GET,PREP} macros take care of finding out what the
-appropriate shift is based on compilation time ffs operation.
-
-GENMASK can be used to define registers (which is usually
-less error-prone and easier to match with datasheets).
-
-This approach is the most convenient I've seen so to limit code
-multiplication let's move the macros to a global header file.
-Attempts to use static inlines instead of macros failed due
-to false positive triggering of BUILD_BUG_ON()s, especially with
-GCC < 6.0.
-
-Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
-Reviewed-by: Dinan Gunawardena <dinan.gunawardena@netronome.com>
----
- create mode 100644 include/linux/bitfield.h
-
---- /dev/null
-+++ b/include/linux/bitfield.h
-@@ -0,0 +1,100 @@
-+/*
-+ * Copyright (C) 2014 Felix Fietkau <nbd@nbd.name>
-+ * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+
-+#ifndef _LINUX_BITFIELD_H
-+#define _LINUX_BITFIELD_H
-+
-+#include <linux/bug.h>
-+
-+#ifdef __CHECKER__
-+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
-+#else
-+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n)      \
-+      BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
-+#endif
-+
-+/*
-+ * Bitfield access macros
-+ *
-+ * FIELD_{GET,PREP} macros take as first parameter shifted mask
-+ * from which they extract the base mask and shift amount.
-+ * Mask must be a compilation time constant.
-+ *
-+ * Example:
-+ *
-+ *  #define REG_FIELD_A  GENMASK(6, 0)
-+ *  #define REG_FIELD_B  BIT(7)
-+ *  #define REG_FIELD_C  GENMASK(15, 8)
-+ *  #define REG_FIELD_D  GENMASK(31, 16)
-+ *
-+ * Get:
-+ *  a = FIELD_GET(REG_FIELD_A, reg);
-+ *  b = FIELD_GET(REG_FIELD_B, reg);
-+ *
-+ * Set:
-+ *  reg = FIELD_PREP(REG_FIELD_A, 1) |
-+ *      FIELD_PREP(REG_FIELD_B, 0) |
-+ *      FIELD_PREP(REG_FIELD_C, c) |
-+ *      FIELD_PREP(REG_FIELD_D, 0x40);
-+ *
-+ * Modify:
-+ *  reg &= ~REG_FIELD_C;
-+ *  reg |= FIELD_PREP(REG_FIELD_C, c);
-+ */
-+
-+#define __bf_shf(x) (__builtin_ffsll(x) - 1)
-+
-+#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx)                     \
-+      ({                                                              \
-+              BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask),          \
-+                               _pfx "mask is not constant");          \
-+              BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero");        \
-+              BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?           \
-+                               ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
-+                               _pfx "value too large for the field"); \
-+              BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull,         \
-+                               _pfx "type of reg too small for mask"); \
-+              __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) +                 \
-+                                            (1ULL << __bf_shf(_mask))); \
-+      })
-+
-+/**
-+ * FIELD_PREP() - prepare a bitfield element
-+ * @_mask: shifted mask defining the field's length and position
-+ * @_val:  value to put in the field
-+ *
-+ * FIELD_PREP() masks and shifts up the value.  The result should
-+ * be combined with other fields of the bitfield using logical OR.
-+ */
-+#define FIELD_PREP(_mask, _val)                                               \
-+      ({                                                              \
-+              __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");    \
-+              ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);   \
-+      })
-+
-+/**
-+ * FIELD_GET() - extract a bitfield element
-+ * @_mask: shifted mask defining the field's length and position
-+ * @_reg:  32bit value of entire bitfield
-+ *
-+ * FIELD_GET() extracts the field specified by @_mask from the
-+ * bitfield passed in as @_reg by masking and shifting it down.
-+ */
-+#define FIELD_GET(_mask, _reg)                                                \
-+      ({                                                              \
-+              __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: ");       \
-+              (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
-+      })
-+
-+#endif
index 8be5fa1..4df5ac5 100644 (file)
@@ -1,6 +1,6 @@
 --- a/.local-symbols
 +++ b/.local-symbols
-@@ -481,45 +481,6 @@ USB_IPHETH=
+@@ -477,45 +477,6 @@ USB_IPHETH=
  USB_SIERRA_NET=
  USB_VL600=
  USB_NET_CH9200=
index fbe22e5..b65b0bd 100644 (file)
  #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)
 +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];
++{
 +      int i;
 +
 +      crypto_cipher_encrypt_one(tfm, b, b_0);
 +      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;
++
 +      /* Mask out bits from auth-only-b_0 */
 +      b_0[0] &= 0x07;
--      memset(aead_req, 0, sizeof(aead_req_data));
++
 +      /* 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);
++
++
 +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)
-+{
+                              u8 *data, size_t data_len, u8 *mic,
+                              size_t mic_len)
+ {
+-      struct scatterlist sg[3];
 +      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;
-+
+-      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;
 +      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);
-+
+-      memset(aead_req, 0, sizeof(aead_req_data));
 +      /* 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;
-+
+-      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);
 +              /* Authentication followed by encryption */
 +              for (i = 0; i < blen; i++)
 +                      b[i] ^= pos[i];
 +              crypto_cipher_encrypt_one(tfm, b, b);
-+
+-      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);
 +              b_0[14] = (j >> 8) & 0xff;
 +              b_0[15] = j & 0xff;
 +              crypto_cipher_encrypt_one(tfm, e, b_0);
 -                         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);
 +      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];
-+
+-      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, a, b);
-+
+-      memset(aead_req, 0, sizeof(aead_req_data));
 +      /* Process payload blocks */
 +      cpos = data;
 +      pos = data;
 +      for (j = 1; j <= num_blocks; j++) {
 +              int blen = (j == num_blocks && last_len) ?
 +                      last_len : AES_BLOCK_SIZE;
-+
+-      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);
 +              /* Decryption followed by authentication */
 +              b_0[14] = (j >> 8) & 0xff;
 +              b_0[15] = j & 0xff;
 +              }
 +              crypto_cipher_encrypt_one(tfm, a, a);
 +      }
-+
+-      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++) {
 +              if ((mic[i] ^ s_0[i]) != a[i])
 +                      return -1;
  {
 -      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;
index 3ca166f..c42b17d 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
-@@ -850,7 +850,6 @@ static int ieee80211_stop_ap(struct wiph
+@@ -1016,7 +1016,6 @@ static int ieee80211_stop_ap(struct wiph
        sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
  
        __sta_info_flush(sdata, true);
index cdcd5c8..29d7034 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/mac80211_hwsim.c
 +++ b/drivers/net/wireless/mac80211_hwsim.c
-@@ -2631,7 +2631,7 @@ static int mac80211_hwsim_new_radio(stru
+@@ -2662,7 +2662,7 @@ static int mac80211_hwsim_new_radio(stru
  
        tasklet_hrtimer_init(&data->beacon_timer,
                             mac80211_hwsim_beacon,
index 16fab84..f4cb41c 100644 (file)
@@ -18,7 +18,7 @@
  static int ieee80211_ifa6_changed(struct notifier_block *nb,
                                  unsigned long data, void *arg)
  {
-@@ -1090,14 +1090,14 @@ int ieee80211_register_hw(struct ieee802
+@@ -1101,14 +1101,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)
-@@ -1106,13 +1106,13 @@ int ieee80211_register_hw(struct ieee802
+@@ -1117,13 +1117,13 @@ int ieee80211_register_hw(struct ieee802
  
        return 0;
  
@@ -52,7 +52,7 @@
   fail_ifa:
  #endif
        ieee80211_txq_teardown_flows(local);
-@@ -1142,10 +1142,10 @@ void ieee80211_unregister_hw(struct ieee
+@@ -1153,10 +1153,10 @@ void ieee80211_unregister_hw(struct ieee
        tasklet_kill(&local->tx_pending_tasklet);
        tasklet_kill(&local->tasklet);
  
index 29f05c4..94f5f39 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2008,7 +2008,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -2175,7 +2175,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
new file mode 100644 (file)
index 0000000..57917c5
--- /dev/null
@@ -0,0 +1,953 @@
+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-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/300-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-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/301-ath9k-force-rx_clear-when-disabling-rx.patch
new file mode 100644 (file)
index 0000000..098bda7
--- /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 (!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-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/301-ath9k-limit-retries-for-powersave-response-frames.patch
deleted file mode 100644 (file)
index a160dc4..0000000
+++ /dev/null
@@ -1,121 +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
-@@ -136,10 +136,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,
-@@ -1419,7 +1434,7 @@ ath_tx_form_burst(struct ath_softc *sc,
-               if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
-                       break;
--              ath_set_rates(tid->an->vif, tid->an->sta, bf);
-+              ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
-       } while (1);
- }
-@@ -1450,7 +1465,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)
-               last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
-                                       tid_q, &aggr_len);
-@@ -1647,7 +1662,7 @@ void ath9k_release_buffered_frames(struc
-                       __skb_unlink(bf->bf_mpdu, tid_q);
-                       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;
-@@ -2293,7 +2308,7 @@ int ath_tx_start(struct ieee80211_hw *hw
-       struct ath_txq *txq = txctl->txq;
-       struct ath_atx_tid *tid = NULL;
-       struct ath_buf *bf;
--      bool queue, skip_uapsd = false, ps_resp;
-+      bool queue, ps_resp;
-       int q, ret;
-       if (vif)
-@@ -2346,13 +2361,13 @@ int ath_tx_start(struct ieee80211_hw *hw
-               if (!txctl->an)
-                       txctl->an = &avp->mcast_node;
-               queue = true;
--              skip_uapsd = true;
-+              ps_resp = false;
-       }
-       if (txctl->an && queue)
-               tid = ath_get_skb_tid(sc, txctl->an, skb);
--      if (!skip_uapsd && ps_resp) {
-+      if (ps_resp) {
-               ath_txq_unlock(sc, txq);
-               txq = sc->tx.uapsdq;
-               ath_txq_lock(sc, txq);
-@@ -2390,7 +2405,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:
-@@ -2429,7 +2444,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)
-@@ -2932,7 +2947,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-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/302-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch
deleted file mode 100644 (file)
index 7caa9be..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
-@@ -2914,7 +2914,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;
-@@ -2922,10 +2923,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/302-ath9k-limit-retries-for-powersave-response-frames.patch b/package/kernel/mac80211/patches/302-ath9k-limit-retries-for-powersave-response-frames.patch
new file mode 100644 (file)
index 0000000..8c19ea2
--- /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
+@@ -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/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
new file mode 100644 (file)
index 0000000..57f45c1
--- /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
+@@ -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-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch b/package/kernel/mac80211/patches/303-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch
deleted file mode 100644 (file)
index 73accd8..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Ben Greear <greearb@candelatech.com>
-Date: Fri, 1 Apr 2016 14:12:08 -0700
-Subject: [PATCH] ath10k: Ensure txrx-compl-task is stopped when cleaning
- htt-tx.
-
-Otherwise, the txrx-compl-task may access some bad memory?
-
-Signed-off-by: Ben Greear <greearb@candelatech.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/htt_tx.c
-+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
-@@ -388,6 +388,8 @@ void ath10k_htt_tx_free(struct ath10k_ht
- {
-       int size;
-+      tasklet_kill(&htt->txrx_compl_task);
-+
-       idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
-       idr_destroy(&htt->pending_tx);
diff --git a/package/kernel/mac80211/patches/304-ath10k-Ensure-peer_map-references-are-cleaned-up.patch b/package/kernel/mac80211/patches/304-ath10k-Ensure-peer_map-references-are-cleaned-up.patch
deleted file mode 100644 (file)
index 7dec1fb..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-From: Ben Greear <greearb@candelatech.com>
-Date: Fri, 1 Apr 2016 14:12:09 -0700
-Subject: [PATCH] ath10k: Ensure peer_map references are cleaned up.
-
-While debugging OS crashes due to firmware crashes, I enabled
-kasan, and it noticed that peer objects were being used-after-freed.
-
-Looks like there are two places we could be leaving stale references
-in the peer-map, so clean that up.
-
-Signed-off-by: Ben Greear <greearb@candelatech.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct a
- {
-       struct ath10k_peer *peer, *tmp;
-       int peer_id;
-+      int i;
-       lockdep_assert_held(&ar->conf_mutex);
-@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct a
-                       ar->peer_map[peer_id] = NULL;
-               }
-+              /* Double check that peer is properly un-referenced from
-+               * the peer_map
-+               */
-+              for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
-+                      if (ar->peer_map[i] == peer) {
-+                              ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n",
-+                                          peer->addr, peer, i);
-+                              ar->peer_map[i] = NULL;
-+                      }
-+              }
-+
-               list_del(&peer->list);
-               kfree(peer);
-               ar->num_peers--;
-@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct a
- static void ath10k_peer_cleanup_all(struct ath10k *ar)
- {
-       struct ath10k_peer *peer, *tmp;
-+      int i;
-       lockdep_assert_held(&ar->conf_mutex);
-@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(stru
-               list_del(&peer->list);
-               kfree(peer);
-       }
-+
-+      for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
-+              ar->peer_map[i] = NULL;
-+
-       spin_unlock_bh(&ar->data_lock);
-       ar->num_peers = 0;
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
new file mode 100644 (file)
index 0000000..72e81ee
--- /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
+@@ -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-ath10k-Clean-up-peer-when-sta-goes-away.patch b/package/kernel/mac80211/patches/305-ath10k-Clean-up-peer-when-sta-goes-away.patch
deleted file mode 100644 (file)
index 7248a8c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From: Ben Greear <greearb@candelatech.com>
-Date: Fri, 1 Apr 2016 14:12:11 -0700
-Subject: [PATCH] ath10k: Clean up peer when sta goes away.
-
-If WMI and/or firmware has issues removing the peer object,
-then we still need to clean up the peer object in the driver.
-
-Signed-off-by: Ben Greear <greearb@candelatech.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -5992,9 +5992,17 @@ static int ath10k_sta_state(struct ieee8
-                               continue;
-                       if (peer->sta == sta) {
--                              ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n",
--                                          sta->addr, arvif->vdev_id);
-+                              ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n",
-+                                          sta->addr, peer, i, arvif->vdev_id);
-                               peer->sta = NULL;
-+
-+                              /* Clean up the peer object as well since we
-+                               * must have failed to do this above.
-+                               */
-+                              list_del(&peer->list);
-+                              ar->peer_map[i] = NULL;
-+                              kfree(peer);
-+                              ar->num_peers--;
-                       }
-               }
-               spin_unlock_bh(&ar->data_lock);
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
new file mode 100644 (file)
index 0000000..508cc92
--- /dev/null
@@ -0,0 +1,224 @@
+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,
+--- 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-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/306-mac80211-add-hdrlen-to-ieee80211_tx_data.patch
deleted file mode 100644 (file)
index 4a8f143..0000000
+++ /dev/null
@@ -1,203 +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
-@@ -173,6 +173,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
-@@ -922,7 +922,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 */
-@@ -943,8 +943,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;
-@@ -1176,6 +1174,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;
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -1226,6 +1226,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 */
-@@ -1250,8 +1251,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/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
new file mode 100644 (file)
index 0000000..6e7ecb9
--- /dev/null
@@ -0,0 +1,81 @@
+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
new file mode 100644 (file)
index 0000000..4fc6dc1
--- /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
+@@ -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-NEED_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/307-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch
deleted file mode 100644 (file)
index eeb881e..0000000
+++ /dev/null
@@ -1,235 +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
-@@ -2014,6 +2014,9 @@ struct ieee80211_txq {
-  * @IEEE80211_HW_TX_FRAG_LIST: Hardware (or driver) supports sending frag_list
-  *    skbs, needed for zero-copy software A-MSDU.
-  *
-+ * @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 {
-@@ -2054,6 +2057,7 @@ enum ieee80211_hw_flags {
-       IEEE80211_HW_USES_RSS,
-       IEEE80211_HW_TX_AMSDU,
-       IEEE80211_HW_TX_FRAG_LIST,
-+      IEEE80211_HW_NEEDS_ALIGNED4_SKBS,
-       /* keep last, obviously */
-       NUM_IEEE80211_HW_FLAGS
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -302,6 +302,7 @@ static const char *hw_flag_names[] = {
-       FLAG(USES_RSS),
-       FLAG(TX_AMSDU),
-       FLAG(TX_FRAG_LIST),
-+      FLAG(NEEDS_ALIGNED4_SKBS),
- #undef FLAG
- };
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1497,6 +1497,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
-@@ -279,7 +279,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
-@@ -683,9 +683,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
-@@ -1173,8 +1173,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))
-@@ -2108,7 +2107,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;
-@@ -2334,7 +2333,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;
-@@ -2554,6 +2553,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.
-@@ -2640,6 +2642,7 @@ static struct sk_buff *ieee80211_build_h
-       h_pos -= 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
-@@ -2678,6 +2681,9 @@ static struct sk_buff *ieee80211_build_h
-       }
- #endif
-+      if (padsize)
-+              memset(skb_push(skb, padsize), 0, padsize);
-+
-       if (ieee80211_is_data_qos(fc)) {
-               __le16 *qos_control;
-@@ -2691,8 +2697,8 @@ static struct sk_buff *ieee80211_build_h
-       } else
-               memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
--      nh_pos += hdrlen;
--      h_pos += hdrlen;
-+      nh_pos += hdrlen + padsize;
-+      h_pos += hdrlen + padsize;
-       /* Update skb pointers to various headers since this modified frame
-        * is going to go through Linux networking code that may potentially
-@@ -2861,6 +2867,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,
---- a/net/mac80211/util.c
-+++ b/net/mac80211/util.c
-@@ -1224,6 +1224,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;
-@@ -1251,7 +1252,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/308-ath10k-Fix-sending-NULL-Qos-NULL-data-frames-for-QCA.patch b/package/kernel/mac80211/patches/308-ath10k-Fix-sending-NULL-Qos-NULL-data-frames-for-QCA.patch
deleted file mode 100644 (file)
index 8590aad..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-From: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
-Date: Thu, 23 Jun 2016 22:10:01 +0530
-Subject: [PATCH] ath10k: Fix sending NULL/ Qos NULL data frames for
- QCA99X0 and later
-
-For chipsets like QCA99X0, IPQ4019 and later we are not getting proper
-NULL func status (always acked/successs !!) when hostapd does a
-PROBE_CLIENT via nullfunc frames when the station is powered off
-abruptly (inactive timer probes client via null func after the inactive
-time reaches beyond the threshold). Fix this by disabling the workaround
-(getting the ACK status of NULL func frames by sending via HTT mgmt-tx
- path) introduced by the change ("ath10k: fix beacon loss handling ")
-for QCA99X0 and later chipsets. The normal tx path provides the proper
-ACK status for NULL data frames. As of now disable this workaround for
-chipsets QCA99X0 and later, once the 10.1 firmware is obselete we can
-completely get rid of this workaround for all the chipsets
-
-Signed-off-by: Tamizh chelvam <c_traja@qti.qualcomm.com>
-Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/core.c
-+++ b/drivers/net/wireless/ath/ath10k/core.c
-@@ -181,6 +181,7 @@ static const struct ath10k_hw_params ath
-                       .board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
-                       .board_size = QCA99X0_BOARD_DATA_SZ,
-                       .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
-+                      .disable_null_func_workaround = true,
-               },
-       },
-       {
-@@ -204,6 +205,7 @@ static const struct ath10k_hw_params ath
-                       .board = QCA9984_HW_1_0_BOARD_DATA_FILE,
-                       .board_size = QCA99X0_BOARD_DATA_SZ,
-                       .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
-+                      .disable_null_func_workaround = true,
-               },
-       },
-       {
-@@ -262,6 +264,7 @@ static const struct ath10k_hw_params ath
-                       .board = QCA4019_HW_1_0_BOARD_DATA_FILE,
-                       .board_size = QCA4019_BOARD_DATA_SZ,
-                       .board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,
-+                      .disable_null_func_workaround = true,
-               },
-       },
- };
---- a/drivers/net/wireless/ath/ath10k/core.h
-+++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -750,6 +750,12 @@ struct ath10k {
-                       const char *board;
-                       size_t board_size;
-                       size_t board_ext_size;
-+                      /* Workaround of sending NULL data frames via
-+                       * HTT mgmt TX and getting the proper ACK status does
-+                       * not works for chipsets QCA99X0 and later, while
-+                       * Tx data path reports the ACK status properly.
-+                       */
-+                      bool disable_null_func_workaround;
-               } fw;
-       } hw_params;
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -3253,6 +3253,7 @@ ath10k_mac_tx_h_get_txmode(struct ath10k
-        * mode though because AP don't sleep.
-        */
-       if (ar->htt.target_version_major < 3 &&
-+          !ar->hw_params.fw.disable_null_func_workaround &&
-           (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
-           !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
-                     ar->running_fw->fw_file.fw_features))
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
new file mode 100644 (file)
index 0000000..929da25
--- /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
+@@ -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/309-ath9k-report-tx-status-on-EOSP.patch b/package/kernel/mac80211/patches/309-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/309-cfg80211-fix-proto-in-ieee80211_data_to_8023-for-fra.patch b/package/kernel/mac80211/patches/309-cfg80211-fix-proto-in-ieee80211_data_to_8023-for-fra.patch
deleted file mode 100644 (file)
index 41c27ca..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 29 Jun 2016 10:02:32 +0200
-Subject: [PATCH] cfg80211: fix proto in ieee80211_data_to_8023 for frames
- without LLC header
-
-The PDU length of incoming LLC frames is set to the total skb payload size
-in __ieee80211_data_to_8023() of net/wireless/util.c which incorrectly
-includes the length of the IEEE 802.11 header.
-
-The resulting LLC frame header has a too large PDU length, causing the
-llc_fixup_skb() function of net/llc/llc_input.c to reject the incoming
-skb, effectively breaking STP.
-
-Solve the problem by properly substracting the IEEE 802.11 frame header size
-from the PDU length, allowing the LLC processor to pick up the incoming
-control messages.
-
-Special thanks to Gerry Rozema for tracking down the regression and proposing
-a suitable patch.
-
-Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer")
-Cc: stable@vger.kernel.org
-Reported-by: Gerry Rozema <gerryr@rozeware.com>
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -509,7 +509,7 @@ static int __ieee80211_data_to_8023(stru
-                * replace EtherType */
-               hdrlen += ETH_ALEN + 2;
-       else
--              tmp.h_proto = htons(skb->len);
-+              tmp.h_proto = htons(skb->len - hdrlen);
-       pskb_pull(skb, hdrlen);
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
new file mode 100644 (file)
index 0000000..2993cba
--- /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,
+@@ -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-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/310-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch
deleted file mode 100644 (file)
index 25929c9..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
-@@ -1550,6 +1550,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/311-ath10k-Add-support-for-160Mhz.patch b/package/kernel/mac80211/patches/311-ath10k-Add-support-for-160Mhz.patch
new file mode 100644 (file)
index 0000000..372ce58
--- /dev/null
@@ -0,0 +1,285 @@
+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-ath10k-disable-wake_tx_queue-for-older-devices.patch b/package/kernel/mac80211/patches/311-ath10k-disable-wake_tx_queue-for-older-devices.patch
deleted file mode 100644 (file)
index 4cf26a6..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-From: Michal Kazior <michal.kazior@tieto.com>
-Date: Tue, 17 May 2016 14:47:01 +0200
-Subject: [PATCH] ath10k: disable wake_tx_queue for older devices
-
-Some setups suffer performance regressions with
-current wake_tx_queue implementation.
-
-Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
----
-
---- a/drivers/net/wireless/ath/ath10k/core.h
-+++ b/drivers/net/wireless/ath/ath10k/core.h
-@@ -667,6 +667,7 @@ struct ath10k_fw_components {
- struct ath10k {
-       struct ath_common ath_common;
-       struct ieee80211_hw *hw;
-+      struct ieee80211_ops *ops;
-       struct device *dev;
-       u8 mac_addr[ETH_ALEN];
---- a/drivers/net/wireless/ath/ath10k/mac.c
-+++ b/drivers/net/wireless/ath/ath10k/mac.c
-@@ -7497,21 +7497,32 @@ static const struct ieee80211_channel at
- struct ath10k *ath10k_mac_create(size_t priv_size)
- {
-       struct ieee80211_hw *hw;
-+      struct ieee80211_ops *ops;
-       struct ath10k *ar;
--      hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
--      if (!hw)
-+      ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
-+      if (!ops)
-+              return NULL;
-+
-+      hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
-+      if (!hw) {
-+              kfree(ops);
-               return NULL;
-+      }
-       ar = hw->priv;
-       ar->hw = hw;
-+      ar->ops = ops;
-       return ar;
- }
- void ath10k_mac_destroy(struct ath10k *ar)
- {
-+      struct ieee80211_ops *ops = ar->ops;
-+
-       ieee80211_free_hw(ar->hw);
-+      kfree(ops);
- }
- static const struct ieee80211_iface_limit ath10k_if_limits[] = {
-@@ -7945,6 +7956,15 @@ int ath10k_mac_register(struct ath10k *a
-                       ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
-       }
-+      /* Current wake_tx_queue implementation imposes a significant
-+       * performance penalty in some setups. The tx scheduling code needs
-+       * more work anyway so disable the wake_tx_queue unless firmware
-+       * supports the pull-push mechanism.
-+       */
-+      if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
-+                    ar->running_fw->fw_file.fw_features))
-+              ar->ops->wake_tx_queue = NULL;
-+
-       ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
-                           ath10k_reg_notifier);
-       if (ret) {
diff --git a/package/kernel/mac80211/patches/312-ath9k-Correct-TSF-adjustment-to-align-the-beacon-tim.patch b/package/kernel/mac80211/patches/312-ath9k-Correct-TSF-adjustment-to-align-the-beacon-tim.patch
deleted file mode 100644 (file)
index df43105..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From: Benjamin Berg <benjamin.berg@open-mesh.com>
-Date: Mon, 4 Jul 2016 14:37:20 +0200
-Subject: [PATCH] ath9k: Correct TSF adjustment to align the beacon time
- correctly
-
-Beacons were not send out at (timestamp % beacon_time == 0) for interfaces
-other than the primary one. To send out beacons with the correct timestamp
-according to 10.1.3.2 of the 802.11 standard the tsf_adjustment has to be
-set to the negative time difference instead of positive. This way the
-later beacons get corrected to have a lower (and similar) timestamp with
-regard to the beacon from slot 0.
-
-I am not aware about any issues that have been caused by this.
-
-Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -279,17 +279,21 @@ static void ath9k_set_tsfadjust(struct a
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_vif *avp = (void *)vif->drv_priv;
-       struct ath_beacon_config *cur_conf = &avp->chanctx->beacon;
--      u32 tsfadjust;
-+      s64 tsfadjust;
-       if (avp->av_bslot == 0)
-               return;
-+      /* tsf_adjust is added to the TSF value. We send out the beacon late,
-+       * so need to adjust the TSF starting point to be later in time (i.e.
-+       * the theoretical first beacon has a TSF of 0 after correction).
-+       */
-       tsfadjust = cur_conf->beacon_interval * avp->av_bslot;
--      tsfadjust = TU_TO_USEC(tsfadjust) / ATH_BCBUF;
-+      tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF;
-       avp->tsf_adjust = cpu_to_le64(tsfadjust);
--      ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n",
--              (unsigned long long)tsfadjust, avp->av_bslot);
-+      ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n",
-+              (signed long long)tsfadjust, avp->av_bslot);
- }
- bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif)
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
new file mode 100644 (file)
index 0000000..4c5fff1
--- /dev/null
@@ -0,0 +1,275 @@
+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-Handle-channel-context-in-get_-set_-reset_tsf.patch b/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch
deleted file mode 100644 (file)
index ef0afbe..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From: Benjamin Berg <benjamin.berg@open-mesh.com>
-Date: Mon, 4 Jul 2016 14:37:21 +0200
-Subject: [PATCH] ath9k: Handle channel context in get_/set_/reset_tsf
-
-The ath9k TSF handling routines need to be aware of the channel context that
-is being modified. With this change the TSF related values that are stored
-in each channel context will be correctly tracked and the harware will only
-be updated if the modified context is currently the active one.
-
-Without this change the TSF modifications done using these routines would
-for example be lost during a hardware reset as done by ath_complete_reset.
-
-Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1823,11 +1823,18 @@ static void ath9k_bss_info_changed(struc
- static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
- {
-       struct ath_softc *sc = hw->priv;
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-       u64 tsf;
-       mutex_lock(&sc->mutex);
-       ath9k_ps_wakeup(sc);
--      tsf = ath9k_hw_gettsf64(sc->sc_ah);
-+      /* Get current TSF either from HW or kernel time. */
-+      if (sc->cur_chan == avp->chanctx) {
-+              tsf = ath9k_hw_gettsf64(sc->sc_ah);
-+      } else {
-+              tsf = sc->cur_chan->tsf_val +
-+                    ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
-+      }
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
-@@ -1839,10 +1846,14 @@ static void ath9k_set_tsf(struct ieee802
-                         u64 tsf)
- {
-       struct ath_softc *sc = hw->priv;
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-       mutex_lock(&sc->mutex);
-       ath9k_ps_wakeup(sc);
--      ath9k_hw_settsf64(sc->sc_ah, tsf);
-+      getrawmonotonic(&avp->chanctx->tsf_ts);
-+      if (sc->cur_chan == avp->chanctx)
-+              ath9k_hw_settsf64(sc->sc_ah, tsf);
-+      avp->chanctx->tsf_val = tsf;
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
- }
-@@ -1850,11 +1861,15 @@ static void ath9k_set_tsf(struct ieee802
- static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
- {
-       struct ath_softc *sc = hw->priv;
-+      struct ath_vif *avp = (void *)vif->drv_priv;
-       mutex_lock(&sc->mutex);
-       ath9k_ps_wakeup(sc);
--      ath9k_hw_reset_tsf(sc->sc_ah);
-+      getrawmonotonic(&avp->chanctx->tsf_ts);
-+      if (sc->cur_chan == avp->chanctx)
-+              ath9k_hw_reset_tsf(sc->sc_ah);
-+      avp->chanctx->tsf_val = 0;
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
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
new file mode 100644 (file)
index 0000000..c1548be
--- /dev/null
@@ -0,0 +1,37 @@
+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-Use-tsf-offset-helper-in-ath9k_hw_reset.patch b/package/kernel/mac80211/patches/314-ath9k-Use-tsf-offset-helper-in-ath9k_hw_reset.patch
deleted file mode 100644 (file)
index e725a8b..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-From: Benjamin Berg <benjamin.berg@open-mesh.com>
-Date: Mon, 4 Jul 2016 14:37:22 +0200
-Subject: [PATCH] ath9k: Use tsf offset helper in ath9k_hw_reset
-
-These changes make ath9k_hw_reset more consistent with other places that
-handle the TSF value by using the same helper routine.
-
-A slight improvement is to not assume that a fixed time of 1.5ms has
-passed for the initval writes when compared to the first write attempt.
-Instead the TSF value is re-calculated which will yield a higher accuracy
-of the restored TSF timer.
-
-Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1832,8 +1832,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-       u32 saveLedState;
-       u32 saveDefAntenna;
-       u32 macStaId1;
-+      struct timespec tsf_ts;
-+      u32 tsf_offset;
-       u64 tsf = 0;
--      s64 usec = 0;
-       int r;
-       bool start_mci_reset = false;
-       bool save_fullsleep = ah->chip_fullsleep;
-@@ -1877,8 +1878,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-       macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
-       /* Save TSF before chip reset, a cold reset clears it */
-+      getrawmonotonic(&tsf_ts);
-       tsf = ath9k_hw_gettsf64(ah);
--      usec = ktime_to_us(ktime_get_raw());
-       saveLedState = REG_READ(ah, AR_CFG_LED) &
-               (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
-@@ -1911,8 +1912,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-       }
-       /* Restore TSF */
--      usec = ktime_to_us(ktime_get_raw()) - usec;
--      ath9k_hw_settsf64(ah, tsf + usec);
-+      tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL);
-+      ath9k_hw_settsf64(ah, tsf + tsf_offset);
-       if (AR_SREV_9280_20_OR_LATER(ah))
-               REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
-@@ -1932,12 +1933,11 @@ int ath9k_hw_reset(struct ath_hw *ah, st
-       /*
-        * Some AR91xx SoC devices frequently fail to accept TSF writes
-        * right after the chip reset. When that happens, write a new
--       * value after the initvals have been applied, with an offset
--       * based on measured time difference
-+       * value after the initvals have been applied.
-        */
-       if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) {
--              tsf += 1500;
--              ath9k_hw_settsf64(ah, tsf);
-+              tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL);
-+              ath9k_hw_settsf64(ah, tsf + tsf_offset);
-       }
-       ath9k_hw_init_mfp(ah);
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
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/315-ath9k-Expose-tsf_adjustment-in-mac80211-tsf-getters-.patch b/package/kernel/mac80211/patches/315-ath9k-Expose-tsf_adjustment-in-mac80211-tsf-getters-.patch
deleted file mode 100644 (file)
index c95ab7e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From: Benjamin Berg <benjamin.berg@open-mesh.com>
-Date: Mon, 4 Jul 2016 14:37:23 +0200
-Subject: [PATCH] ath9k: Expose tsf_adjustment in mac80211 tsf getters and
- setters.
-
-The ath9k driver modifies the TSF for VIFs for the purpose of sending
-beacons in a staggered fashion. This patch exposes this VIF specific
-adjustment of the TSF value to mac80211. Without the change the TSF
-routines handle the hardware TSF value instead of the actual TSF value as
-seen on the air.
-
-Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1835,6 +1835,7 @@ static u64 ath9k_get_tsf(struct ieee8021
-               tsf = sc->cur_chan->tsf_val +
-                     ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
-       }
-+      tsf += le64_to_cpu(avp->tsf_adjust);
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
-@@ -1850,6 +1851,7 @@ static void ath9k_set_tsf(struct ieee802
-       mutex_lock(&sc->mutex);
-       ath9k_ps_wakeup(sc);
-+      tsf -= le64_to_cpu(avp->tsf_adjust);
-       getrawmonotonic(&avp->chanctx->tsf_ts);
-       if (sc->cur_chan == avp->chanctx)
-               ath9k_hw_settsf64(sc->sc_ah, tsf);
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
new file mode 100644 (file)
index 0000000..6a958a4
--- /dev/null
@@ -0,0 +1,125 @@
+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,23 @@ 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);
+       }
++      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-Remove-some-defined-constants-to-decrease-verb.patch b/package/kernel/mac80211/patches/316-ath9k-Remove-some-defined-constants-to-decrease-verb.patch
deleted file mode 100644 (file)
index 36aaa10..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-From: Benjamin Berg <benjamin.berg@open-mesh.com>
-Date: Mon, 4 Jul 2016 14:37:24 +0200
-Subject: [PATCH] ath9k: Remove some #defined constants to decrease
- verbosity
-
-The removed ATH9K_SLOT_TIME_X constants simply map the value in microseconds
-to the same integer. These constants were not used consistently, so fix the
-inconsistency issue by replacing all occurances with the integer equivalent.
-
-Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -50,7 +50,7 @@ static void ath9k_beaconq_config(struct
-               txq = sc->tx.txq_map[IEEE80211_AC_BE];
-               ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
-               qi.tqi_aifs = qi_be.tqi_aifs;
--              if (ah->slottime == ATH9K_SLOT_TIME_20)
-+              if (ah->slottime == 20)
-                       qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
-               else
-                       qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
---- a/drivers/net/wireless/ath/ath9k/dynack.c
-+++ b/drivers/net/wireless/ath/ath9k/dynack.c
-@@ -280,7 +280,7 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts);
- void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an)
- {
-       /* ackto = slottime + sifs + air delay */
--      u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64;
-+      u32 ackto = 9 + 16 + 64;
-       struct ath_dynack *da = &ah->dynack;
-       an->ackto = ackto;
-@@ -315,7 +315,7 @@ EXPORT_SYMBOL(ath_dynack_node_deinit);
- void ath_dynack_reset(struct ath_hw *ah)
- {
-       /* ackto = slottime + sifs + air delay */
--      u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64;
-+      u32 ackto = 9 + 16 + 64;
-       struct ath_dynack *da = &ah->dynack;
-       da->lto = jiffies;
---- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
-@@ -45,7 +45,7 @@ void ath9k_htc_beaconq_config(struct ath
-                * Long slot time  : 2x cwmin
-                * Short slot time : 4x cwmin
-                */
--              if (ah->slottime == ATH9K_SLOT_TIME_20)
-+              if (ah->slottime == 20)
-                       qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
-               else
-                       qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
---- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
-+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
-@@ -678,7 +678,7 @@ static int ath9k_init_priv(struct ath9k_
-       for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
-               priv->beacon.bslot[i] = NULL;
--      priv->beacon.slottime = ATH9K_SLOT_TIME_9;
-+      priv->beacon.slottime = 9;
-       ath9k_cmn_init_channels_rates(common);
-       ath9k_cmn_init_crypto(ah);
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -454,7 +454,7 @@ static void ath9k_hw_init_defaults(struc
-       if (AR_SREV_9100(ah))
-               ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
--      ah->slottime = ATH9K_SLOT_TIME_9;
-+      ah->slottime = 9;
-       ah->globaltxtimeout = (u32) -1;
-       ah->power_mode = ATH9K_PM_UNDEFINED;
-       ah->htc_reset_init = true;
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -372,7 +372,7 @@ static void ath9k_init_misc(struct ath_s
-       common->last_rssi = ATH_RSSI_DUMMY_MARKER;
-       memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
--      sc->beacon.slottime = ATH9K_SLOT_TIME_9;
-+      sc->beacon.slottime = 9;
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
-               sc->beacon.bslot[i] = NULL;
---- a/drivers/net/wireless/ath/ath9k/mac.h
-+++ b/drivers/net/wireless/ath/ath9k/mac.h
-@@ -65,10 +65,6 @@
- #define INIT_SSH_RETRY  32
- #define INIT_SLG_RETRY  32
--#define ATH9K_SLOT_TIME_6 6
--#define ATH9K_SLOT_TIME_9 9
--#define ATH9K_SLOT_TIME_20 20
--
- #define ATH9K_TXERR_XRETRY         0x01
- #define ATH9K_TXERR_FILT           0x02
- #define ATH9K_TXERR_FIFO           0x04
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -926,7 +926,7 @@ static void ath9k_vif_iter(struct ath9k_
-       }
-       if (!vif->bss_conf.use_short_slot)
--              iter_data->slottime = ATH9K_SLOT_TIME_20;
-+              iter_data->slottime = 20;
-       switch (vif->type) {
-       case NL80211_IFTYPE_AP:
-@@ -999,7 +999,7 @@ void ath9k_calculate_iter_data(struct at
-        */
-       memset(iter_data, 0, sizeof(*iter_data));
-       eth_broadcast_addr(iter_data->mask);
--      iter_data->slottime = ATH9K_SLOT_TIME_9;
-+      iter_data->slottime = 9;
-       list_for_each_entry(avp, &ctx->vifs, list)
-               ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif);
-@@ -1061,7 +1061,7 @@ static void ath9k_set_offchannel_state(s
-       ah->opmode = vif->type;
-       ah->imask &= ~ATH9K_INT_SWBA;
-       ah->imask &= ~ATH9K_INT_TSFOOR;
--      ah->slottime = ATH9K_SLOT_TIME_9;
-+      ah->slottime = 9;
-       ath_hw_setbssidmask(common);
-       ath9k_hw_setopmode(ah);
-@@ -1788,6 +1788,7 @@ static void ath9k_bss_info_changed(struc
-                       slottime = 9;
-               else
-                       slottime = 20;
-+
-               if (vif->type == NL80211_IFTYPE_AP) {
-                       /*
-                        * Defer update, so that connected stations can adjust
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
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/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch b/package/kernel/mac80211/patches/317-Revert-ath9k_hw-implement-temperature-compensation-s.patch
new file mode 100644 (file)
index 0000000..687df35
--- /dev/null
@@ -0,0 +1,101 @@
+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-ath9k-Fix-beacon-configuration-for-addition-removal-.patch b/package/kernel/mac80211/patches/317-ath9k-Fix-beacon-configuration-for-addition-removal-.patch
deleted file mode 100644 (file)
index 360dfbf..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-From: Benjamin Berg <benjamin.berg@open-mesh.com>
-Date: Mon, 4 Jul 2016 14:37:25 +0200
-Subject: [PATCH] ath9k: Fix beacon configuration for addition/removal of
- interfaces
-
-This patch fixes some issues with interface reconfiguration. It could
-for example happen that an AP interface in beacon slot 0 was removed
-leaving an IBSS station in one of the other slots. When this happens
-the driver never sends out the beacon as it only tries to send a beacon
-from slot 0.
-
-Appart from that the tracking of required changes to the beacon config is
-relatively complicated and prone to errors.
-
-The approach taken here is to solve reconfiguration issues is to
-reconfigure the beacons when any interface changes. This means that
-the complexity of deciding whether an interface change may modify the
-beacon configuration is gone. It also means that the beacon config will
-be reliably updated when an interface is removed.
-
-The issue that a single non-AP interface might not be in beacon
-slot 0 and wouldn't be send out is solved by moving it into the
-first slot. The TSF value in hardware is adjusted accordingly so
-that the timestamp of the beacons stay consistent.
-
-Signed-off-by: Benjamin Berg <benjamin.berg@open-mesh.com>
----
-
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -637,6 +637,8 @@ struct ath9k_vif_iter_data {
-       int nwds;      /* number of WDS vifs */
-       int nadhocs;   /* number of adhoc vifs */
-       int nocbs;     /* number of OCB vifs */
-+      int nbcnvifs;  /* number of beaconing vifs */
-+      struct ieee80211_vif *primary_beacon_vif;
-       struct ieee80211_vif *primary_sta;
- };
-@@ -685,10 +687,11 @@ struct ath_beacon {
- };
- void ath9k_beacon_tasklet(unsigned long data);
--void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
--                       u32 changed);
-+void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif,
-+                       bool beacons);
- void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
- void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
-+void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc);
- void ath9k_set_beacon(struct ath_softc *sc);
- bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif);
- void ath9k_csa_update(struct ath_softc *sc);
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -209,7 +209,6 @@ void ath9k_beacon_assign_slot(struct ath
-       }
-       sc->beacon.bslot[avp->av_bslot] = vif;
--      sc->nbcnvifs++;
-       ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n",
-               avp->av_bslot);
-@@ -220,15 +219,12 @@ void ath9k_beacon_remove_slot(struct ath
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-       struct ath_vif *avp = (void *)vif->drv_priv;
-       struct ath_buf *bf = avp->av_bcbuf;
--      struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
-       ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
-               avp->av_bslot);
-       tasklet_disable(&sc->bcon_tasklet);
--      cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
--
-       if (bf && bf->bf_mpdu) {
-               struct sk_buff *skb = bf->bf_mpdu;
-               dma_unmap_single(sc->dev, bf->bf_buf_addr,
-@@ -240,12 +236,73 @@ void ath9k_beacon_remove_slot(struct ath
-       avp->av_bcbuf = NULL;
-       sc->beacon.bslot[avp->av_bslot] = NULL;
--      sc->nbcnvifs--;
-       list_add_tail(&bf->list, &sc->beacon.bbuf);
-       tasklet_enable(&sc->bcon_tasklet);
- }
-+void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc)
-+{
-+      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-+      struct ieee80211_vif *vif;
-+      struct ath_vif *avp;
-+      s64 tsfadjust;
-+      u32 offset;
-+      int first_slot = ATH_BCBUF;
-+      int slot;
-+
-+      tasklet_disable(&sc->bcon_tasklet);
-+
-+      /* Find first taken slot. */
-+      for (slot = 0; slot < ATH_BCBUF; slot++) {
-+              if (sc->beacon.bslot[slot]) {
-+                      first_slot = slot;
-+                      break;
-+              }
-+      }
-+      if (first_slot == 0)
-+              goto out;
-+
-+      /* Re-enumarate all slots, moving them forward. */
-+      for (slot = 0; slot < ATH_BCBUF; slot++) {
-+              if (slot + first_slot < ATH_BCBUF) {
-+                      vif = sc->beacon.bslot[slot + first_slot];
-+                      sc->beacon.bslot[slot] = vif;
-+
-+                      if (vif) {
-+                              avp = (void *)vif->drv_priv;
-+                              avp->av_bslot = slot;
-+                      }
-+              } else {
-+                      sc->beacon.bslot[slot] = NULL;
-+              }
-+      }
-+
-+      vif = sc->beacon.bslot[0];
-+      if (WARN_ON(!vif))
-+              goto out;
-+
-+      /* Get the tsf_adjust value for the new first slot. */
-+      avp = (void *)vif->drv_priv;
-+      tsfadjust = le64_to_cpu(avp->tsf_adjust);
-+
-+      ath_dbg(common, CONFIG,
-+              "Adjusting global TSF after beacon slot reassignment: %lld\n",
-+              (signed long long)tsfadjust);
-+
-+      /* Modify TSF as required and update the HW. */
-+      avp->chanctx->tsf_val += tsfadjust;
-+      if (sc->cur_chan == avp->chanctx) {
-+              offset = ath9k_hw_get_tsf_offset(&avp->chanctx->tsf_ts, NULL);
-+              ath9k_hw_settsf64(sc->sc_ah, avp->chanctx->tsf_val + offset);
-+      }
-+
-+      /* The slots tsf_adjust will be updated by ath9k_beacon_config later. */
-+
-+out:
-+      tasklet_enable(&sc->bcon_tasklet);
-+}
-+
- static int ath9k_beacon_choose_slot(struct ath_softc *sc)
- {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-@@ -274,26 +331,33 @@ static int ath9k_beacon_choose_slot(stru
-       return slot;
- }
--static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
-+static void ath9k_set_tsfadjust(struct ath_softc *sc,
-+                              struct ath_beacon_config *cur_conf)
- {
-       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--      struct ath_vif *avp = (void *)vif->drv_priv;
--      struct ath_beacon_config *cur_conf = &avp->chanctx->beacon;
-       s64 tsfadjust;
-+      int slot;
--      if (avp->av_bslot == 0)
--              return;
-+      for (slot = 0; slot < ATH_BCBUF; slot++) {
-+              struct ath_vif *avp;
--      /* tsf_adjust is added to the TSF value. We send out the beacon late,
--       * so need to adjust the TSF starting point to be later in time (i.e.
--       * the theoretical first beacon has a TSF of 0 after correction).
--       */
--      tsfadjust = cur_conf->beacon_interval * avp->av_bslot;
--      tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF;
--      avp->tsf_adjust = cpu_to_le64(tsfadjust);
-+              if (!sc->beacon.bslot[slot])
-+                      continue;
--      ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n",
--              (signed long long)tsfadjust, avp->av_bslot);
-+              avp = (void *)sc->beacon.bslot[slot]->drv_priv;
-+
-+              /* tsf_adjust is added to the TSF value. We send out the
-+               * beacon late, so need to adjust the TSF starting point to be
-+               * later in time (i.e. the theoretical first beacon has a TSF
-+               * of 0 after correction).
-+               */
-+              tsfadjust = cur_conf->beacon_interval * avp->av_bslot;
-+              tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF;
-+              avp->tsf_adjust = cpu_to_le64(tsfadjust);
-+
-+              ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n",
-+                      (signed long long)tsfadjust, avp->av_bslot);
-+      }
- }
- bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif)
-@@ -447,20 +511,28 @@ void ath9k_beacon_tasklet(unsigned long
-  * Both nexttbtt and intval have to be in usecs.
-  */
- static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
--                            u32 intval, bool reset_tsf)
-+                            u32 intval)
- {
-       struct ath_hw *ah = sc->sc_ah;
-       ath9k_hw_disable_interrupts(ah);
--      if (reset_tsf)
--              ath9k_hw_reset_tsf(ah);
-       ath9k_beaconq_config(sc);
-       ath9k_hw_beaconinit(ah, nexttbtt, intval);
-+      ah->imask |= ATH9K_INT_SWBA;
-       sc->beacon.bmisscnt = 0;
-       ath9k_hw_set_interrupts(ah);
-       ath9k_hw_enable_interrupts(ah);
- }
-+static void ath9k_beacon_stop(struct ath_softc *sc)
-+{
-+      ath9k_hw_disable_interrupts(sc->sc_ah);
-+      sc->sc_ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-+      sc->beacon.bmisscnt = 0;
-+      ath9k_hw_set_interrupts(sc->sc_ah);
-+      ath9k_hw_enable_interrupts(sc->sc_ah);
-+}
-+
- /*
-  * For multi-bss ap support beacons are either staggered evenly over N slots or
-  * burst together.  For the former arrange for the SWBA to be delivered for each
-@@ -472,7 +544,7 @@ static void ath9k_beacon_config_ap(struc
-       struct ath_hw *ah = sc->sc_ah;
-       ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF);
--      ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, false);
-+      ath9k_beacon_init(sc, conf->nexttbtt, conf->intval);
- }
- static void ath9k_beacon_config_sta(struct ath_hw *ah,
-@@ -501,7 +573,7 @@ static void ath9k_beacon_config_adhoc(st
-       ath9k_cmn_beacon_config_adhoc(ah, conf);
--      ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, conf->ibss_creator);
-+      ath9k_beacon_init(sc, conf->nexttbtt, conf->intval);
-       /*
-        * Set the global 'beacon has been configured' flag for the
-@@ -511,44 +583,6 @@ static void ath9k_beacon_config_adhoc(st
-               set_bit(ATH_OP_BEACONS, &common->op_flags);
- }
--static bool ath9k_allow_beacon_config(struct ath_softc *sc,
--                                    struct ieee80211_vif *vif)
--{
--      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
--      struct ath_vif *avp = (void *)vif->drv_priv;
--
--      if (ath9k_is_chanctx_enabled()) {
--              /*
--               * If the VIF is not present in the current channel context,
--               * then we can't do the usual opmode checks. Allow the
--               * beacon config for the VIF to be updated in this case and
--               * return immediately.
--               */
--              if (sc->cur_chan != avp->chanctx)
--                      return true;
--      }
--
--      if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
--              if (vif->type != NL80211_IFTYPE_AP) {
--                      ath_dbg(common, CONFIG,
--                              "An AP interface is already present !\n");
--                      return false;
--              }
--      }
--
--      if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
--              if ((vif->type == NL80211_IFTYPE_STATION) &&
--                  test_bit(ATH_OP_BEACONS, &common->op_flags) &&
--                  vif != sc->cur_chan->primary_sta) {
--                      ath_dbg(common, CONFIG,
--                              "Beacon already configured for a station interface\n");
--                      return false;
--              }
--      }
--
--      return true;
--}
--
- static void ath9k_cache_beacon_config(struct ath_softc *sc,
-                                     struct ath_chanctx *ctx,
-                                     struct ieee80211_bss_conf *bss_conf)
-@@ -584,87 +618,79 @@ static void ath9k_cache_beacon_config(st
-       if (cur_conf->dtim_period == 0)
-               cur_conf->dtim_period = 1;
-+      ath9k_set_tsfadjust(sc, cur_conf);
- }
--void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
--                       u32 changed)
-+void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif,
-+                       bool beacons)
- {
--      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
--        struct ath_hw *ah = sc->sc_ah;
--        struct ath_common *common = ath9k_hw_common(ah);
--      struct ath_vif *avp = (void *)vif->drv_priv;
--      struct ath_chanctx *ctx = avp->chanctx;
-+      struct ath_hw *ah = sc->sc_ah;
-+      struct ath_common *common = ath9k_hw_common(ah);
-+      struct ath_vif *avp;
-+      struct ath_chanctx *ctx;
-       struct ath_beacon_config *cur_conf;
-       unsigned long flags;
-+      bool enabled;
-       bool skip_beacon = false;
--      if (!ctx)
-+      if (!beacons) {
-+              clear_bit(ATH_OP_BEACONS, &common->op_flags);
-+              ath9k_beacon_stop(sc);
-               return;
-+      }
--      cur_conf = &avp->chanctx->beacon;
--      if (vif->type == NL80211_IFTYPE_AP)
--              ath9k_set_tsfadjust(sc, vif);
--
--      if (!ath9k_allow_beacon_config(sc, vif))
-+      if (WARN_ON(!main_vif))
-               return;
--      if (vif->type == NL80211_IFTYPE_STATION) {
--              ath9k_cache_beacon_config(sc, ctx, bss_conf);
--              if (ctx != sc->cur_chan)
--                      return;
-+      avp = (void *)main_vif->drv_priv;
-+      ctx = avp->chanctx;
-+      cur_conf = &ctx->beacon;
-+      enabled = cur_conf->enable_beacon;
-+      cur_conf->enable_beacon = beacons;
-+
-+      if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
-+              ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf);
-               ath9k_set_beacon(sc);
-               set_bit(ATH_OP_BEACONS, &common->op_flags);
-               return;
-       }
--      /*
--       * Take care of multiple interfaces when
--       * enabling/disabling SWBA.
--       */
--      if (changed & BSS_CHANGED_BEACON_ENABLED) {
--              bool enabled = cur_conf->enable_beacon;
--
--              if (!bss_conf->enable_beacon) {
--                      cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
--              } else {
--                      cur_conf->enable_beacon |= BIT(avp->av_bslot);
--                      if (!enabled)
--                              ath9k_cache_beacon_config(sc, ctx, bss_conf);
--              }
--      }
--
--      if (ctx != sc->cur_chan)
--              return;
-+      /* Update the beacon configuration. */
-+      ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf);
-       /*
-        * Configure the HW beacon registers only when we have a valid
-        * beacon interval.
-        */
-       if (cur_conf->beacon_interval) {
--              /*
--               * If we are joining an existing IBSS network, start beaconing
--               * only after a TSF-sync has taken place. Ensure that this
--               * happens by setting the appropriate flags.
-+              /* Special case to sync the TSF when joining an existing IBSS.
-+               * This is only done if no AP interface is active.
-+               * Note that mac80211 always resets the TSF when creating a new
-+               * IBSS interface.
-                */
--              if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator &&
--                  bss_conf->enable_beacon) {
-+              if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC &&
-+                  !enabled && beacons && !main_vif->bss_conf.ibss_creator) {
-                       spin_lock_irqsave(&sc->sc_pm_lock, flags);
-                       sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
-                       spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
-                       skip_beacon = true;
--              } else {
--                      ath9k_set_beacon(sc);
-               }
-               /*
-                * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode
-                * here, it is done in ath9k_beacon_config_adhoc().
-                */
--              if (cur_conf->enable_beacon && !skip_beacon)
-+              if (beacons && !skip_beacon) {
-                       set_bit(ATH_OP_BEACONS, &common->op_flags);
--              else
-+                      ath9k_set_beacon(sc);
-+              } else {
-                       clear_bit(ATH_OP_BEACONS, &common->op_flags);
-+                      ath9k_beacon_stop(sc);
-+              }
-+      } else {
-+              clear_bit(ATH_OP_BEACONS, &common->op_flags);
-+              ath9k_beacon_stop(sc);
-       }
- }
---- a/drivers/net/wireless/ath/ath9k/common.h
-+++ b/drivers/net/wireless/ath/ath9k/common.h
-@@ -50,6 +50,7 @@
- #define IEEE80211_MS_TO_TU(x)   (((x) * 1000) / 1024)
- struct ath_beacon_config {
-+      struct ieee80211_vif *main_vif;
-       int beacon_interval;
-       u16 dtim_period;
-       u16 bmiss_timeout;
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -910,6 +910,22 @@ static bool ath9k_uses_beacons(int type)
-       }
- }
-+static void ath9k_vif_iter_set_beacon(struct ath9k_vif_iter_data *iter_data,
-+                                    struct ieee80211_vif *vif)
-+{
-+      /* Use the first (configured) interface, but prefering AP interfaces. */
-+      if (!iter_data->primary_beacon_vif) {
-+              iter_data->primary_beacon_vif = vif;
-+      } else {
-+              if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP &&
-+                  vif->type == NL80211_IFTYPE_AP)
-+              iter_data->primary_beacon_vif = vif;
-+      }
-+
-+      iter_data->beacons = true;
-+      iter_data->nbcnvifs += 1;
-+}
-+
- static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
-                          u8 *mac, struct ieee80211_vif *vif)
- {
-@@ -931,6 +947,8 @@ static void ath9k_vif_iter(struct ath9k_
-       switch (vif->type) {
-       case NL80211_IFTYPE_AP:
-               iter_data->naps++;
-+              if (vif->bss_conf.enable_beacon)
-+                      ath9k_vif_iter_set_beacon(iter_data, vif);
-               break;
-       case NL80211_IFTYPE_STATION:
-               iter_data->nstations++;
-@@ -943,12 +961,12 @@ static void ath9k_vif_iter(struct ath9k_
-       case NL80211_IFTYPE_ADHOC:
-               iter_data->nadhocs++;
-               if (vif->bss_conf.enable_beacon)
--                      iter_data->beacons = true;
-+                      ath9k_vif_iter_set_beacon(iter_data, vif);
-               break;
-       case NL80211_IFTYPE_MESH_POINT:
-               iter_data->nmeshes++;
-               if (vif->bss_conf.enable_beacon)
--                      iter_data->beacons = true;
-+                      ath9k_vif_iter_set_beacon(iter_data, vif);
-               break;
-       case NL80211_IFTYPE_WDS:
-               iter_data->nwds++;
-@@ -1081,7 +1099,6 @@ void ath9k_calculate_summary_state(struc
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_common *common = ath9k_hw_common(ah);
-       struct ath9k_vif_iter_data iter_data;
--      struct ath_beacon_config *cur_conf;
-       ath_chanctx_check_active(sc, ctx);
-@@ -1103,13 +1120,12 @@ void ath9k_calculate_summary_state(struc
-       ath_hw_setbssidmask(common);
-       if (iter_data.naps > 0) {
--              cur_conf = &ctx->beacon;
-               ath9k_hw_set_tsfadjust(ah, true);
-               ah->opmode = NL80211_IFTYPE_AP;
--              if (cur_conf->enable_beacon)
--                      iter_data.beacons = true;
-       } else {
-               ath9k_hw_set_tsfadjust(ah, false);
-+              if (iter_data.beacons)
-+                      ath9k_beacon_ensure_primary_slot(sc);
-               if (iter_data.nmeshes)
-                       ah->opmode = NL80211_IFTYPE_MESH_POINT;
-@@ -1134,7 +1150,6 @@ void ath9k_calculate_summary_state(struc
-                       ctx->switch_after_beacon = true;
-       }
--      ah->imask &= ~ATH9K_INT_SWBA;
-       if (ah->opmode == NL80211_IFTYPE_STATION) {
-               bool changed = (iter_data.primary_sta != ctx->primary_sta);
-@@ -1151,16 +1166,12 @@ void ath9k_calculate_summary_state(struc
-                       if (ath9k_hw_mci_is_enabled(sc->sc_ah))
-                               ath9k_mci_update_wlan_channels(sc, true);
-               }
--      } else if (iter_data.beacons) {
--              ah->imask |= ATH9K_INT_SWBA;
-       }
-+      sc->nbcnvifs = iter_data.nbcnvifs;
-+      ath9k_beacon_config(sc, iter_data.primary_beacon_vif,
-+                          iter_data.beacons);
-       ath9k_hw_set_interrupts(ah);
--      if (iter_data.beacons)
--              set_bit(ATH_OP_BEACONS, &common->op_flags);
--      else
--              clear_bit(ATH_OP_BEACONS, &common->op_flags);
--
-       if (ah->slottime != iter_data.slottime) {
-               ah->slottime = iter_data.slottime;
-               ath9k_hw_init_global_settings(ah);
-@@ -1777,9 +1788,7 @@ static void ath9k_bss_info_changed(struc
-       if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
-           (changed & BSS_CHANGED_BEACON_INT) ||
-           (changed & BSS_CHANGED_BEACON_INFO)) {
--              ath9k_beacon_config(sc, vif, changed);
--              if (changed & BSS_CHANGED_BEACON_ENABLED)
--                      ath9k_calculate_summary_state(sc, avp->chanctx);
-+              ath9k_calculate_summary_state(sc, avp->chanctx);
-       }
-       if ((avp->chanctx == sc->cur_chan) &&
diff --git a/package/kernel/mac80211/patches/318-brcmfmac-slightly-simplify-building-interface-combin.patch b/package/kernel/mac80211/patches/318-brcmfmac-slightly-simplify-building-interface-combin.patch
deleted file mode 100644 (file)
index d946ecc..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Tue, 7 Jun 2016 21:10:18 +0200
-Subject: [PATCH] brcmfmac: slightly simplify building interface combinations
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This change reorders some operations in brcmf_setup_ifmodes in hope to
-make it simpler:
-1) It allocates arrays right before filling them. This way it's easier
-   to follow requested array length as it's immediately followed by
-   code filling it. It's easier to check e.g. why we need 4 entries for
-   P2P. Other than that it deduplicates some checks (e.g. for P2P).
-2) It reorders code to first prepare limits and then define a new combo.
-   Previously this was mixed (e.g. we were setting num of channels
-   before preparing limits).
-3) It modifies mbss code to use i variable just like other combos do.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -6284,29 +6284,15 @@ static int brcmf_setup_ifmodes(struct wi
-       if (!combo)
-               goto err;
--      c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
--      if (!c0_limits)
--              goto err;
--
--      if (p2p) {
--              p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
--              if (!p2p_limits)
--                      goto err;
--      }
--
--      if (mbss) {
--              mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
--              if (!mbss_limits)
--                      goto err;
--      }
--
-       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-                                BIT(NL80211_IFTYPE_ADHOC) |
-                                BIT(NL80211_IFTYPE_AP);
-       c = 0;
-       i = 0;
--      combo[c].num_different_channels = 1;
-+      c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
-+      if (!c0_limits)
-+              goto err;
-       c0_limits[i].max = 1;
-       c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
-       if (p2p) {
-@@ -6324,6 +6310,7 @@ static int brcmf_setup_ifmodes(struct wi
-               c0_limits[i].max = 1;
-               c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
-       }
-+      combo[c].num_different_channels = 1;
-       combo[c].max_interfaces = i;
-       combo[c].n_limits = i;
-       combo[c].limits = c0_limits;
-@@ -6331,7 +6318,9 @@ static int brcmf_setup_ifmodes(struct wi
-       if (p2p) {
-               c++;
-               i = 0;
--              combo[c].num_different_channels = 1;
-+              p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
-+              if (!p2p_limits)
-+                      goto err;
-               p2p_limits[i].max = 1;
-               p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
-               p2p_limits[i].max = 1;
-@@ -6340,6 +6329,7 @@ static int brcmf_setup_ifmodes(struct wi
-               p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
-               p2p_limits[i].max = 1;
-               p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
-+              combo[c].num_different_channels = 1;
-               combo[c].max_interfaces = i;
-               combo[c].n_limits = i;
-               combo[c].limits = p2p_limits;
-@@ -6347,14 +6337,19 @@ static int brcmf_setup_ifmodes(struct wi
-       if (mbss) {
-               c++;
-+              i = 0;
-+              mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
-+              if (!mbss_limits)
-+                      goto err;
-+              mbss_limits[i].max = 4;
-+              mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
-               combo[c].beacon_int_infra_match = true;
-               combo[c].num_different_channels = 1;
--              mbss_limits[0].max = 4;
--              mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
-               combo[c].max_interfaces = 4;
--              combo[c].n_limits = 1;
-+              combo[c].n_limits = i;
-               combo[c].limits = mbss_limits;
-       }
-+
-       wiphy->n_iface_combinations = n_combos;
-       wiphy->iface_combinations = combo;
-       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
new file mode 100644 (file)
index 0000000..2e742e4
--- /dev/null
@@ -0,0 +1,35 @@
+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-0001-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch b/package/kernel/mac80211/patches/319-0001-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch
deleted file mode 100644 (file)
index 073d012..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Fri, 17 Jun 2016 12:29:21 +0200
-Subject: [PATCH] brcmfmac: fix lockup when removing P2P interface after
- event timeout
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Removing P2P interface is handled by sending a proper request to the
-firmware. On success firmware triggers an event and driver's handler
-removes a matching interface.
-
-However on event timeout we remove interface directly from the cfg80211
-callback. Current code doesn't handle this case correctly as it always
-assumes rtnl to be unlocked.
-
-Fix it by adding an extra rtnl_locked parameter to functions and calling
-unregister_netdevice when needed.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -548,12 +548,16 @@ fail:
-       return -EBADE;
- }
--static void brcmf_net_detach(struct net_device *ndev)
-+static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
- {
--      if (ndev->reg_state == NETREG_REGISTERED)
--              unregister_netdev(ndev);
--      else
-+      if (ndev->reg_state == NETREG_REGISTERED) {
-+              if (rtnl_locked)
-+                      unregister_netdevice(ndev);
-+              else
-+                      unregister_netdev(ndev);
-+      } else {
-               brcmf_cfg80211_free_netdev(ndev);
-+      }
- }
- void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
-@@ -651,7 +655,7 @@ struct brcmf_if *brcmf_add_if(struct brc
-                       brcmf_err("ERROR: netdev:%s already exists\n",
-                                 ifp->ndev->name);
-                       netif_stop_queue(ifp->ndev);
--                      brcmf_net_detach(ifp->ndev);
-+                      brcmf_net_detach(ifp->ndev, false);
-                       drvr->iflist[bsscfgidx] = NULL;
-               } else {
-                       brcmf_dbg(INFO, "netdev:%s ignore IF event\n",
-@@ -699,7 +703,8 @@ struct brcmf_if *brcmf_add_if(struct brc
-       return ifp;
- }
--static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx)
-+static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx,
-+                       bool rtnl_locked)
- {
-       struct brcmf_if *ifp;
-@@ -729,7 +734,7 @@ static void brcmf_del_if(struct brcmf_pu
-                       cancel_work_sync(&ifp->multicast_work);
-                       cancel_work_sync(&ifp->ndoffload_work);
-               }
--              brcmf_net_detach(ifp->ndev);
-+              brcmf_net_detach(ifp->ndev, rtnl_locked);
-       } else {
-               /* Only p2p device interfaces which get dynamically created
-                * end up here. In this case the p2p module should be informed
-@@ -743,14 +748,14 @@ static void brcmf_del_if(struct brcmf_pu
-       }
- }
--void brcmf_remove_interface(struct brcmf_if *ifp)
-+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked)
- {
-       if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp))
-               return;
-       brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,
-                 ifp->ifidx);
-       brcmf_fws_del_interface(ifp);
--      brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
-+      brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
- }
- #ifdef CONFIG_INET
-@@ -1057,9 +1062,9 @@ fail:
-               brcmf_fws_deinit(drvr);
-       }
-       if (ifp)
--              brcmf_net_detach(ifp->ndev);
-+              brcmf_net_detach(ifp->ndev, false);
-       if (p2p_ifp)
--              brcmf_net_detach(p2p_ifp->ndev);
-+              brcmf_net_detach(p2p_ifp->ndev, false);
-       drvr->iflist[0] = NULL;
-       drvr->iflist[1] = NULL;
-       if (drvr->settings->ignore_probe_fail)
-@@ -1128,7 +1133,7 @@ void brcmf_detach(struct device *dev)
-       /* make sure primary interface removed last */
-       for (i = BRCMF_MAX_IFS-1; i > -1; i--)
--              brcmf_remove_interface(drvr->iflist[i]);
-+              brcmf_remove_interface(drvr->iflist[i], false);
-       brcmf_cfg80211_detach(drvr->config);
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
-@@ -216,7 +216,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
- int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
-                             bool is_p2pdev, char *name, u8 *mac_addr);
--void brcmf_remove_interface(struct brcmf_if *ifp);
-+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);
- void brcmf_txflowblock_if(struct brcmf_if *ifp,
-                         enum brcmf_netif_stop_reason reason, bool state);
- void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
-@@ -183,7 +183,7 @@ static void brcmf_fweh_handle_if_event(s
-       err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
-       if (ifp && ifevent->action == BRCMF_E_IF_DEL)
--              brcmf_remove_interface(ifp);
-+              brcmf_remove_interface(ifp, false);
- }
- /**
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
-@@ -2289,7 +2289,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
-                       err = 0;
-       }
-       if (err)
--              brcmf_remove_interface(vif->ifp);
-+              brcmf_remove_interface(vif->ifp, true);
-       brcmf_cfg80211_arm_vif_event(cfg, NULL);
-       if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
-@@ -2395,7 +2395,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i
-       if (vif != NULL) {
-               brcmf_p2p_cancel_remain_on_channel(vif->ifp);
-               brcmf_p2p_deinit_discovery(p2p);
--              brcmf_remove_interface(vif->ifp);
-+              brcmf_remove_interface(vif->ifp, false);
-       }
-       /* just set it all to zero */
-       memset(p2p, 0, sizeof(*p2p));
diff --git a/package/kernel/mac80211/patches/319-0002-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch b/package/kernel/mac80211/patches/319-0002-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch
deleted file mode 100644 (file)
index 6d3f3c6..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Fri, 17 Jun 2016 12:48:44 +0200
-Subject: [PATCH] brcmfmac: use const char * for interface name in
- brcmf_add_if
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This function can work just fine with const pointer, it only calls
-alloc_netdev which take const as well. Moreover it makes this function
-more flexible as some cfg80211 callback may provide const char * as
-well, e.g. add_virtual_intf. This will be needed for more advanced
-interface management.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -638,7 +638,7 @@ fail:
- }
- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
--                            bool is_p2pdev, char *name, u8 *mac_addr)
-+                            bool is_p2pdev, const char *name, u8 *mac_addr)
- {
-       struct brcmf_if *ifp;
-       struct net_device *ndev;
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
-@@ -215,7 +215,7 @@ char *brcmf_ifname(struct brcmf_if *ifp)
- struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
- int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
--                            bool is_p2pdev, char *name, u8 *mac_addr);
-+                            bool is_p2pdev, const char *name, u8 *mac_addr);
- void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);
- void brcmf_txflowblock_if(struct brcmf_if *ifp,
-                         enum brcmf_netif_stop_reason reason, bool state);
diff --git a/package/kernel/mac80211/patches/319-0003-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch b/package/kernel/mac80211/patches/319-0003-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch
deleted file mode 100644 (file)
index eeda766..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Sat, 18 Jun 2016 18:49:38 +0200
-Subject: [PATCH] brcmfmac: include also core.h header in cfg80211.h
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This header provides two inline functions using struct brcmf_if so we
-need core.h to avoid:
-
-drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_prof’:
-drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:368:13: error: dereferencing pointer to incomplete type
-  return &ifp->vif->profile;
-             ^
-drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_vif’:
-drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:374:12: error: dereferencing pointer to incomplete type
-  return ifp->vif;
-            ^
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
-@@ -20,6 +20,7 @@
- /* for brcmu_d11inf */
- #include <brcmu_d11.h>
-+#include "core.h"
- #include "fwil_types.h"
- #include "p2p.h"
diff --git a/package/kernel/mac80211/patches/319-0004-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch b/package/kernel/mac80211/patches/319-0004-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch
deleted file mode 100644 (file)
index 3819248..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Sun, 19 Jun 2016 01:55:57 +0200
-Subject: [PATCH] brcmfmac: add missing break when deleting P2P_DEVICE
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-We obviously don't want to fall through in that switch. With this change
-1) We wait for event (triggered by p2p_disc) as expected
-2) We remove interface manually on timeout
-3) We return 0 on success instead of -ENOTSUPP
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
-@@ -2263,6 +2263,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
-                       return 0;
-               brcmf_p2p_cancel_remain_on_channel(vif->ifp);
-               brcmf_p2p_deinit_discovery(p2p);
-+              break;
-+
-       default:
-               return -ENOTSUPP;
-       }
diff --git a/package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch b/package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch
deleted file mode 100644 (file)
index 12d7eb4..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Wed, 29 Jun 2016 21:54:26 +0200
-Subject: [PATCH] brcmfmac: delete interface directly in code that sent fw
- request
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-So far when receiving event about in-firmware-interface removal our
-event worker was notifying listener and afterwards it was removing Linux
-interface.
-
-First of all it was resulting in slightly unexpected order. The listener
-(del_virtual_intf callback) was (usually) returning with success before
-we even called unregister_netdev(ice).
-
-Please note this couldn't be simply fixed by changing order of calls in
-brcmf_fweh_handle_if_event as unregistering interface earlier could free
-struct brcmf_if.
-
-Another problem of current implementation are possible lockups. Focus on
-the time slot between calling event handler and removing Linux
-interface. During that time original caller may leave (unlocking rtnl
-semaphore) *and* another call to the same code may be done (locking it
-again). If that happens our event handler will stuck at removing Linux
-interface, it won't handle another event and will block process holding
-rtnl lock.
-
-This can be simply solved by unregistering interface in a proper
-callback, right after receiving confirmation event from firmware. This
-only required modifying worker to don't unregister on its own if there
-is someone waiting for the event.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
-@@ -18,6 +18,7 @@
- #include "brcmu_wifi.h"
- #include "brcmu_utils.h"
-+#include "cfg80211.h"
- #include "core.h"
- #include "debug.h"
- #include "tracepoint.h"
-@@ -182,8 +183,13 @@ static void brcmf_fweh_handle_if_event(s
-       err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
--      if (ifp && ifevent->action == BRCMF_E_IF_DEL)
--              brcmf_remove_interface(ifp, false);
-+      if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
-+              bool armed = brcmf_cfg80211_vif_event_armed(drvr->config);
-+
-+              /* Default handling in case no-one waits for this event */
-+              if (!armed)
-+                      brcmf_remove_interface(ifp, false);
-+      }
- }
- /**
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
-@@ -2290,8 +2290,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
-               else
-                       err = 0;
-       }
--      if (err)
--              brcmf_remove_interface(vif->ifp, true);
-+      brcmf_remove_interface(vif->ifp, true);
-       brcmf_cfg80211_arm_vif_event(cfg, NULL);
-       if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
diff --git a/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch b/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch
deleted file mode 100644 (file)
index 2f7165e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Wed, 29 Jun 2016 21:54:27 +0200
-Subject: [PATCH] brcmfmac: support removing AP interfaces with
- "interface_remove"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove"
-for removing interfaces. Try to use this method on cfg80211 request. In
-case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this
-will just result in firmware rejecting command and this won't change any
-behavior.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -785,12 +785,48 @@ s32 brcmf_notify_escan_complete(struct b
-       return err;
- }
-+static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
-+                                     struct wireless_dev *wdev)
-+{
-+      struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
-+      struct net_device *ndev = wdev->netdev;
-+      struct brcmf_if *ifp = netdev_priv(ndev);
-+      int ret;
-+      int err;
-+
-+      brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
-+
-+      err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
-+      if (err) {
-+              brcmf_err("interface_remove failed %d\n", err);
-+              goto err_unarm;
-+      }
-+
-+      /* wait for firmware event */
-+      ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
-+                                          BRCMF_VIF_EVENT_TIMEOUT);
-+      if (!ret) {
-+              brcmf_err("timeout occurred\n");
-+              err = -EIO;
-+              goto err_unarm;
-+      }
-+
-+      brcmf_remove_interface(ifp, true);
-+
-+err_unarm:
-+      brcmf_cfg80211_arm_vif_event(cfg, NULL);
-+      return err;
-+}
-+
- static
- int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
- {
-       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
-       struct net_device *ndev = wdev->netdev;
-+      if (ndev && ndev == cfg_to_ndev(cfg))
-+              return -ENOTSUPP;
-+
-       /* vif event pending in firmware */
-       if (brcmf_cfg80211_vif_event_armed(cfg))
-               return -EBUSY;
-@@ -807,12 +843,13 @@ int brcmf_cfg80211_del_iface(struct wiph
-       switch (wdev->iftype) {
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_STATION:
--      case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_AP_VLAN:
-       case NL80211_IFTYPE_WDS:
-       case NL80211_IFTYPE_MONITOR:
-       case NL80211_IFTYPE_MESH_POINT:
-               return -EOPNOTSUPP;
-+      case NL80211_IFTYPE_AP:
-+              return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
-       case NL80211_IFTYPE_P2P_CLIENT:
-       case NL80211_IFTYPE_P2P_GO:
-       case NL80211_IFTYPE_P2P_DEVICE:
diff --git a/package/kernel/mac80211/patches/319-0007-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch b/package/kernel/mac80211/patches/319-0007-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch
deleted file mode 100644 (file)
index 26721d6..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From c940de10d45efc5664ee993a6da281f45c804e59 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Wed, 6 Jul 2016 12:22:54 +0200
-Subject: [PATCH] brcmfmac: respect hidden_ssid for AP interfaces
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This was succesfully tested with 4366B1. A small workaround is needed
-for the main interface otherwise it would stuck at the hidden state.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -4662,6 +4662,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
-                       brcmf_err("SET SSID error (%d)\n", err);
-                       goto exit;
-               }
-+
-+              if (settings->hidden_ssid) {
-+                      err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
-+                      if (err) {
-+                              brcmf_err("closednet error (%d)\n", err);
-+                              goto exit;
-+                      }
-+              }
-+
-               brcmf_dbg(TRACE, "AP mode configuration complete\n");
-       } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
-               err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
-@@ -4720,6 +4729,10 @@ static int brcmf_cfg80211_stop_ap(struct
-                       return err;
-               }
-+              /* First BSS doesn't get a full reset */
-+              if (ifp->bsscfgidx == 0)
-+                      brcmf_fil_iovar_int_set(ifp, "closednet", 0);
-+
-               memset(&join_params, 0, sizeof(join_params));
-               err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
-                                            &join_params, sizeof(join_params));
diff --git a/package/kernel/mac80211/patches/319-0008-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch b/package/kernel/mac80211/patches/319-0008-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch
deleted file mode 100644 (file)
index 740f84e..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-From 82bc9ab6a8f577d2174a736c33f3d4ecf7d9ef47 Mon Sep 17 00:00:00 2001
-From: Arend Van Spriel <arend.vanspriel@broadcom.com>
-Date: Fri, 15 Jul 2016 12:16:12 +0200
-Subject: [PATCH] brcmfmac: restore stopping netdev queue when bus clogs up
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When the host-interface bus has hard time handling transmit packets
-it informs higher layer about this and it would stop the netdev
-queue when needed. However, since commit 9cd18359d31e ("brcmfmac:
-Make FWS queueing configurable.") this was broken. With this patch
-the behaviour is restored.
-
-Cc: stable@vger.kernel.org # v4.5, v4.6, v4.7
-Fixes: 9cd18359d31e ("brcmfmac: Make FWS queueing configurable.")
-Tested-by: Per Förlin <per.forlin@gmail.com>
-Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
-Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
-Reviewed-by: Franky Lin <franky.lin@broadcom.com>
-Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- .../broadcom/brcm80211/brcmfmac/fwsignal.c         | 22 +++++++++++++++++-----
- 1 file changed, 17 insertions(+), 5 deletions(-)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
-@@ -2469,10 +2469,22 @@ void brcmf_fws_bustxfail(struct brcmf_fw
- void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked)
- {
-       struct brcmf_fws_info *fws = drvr->fws;
-+      struct brcmf_if *ifp;
-+      int i;
--      fws->bus_flow_blocked = flow_blocked;
--      if (!flow_blocked)
--              brcmf_fws_schedule_deq(fws);
--      else
--              fws->stats.bus_flow_block++;
-+      if (fws->avoid_queueing) {
-+              for (i = 0; i < BRCMF_MAX_IFS; i++) {
-+                      ifp = drvr->iflist[i];
-+                      if (!ifp || !ifp->ndev)
-+                              continue;
-+                      brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW,
-+                                           flow_blocked);
-+              }
-+      } else {
-+              fws->bus_flow_blocked = flow_blocked;
-+              if (!flow_blocked)
-+                      brcmf_fws_schedule_deq(fws);
-+              else
-+                      fws->stats.bus_flow_block++;
-+      }
- }
diff --git a/package/kernel/mac80211/patches/319-0009-brcmfmac-defer-DPC-processing-during-probe.patch b/package/kernel/mac80211/patches/319-0009-brcmfmac-defer-DPC-processing-during-probe.patch
deleted file mode 100644 (file)
index 2fbf5e3..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-From fd3ed33f51c2a586412d35b4f64803f019ab589f Mon Sep 17 00:00:00 2001
-From: Arend Van Spriel <arend.vanspriel@broadcom.com>
-Date: Fri, 15 Jul 2016 12:39:13 +0200
-Subject: [PATCH] brcmfmac: defer DPC processing during probe
-
-The sdio dpc starts processing when in SDIOD_STATE_DATA. This state was
-entered right after firmware download. This patch moves that transition
-just before enabling sdio interrupt handling thus avoiding watchdog
-expiry which would put the bus to sleep while probing.
-
-Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
-Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
-Reviewed-by: Franky Lin <franky.lin@broadcom.com>
-Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
-@@ -3305,10 +3305,6 @@ static int brcmf_sdio_download_firmware(
-               goto err;
-       }
--      /* Allow full data communication using DPC from now on. */
--      brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
--      bcmerror = 0;
--
- err:
-       brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
-       sdio_release_host(bus->sdiodev->func[1]);
-@@ -4046,6 +4042,9 @@ static void brcmf_sdio_firmware_callback
-       }
-       if (err == 0) {
-+              /* Allow full data communication using DPC from now on. */
-+              brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
-+
-               err = brcmf_sdiod_intr_register(sdiodev);
-               if (err != 0)
-                       brcmf_err("intr register failed:%d\n", err);
diff --git a/package/kernel/mac80211/patches/319-0010-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch b/package/kernel/mac80211/patches/319-0010-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch
deleted file mode 100644 (file)
index c33aa2d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3bdae810721b33061d2e541bd78a70f86ca42af3 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Mon, 18 Jul 2016 16:24:34 -0700
-Subject: [PATCH] brcmfmac: Fix glob_skb leak in brcmf_sdiod_recv_chain
-
-In case brcmf_sdiod_recv_chain() cannot complete a succeful call to
-brcmf_sdiod_buffrw, we would be leaking glom_skb and not free it as we
-should, fix this.
-
-Reported-by: coverity (CID 1164856)
-Fixes: a413e39a38573 ("brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support")
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
- drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
-+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
-@@ -726,8 +726,10 @@ int brcmf_sdiod_recv_chain(struct brcmf_
-                       return -ENOMEM;
-               err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
-                                        glom_skb);
--              if (err)
-+              if (err) {
-+                      brcmu_pkt_buf_free_skb(glom_skb);
-                       goto done;
-+              }
-               skb_queue_walk(pktq, skb) {
-                       memcpy(skb->data, glom_skb->data, skb->len);
diff --git a/package/kernel/mac80211/patches/319-0011-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch b/package/kernel/mac80211/patches/319-0011-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch
deleted file mode 100644 (file)
index