Procházet zdrojové kódy

mac80211: update to latest wireless-testing + more stability work

SVN-Revision: 24044
Felix Fietkau před 15 roky
rodič
revize
0e2ad3a266

+ 2 - 2
package/mac80211/Makefile

@@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=mac80211
 
-PKG_VERSION:=2010-11-16
+PKG_VERSION:=2010-11-20
 PKG_RELEASE:=1
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 #	http://www.orbit-lab.org/kernel/compat-wireless-2.6/2010/11 \
 #	http://wireless.kernel.org/download/compat-wireless-2.6
-PKG_MD5SUM:=eb996cb637326203544753d3a05a3979
+PKG_MD5SUM:=2c9ca2ff2d8c20dca33e72d271219c3c
 
 PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2
 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)

+ 2 - 2
package/mac80211/patches/300-ath9k_gpio_settings.patch

@@ -26,7 +26,7 @@
  	struct ar5416IniArray iniCommon;
 --- a/drivers/net/wireless/ath/ath9k/hw.c
 +++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1182,6 +1182,20 @@ static bool ath9k_hw_channel_change(stru
+@@ -1178,6 +1178,20 @@ static bool ath9k_hw_channel_change(stru
  	return true;
  }
  
@@ -47,7 +47,7 @@
  bool ath9k_hw_check_alive(struct ath_hw *ah)
  {
  	int count = 50;
-@@ -1468,6 +1482,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+@@ -1464,6 +1478,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
  	if (AR_SREV_9300_20_OR_LATER(ah))
  		ar9003_hw_bb_watchdog_config(ah);
  

+ 0 - 127
package/mac80211/patches/310-pending_work.patch → package/mac80211/patches/310-pending_cfg80211_fixes.patch

@@ -1,117 +1,3 @@
---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
-@@ -3271,6 +3271,18 @@ static bool ar9300_check_eeprom_header(s
- 	return ar9300_check_header(header);
- }
- 
-+static int ar9300_eeprom_restore_flash(struct ath_hw *ah, u8 *mptr,
-+				       int mdata_size)
-+{
-+	struct ath_common *common = ath9k_hw_common(ah);
-+	u16 *data = (u16 *) mptr;
-+	int i;
-+
-+	for (i = 0; i < mdata_size / 2; i++, data++)
-+		ath9k_hw_nvram_read(common, i, data);
-+
-+	return 0;
-+}
- /*
-  * Read the configuration data from the eeprom.
-  * The data can be put in any specified memory buffer.
-@@ -3293,6 +3305,9 @@ static int ar9300_eeprom_restore_interna
- 	struct ath_common *common = ath9k_hw_common(ah);
- 	eeprom_read_op read;
- 
-+	if (ath9k_hw_use_flash(ah))
-+		return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
-+
- 	word = kzalloc(2048, GFP_KERNEL);
- 	if (!word)
- 		return -1;
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -419,10 +419,6 @@ static void ath9k_hw_init_defaults(struc
- 	ah->hw_version.magic = AR5416_MAGIC;
- 	ah->hw_version.subvendorid = 0;
- 
--	ah->ah_flags = 0;
--	if (!AR_SREV_9100(ah))
--		ah->ah_flags = AH_USE_EEPROM;
--
- 	ah->atim_window = 0;
- 	ah->sta_id1_defaults =
- 		AR_STA_ID1_CRPT_MIC_ENABLE |
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -533,6 +533,9 @@ static int ath9k_init_softc(u16 devid, s
- 	ah->hw_version.subsysid = subsysid;
- 	sc->sc_ah = ah;
- 
-+	if (!sc->dev->platform_data)
-+		ah->ah_flags |= AH_USE_EEPROM;
-+
- 	common = ath9k_hw_common(ah);
- 	common->ops = &ath9k_common_ops;
- 	common->bus_ops = bus_ops;
---- a/drivers/net/wireless/ath/ath9k/pci.c
-+++ b/drivers/net/wireless/ath/ath9k/pci.c
-@@ -16,6 +16,7 @@
- 
- #include <linux/nl80211.h>
- #include <linux/pci.h>
-+#include <linux/ath9k_platform.h>
- #include "ath9k.h"
- 
- static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
-@@ -53,21 +54,36 @@ static void ath_pci_read_cachesize(struc
- 
- static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
- {
--	struct ath_hw *ah = (struct ath_hw *) common->ah;
-+	struct ath_softc *sc = (struct ath_softc *) common->priv;
-+	struct ath9k_platform_data *pdata = sc->dev->platform_data;
- 
--	common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
-+	if (pdata) {
-+		if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
-+			ath_print(common, ATH_DBG_FATAL,
-+				  "%s: eeprom read failed, offset %08x "
-+				  "is out of range\n",
-+				  __func__, off);
-+		}
-+
-+		*data = pdata->eeprom_data[off];
-+	} else {
-+		struct ath_hw *ah = (struct ath_hw *) common->ah;
-+
-+		common->ops->read(ah, AR5416_EEPROM_OFFSET +
-+				      (off << AR5416_EEPROM_S));
-+
-+		if (!ath9k_hw_wait(ah,
-+				   AR_EEPROM_STATUS_DATA,
-+				   AR_EEPROM_STATUS_DATA_BUSY |
-+				   AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
-+				   AH_WAIT_TIMEOUT)) {
-+			return false;
-+		}
- 
--	if (!ath9k_hw_wait(ah,
--			   AR_EEPROM_STATUS_DATA,
--			   AR_EEPROM_STATUS_DATA_BUSY |
--			   AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
--			   AH_WAIT_TIMEOUT)) {
--		return false;
-+		*data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
-+			   AR_EEPROM_STATUS_DATA_VAL);
- 	}
- 
--	*data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
--		   AR_EEPROM_STATUS_DATA_VAL);
--
- 	return true;
- }
- 
 --- a/include/net/regulatory.h
 +++ b/include/net/regulatory.h
 @@ -43,6 +43,12 @@ enum environment_cap {
@@ -290,16 +176,3 @@
  	mutex_unlock(&reg_mutex);
  
  	return r;
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -54,8 +54,10 @@ static bool can_beacon_sec_chan(struct w
- 	switch (channel_type) {
- 	case NL80211_CHAN_HT40PLUS:
- 		diff = 20;
-+		break;
- 	case NL80211_CHAN_HT40MINUS:
- 		diff = -20;
-+		break;
- 	default:
- 		return false;
- 	}

+ 279 - 0
package/mac80211/patches/311-pending_work.patch

@@ -0,0 +1,279 @@
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -766,14 +766,6 @@ void ath9k_hw_startpcureceive(struct ath
+ }
+ EXPORT_SYMBOL(ath9k_hw_startpcureceive);
+ 
+-void ath9k_hw_stoppcurecv(struct ath_hw *ah)
+-{
+-	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+-
+-	ath9k_hw_disable_mib_counters(ah);
+-}
+-EXPORT_SYMBOL(ath9k_hw_stoppcurecv);
+-
+ void ath9k_hw_abortpcurecv(struct ath_hw *ah)
+ {
+ 	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -691,7 +691,6 @@ void ath9k_hw_setuprxdesc(struct ath_hw 
+ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
+ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
+ void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning);
+-void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+ void ath9k_hw_abortpcurecv(struct ath_hw *ah);
+ bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
+ int ath9k_hw_beaconq_setup(struct ath_hw *ah);
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc)
+ 	bool stopped;
+ 
+ 	spin_lock_bh(&sc->rx.rxbuflock);
+-	ath9k_hw_stoppcurecv(ah);
++	ath9k_hw_abortpcurecv(ah);
+ 	ath9k_hw_setrxfilter(ah, 0);
+ 	stopped = ath9k_hw_stopdmarecv(ah);
+ 
+--- a/drivers/net/wireless/ath/ath9k/xmit.c
++++ b/drivers/net/wireless/ath/ath9k/xmit.c
+@@ -163,6 +163,7 @@ static void ath_tx_flush_tid(struct ath_
+ 		bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+ 		list_move_tail(&bf->list, &bf_head);
+ 
++		spin_unlock_bh(&txq->axq_lock);
+ 		fi = get_frame_info(bf->bf_mpdu);
+ 		if (fi->retries) {
+ 			ath_tx_update_baw(sc, tid, fi->seqno);
+@@ -170,6 +171,7 @@ static void ath_tx_flush_tid(struct ath_
+ 		} else {
+ 			ath_tx_send_normal(sc, txq, tid, &bf_head);
+ 		}
++		spin_lock_bh(&txq->axq_lock);
+ 	}
+ 
+ 	spin_unlock_bh(&txq->axq_lock);
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -349,6 +349,7 @@ struct ieee80211_if_managed {
+ 	struct work_struct chswitch_work;
+ 	struct work_struct beacon_connection_loss_work;
+ 
++	unsigned long beacon_timeout;
+ 	unsigned long probe_timeout;
+ 	int probe_send_count;
+ 
+@@ -1269,6 +1270,8 @@ void ieee80211_send_nullfunc(struct ieee
+ 			     int powersave);
+ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
+ 			     struct ieee80211_hdr *hdr);
++void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
++			     struct ieee80211_hdr *hdr);
+ void ieee80211_beacon_connection_loss_work(struct work_struct *work);
+ 
+ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -28,13 +28,19 @@
+ #include "rate.h"
+ #include "led.h"
+ 
++#define IEEE80211_MAX_NULLFUNC_TRIES 2
+ #define IEEE80211_MAX_PROBE_TRIES 5
+ 
+ /*
+- * beacon loss detection timeout
+- * XXX: should depend on beacon interval
++ * Beacon loss timeout is calculated as N frames times the
++ * advertised beacon interval.  This may need to be somewhat
++ * higher than what hardware might detect to account for
++ * delays in the host processing frames. But since we also
++ * probe on beacon miss before declaring the connection lost
++ * default to what we want.
+  */
+-#define IEEE80211_BEACON_LOSS_TIME	(2 * HZ)
++#define IEEE80211_BEACON_LOSS_COUNT	7
++
+ /*
+  * Time the connection can be idle before we probe
+  * it to see if we can still talk to the AP.
+@@ -45,7 +51,7 @@
+  * a probe request because of beacon loss or for
+  * checking the connection still works.
+  */
+-#define IEEE80211_PROBE_WAIT		(HZ / 2)
++#define IEEE80211_PROBE_WAIT		(HZ / 5)
+ 
+ /*
+  * Weight given to the latest Beacon frame when calculating average signal
+@@ -121,7 +127,7 @@ void ieee80211_sta_reset_beacon_monitor(
+ 		return;
+ 
+ 	mod_timer(&sdata->u.mgd.bcn_mon_timer,
+-		  round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
++		  round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
+ }
+ 
+ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
+@@ -871,6 +877,9 @@ static void ieee80211_set_associated(str
+ 	bss_info_changed |= ieee80211_handle_bss_capability(sdata,
+ 		cbss->capability, bss->has_erp_value, bss->erp_value);
+ 
++	sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
++		IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
++
+ 	sdata->u.mgd.associated = cbss;
+ 	memcpy(sdata->u.mgd.bssid, cbss->bssid, ETH_ALEN);
+ 
+@@ -1026,6 +1035,50 @@ void ieee80211_sta_rx_notify(struct ieee
+ 	ieee80211_sta_reset_conn_monitor(sdata);
+ }
+ 
++static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
++{
++	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
++
++	if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
++			      IEEE80211_STA_CONNECTION_POLL)))
++	    return;
++
++	ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
++			  IEEE80211_STA_BEACON_POLL);
++	mutex_lock(&sdata->local->iflist_mtx);
++	ieee80211_recalc_ps(sdata->local, -1);
++	mutex_unlock(&sdata->local->iflist_mtx);
++
++	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
++		return;
++
++	/*
++	 * We've received a probe response, but are not sure whether
++	 * we have or will be receiving any beacons or data, so let's
++	 * schedule the timers again, just in case.
++	 */
++	ieee80211_sta_reset_beacon_monitor(sdata);
++
++	mod_timer(&ifmgd->conn_mon_timer,
++		  round_jiffies_up(jiffies +
++				   IEEE80211_CONNECTION_IDLE_TIME));
++}
++
++void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
++			     struct ieee80211_hdr *hdr)
++{
++	if (!ieee80211_is_data(hdr->frame_control) &&
++	    !ieee80211_is_nullfunc(hdr->frame_control))
++	    return;
++
++	ieee80211_sta_reset_conn_monitor(sdata);
++
++	if (ieee80211_is_nullfunc(hdr->frame_control)) {
++		sdata->u.mgd.probe_send_count = 0;
++		ieee80211_queue_work(&sdata->local->hw, &sdata->work);
++	}
++}
++
+ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
+ {
+ 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+@@ -1041,8 +1094,19 @@ static void ieee80211_mgd_probe_ap_send(
+ 	if (ifmgd->probe_send_count >= unicast_limit)
+ 		dst = NULL;
+ 
+-	ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
+-	ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
++	/*
++	 * When the hardware reports an accurate Tx ACK status, it's
++	 * better to send a nullfunc frame instead of a probe request,
++	 * as it will kick us off the AP quickly if we aren't associated
++	 * anymore. The timeout will be reset if the frame is ACKed by
++	 * the AP.
++	 */
++	if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
++		ieee80211_send_nullfunc(sdata->local, sdata, 0);
++	else {
++		ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
++		ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0);
++	}
+ 
+ 	ifmgd->probe_send_count++;
+ 	ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
+@@ -1509,29 +1573,8 @@ static void ieee80211_rx_mgmt_probe_resp
+ 	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
+ 
+ 	if (ifmgd->associated &&
+-	    memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0 &&
+-	    ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+-			    IEEE80211_STA_CONNECTION_POLL)) {
+-		ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+-				  IEEE80211_STA_BEACON_POLL);
+-		mutex_lock(&sdata->local->iflist_mtx);
+-		ieee80211_recalc_ps(sdata->local, -1);
+-		mutex_unlock(&sdata->local->iflist_mtx);
+-
+-		if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
+-			return;
+-
+-		/*
+-		 * We've received a probe response, but are not sure whether
+-		 * we have or will be receiving any beacons or data, so let's
+-		 * schedule the timers again, just in case.
+-		 */
+-		ieee80211_sta_reset_beacon_monitor(sdata);
+-
+-		mod_timer(&ifmgd->conn_mon_timer,
+-			  round_jiffies_up(jiffies +
+-					   IEEE80211_CONNECTION_IDLE_TIME));
+-	}
++	    memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
++		ieee80211_reset_ap_probe(sdata);
+ }
+ 
+ /*
+@@ -1881,12 +1924,22 @@ void ieee80211_sta_work(struct ieee80211
+ 			    IEEE80211_STA_CONNECTION_POLL) &&
+ 	    ifmgd->associated) {
+ 		u8 bssid[ETH_ALEN];
++		int max_tries;
++
++		/* ACK received for nullfunc probing frame */
++		if (!ifmgd->probe_send_count)
++			ieee80211_reset_ap_probe(sdata);
++
++		if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
++			max_tries = IEEE80211_MAX_NULLFUNC_TRIES;
++		else
++			max_tries = IEEE80211_MAX_PROBE_TRIES;
+ 
+ 		memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
+ 		if (time_is_after_jiffies(ifmgd->probe_timeout))
+ 			run_again(ifmgd, ifmgd->probe_timeout);
+ 
+-		else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
++		else if (ifmgd->probe_send_count < max_tries) {
+ #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ 			wiphy_debug(local->hw.wiphy,
+ 				    "%s: No probe response from AP %pM"
+@@ -2012,6 +2065,8 @@ void ieee80211_sta_restart(struct ieee80
+ 		add_timer(&ifmgd->timer);
+ 	if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
+ 		add_timer(&ifmgd->chswitch_timer);
++	ieee80211_sta_reset_beacon_monitor(sdata);
++	ieee80211_send_nullfunc(sdata->local, sdata, 0);
+ }
+ #endif
+ 
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -155,6 +155,10 @@ static void ieee80211_frame_acked(struct
+ 
+ 		ieee80211_queue_work(&local->hw, &local->recalc_smps);
+ 	}
++
++	if ((sdata->vif.type == NL80211_IFTYPE_STATION) &&
++	    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
++		ieee80211_sta_tx_notify(sdata, (void *) skb->data);
+ }
+ 
+ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)