diff options
Diffstat (limited to 'package/mac80211/patches/.svn/text-base')
81 files changed, 6307 insertions, 0 deletions
diff --git a/package/mac80211/patches/.svn/text-base/001-disable_rfkill.patch.svn-base b/package/mac80211/patches/.svn/text-base/001-disable_rfkill.patch.svn-base new file mode 100644 index 0000000..7af485f --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/001-disable_rfkill.patch.svn-base @@ -0,0 +1,13 @@ +--- a/include/linux/rfkill.h ++++ b/include/linux/rfkill.h +@@ -3,6 +3,10 @@ + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) + ++#undef CONFIG_RFKILL ++#undef CONFIG_RFKILL_LEDS ++#undef CONFIG_RFKILL_MODULE ++ + #include_next <linux/rfkill.h> + + #else diff --git a/package/mac80211/patches/.svn/text-base/002-disable_ssb_build.patch.svn-base b/package/mac80211/patches/.svn/text-base/002-disable_ssb_build.patch.svn-base new file mode 100644 index 0000000..ef184c4 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/002-disable_ssb_build.patch.svn-base @@ -0,0 +1,21 @@ +--- a/config.mk ++++ b/config.mk +@@ -364,7 +364,8 @@ export CONFIG_IPW2200_QOS=y + # % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface + endif #CONFIG_WIRELESS_EXT + +-ifdef CONFIG_SSB ++# disabled ++ifdef __CONFIG_SSB + # Sonics Silicon Backplane + export CONFIG_SSB_SPROM=y + +@@ -377,7 +378,7 @@ endif #CONFIG_PCMCIA + # export CONFIG_SSB_DEBUG=y + export CONFIG_SSB_DRIVER_PCICORE=y + export CONFIG_B43_SSB=y +-endif #CONFIG_SSB ++endif #__CONFIG_SSB + + # export CONFIG_BCMA=m + # export CONFIG_BCMA_BLOCKIO=y diff --git a/package/mac80211/patches/.svn/text-base/003-disable_codel.patch.svn-base b/package/mac80211/patches/.svn/text-base/003-disable_codel.patch.svn-base new file mode 100644 index 0000000..0d6d749 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/003-disable_codel.patch.svn-base @@ -0,0 +1,19 @@ +--- a/compat/scripts/gen-compat-config.sh ++++ b/compat/scripts/gen-compat-config.sh +@@ -66,16 +66,3 @@ if [[ ${CONFIG_COMPAT_KERNEL_2_6_36} = " + echo "export CONFIG_COMPAT_KFIFO=y" + fi + fi +- +-if [[ ${CONFIG_COMPAT_KERNEL_3_5} = "y" ]]; then +- # We don't have 2.6.24 backport support yet for Codel / FQ CoDel +- # For those who want to try this is what is required that I can tell +- # so far: +- # * struct Qdisc_ops +- # - init and change callback ops use a different argument dataype +- # - you need to parse data received from userspace differently +- if [[ ${CONFIG_COMPAT_KERNEL_2_6_25} != "y" ]]; then +- echo "export CONFIG_COMPAT_NET_SCH_CODEL=m" +- echo "export CONFIG_COMPAT_NET_SCH_FQ_CODEL=m" +- fi +-fi diff --git a/package/mac80211/patches/.svn/text-base/004-use_env_for_bash.patch.svn-base b/package/mac80211/patches/.svn/text-base/004-use_env_for_bash.patch.svn-base new file mode 100644 index 0000000..0ae3820 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/004-use_env_for_bash.patch.svn-base @@ -0,0 +1,8 @@ +--- a/compat/scripts/gen-compat-config.sh ++++ b/compat/scripts/gen-compat-config.sh +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # Copyright 2012 Luis R. Rodriguez <mcgrof@frijolero.org> + # Copyright 2012 Hauke Mehrtens <hauke@hauke-m.de> + # diff --git a/package/mac80211/patches/.svn/text-base/010-add_include_for_bcma.patch.svn-base b/package/mac80211/patches/.svn/text-base/010-add_include_for_bcma.patch.svn-base new file mode 100644 index 0000000..e2e856e --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/010-add_include_for_bcma.patch.svn-base @@ -0,0 +1,11 @@ +--- a/include/linux/compat-3.0.h ++++ b/include/linux/compat-3.0.h +@@ -36,6 +36,8 @@ static inline struct page *shmem_read_ma + #endif + + ++#include <linux/mod_devicetable.h> ++ + /* + * since commit 1c5cae815d19ffe02bdfda1260949ef2b1806171 + * "net: call dev_alloc_name from register_netdevice" dev_alloc_name is diff --git a/package/mac80211/patches/.svn/text-base/020-disable_tty_set_termios.patch.svn-base b/package/mac80211/patches/.svn/text-base/020-disable_tty_set_termios.patch.svn-base new file mode 100644 index 0000000..fc5d4d6 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/020-disable_tty_set_termios.patch.svn-base @@ -0,0 +1,16 @@ +--- a/compat/compat-2.6.39.c ++++ b/compat/compat-2.6.39.c +@@ -12,6 +12,7 @@ + #include <linux/tty.h> + #include <linux/sched.h> + ++#ifdef CONFIG_COMPAT_BLUETOOTH + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + /* + * Termios Helper Methods +@@ -111,4 +112,4 @@ int tty_set_termios(struct tty_struct *t + } + EXPORT_SYMBOL_GPL(tty_set_termios); + #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */ +- ++#endif diff --git a/package/mac80211/patches/.svn/text-base/030-wext.patch.svn-base b/package/mac80211/patches/.svn/text-base/030-wext.patch.svn-base new file mode 100644 index 0000000..cb52e7c --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/030-wext.patch.svn-base @@ -0,0 +1,18 @@ +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -884,6 +884,15 @@ static int cfg80211_netdev_notifier_call + wdev->sme_state = CFG80211_SME_IDLE; + mutex_unlock(&rdev->devlist_mtx); + #ifdef CONFIG_CFG80211_WEXT ++#ifdef CONFIG_WIRELESS_EXT ++ if (!dev->wireless_handlers) ++ dev->wireless_handlers = &cfg80211_wext_handler; ++#else ++ printk_once(KERN_WARNING "cfg80211: wext will not work because " ++ "kernel was compiled with CONFIG_WIRELESS_EXT=n. " ++ "Tools using wext interface, like iwconfig will " ++ "not work.\n"); ++#endif + wdev->wext.default_key = -1; + wdev->wext.default_mgmt_key = -1; + wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; diff --git a/package/mac80211/patches/.svn/text-base/040-linux_3_9_compat.patch.svn-base b/package/mac80211/patches/.svn/text-base/040-linux_3_9_compat.patch.svn-base new file mode 100644 index 0000000..d83c39c --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/040-linux_3_9_compat.patch.svn-base @@ -0,0 +1,153 @@ +--- a/include/linux/compat-2.6.h ++++ b/include/linux/compat-2.6.h +@@ -69,6 +69,7 @@ void compat_dependency_symbol(void); + #include <linux/compat-3.6.h> + #include <linux/compat-3.7.h> + #include <linux/compat-3.8.h> ++#include <linux/compat-3.9.h> + + #endif /* __ASSEMBLY__ */ + +--- /dev/null ++++ b/include/linux/compat-3.9.h +@@ -0,0 +1,140 @@ ++#ifndef LINUX_3_9_COMPAT_H ++#define LINUX_3_9_COMPAT_H ++ ++#include <linux/version.h> ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) ++ ++#include <linux/idr.h> ++#include <linux/list.h> ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) ++#include <linux/rculist.h> ++#endif ++#include <net/sock.h> ++#include <linux/tty.h> ++#include <linux/tty_flip.h> ++ ++/* include this before changing hlist_for_each_* to use the old versions. */ ++#include <net/sch_generic.h> ++ ++ ++/** ++ * backport of idr idr_alloc() usage ++ * ++ * This backports a patch series send by Tejun Heo: ++ * https://lkml.org/lkml/2013/2/2/159 ++ */ ++static inline void compat_idr_destroy(struct idr *idp) ++{ ++ idr_remove_all(idp); ++ idr_destroy(idp); ++} ++#define idr_destroy(idp) compat_idr_destroy(idp) ++ ++static inline int idr_alloc(struct idr *idr, void *ptr, int start, int end, ++ gfp_t gfp_mask) ++{ ++ int id, ret; ++ ++ do { ++ if (!idr_pre_get(idr, gfp_mask)) ++ return -ENOMEM; ++ ret = idr_get_new_above(idr, ptr, start, &id); ++ if (!ret && id > end) { ++ idr_remove(idr, id); ++ ret = -ENOSPC; ++ } ++ } while (ret == -EAGAIN); ++ ++ return ret ? ret : id; ++} ++ ++static inline void idr_preload(gfp_t gfp_mask) ++{ ++} ++ ++static inline void idr_preload_end(void) ++{ ++} ++ ++ ++/** ++ * backport: ++ * ++ * commit 0bbacca7c3911451cea923b0ad6389d58e3d9ce9 ++ * Author: Sasha Levin <sasha.levin@oracle.com> ++ * Date: Thu Feb 7 12:32:18 2013 +1100 ++ * ++ * hlist: drop the node parameter from iterators ++ */ ++ ++#define hlist_entry_safe(ptr, type, member) \ ++ (ptr) ? hlist_entry(ptr, type, member) : NULL ++ ++#undef hlist_for_each_entry ++/** ++ * hlist_for_each_entry - iterate over list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry(pos, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); \ ++ pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++#undef hlist_for_each_entry_safe ++/** ++ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry ++ * @pos: the type * to use as a loop cursor. ++ * @n: another &struct hlist_node to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_safe(pos, n, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \ ++ pos && ({ n = pos->member.next; 1; }); \ ++ pos = hlist_entry_safe(n, typeof(*pos), member)) ++ ++#undef hlist_for_each_entry_rcu ++/** ++ * hlist_for_each_entry_rcu - iterate over rcu list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ * ++ * This list-traversal primitive may safely run concurrently with ++ * the _rcu list-mutation primitives such as hlist_add_head_rcu() ++ * as long as the traversal is guarded by rcu_read_lock(). ++ */ ++#define hlist_for_each_entry_rcu(pos, head, member) \ ++ for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\ ++ typeof(*(pos)), member); \ ++ pos; \ ++ pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ ++ &(pos)->member)), typeof(*(pos)), member)) ++ ++#undef sk_for_each ++#define sk_for_each(__sk, list) \ ++ hlist_for_each_entry(__sk, list, sk_node) ++ ++#define tty_flip_buffer_push(port) tty_flip_buffer_push((port)->tty) ++#define tty_insert_flip_string(port, chars, size) tty_insert_flip_string((port)->tty, chars, size) ++ ++/** ++ * backport of: ++ * ++ * commit 496ad9aa8ef448058e36ca7a787c61f2e63f0f54 ++ * Author: Al Viro <viro@zeniv.linux.org.uk> ++ * Date: Wed Jan 23 17:07:38 2013 -0500 ++ * ++ * new helper: file_inode(file) ++ */ ++static inline struct inode *file_inode(struct file *f) ++{ ++ return f->f_path.dentry->d_inode; ++} ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) */ ++ ++#endif /* LINUX_3_9_COMPAT_H */ diff --git a/package/mac80211/patches/.svn/text-base/130-mesh_pathtbl_backport.patch.svn-base b/package/mac80211/patches/.svn/text-base/130-mesh_pathtbl_backport.patch.svn-base new file mode 100644 index 0000000..1322099 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/130-mesh_pathtbl_backport.patch.svn-base @@ -0,0 +1,212 @@ +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -72,9 +72,9 @@ static inline struct mesh_table *resize_ + * it's used twice. So it is illegal to do + * for_each_mesh_entry(rcu_dereference(...), ...) + */ +-#define for_each_mesh_entry(tbl, p, node, i) \ ++#define for_each_mesh_entry(tbl, node, i) \ + for (i = 0; i <= tbl->hash_mask; i++) \ +- hlist_for_each_entry_rcu(node, p, &tbl->hash_buckets[i], list) ++ hlist_for_each_entry_rcu(node, &tbl->hash_buckets[i], list) + + + static struct mesh_table *mesh_table_alloc(int size_order) +@@ -139,7 +139,7 @@ static void mesh_table_free(struct mesh_ + } + if (free_leafs) { + spin_lock_bh(&tbl->gates_lock); +- hlist_for_each_entry_safe(gate, p, q, ++ hlist_for_each_entry_safe(gate, q, + tbl->known_gates, list) { + hlist_del(&gate->list); + kfree(gate); +@@ -333,12 +333,11 @@ static struct mesh_path *mpath_lookup(st + struct ieee80211_sub_if_data *sdata) + { + struct mesh_path *mpath; +- struct hlist_node *n; + struct hlist_head *bucket; + struct mpath_node *node; + + bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; +- hlist_for_each_entry_rcu(node, n, bucket, list) { ++ hlist_for_each_entry_rcu(node, bucket, list) { + mpath = node->mpath; + if (mpath->sdata == sdata && + ether_addr_equal(dst, mpath->dst)) { +@@ -389,11 +388,10 @@ mesh_path_lookup_by_idx(struct ieee80211 + { + struct mesh_table *tbl = rcu_dereference(mesh_paths); + struct mpath_node *node; +- struct hlist_node *p; + int i; + int j = 0; + +- for_each_mesh_entry(tbl, p, node, i) { ++ for_each_mesh_entry(tbl, node, i) { + if (sdata && node->mpath->sdata != sdata) + continue; + if (j++ == idx) { +@@ -417,13 +415,12 @@ int mesh_path_add_gate(struct mesh_path + { + struct mesh_table *tbl; + struct mpath_node *gate, *new_gate; +- struct hlist_node *n; + int err; + + rcu_read_lock(); + tbl = rcu_dereference(mesh_paths); + +- hlist_for_each_entry_rcu(gate, n, tbl->known_gates, list) ++ hlist_for_each_entry_rcu(gate, tbl->known_gates, list) + if (gate->mpath == mpath) { + err = -EEXIST; + goto err_rcu; +@@ -460,9 +457,9 @@ err_rcu: + static void mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) + { + struct mpath_node *gate; +- struct hlist_node *p, *q; ++ struct hlist_node *q; + +- hlist_for_each_entry_safe(gate, p, q, tbl->known_gates, list) { ++ hlist_for_each_entry_safe(gate, q, tbl->known_gates, list) { + if (gate->mpath != mpath) + continue; + spin_lock_bh(&tbl->gates_lock); +@@ -504,7 +501,6 @@ int mesh_path_add(struct ieee80211_sub_i + struct mesh_path *mpath, *new_mpath; + struct mpath_node *node, *new_node; + struct hlist_head *bucket; +- struct hlist_node *n; + int grow = 0; + int err = 0; + u32 hash_idx; +@@ -550,7 +546,7 @@ int mesh_path_add(struct ieee80211_sub_i + spin_lock(&tbl->hashwlock[hash_idx]); + + err = -EEXIST; +- hlist_for_each_entry(node, n, bucket, list) { ++ hlist_for_each_entry(node, bucket, list) { + mpath = node->mpath; + if (mpath->sdata == sdata && + ether_addr_equal(dst, mpath->dst)) +@@ -640,7 +636,6 @@ int mpp_path_add(struct ieee80211_sub_if + struct mesh_path *mpath, *new_mpath; + struct mpath_node *node, *new_node; + struct hlist_head *bucket; +- struct hlist_node *n; + int grow = 0; + int err = 0; + u32 hash_idx; +@@ -680,7 +675,7 @@ int mpp_path_add(struct ieee80211_sub_if + spin_lock(&tbl->hashwlock[hash_idx]); + + err = -EEXIST; +- hlist_for_each_entry(node, n, bucket, list) { ++ hlist_for_each_entry(node, bucket, list) { + mpath = node->mpath; + if (mpath->sdata == sdata && + ether_addr_equal(dst, mpath->dst)) +@@ -725,14 +720,13 @@ void mesh_plink_broken(struct sta_info * + static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + struct mesh_path *mpath; + struct mpath_node *node; +- struct hlist_node *p; + struct ieee80211_sub_if_data *sdata = sta->sdata; + int i; + __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE); + + rcu_read_lock(); + tbl = rcu_dereference(mesh_paths); +- for_each_mesh_entry(tbl, p, node, i) { ++ for_each_mesh_entry(tbl, node, i) { + mpath = node->mpath; + if (rcu_dereference(mpath->next_hop) == sta && + mpath->flags & MESH_PATH_ACTIVE && +@@ -792,13 +786,12 @@ void mesh_path_flush_by_nexthop(struct s + struct mesh_table *tbl; + struct mesh_path *mpath; + struct mpath_node *node; +- struct hlist_node *p; + int i; + + rcu_read_lock(); + read_lock_bh(&pathtbl_resize_lock); + tbl = resize_dereference_mesh_paths(); +- for_each_mesh_entry(tbl, p, node, i) { ++ for_each_mesh_entry(tbl, node, i) { + mpath = node->mpath; + if (rcu_dereference(mpath->next_hop) == sta) { + spin_lock(&tbl->hashwlock[i]); +@@ -815,11 +808,9 @@ static void table_flush_by_iface(struct + { + struct mesh_path *mpath; + struct mpath_node *node; +- struct hlist_node *p; + int i; + +- WARN_ON(!rcu_read_lock_held()); +- for_each_mesh_entry(tbl, p, node, i) { ++ for_each_mesh_entry(tbl, node, i) { + mpath = node->mpath; + if (mpath->sdata != sdata) + continue; +@@ -865,7 +856,6 @@ int mesh_path_del(struct ieee80211_sub_i + struct mesh_path *mpath; + struct mpath_node *node; + struct hlist_head *bucket; +- struct hlist_node *n; + int hash_idx; + int err = 0; + +@@ -875,7 +865,7 @@ int mesh_path_del(struct ieee80211_sub_i + bucket = &tbl->hash_buckets[hash_idx]; + + spin_lock(&tbl->hashwlock[hash_idx]); +- hlist_for_each_entry(node, n, bucket, list) { ++ hlist_for_each_entry(node, bucket, list) { + mpath = node->mpath; + if (mpath->sdata == sdata && + ether_addr_equal(addr, mpath->dst)) { +@@ -920,7 +910,6 @@ void mesh_path_tx_pending(struct mesh_pa + int mesh_path_send_to_gates(struct mesh_path *mpath) + { + struct ieee80211_sub_if_data *sdata = mpath->sdata; +- struct hlist_node *n; + struct mesh_table *tbl; + struct mesh_path *from_mpath = mpath; + struct mpath_node *gate = NULL; +@@ -935,7 +924,7 @@ int mesh_path_send_to_gates(struct mesh_ + if (!known_gates) + return -EHOSTUNREACH; + +- hlist_for_each_entry_rcu(gate, n, known_gates, list) { ++ hlist_for_each_entry_rcu(gate, known_gates, list) { + if (gate->mpath->sdata != sdata) + continue; + +@@ -951,7 +940,7 @@ int mesh_path_send_to_gates(struct mesh_ + } + } + +- hlist_for_each_entry_rcu(gate, n, known_gates, list) ++ hlist_for_each_entry_rcu(gate, known_gates, list) + if (gate->mpath->sdata == sdata) { + mpath_dbg(sdata, "Sending to %pM\n", gate->mpath->dst); + mesh_path_tx_pending(gate->mpath); +@@ -1096,12 +1085,11 @@ void mesh_path_expire(struct ieee80211_s + struct mesh_table *tbl; + struct mesh_path *mpath; + struct mpath_node *node; +- struct hlist_node *p; + int i; + + rcu_read_lock(); + tbl = rcu_dereference(mesh_paths); +- for_each_mesh_entry(tbl, p, node, i) { ++ for_each_mesh_entry(tbl, node, i) { + if (node->mpath->sdata != sdata) + continue; + mpath = node->mpath; diff --git a/package/mac80211/patches/.svn/text-base/150-disable_addr_notifier.patch.svn-base b/package/mac80211/patches/.svn/text-base/150-disable_addr_notifier.patch.svn-base new file mode 100644 index 0000000..9714696 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/150-disable_addr_notifier.patch.svn-base @@ -0,0 +1,67 @@ +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -313,7 +313,7 @@ void ieee80211_restart_hw(struct ieee802 + } + EXPORT_SYMBOL(ieee80211_restart_hw); + +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + static int ieee80211_ifa_changed(struct notifier_block *nb, + unsigned long data, void *arg) + { +@@ -372,7 +372,7 @@ static int ieee80211_ifa_changed(struct + } + #endif + +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + static int ieee80211_ifa6_changed(struct notifier_block *nb, + unsigned long data, void *arg) + { +@@ -1015,14 +1015,14 @@ int ieee80211_register_hw(struct ieee802 + goto fail_pm_qos; + } + +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + local->ifa_notifier.notifier_call = ieee80211_ifa_changed; + result = register_inetaddr_notifier(&local->ifa_notifier); + if (result) + goto fail_ifa; + #endif + +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; + result = register_inet6addr_notifier(&local->ifa6_notifier); + if (result) +@@ -1034,13 +1034,13 @@ int ieee80211_register_hw(struct ieee802 + + return 0; + +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + fail_ifa6: +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + unregister_inetaddr_notifier(&local->ifa_notifier); + #endif + #endif +-#if defined(CONFIG_INET) || defined(CONFIG_IPV6) ++#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6) + fail_ifa: + pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, + &local->network_latency_notifier); +@@ -1073,10 +1073,10 @@ void ieee80211_unregister_hw(struct ieee + + pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, + &local->network_latency_notifier); +-#ifdef CONFIG_INET ++#ifdef __disabled__CONFIG_INET + unregister_inetaddr_notifier(&local->ifa_notifier); + #endif +-#if IS_ENABLED(CONFIG_IPV6) ++#if IS_ENABLED(__disabled__CONFIG_IPV6) + unregister_inet6addr_notifier(&local->ifa6_notifier); + #endif + diff --git a/package/mac80211/patches/.svn/text-base/201-ath5k-WAR-for-AR71xx-PCI-bug.patch.svn-base b/package/mac80211/patches/.svn/text-base/201-ath5k-WAR-for-AR71xx-PCI-bug.patch.svn-base new file mode 100644 index 0000000..9e08a08 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/201-ath5k-WAR-for-AR71xx-PCI-bug.patch.svn-base @@ -0,0 +1,38 @@ +--- a/drivers/net/wireless/ath/ath5k/initvals.c ++++ b/drivers/net/wireless/ath/ath5k/initvals.c +@@ -65,8 +65,14 @@ static const struct ath5k_ini ar5210_ini + { AR5K_IMR, 0 }, + { AR5K_IER, AR5K_IER_DISABLE }, + { AR5K_BSR, 0, AR5K_INI_READ }, ++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) + { AR5K_TXCFG, AR5K_DMASIZE_128B }, + { AR5K_RXCFG, AR5K_DMASIZE_128B }, ++#else ++ /* WAR for AR71xx PCI bug */ ++ { AR5K_TXCFG, AR5K_DMASIZE_128B }, ++ { AR5K_RXCFG, AR5K_DMASIZE_4B }, ++#endif + { AR5K_CFG, AR5K_INIT_CFG }, + { AR5K_TOPS, 8 }, + { AR5K_RXNOFRM, 8 }, +--- a/drivers/net/wireless/ath/ath5k/dma.c ++++ b/drivers/net/wireless/ath/ath5k/dma.c +@@ -863,10 +863,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah) + * guess we can tweak it and see how it goes ;-) + */ + if (ah->ah_version != AR5K_AR5210) { ++#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79) + AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, + AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); + AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, + AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); ++#else ++ /* WAR for AR71xx PCI bug */ ++ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, ++ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); ++ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, ++ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B); ++#endif + } + + /* Pre-enable interrupts on 5211/5212*/ diff --git a/package/mac80211/patches/.svn/text-base/300-pending_work.patch.svn-base b/package/mac80211/patches/.svn/text-base/300-pending_work.patch.svn-base new file mode 100644 index 0000000..cf51aae --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/300-pending_work.patch.svn-base @@ -0,0 +1,963 @@ +--- a/drivers/net/wireless/ath/ath9k/common.h ++++ b/drivers/net/wireless/ath/ath9k/common.h +@@ -27,7 +27,7 @@ + #define WME_MAX_BA WME_BA_BMP_SIZE + #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) + +-#define ATH_RSSI_DUMMY_MARKER 0x127 ++#define ATH_RSSI_DUMMY_MARKER 127 + #define ATH_RSSI_LPF_LEN 10 + #define RSSI_LPF_THRESHOLD -20 + #define ATH_RSSI_EP_MULTIPLIER (1<<7) +--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +@@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9 + + last_rssi = priv->rx.last_rssi; + +- if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) +- rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, +- ATH_RSSI_EP_MULTIPLIER); ++ if (ieee80211_is_beacon(hdr->frame_control) && ++ !is_zero_ether_addr(common->curbssid) && ++ ether_addr_equal(hdr->addr3, common->curbssid)) { ++ s8 rssi = rxbuf->rxstatus.rs_rssi; + +- if (rxbuf->rxstatus.rs_rssi < 0) +- rxbuf->rxstatus.rs_rssi = 0; ++ if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) ++ rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); + +- if (ieee80211_is_beacon(fc)) +- priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; ++ if (rssi < 0) ++ rssi = 0; ++ ++ priv->ah->stats.avgbrssi = rssi; ++ } + + rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); + rx_status->band = hw->conf.channel->band; +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -185,7 +185,7 @@ struct ieee80211_hdr { + u8 addr3[6]; + __le16 seq_ctrl; + u8 addr4[6]; +-} __packed; ++} __packed __aligned(2); + + struct ieee80211_hdr_3addr { + __le16 frame_control; +@@ -194,7 +194,7 @@ struct ieee80211_hdr_3addr { + u8 addr2[6]; + u8 addr3[6]; + __le16 seq_ctrl; +-} __packed; ++} __packed __aligned(2); + + struct ieee80211_qos_hdr { + __le16 frame_control; +@@ -204,7 +204,7 @@ struct ieee80211_qos_hdr { + u8 addr3[6]; + __le16 seq_ctrl; + __le16 qos_ctrl; +-} __packed; ++} __packed __aligned(2); + + /** + * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set +@@ -581,7 +581,7 @@ struct ieee80211s_hdr { + __le32 seqnum; + u8 eaddr1[6]; + u8 eaddr2[6]; +-} __packed; ++} __packed __aligned(2); + + /* Mesh flags */ + #define MESH_FLAGS_AE_A4 0x1 +@@ -875,7 +875,7 @@ struct ieee80211_mgmt { + } u; + } __packed action; + } u; +-} __packed; ++} __packed __aligned(2); + + /* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */ + #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 +@@ -906,20 +906,20 @@ struct ieee80211_rts { + __le16 duration; + u8 ra[6]; + u8 ta[6]; +-} __packed; ++} __packed __aligned(2); + + struct ieee80211_cts { + __le16 frame_control; + __le16 duration; + u8 ra[6]; +-} __packed; ++} __packed __aligned(2); + + struct ieee80211_pspoll { + __le16 frame_control; + __le16 aid; + u8 bssid[6]; + u8 ta[6]; +-} __packed; ++} __packed __aligned(2); + + /* TDLS */ + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -204,6 +204,8 @@ static void ieee80211_send_addba_resp(st + memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); ++ else if (sdata->vif.type == NL80211_IFTYPE_WDS) ++ memcpy(mgmt->bssid, da, ETH_ALEN); + + mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_ACTION); +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -81,7 +81,8 @@ static void ieee80211_send_addba_request + memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); + if (sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN || +- sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ++ sdata->vif.type == NL80211_IFTYPE_MESH_POINT || ++ sdata->vif.type == NL80211_IFTYPE_WDS) + memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); + else if (sdata->vif.type == NL80211_IFTYPE_STATION) + memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); +@@ -527,6 +528,7 @@ int ieee80211_start_tx_ba_session(struct + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_AP_VLAN && + sdata->vif.type != NL80211_IFTYPE_AP && ++ sdata->vif.type != NL80211_IFTYPE_WDS && + sdata->vif.type != NL80211_IFTYPE_ADHOC) + return -EINVAL; + +--- a/net/mac80211/debugfs_sta.c ++++ b/net/mac80211/debugfs_sta.c +@@ -65,11 +65,11 @@ static ssize_t sta_flags_read(struct fil + test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" + + int res = scnprintf(buf, sizeof(buf), +- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", ++ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + TEST(AUTH), TEST(ASSOC), TEST(PS_STA), + TEST(PS_DRIVER), TEST(AUTHORIZED), + TEST(SHORT_PREAMBLE), +- TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), ++ TEST(WME), TEST(CLEAR_PS_FILT), + TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), + TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), + TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -107,7 +107,7 @@ void ieee80211_recalc_idle(struct ieee80 + + lockdep_assert_held(&local->mtx); + +- active = !list_empty(&local->chanctx_list); ++ active = !list_empty(&local->chanctx_list) || local->monitors; + + if (!local->ops->remain_on_channel) { + list_for_each_entry(roc, &local->roc_list, list) { +@@ -436,7 +436,6 @@ int ieee80211_do_open(struct wireless_de + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); + struct net_device *dev = wdev->netdev; + struct ieee80211_local *local = sdata->local; +- struct sta_info *sta; + u32 changed = 0; + int res; + u32 hw_reconf_flags = 0; +@@ -541,6 +540,9 @@ int ieee80211_do_open(struct wireless_de + + ieee80211_adjust_monitor_flags(sdata, 1); + ieee80211_configure_filter(local); ++ mutex_lock(&local->mtx); ++ ieee80211_recalc_idle(local); ++ mutex_unlock(&local->mtx); + + netif_carrier_on(dev); + break; +@@ -595,30 +597,8 @@ int ieee80211_do_open(struct wireless_de + + set_bit(SDATA_STATE_RUNNING, &sdata->state); + +- if (sdata->vif.type == NL80211_IFTYPE_WDS) { +- /* Create STA entry for the WDS peer */ +- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, +- GFP_KERNEL); +- if (!sta) { +- res = -ENOMEM; +- goto err_del_interface; +- } +- +- sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); +- sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); +- sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); +- +- res = sta_info_insert(sta); +- if (res) { +- /* STA has been freed */ +- goto err_del_interface; +- } +- +- rate_control_rate_init(sta); +- netif_carrier_on(dev); +- } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { ++ if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) + rcu_assign_pointer(local->p2p_sdata, sdata); +- } + + /* + * set_multicast_list will be invoked by the networking core +@@ -817,6 +797,9 @@ static void ieee80211_do_stop(struct iee + + ieee80211_adjust_monitor_flags(sdata, -1); + ieee80211_configure_filter(local); ++ mutex_lock(&local->mtx); ++ ieee80211_recalc_idle(local); ++ mutex_unlock(&local->mtx); + break; + case NL80211_IFTYPE_P2P_DEVICE: + /* relies on synchronize_rcu() below */ +@@ -1022,6 +1005,72 @@ static void ieee80211_if_setup(struct ne + dev->destructor = free_netdev; + } + ++static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_rx_status *rx_status; ++ struct ieee802_11_elems elems; ++ struct ieee80211_mgmt *mgmt; ++ struct sta_info *sta; ++ size_t baselen; ++ u32 rates = 0; ++ u16 stype; ++ bool new = false; ++ enum ieee80211_band band = local->hw.conf.channel->band; ++ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; ++ ++ rx_status = IEEE80211_SKB_RXCB(skb); ++ mgmt = (struct ieee80211_mgmt *) skb->data; ++ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; ++ ++ if (stype != IEEE80211_STYPE_BEACON) ++ return; ++ ++ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; ++ if (baselen > skb->len) ++ return; ++ ++ ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ skb->len - baselen, &elems); ++ ++ rates = ieee80211_sta_get_rates(local, &elems, band, NULL); ++ ++ rcu_read_lock(); ++ ++ sta = sta_info_get(sdata, sdata->u.wds.remote_addr); ++ ++ if (!sta) { ++ rcu_read_unlock(); ++ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, ++ GFP_KERNEL); ++ if (!sta) ++ return; ++ ++ new = true; ++ } ++ ++ sta->last_rx = jiffies; ++ sta->sta.supp_rates[local->hw.conf.channel->band] = rates; ++ ++ if (elems.ht_cap_elem) ++ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, ++ elems.ht_cap_elem, sta); ++ ++ if (elems.wmm_param) ++ set_sta_flag(sta, WLAN_STA_WME); ++ ++ if (new) { ++ sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); ++ sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); ++ sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); ++ rate_control_rate_init(sta); ++ sta_info_insert_rcu(sta); ++ } ++ ++ rcu_read_unlock(); ++} ++ + static void ieee80211_iface_work(struct work_struct *work) + { + struct ieee80211_sub_if_data *sdata = +@@ -1126,6 +1175,9 @@ static void ieee80211_iface_work(struct + break; + ieee80211_mesh_rx_queued_mgmt(sdata, skb); + break; ++ case NL80211_IFTYPE_WDS: ++ ieee80211_wds_rx_queued_mgmt(sdata, skb); ++ break; + default: + WARN(1, "frame for unexpected interface type"); + break; +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2365,6 +2365,7 @@ ieee80211_rx_h_action(struct ieee80211_r + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + sdata->vif.type != NL80211_IFTYPE_AP_VLAN && + sdata->vif.type != NL80211_IFTYPE_AP && ++ sdata->vif.type != NL80211_IFTYPE_WDS && + sdata->vif.type != NL80211_IFTYPE_ADHOC) + break; + +@@ -2692,14 +2693,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_ + + if (!ieee80211_vif_is_mesh(&sdata->vif) && + sdata->vif.type != NL80211_IFTYPE_ADHOC && +- sdata->vif.type != NL80211_IFTYPE_STATION) ++ sdata->vif.type != NL80211_IFTYPE_STATION && ++ sdata->vif.type != NL80211_IFTYPE_WDS) + return RX_DROP_MONITOR; + + switch (stype) { + case cpu_to_le16(IEEE80211_STYPE_AUTH): + case cpu_to_le16(IEEE80211_STYPE_BEACON): + case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): +- /* process for all: mesh, mlme, ibss */ ++ /* process for all: mesh, mlme, ibss, wds */ + break; + case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): + case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): +@@ -3028,10 +3030,16 @@ static int prepare_for_handlers(struct i + } + break; + case NL80211_IFTYPE_WDS: +- if (bssid || !ieee80211_is_data(hdr->frame_control)) +- return 0; + if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) + return 0; ++ ++ if (ieee80211_is_data(hdr->frame_control) || ++ ieee80211_is_action(hdr->frame_control)) { ++ if (compare_ether_addr(sdata->vif.addr, hdr->addr1)) ++ return 0; ++ } else if (!ieee80211_is_beacon(hdr->frame_control)) ++ return 0; ++ + break; + case NL80211_IFTYPE_P2P_DEVICE: + if (!ieee80211_is_public_action(hdr, skb->len) && +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -32,7 +32,6 @@ + * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble + * frames. + * @WLAN_STA_WME: Station is a QoS-STA. +- * @WLAN_STA_WDS: Station is one of our WDS peers. + * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the + * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next + * frame to this station is transmitted. +@@ -66,7 +65,6 @@ enum ieee80211_sta_info_flags { + WLAN_STA_AUTHORIZED, + WLAN_STA_SHORT_PREAMBLE, + WLAN_STA_WME, +- WLAN_STA_WDS, + WLAN_STA_CLEAR_PS_FILT, + WLAN_STA_MFP, + WLAN_STA_BLOCK_BA, +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1231,34 +1231,40 @@ static bool ieee80211_tx_frags(struct ie + if (local->queue_stop_reasons[q] || + (!txpending && !skb_queue_empty(&local->pending[q]))) { + if (unlikely(info->flags & +- IEEE80211_TX_INTFL_OFFCHAN_TX_OK && +- local->queue_stop_reasons[q] & +- ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) { ++ IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) { ++ if (local->queue_stop_reasons[q] & ++ ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) { ++ /* ++ * Drop off-channel frames if queues ++ * are stopped for any reason other ++ * than off-channel operation. Never ++ * queue them. ++ */ ++ spin_unlock_irqrestore( ++ &local->queue_stop_reason_lock, ++ flags); ++ ieee80211_purge_tx_queue(&local->hw, ++ skbs); ++ return true; ++ } ++ } else { ++ + /* +- * Drop off-channel frames if queues are stopped +- * for any reason other than off-channel +- * operation. Never queue them. ++ * Since queue is stopped, queue up frames for ++ * later transmission from the tx-pending ++ * tasklet when the queue is woken again. + */ +- spin_unlock_irqrestore( +- &local->queue_stop_reason_lock, flags); +- ieee80211_purge_tx_queue(&local->hw, skbs); +- return true; ++ if (txpending) ++ skb_queue_splice_init(skbs, ++ &local->pending[q]); ++ else ++ skb_queue_splice_tail_init(skbs, ++ &local->pending[q]); ++ ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, ++ flags); ++ return false; + } +- +- /* +- * Since queue is stopped, queue up frames for later +- * transmission from the tx-pending tasklet when the +- * queue is woken again. +- */ +- if (txpending) +- skb_queue_splice_init(skbs, &local->pending[q]); +- else +- skb_queue_splice_tail_init(skbs, +- &local->pending[q]); +- +- spin_unlock_irqrestore(&local->queue_stop_reason_lock, +- flags); +- return false; + } + spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); + +@@ -1848,9 +1854,24 @@ netdev_tx_t ieee80211_subif_start_xmit(s + } + + if (!is_multicast_ether_addr(skb->data)) { ++ struct sta_info *next_hop; ++ bool mpp_lookup = true; ++ + mpath = mesh_path_lookup(sdata, skb->data); +- if (!mpath) ++ if (mpath) { ++ mpp_lookup = false; ++ next_hop = rcu_dereference(mpath->next_hop); ++ if (!next_hop || ++ !(mpath->flags & (MESH_PATH_ACTIVE | ++ MESH_PATH_RESOLVING))) ++ mpp_lookup = true; ++ } ++ ++ if (mpp_lookup) + mppath = mpp_path_lookup(sdata, skb->data); ++ ++ if (mppath && mpath) ++ mesh_path_del(mpath->sdata, mpath->dst); + } + + /* +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -554,16 +554,9 @@ static int nl80211_msg_put_channel(struc + if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) + goto nla_put_failure; +- if (chan->flags & IEEE80211_CHAN_RADAR) { +- u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered); +- if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) +- goto nla_put_failure; +- if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE, +- chan->dfs_state)) +- goto nla_put_failure; +- if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time)) +- goto nla_put_failure; +- } ++ if ((chan->flags & IEEE80211_CHAN_RADAR) && ++ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) ++ goto nla_put_failure; + if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS)) + goto nla_put_failure; +@@ -900,9 +893,6 @@ static int nl80211_put_iface_combination + nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, + c->max_interfaces)) + goto nla_put_failure; +- if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, +- c->radar_detect_widths)) +- goto nla_put_failure; + + nla_nest_end(msg, nl_combi); + } +@@ -914,48 +904,6 @@ nla_put_failure: + return -ENOBUFS; + } + +-#ifdef CONFIG_PM +-static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev, +- struct sk_buff *msg) +-{ +- const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp; +- struct nlattr *nl_tcp; +- +- if (!tcp) +- return 0; +- +- nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION); +- if (!nl_tcp) +- return -ENOBUFS; +- +- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD, +- tcp->data_payload_max)) +- return -ENOBUFS; +- +- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD, +- tcp->data_payload_max)) +- return -ENOBUFS; +- +- if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ)) +- return -ENOBUFS; +- +- if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, +- sizeof(*tcp->tok), tcp->tok)) +- return -ENOBUFS; +- +- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL, +- tcp->data_interval_max)) +- return -ENOBUFS; +- +- if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD, +- tcp->wake_payload_max)) +- return -ENOBUFS; +- +- nla_nest_end(msg, nl_tcp); +- return 0; +-} +-#endif +- + static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, + struct cfg80211_registered_device *dev) + { +@@ -1330,9 +1278,6 @@ static int nl80211_send_wiphy(struct sk_ + goto nla_put_failure; + } + +- if (nl80211_send_wowlan_tcp_caps(dev, msg)) +- goto nla_put_failure; +- + nla_nest_end(msg, nl_wowlan); + } + #endif +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -3285,13 +3285,19 @@ static int ieee80211_cfg_get_channel(str + struct cfg80211_chan_def *chandef) + { + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); ++ struct ieee80211_local *local = wiphy_priv(wiphy); + struct ieee80211_chanctx_conf *chanctx_conf; + int ret = -ENODATA; + + rcu_read_lock(); +- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); +- if (chanctx_conf) { +- *chandef = chanctx_conf->def; ++ if (local->use_chanctx) { ++ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); ++ if (chanctx_conf) { ++ *chandef = chanctx_conf->def; ++ ret = 0; ++ } ++ } else if (local->open_count == local->monitors) { ++ *chandef = local->monitor_chandef; + ret = 0; + } + rcu_read_unlock(); +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1463,7 +1463,9 @@ static bool ath9k_hw_chip_reset(struct a + reset_type = ATH9K_RESET_POWER_ON; + else + reset_type = ATH9K_RESET_COLD; +- } ++ } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) || ++ (REG_READ(ah, AR_CR) & AR_CR_RXE)) ++ reset_type = ATH9K_RESET_COLD; + + if (!ath9k_hw_set_reset_reg(ah, reset_type)) + return false; +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -1236,8 +1236,10 @@ static inline void rt2x00lib_set_if_comb + */ + if_limit = &rt2x00dev->if_limits_ap; + if_limit->max = rt2x00dev->ops->max_ap_intf; +- if_limit->types = BIT(NL80211_IFTYPE_AP) | +- BIT(NL80211_IFTYPE_MESH_POINT); ++ if_limit->types = BIT(NL80211_IFTYPE_AP); ++#ifdef CONFIG_MAC80211_MESH ++ if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); ++#endif + + /* + * Build up AP interface combinations structure. +@@ -1309,7 +1311,9 @@ int rt2x00lib_probe_dev(struct rt2x00_de + rt2x00dev->hw->wiphy->interface_modes |= + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP) | ++#ifdef CONFIG_MAC80211_MESH + BIT(NL80211_IFTYPE_MESH_POINT) | ++#endif + BIT(NL80211_IFTYPE_WDS); + + rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -26,11 +26,11 @@ + /* Number of symbols for a packet with (bps) bits per symbol */ + #define MCS_NSYMS(bps) ((MCS_NBITS + (bps) - 1) / (bps)) + +-/* Transmission time for a packet containing (syms) symbols */ ++/* Transmission time (nanoseconds) for a packet containing (syms) symbols */ + #define MCS_SYMBOL_TIME(sgi, syms) \ + (sgi ? \ +- ((syms) * 18 + 4) / 5 : /* syms * 3.6 us */ \ +- (syms) << 2 /* syms * 4 us */ \ ++ ((syms) * 18000 + 4000) / 5 : /* syms * 3.6 us */ \ ++ ((syms) * 1000) << 2 /* syms * 4 us */ \ + ) + + /* Transmit duration for the raw data part of an average sized packet */ +@@ -64,9 +64,9 @@ + } + + #define CCK_DURATION(_bitrate, _short, _len) \ +- (10 /* SIFS */ + \ ++ (1000 * (10 /* SIFS */ + \ + (_short ? 72 + 24 : 144 + 48 ) + \ +- (8 * (_len + 4) * 10) / (_bitrate)) ++ (8 * (_len + 4) * 10) / (_bitrate))) + + #define CCK_ACK_DURATION(_bitrate, _short) \ + (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ +@@ -211,20 +211,32 @@ static void + minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) + { + struct minstrel_rate_stats *mr; +- unsigned int usecs = 0; ++ unsigned int nsecs = 0; ++ unsigned int tp; ++ unsigned int prob; + + mr = &mi->groups[group].rates[rate]; ++ prob = mr->probability; + +- if (mr->probability < MINSTREL_FRAC(1, 10)) { ++ if (prob < MINSTREL_FRAC(1, 10)) { + mr->cur_tp = 0; + return; + } + ++ /* ++ * For the throughput calculation, limit the probability value to 90% to ++ * account for collision related packet error rate fluctuation ++ */ ++ if (prob > MINSTREL_FRAC(9, 10)) ++ prob = MINSTREL_FRAC(9, 10); ++ + if (group != MINSTREL_CCK_GROUP) +- usecs = mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); ++ nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); + +- usecs += minstrel_mcs_groups[group].duration[rate]; +- mr->cur_tp = MINSTREL_TRUNC((1000000 / usecs) * mr->probability); ++ nsecs += minstrel_mcs_groups[group].duration[rate]; ++ tp = 1000000 * ((mr->probability * 1000) / nsecs); ++ ++ mr->cur_tp = MINSTREL_TRUNC(tp); + } + + /* +@@ -308,8 +320,8 @@ minstrel_ht_update_stats(struct minstrel + } + } + +- /* try to sample up to half of the available rates during each interval */ +- mi->sample_count *= 4; ++ /* try to sample all available rates during each interval */ ++ mi->sample_count *= 8; + + cur_prob = 0; + cur_prob_tp = 0; +@@ -320,20 +332,13 @@ minstrel_ht_update_stats(struct minstrel + if (!mg->supported) + continue; + +- mr = minstrel_get_ratestats(mi, mg->max_prob_rate); +- if (cur_prob_tp < mr->cur_tp && +- minstrel_mcs_groups[group].streams == 1) { +- mi->max_prob_rate = mg->max_prob_rate; +- cur_prob = mr->cur_prob; +- cur_prob_tp = mr->cur_tp; +- } +- + mr = minstrel_get_ratestats(mi, mg->max_tp_rate); + if (cur_tp < mr->cur_tp) { + mi->max_tp_rate2 = mi->max_tp_rate; + cur_tp2 = cur_tp; + mi->max_tp_rate = mg->max_tp_rate; + cur_tp = mr->cur_tp; ++ mi->max_prob_streams = minstrel_mcs_groups[group].streams - 1; + } + + mr = minstrel_get_ratestats(mi, mg->max_tp_rate2); +@@ -343,6 +348,23 @@ minstrel_ht_update_stats(struct minstrel + } + } + ++ if (mi->max_prob_streams < 1) ++ mi->max_prob_streams = 1; ++ ++ for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { ++ mg = &mi->groups[group]; ++ if (!mg->supported) ++ continue; ++ mr = minstrel_get_ratestats(mi, mg->max_prob_rate); ++ if (cur_prob_tp < mr->cur_tp && ++ minstrel_mcs_groups[group].streams <= mi->max_prob_streams) { ++ mi->max_prob_rate = mg->max_prob_rate; ++ cur_prob = mr->cur_prob; ++ cur_prob_tp = mr->cur_tp; ++ } ++ } ++ ++ + mi->stats_update = jiffies; + } + +@@ -467,7 +489,7 @@ minstrel_ht_tx_status(void *priv, struct + + if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { + mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); +- mi->sample_tries = 2; ++ mi->sample_tries = 1; + mi->sample_count--; + } + +@@ -536,7 +558,7 @@ minstrel_calc_retransmit(struct minstrel + mr->retry_updated = true; + + group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; ++ tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000; + + /* Contention time for first 2 tries */ + ctime = (t_slot * cw) >> 1; +@@ -616,6 +638,7 @@ minstrel_get_sample_rate(struct minstrel + { + struct minstrel_rate_stats *mr; + struct minstrel_mcs_group_data *mg; ++ unsigned int sample_dur, sample_group; + int sample_idx = 0; + + if (mi->sample_wait > 0) { +@@ -626,39 +649,46 @@ minstrel_get_sample_rate(struct minstrel + if (!mi->sample_tries) + return -1; + +- mi->sample_tries--; + mg = &mi->groups[mi->sample_group]; + sample_idx = sample_table[mg->column][mg->index]; + mr = &mg->rates[sample_idx]; +- sample_idx += mi->sample_group * MCS_GROUP_RATES; ++ sample_group = mi->sample_group; ++ sample_idx += sample_group * MCS_GROUP_RATES; + minstrel_next_sample_idx(mi); + + /* + * Sampling might add some overhead (RTS, no aggregation) + * to the frame. Hence, don't use sampling for the currently +- * used max TP rate. ++ * used rates. + */ +- if (sample_idx == mi->max_tp_rate) ++ if (sample_idx == mi->max_tp_rate || ++ sample_idx == mi->max_tp_rate2 || ++ sample_idx == mi->max_prob_rate) + return -1; ++ + /* +- * When not using MRR, do not sample if the probability is already +- * higher than 95% to avoid wasting airtime ++ * Do not sample if the probability is already higher than 95% ++ * to avoid wasting airtime. + */ +- if (!mp->has_mrr && (mr->probability > MINSTREL_FRAC(95, 100))) ++ if (mr->probability > MINSTREL_FRAC(95, 100)) + return -1; + + /* + * Make sure that lower rates get sampled only occasionally, + * if the link is working perfectly. + */ +- if (minstrel_get_duration(sample_idx) > +- minstrel_get_duration(mi->max_tp_rate)) { ++ sample_dur = minstrel_get_duration(sample_idx); ++ if (sample_dur >= minstrel_get_duration(mi->max_tp_rate2) && ++ (mi->max_prob_streams < ++ minstrel_mcs_groups[sample_group].streams || ++ sample_dur >= minstrel_get_duration(mi->max_prob_rate))) { + if (mr->sample_skipped < 20) + return -1; + + if (mi->sample_slow++ > 2) + return -1; + } ++ mi->sample_tries--; + + return sample_idx; + } +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -85,6 +85,7 @@ struct minstrel_ht_sta { + + /* best probability rate */ + unsigned int max_prob_rate; ++ unsigned int max_prob_streams; + + /* time of last status update */ + unsigned long stats_update; +--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c +@@ -1023,6 +1023,7 @@ static bool ar9003_hw_init_cal(struct at + AR_PHY_AGC_CONTROL_FLTR_CAL | + AR_PHY_AGC_CONTROL_PKDET_CAL; + ++ /* Use chip chainmask only for calibration */ + ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); + + if (rtt) { +@@ -1150,6 +1151,9 @@ skip_tx_iqcal: + ar9003_hw_rtt_disable(ah); + } + ++ /* Revert chainmask to runtime parameters */ ++ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ++ + /* Initialize list pointers */ + ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; + +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +@@ -3606,6 +3606,12 @@ static void ar9003_hw_ant_ctrl_apply(str + value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); + REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); + ++ if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) { ++ value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); ++ REG_RMW_FIELD(ah, switch_chain_reg[0], ++ AR_SWITCH_TABLE_ALL, value); ++ } ++ + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { + if ((ah->rxchainmask & BIT(chain)) || + (ah->txchainmask & BIT(chain))) { +@@ -3772,6 +3778,17 @@ static void ar9003_hw_atten_apply(struct + AR_PHY_EXT_ATTEN_CTL_2, + }; + ++ if ((AR_SREV_9462(ah)) && (ah->rxchainmask == 0x2)) { ++ value = ar9003_hw_atten_chain_get(ah, 1, chan); ++ REG_RMW_FIELD(ah, ext_atten_reg[0], ++ AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); ++ ++ value = ar9003_hw_atten_chain_get_margin(ah, 1, chan); ++ REG_RMW_FIELD(ah, ext_atten_reg[0], ++ AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, ++ value); ++ } ++ + /* Test value. if 0 then attenuation is unused. Don't load anything. */ + for (i = 0; i < 3; i++) { + if (ah->txchainmask & BIT(i)) { +--- a/drivers/net/wireless/ath/ath9k/link.c ++++ b/drivers/net/wireless/ath/ath9k/link.c +@@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct wo + int i; + bool needreset = false; + +- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) +- if (ATH_TXQ_SETUP(sc, i)) { +- txq = &sc->tx.txq[i]; +- ath_txq_lock(sc, txq); +- if (txq->axq_depth) { +- if (txq->axq_tx_inprogress) { +- needreset = true; +- ath_txq_unlock(sc, txq); +- break; +- } else { +- txq->axq_tx_inprogress = true; +- } ++ for (i = 0; i < IEEE80211_NUM_ACS; i++) { ++ txq = sc->tx.txq_map[i]; ++ ++ ath_txq_lock(sc, txq); ++ if (txq->axq_depth) { ++ if (txq->axq_tx_inprogress) { ++ needreset = true; ++ ath_txq_unlock(sc, txq); ++ break; ++ } else { ++ txq->axq_tx_inprogress = true; + } +- ath_txq_unlock_complete(sc, txq); + } ++ ath_txq_unlock_complete(sc, txq); ++ } + + if (needreset) { + ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -766,6 +766,7 @@ int __must_check __sta_info_destroy(stru + struct ieee80211_local *local; + struct ieee80211_sub_if_data *sdata; + int ret, i; ++ bool have_key = false; + + might_sleep(); + +@@ -793,12 +794,19 @@ int __must_check __sta_info_destroy(stru + list_del_rcu(&sta->list); + + mutex_lock(&local->key_mtx); +- for (i = 0; i < NUM_DEFAULT_KEYS; i++) ++ for (i = 0; i < NUM_DEFAULT_KEYS; i++) { + __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i])); +- if (sta->ptk) ++ have_key = true; ++ } ++ if (sta->ptk) { + __ieee80211_key_free(key_mtx_dereference(local, sta->ptk)); ++ have_key = true; ++ } + mutex_unlock(&local->key_mtx); + ++ if (!have_key) ++ synchronize_net(); ++ + sta->dead = true; + + local->num_sta--; diff --git a/package/mac80211/patches/.svn/text-base/310-ap_scan.patch.svn-base b/package/mac80211/patches/.svn/text-base/310-ap_scan.patch.svn-base new file mode 100644 index 0000000..b8f2671 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/310-ap_scan.patch.svn-base @@ -0,0 +1,11 @@ +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2009,7 +2009,7 @@ static int ieee80211_scan(struct wiphy * + * the frames sent while scanning on other channel will be + * lost) + */ +- if (sdata->u.ap.beacon && ++ if (0 && sdata->u.ap.beacon && + (!(wiphy->features & NL80211_FEATURE_AP_SCAN) || + !(req->flags & NL80211_SCAN_FLAG_AP))) + return -EOPNOTSUPP; diff --git a/package/mac80211/patches/.svn/text-base/400-ath_move_debug_code.patch.svn-base b/package/mac80211/patches/.svn/text-base/400-ath_move_debug_code.patch.svn-base new file mode 100644 index 0000000..c91128d --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/400-ath_move_debug_code.patch.svn-base @@ -0,0 +1,28 @@ +--- a/drivers/net/wireless/ath/Makefile ++++ b/drivers/net/wireless/ath/Makefile +@@ -10,7 +10,7 @@ obj-$(CONFIG_ATH_COMMON) += ath.o + ath-objs := main.o \ + regd.o \ + hw.o \ +- key.o ++ key.o \ ++ debug.o + +-ath-$(CONFIG_ATH_DEBUG) += debug.o + ccflags-y += -D__CHECK_ENDIAN__ +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -281,13 +281,6 @@ void _ath_dbg(struct ath_common *common, + #endif /* CONFIG_ATH_DEBUG */ + + /** Returns string describing opmode, or NULL if unknown mode. */ +-#ifdef CONFIG_ATH_DEBUG + const char *ath_opmode_to_string(enum nl80211_iftype opmode); +-#else +-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) +-{ +- return "UNKNOWN"; +-} +-#endif + + #endif /* ATH_H */ diff --git a/package/mac80211/patches/.svn/text-base/401-ath9k_blink_default.patch.svn-base b/package/mac80211/patches/.svn/text-base/401-ath9k_blink_default.patch.svn-base new file mode 100644 index 0000000..421e785 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/401-ath9k_blink_default.patch.svn-base @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -46,7 +46,7 @@ int ath9k_modparam_nohwcrypt; + module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); + MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); + +-int led_blink; ++int led_blink = 1; + module_param_named(blink, led_blink, int, 0444); + MODULE_PARM_DESC(blink, "Enable LED blink on activity"); + diff --git a/package/mac80211/patches/.svn/text-base/402-ath9k-fix-invalid-mac-address-handling.patch.svn-base b/package/mac80211/patches/.svn/text-base/402-ath9k-fix-invalid-mac-address-handling.patch.svn-base new file mode 100644 index 0000000..3dbdba0 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/402-ath9k-fix-invalid-mac-address-handling.patch.svn-base @@ -0,0 +1,29 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -17,6 +17,7 @@ + #include <linux/io.h> + #include <linux/slab.h> + #include <linux/module.h> ++#include <linux/etherdevice.h> + #include <asm/unaligned.h> + + #include "hw.h" +@@ -519,8 +520,16 @@ static int ath9k_hw_init_macaddr(struct + common->macaddr[2 * i] = eeval >> 8; + common->macaddr[2 * i + 1] = eeval & 0xff; + } +- if (sum == 0 || sum == 0xffff * 3) +- return -EADDRNOTAVAIL; ++ if (!is_valid_ether_addr(common->macaddr)) { ++ ath_err(common, ++ "eeprom contains invalid mac address: %pM\n", ++ common->macaddr); ++ ++ random_ether_addr(common->macaddr); ++ ath_err(common, ++ "random mac address will be used: %pM\n", ++ common->macaddr); ++ } + + return 0; + } diff --git a/package/mac80211/patches/.svn/text-base/403-ath_regd_optional.patch.svn-base b/package/mac80211/patches/.svn/text-base/403-ath_regd_optional.patch.svn-base new file mode 100644 index 0000000..683417b --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/403-ath_regd_optional.patch.svn-base @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -198,6 +198,10 @@ ath_reg_apply_beaconing_flags(struct wip + struct ieee80211_channel *ch; + unsigned int i; + ++#ifdef ATH_USER_REGD ++ return; ++#endif ++ + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + + if (!wiphy->bands[band]) +@@ -252,6 +256,10 @@ ath_reg_apply_active_scan_flags(struct w + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + ++#ifdef ATH_USER_REGD ++ return; ++#endif ++ + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + if (!sband) + return; +@@ -301,6 +309,10 @@ static void ath_reg_apply_radar_flags(st + struct ieee80211_channel *ch; + unsigned int i; + ++#ifdef ATH_USER_REGD ++ return; ++#endif ++ + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) + return; + +@@ -505,6 +517,10 @@ ath_regd_init_wiphy(struct ath_regulator + { + const struct ieee80211_regdomain *regd; + ++#ifdef ATH_USER_REGD ++ return 0; ++#endif ++ + wiphy->reg_notifier = reg_notifier; + wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; + diff --git a/package/mac80211/patches/.svn/text-base/404-world_regd_fixup.patch.svn-base b/package/mac80211/patches/.svn/text-base/404-world_regd_fixup.patch.svn-base new file mode 100644 index 0000000..d609b55 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/404-world_regd_fixup.patch.svn-base @@ -0,0 +1,84 @@ +--- a/drivers/net/wireless/ath/regd.c ++++ b/drivers/net/wireless/ath/regd.c +@@ -44,7 +44,8 @@ static int __ath_regd_init(struct ath_re + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) + + /* We allow IBSS on these on a case by case basis by regulatory domain */ +-#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\ ++#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5250, 40, 0, 30, 0), \ ++ REG_RULE(5250, 5350+10, 40, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) +@@ -62,57 +63,56 @@ static int __ath_regd_init(struct ath_re + #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ + ATH9K_5GHZ_5725_5850 + ++#define REGD_RULES(...) \ ++ .reg_rules = { __VA_ARGS__ }, \ ++ .n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ })) ++ + /* Can be used for: + * 0x60, 0x61, 0x62 */ + static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { +- .n_reg_rules = 5, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_ALL, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + /* Can be used by 0x63 and 0x65 */ + static const struct ieee80211_regdomain ath_world_regdom_63_65 = { +- .n_reg_rules = 4, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_NO_MIDBAND, +- } ++ ) + }; + + /* Can be used by 0x64 only */ + static const struct ieee80211_regdomain ath_world_regdom_64 = { +- .n_reg_rules = 3, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_NO_MIDBAND, +- } ++ ) + }; + + /* Can be used by 0x66 and 0x69 */ + static const struct ieee80211_regdomain ath_world_regdom_66_69 = { +- .n_reg_rules = 3, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + /* Can be used by 0x67, 0x68, 0x6A and 0x6C */ + static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = { +- .n_reg_rules = 4, + .alpha2 = "99", +- .reg_rules = { ++ REGD_RULES( + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_ALL, +- } ++ ) + }; + + static inline bool is_wwr_sku(u16 regd) diff --git a/package/mac80211/patches/.svn/text-base/405-regd_no_assoc_hints.patch.svn-base b/package/mac80211/patches/.svn/text-base/405-regd_no_assoc_hints.patch.svn-base new file mode 100644 index 0000000..938ac42 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/405-regd_no_assoc_hints.patch.svn-base @@ -0,0 +1,19 @@ +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1730,6 +1730,8 @@ void regulatory_hint_11d(struct wiphy *w + enum environment_cap env = ENVIRON_ANY; + struct regulatory_request *request, *lr; + ++ return; ++ + mutex_lock(®_mutex); + lr = get_last_request(); + +@@ -1926,6 +1928,7 @@ static void restore_regulatory_settings( + + void regulatory_hint_disconnect(void) + { ++ return; + REG_DBG_PRINT("All devices are disconnected, going to restore regulatory settings\n"); + restore_regulatory_settings(false); + } diff --git a/package/mac80211/patches/.svn/text-base/406-ath_regd_us.patch.svn-base b/package/mac80211/patches/.svn/text-base/406-ath_regd_us.patch.svn-base new file mode 100644 index 0000000..cc55877 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/406-ath_regd_us.patch.svn-base @@ -0,0 +1,26 @@ +--- a/drivers/net/wireless/ath/regd_common.h ++++ b/drivers/net/wireless/ath/regd_common.h +@@ -32,6 +32,7 @@ enum EnumRd { + FCC2_WORLD = 0x21, + FCC2_ETSIC = 0x22, + FCC6_WORLD = 0x23, ++ FCC3_FCCA_2 = 0x2A, + FRANCE_RES = 0x31, + FCC3_FCCA = 0x3A, + FCC3_WORLD = 0x3B, +@@ -167,6 +168,7 @@ static struct reg_dmn_pair_mapping regDo + {FCC2_WORLD, CTL_FCC, CTL_ETSI}, + {FCC2_ETSIC, CTL_FCC, CTL_ETSI}, + {FCC3_FCCA, CTL_FCC, CTL_FCC}, ++ {FCC3_FCCA_2, CTL_FCC, CTL_FCC}, + {FCC3_WORLD, CTL_FCC, CTL_ETSI}, + {FCC4_FCCA, CTL_FCC, CTL_FCC}, + {FCC5_FCCA, CTL_FCC, CTL_FCC}, +@@ -463,6 +465,7 @@ static struct country_code_to_enum_rd al + {CTRY_UAE, NULL1_WORLD, "AE"}, + {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"}, + {CTRY_UNITED_STATES, FCC3_FCCA, "US"}, ++ {CTRY_UNITED_STATES, FCC3_FCCA_2, "US"}, + /* This "PS" is for US public safety actually... to support this we + * would need to assign new special alpha2 to CRDA db as with the world + * regdomain and use another alpha2 */ diff --git a/package/mac80211/patches/.svn/text-base/410-ath9k_allow_adhoc_and_ap.patch.svn-base b/package/mac80211/patches/.svn/text-base/410-ath9k_allow_adhoc_and_ap.patch.svn-base new file mode 100644 index 0000000..7a07eb6 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/410-ath9k_allow_adhoc_and_ap.patch.svn-base @@ -0,0 +1,10 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -727,6 +727,7 @@ static const struct ieee80211_iface_limi + #endif + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO) }, ++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + }; + + static const struct ieee80211_iface_combination if_comb = { diff --git a/package/mac80211/patches/.svn/text-base/411-ath5k_allow_adhoc_and_ap.patch.svn-base b/package/mac80211/patches/.svn/text-base/411-ath5k_allow_adhoc_and_ap.patch.svn-base new file mode 100644 index 0000000..3d885bb --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/411-ath5k_allow_adhoc_and_ap.patch.svn-base @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c ++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c +@@ -89,13 +89,8 @@ ath5k_add_interface(struct ieee80211_hw + goto end; + } + +- /* Don't allow other interfaces if one ad-hoc is configured. +- * TODO: Fix the problems with ad-hoc and multiple other interfaces. +- * We would need to operate the HW in ad-hoc mode to allow TSF updates +- * for the IBSS, but this breaks with additional AP or STA interfaces +- * at the moment. */ +- if (ah->num_adhoc_vifs || +- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { ++ /* Don't allow more than one ad-hoc interface */ ++ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) { + ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n"); + ret = -ELNRNG; + goto end; +--- a/drivers/net/wireless/ath/ath5k/base.c ++++ b/drivers/net/wireless/ath/ath5k/base.c +@@ -1868,7 +1868,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) + } + + if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + +- ah->num_mesh_vifs > 1) || ++ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) || + ah->opmode == NL80211_IFTYPE_MESH_POINT) { + u64 tsf = ath5k_hw_get_tsf64(ah); + u32 tsftu = TSF_TO_TU(tsf); +@@ -1954,7 +1954,7 @@ ath5k_beacon_update_timers(struct ath5k_ + + intval = ah->bintval & AR5K_BEACON_PERIOD; + if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +- + ah->num_mesh_vifs > 1) { ++ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) { + intval /= ATH_BCBUF; /* staggered multi-bss beacons */ + if (intval < 15) + ATH5K_WARN(ah, "intval %u is too low, min 15\n", +@@ -2418,6 +2418,7 @@ static const struct ieee80211_iface_limi + BIT(NL80211_IFTYPE_MESH_POINT) | + #endif + BIT(NL80211_IFTYPE_AP) }, ++ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) }, + }; + + static const struct ieee80211_iface_combination if_comb = { diff --git a/package/mac80211/patches/.svn/text-base/420-ath5k_disable_fast_cc.patch.svn-base b/package/mac80211/patches/.svn/text-base/420-ath5k_disable_fast_cc.patch.svn-base new file mode 100644 index 0000000..48b8467 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/420-ath5k_disable_fast_cc.patch.svn-base @@ -0,0 +1,18 @@ +--- a/drivers/net/wireless/ath/ath5k/reset.c ++++ b/drivers/net/wireless/ath/ath5k/reset.c +@@ -1158,6 +1158,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum + tsf_lo = 0; + mode = 0; + ++#if 0 + /* + * Sanity check for fast flag + * Fast channel change only available +@@ -1165,6 +1166,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum + */ + if (fast && (ah->ah_radio != AR5K_RF2413) && + (ah->ah_radio != AR5K_RF5413)) ++#endif + fast = false; + + /* Disable sleep clock operation diff --git a/package/mac80211/patches/.svn/text-base/430-add_ath5k_platform.patch.svn-base b/package/mac80211/patches/.svn/text-base/430-add_ath5k_platform.patch.svn-base new file mode 100644 index 0000000..b213e2a --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/430-add_ath5k_platform.patch.svn-base @@ -0,0 +1,33 @@ +--- /dev/null ++++ b/include/linux/ath5k_platform.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2008 Atheros Communications Inc. ++ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> ++ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> ++ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com> ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef _LINUX_ATH5K_PLATFORM_H ++#define _LINUX_ATH5K_PLATFORM_H ++ ++#define ATH5K_PLAT_EEP_MAX_WORDS 2048 ++ ++struct ath5k_platform_data { ++ u16 *eeprom_data; ++ u8 *macaddr; ++}; ++ ++#endif /* _LINUX_ATH5K_PLATFORM_H */ diff --git a/package/mac80211/patches/.svn/text-base/431-add_platform_eeprom_support_to_ath5k.patch.svn-base b/package/mac80211/patches/.svn/text-base/431-add_platform_eeprom_support_to_ath5k.patch.svn-base new file mode 100644 index 0000000..d4967b6 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/431-add_platform_eeprom_support_to_ath5k.patch.svn-base @@ -0,0 +1,56 @@ +--- a/drivers/net/wireless/ath/ath5k/pci.c ++++ b/drivers/net/wireless/ath/ath5k/pci.c +@@ -23,6 +23,7 @@ + #include <linux/pci-aspm.h> + #include <linux/etherdevice.h> + #include <linux/module.h> ++#include <linux/ath5k_platform.h> + #include "../ath.h" + #include "ath5k.h" + #include "debug.h" +@@ -74,7 +75,7 @@ static void ath5k_pci_read_cachesize(str + } + + /* +- * Read from eeprom ++ * Read from eeprom or platform_data + */ + static bool + ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) +@@ -82,6 +83,19 @@ ath5k_pci_eeprom_read(struct ath_common + struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; + u32 status, timeout; + ++ struct ath5k_platform_data *pdata = NULL; ++ ++ if (ah->pdev) ++ pdata = ah->pdev->dev.platform_data; ++ ++ if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) { ++ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS) ++ return false; ++ ++ *data = pdata->eeprom_data[offset]; ++ return true; ++ } ++ + /* + * Initialize EEPROM access + */ +@@ -125,6 +139,16 @@ static int ath5k_pci_eeprom_read_mac(str + u16 data; + int octet; + ++ struct ath5k_platform_data *pdata = NULL; ++ ++ if (ah->pdev) ++ pdata = ah->pdev->dev.platform_data; ++ ++ if (pdata && pdata->macaddr) { ++ memcpy(mac, pdata->macaddr, ETH_ALEN); ++ return 0; ++ } ++ + AR5K_EEPROM_READ(0x20, data); + + for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { diff --git a/package/mac80211/patches/.svn/text-base/432-ath5k_add_pciids.patch.svn-base b/package/mac80211/patches/.svn/text-base/432-ath5k_add_pciids.patch.svn-base new file mode 100644 index 0000000..8db5e1b --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/432-ath5k_add_pciids.patch.svn-base @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath5k/pci.c ++++ b/drivers/net/wireless/ath/ath5k/pci.c +@@ -50,6 +50,8 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci + { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ + { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ + { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ ++ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */ ++ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */ + { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ + { 0 } + }; diff --git a/package/mac80211/patches/.svn/text-base/440-ath5k_channel_bw_debugfs.patch.svn-base b/package/mac80211/patches/.svn/text-base/440-ath5k_channel_bw_debugfs.patch.svn-base new file mode 100644 index 0000000..f9c2a09 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/440-ath5k_channel_bw_debugfs.patch.svn-base @@ -0,0 +1,113 @@ +This adds a bwmode debugfs file which can be used to set alternate +channel operating bandwidths. Only tested with AR5413 and only at +5 and 20 mhz channels. + +Signed-off-by: Pat Erley <pat-lkml at erley.org> +--- +Other devices will need to be added to the switch in write_file_bwmode + +drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++ + 1 files changed, 86 insertions(+), 0 deletions(-) + +--- a/drivers/net/wireless/ath/ath5k/debug.c ++++ b/drivers/net/wireless/ath/ath5k/debug.c +@@ -813,6 +813,89 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++/* debugfs: bwmode */ ++ ++static ssize_t read_file_bwmode(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath5k_hw *ah = file->private_data; ++ char buf[15]; ++ unsigned int len = 0; ++ ++ int cur_ah_bwmode = ah->ah_bwmode; ++ ++#define print_selected(MODE, LABEL) \ ++ if (cur_ah_bwmode == MODE) \ ++ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \ ++ else \ ++ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \ ++ len += snprintf(buf+len, sizeof(buf)-len, " "); ++ ++ print_selected(AR5K_BWMODE_5MHZ, "5"); ++ print_selected(AR5K_BWMODE_10MHZ, "10"); ++ print_selected(AR5K_BWMODE_DEFAULT, "20"); ++ print_selected(AR5K_BWMODE_40MHZ, "40"); ++#undef print_selected ++ ++ len += snprintf(buf+len, sizeof(buf)-len, "\n"); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_bwmode(struct file *file, ++ const char __user *userbuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath5k_hw *ah = file->private_data; ++ char buf[3]; ++ int bw = 20; ++ int tobwmode = AR5K_BWMODE_DEFAULT; ++ ++ if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) ++ return -EFAULT; ++ ++ /* TODO: Add check for active interface */ ++ ++ if(strncmp(buf, "5", 1) == 0 ) { ++ tobwmode = AR5K_BWMODE_5MHZ; ++ bw = 5; ++ } else if ( strncmp(buf, "10", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_10MHZ; ++ bw = 10; ++ } else if ( strncmp(buf, "20", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_DEFAULT; ++ bw = 20; ++ } else if ( strncmp(buf, "40", 2) == 0 ) { ++ tobwmode = AR5K_BWMODE_40MHZ; ++ bw = 40; ++ } else ++ return -EINVAL; ++ ++ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n", ++ bw, tobwmode); ++ ++ switch (ah->ah_radio) { ++ /* TODO: only define radios that actually support 5/10mhz channels */ ++ case AR5K_RF5413: case AR5K_RF5110: case AR5K_RF5111: case AR5K_RF5112: case AR5K_RF2413: case AR5K_RF2316: case AR5K_RF2317: case AR5K_RF2425: ++ if(ah->ah_bwmode != tobwmode) { ++ mutex_lock(&ah->lock); ++ ah->ah_bwmode = tobwmode; ++ mutex_unlock(&ah->lock); ++ } ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ return count; ++} ++ ++static const struct file_operations fops_bwmode = { ++ .read = read_file_bwmode, ++ .write = write_file_bwmode, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; + + /* debugfs: queues etc */ + +@@ -904,6 +987,9 @@ ath5k_debug_init_device(struct ath5k_hw + debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah, + &fops_beacon); + ++ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah, ++ &fops_bwmode); ++ + debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset); + + debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah, diff --git a/package/mac80211/patches/.svn/text-base/500-ath9k_eeprom_debugfs.patch.svn-base b/package/mac80211/patches/.svn/text-base/500-ath9k_eeprom_debugfs.patch.svn-base new file mode 100644 index 0000000..285fce2 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/500-ath9k_eeprom_debugfs.patch.svn-base @@ -0,0 +1,65 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -2003,6 +2003,53 @@ void ath9k_get_et_stats(struct ieee80211 + WARN_ON(i != ATH9K_SSTATS_LEN); + } + ++static ssize_t read_file_eeprom(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); ++ int bytes = 0; ++ int pos = *ppos; ++ int size = 4096; ++ u16 val; ++ int i; ++ ++ if (AR_SREV_9300_20_OR_LATER(ah)) ++ size = 16384; ++ ++ if (*ppos < 0) ++ return -EINVAL; ++ ++ if (count > size - *ppos) ++ count = size - *ppos; ++ ++ for (i = *ppos / 2; count > 0; count -= bytes, *ppos += bytes, i++) { ++ void *from = &val; ++ ++ if (!common->bus_ops->eeprom_read(common, i, &val)) ++ val = 0xffff; ++ ++ if (*ppos % 2) { ++ from++; ++ bytes = 1; ++ } else if (count == 1) { ++ bytes = 1; ++ } else { ++ bytes = 2; ++ } ++ copy_to_user(user_buf, from, bytes); ++ user_buf += bytes; ++ } ++ return *ppos - pos; ++} ++ ++static const struct file_operations fops_eeprom = { ++ .read = read_file_eeprom, ++ .open = simple_open, ++ .owner = THIS_MODULE ++}; ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -2020,6 +2067,8 @@ int ath9k_init_debug(struct ath_hw *ah) + + ath9k_dfs_init_debug(sc); + ++ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, ++ &fops_eeprom); + debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_dma); + debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, diff --git a/package/mac80211/patches/.svn/text-base/501-ath9k-eeprom_endianess.patch.svn-base b/package/mac80211/patches/.svn/text-base/501-ath9k-eeprom_endianess.patch.svn-base new file mode 100644 index 0000000..bdd7e19 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/501-ath9k-eeprom_endianess.patch.svn-base @@ -0,0 +1,102 @@ +--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c +@@ -262,7 +262,7 @@ static int ath9k_hw_def_check_eeprom(str + { + struct ar5416_eeprom_def *eep = &ah->eeprom.def; + struct ath_common *common = ath9k_hw_common(ah); +- u16 *eepdata, temp, magic, magic2; ++ u16 *eepdata, temp, magic; + u32 sum = 0, el; + bool need_swap = false; + int i, addr, size; +@@ -272,27 +272,16 @@ static int ath9k_hw_def_check_eeprom(str + return false; + } + +- if (!ath9k_hw_use_flash(ah)) { +- ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic); +- +- if (magic != AR5416_EEPROM_MAGIC) { +- magic2 = swab16(magic); +- +- if (magic2 == AR5416_EEPROM_MAGIC) { +- size = sizeof(struct ar5416_eeprom_def); +- need_swap = true; +- eepdata = (u16 *) (&ah->eeprom); +- +- for (addr = 0; addr < size / sizeof(u16); addr++) { +- temp = swab16(*eepdata); +- *eepdata = temp; +- eepdata++; +- } +- } else { +- ath_err(common, +- "Invalid EEPROM Magic. Endianness mismatch.\n"); +- return -EINVAL; +- } ++ if (swab16(magic) == AR5416_EEPROM_MAGIC && ++ !(ah->ah_flags & AH_NO_EEP_SWAP)) { ++ size = sizeof(struct ar5416_eeprom_def); ++ need_swap = true; ++ eepdata = (u16 *) (&ah->eeprom); ++ ++ for (addr = 0; addr < size / sizeof(u16); addr++) { ++ temp = swab16(*eepdata); ++ *eepdata = temp; ++ eepdata++; + } + } + +--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c +@@ -57,7 +57,7 @@ static bool ath9k_hw_4k_fill_eeprom(stru + { + struct ath_common *common = ath9k_hw_common(ah); + +- if (!ath9k_hw_use_flash(ah)) { ++ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) { + ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n"); + } + +--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c ++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c +@@ -60,7 +60,7 @@ static bool ath9k_hw_ar9287_fill_eeprom( + { + struct ath_common *common = ath9k_hw_common(ah); + +- if (!ath9k_hw_use_flash(ah)) { ++ if (!(ah->ah_flags & AH_NO_EEP_SWAP)) { + ath_dbg(common, EEPROM, "Reading from EEPROM, not flash\n"); + } + +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -740,6 +740,7 @@ enum ath_cal_list { + #define AH_USE_EEPROM 0x1 + #define AH_UNPLUGGED 0x2 /* The card has been physically removed. */ + #define AH_FASTCC 0x4 ++#define AH_NO_EEP_SWAP 0x8 /* Do not swap EEPROM data */ + + struct ath_hw { + struct ath_ops reg_ops; +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -587,6 +587,8 @@ static int ath9k_init_softc(u16 devid, s + ah->is_clk_25mhz = pdata->is_clk_25mhz; + ah->get_mac_revision = pdata->get_mac_revision; + ah->external_reset = pdata->external_reset; ++ if (!pdata->endian_check) ++ ah->ah_flags |= AH_NO_EEP_SWAP; + } + + common = ath9k_hw_common(ah); +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -31,6 +31,7 @@ struct ath9k_platform_data { + u32 gpio_mask; + u32 gpio_val; + ++ bool endian_check; + bool is_clk_25mhz; + int (*get_mac_revision)(void); + int (*external_reset)(void); diff --git a/package/mac80211/patches/.svn/text-base/502-ath9k_ahb_init.patch.svn-base b/package/mac80211/patches/.svn/text-base/502-ath9k_ahb_init.patch.svn-base new file mode 100644 index 0000000..8884163 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/502-ath9k_ahb_init.patch.svn-base @@ -0,0 +1,32 @@ +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -965,23 +965,23 @@ static int __init ath9k_init(void) + goto err_out; + } + +- error = ath_pci_init(); ++ error = ath_ahb_init(); + if (error < 0) { +- pr_err("No PCI devices found, driver not installed\n"); + error = -ENODEV; + goto err_rate_unregister; + } + +- error = ath_ahb_init(); ++ error = ath_pci_init(); + if (error < 0) { ++ pr_err("No PCI devices found, driver not installed\n"); + error = -ENODEV; +- goto err_pci_exit; ++ goto err_ahb_exit; + } + + return 0; + +- err_pci_exit: +- ath_pci_exit(); ++ err_ahb_exit: ++ ath_ahb_exit(); + + err_rate_unregister: + ath_rate_control_unregister(); diff --git a/package/mac80211/patches/.svn/text-base/510-ath9k_intr_mitigation_tweak.patch.svn-base b/package/mac80211/patches/.svn/text-base/510-ath9k_intr_mitigation_tweak.patch.svn-base new file mode 100644 index 0000000..ff6ff27 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/510-ath9k_intr_mitigation_tweak.patch.svn-base @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1947,8 +1947,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st + REG_WRITE(ah, AR_OBS, 8); + + if (ah->config.rx_intr_mitigation) { +- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); +- REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); ++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 250); ++ REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 500); + } + + if (ah->config.tx_intr_mitigation) { diff --git a/package/mac80211/patches/.svn/text-base/511-ath9k_reduce_rxbuf.patch.svn-base b/package/mac80211/patches/.svn/text-base/511-ath9k_reduce_rxbuf.patch.svn-base new file mode 100644 index 0000000..8d8c5fd --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/511-ath9k_reduce_rxbuf.patch.svn-base @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -119,7 +119,7 @@ int ath_descdma_setup(struct ath_softc * + /* RX / TX */ + /***********/ + +-#define ATH_RXBUF 512 ++#define ATH_RXBUF 256 + #define ATH_TXBUF 512 + #define ATH_TXBUF_RESERVE 5 + #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) diff --git a/package/mac80211/patches/.svn/text-base/512-ath9k_channelbw_debugfs.patch.svn-base b/package/mac80211/patches/.svn/text-base/512-ath9k_channelbw_debugfs.patch.svn-base new file mode 100644 index 0000000..1af9de0 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/512-ath9k_channelbw_debugfs.patch.svn-base @@ -0,0 +1,128 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -690,6 +690,7 @@ struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; + ++ u32 chan_bw; + struct survey_info *cur_survey; + struct survey_info survey[ATH9K_NUM_CHANNELS]; + +@@ -894,6 +895,7 @@ struct fft_sample_ht20 { + u8 data[SPECTRAL_HT20_NUM_BINS]; + } __packed; + ++int ath9k_config(struct ieee80211_hw *hw, u32 changed); + void ath9k_tasklet(unsigned long data); + int ath_cabq_update(struct ath_softc *); + +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -2050,6 +2050,50 @@ static const struct file_operations fops + .owner = THIS_MODULE + }; + ++ ++static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "0x%08x\n", sc->chan_bw); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ unsigned long chan_bw; ++ char buf[32]; ++ ssize_t len; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (strict_strtoul(buf, 0, &chan_bw)) ++ return -EINVAL; ++ ++ sc->chan_bw = chan_bw; ++ if (!test_bit(SC_OP_INVALID, &sc->sc_flags)) ++ ath9k_config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL); ++ ++ return count; ++} ++ ++static const struct file_operations fops_chanbw = { ++ .read = read_file_chan_bw, ++ .write = write_file_chan_bw, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -2069,6 +2113,8 @@ int ath9k_init_debug(struct ath_hw *ah) + + debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_eeprom); ++ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ sc, &fops_chanbw); + debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_dma); + debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1131,7 +1131,7 @@ int ath9k_spectral_scan_config(struct ie + return 0; + } + +-static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ++int ath9k_config(struct ieee80211_hw *hw, u32 changed) + { + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; +@@ -1185,9 +1185,11 @@ static int ath9k_config(struct ieee80211 + + if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { + struct ieee80211_channel *curchan = hw->conf.channel; ++ struct ath9k_channel *hchan; + int pos = curchan->hw_value; + int old_pos = -1; + unsigned long flags; ++ u32 oldflags; + + if (ah->curchan) + old_pos = ah->curchan - &ah->channels[0]; +@@ -1230,7 +1232,23 @@ static int ath9k_config(struct ieee80211 + memset(&sc->survey[pos], 0, sizeof(struct survey_info)); + } + +- if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { ++ hchan = &sc->sc_ah->channels[pos]; ++ oldflags = hchan->channelFlags; ++ switch (sc->chan_bw) { ++ case 5: ++ hchan->channelFlags &= ~CHANNEL_HALF; ++ hchan->channelFlags |= CHANNEL_QUARTER; ++ break; ++ case 10: ++ hchan->channelFlags &= ~CHANNEL_QUARTER; ++ hchan->channelFlags |= CHANNEL_HALF; ++ break; ++ default: ++ hchan->channelFlags &= ~(CHANNEL_HALF | CHANNEL_QUARTER); ++ break; ++ } ++ ++ if (ath_set_channel(sc, hw, hchan) < 0) { + ath_err(common, "Unable to set channel\n"); + mutex_unlock(&sc->mutex); + ath9k_ps_restore(sc); diff --git a/package/mac80211/patches/.svn/text-base/513-mac80211_reduce_txqueuelen.patch.svn-base b/package/mac80211/patches/.svn/text-base/513-mac80211_reduce_txqueuelen.patch.svn-base new file mode 100644 index 0000000..fe44cdb --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/513-mac80211_reduce_txqueuelen.patch.svn-base @@ -0,0 +1,10 @@ +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -995,6 +995,7 @@ static const struct net_device_ops ieee8 + static void ieee80211_if_setup(struct net_device *dev) + { + ether_setup(dev); ++ dev->tx_queue_len = 32; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; + netdev_attach_ops(dev, &ieee80211_dataif_ops); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) diff --git a/package/mac80211/patches/.svn/text-base/520-mac80211_cur_txpower.patch.svn-base b/package/mac80211/patches/.svn/text-base/520-mac80211_cur_txpower.patch.svn-base new file mode 100644 index 0000000..f0ed3d9 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/520-mac80211_cur_txpower.patch.svn-base @@ -0,0 +1,33 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1554,6 +1554,7 @@ struct ieee80211_hw { + u8 max_tx_aggregation_subframes; + u8 offchannel_tx_hw_queue; + u8 radiotap_mcs_details; ++ s8 cur_power_level; + u16 radiotap_vht_details; + netdev_features_t netdev_features; + }; +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2190,7 +2190,9 @@ static int ieee80211_get_tx_power(struct + struct ieee80211_local *local = wiphy_priv(wiphy); + struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); + +- if (!local->use_chanctx) ++ if (local->hw.cur_power_level) ++ *dbm = local->hw.cur_power_level; ++ else if (!local->use_chanctx) + *dbm = local->hw.conf.power_level; + else + *dbm = sdata->vif.bss_conf.txpower; +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -166,6 +166,7 @@ static u32 ieee80211_hw_conf_chan(struct + + if (local->hw.conf.power_level != power) { + changed |= IEEE80211_CONF_CHANGE_POWER; ++ local->hw.cur_power_level = power; + local->hw.conf.power_level = power; + } + diff --git a/package/mac80211/patches/.svn/text-base/521-ath9k_cur_txpower.patch.svn-base b/package/mac80211/patches/.svn/text-base/521-ath9k_cur_txpower.patch.svn-base new file mode 100644 index 0000000..fc091f2 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/521-ath9k_cur_txpower.patch.svn-base @@ -0,0 +1,19 @@ +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1255,6 +1255,8 @@ int ath9k_config(struct ieee80211_hw *hw + return -EINVAL; + } + ++ hw->cur_power_level = sc->curtxpow / 2; ++ + /* + * The most recent snapshot of channel->noisefloor for the old + * channel is only available after the hardware reset. Copy it to +@@ -1274,6 +1276,7 @@ int ath9k_config(struct ieee80211_hw *hw + sc->config.txpowlimit = 2 * conf->power_level; + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); ++ hw->cur_power_level = sc->curtxpow / 2; + } + + mutex_unlock(&sc->mutex); diff --git a/package/mac80211/patches/.svn/text-base/522-ath9k_per_chain_signal_strength.patch.svn-base b/package/mac80211/patches/.svn/text-base/522-ath9k_per_chain_signal_strength.patch.svn-base new file mode 100644 index 0000000..c0feedd --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/522-ath9k_per_chain_signal_strength.patch.svn-base @@ -0,0 +1,393 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -839,6 +839,9 @@ enum mac80211_rx_flags { + * @signal: signal strength when receiving this frame, either in dBm, in dB or + * unspecified depending on the hardware capabilities flags + * @IEEE80211_HW_SIGNAL_* ++ * @chains: bitmask of receive chains for which separate signal strength ++ * values were filled. ++ * @chain_signal: per-chain signal strength, same format as @signal + * @antenna: antenna used + * @rate_idx: index of data rate into band's supported rates or MCS index if + * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) +@@ -870,6 +873,8 @@ struct ieee80211_rx_status { + u8 band; + u8 antenna; + s8 signal; ++ u8 chains; ++ s8 chain_signal[4]; + u8 ampdu_delimiter_crc; + u8 vendor_radiotap_align; + u8 vendor_radiotap_oui[3]; +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -342,6 +342,11 @@ struct sta_info { + int last_signal; + struct ewma avg_signal; + int last_ack_signal; ++ ++ u8 chains; ++ s8 chain_signal_last[4]; ++ struct ewma chain_signal_avg[4]; ++ + /* Plus 1 for non-QoS frames */ + __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1]; + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1383,6 +1383,7 @@ ieee80211_rx_h_sta_process(struct ieee80 + struct sk_buff *skb = rx->skb; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ int i; + + if (!sta) + return RX_CONTINUE; +@@ -1433,6 +1434,19 @@ ieee80211_rx_h_sta_process(struct ieee80 + ewma_add(&sta->avg_signal, -status->signal); + } + ++ if (status->chains) { ++ sta->chains = status->chains; ++ for (i = 0; i < 4; i++) { ++ int signal = status->chain_signal[i]; ++ ++ if (!(status->chains & BIT(i))) ++ continue; ++ ++ sta->chain_signal_last[i] = signal; ++ ewma_add(&sta->chain_signal_avg[i], -signal); ++ } ++ } ++ + /* + * Change STA power saving mode only at the end of a frame + * exchange sequence. +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -353,6 +353,8 @@ struct sta_info *sta_info_alloc(struct i + do_posix_clock_monotonic_gettime(&uptime); + sta->last_connected = uptime.tv_sec; + ewma_init(&sta->avg_signal, 1024, 8); ++ for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) ++ ewma_init(&sta->chain_signal_avg[i], 1024, 8); + + if (sta_prepare_rate_control(local, sta, gfp)) { + kfree(sta); +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -721,6 +721,8 @@ struct station_parameters { + * @STATION_INFO_LOCAL_PM: @local_pm filled + * @STATION_INFO_PEER_PM: @peer_pm filled + * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled ++ * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled ++ * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled + */ + enum station_info_flags { + STATION_INFO_INACTIVE_TIME = 1<<0, +@@ -749,6 +751,8 @@ enum station_info_flags { + STATION_INFO_NONPEER_PM = 1<<23, + STATION_INFO_RX_BYTES64 = 1<<24, + STATION_INFO_TX_BYTES64 = 1<<25, ++ STATION_INFO_CHAIN_SIGNAL = 1<<26, ++ STATION_INFO_CHAIN_SIGNAL_AVG = 1<<27, + }; + + /** +@@ -842,6 +846,9 @@ struct sta_bss_parameters { + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. ++ * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg ++ * @chain_signal: per-chain signal strength of last received packet in dBm ++ * @chain_signal_avg: per-chain signal strength average in dBm + * @txrate: current unicast bitrate from this station + * @rxrate: current unicast bitrate to this station + * @rx_packets: packets received from this station +@@ -877,6 +884,11 @@ struct station_info { + u8 plink_state; + s8 signal; + s8 signal_avg; ++ ++ u8 chains; ++ s8 chain_signal[4]; ++ s8 chain_signal_avg[4]; ++ + struct rate_info txrate; + struct rate_info rxrate; + u32 rx_packets; +--- a/drivers/net/wireless/ath/ath9k/mac.h ++++ b/drivers/net/wireless/ath/ath9k/mac.h +@@ -133,12 +133,8 @@ struct ath_rx_status { + u8 rs_rate; + u8 rs_antenna; + u8 rs_more; +- int8_t rs_rssi_ctl0; +- int8_t rs_rssi_ctl1; +- int8_t rs_rssi_ctl2; +- int8_t rs_rssi_ext0; +- int8_t rs_rssi_ext1; +- int8_t rs_rssi_ext2; ++ int8_t rs_rssi_ctl[3]; ++ int8_t rs_rssi_ext[3]; + u8 rs_isaggr; + u8 rs_moreaggr; + u8 rs_num_delims; +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -937,6 +937,7 @@ static int ath9k_rx_skb_preprocess(struc + bool *decrypt_error) + { + struct ath_hw *ah = common->ah; ++ int i, j; + + /* + * everything but the rate is checked here, the rate check is done +@@ -962,6 +963,20 @@ static int ath9k_rx_skb_preprocess(struc + if (rx_stats->rs_moreaggr) + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + ++ for (i = 0, j = 0; i < ARRAY_SIZE(rx_stats->rs_rssi_ctl); i++) { ++ s8 rssi; ++ ++ if (!(ah->rxchainmask & BIT(i))) ++ continue; ++ ++ rssi = rx_stats->rs_rssi_ctl[i]; ++ if (rssi != ATH9K_RSSI_BAD) { ++ rx_status->chains |= BIT(j); ++ rx_status->chain_signal[j] = ah->noise + rssi; ++ } ++ j++; ++ } ++ + return 0; + } + +@@ -1070,7 +1085,7 @@ static int ath_process_fft(struct ath_so + fft_sample.tlv.length = __cpu_to_be16(length); + + fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq); +- fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0); ++ fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl[0]); + fft_sample.noise = ah->noise; + + switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) { +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -475,12 +475,12 @@ int ath9k_hw_process_rxdesc_edma(struct + + /* XXX: Keycache */ + rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined); +- rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00); +- rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01); +- rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02); +- rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10); +- rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11); +- rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12); ++ rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00); ++ rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01); ++ rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02); ++ rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10); ++ rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11); ++ rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12); + + if (rxsp->status11 & AR_RxKeyIdxValid) + rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx); +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -553,25 +553,25 @@ int ath9k_hw_rxprocdesc(struct ath_hw *a + + if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { + rs->rs_rssi = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext0 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext1 = ATH9K_RSSI_BAD; +- rs->rs_rssi_ext2 = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD; ++ rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD; + } else { + rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); +- rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt00); +- rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt01); +- rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0, ++ rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0, + AR_RxRSSIAnt02); +- rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt10); +- rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt11); +- rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4, ++ rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4, + AR_RxRSSIAnt12); + } + if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -940,12 +940,12 @@ void ath_debug_stat_rx(struct ath_softc + #ifdef CONFIG_ATH9K_MAC_DEBUG + spin_lock(&sc->debug.samp_lock); + RX_SAMP_DBG(jiffies) = jiffies; +- RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; +- RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1; +- RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2; +- RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0; +- RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1; +- RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2; ++ RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl[0]; ++ RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl[1]; ++ RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl[2]; ++ RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext[0]; ++ RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext[1]; ++ RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext[2]; + RX_SAMP_DBG(antenna) = rs->rs_antenna; + RX_SAMP_DBG(rssi) = rs->rs_rssi; + RX_SAMP_DBG(rate) = rs->rs_rate; +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -1918,6 +1918,8 @@ enum nl80211_sta_bss_param { + * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode + * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards + * non-peer STA ++ * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU ++ * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average + * @__NL80211_STA_INFO_AFTER_LAST: internal + * @NL80211_STA_INFO_MAX: highest possible station info attribute + */ +@@ -1947,6 +1949,8 @@ enum nl80211_sta_info { + NL80211_STA_INFO_NONPEER_PM, + NL80211_STA_INFO_RX_BYTES64, + NL80211_STA_INFO_TX_BYTES64, ++ NL80211_STA_INFO_CHAIN_SIGNAL, ++ NL80211_STA_INFO_CHAIN_SIGNAL_AVG, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3082,6 +3082,32 @@ static bool nl80211_put_sta_rate(struct + return true; + } + ++static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal, ++ int id) ++{ ++ void *attr; ++ int i = 0; ++ ++ if (!mask) ++ return true; ++ ++ attr = nla_nest_start(msg, id); ++ if (!attr) ++ return false; ++ ++ for (i = 0; i < 4; i++) { ++ if (!(mask & BIT(i))) ++ continue; ++ ++ if (nla_put_u8(msg, i, signal[i])) ++ return false; ++ } ++ ++ nla_nest_end(msg, attr); ++ ++ return true; ++} ++ + static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, + int flags, + struct cfg80211_registered_device *rdev, +@@ -3153,6 +3179,18 @@ static int nl80211_send_station(struct s + default: + break; + } ++ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) { ++ if (!nl80211_put_signal(msg, sinfo->chains, ++ sinfo->chain_signal, ++ NL80211_STA_INFO_CHAIN_SIGNAL)) ++ goto nla_put_failure; ++ } ++ if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) { ++ if (!nl80211_put_signal(msg, sinfo->chains, ++ sinfo->chain_signal_avg, ++ NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) ++ goto nla_put_failure; ++ } + if (sinfo->filled & STATION_INFO_TX_BITRATE) { + if (!nl80211_put_sta_rate(msg, &sinfo->txrate, + NL80211_STA_INFO_TX_BITRATE)) +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -445,6 +445,7 @@ static void sta_set_sinfo(struct sta_inf + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_local *local = sdata->local; + struct timespec uptime; ++ int i; + + sinfo->generation = sdata->local->sta_generation; + +@@ -484,6 +485,17 @@ static void sta_set_sinfo(struct sta_inf + sinfo->signal = (s8)sta->last_signal; + sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); + } ++ if (sta->chains) { ++ sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | ++ STATION_INFO_CHAIN_SIGNAL_AVG; ++ ++ sinfo->chains = sta->chains; ++ for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { ++ sinfo->chain_signal[i] = sta->chain_signal_last[i]; ++ sinfo->chain_signal_avg[i] = ++ (s8) -ewma_read(&sta->chain_signal_avg[i]); ++ } ++ } + + sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); + sta_set_rate_info_rx(sta, &sinfo->rxrate); +--- a/drivers/net/wireless/ath/ath9k/dfs.c ++++ b/drivers/net/wireless/ath/ath9k/dfs.c +@@ -164,8 +164,8 @@ void ath9k_dfs_process_phyerr(struct ath + return; + } + +- ard.rssi = rs->rs_rssi_ctl0; +- ard.ext_rssi = rs->rs_rssi_ext0; ++ ard.rssi = rs->rs_rssi_ctl[0]; ++ ard.ext_rssi = rs->rs_rssi_ext[0]; + + /* + * hardware stores this as 8 bit signed value. +--- a/drivers/net/wireless/ath/ath9k/antenna.c ++++ b/drivers/net/wireless/ath/ath9k/antenna.c +@@ -546,14 +546,14 @@ void ath_ant_comb_scan(struct ath_softc + struct ath_ant_comb *antcomb = &sc->ant_comb; + int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; + int curr_main_set; +- int main_rssi = rs->rs_rssi_ctl0; +- int alt_rssi = rs->rs_rssi_ctl1; ++ int main_rssi = rs->rs_rssi_ctl[0]; ++ int alt_rssi = rs->rs_rssi_ctl[1]; + int rx_ant_conf, main_ant_conf; + bool short_scan = false; + +- rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & ++ rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) & + ATH_ANT_RX_MASK; +- main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & ++ main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) & + ATH_ANT_RX_MASK; + + /* Record packet only when both main_rssi and alt_rssi is positive */ diff --git a/package/mac80211/patches/.svn/text-base/523-mac80211_configure_antenna_gain.patch.svn-base b/package/mac80211/patches/.svn/text-base/523-mac80211_configure_antenna_gain.patch.svn-base new file mode 100644 index 0000000..8c13f32 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/523-mac80211_configure_antenna_gain.patch.svn-base @@ -0,0 +1,162 @@ +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -978,6 +978,7 @@ enum ieee80211_smps_mode { + * + * @power_level: requested transmit power (in dBm), backward compatibility + * value only that is set to the minimum of all interfaces ++ * @max_antenna_gain: maximum antenna gain adjusted by user config (in dBi) + * + * @channel: the channel to tune to + * @channel_type: the channel (HT) type +@@ -1000,6 +1001,7 @@ struct ieee80211_conf { + u32 flags; + int power_level, dynamic_ps_timeout; + int max_sleep_period; ++ int max_antenna_gain; + + u16 listen_interval; + u8 ps_dtim_period; +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1116,6 +1116,7 @@ struct ieee80211_local { + int dynamic_ps_forced_timeout; + + int user_power_level; /* in dBm, for all interfaces */ ++ int user_antenna_gain; /* in dBi */ + + enum ieee80211_smps_mode smps_mode; + +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -1654,6 +1654,8 @@ enum nl80211_attrs { + NL80211_ATTR_STA_CAPABILITY, + NL80211_ATTR_STA_EXT_CAPABILITY, + ++ NL80211_ATTR_WIPHY_ANTENNA_GAIN, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -370,6 +370,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, + [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 }, + [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, }, ++ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, + }; + + /* policy for the key attributes */ +@@ -1705,6 +1706,22 @@ static int nl80211_set_wiphy(struct sk_b + if (result) + goto bad_res; + } ++ ++ if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) { ++ int idx, dbi = 0; ++ ++ if (!rdev->ops->set_antenna_gain) { ++ result = -EOPNOTSUPP; ++ goto bad_res; ++ } ++ ++ idx = NL80211_ATTR_WIPHY_ANTENNA_GAIN; ++ dbi = nla_get_u32(info->attrs[idx]); ++ ++ result = rdev->ops->set_antenna_gain(&rdev->wiphy, dbi); ++ if (result) ++ goto bad_res; ++ } + + if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && + info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2212,6 +2212,19 @@ static int ieee80211_get_tx_power(struct + return 0; + } + ++static int ieee80211_set_antenna_gain(struct wiphy *wiphy, int dbi) ++{ ++ struct ieee80211_local *local = wiphy_priv(wiphy); ++ ++ if (dbi < 0) ++ return -EINVAL; ++ ++ local->user_antenna_gain = dbi; ++ ieee80211_hw_config(local, 0); ++ ++ return 0; ++} ++ + static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr) + { +@@ -3375,6 +3388,7 @@ struct cfg80211_ops mac80211_config_ops + .set_wiphy_params = ieee80211_set_wiphy_params, + .set_tx_power = ieee80211_set_tx_power, + .get_tx_power = ieee80211_get_tx_power, ++ .set_antenna_gain = ieee80211_set_antenna_gain, + .set_wds_peer = ieee80211_set_wds_peer, + .rfkill_poll = ieee80211_rfkill_poll, + CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -1862,6 +1862,7 @@ struct cfg80211_gtk_rekey_data { + * (as advertised by the nl80211 feature flag.) + * @get_tx_power: store the current TX power into the dbm variable; + * return 0 if successful ++ * @set_antenna_gain: set antenna gain to reduce maximum tx power if necessary + * + * @set_wds_peer: set the WDS peer for a WDS interface + * +@@ -2071,6 +2072,7 @@ struct cfg80211_ops { + enum nl80211_tx_power_setting type, int mbm); + int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, + int *dbm); ++ int (*set_antenna_gain)(struct wiphy *wiphy, int dbi); + + int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr); +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -101,7 +101,7 @@ static u32 ieee80211_hw_conf_chan(struct + struct ieee80211_sub_if_data *sdata; + struct ieee80211_channel *chan; + u32 changed = 0; +- int power; ++ int power, ant_gain, max_power; + enum nl80211_channel_type channel_type; + u32 offchannel_flag; + bool scanning = false; +@@ -164,8 +164,21 @@ static u32 ieee80211_hw_conf_chan(struct + } + rcu_read_unlock(); + +- if (local->hw.conf.power_level != power) { ++ max_power = chan->max_reg_power; ++ ant_gain = chan->max_antenna_gain; ++ if (local->user_antenna_gain > 0) { ++ if (local->user_antenna_gain > ant_gain) { ++ max_power -= local->user_antenna_gain - ant_gain; ++ ant_gain = 0; ++ } else ++ ant_gain -= local->user_antenna_gain; ++ power = min(power, max_power); ++ } ++ ++ if (local->hw.conf.power_level != power || ++ local->hw.conf.max_antenna_gain != ant_gain) { + changed |= IEEE80211_CONF_CHANGE_POWER; ++ local->hw.conf.max_antenna_gain = ant_gain; + local->hw.cur_power_level = power; + local->hw.conf.power_level = power; + } +@@ -612,6 +625,7 @@ struct ieee80211_hw *ieee80211_alloc_hw( + IEEE80211_RADIOTAP_MCS_HAVE_BW; + local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | + IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; ++ local->user_antenna_gain = 0; + local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; + wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; + diff --git a/package/mac80211/patches/.svn/text-base/524-ath9k_use_configured_antenna_gain.patch.svn-base b/package/mac80211/patches/.svn/text-base/524-ath9k_use_configured_antenna_gain.patch.svn-base new file mode 100644 index 0000000..fe05212 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/524-ath9k_use_configured_antenna_gain.patch.svn-base @@ -0,0 +1,34 @@ +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -73,6 +73,7 @@ struct ath_regulatory { + u16 max_power_level; + u16 current_rd; + int16_t power_limit; ++ int16_t max_antenna_gain; + struct reg_dmn_pair_mapping *regpair; + }; + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2818,7 +2818,7 @@ 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; ++ max_gain = chan_pwr - new_pwr + reg->max_antenna_gain * 2; + + ant_gain = get_antenna_gain(ah, chan); + if (ant_gain > max_gain) +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1272,7 +1272,10 @@ int ath9k_config(struct ieee80211_hw *hw + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { ++ struct ath_regulatory *reg = ath9k_hw_regulatory(ah); ++ + ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level); ++ reg->max_antenna_gain = conf->max_antenna_gain; + sc->config.txpowlimit = 2 * conf->power_level; + ath9k_cmn_update_txpow(ah, sc->curtxpow, + sc->config.txpowlimit, &sc->curtxpow); diff --git a/package/mac80211/patches/.svn/text-base/530-ath9k_extra_leds.patch.svn-base b/package/mac80211/patches/.svn/text-base/530-ath9k_extra_leds.patch.svn-base new file mode 100644 index 0000000..a13cb41 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/530-ath9k_extra_leds.patch.svn-base @@ -0,0 +1,248 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -551,6 +551,9 @@ struct ath9k_wow_pattern { + void ath_init_leds(struct ath_softc *sc); + void ath_deinit_leds(struct ath_softc *sc); + void ath_fill_led_pin(struct ath_softc *sc); ++int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name, ++ const char *trigger, bool active_low); ++ + #else + static inline void ath_init_leds(struct ath_softc *sc) + { +@@ -686,6 +689,13 @@ enum spectral_mode { + SPECTRAL_CHANSCAN, + }; + ++struct ath_led { ++ struct list_head list; ++ struct ath_softc *sc; ++ const struct gpio_led *gpio; ++ struct led_classdev cdev; ++}; ++ + struct ath_softc { + struct ieee80211_hw *hw; + struct device *dev; +@@ -727,9 +737,8 @@ struct ath_softc { + struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; + + #ifdef CONFIG_MAC80211_LEDS +- bool led_registered; +- char led_name[32]; +- struct led_classdev led_cdev; ++ const char *led_default_trigger; ++ struct list_head leds; + #endif + + struct ath9k_hw_cal_data caldata; +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -24,40 +24,102 @@ + static void ath_led_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) + { +- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); +- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF)); ++ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev); ++ struct ath_softc *sc = led->sc; ++ ++ ath9k_ps_wakeup(sc); ++ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio, ++ (brightness != LED_OFF) ^ led->gpio->active_low); ++ ath9k_ps_restore(sc); ++} ++ ++static int ath_add_led(struct ath_softc *sc, struct ath_led *led) ++{ ++ const struct gpio_led *gpio = led->gpio; ++ int ret; ++ ++ led->cdev.name = gpio->name; ++ led->cdev.default_trigger = gpio->default_trigger; ++ led->cdev.brightness_set = ath_led_brightness; ++ ++ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev); ++ if (ret < 0) ++ return ret; ++ ++ led->sc = sc; ++ list_add(&led->list, &sc->leds); ++ ++ /* Configure gpio for output */ ++ ath9k_hw_cfg_output(sc->sc_ah, gpio->gpio, ++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ++ ++ /* LED off */ ++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); ++ ++ return 0; ++} ++ ++int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name, ++ const char *trigger, bool active_low) ++{ ++ struct ath_led *led; ++ struct gpio_led *gpio; ++ char *_name; ++ int ret; ++ ++ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1, ++ GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio = (struct gpio_led *) (led + 1); ++ _name = (char *) (led->gpio + 1); ++ ++ strcpy(_name, name); ++ gpio->name = _name; ++ gpio->gpio = gpio_num; ++ gpio->active_low = active_low; ++ gpio->default_trigger = trigger; ++ ++ ret = ath_add_led(sc, led); ++ if (unlikely(ret < 0)) ++ kfree(led); ++ ++ return ret; + } + + void ath_deinit_leds(struct ath_softc *sc) + { +- if (!sc->led_registered) +- return; ++ struct ath_led *led; + +- ath_led_brightness(&sc->led_cdev, LED_OFF); +- led_classdev_unregister(&sc->led_cdev); ++ while (!list_empty(&sc->leds)) { ++ led = list_first_entry(&sc->leds, struct ath_led, list); ++ list_del(&led->list); ++ ath_led_brightness(&led->cdev, LED_OFF); ++ led_classdev_unregister(&led->cdev); ++ kfree(led); ++ } + } + + void ath_init_leds(struct ath_softc *sc) + { +- int ret; ++ char led_name[32]; ++ const char *trigger; ++ ++ INIT_LIST_HEAD(&sc->leds); + + if (AR_SREV_9100(sc->sc_ah)) + return; + +- if (!led_blink) +- sc->led_cdev.default_trigger = +- ieee80211_get_radio_led_name(sc->hw); +- +- snprintf(sc->led_name, sizeof(sc->led_name), +- "ath9k-%s", wiphy_name(sc->hw->wiphy)); +- sc->led_cdev.name = sc->led_name; +- sc->led_cdev.brightness_set = ath_led_brightness; ++ snprintf(led_name, sizeof(led_name), "ath9k-%s", ++ wiphy_name(sc->hw->wiphy)); + +- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev); +- if (ret < 0) +- return; ++ if (led_blink) ++ trigger = sc->led_default_trigger; ++ else ++ trigger = ieee80211_get_radio_led_name(sc->hw); + +- sc->led_registered = true; ++ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1); + } + + void ath_fill_led_pin(struct ath_softc *sc) +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -870,7 +870,7 @@ int ath9k_init_device(u16 devid, struct + + #ifdef CONFIG_MAC80211_LEDS + /* must be initialized before ieee80211_register_hw */ +- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, ++ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, + ARRAY_SIZE(ath9k_tpt_blink)); + #endif +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1482,6 +1482,61 @@ static const struct file_operations fops + .llseek = default_llseek, + }; + ++#ifdef CONFIG_MAC80211_LEDS ++ ++static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32], *str, *name, *c; ++ ssize_t len; ++ unsigned int gpio; ++ bool active_low = false; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, ubuf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ name = strchr(buf, ','); ++ if (!name) ++ return -EINVAL; ++ ++ *(name++) = 0; ++ if (!*name) ++ return -EINVAL; ++ ++ c = strchr(name, '\n'); ++ if (c) ++ *c = 0; ++ ++ str = buf; ++ if (*str == '!') { ++ str++; ++ active_low = true; ++ } ++ ++ if (kstrtouint(str, 0, &gpio) < 0) ++ return -EINVAL; ++ ++ if (gpio >= sc->sc_ah->caps.num_gpio_pins) ++ return -EINVAL; ++ ++ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0) ++ return -EINVAL; ++ ++ return count; ++} ++ ++static const struct file_operations fops_gpio_led = { ++ .write = write_file_gpio_led, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++#endif ++ + #ifdef CONFIG_ATH9K_MAC_DEBUG + + void ath9k_debug_samp_bb_mac(struct ath_softc *sc) +@@ -2115,6 +2170,10 @@ int ath9k_init_debug(struct ath_hw *ah) + &fops_eeprom); + debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + sc, &fops_chanbw); ++#ifdef CONFIG_MAC80211_LEDS ++ debugfs_create_file("gpio_led", S_IWUSR, ++ sc->debug.debugfs_phy, sc, &fops_gpio_led); ++#endif + debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_dma); + debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, diff --git a/package/mac80211/patches/.svn/text-base/531-ath9k_extra_platform_leds.patch.svn-base b/package/mac80211/patches/.svn/text-base/531-ath9k_extra_platform_leds.patch.svn-base new file mode 100644 index 0000000..d07fc4e --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/531-ath9k_extra_platform_leds.patch.svn-base @@ -0,0 +1,71 @@ +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -35,6 +35,9 @@ struct ath9k_platform_data { + bool is_clk_25mhz; + int (*get_mac_revision)(void); + int (*external_reset)(void); ++ ++ int num_leds; ++ const struct gpio_led *leds; + }; + + #endif /* _LINUX_ATH9K_PLATFORM_H */ +--- a/drivers/net/wireless/ath/ath9k/gpio.c ++++ b/drivers/net/wireless/ath/ath9k/gpio.c +@@ -14,6 +14,7 @@ + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++#include <linux/ath9k_platform.h> + #include "ath9k.h" + + /********************************/ +@@ -88,6 +89,24 @@ int ath_create_gpio_led(struct ath_softc + return ret; + } + ++static int ath_create_platform_led(struct ath_softc *sc, ++ const struct gpio_led *gpio) ++{ ++ struct ath_led *led; ++ int ret; ++ ++ led = kzalloc(sizeof(*led), GFP_KERNEL); ++ if (!led) ++ return -ENOMEM; ++ ++ led->gpio = gpio; ++ ret = ath_add_led(sc, led); ++ if (ret < 0) ++ kfree(led); ++ ++ return ret; ++} ++ + void ath_deinit_leds(struct ath_softc *sc) + { + struct ath_led *led; +@@ -103,8 +122,10 @@ void ath_deinit_leds(struct ath_softc *s + + void ath_init_leds(struct ath_softc *sc) + { ++ struct ath9k_platform_data *pdata = sc->dev->platform_data; + char led_name[32]; + const char *trigger; ++ int i; + + INIT_LIST_HEAD(&sc->leds); + +@@ -120,6 +141,12 @@ void ath_init_leds(struct ath_softc *sc) + trigger = ieee80211_get_radio_led_name(sc->hw); + + ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, 1); ++ ++ if (!pdata) ++ return; ++ ++ for (i = 0; i < pdata->num_leds; i++) ++ ath_create_platform_led(sc, &pdata->leds[i]); + } + + void ath_fill_led_pin(struct ath_softc *sc) diff --git a/package/mac80211/patches/.svn/text-base/540-mac80211_optimize_mcs_rate_mask.patch.svn-base b/package/mac80211/patches/.svn/text-base/540-mac80211_optimize_mcs_rate_mask.patch.svn-base new file mode 100644 index 0000000..347c920 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/540-mac80211_optimize_mcs_rate_mask.patch.svn-base @@ -0,0 +1,98 @@ +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -739,6 +739,8 @@ struct ieee80211_sub_if_data { + + /* bitmap of allowed (non-MCS) rate indexes for rate control */ + u32 rc_rateidx_mask[IEEE80211_NUM_BANDS]; ++ ++ bool rc_has_mcs_mask[IEEE80211_NUM_BANDS]; + u8 rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN]; + + union { +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -2386,9 +2386,20 @@ static int ieee80211_set_bitrate_mask(st + } + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { ++ struct ieee80211_supported_band *sband = wiphy->bands[i]; ++ + sdata->rc_rateidx_mask[i] = mask->control[i].legacy; + memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs, + sizeof(mask->control[i].mcs)); ++ ++ sdata->rc_has_mcs_mask[i] = false; ++ if (!sband) ++ continue; ++ ++ if (memcmp(sdata->rc_rateidx_mcs_mask[i], ++ sband->ht_cap.mcs.rx_mask, ++ sizeof(sband->ht_cap.mcs.rx_mask)) != 0) ++ sdata->rc_has_mcs_mask[i] = true; + } + + return 0; +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -4091,7 +4091,7 @@ void ieee80211_send_bar(struct ieee80211 + * (deprecated; this will be removed once drivers get updated to use + * rate_idx_mask) + * @rate_idx_mask: user-requested (legacy) rate mask +- * @rate_idx_mcs_mask: user-requested MCS rate mask ++ * @rate_idx_mcs_mask: user-requested MCS rate mask (NULL if not in use) + * @bss: whether this frame is sent out in AP or IBSS mode + */ + struct ieee80211_tx_rate_control { +@@ -4103,7 +4103,7 @@ struct ieee80211_tx_rate_control { + bool rts, short_preamble; + u8 max_rate_idx; + u32 rate_idx_mask; +- u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN]; ++ u8 *rate_idx_mcs_mask; + bool bss; + }; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -641,9 +641,11 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 + txrc.max_rate_idx = -1; + else + txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; +- memcpy(txrc.rate_idx_mcs_mask, +- tx->sdata->rc_rateidx_mcs_mask[info->band], +- sizeof(txrc.rate_idx_mcs_mask)); ++ ++ if (tx->sdata->rc_has_mcs_mask[info->band]) ++ txrc.rate_idx_mcs_mask = ++ tx->sdata->rc_rateidx_mcs_mask[info->band]; ++ + txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP || + tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT || + tx->sdata->vif.type == NL80211_IFTYPE_ADHOC); +@@ -2511,8 +2513,6 @@ struct sk_buff *ieee80211_beacon_get_tim + txrc.max_rate_idx = -1; + else + txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1; +- memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band], +- sizeof(txrc.rate_idx_mcs_mask)); + txrc.bss = true; + rate_control_get_rate(sdata, NULL, &txrc); + +--- a/net/mac80211/rate.c ++++ b/net/mac80211/rate.c +@@ -460,9 +460,12 @@ void rate_control_get_rate(struct ieee80 + * the common case. + */ + mask = sdata->rc_rateidx_mask[info->band]; +- memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band], +- sizeof(mcs_mask)); +- if (mask != (1 << txrc->sband->n_bitrates) - 1) { ++ if (mask != (1 << txrc->sband->n_bitrates) - 1 || txrc->rate_idx_mcs_mask) { ++ if (txrc->rate_idx_mcs_mask) ++ memcpy(mcs_mask, txrc->rate_idx_mcs_mask, sizeof(mcs_mask)); ++ else ++ memset(mcs_mask, 0xff, sizeof(mcs_mask)); ++ + if (sta) { + /* Filter out rates that the STA does not support */ + mask &= sta->sta.supp_rates[info->band]; diff --git a/package/mac80211/patches/.svn/text-base/541-ath9k_optimize_interrupt_mitigation.patch.svn-base b/package/mac80211/patches/.svn/text-base/541-ath9k_optimize_interrupt_mitigation.patch.svn-base new file mode 100644 index 0000000..95ceb35 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/541-ath9k_optimize_interrupt_mitigation.patch.svn-base @@ -0,0 +1,30 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c +@@ -241,21 +241,19 @@ static bool ar9003_hw_get_isr(struct ath + + *masked = isr & ATH9K_INT_COMMON; + +- if (ah->config.rx_intr_mitigation) ++ if (ah->config.rx_intr_mitigation) { + if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) + *masked |= ATH9K_INT_RXLP; +- +- if (ah->config.tx_intr_mitigation) +- if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) +- *masked |= ATH9K_INT_TX; +- +- if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) ++ } else if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) + *masked |= ATH9K_INT_RXLP; + + if (isr & AR_ISR_HP_RXOK) + *masked |= ATH9K_INT_RXHP; + +- if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) { ++ if (ah->config.tx_intr_mitigation) { ++ if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) ++ *masked |= ATH9K_INT_TX; ++ } else if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) { + *masked |= ATH9K_INT_TX; + + if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { diff --git a/package/mac80211/patches/.svn/text-base/550-ath9k_reduce_ani_interval.patch.svn-base b/package/mac80211/patches/.svn/text-base/550-ath9k_reduce_ani_interval.patch.svn-base new file mode 100644 index 0000000..e2a0d12 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/550-ath9k_reduce_ani_interval.patch.svn-base @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/ath/ath9k/ani.h ++++ b/drivers/net/wireless/ath/ath9k/ani.h +@@ -51,7 +51,7 @@ + #define ATH9K_ANI_PERIOD 300 + + /* in ms */ +-#define ATH9K_ANI_POLLINTERVAL 1000 ++#define ATH9K_ANI_POLLINTERVAL 100 + + #define HAL_NOISE_IMMUNE_MAX 4 + #define HAL_SPUR_IMMUNE_MAX 7 diff --git a/package/mac80211/patches/.svn/text-base/551-ath9k_revert_initval_change.patch.svn-base b/package/mac80211/patches/.svn/text-base/551-ath9k_revert_initval_change.patch.svn-base new file mode 100644 index 0000000..ffb08bf --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/551-ath9k_revert_initval_change.patch.svn-base @@ -0,0 +1,19 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +@@ -958,11 +958,11 @@ static const u32 ar9300Common_rx_gain_ta + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, +- {0x0000a080, 0x1a1a1a1a}, +- {0x0000a084, 0x1a1a1a1a}, +- {0x0000a088, 0x1a1a1a1a}, +- {0x0000a08c, 0x1a1a1a1a}, +- {0x0000a090, 0x171a1a1a}, ++ {0x0000a080, 0x22222229}, ++ {0x0000a084, 0x1d1d1d1d}, ++ {0x0000a088, 0x1d1d1d1d}, ++ {0x0000a08c, 0x1d1d1d1d}, ++ {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, diff --git a/package/mac80211/patches/.svn/text-base/552-ath9k_rx_dma_stop_check.patch.svn-base b/package/mac80211/patches/.svn/text-base/552-ath9k_rx_dma_stop_check.patch.svn-base new file mode 100644 index 0000000..1da7207 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/552-ath9k_rx_dma_stop_check.patch.svn-base @@ -0,0 +1,28 @@ +--- a/drivers/net/wireless/ath/ath9k/mac.c ++++ b/drivers/net/wireless/ath/ath9k/mac.c +@@ -689,7 +689,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw + { + #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ + struct ath_common *common = ath9k_hw_common(ah); +- u32 mac_status, last_mac_status = 0; ++ u32 mac_status = 0, last_mac_status = 0; + int i; + + /* Enable access to the DMA observation bus */ +@@ -719,6 +719,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw + } + + if (i == 0) { ++ if (!AR_SREV_9300_20_OR_LATER(ah) && ++ (mac_status & 0x700) == 0) { ++ /* ++ * DMA is idle but the MAC is still stuck ++ * processing events ++ */ ++ *reset = true; ++ return true; ++ } ++ + ath_err(common, + "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n", + AH_RX_STOP_DMA_TIMEOUT / 1000, diff --git a/package/mac80211/patches/.svn/text-base/553-ath9k_debugfs_diag.patch.svn-base b/package/mac80211/patches/.svn/text-base/553-ath9k_debugfs_diag.patch.svn-base new file mode 100644 index 0000000..915f30f --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/553-ath9k_debugfs_diag.patch.svn-base @@ -0,0 +1,139 @@ +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -2149,6 +2149,50 @@ static const struct file_operations fops + }; + + ++static ssize_t read_file_diag(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "0x%08lx\n", ah->diag); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_diag(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_hw *ah = sc->sc_ah; ++ unsigned long diag; ++ char buf[32]; ++ ssize_t len; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ buf[len] = '\0'; ++ if (strict_strtoul(buf, 0, &diag)) ++ return -EINVAL; ++ ++ ah->diag = diag; ++ ath9k_hw_update_diag(ah); ++ ++ return count; ++} ++ ++static const struct file_operations fops_diag = { ++ .read = read_file_diag, ++ .write = write_file_diag, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++ + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -2174,6 +2218,8 @@ int ath9k_init_debug(struct ath_hw *ah) + debugfs_create_file("gpio_led", S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_gpio_led); + #endif ++ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, ++ sc, &fops_diag); + debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_dma); + debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -500,6 +500,12 @@ enum { + ATH9K_RESET_COLD, + }; + ++enum { ++ ATH_DIAG_DISABLE_RX, ++ ATH_DIAG_DISABLE_TX, ++ ATH_DIAG_TRIGGER_ERROR, ++}; ++ + struct ath9k_hw_version { + u32 magic; + u16 devid; +@@ -778,6 +784,8 @@ struct ath_hw { + u32 rfkill_polarity; + u32 ah_flags; + ++ unsigned long diag; ++ + bool reset_power_on; + bool htc_reset_init; + +@@ -1041,6 +1049,7 @@ void ath9k_hw_set_sta_beacon_timers(stru + bool ath9k_hw_check_alive(struct ath_hw *ah); + + bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); ++void ath9k_hw_update_diag(struct ath_hw *ah); + + #ifdef CONFIG_ATH9K_DEBUGFS + void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause); +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1747,6 +1747,20 @@ fail: + return -EINVAL; + } + ++void ath9k_hw_update_diag(struct ath_hw *ah) ++{ ++ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag)) ++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); ++ else ++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); ++ ++ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag)) ++ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); ++ else ++ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK); ++} ++EXPORT_SYMBOL(ath9k_hw_update_diag); ++ + int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata, bool fastcc) + { +@@ -2024,6 +2038,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st + } + + ath9k_hw_apply_gpio_override(ah); ++ ath9k_hw_update_diag(ah); + + if (AR_SREV_9565(ah) && ah->shared_chain_lnadiv) + REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -459,6 +459,11 @@ irqreturn_t ath_isr(int irq, void *dev) + ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ + status &= ah->imask; /* discard unasked-for bits */ + ++ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) { ++ status |= ATH9K_INT_FATAL; ++ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag); ++ } ++ + /* + * If there are no status bits set, then this interrupt was not + * for me (should have been caught above). diff --git a/package/mac80211/patches/.svn/text-base/554-ath9k_ani_mrc_fix.patch.svn-base b/package/mac80211/patches/.svn/text-base/554-ath9k_ani_mrc_fix.patch.svn-base new file mode 100644 index 0000000..6edc8ef --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/554-ath9k_ani_mrc_fix.patch.svn-base @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -1075,6 +1075,10 @@ static bool ar9003_hw_ani_control(struct + * is_on == 0 means MRC CCK is OFF (more noise imm) + */ + bool is_on = param ? 1 : 0; ++ ++ if (ah->caps.rx_chainmask == 1) ++ break; ++ + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, + AR_PHY_MRC_CCK_ENABLE, is_on); + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, diff --git a/package/mac80211/patches/.svn/text-base/555-ath9k-allow-to-disable-bands-via-platform-data.patch.svn-base b/package/mac80211/patches/.svn/text-base/555-ath9k-allow-to-disable-bands-via-platform-data.patch.svn-base new file mode 100644 index 0000000..515bb8f --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/555-ath9k-allow-to-disable-bands-via-platform-data.patch.svn-base @@ -0,0 +1,70 @@ +--- a/include/linux/ath9k_platform.h ++++ b/include/linux/ath9k_platform.h +@@ -33,6 +33,9 @@ struct ath9k_platform_data { + + bool endian_check; + bool is_clk_25mhz; ++ bool disable_2ghz; ++ bool disable_5ghz; ++ + int (*get_mac_revision)(void); + int (*external_reset)(void); + +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -2414,17 +2414,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw + } + + eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); +- if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) { +- ath_err(common, +- "no band has been marked as supported in EEPROM\n"); +- return -EINVAL; ++ ++ if (eeval & AR5416_OPFLAGS_11A) { ++ if (ah->disable_5ghz) ++ ath_warn(common, "disabling 5GHz band\n"); ++ else ++ pCap->hw_caps |= ATH9K_HW_CAP_5GHZ; + } + +- if (eeval & AR5416_OPFLAGS_11A) +- pCap->hw_caps |= ATH9K_HW_CAP_5GHZ; ++ if (eeval & AR5416_OPFLAGS_11G) { ++ if (ah->disable_2ghz) ++ ath_warn(common, "disabling 2GHz band\n"); ++ else ++ pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; ++ } + +- if (eeval & AR5416_OPFLAGS_11G) +- pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; ++ if ((pCap->hw_caps & (ATH9K_HW_CAP_2GHZ | ATH9K_HW_CAP_5GHZ)) == 0) { ++ ath_err(common, "both bands are disabled\n"); ++ return -EINVAL; ++ } + + if (AR_SREV_9485(ah) || + AR_SREV_9285(ah) || +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -961,6 +961,8 @@ struct ath_hw { + bool is_clk_25mhz; + int (*get_mac_revision)(void); + int (*external_reset)(void); ++ bool disable_2ghz; ++ bool disable_5ghz; + + const struct firmware *eeprom_blob; + }; +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -587,6 +587,8 @@ static int ath9k_init_softc(u16 devid, s + ah->is_clk_25mhz = pdata->is_clk_25mhz; + ah->get_mac_revision = pdata->get_mac_revision; + ah->external_reset = pdata->external_reset; ++ ah->disable_2ghz = pdata->disable_2ghz; ++ ah->disable_5ghz = pdata->disable_5ghz; + if (!pdata->endian_check) + ah->ah_flags |= AH_NO_EEP_SWAP; + } diff --git a/package/mac80211/patches/.svn/text-base/600-rt2x00-disable-pci-code-if-CONFIG_PCI-not-defined.patch.svn-base b/package/mac80211/patches/.svn/text-base/600-rt2x00-disable-pci-code-if-CONFIG_PCI-not-defined.patch.svn-base new file mode 100644 index 0000000..a7609ed --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/600-rt2x00-disable-pci-code-if-CONFIG_PCI-not-defined.patch.svn-base @@ -0,0 +1,18 @@ +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -208,6 +208,7 @@ void rt2x00pci_uninitialize(struct rt2x0 + } + EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); + ++#ifdef CONFIG_PCI + /* + * PCI driver handlers. + */ +@@ -392,6 +393,7 @@ int rt2x00pci_resume(struct pci_dev *pci + } + EXPORT_SYMBOL_GPL(rt2x00pci_resume); + #endif /* CONFIG_PM */ ++#endif /* CONFIG_PCI */ + + /* + * rt2x00pci module information. diff --git a/package/mac80211/patches/.svn/text-base/601-rt2x00-set_pci_mwi.patch.svn-base b/package/mac80211/patches/.svn/text-base/601-rt2x00-set_pci_mwi.patch.svn-base new file mode 100644 index 0000000..9ff50b7 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/601-rt2x00-set_pci_mwi.patch.svn-base @@ -0,0 +1,13 @@ +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -273,8 +273,10 @@ int rt2x00pci_probe(struct pci_dev *pci_ + + pci_set_master(pci_dev); + ++#ifdef CONFIG_PCI_SET_MWI + if (pci_set_mwi(pci_dev)) + ERROR_PROBE("MWI not available.\n"); ++#endif + + if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { + ERROR_PROBE("PCI DMA not supported.\n"); diff --git a/package/mac80211/patches/.svn/text-base/602-rt2x00-introduce-rt2x00_platform_h.patch.svn-base b/package/mac80211/patches/.svn/text-base/602-rt2x00-introduce-rt2x00_platform_h.patch.svn-base new file mode 100644 index 0000000..6c80c3d --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/602-rt2x00-introduce-rt2x00_platform_h.patch.svn-base @@ -0,0 +1,32 @@ +--- /dev/null ++++ b/include/linux/rt2x00_platform.h +@@ -0,0 +1,19 @@ ++/* ++ * Platform data definition for the rt2x00 driver ++ * ++ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ */ ++ ++#ifndef _RT2X00_PLATFORM_H ++#define _RT2X00_PLATFORM_H ++ ++struct rt2x00_platform_data { ++ char *eeprom_file_name; ++}; ++ ++#endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -39,6 +39,7 @@ + #include <linux/input-polldev.h> + #include <linux/kfifo.h> + #include <linux/hrtimer.h> ++#include <linux/rt2x00_platform.h> + + #include <net/mac80211.h> + diff --git a/package/mac80211/patches/.svn/text-base/603-rt2x00-introduce-rt2x00eeprom.patch.svn-base b/package/mac80211/patches/.svn/text-base/603-rt2x00-introduce-rt2x00eeprom.patch.svn-base new file mode 100644 index 0000000..6b1f030 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/603-rt2x00-introduce-rt2x00eeprom.patch.svn-base @@ -0,0 +1,279 @@ +--- /dev/null ++++ b/drivers/net/wireless/rt2x00/rt2x00eeprom.c +@@ -0,0 +1,98 @@ ++/* ++ Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> ++ Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com> ++ <http://rt2x00.serialmonkey.com> ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the ++ Free Software Foundation, Inc., ++ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ Module: rt2x00lib ++ Abstract: rt2x00 eeprom file loading routines. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++ ++#include "rt2x00.h" ++#include "rt2x00lib.h" ++ ++static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ const struct firmware *ee; ++ char *ee_name; ++ int retval; ++ ++ ee_name = rt2x00dev->ops->lib->get_eeprom_file_name(rt2x00dev); ++ if (!ee_name) { ++ ERROR(rt2x00dev, ++ "Invalid EEPROM filename.\n" ++ "Please file bug report to %s.\n", DRV_PROJECT); ++ return -EINVAL; ++ } ++ ++ INFO(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name); ++ ++ retval = request_firmware(&ee, ee_name, rt2x00dev->dev); ++ if (retval) { ++ ERROR(rt2x00dev, "Failed to request EEPROM.\n"); ++ return retval; ++ } ++ ++ if (!ee || !ee->size || !ee->data) { ++ ERROR(rt2x00dev, "Failed to read EEPROM file.\n"); ++ retval = -ENOENT; ++ goto err_exit; ++ } ++ ++ if (ee->size != rt2x00dev->ops->eeprom_size) { ++ ERROR(rt2x00dev, ++ "EEPROM file size is invalid, it should be %d bytes\n", ++ rt2x00dev->ops->eeprom_size); ++ retval = -EINVAL; ++ goto err_release_ee; ++ } ++ ++ rt2x00dev->eeprom_file = ee; ++ return 0; ++ ++err_release_ee: ++ release_firmware(ee); ++err_exit: ++ return retval; ++} ++ ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ int retval; ++ ++ if (!test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) ++ return 0; ++ ++ if (!rt2x00dev->eeprom_file) { ++ retval = rt2x00lib_request_eeprom_file(rt2x00dev); ++ if (retval) ++ return retval; ++ } ++ ++ return 0; ++} ++ ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ release_firmware(rt2x00dev->eeprom_file); ++ rt2x00dev->eeprom_file = NULL; ++} +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -559,6 +559,7 @@ struct rt2x00lib_ops { + const u8 *data, const size_t len); + int (*load_firmware) (struct rt2x00_dev *rt2x00dev, + const u8 *data, const size_t len); ++ char *(*get_eeprom_file_name) (struct rt2x00_dev *rt2x00dev); + + /* + * Device initialization/deinitialization handlers. +@@ -719,6 +720,7 @@ enum rt2x00_capability_flags { + REQUIRE_SW_SEQNO, + REQUIRE_HT_TX_DESC, + REQUIRE_PS_AUTOWAKE, ++ REQUIRE_EEPROM_FILE, + + /* + * Capabilities +@@ -988,6 +990,11 @@ struct rt2x00_dev { + const struct firmware *fw; + + /* ++ * EEPROM image. ++ */ ++ const struct firmware *eeprom_file; ++ ++ /* + * FIFO for storing tx status reports between isr and tasklet. + */ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); +--- a/drivers/net/wireless/rt2x00/rt2x00lib.h ++++ b/drivers/net/wireless/rt2x00/rt2x00lib.h +@@ -322,6 +322,22 @@ static inline void rt2x00lib_free_firmwa + #endif /* CONFIG_RT2X00_LIB_FIRMWARE */ + + /* ++ * EEPROM file handlers. ++ */ ++#ifdef CONFIG_RT2X00_LIB_EEPROM ++int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev); ++void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev); ++#else ++static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++ return 0; ++} ++static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev) ++{ ++} ++#endif /* CONFIG_RT2X00_LIB_EEPROM_FILE */ ++ ++/* + * Debugfs handlers. + */ + #ifdef CONFIG_RT2X00_LIB_DEBUGFS +--- a/drivers/net/wireless/rt2x00/Kconfig ++++ b/drivers/net/wireless/rt2x00/Kconfig +@@ -60,6 +60,7 @@ config RT2800PCI + select RT2X00_LIB_PCI if PCI + select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X + select RT2X00_LIB_FIRMWARE ++ select RT2X00_LIB_EEPROM + select RT2X00_LIB_CRYPTO + select CRC_CCITT + select EEPROM_93CX6 +@@ -212,6 +213,9 @@ config RT2X00_LIB_FIRMWARE + config RT2X00_LIB_CRYPTO + boolean + ++config RT2X00_LIB_EEPROM ++ boolean ++ + config RT2X00_LIB_LEDS + boolean + default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) +--- a/drivers/net/wireless/rt2x00/Makefile ++++ b/drivers/net/wireless/rt2x00/Makefile +@@ -7,6 +7,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) + + rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o + rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o + rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o ++rt2x00lib-$(CONFIG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o + + obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o + obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o +--- a/drivers/net/wireless/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/rt2x00/rt2800pci.c +@@ -89,25 +89,11 @@ static void rt2800pci_mcu_status(struct + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + } + +-#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) + static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) + { +- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); +- +- if (!base_addr) +- return -ENOMEM; +- +- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); +- +- iounmap(base_addr); ++ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE); + return 0; + } +-#else +-static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) +-{ +- return -ENOMEM; +-} +-#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ + + #ifdef CONFIG_PCI + static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) +@@ -331,6 +317,20 @@ static int rt2800pci_write_firmware(stru + } + + /* ++ * EEPROM file functions. ++ */ ++static char *rt2800pci_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev) ++{ ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata) ++ return pdata->eeprom_file_name; ++ ++ return NULL; ++} ++ ++/* + * Initialization functions. + */ + static bool rt2800pci_get_entry_state(struct queue_entry *entry) +@@ -1046,6 +1046,7 @@ static const struct rt2x00lib_ops rt2800 + .get_firmware_name = rt2800pci_get_firmware_name, + .check_firmware = rt2800_check_firmware, + .load_firmware = rt2800_load_firmware, ++ .get_eeprom_file_name = rt2800pci_get_eeprom_file_name, + .initialize = rt2x00pci_initialize, + .uninitialize = rt2x00pci_uninitialize, + .get_entry_state = rt2800pci_get_entry_state, +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -1318,6 +1318,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de + + rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + ++ retval = rt2x00lib_load_eeprom_file(rt2x00dev); ++ if (retval) ++ goto exit; ++ + /* + * Initialize work. + */ +@@ -1442,6 +1446,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ + */ + if (rt2x00dev->drv_data) + kfree(rt2x00dev->drv_data); ++ ++ /* ++ * Free EEPROM image. ++ */ ++ rt2x00lib_free_eeprom_file(rt2x00dev); + } + EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); + +--- a/drivers/net/wireless/rt2x00/rt2x00soc.c ++++ b/drivers/net/wireless/rt2x00/rt2x00soc.c +@@ -94,6 +94,7 @@ int rt2x00soc_probe(struct platform_devi + rt2x00dev->hw = hw; + rt2x00dev->irq = platform_get_irq(pdev, 0); + rt2x00dev->name = pdev->dev.driver->name; ++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); + + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); + diff --git a/package/mac80211/patches/.svn/text-base/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch.svn-base b/package/mac80211/patches/.svn/text-base/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch.svn-base new file mode 100644 index 0000000..d9f1764 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/604-rt2x00-add-CONFIG_RT2X00_LIB_EEPROM-option.patch.svn-base @@ -0,0 +1,10 @@ +--- a/config.mk ++++ b/config.mk +@@ -640,6 +640,7 @@ export CONFIG_RT2X00=y + export CONFIG_RT2X00_LIB=m + export CONFIG_RT2800_LIB=m + export CONFIG_RT2X00_LIB_FIRMWARE=y ++export CONFIG_RT2X00_LIB_EEPROM=y + export CONFIG_RT2X00_LIB_CRYPTO=y + # export CONFIG_RT2X00_LIB_SOC=y + ifdef CONFIG_COMPAT_KERNEL_2_6_25 diff --git a/package/mac80211/patches/.svn/text-base/605-rt2x00-pci-eeprom.patch.svn-base b/package/mac80211/patches/.svn/text-base/605-rt2x00-pci-eeprom.patch.svn-base new file mode 100644 index 0000000..25b21ce --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/605-rt2x00-pci-eeprom.patch.svn-base @@ -0,0 +1,46 @@ +--- a/drivers/net/wireless/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/rt2x00/rt2800pci.c +@@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + } + +-static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) ++static int rt2800pci_read_eeprom_file(struct rt2x00_dev *rt2x00dev) + { + memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data, EEPROM_SIZE); + return 0; +@@ -983,8 +983,9 @@ static int rt2800pci_read_eeprom(struct + { + int retval; + +- if (rt2x00_is_soc(rt2x00dev)) +- retval = rt2800pci_read_eeprom_soc(rt2x00dev); ++ if (rt2x00_is_soc(rt2x00dev) || ++ test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) ++ retval = rt2800pci_read_eeprom_file(rt2x00dev); + else if (rt2800pci_efuse_detect(rt2x00dev)) + retval = rt2800pci_read_eeprom_efuse(rt2x00dev); + else +--- a/drivers/net/wireless/rt2x00/rt2x00pci.c ++++ b/drivers/net/wireless/rt2x00/rt2x00pci.c +@@ -255,6 +255,7 @@ exit: + int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) + { + struct ieee80211_hw *hw; ++ struct rt2x00_platform_data *pdata; + struct rt2x00_dev *rt2x00dev; + int retval; + u16 chip; +@@ -300,6 +301,12 @@ int rt2x00pci_probe(struct pci_dev *pci_ + rt2x00dev->irq = pci_dev->irq; + rt2x00dev->name = pci_name(pci_dev); + ++ /* if we get passed the name of a eeprom_file_name, then use this in ++ favour of the eeprom */ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata && pdata->eeprom_file_name) ++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags); ++ + if (pci_is_pcie(pci_dev)) + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); + else diff --git a/package/mac80211/patches/.svn/text-base/606-rt2x00_no_realign.patch.svn-base b/package/mac80211/patches/.svn/text-base/606-rt2x00_no_realign.patch.svn-base new file mode 100644 index 0000000..2025701 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/606-rt2x00_no_realign.patch.svn-base @@ -0,0 +1,67 @@ +[RFC] rt2x00: For drivers that only need L2 padding don't realign frames + +Signed-off-by: Helmut Schaa <helmut.schaa@...> +--- + +Ivo, Gertjan, do you remeber by any chance why this alignment stuff was added +in the first place? Was it because of DMA restrictions? + +While doing some profiling on the rt3052 SoC I noticed that 30-40% time was +spent in memmove calls. And the culprit is the memmove aligning the payload +to a 4byte boundary since that has to move a whole bunch of data. + +Interesstingly the legacy drivers insert an l2pad between the header and the +payload but doesn't realign the payload itself to a 4-byte boundary. Hence, +I came up with this patch and indeed CPU usage improves impressively. + +Only tested on rt2800pci! + +Thanks, +Helmut + + drivers/net/wireless/rt2x00/rt2x00queue.c | 30 +++------------------------- + 1 files changed, 4 insertions(+), 26 deletions(-) + +--- a/drivers/net/wireless/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c +@@ -162,36 +162,14 @@ void rt2x00queue_align_frame(struct sk_b + void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) + { + unsigned int payload_length = skb->len - header_length; +- unsigned int header_align = ALIGN_SIZE(skb, 0); +- unsigned int payload_align = ALIGN_SIZE(skb, header_length); + unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0; + +- /* +- * Adjust the header alignment if the payload needs to be moved more +- * than the header. +- */ +- if (payload_align > header_align) +- header_align += 4; +- +- /* There is nothing to do if no alignment is needed */ +- if (!header_align) ++ if (!l2pad) + return; + +- /* Reserve the amount of space needed in front of the frame */ +- skb_push(skb, header_align); +- +- /* +- * Move the header. +- */ +- memmove(skb->data, skb->data + header_align, header_length); +- +- /* Move the payload, if present and if required */ +- if (payload_length && payload_align) +- memmove(skb->data + header_length + l2pad, +- skb->data + header_length + l2pad + payload_align, +- payload_length); +- +- /* Trim the skb to the correct size */ ++ /* insert l2pad -> Move header */ ++ skb_push(skb, l2pad); ++ memmove(skb->data, skb->data + l2pad, header_length); + skb_trim(skb, header_length + l2pad + payload_length); + } + diff --git a/package/mac80211/patches/.svn/text-base/607-rt2x00-allow_disabling_bands_through_platform_data.patch.svn-base b/package/mac80211/patches/.svn/text-base/607-rt2x00-allow_disabling_bands_through_platform_data.patch.svn-base new file mode 100644 index 0000000..0b0c30e --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/607-rt2x00-allow_disabling_bands_through_platform_data.patch.svn-base @@ -0,0 +1,47 @@ +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,9 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ ++ int disable_2ghz; ++ int disable_5ghz; + }; + + #endif /* _RT2X00_PLATFORM_H */ +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -939,6 +939,22 @@ static int rt2x00lib_probe_hw_modes(stru + unsigned int num_rates; + unsigned int i; + ++ if (rt2x00dev->dev->platform_data) { ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (pdata->disable_2ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_2GHZ; ++ if (pdata->disable_5ghz) ++ spec->supported_bands &= ~SUPPORT_BAND_5GHZ; ++ } ++ ++ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) { ++ ERROR(rt2x00dev, "No supported bands\n"); ++ return -EINVAL; ++ } ++ ++ + num_rates = 0; + if (spec->supported_rates & SUPPORT_RATE_CCK) + num_rates += 4; +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -424,6 +424,7 @@ struct hw_mode_spec { + unsigned int supported_bands; + #define SUPPORT_BAND_2GHZ 0x00000001 + #define SUPPORT_BAND_5GHZ 0x00000002 ++#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ) + + unsigned int supported_rates; + #define SUPPORT_RATE_CCK 0x00000001 diff --git a/package/mac80211/patches/.svn/text-base/608-add_platform_data_mac_addr.patch.svn-base b/package/mac80211/patches/.svn/text-base/608-add_platform_data_mac_addr.patch.svn-base new file mode 100644 index 0000000..bb77df9 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/608-add_platform_data_mac_addr.patch.svn-base @@ -0,0 +1,63 @@ +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -14,6 +14,7 @@ + + struct rt2x00_platform_data { + char *eeprom_file_name; ++ const u8 *mac_address; + + int disable_2ghz; + int disable_5ghz; +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -930,6 +930,18 @@ static void rt2x00lib_rate(struct ieee80 + entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; + } + ++const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev) ++{ ++ struct rt2x00_platform_data *pdata; ++ ++ pdata = rt2x00dev->dev->platform_data; ++ if (!pdata) ++ return NULL; ++ ++ return pdata->mac_address; ++} ++EXPORT_SYMBOL_GPL(rt2x00lib_get_mac_address); ++ + static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, + struct hw_mode_spec *spec) + { +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -1314,6 +1314,7 @@ static inline void rt2x00debug_dump_fram + */ + u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif); ++const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev); + + /* + * Interrupt context handlers. +--- a/drivers/net/wireless/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/rt2x00/rt61pci.c +@@ -2392,6 +2392,7 @@ static int rt61pci_validate_eeprom(struc + u32 reg; + u16 word; + u8 *mac; ++ const u8 *pdata_mac; + s8 value; + + rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, ®); +@@ -2412,7 +2413,11 @@ static int rt61pci_validate_eeprom(struc + /* + * Start validation of the data that has been read. + */ ++ pdata_mac = rt2x00lib_get_mac_address(rt2x00dev); + mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); ++ if (pdata_mac) ++ memcpy(mac, pdata_mac, 6); ++ + if (!is_valid_ether_addr(mac)) { + eth_random_addr(mac); + EEPROM(rt2x00dev, "MAC: %pM\n", mac); diff --git a/package/mac80211/patches/.svn/text-base/610-rt2x00-fix-rt3352-ext-pa.patch.svn-base b/package/mac80211/patches/.svn/text-base/610-rt2x00-fix-rt3352-ext-pa.patch.svn-base new file mode 100644 index 0000000..bf070e6 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/610-rt2x00-fix-rt3352-ext-pa.patch.svn-base @@ -0,0 +1,214 @@ +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2249,15 +2249,18 @@ static void rt2800_config_channel(struct + /* + * Change BBP settings + */ ++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); ++ + if (rt2x00_rt(rt2x00dev, RT3352)) { + rt2800_bbp_write(rt2x00dev, 27, 0x0); + rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 27, 0x20); + rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 86, 0x38); ++ rt2800_bbp_write(rt2x00dev, 83, 0x6a); + } else { +- rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); +- rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); +- rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 86, 0); + } + +@@ -3670,6 +3673,7 @@ static int rt2800_init_bbp(struct rt2x00 + rt2800_bbp_write(rt2x00dev, 120, 0x50); + + if (rt2x00_rt(rt2x00dev, RT3290) || ++ rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 128, 0x12); +@@ -3976,6 +3980,12 @@ static void rt2800_init_rfcsr_3290(struc + + static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) + { ++ int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0, ++ &rt2x00dev->cap_flags); ++ int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1, ++ &rt2x00dev->cap_flags); ++ u8 rfcsr; ++ + rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); + rt2800_rfcsr_write(rt2x00dev, 1, 0x23); + rt2800_rfcsr_write(rt2x00dev, 2, 0x50); +@@ -4009,15 +4019,30 @@ static void rt2800_init_rfcsr_3352(struc + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); +- rt2800_rfcsr_write(rt2x00dev, 34, 0x01); ++ rfcsr = 0x01; ++ if (!tx0_int_pa) ++ rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1); ++ if (!tx1_int_pa) ++ rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1); ++ rt2800_rfcsr_write(rt2x00dev, 34, rfcsr ); + rt2800_rfcsr_write(rt2x00dev, 35, 0x03); + rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); + rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); + rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); + rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); + rt2800_rfcsr_write(rt2x00dev, 40, 0x33); +- rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); +- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); ++ rfcsr = 0x52; ++ if (tx0_int_pa) { ++ rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1); ++ } ++ rt2800_rfcsr_write(rt2x00dev, 41, rfcsr); ++ rfcsr = 0x52; ++ if (tx1_int_pa) { ++ rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1); ++ } ++ rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); + rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); + rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); + rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); +@@ -4025,15 +4050,20 @@ static void rt2800_init_rfcsr_3352(struc + rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); + rt2800_rfcsr_write(rt2x00dev, 48, 0x14); + rt2800_rfcsr_write(rt2x00dev, 49, 0x00); +- rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); +- rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); +- rt2800_rfcsr_write(rt2x00dev, 52, 0x00); +- rt2800_rfcsr_write(rt2x00dev, 53, 0x52); +- rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); +- rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); +- rt2800_rfcsr_write(rt2x00dev, 56, 0x00); +- rt2800_rfcsr_write(rt2x00dev, 57, 0x52); +- rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); ++ rfcsr = 0x2d; ++ if (!tx0_int_pa) ++ rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1); ++ if (!tx1_int_pa) ++ rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1); ++ rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); ++ rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52)); ++ rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0)); ++ rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2)); ++ rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0)); ++ rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52)); ++ rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0)); ++ rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49)); ++ rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0)); + rt2800_rfcsr_write(rt2x00dev, 59, 0x00); + rt2800_rfcsr_write(rt2x00dev, 60, 0x00); + rt2800_rfcsr_write(rt2x00dev, 61, 0x00); +@@ -4949,7 +4979,8 @@ static int rt2800_init_eeprom(struct rt2 + /* + * Detect if this device has Bluetooth co-existence. + */ +- if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) ++ if (!rt2x00_rt(rt2x00dev, RT3352) && ++ rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) + __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags); + + /* +@@ -4978,6 +5009,22 @@ static int rt2800_init_eeprom(struct rt2 + EIRP_MAX_TX_POWER_LIMIT) + __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); + ++ /* ++ * Detect if device uses internal or external PA ++ */ ++ rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); ++ ++ if (rt2x00_rt(rt2x00dev, RT3352)) { ++ if (!rt2x00_get_field16(eeprom, ++ EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) ++ __set_bit(CAPABILITY_INTERNAL_PA_TX0, ++ &rt2x00dev->cap_flags); ++ if (!rt2x00_get_field16(eeprom, ++ EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352)) ++ __set_bit(CAPABILITY_INTERNAL_PA_TX1, ++ &rt2x00dev->cap_flags); ++ } ++ + return 0; + } + +--- a/drivers/net/wireless/rt2x00/rt2800.h ++++ b/drivers/net/wireless/rt2x00/rt2800.h +@@ -2117,6 +2117,12 @@ struct mac_iveiv_entry { + #define RFCSR31_RX_CALIB FIELD8(0x7f) + + /* ++ * RFCSR 34: ++ */ ++#define RFCSR34_TX0_EXT_PA FIELD8(0x04) ++#define RFCSR34_TX1_EXT_PA FIELD8(0x08) ++ ++/* + * RFCSR 38: + */ + #define RFCSR38_RX_LO1_EN FIELD8(0x20) +@@ -2127,6 +2133,18 @@ struct mac_iveiv_entry { + #define RFCSR39_RX_LO2_EN FIELD8(0x80) + + /* ++ * RFCSR 41: ++ */ ++#define RFCSR41_BIT1 FIELD8(0x01) ++#define RFCSR41_BIT4 FIELD8(0x08) ++ ++/* ++ * RFCSR 42: ++ */ ++#define RFCSR42_BIT1 FIELD8(0x01) ++#define RFCSR42_BIT4 FIELD8(0x08) ++ ++/* + * RFCSR 49: + */ + #define RFCSR49_TX FIELD8(0x3f) +@@ -2135,6 +2153,8 @@ struct mac_iveiv_entry { + * RFCSR 50: + */ + #define RFCSR50_TX FIELD8(0x3f) ++#define RFCSR50_TX0_EXT_PA FIELD8(0x02) ++#define RFCSR50_TX1_EXT_PA FIELD8(0x10) + + /* + * RF registers +@@ -2222,6 +2242,8 @@ struct mac_iveiv_entry { + * INTERNAL_TX_ALC: 0: disable, 1: enable + * BT_COEXIST: 0: disable, 1: enable + * DAC_TEST: 0: disable, 1: enable ++ * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352) ++ * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352) + */ + #define EEPROM_NIC_CONF1 0x001b + #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) +@@ -2239,6 +2261,8 @@ struct mac_iveiv_entry { + #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) + #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) + #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) ++#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352 FIELD16(0x4000) ++#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352 FIELD16(0x8000) + + /* + * EEPROM frequency +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -740,6 +740,8 @@ enum rt2x00_capability_flags { + CAPABILITY_DOUBLE_ANTENNA, + CAPABILITY_BT_COEXIST, + CAPABILITY_VCO_RECALIBRATION, ++ CAPABILITY_INTERNAL_PA_TX0, ++ CAPABILITY_INTERNAL_PA_TX1, + }; + + /* diff --git a/package/mac80211/patches/.svn/text-base/611-rt2x00-rf_vals-rt3352-xtal20.patch.svn-base b/package/mac80211/patches/.svn/text-base/611-rt2x00-rf_vals-rt3352-xtal20.patch.svn-base new file mode 100644 index 0000000..38b56b4 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/611-rt2x00-rf_vals-rt3352-xtal20.patch.svn-base @@ -0,0 +1,115 @@ +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -5169,6 +5169,27 @@ static const struct rf_channel rf_vals_3 + {173, 0x61, 0, 9}, + }; + ++/* ++ * RF value list for rt3xxx with Xtal20MHz ++ * Supports: 2.4 GHz (all) (RF3322) ++ */ ++static const struct rf_channel rf_vals_xtal20mhz_3x[] = { ++ {1, 0xE2, 2, 0x14}, ++ {2, 0xE3, 2, 0x14}, ++ {3, 0xE4, 2, 0x14}, ++ {4, 0xE5, 2, 0x14}, ++ {5, 0xE6, 2, 0x14}, ++ {6, 0xE7, 2, 0x14}, ++ {7, 0xE8, 2, 0x14}, ++ {8, 0xE9, 2, 0x14}, ++ {9, 0xEA, 2, 0x14}, ++ {10, 0xEB, 2, 0x14}, ++ {11, 0xEC, 2, 0x14}, ++ {12, 0xED, 2, 0x14}, ++ {13, 0xEE, 2, 0x14}, ++ {14, 0xF0, 2, 0x18}, ++}; ++ + static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) + { + struct hw_mode_spec *spec = &rt2x00dev->spec; +@@ -5246,7 +5267,6 @@ static int rt2800_probe_hw_mode(struct r + rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3290) || + rt2x00_rf(rt2x00dev, RF3320) || +- rt2x00_rf(rt2x00dev, RF3322) || + rt2x00_rf(rt2x00dev, RF5360) || + rt2x00_rf(rt2x00dev, RF5370) || + rt2x00_rf(rt2x00dev, RF5372) || +@@ -5254,6 +5274,12 @@ static int rt2800_probe_hw_mode(struct r + rt2x00_rf(rt2x00dev, RF5392)) { + spec->num_channels = 14; + spec->channels = rf_vals_3x; ++ } else if (rt2x00_rf(rt2x00dev, RF3322)) { ++ spec->num_channels = 14; ++ if (spec->clk_is_20mhz) ++ spec->channels = rf_vals_xtal20mhz_3x; ++ else ++ spec->channels = rf_vals_3x; + } else if (rt2x00_rf(rt2x00dev, RF3052)) { + spec->supported_bands |= SUPPORT_BAND_5GHZ; + spec->num_channels = ARRAY_SIZE(rf_vals_3x); +@@ -5347,6 +5373,19 @@ static int rt2800_probe_hw_mode(struct r + return 0; + } + ++int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev) ++{ ++ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data; ++ struct hw_mode_spec *spec = &rt2x00dev->spec; ++ ++ if (!pdata) ++ return -EINVAL; ++ ++ spec->clk_is_20mhz = pdata->clk_is_20mhz; ++ ++ return 0; ++} ++ + int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) + { + int retval; +@@ -5372,6 +5411,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r + rt2800_register_write(rt2x00dev, GPIO_CTRL, reg); + + /* ++ * Probe SoC clock. ++ */ ++ if (rt2x00_is_soc(rt2x00dev)) { ++ retval = rt2800_probe_clk(rt2x00dev); ++ if (retval) ++ return retval; ++ } ++ ++ /* + * Initialize hw specifications. + */ + retval = rt2800_probe_hw_mode(rt2x00dev); +--- a/drivers/net/wireless/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/rt2x00/rt2x00.h +@@ -419,6 +419,7 @@ static inline struct rt2x00_intf* vif_to + * @channels: Device/chipset specific channel values (See &struct rf_channel). + * @channels_info: Additional information for channels (See &struct channel_info). + * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap). ++ * @clk_is_20mhz: External crystal of WiSoC is 20MHz instead of 40MHz + */ + struct hw_mode_spec { + unsigned int supported_bands; +@@ -435,6 +436,7 @@ struct hw_mode_spec { + const struct channel_info *channels_info; + + struct ieee80211_sta_ht_cap ht; ++ int clk_is_20mhz; + }; + + /* +--- a/include/linux/rt2x00_platform.h ++++ b/include/linux/rt2x00_platform.h +@@ -18,6 +18,7 @@ struct rt2x00_platform_data { + + int disable_2ghz; + int disable_5ghz; ++ int clk_is_20mhz; + }; + + #endif /* _RT2X00_PLATFORM_H */ diff --git a/package/mac80211/patches/.svn/text-base/700-mwl8k-missing-pci-id-for-WNR854T.patch.svn-base b/package/mac80211/patches/.svn/text-base/700-mwl8k-missing-pci-id-for-WNR854T.patch.svn-base new file mode 100644 index 0000000..80fde27 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/700-mwl8k-missing-pci-id-for-WNR854T.patch.svn-base @@ -0,0 +1,10 @@ +--- a/drivers/net/wireless/mwl8k.c ++++ b/drivers/net/wireless/mwl8k.c +@@ -5497,6 +5497,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") + MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); + + static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { ++ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, }, + { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, }, diff --git a/package/mac80211/patches/.svn/text-base/800-b43-gpio-mask-module-option.patch.svn-base b/package/mac80211/patches/.svn/text-base/800-b43-gpio-mask-module-option.patch.svn-base new file mode 100644 index 0000000..d8fb06d --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/800-b43-gpio-mask-module-option.patch.svn-base @@ -0,0 +1,37 @@ +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -812,6 +812,7 @@ struct b43_wldev { + bool qos_enabled; /* TRUE, if QoS is used. */ + bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ + bool use_pio; /* TRUE if next init should use PIO */ ++ int gpiomask; /* GPIO LED mask as a module parameter */ + + /* PHY/Radio device. */ + struct b43_phy phy; +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -76,6 +76,11 @@ MODULE_FIRMWARE("b43/ucode16_mimo.fw"); + MODULE_FIRMWARE("b43/ucode5.fw"); + MODULE_FIRMWARE("b43/ucode9.fw"); + ++static int modparam_gpiomask = 0x000F; ++module_param_named(gpiomask, modparam_gpiomask, int, 0444); ++MODULE_PARM_DESC(gpiomask, ++ "GPIO mask for LED control (default 0x000F)"); ++ + static int modparam_bad_frames_preempt; + module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); + MODULE_PARM_DESC(bad_frames_preempt, +@@ -2740,10 +2745,10 @@ static int b43_gpio_init(struct b43_wlde + u32 mask, set; + + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); +- b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); ++ b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, modparam_gpiomask); + + mask = 0x0000001F; +- set = 0x0000000F; ++ set = modparam_gpiomask; + if (dev->dev->chip_id == 0x4301) { + mask |= 0x0060; + set |= 0x0060; diff --git a/package/mac80211/patches/.svn/text-base/810-b43_no_pio.patch.svn-base b/package/mac80211/patches/.svn/text-base/810-b43_no_pio.patch.svn-base new file mode 100644 index 0000000..5b4c22e --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/810-b43_no_pio.patch.svn-base @@ -0,0 +1,75 @@ +--- a/drivers/net/wireless/b43/Makefile ++++ b/drivers/net/wireless/b43/Makefile +@@ -20,7 +20,7 @@ b43-y += xmit.o + b43-y += lo.o + b43-y += wa.o + b43-y += dma.o +-b43-y += pio.o ++b43-$(CONFIG_B43_PIO) += pio.o + b43-y += rfkill.o + b43-$(CONFIG_B43_LEDS) += leds.o + b43-$(CONFIG_B43_PCMCIA) += pcmcia.o +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -1909,10 +1909,12 @@ static void b43_do_interrupt_thread(stru + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); ++#ifdef CONFIG_B43_PIO + b43err(dev->wl, "This device does not support DMA " + "on your system. It will now be switched to PIO.\n"); + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; ++#endif + b43_controller_restart(dev, "DMA error"); + return; + } +--- a/drivers/net/wireless/b43/pio.h ++++ b/drivers/net/wireless/b43/pio.h +@@ -150,7 +150,7 @@ static inline void b43_piorx_write32(str + b43_write32(q->dev, q->mmio_base + offset, value); + } + +- ++#ifdef CONFIG_B43_PIO + int b43_pio_init(struct b43_wldev *dev); + void b43_pio_free(struct b43_wldev *dev); + +@@ -161,5 +161,37 @@ void b43_pio_rx(struct b43_pio_rxqueue * + + void b43_pio_tx_suspend(struct b43_wldev *dev); + void b43_pio_tx_resume(struct b43_wldev *dev); ++#else ++static inline int b43_pio_init(struct b43_wldev *dev) ++{ ++ return 0; ++} ++ ++static inline void b43_pio_free(struct b43_wldev *dev) ++{ ++} ++ ++static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb) ++{ ++ return 0; ++} ++ ++static inline void b43_pio_handle_txstatus(struct b43_wldev *dev, ++ const struct b43_txstatus *status) ++{ ++} ++ ++static inline void b43_pio_rx(struct b43_pio_rxqueue *q) ++{ ++} ++ ++static inline void b43_pio_tx_suspend(struct b43_wldev *dev) ++{ ++} ++ ++static inline void b43_pio_tx_resume(struct b43_wldev *dev) ++{ ++} ++#endif /* CONFIG_B43_PIO */ + + #endif /* B43_PIO_H_ */ diff --git a/package/mac80211/patches/.svn/text-base/820-b43-add-antenna-control.patch.svn-base b/package/mac80211/patches/.svn/text-base/820-b43-add-antenna-control.patch.svn-base new file mode 100644 index 0000000..8b6255f --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/820-b43-add-antenna-control.patch.svn-base @@ -0,0 +1,131 @@ +--- a/drivers/net/wireless/b43/main.c ++++ b/drivers/net/wireless/b43/main.c +@@ -1553,7 +1553,7 @@ static void b43_write_beacon_template(st + len, ram_offset, shm_size_offset, rate); + + /* Write the PHY TX control parameters. */ +- antenna = B43_ANTENNA_DEFAULT; ++ antenna = dev->tx_antenna; + antenna = b43_antenna_to_phyctl(antenna); + ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); + /* We can't send beacons with short preamble. Would get PHY errors. */ +@@ -3101,8 +3101,8 @@ static int b43_chip_init(struct b43_wlde + + /* Select the antennae */ + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT); +- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + + if (phy->type == B43_PHYTYPE_B) { + value16 = b43_read16(dev, 0x005E); +@@ -3846,7 +3846,6 @@ static int b43_op_config(struct ieee8021 + struct b43_wldev *dev; + struct b43_phy *phy; + struct ieee80211_conf *conf = &hw->conf; +- int antenna; + int err = 0; + bool reload_bss = false; + +@@ -3900,11 +3899,9 @@ static int b43_op_config(struct ieee8021 + } + + /* Antennas for RX and management frame TX. */ +- antenna = B43_ANTENNA_DEFAULT; +- b43_mgmtframe_txantenna(dev, antenna); +- antenna = B43_ANTENNA_DEFAULT; ++ b43_mgmtframe_txantenna(dev, dev->tx_antenna); + if (phy->ops->set_rx_antenna) +- phy->ops->set_rx_antenna(dev, antenna); ++ phy->ops->set_rx_antenna(dev, dev->rx_antenna); + + if (wl->radio_enabled != phy->radio_on) { + if (wl->radio_enabled) { +@@ -5030,6 +5027,47 @@ static int b43_op_get_survey(struct ieee + return 0; + } + ++static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ if (tx_ant == 1 && rx_ant == 1) { ++ dev->tx_antenna = B43_ANTENNA0; ++ dev->rx_antenna = B43_ANTENNA0; ++ } ++ else if (tx_ant == 2 && rx_ant == 2) { ++ dev->tx_antenna = B43_ANTENNA1; ++ dev->rx_antenna = B43_ANTENNA1; ++ } ++ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) { ++ dev->tx_antenna = B43_ANTENNA_DEFAULT; ++ dev->rx_antenna = B43_ANTENNA_DEFAULT; ++ } ++ else { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++ ++static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) ++{ ++ struct b43_wl *wl = hw_to_b43_wl(hw); ++ struct b43_wldev *dev = wl->current_dev; ++ ++ switch (dev->tx_antenna) { ++ case B43_ANTENNA0: ++ *tx_ant = 1; *rx_ant = 1; break; ++ case B43_ANTENNA1: ++ *tx_ant = 2; *rx_ant = 2; break; ++ case B43_ANTENNA_DEFAULT: ++ *tx_ant = 3; *rx_ant = 3; break; ++ } ++ return 0; ++} ++ + static const struct ieee80211_ops b43_hw_ops = { + .tx = b43_op_tx, + .conf_tx = b43_op_conf_tx, +@@ -5051,6 +5089,8 @@ static const struct ieee80211_ops b43_hw + .sw_scan_complete = b43_op_sw_scan_complete_notifier, + .get_survey = b43_op_get_survey, + .rfkill_poll = b43_rfkill_poll, ++ .set_antenna = b43_op_set_antenna, ++ .get_antenna = b43_op_get_antenna, + }; + + /* Hard-reset the chip. Do not call this directly. +@@ -5297,6 +5337,8 @@ static int b43_one_core_attach(struct b4 + if (!wldev) + goto out; + ++ wldev->rx_antenna = B43_ANTENNA_DEFAULT; ++ wldev->tx_antenna = B43_ANTENNA_DEFAULT; + wldev->use_pio = b43_modparam_pio; + wldev->dev = dev; + wldev->wl = wl; +@@ -5387,6 +5429,9 @@ static struct b43_wl *b43_wireless_init( + + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + ++ hw->wiphy->available_antennas_rx = 0x3; ++ hw->wiphy->available_antennas_tx = 0x3; ++ + wl->hw_registred = false; + hw->max_rates = 2; + SET_IEEE80211_DEV(hw, dev->dev); +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -813,6 +813,8 @@ struct b43_wldev { + bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ + bool use_pio; /* TRUE if next init should use PIO */ + int gpiomask; /* GPIO LED mask as a module parameter */ ++ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */ ++ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */ + + /* PHY/Radio device. */ + struct b43_phy phy; diff --git a/package/mac80211/patches/.svn/text-base/830-b43-workaround-pcie-bcm4716.patch.svn-base b/package/mac80211/patches/.svn/text-base/830-b43-workaround-pcie-bcm4716.patch.svn-base new file mode 100644 index 0000000..bd10f99 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/830-b43-workaround-pcie-bcm4716.patch.svn-base @@ -0,0 +1,134 @@ +From 4f214b1ead0af7439921637645cb63f378516175 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 21 Jan 2012 18:48:38 +0100 +Subject: [PATCH 33/34] b43: add workaround for b43 on pcie bus of bcm4716. + +bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder +transactions. As a fix, a read after write is performed on certain +places in the code. Older chips and the newer 5357 family don't require +this fix. +This code is based on the brcmsmac driver. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + drivers/net/wireless/b43/b43.h | 26 ++++++++++++++++++++++++++ + drivers/net/wireless/b43/bus.h | 10 ++++++++++ + drivers/net/wireless/b43/phy_common.c | 6 ++++++ + drivers/net/wireless/b43/phy_n.c | 10 +++++----- + 4 files changed, 47 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/b43/b43.h ++++ b/drivers/net/wireless/b43/b43.h +@@ -1053,6 +1053,32 @@ static inline bool b43_using_pio_transfe + return dev->__using_pio_transfers; + } + ++/* ++ * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder ++ * transactions. As a fix, a read after write is performed on certain places ++ * in the code. Older chips and the newer 5357 family don't require this fix. ++ */ ++#ifdef CONFIG_BCM47XX_BCMA ++#include <asm/mach-bcm47xx/bcm47xx.h> ++static inline void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value) ++{ ++ if (b43_bus_host_is_pci(dev->dev) && ++ bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA && ++ (bcm47xx_bus.bcma.bus.chipinfo.id == 0x4716 || ++ bcm47xx_bus.bcma.bus.chipinfo.id == 0x5300)) { ++ b43_write16(dev, offset, value); ++ b43_read16(dev, offset); ++ } else { ++ b43_write16(dev, offset, value); ++ } ++} ++#else ++static inline void b43_wflush16(struct b43_wldev *dev, u16 offset, u16 value) ++{ ++ b43_write16(dev, offset, value); ++} ++#endif ++ + /* Message printing */ + __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...); + __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); +--- a/drivers/net/wireless/b43/bus.h ++++ b/drivers/net/wireless/b43/bus.h +@@ -60,6 +60,16 @@ static inline bool b43_bus_host_is_sdio( + return (dev->bus_type == B43_BUS_SSB && + dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); + } ++static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev) ++{ ++ if (dev->bus_type == B43_BUS_SSB) ++ return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI); ++#ifdef CONFIG_B43_BCMA ++ if (dev->bus_type == B43_BUS_BCMA) ++ return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI); ++#endif ++ return false; ++} + + struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core); + struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); +--- a/drivers/net/wireless/b43/phy_common.c ++++ b/drivers/net/wireless/b43/phy_common.c +@@ -266,6 +266,12 @@ void b43_phy_write(struct b43_wldev *dev + { + assert_mac_suspended(dev); + dev->phy.ops->phy_write(dev, reg, value); ++#ifdef CONFIG_BCM47XX ++ if (b43_bus_host_is_pci(dev->dev) && reg == 0x72) { ++ b43_read16(dev, B43_MMIO_PHY_VER); ++ return; ++ } ++#endif + if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) { + b43_read16(dev, B43_MMIO_PHY_VER); + dev->phy.writes_counter = 0; +--- a/drivers/net/wireless/b43/phy_n.c ++++ b/drivers/net/wireless/b43/phy_n.c +@@ -5423,14 +5423,14 @@ static inline void check_phyreg(struct b + static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg) + { + check_phyreg(dev, reg); +- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg); + return b43_read16(dev, B43_MMIO_PHY_DATA); + } + + static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value) + { + check_phyreg(dev, reg); +- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, value); + } + +@@ -5438,7 +5438,7 @@ static void b43_nphy_op_maskset(struct b + u16 set) + { + check_phyreg(dev, reg); +- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); + } + +@@ -5449,7 +5449,7 @@ static u16 b43_nphy_op_radio_read(struct + /* N-PHY needs 0x100 for read access */ + reg |= 0x100; + +- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg); + return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); + } + +@@ -5458,7 +5458,7 @@ static void b43_nphy_op_radio_write(stru + /* Register 1 is a 32-bit register. */ + B43_WARN_ON(reg == 1); + +- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg); ++ b43_wflush16(dev, B43_MMIO_RADIO_CONTROL, reg); + b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value); + } + diff --git a/package/mac80211/patches/.svn/text-base/840-b43-increase_number_of_rx_dma_slots.patch.svn-base b/package/mac80211/patches/.svn/text-base/840-b43-increase_number_of_rx_dma_slots.patch.svn-base new file mode 100644 index 0000000..94c6ff2 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/840-b43-increase_number_of_rx_dma_slots.patch.svn-base @@ -0,0 +1,11 @@ +--- a/drivers/net/wireless/b43/dma.h ++++ b/drivers/net/wireless/b43/dma.h +@@ -169,7 +169,7 @@ struct b43_dmadesc_generic { + + /* DMA engine tuning knobs */ + #define B43_TXRING_SLOTS 256 +-#define B43_RXRING_SLOTS 64 ++#define B43_RXRING_SLOTS 256 + #define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN) + #define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN) + diff --git a/package/mac80211/patches/.svn/text-base/850-brcmsmac-start-adding-support-for-core-rev-28.patch.svn-base b/package/mac80211/patches/.svn/text-base/850-brcmsmac-start-adding-support-for-core-rev-28.patch.svn-base new file mode 100644 index 0000000..41c4476 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/850-brcmsmac-start-adding-support-for-core-rev-28.patch.svn-base @@ -0,0 +1,75 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -99,6 +99,7 @@ static struct bcma_device_id brcms_corei + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 17, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS), + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS), ++// BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 28, BCMA_ANY_CLASS), + BCMA_CORETABLE_END + }; + MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -717,7 +717,7 @@ static void brcms_c_ucode_bsinit(struct + brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs); + + /* do band-specific ucode IHR, SHM, and SCR inits */ +- if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); + else +@@ -2257,7 +2257,7 @@ static void brcms_ucode_download(struct + if (wlc_hw->ucode_loaded) + return; + +- if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) { + if (BRCMS_ISNPHY(wlc_hw->band)) { + brcms_ucode_write(wlc_hw, ucode->bcm43xx_16_mimo, + ucode->bcm43xx_16_mimosz); +@@ -3207,7 +3207,7 @@ static void brcms_b_coreinit(struct brcm + + sflags = bcma_aread32(core, BCMA_IOST); + +- if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23)) { ++ if (D11REV_IS(wlc_hw->corerev, 17) || D11REV_IS(wlc_hw->corerev, 23) || D11REV_IS(wlc_hw->corerev, 28)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); + else +@@ -5663,6 +5663,8 @@ static bool brcms_c_chipmatch_soc(struct + + if (chipinfo->id == BCMA_CHIP_ID_BCM4716) + return true; ++ if (chipinfo->id == BCMA_CHIP_ID_BCM5357) ++ return true; + + pr_err("unknown chip id %04x\n", chipinfo->id); + return false; +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -65,7 +65,7 @@ + #define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ + + /* max # supported core revisions (0 .. MAXCOREREV - 1) */ +-#define MAXCOREREV 28 ++#define MAXCOREREV 29 + + /* Double check that unsupported cores are not enabled */ + #if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV) +--- a/drivers/net/wireless/brcm80211/brcmsmac/types.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h +@@ -93,11 +93,11 @@ + #define BOARD_GPIO_13 0x2000 + + /* **** Core type/rev defaults **** */ +-#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 ++#define D11CONF 0x1fffffb0 /* Supported D11 revs: 4, 5, 7-27 + * also need to update wlc.h MAXCOREREV + */ + +-#define NCONF 0x000001ff /* Supported nphy revs: ++#define NCONF 0x000002ff /* Supported nphy revs: + * 0 4321a0 + * 1 4321a1 + * 2 4321b0/b1/c0/c1 diff --git a/package/mac80211/patches/.svn/text-base/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch.svn-base b/package/mac80211/patches/.svn/text-base/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch.svn-base new file mode 100644 index 0000000..33991bc --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/860-brcmsmac-implement-ieee80211_ops-get_tsf-and-set_tsf.patch.svn-base @@ -0,0 +1,121 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/d11.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/d11.h +@@ -457,6 +457,7 @@ struct d11regs { + /*== maccontrol register ==*/ + #define MCTL_GMODE (1U << 31) + #define MCTL_DISCARD_PMQ (1 << 30) ++#define MCTL_TBTTHOLD (1 << 28) + #define MCTL_WAKE (1 << 26) + #define MCTL_HPS (1 << 25) + #define MCTL_PROMISC (1 << 24) +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -741,6 +741,28 @@ static void brcms_ops_flush(struct ieee8 + "ret=%d\n", jiffies_to_msecs(ret)); + } + ++static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ++{ ++ struct brcms_info *wl = hw->priv; ++ u64 tsf; ++ ++ spin_lock_bh(&wl->lock); ++ tsf = brcms_c_tsf_get(wl->wlc); ++ spin_unlock_bh(&wl->lock); ++ ++ return tsf; ++} ++ ++static void brcms_ops_set_tsf(struct ieee80211_hw *hw, ++ struct ieee80211_vif *vif, u64 tsf) ++{ ++ struct brcms_info *wl = hw->priv; ++ ++ spin_lock_bh(&wl->lock); ++ brcms_c_tsf_set(wl->wlc, tsf); ++ spin_unlock_bh(&wl->lock); ++} ++ + static const struct ieee80211_ops brcms_ops = { + .tx = brcms_ops_tx, + .start = brcms_ops_start, +@@ -757,6 +779,8 @@ static const struct ieee80211_ops brcms_ + .ampdu_action = brcms_ops_ampdu_action, + .rfkill_poll = brcms_ops_rfkill_poll, + .flush = brcms_ops_flush, ++ .get_tsf = brcms_ops_get_tsf, ++ .set_tsf = brcms_ops_set_tsf, + }; + + void brcms_dpc(unsigned long data) +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -5545,6 +5545,20 @@ int brcms_c_set_rateset(struct brcms_c_i + return bcmerror; + } + ++static void brcms_c_time_lock(struct brcms_c_info *wlc) ++{ ++ bcma_set32(wlc->hw->d11core, D11REGOFFS(maccontrol), MCTL_TBTTHOLD); ++ /* Commit the write */ ++ bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); ++} ++ ++static void brcms_c_time_unlock(struct brcms_c_info *wlc) ++{ ++ bcma_mask32(wlc->hw->d11core, D11REGOFFS(maccontrol), ~MCTL_TBTTHOLD); ++ /* Commit the write */ ++ bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); ++} ++ + int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period) + { + if (period == 0) +@@ -7530,6 +7544,36 @@ void brcms_c_set_beacon_listen_interval( + brcms_c_bcn_li_upd(wlc); + } + ++u64 brcms_c_tsf_get(struct brcms_c_info *wlc) ++{ ++ u32 tsf_h, tsf_l; ++ u64 tsf; ++ ++ brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h); ++ ++ tsf = tsf_h; ++ tsf <<= 32; ++ tsf |= tsf_l; ++ ++ return tsf; ++} ++ ++void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf) ++{ ++ u32 tsf_h, tsf_l; ++ ++ brcms_c_time_lock(wlc); ++ ++ tsf_l = tsf; ++ tsf_h = (tsf >> 32); ++ ++ /* read the tsf timer low, then high to get an atomic read */ ++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerlow), tsf_l); ++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_timerhigh), tsf_h); ++ ++ brcms_c_time_unlock(wlc); ++} ++ + int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr) + { + uint qdbm; +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -326,6 +326,8 @@ extern void brcms_c_set_shortslot_overri + s8 sslot_override); + extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, + u8 interval); ++extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc); ++extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf); + extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); + extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); + extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); diff --git a/package/mac80211/patches/.svn/text-base/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch.svn-base b/package/mac80211/patches/.svn/text-base/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch.svn-base new file mode 100644 index 0000000..21b1e0e --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/861-brcmsmac-add-interface-type-to-brcms_bss_cfg.patch.svn-base @@ -0,0 +1,66 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -367,9 +367,10 @@ brcms_ops_add_interface(struct ieee80211 + } + + spin_lock_bh(&wl->lock); +- memcpy(wl->pub->cur_etheraddr, vif->addr, sizeof(vif->addr)); + wl->mute_tx = false; + brcms_c_mute(wl->wlc, false); ++ if (vif->type == NL80211_IFTYPE_STATION) ++ brcms_c_start_station(wl->wlc, vif->addr); + spin_unlock_bh(&wl->lock); + + return 0; +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -2165,6 +2165,12 @@ void brcms_b_switch_macfreq(struct brcms + } + } + ++void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr) ++{ ++ memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr)); ++ wlc->bsscfg->type = BRCMS_TYPE_STATION; ++} ++ + /* Initialize GPIOs that are controlled by D11 core */ + static void brcms_c_gpio_init(struct brcms_c_info *wlc) + { +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -576,10 +576,17 @@ struct antsel_info { + struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */ + }; + ++enum brcms_bss_type { ++ BRCMS_TYPE_STATION, ++ BRCMS_TYPE_AP, ++ BRCMS_TYPE_ADHOC, ++}; ++ + /* + * BSS configuration state + * + * wlc: wlc to which this bsscfg belongs to. ++ * type: interface type + * up: is this configuration up operational + * enable: is this configuration enabled + * associated: is BSS in ASSOCIATED state +@@ -599,6 +606,7 @@ struct antsel_info { + */ + struct brcms_bss_cfg { + struct brcms_c_info *wlc; ++ enum brcms_bss_type type; + bool up; + bool enable; + bool associated; +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -333,5 +333,6 @@ extern int brcms_c_get_tx_power(struct b + extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); + extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); + extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); ++extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr); + + #endif /* _BRCM_PUB_H_ */ diff --git a/package/mac80211/patches/.svn/text-base/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch.svn-base b/package/mac80211/patches/.svn/text-base/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch.svn-base new file mode 100644 index 0000000..a7ffcf6 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/862-brcmsmac-remove-brcms_bss_cfg-BSS.patch.svn-base @@ -0,0 +1,77 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -1071,7 +1071,7 @@ brcms_b_txstatus(struct brcms_hardware * + + static void brcms_c_tbtt(struct brcms_c_info *wlc) + { +- if (!wlc->bsscfg->BSS) ++ if (wlc->bsscfg->type == BRCMS_TYPE_ADHOC) + /* + * DirFrmQ is now valid...defer setting until end + * of ATIM window +@@ -3061,16 +3061,8 @@ static bool brcms_c_ps_allowed(struct br + if (wlc->filter_flags & FIF_PROMISC_IN_BSS) + return false; + +- if (cfg->associated) { +- /* +- * disallow PS when one of the following +- * bsscfg specific conditions meets +- */ +- if (!cfg->BSS) +- return false; +- ++ if (cfg->associated) + return false; +- } + + return true; + } +@@ -5080,8 +5072,9 @@ int brcms_c_up(struct brcms_c_info *wlc) + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + mboolset(wlc->pub->radio_disabled, + WL_RADIO_HW_DISABLE); +- +- if (bsscfg->enable && bsscfg->BSS) ++ if (bsscfg->enable && ++ (bsscfg->type == BRCMS_TYPE_STATION || ++ bsscfg->type == BRCMS_TYPE_ADHOC)) + brcms_err(wlc->hw->d11core, + "wl%d: up: rfdisable -> " + "bsscfg_disable()\n", +@@ -7390,7 +7383,7 @@ void brcms_c_update_beacon(struct brcms_ + { + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + +- if (bsscfg->up && !bsscfg->BSS) ++ if (bsscfg->up && bsscfg->type == BRCMS_TYPE_AP) + /* Clear the soft intmask */ + wlc->defmacintmask &= ~MI_BCNTPL; + } +@@ -7465,7 +7458,7 @@ void brcms_c_update_probe_resp(struct br + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + + /* update AP or IBSS probe responses */ +- if (bsscfg->up && !bsscfg->BSS) ++ if (bsscfg->up && bsscfg->type == BRCMS_TYPE_AP) + brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); + } + +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -590,7 +590,6 @@ enum brcms_bss_type { + * up: is this configuration up operational + * enable: is this configuration enabled + * associated: is BSS in ASSOCIATED state +- * BSS: infraustructure or adhoc + * SSID_len: the length of SSID + * SSID: SSID string + * +@@ -610,7 +609,6 @@ struct brcms_bss_cfg { + bool up; + bool enable; + bool associated; +- bool BSS; + u8 SSID_len; + u8 SSID[IEEE80211_MAX_SSID_LEN]; + u8 BSSID[ETH_ALEN]; diff --git a/package/mac80211/patches/.svn/text-base/863-brcmsmac-remove-brcms_bss_cfg-associated.patch.svn-base b/package/mac80211/patches/.svn/text-base/863-brcmsmac-remove-brcms_bss_cfg-associated.patch.svn-base new file mode 100644 index 0000000..7f84f00 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/863-brcmsmac-remove-brcms_bss_cfg-associated.patch.svn-base @@ -0,0 +1,74 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -3051,8 +3051,6 @@ static void brcms_b_antsel_set(struct br + */ + static bool brcms_c_ps_allowed(struct brcms_c_info *wlc) + { +- struct brcms_bss_cfg *cfg = wlc->bsscfg; +- + /* disallow PS when one of the following global conditions meets */ + if (!wlc->pub->associated) + return false; +@@ -3061,9 +3059,6 @@ static bool brcms_c_ps_allowed(struct br + if (wlc->filter_flags & FIF_PROMISC_IN_BSS) + return false; + +- if (cfg->associated) +- return false; +- + return true; + } + +@@ -3821,7 +3816,7 @@ static void brcms_c_set_home_chanspec(st + if (wlc->home_chanspec != chanspec) { + wlc->home_chanspec = chanspec; + +- if (wlc->bsscfg->associated) ++ if (wlc->pub->associated) + wlc->bsscfg->current_bss->chanspec = chanspec; + } + } +@@ -5435,7 +5430,7 @@ static void brcms_c_ofdm_rateset_war(str + u8 r; + bool war = false; + +- if (wlc->bsscfg->associated) ++ if (wlc->pub->associated) + r = wlc->bsscfg->current_bss->rateset.rates[0]; + else + r = wlc->default_bss->rateset.rates[0]; +@@ -5529,7 +5524,7 @@ int brcms_c_set_rateset(struct brcms_c_i + /* merge rateset coming in with the current mcsset */ + if (wlc->pub->_n_enab & SUPPORT_11N) { + struct brcms_bss_info *mcsset_bss; +- if (wlc->bsscfg->associated) ++ if (wlc->pub->associated) + mcsset_bss = wlc->bsscfg->current_bss; + else + mcsset_bss = wlc->default_bss; +@@ -7498,7 +7493,6 @@ void brcms_c_scan_stop(struct brcms_c_in + void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state) + { + wlc->pub->associated = state; +- wlc->bsscfg->associated = state; + } + + /* +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -589,7 +589,6 @@ enum brcms_bss_type { + * type: interface type + * up: is this configuration up operational + * enable: is this configuration enabled +- * associated: is BSS in ASSOCIATED state + * SSID_len: the length of SSID + * SSID: SSID string + * +@@ -608,7 +607,6 @@ struct brcms_bss_cfg { + enum brcms_bss_type type; + bool up; + bool enable; +- bool associated; + u8 SSID_len; + u8 SSID[IEEE80211_MAX_SSID_LEN]; + u8 BSSID[ETH_ALEN]; diff --git a/package/mac80211/patches/.svn/text-base/864-brcmsmac-remove-brcms_bss_cfg-enable.patch.svn-base b/package/mac80211/patches/.svn/text-base/864-brcmsmac-remove-brcms_bss_cfg-enable.patch.svn-base new file mode 100644 index 0000000..9f5c4da --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/864-brcmsmac-remove-brcms_bss_cfg-enable.patch.svn-base @@ -0,0 +1,32 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -5067,9 +5067,8 @@ int brcms_c_up(struct brcms_c_info *wlc) + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + mboolset(wlc->pub->radio_disabled, + WL_RADIO_HW_DISABLE); +- if (bsscfg->enable && +- (bsscfg->type == BRCMS_TYPE_STATION || +- bsscfg->type == BRCMS_TYPE_ADHOC)) ++ if (bsscfg->type == BRCMS_TYPE_STATION || ++ bsscfg->type == BRCMS_TYPE_ADHOC) + brcms_err(wlc->hw->d11core, + "wl%d: up: rfdisable -> " + "bsscfg_disable()\n", +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -588,7 +588,6 @@ enum brcms_bss_type { + * wlc: wlc to which this bsscfg belongs to. + * type: interface type + * up: is this configuration up operational +- * enable: is this configuration enabled + * SSID_len: the length of SSID + * SSID: SSID string + * +@@ -606,7 +605,6 @@ struct brcms_bss_cfg { + struct brcms_c_info *wlc; + enum brcms_bss_type type; + bool up; +- bool enable; + u8 SSID_len; + u8 SSID[IEEE80211_MAX_SSID_LEN]; + u8 BSSID[ETH_ALEN]; diff --git a/package/mac80211/patches/.svn/text-base/865-brcmsmac-remove-brcms_bss_cfg-up.patch.svn-base b/package/mac80211/patches/.svn/text-base/865-brcmsmac-remove-brcms_bss_cfg-up.patch.svn-base new file mode 100644 index 0000000..40fe6ea --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/865-brcmsmac-remove-brcms_bss_cfg-up.patch.svn-base @@ -0,0 +1,47 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -7377,7 +7377,7 @@ void brcms_c_update_beacon(struct brcms_ + { + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + +- if (bsscfg->up && bsscfg->type == BRCMS_TYPE_AP) ++ if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP) + /* Clear the soft intmask */ + wlc->defmacintmask &= ~MI_BCNTPL; + } +@@ -7452,7 +7452,7 @@ void brcms_c_update_probe_resp(struct br + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + + /* update AP or IBSS probe responses */ +- if (bsscfg->up && bsscfg->type == BRCMS_TYPE_AP) ++ if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP) + brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); + } + +@@ -7805,7 +7805,7 @@ void brcms_c_init(struct brcms_c_info *w + brcms_c_set_bssid(wlc->bsscfg); + + /* Update tsf_cfprep if associated and up */ +- if (wlc->pub->associated && wlc->bsscfg->up) { ++ if (wlc->pub->associated && wlc->pub->up) { + u32 bi; + + /* get beacon period and convert to uS */ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -587,7 +587,6 @@ enum brcms_bss_type { + * + * wlc: wlc to which this bsscfg belongs to. + * type: interface type +- * up: is this configuration up operational + * SSID_len: the length of SSID + * SSID: SSID string + * +@@ -604,7 +603,6 @@ enum brcms_bss_type { + struct brcms_bss_cfg { + struct brcms_c_info *wlc; + enum brcms_bss_type type; +- bool up; + u8 SSID_len; + u8 SSID[IEEE80211_MAX_SSID_LEN]; + u8 BSSID[ETH_ALEN]; diff --git a/package/mac80211/patches/.svn/text-base/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch.svn-base b/package/mac80211/patches/.svn/text-base/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch.svn-base new file mode 100644 index 0000000..0571932 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/866-brcmsmac-remove-brcms_bss_cfg-cur_etheraddr.patch.svn-base @@ -0,0 +1,30 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -3766,7 +3766,7 @@ static int brcms_c_set_mac(struct brcms_ + struct brcms_c_info *wlc = bsscfg->wlc; + + /* enter the MAC addr into the RXE match registers */ +- brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, bsscfg->cur_etheraddr); ++ brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, wlc->pub->cur_etheraddr); + + brcms_c_ampdu_macaddr_upd(wlc); + +@@ -7359,7 +7359,7 @@ brcms_c_bcn_prb_template(struct brcms_c_ + /* A1 filled in by MAC for prb resp, broadcast for bcn */ + if (type == IEEE80211_STYPE_BEACON) + memcpy(&h->da, ðer_bcast, ETH_ALEN); +- memcpy(&h->sa, &cfg->cur_etheraddr, ETH_ALEN); ++ memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN); + memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN); + + /* SEQ filled in by MAC */ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -606,7 +606,6 @@ struct brcms_bss_cfg { + u8 SSID_len; + u8 SSID[IEEE80211_MAX_SSID_LEN]; + u8 BSSID[ETH_ALEN]; +- u8 cur_etheraddr[ETH_ALEN]; + struct brcms_bss_info *current_bss; + }; + diff --git a/package/mac80211/patches/.svn/text-base/867-brcmsmac-remove-brcms_pub-bcmerr.patch.svn-base b/package/mac80211/patches/.svn/text-base/867-brcmsmac-remove-brcms_pub-bcmerr.patch.svn-base new file mode 100644 index 0000000..2e7c166 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/867-brcmsmac-remove-brcms_pub-bcmerr.patch.svn-base @@ -0,0 +1,21 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -4327,7 +4327,6 @@ static void brcms_c_info_init(struct brc + + /* WME QoS mode is Auto by default */ + wlc->pub->_ampdu = AMPDU_AGG_HOST; +- wlc->pub->bcmerror = 0; + } + + static uint brcms_c_attach_module(struct brcms_c_info *wlc) +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -164,8 +164,6 @@ struct brcms_pub { + + u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ + +- int bcmerror; /* last bcm error */ +- + u32 radio_disabled; /* bit vector for radio disabled reasons */ + + u16 boardrev; /* version # of particular board */ diff --git a/package/mac80211/patches/.svn/text-base/868-brcmsmac-write-beacon-period-to-hardware.patch.svn-base b/package/mac80211/patches/.svn/text-base/868-brcmsmac-write-beacon-period-to-hardware.patch.svn-base new file mode 100644 index 0000000..fb10e1b --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/868-brcmsmac-write-beacon-period-to-hardware.patch.svn-base @@ -0,0 +1,23 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -5553,10 +5553,20 @@ static void brcms_c_time_unlock(struct b + + int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period) + { ++ u32 bcnint_us; ++ + if (period == 0) + return -EINVAL; + + wlc->default_bss->beacon_period = period; ++ ++ bcnint_us = period << 10; ++ brcms_c_time_lock(wlc); ++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfprep), ++ (bcnint_us << CFPREP_CBI_SHIFT)); ++ bcma_write32(wlc->hw->d11core, D11REGOFFS(tsf_cfpstart), bcnint_us); ++ brcms_c_time_unlock(wlc); ++ + return 0; + } + diff --git a/package/mac80211/patches/.svn/text-base/869-brcmsmac-add-beacon-template-support.patch.svn-base b/package/mac80211/patches/.svn/text-base/869-brcmsmac-add-beacon-template-support.patch.svn-base new file mode 100644 index 0000000..ab864a3 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/869-brcmsmac-add-beacon-template-support.patch.svn-base @@ -0,0 +1,266 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2010 Broadcom Corporation ++ * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -522,9 +523,17 @@ brcms_ops_bss_info_changed(struct ieee80 + brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); + spin_unlock_bh(&wl->lock); + } +- if (changed & BSS_CHANGED_BEACON) ++ if (changed & BSS_CHANGED_BEACON) { + /* Beacon data changed, retrieve new beacon (beaconing modes) */ +- brcms_err(core, "%s: beacon changed\n", __func__); ++ struct sk_buff *beacon; ++ u16 tim_offset = 0; ++ ++ spin_lock_bh(&wl->lock); ++ beacon = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL); ++ brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset, ++ info->dtim_period); ++ spin_unlock_bh(&wl->lock); ++ } + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + /* Beaconing should be enabled/disabled (beaconing modes) */ +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2010 Broadcom Corporation ++ * Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -450,6 +451,8 @@ static void brcms_c_detach_mfree(struct + kfree(wlc->corestate); + kfree(wlc->hw->bandstate[0]); + kfree(wlc->hw); ++ if (wlc->beacon) ++ dev_kfree_skb_any(wlc->beacon); + + /* free the wlc */ + kfree(wlc); +@@ -4086,10 +4089,14 @@ void brcms_c_wme_setparams(struct brcms_ + *shm_entry++); + } + +- if (suspend) { ++ if (suspend) + brcms_c_suspend_mac_and_wait(wlc); ++ ++ brcms_c_update_beacon(wlc); ++ brcms_c_update_probe_resp(wlc, false); ++ ++ if (suspend) + brcms_c_enable_mac(wlc); +- } + } + + static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) +@@ -7379,6 +7386,107 @@ int brcms_c_get_header_len(void) + return TXOFF; + } + ++static void brcms_c_beacon_write(struct brcms_c_info *wlc, ++ struct sk_buff *beacon, u16 tim_offset, ++ u16 dtim_period, bool bcn0, bool bcn1) ++{ ++ size_t len; ++ struct ieee80211_tx_info *tx_info; ++ struct brcms_hardware *wlc_hw = wlc->hw; ++ struct ieee80211_hw *ieee_hw = brcms_c_pub(wlc)->ieee_hw; ++ ++ /* Get tx_info */ ++ tx_info = IEEE80211_SKB_CB(beacon); ++ ++ len = min_t(size_t, beacon->len, BCN_TMPL_LEN); ++ wlc->bcn_rspec = ieee80211_get_tx_rate(ieee_hw, tx_info)->hw_value; ++ ++ brcms_c_compute_plcp(wlc, wlc->bcn_rspec, ++ len + FCS_LEN - D11_PHY_HDR_LEN, beacon->data); ++ ++ /* "Regular" and 16 MBSS but not for 4 MBSS */ ++ /* Update the phytxctl for the beacon based on the rspec */ ++ brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); ++ ++ if (bcn0) { ++ /* write the probe response into the template region */ ++ brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, ++ (len + 3) & ~3, beacon->data); ++ ++ /* write beacon length to SCR */ ++ brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); ++ } ++ if (bcn1) { ++ /* write the probe response into the template region */ ++ brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, ++ (len + 3) & ~3, beacon->data); ++ ++ /* write beacon length to SCR */ ++ brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); ++ } ++ ++ if (tim_offset != 0) { ++ brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON, ++ tim_offset + D11B_PHY_HDR_LEN); ++ brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, dtim_period); ++ } else { ++ brcms_b_write_shm(wlc_hw, M_TIMBPOS_INBEACON, ++ len + D11B_PHY_HDR_LEN); ++ brcms_b_write_shm(wlc_hw, M_DOT11_DTIMPERIOD, 0); ++ } ++} ++ ++static void brcms_c_update_beacon_hw(struct brcms_c_info *wlc, ++ struct sk_buff *beacon, u16 tim_offset, ++ u16 dtim_period) ++{ ++ struct brcms_hardware *wlc_hw = wlc->hw; ++ struct bcma_device *core = wlc_hw->d11core; ++ ++ /* Hardware beaconing for this config */ ++ u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; ++ ++ /* Check if both templates are in use, if so sched. an interrupt ++ * that will call back into this routine ++ */ ++ if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) ++ /* clear any previous status */ ++ bcma_write32(core, D11REGOFFS(macintstatus), MI_BCNTPL); ++ ++ if (wlc->beacon_template_virgin) { ++ wlc->beacon_template_virgin = false; ++ brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true, ++ true); ++ /* mark beacon0 valid */ ++ bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD); ++ return; ++ } ++ ++ /* Check that after scheduling the interrupt both of the ++ * templates are still busy. if not clear the int. & remask ++ */ ++ if ((bcma_read32(core, D11REGOFFS(maccommand)) & both_valid) == both_valid) { ++ wlc->defmacintmask |= MI_BCNTPL; ++ return; ++ } ++ ++ if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN0VLD)) { ++ brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, true, ++ false); ++ /* mark beacon0 valid */ ++ bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN0VLD); ++ return; ++ } ++ if (!(bcma_read32(core, D11REGOFFS(maccommand)) & MCMD_BCN1VLD)) { ++ brcms_c_beacon_write(wlc, beacon, tim_offset, dtim_period, ++ false, true); ++ /* mark beacon0 valid */ ++ bcma_set32(core, D11REGOFFS(maccommand), MCMD_BCN1VLD); ++ return; ++ } ++ return; ++} ++ + /* + * Update all beacons for the system. + */ +@@ -7386,9 +7494,31 @@ void brcms_c_update_beacon(struct brcms_ + { + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + +- if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP) ++ if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP) { + /* Clear the soft intmask */ + wlc->defmacintmask &= ~MI_BCNTPL; ++ if (!wlc->beacon) ++ return; ++ brcms_c_update_beacon_hw(wlc, wlc->beacon, ++ wlc->beacon_tim_offset, ++ wlc->beacon_dtim_period); ++ } ++} ++ ++void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon, ++ u16 tim_offset, u16 dtim_period) ++{ ++ if (!beacon) ++ return; ++ if (wlc->beacon) ++ dev_kfree_skb_any(wlc->beacon); ++ wlc->beacon = beacon; ++ ++ /* add PLCP */ ++ skb_push(wlc->beacon, D11_PHY_HDR_LEN); ++ wlc->beacon_tim_offset = tim_offset; ++ wlc->beacon_dtim_period = dtim_period; ++ brcms_c_update_beacon(wlc); + } + + /* Write ssid into shared memory */ +@@ -7786,6 +7916,10 @@ bool brcms_c_dpc(struct brcms_c_info *wl + brcms_rfkill_set_hw_state(wlc->wl); + } + ++ /* BCN template is available */ ++ if (macintstatus & MI_BCNTPL) ++ brcms_c_update_beacon(wlc); ++ + /* it isn't done and needs to be resched if macintstatus is non-zero */ + return wlc->macintstatus != 0; + +@@ -7917,6 +8051,7 @@ brcms_c_attach(struct brcms_info *wl, st + pub->unit = unit; + pub->_piomode = piomode; + wlc->bandinit_pending = false; ++ wlc->beacon_template_virgin = true; + + /* populate struct brcms_c_info with default values */ + brcms_c_info_init(wlc, unit); +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -492,6 +492,8 @@ struct brcms_c_info { + bool radio_monitor; + bool going_down; + ++ bool beacon_template_virgin; ++ + struct brcms_timer *wdtimer; + struct brcms_timer *radio_timer; + +@@ -561,6 +563,10 @@ struct brcms_c_info { + + struct wiphy *wiphy; + struct scb pri_scb; ++ ++ struct sk_buff *beacon; ++ u16 beacon_tim_offset; ++ u16 beacon_dtim_period; + }; + + /* antsel module specific state */ +@@ -630,7 +636,6 @@ extern u16 brcms_c_compute_rtscts_dur(st + extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, + struct ieee80211_sta *sta, + void (*dma_callback_fn)); +-extern void brcms_c_update_beacon(struct brcms_c_info *wlc); + extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend); + extern int brcms_c_set_nmode(struct brcms_c_info *wlc); + extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -332,5 +332,9 @@ extern bool brcms_c_check_radio_disabled + extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); + extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); + extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr); ++extern void brcms_c_update_beacon(struct brcms_c_info *wlc); ++extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc, ++ struct sk_buff *beacon, u16 tim_offset, ++ u16 dtim_period); + + #endif /* _BRCM_PUB_H_ */ diff --git a/package/mac80211/patches/.svn/text-base/870-brcmsmac-react-on-changing-SSID.patch.svn-base b/package/mac80211/patches/.svn/text-base/870-brcmsmac-react-on-changing-SSID.patch.svn-base new file mode 100644 index 0000000..34969ad --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/870-brcmsmac-react-on-changing-SSID.patch.svn-base @@ -0,0 +1,43 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -523,6 +523,12 @@ brcms_ops_bss_info_changed(struct ieee80 + brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); + spin_unlock_bh(&wl->lock); + } ++ if (changed & BSS_CHANGED_SSID) { ++ /* BSSID changed, for whatever reason (IBSS and managed mode) */ ++ spin_lock_bh(&wl->lock); ++ brcms_c_set_ssid(wl->wlc, info->ssid, info->ssid_len); ++ spin_unlock_bh(&wl->lock); ++ } + if (changed & BSS_CHANGED_BEACON) { + /* Beacon data changed, retrieve new beacon (beaconing modes) */ + struct sk_buff *beacon; +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -3785,6 +3785,15 @@ static void brcms_c_set_bssid(struct brc + brcms_c_set_addrmatch(bsscfg->wlc, RCM_BSSID_OFFSET, bsscfg->BSSID); + } + ++void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len) ++{ ++ u8 len = min_t(u8, sizeof(wlc->bsscfg->SSID), ssid_len); ++ memset(wlc->bsscfg->SSID, 0, sizeof(wlc->bsscfg->SSID)); ++ ++ memcpy(wlc->bsscfg->SSID, ssid, len); ++ wlc->bsscfg->SSID_len = len; ++} ++ + static void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot) + { + wlc_hw->shortslot = shortslot; +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -336,5 +336,7 @@ extern void brcms_c_update_beacon(struct + extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc, + struct sk_buff *beacon, u16 tim_offset, + u16 dtim_period); ++extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, ++ size_t ssid_len); + + #endif /* _BRCM_PUB_H_ */ diff --git a/package/mac80211/patches/.svn/text-base/871-brcmsmac-add-support-for-probe-response-template.patch.svn-base b/package/mac80211/patches/.svn/text-base/871-brcmsmac-add-support-for-probe-response-template.patch.svn-base new file mode 100644 index 0000000..5d022d2 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/871-brcmsmac-add-support-for-probe-response-template.patch.svn-base @@ -0,0 +1,216 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -541,6 +541,15 @@ brcms_ops_bss_info_changed(struct ieee80 + spin_unlock_bh(&wl->lock); + } + ++ if (changed & BSS_CHANGED_AP_PROBE_RESP) { ++ struct sk_buff *probe_resp; ++ ++ spin_lock_bh(&wl->lock); ++ probe_resp = ieee80211_proberesp_get(hw, vif); ++ brcms_c_set_new_probe_resp(wl->wlc, probe_resp); ++ spin_unlock_bh(&wl->lock); ++ } ++ + if (changed & BSS_CHANGED_BEACON_ENABLED) { + /* Beaconing should be enabled/disabled (beaconing modes) */ + brcms_err(core, "%s: Beacon enabled: %s\n", __func__, +@@ -1039,6 +1048,8 @@ static int ieee_hw_init(struct ieee80211 + hw->channel_change_time = 7 * 1000; + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + ++ hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; ++ + hw->rate_control_algorithm = "minstrel_ht"; + + hw->sta_data_size = 0; +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -453,6 +453,8 @@ static void brcms_c_detach_mfree(struct + kfree(wlc->hw); + if (wlc->beacon) + dev_kfree_skb_any(wlc->beacon); ++ if (wlc->probe_resp) ++ dev_kfree_skb_any(wlc->probe_resp); + + /* free the wlc */ + kfree(wlc); +@@ -7327,69 +7329,6 @@ brcms_c_mod_prb_rsp_rate_table(struct br + } + } + +-/* Max buffering needed for beacon template/prb resp template is 142 bytes. +- * +- * PLCP header is 6 bytes. +- * 802.11 A3 header is 24 bytes. +- * Max beacon frame body template length is 112 bytes. +- * Max probe resp frame body template length is 110 bytes. +- * +- * *len on input contains the max length of the packet available. +- * +- * The *len value is set to the number of bytes in buf used, and starts +- * with the PLCP and included up to, but not including, the 4 byte FCS. +- */ +-static void +-brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type, +- u32 bcn_rspec, +- struct brcms_bss_cfg *cfg, u16 *buf, int *len) +-{ +- static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; +- struct cck_phy_hdr *plcp; +- struct ieee80211_mgmt *h; +- int hdr_len, body_len; +- +- hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; +- +- /* calc buffer size provided for frame body */ +- body_len = *len - hdr_len; +- /* return actual size */ +- *len = hdr_len + body_len; +- +- /* format PHY and MAC headers */ +- memset(buf, 0, hdr_len); +- +- plcp = (struct cck_phy_hdr *) buf; +- +- /* +- * PLCP for Probe Response frames are filled in from +- * core's rate table +- */ +- if (type == IEEE80211_STYPE_BEACON) +- /* fill in PLCP */ +- brcms_c_compute_plcp(wlc, bcn_rspec, +- (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), +- (u8 *) plcp); +- +- /* "Regular" and 16 MBSS but not for 4 MBSS */ +- /* Update the phytxctl for the beacon based on the rspec */ +- brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec); +- +- h = (struct ieee80211_mgmt *)&plcp[1]; +- +- /* fill in 802.11 header */ +- h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type); +- +- /* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */ +- /* A1 filled in by MAC for prb resp, broadcast for bcn */ +- if (type == IEEE80211_STYPE_BEACON) +- memcpy(&h->da, ðer_bcast, ETH_ALEN); +- memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN); +- memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN); +- +- /* SEQ filled in by MAC */ +-} +- + int brcms_c_get_header_len(void) + { + return TXOFF; +@@ -7530,6 +7469,20 @@ void brcms_c_set_new_beacon(struct brcms + brcms_c_update_beacon(wlc); + } + ++void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc, ++ struct sk_buff *probe_resp) ++{ ++ if (!probe_resp) ++ return; ++ if (wlc->probe_resp) ++ dev_kfree_skb_any(wlc->probe_resp); ++ wlc->probe_resp = probe_resp; ++ ++ /* add PLCP */ ++ skb_push(wlc->probe_resp, D11_PHY_HDR_LEN); ++ brcms_c_update_probe_resp(wlc, false); ++} ++ + /* Write ssid into shared memory */ + static void + brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg) +@@ -7549,30 +7502,19 @@ brcms_c_shm_ssid_upd(struct brcms_c_info + static void + brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, + struct brcms_bss_cfg *cfg, ++ struct sk_buff *probe_resp, + bool suspend) + { +- u16 *prb_resp; +- int len = BCN_TMPL_LEN; ++ int len; + +- prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC); +- if (!prb_resp) +- return; +- +- /* +- * write the probe response to hardware, or save in +- * the config structure +- */ +- +- /* create the probe response template */ +- brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, +- cfg, prb_resp, &len); ++ len = min_t(size_t, probe_resp->len, BCN_TMPL_LEN); + + if (suspend) + brcms_c_suspend_mac_and_wait(wlc); + + /* write the probe response into the template region */ + brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE, +- (len + 3) & ~3, prb_resp); ++ (len + 3) & ~3, probe_resp->data); + + /* write the length of the probe response frame (+PLCP/-FCS) */ + brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len); +@@ -7586,13 +7528,11 @@ brcms_c_bss_update_probe_resp(struct brc + * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table() + * by subtracting the PLCP len and adding the FCS. + */ +- len += (-D11_PHY_HDR_LEN + FCS_LEN); +- brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len); ++ brcms_c_mod_prb_rsp_rate_table(wlc, ++ (u16)len + FCS_LEN - D11_PHY_HDR_LEN); + + if (suspend) + brcms_c_enable_mac(wlc); +- +- kfree(prb_resp); + } + + void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) +@@ -7600,8 +7540,12 @@ void brcms_c_update_probe_resp(struct br + struct brcms_bss_cfg *bsscfg = wlc->bsscfg; + + /* update AP or IBSS probe responses */ +- if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP) +- brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); ++ if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP) { ++ if (!wlc->probe_resp) ++ return; ++ brcms_c_bss_update_probe_resp(wlc, bsscfg, wlc->probe_resp, ++ suspend); ++ } + } + + int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h +@@ -567,6 +567,7 @@ struct brcms_c_info { + struct sk_buff *beacon; + u16 beacon_tim_offset; + u16 beacon_dtim_period; ++ struct sk_buff *probe_resp; + }; + + /* antsel module specific state */ +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -336,6 +336,8 @@ extern void brcms_c_update_beacon(struct + extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc, + struct sk_buff *beacon, u16 tim_offset, + u16 dtim_period); ++extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc, ++ struct sk_buff *probe_resp); + extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, + size_t ssid_len); + diff --git a/package/mac80211/patches/.svn/text-base/872-brcmsmac-activate-AP-support.patch.svn-base b/package/mac80211/patches/.svn/text-base/872-brcmsmac-activate-AP-support.patch.svn-base new file mode 100644 index 0000000..aaf6840 --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/872-brcmsmac-activate-AP-support.patch.svn-base @@ -0,0 +1,74 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -360,7 +360,8 @@ brcms_ops_add_interface(struct ieee80211 + struct brcms_info *wl = hw->priv; + + /* Just STA for now */ +- if (vif->type != NL80211_IFTYPE_STATION) { ++ if (vif->type != NL80211_IFTYPE_STATION && ++ vif->type != NL80211_IFTYPE_AP) { + brcms_err(wl->wlc->hw->d11core, + "%s: Attempt to add type %d, only STA for now\n", + __func__, vif->type); +@@ -372,6 +373,9 @@ brcms_ops_add_interface(struct ieee80211 + brcms_c_mute(wl->wlc, false); + if (vif->type == NL80211_IFTYPE_STATION) + brcms_c_start_station(wl->wlc, vif->addr); ++ else if (vif->type == NL80211_IFTYPE_AP) ++ brcms_c_start_ap(wl->wlc, vif->addr, vif->bss_conf.bssid, ++ vif->bss_conf.ssid, vif->bss_conf.ssid_len); + spin_unlock_bh(&wl->lock); + + return 0; +@@ -1046,7 +1050,8 @@ static int ieee_hw_init(struct ieee80211 + + /* channel change time is dependent on chip and band */ + hw->channel_change_time = 7 * 1000; +- hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); ++ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | ++ BIT(NL80211_IFTYPE_AP); + + hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; + +--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c +@@ -2176,6 +2176,18 @@ void brcms_c_start_station(struct brcms_ + wlc->bsscfg->type = BRCMS_TYPE_STATION; + } + ++void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid, ++ u8 *ssid, size_t ssid_len) ++{ ++ brcms_c_set_ssid(wlc, ssid, ssid_len); ++ ++ memcpy(wlc->pub->cur_etheraddr, addr, sizeof(wlc->pub->cur_etheraddr)); ++ memcpy(wlc->bsscfg->BSSID, bssid, sizeof(wlc->bsscfg->BSSID)); ++ wlc->bsscfg->type = BRCMS_TYPE_AP; ++ ++ brcms_b_mctrl(wlc->hw, MCTL_AP | MCTL_INFRA, MCTL_AP | MCTL_INFRA); ++} ++ + /* Initialize GPIOs that are controlled by D11 core */ + static void brcms_c_gpio_init(struct brcms_c_info *wlc) + { +@@ -3064,6 +3076,9 @@ static bool brcms_c_ps_allowed(struct br + if (wlc->filter_flags & FIF_PROMISC_IN_BSS) + return false; + ++ if (wlc->bsscfg->type == BRCMS_TYPE_AP) ++ return false; ++ + return true; + } + +--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h ++++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h +@@ -332,6 +332,8 @@ extern bool brcms_c_check_radio_disabled + extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); + extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); + extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr); ++extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, ++ const u8 *bssid, u8 *ssid, size_t ssid_len); + extern void brcms_c_update_beacon(struct brcms_c_info *wlc); + extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc, + struct sk_buff *beacon, u16 tim_offset, diff --git a/package/mac80211/patches/.svn/text-base/873-brcmsmac-remove-extra-regulation-restriction.patch.svn-base b/package/mac80211/patches/.svn/text-base/873-brcmsmac-remove-extra-regulation-restriction.patch.svn-base new file mode 100644 index 0000000..dd1393a --- /dev/null +++ b/package/mac80211/patches/.svn/text-base/873-brcmsmac-remove-extra-regulation-restriction.patch.svn-base @@ -0,0 +1,31 @@ +--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c +@@ -59,23 +59,16 @@ + + #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) + #define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ 0) + + #define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ 0) + #define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_DFS | \ +- NL80211_RRF_NO_IBSS) ++ 0) + #define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_DFS | \ +- NL80211_RRF_NO_IBSS) ++ 0) + #define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ 0) + + static const struct ieee80211_regdomain brcms_regdom_x2 = { + .n_reg_rules = 6, |