Преглед на файлове

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (78 commits)
  AX.25: Fix sysctl registration if !CONFIG_AX25_DAMA_SLAVE
  pktgen: mac count
  pktgen: random flow 
  bridge: Eliminate unnecessary forward delay
  bridge: fix compile warning in net/bridge/br_netfilter.c
  ipv4: remove unused field in struct flowi (include/net/flow.h).
  tg3: Fix 'scheduling while atomic' errors
  net: Kill plain NET_XMIT_BYPASS.
  net_sched: Add qdisc __NET_XMIT_BYPASS flag
  net_sched: Add qdisc __NET_XMIT_STOLEN flag
  iwl3945: fix merge mistake for packet injection
  iwlwifi: grap nic access before accessing periphery registers
  iwlwifi: decrement rx skb counter in scan abort handler
  iwlwifi: fix unhandled interrupt when HW rfkill is on
  iwlwifi: implement iwl5000_calc_rssi
  iwlwifi: memory allocation optimization
  iwlwifi: HW bug fixes
  p54: Fix potential concurrent access to private data
  rt2x00: Disable link tuning in rt2500usb
  iwlwifi: Don't use buffer allocated on the stack for led names
  ...
Linus Torvalds преди 17 години
родител
ревизия
e63e03273b
променени са 95 файла, в които са добавени 1874 реда и са изтрити 1236 реда
  1. 4 16
      drivers/net/tg3.c
  2. 1 0
      drivers/net/wireless/Kconfig
  3. 5 3
      drivers/net/wireless/ath5k/ath5k.h
  4. 1 0
      drivers/net/wireless/ath5k/base.c
  5. 1 1
      drivers/net/wireless/ath5k/debug.c
  6. 0 1
      drivers/net/wireless/ath5k/debug.h
  7. 149 90
      drivers/net/wireless/ath5k/hw.c
  8. 2 2
      drivers/net/wireless/ath5k/initvals.c
  9. 167 18
      drivers/net/wireless/ath5k/phy.c
  10. 410 191
      drivers/net/wireless/ath5k/reg.h
  11. 3 2
      drivers/net/wireless/ipw2200.c
  12. 51 47
      drivers/net/wireless/iwlwifi/Kconfig
  13. 6 7
      drivers/net/wireless/iwlwifi/Makefile
  14. 17 16
      drivers/net/wireless/iwlwifi/iwl-3945-led.c
  15. 1 0
      drivers/net/wireless/iwlwifi/iwl-3945-led.h
  16. 9 8
      drivers/net/wireless/iwlwifi/iwl-3945.c
  17. 40 116
      drivers/net/wireless/iwlwifi/iwl-4965.c
  18. 64 7
      drivers/net/wireless/iwlwifi/iwl-5000.c
  19. 114 213
      drivers/net/wireless/iwlwifi/iwl-agn-rs.c
  20. 7 16
      drivers/net/wireless/iwlwifi/iwl-agn-rs.h
  21. 148 84
      drivers/net/wireless/iwlwifi/iwl-agn.c
  22. 31 13
      drivers/net/wireless/iwlwifi/iwl-commands.h
  23. 4 3
      drivers/net/wireless/iwlwifi/iwl-core.c
  24. 2 1
      drivers/net/wireless/iwlwifi/iwl-core.h
  25. 9 1
      drivers/net/wireless/iwlwifi/iwl-csr.h
  26. 2 2
      drivers/net/wireless/iwlwifi/iwl-debug.h
  27. 7 4
      drivers/net/wireless/iwlwifi/iwl-debugfs.c
  28. 7 15
      drivers/net/wireless/iwlwifi/iwl-dev.h
  29. 1 2
      drivers/net/wireless/iwlwifi/iwl-eeprom.c
  30. 1 1
      drivers/net/wireless/iwlwifi/iwl-hcmd.c
  31. 41 28
      drivers/net/wireless/iwlwifi/iwl-led.c
  32. 1 0
      drivers/net/wireless/iwlwifi/iwl-led.h
  33. 28 17
      drivers/net/wireless/iwlwifi/iwl-power.c
  34. 23 10
      drivers/net/wireless/iwlwifi/iwl-power.h
  35. 7 5
      drivers/net/wireless/iwlwifi/iwl-prph.h
  36. 16 43
      drivers/net/wireless/iwlwifi/iwl-rx.c
  37. 1 0
      drivers/net/wireless/iwlwifi/iwl-scan.c
  38. 2 2
      drivers/net/wireless/iwlwifi/iwl-sta.c
  39. 59 27
      drivers/net/wireless/iwlwifi/iwl-tx.c
  40. 23 35
      drivers/net/wireless/iwlwifi/iwl3945-base.c
  41. 9 6
      drivers/net/wireless/libertas/main.c
  42. 1 0
      drivers/net/wireless/p54/p54.h
  43. 6 0
      drivers/net/wireless/p54/p54common.c
  44. 1 1
      drivers/net/wireless/prism54/isl_ioctl.c
  45. 1 0
      drivers/net/wireless/rt2x00/rt2500pci.c
  46. 17 3
      drivers/net/wireless/rt2x00/rt2500usb.c
  47. 6 0
      drivers/net/wireless/rt2x00/rt2x00.h
  48. 4 0
      drivers/net/wireless/rt2x00/rt2x00config.c
  49. 7 10
      drivers/net/wireless/rt2x00/rt2x00debug.c
  50. 1 0
      drivers/net/wireless/rt2x00/rt2x00mac.c
  51. 3 2
      drivers/net/wireless/rt2x00/rt2x00queue.c
  52. 2 2
      drivers/net/wireless/rt2x00/rt2x00usb.c
  53. 1 1
      drivers/net/wireless/rt2x00/rt2x00usb.h
  54. 5 0
      drivers/net/wireless/rt2x00/rt61pci.c
  55. 4 0
      drivers/net/wireless/rtl8187.h
  56. 16 1
      drivers/net/wireless/rtl8187_dev.c
  57. 13 0
      include/linux/ieee80211.h
  58. 1 3
      include/linux/netdevice.h
  59. 1 11
      include/net/dst.h
  60. 0 1
      include/net/flow.h
  61. 11 2
      include/net/mac80211.h
  62. 25 1
      include/net/sch_generic.h
  63. 1 2
      include/net/sctp/structs.h
  64. 4 10
      net/ax25/sysctl_net_ax25.c
  65. 1 1
      net/bridge/br_netfilter.c
  66. 18 7
      net/bridge/br_stp.c
  67. 22 10
      net/core/dev.c
  68. 7 6
      net/core/neighbour.c
  69. 7 3
      net/core/pktgen.c
  70. 1 0
      net/ipv4/sysctl_net_ipv4.c
  71. 1 1
      net/ipv6/ip6_output.c
  72. 2 0
      net/ipv6/ipv6_sockglue.c
  73. 11 11
      net/ipv6/syncookies.c
  74. 2 0
      net/mac80211/ieee80211_i.h
  75. 5 0
      net/mac80211/main.c
  76. 32 7
      net/mac80211/mlme.c
  77. 12 5
      net/mac80211/tx.c
  78. 1 0
      net/mac80211/util.c
  79. 4 2
      net/mac80211/wme.c
  80. 39 15
      net/rfkill/rfkill-input.c
  81. 14 1
      net/rfkill/rfkill.c
  82. 8 6
      net/sched/sch_atm.c
  83. 17 10
      net/sched/sch_cbq.c
  84. 6 4
      net/sched/sch_dsmark.c
  85. 6 6
      net/sched/sch_generic.c
  86. 7 5
      net/sched/sch_hfsc.c
  87. 14 10
      net/sched/sch_htb.c
  88. 3 2
      net/sched/sch_netem.c
  89. 8 6
      net/sched/sch_prio.c
  90. 1 1
      net/sched/sch_red.c
  91. 4 4
      net/sched/sch_sfq.c
  92. 2 1
      net/sched/sch_tbf.c
  93. 5 3
      net/sctp/ipv6.c
  94. 2 4
      net/sctp/output.c
  95. 7 2
      net/sctp/protocol.c

+ 4 - 16
drivers/net/tg3.c

@@ -7687,21 +7687,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
  */
 static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 {
-	int err;
-
-	/* Force the chip into D0. */
-	err = tg3_set_power_state(tp, PCI_D0);
-	if (err)
-		goto out;
-
 	tg3_switch_clocks(tp);
 
 	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
 
-	err = tg3_reset_hw(tp, reset_phy);
-
-out:
-	return err;
+	return tg3_reset_hw(tp, reset_phy);
 }
 
 #define TG3_STAT_ADD32(PSTAT, REG) \
@@ -8016,13 +8006,11 @@ static int tg3_open(struct net_device *dev)
 
 	netif_carrier_off(tp->dev);
 
-	tg3_full_lock(tp, 0);
-
 	err = tg3_set_power_state(tp, PCI_D0);
-	if (err) {
-		tg3_full_unlock(tp);
+	if (err)
 		return err;
-	}
+
+	tg3_full_lock(tp, 0);
 
 	tg3_disable_ints(tp);
 	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;

+ 1 - 0
drivers/net/wireless/Kconfig

@@ -649,6 +649,7 @@ config RTL8187
 	  Trendnet TEW-424UB
 	  ASUS P5B Deluxe
 	  Toshiba Satellite Pro series of laptops
+	  Asus Wireless Link
 
 	  Thanks to Realtek for their support!
 

+ 5 - 3
drivers/net/wireless/ath5k/ath5k.h

@@ -186,11 +186,13 @@ struct ath5k_srev_name {
 #define AR5K_SREV_RAD_2111	0x20
 #define AR5K_SREV_RAD_5112	0x30
 #define AR5K_SREV_RAD_5112A	0x35
+#define	AR5K_SREV_RAD_5112B	0x36
 #define AR5K_SREV_RAD_2112	0x40
 #define AR5K_SREV_RAD_2112A	0x45
-#define AR5K_SREV_RAD_SC0	0x56	/* Found on 2413/2414 */
-#define AR5K_SREV_RAD_SC1	0x63	/* Found on 5413/5414 */
-#define AR5K_SREV_RAD_SC2	0xa2	/* Found on 2424-5/5424 */
+#define	AR5K_SREV_RAD_2112B	0x46
+#define AR5K_SREV_RAD_SC0	0x50	/* Found on 2413/2414 */
+#define AR5K_SREV_RAD_SC1	0x60	/* Found on 5413/5414 */
+#define AR5K_SREV_RAD_SC2	0xa0	/* Found on 2424-5/5424 */
 #define AR5K_SREV_RAD_5133	0xc0	/* MIMO found on 5418 */
 
 /* IEEE defs */

+ 1 - 0
drivers/net/wireless/ath5k/base.c

@@ -2170,6 +2170,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
 
 	ath5k_hw_set_intr(ah, 0);
 	sc->bmisscount = 0;
+	sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
 
 	if (sc->opmode == IEEE80211_IF_TYPE_STA) {
 		sc->imask |= AR5K_INT_BMISS;

+ 1 - 1
drivers/net/wireless/ath5k/debug.c

@@ -129,7 +129,7 @@ static struct reg regs[] = {
 	REG_STRUCT_INIT(AR5K_CPC1),
 	REG_STRUCT_INIT(AR5K_CPC2),
 	REG_STRUCT_INIT(AR5K_CPC3),
-	REG_STRUCT_INIT(AR5K_CPCORN),
+	REG_STRUCT_INIT(AR5K_CPCOVF),
 	REG_STRUCT_INIT(AR5K_RESET_CTL),
 	REG_STRUCT_INIT(AR5K_SLEEP_CTL),
 	REG_STRUCT_INIT(AR5K_INTPEND),

+ 0 - 1
drivers/net/wireless/ath5k/debug.h

@@ -63,7 +63,6 @@
 
 struct ath5k_softc;
 struct ath5k_hw;
-struct ieee80211_hw_mode;
 struct sk_buff;
 struct ath5k_buf;
 

+ 149 - 90
drivers/net/wireless/ath5k/hw.c

@@ -139,6 +139,8 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
 	for (c = 0; c < 2; c++) {
 
 		cur_reg = regs[c];
+
+		/* Save previous value */
 		init_val = ath5k_hw_reg_read(ah, cur_reg);
 
 		for (i = 0; i < 256; i++) {
@@ -170,6 +172,10 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
 			var_pattern = 0x003b080f;
 			ath5k_hw_reg_write(ah, var_pattern, cur_reg);
 		}
+
+		/* Restore previous value */
+		ath5k_hw_reg_write(ah, init_val, cur_reg);
+
 	}
 
 	return 0;
@@ -287,67 +293,42 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 	/* Identify the radio chip*/
 	if (ah->ah_version == AR5K_AR5210) {
 		ah->ah_radio = AR5K_RF5110;
+	/*
+	 * Register returns 0x0/0x04 for radio revision
+	 * so ath5k_hw_radio_revision doesn't parse the value
+	 * correctly. For now we are based on mac's srev to
+	 * identify RF2425 radio.
+	 */
+	} else if (srev == AR5K_SREV_VER_AR2425) {
+		ah->ah_radio = AR5K_RF2425;
+		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
 	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
 		ah->ah_radio = AR5K_RF5111;
 		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
 	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
-
 		ah->ah_radio = AR5K_RF5112;
-
-		if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
-		} else {
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
-		}
-
+		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
 	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
 		ah->ah_radio = AR5K_RF2413;
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
+		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
 	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
 		ah->ah_radio = AR5K_RF5413;
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
+		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
 	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
-
 		/* AR5424 */
 		if (srev >= AR5K_SREV_VER_AR5424) {
 			ah->ah_radio = AR5K_RF5413;
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
+			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
 		/* AR2424 */
 		} else {
 			ah->ah_radio = AR5K_RF2413; /* For testing */
-			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
+			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
 		}
-
-	/*
-	 * Register returns 0x4 for radio revision
-	 * so ath5k_hw_radio_revision doesn't parse the value
-	 * correctly. For now we are based on mac's srev to
-	 * identify RF2425 radio.
-	 */
-	} else if (srev == AR5K_SREV_VER_AR2425) {
-		ah->ah_radio = AR5K_RF2425;
-		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
 	}
-
 	ah->ah_phy = AR5K_PHY(0);
 
 	/*
-	 * Identify AR5212-based PCI-E cards
-	 * And write some initial settings.
-	 *
-	 * (doing a "strings" on ndis driver
-	 * -ar5211.sys- reveals the following
-	 * pci-e related functions:
-	 *
-	 * pcieClockReq
-	 * pcieRxErrNotify
-	 * pcieL1SKPEnable
-	 * pcieAspm
-	 * pcieDisableAspmOnRfWake
-	 * pciePowerSaveEnable
-	 *
-	 * I guess these point to ClockReq but
-	 * i'm not sure.)
+	 * Write PCI-E power save settings
 	 */
 	if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
 		ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
@@ -369,10 +350,15 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 	if (ret)
 		goto err_free;
 
+	/* Write AR5K_PCICFG_UNK on 2112B and later chips */
+	if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
+	srev > AR5K_SREV_VER_AR2413) {
+		ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
+	}
+
 	/*
 	 * Get card capabilities, values, ...
 	 */
-
 	ret = ath5k_eeprom_init(ah);
 	if (ret) {
 		ATH5K_ERR(sc, "unable to init EEPROM\n");
@@ -843,27 +829,41 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 		 * Write some more initial register settings
 		 */
 		if (ah->ah_version == AR5K_AR5212) {
-			ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
+			ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
 
 			if (channel->hw_value == CHANNEL_G)
 				if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
 					ath5k_hw_reg_write(ah, 0x00f80d80,
-						AR5K_PHY(83));
+								0x994c);
 				else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
 					ath5k_hw_reg_write(ah, 0x00380140,
-						AR5K_PHY(83));
+								0x994c);
 				else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
 					ath5k_hw_reg_write(ah, 0x00fc0ec0,
-						AR5K_PHY(83));
+								0x994c);
 				else /* 2425 */
 					ath5k_hw_reg_write(ah, 0x00fc0fc0,
-						AR5K_PHY(83));
+								0x994c);
 			else
-				ath5k_hw_reg_write(ah, 0x00000000,
-					AR5K_PHY(83));
-
-			ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
-			ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
+				ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
+
+			/* Some bits are disabled here, we know nothing about
+			 * register 0xa228 yet, most of the times this ends up
+			 * with a value 0x9b5 -haven't seen any dump with
+			 * a different value- */
+			/* Got this from decompiling binary HAL */
+			data = ath5k_hw_reg_read(ah, 0xa228);
+			data &= 0xfffffdff;
+			ath5k_hw_reg_write(ah, data, 0xa228);
+
+			data = ath5k_hw_reg_read(ah, 0xa228);
+			data &= 0xfffe03ff;
+			ath5k_hw_reg_write(ah, data, 0xa228);
+			data = 0;
+
+			/* Just write 0x9b5 ? */
+			/* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
+			ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
 			ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
 			ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
 		}
@@ -879,6 +879,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 			else
 				data = 0xffb80d20;
 			ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
+			data = 0;
 		}
 
 		/*
@@ -898,7 +899,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 
 		/*
 		 * Write RF registers
-		 * TODO:Does this work on 5211 (5111) ?
 		 */
 		ret = ath5k_hw_rfregs(ah, channel, mode);
 		if (ret)
@@ -935,7 +935,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 			return ret;
 
 		/* Set antenna mode */
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x44),
+		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
 			ah->ah_antenna[ee_mode][0], 0xfffffc06);
 
 		/*
@@ -965,15 +965,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 
 		ath5k_hw_reg_write(ah,
 			AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
-			AR5K_PHY(0x5a));
+			AR5K_PHY_NFTHRES);
 
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x11),
+		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
 			(ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
 			0xffffc07f);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x12),
+		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
 			(ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
 			0xfffc0fff);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x14),
+		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
 			(ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
 			((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
 			0xffff0000);
@@ -982,13 +982,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 			(ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
 			(ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
 			(ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
-			(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY(0x0d));
+			(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
 
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x0a),
+		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
 			ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x19),
+		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
 			(ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
-		AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x49), 4, 0xffffff01);
+		AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
 
 		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
 		    AR5K_PHY_IQ_CORR_ENABLE |
@@ -1063,7 +1063,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 	ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
 
 	/*
-	 * 5111/5112 Specific
+	 * On 5211+ read activation -> rx delay
+	 * and use it.
 	 */
 	if (ah->ah_version != AR5K_AR5210) {
 		data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
@@ -1071,40 +1072,77 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 		data = (channel->hw_value & CHANNEL_CCK) ?
 			((data << 2) / 22) : (data / 10);
 
-		udelay(100 + data);
+		udelay(100 + (2 * data));
+		data = 0;
 	} else {
 		mdelay(1);
 	}
 
 	/*
-	 * Enable calibration and wait until completion
+	 * Perform ADC test (?)
+	 */
+	data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+	ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
+	for (i = 0; i <= 20; i++) {
+		if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
+			break;
+		udelay(200);
+	}
+	ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
+	data = 0;
+
+	/*
+	 * Start automatic gain calibration
+	 *
+	 * During AGC calibration RX path is re-routed to
+	 * a signal detector so we don't receive anything.
+	 *
+	 * This method is used to calibrate some static offsets
+	 * used together with on-the fly I/Q calibration (the
+	 * one performed via ath5k_hw_phy_calibrate), that doesn't
+	 * interrupt rx path.
+	 *
+	 * If we are in a noisy environment AGC calibration may time
+	 * out.
 	 */
 	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
 				AR5K_PHY_AGCCTL_CAL);
 
+	/* At the same time start I/Q calibration for QAM constellation
+	 * -no need for CCK- */
+	ah->ah_calibration = false;
+	if (!(mode == AR5K_MODE_11B)) {
+		ah->ah_calibration = true;
+		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+				AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+				AR5K_PHY_IQ_RUN);
+	}
+
+	/* Wait for gain calibration to finish (we check for I/Q calibration
+	 * during ath5k_phy_calibrate) */
 	if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
 			AR5K_PHY_AGCCTL_CAL, 0, false)) {
-		ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
+		ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
 			channel->center_freq);
 		return -EAGAIN;
 	}
 
+	/*
+	 * Start noise floor calibration
+	 *
+	 * If we run NF calibration before AGC, it always times out.
+	 * Binary HAL starts NF and AGC calibration at the same time
+	 * and only waits for AGC to finish. I believe that's wrong because
+	 * during NF calibration, rx path is also routed to a detector, so if
+	 * it doesn't finish we won't have RX.
+	 *
+	 * XXX: Find an interval that's OK for all cards...
+	 */
 	ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
 	if (ret)
 		return ret;
 
-	ah->ah_calibration = false;
-
-	/* A and G modes can use QAM modulation which requires enabling
-	 * I and Q calibration. Don't bother in B mode. */
-	if (!(mode == AR5K_MODE_11B)) {
-		ah->ah_calibration = true;
-		AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
-				AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
-		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
-				AR5K_PHY_IQ_RUN);
-	}
-
 	/*
 	 * Reset queues and start beacon timers at the end of the reset routine
 	 */
@@ -1154,6 +1192,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
 		ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
 		ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
 		ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
+
+		data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
+		data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
+						0x00000f80 : 0x00001380 ;
+		ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
+		data = 0;
 	}
 
 	if (ah->ah_version == AR5K_AR5212) {
@@ -1226,7 +1270,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
 		bool set_chip, u16 sleep_duration)
 {
 	unsigned int i;
-	u32 staid;
+	u32 staid, data;
 
 	ATH5K_TRACE(ah->ah_sc);
 	staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
@@ -1238,7 +1282,8 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
 	case AR5K_PM_NETWORK_SLEEP:
 		if (set_chip)
 			ath5k_hw_reg_write(ah,
-				AR5K_SLEEP_CTL_SLE | sleep_duration,
+				AR5K_SLEEP_CTL_SLE_ALLOW |
+				sleep_duration,
 				AR5K_SLEEP_CTL);
 
 		staid |= AR5K_STA_ID1_PWR_SV;
@@ -1253,13 +1298,24 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
 		break;
 
 	case AR5K_PM_AWAKE:
+
+		staid &= ~AR5K_STA_ID1_PWR_SV;
+
 		if (!set_chip)
 			goto commit;
 
-		ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
-				AR5K_SLEEP_CTL);
+		/* Preserve sleep duration */
+		data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
+		if( data & 0xffc00000 ){
+			data = 0;
+		} else {
+			data = data & 0xfffcffff;
+		}
+
+		ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+		udelay(15);
 
-		for (i = 5000; i > 0; i--) {
+		for (i = 50; i > 0; i--) {
 			/* Check if the chip did wake up */
 			if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
 					AR5K_PCICFG_SPWR_DN) == 0)
@@ -1267,15 +1323,13 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
 
 			/* Wait a bit and retry */
 			udelay(200);
-			ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
-				AR5K_SLEEP_CTL);
+			ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
 		}
 
 		/* Fail if the chip didn't wake up */
 		if (i <= 0)
 			return -EIO;
 
-		staid &= ~AR5K_STA_ID1_PWR_SV;
 		break;
 
 	default:
@@ -1304,6 +1358,7 @@ void ath5k_hw_start_rx(struct ath5k_hw *ah)
 {
 	ATH5K_TRACE(ah->ah_sc);
 	ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
+	ath5k_hw_reg_read(ah, AR5K_CR);
 }
 
 /*
@@ -1390,6 +1445,7 @@ int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
 		}
 		/* Start queue */
 		ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
+		ath5k_hw_reg_read(ah, AR5K_CR);
 	} else {
 		/* Return if queue is disabled */
 		if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
@@ -1687,6 +1743,7 @@ enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
 	 * (they will be re-enabled afterwards).
 	 */
 	ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
+	ath5k_hw_reg_read(ah, AR5K_IER);
 
 	old_mask = ah->ah_imr;
 
@@ -3363,11 +3420,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 		ath5k_hw_reg_write(ah, ah->ah_turbo ?
 			AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
 			AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
-		/* Set PHY register 0x9844 (??) */
+		/* Set AR5K_PHY_SETTLING */
 		ath5k_hw_reg_write(ah, ah->ah_turbo ?
-			(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
-			(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
-			AR5K_PHY(17));
+			(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
+			| 0x38 :
+			(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
+			| 0x1C,
+			AR5K_PHY_SETTLING);
 		/* Set Frame Control Register */
 		ath5k_hw_reg_write(ah, ah->ah_turbo ?
 			(AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
@@ -3488,7 +3547,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 			if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
 				AR5K_REG_ENABLE_BITS(ah,
 					AR5K_QUEUE_MISC(queue),
-					AR5K_QCU_MISC_TXE);
+					AR5K_QCU_MISC_RDY_VEOL_POLICY);
 		}
 
 		if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)

+ 2 - 2
drivers/net/wireless/ath5k/initvals.c

@@ -489,7 +489,7 @@ static const struct ath5k_ini ar5212_ini[] = {
 	{ AR5K_QUEUE_TXDP(9),	0x00000000 },
 	{ AR5K_DCU_FP,		0x00000000 },
 	{ AR5K_DCU_TXP,		0x00000000 },
-	{ AR5K_DCU_TX_FILTER,	0x00000000 },
+	{ AR5K_DCU_TX_FILTER_0_BASE,	0x00000000 },
 	/* Unknown table */
 	{ 0x1078, 0x00000000 },
 	{ 0x10b8, 0x00000000 },
@@ -679,7 +679,7 @@ static const struct ath5k_ini ar5212_ini[] = {
 	{ AR5K_PHY(645), 0x00106c10 },
 	{ AR5K_PHY(646), 0x009c4060 },
 	{ AR5K_PHY(647), 0x1483800a },
-	/* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413 */
+	/* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413/2425 */
 	{ AR5K_PHY(648), 0x01831061 },
 	{ AR5K_PHY(649), 0x00000400 },
 	/*{ AR5K_PHY(650), 0x000001b5 },*/

+ 167 - 18
drivers/net/wireless/ath5k/phy.c

@@ -1020,6 +1020,74 @@ static const struct ath5k_ini_rfgain rfgain_2413[] = {
 	{ AR5K_RF_GAIN(63), { 0x000000f9 } },
 };
 
+/* Initial RF Gain settings for RF2425 */
+static const struct ath5k_ini_rfgain rfgain_2425[] = {
+	{ AR5K_RF_GAIN(0), { 0x00000000 } },
+	{ AR5K_RF_GAIN(1), { 0x00000040 } },
+	{ AR5K_RF_GAIN(2), { 0x00000080 } },
+	{ AR5K_RF_GAIN(3), { 0x00000181 } },
+	{ AR5K_RF_GAIN(4), { 0x000001c1 } },
+	{ AR5K_RF_GAIN(5), { 0x00000001 } },
+	{ AR5K_RF_GAIN(6), { 0x00000041 } },
+	{ AR5K_RF_GAIN(7), { 0x00000081 } },
+	{ AR5K_RF_GAIN(8), { 0x00000188 } },
+	{ AR5K_RF_GAIN(9), { 0x000001c8 } },
+	{ AR5K_RF_GAIN(10), { 0x00000008 } },
+	{ AR5K_RF_GAIN(11), { 0x00000048 } },
+	{ AR5K_RF_GAIN(12), { 0x00000088 } },
+	{ AR5K_RF_GAIN(13), { 0x00000189 } },
+	{ AR5K_RF_GAIN(14), { 0x000001c9 } },
+	{ AR5K_RF_GAIN(15), { 0x00000009 } },
+	{ AR5K_RF_GAIN(16), { 0x00000049 } },
+	{ AR5K_RF_GAIN(17), { 0x00000089 } },
+	{ AR5K_RF_GAIN(18), { 0x000001b0 } },
+	{ AR5K_RF_GAIN(19), { 0x000001f0 } },
+	{ AR5K_RF_GAIN(20), { 0x00000030 } },
+	{ AR5K_RF_GAIN(21), { 0x00000070 } },
+	{ AR5K_RF_GAIN(22), { 0x00000171 } },
+	{ AR5K_RF_GAIN(23), { 0x000001b1 } },
+	{ AR5K_RF_GAIN(24), { 0x000001f1 } },
+	{ AR5K_RF_GAIN(25), { 0x00000031 } },
+	{ AR5K_RF_GAIN(26), { 0x00000071 } },
+	{ AR5K_RF_GAIN(27), { 0x000001b8 } },
+	{ AR5K_RF_GAIN(28), { 0x000001f8 } },
+	{ AR5K_RF_GAIN(29), { 0x00000038 } },
+	{ AR5K_RF_GAIN(30), { 0x00000078 } },
+	{ AR5K_RF_GAIN(31), { 0x000000b8 } },
+	{ AR5K_RF_GAIN(32), { 0x000001b9 } },
+	{ AR5K_RF_GAIN(33), { 0x000001f9 } },
+	{ AR5K_RF_GAIN(34), { 0x00000039 } },
+	{ AR5K_RF_GAIN(35), { 0x00000079 } },
+	{ AR5K_RF_GAIN(36), { 0x000000b9 } },
+	{ AR5K_RF_GAIN(37), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(38), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(39), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(40), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(41), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(42), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(43), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(44), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(45), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(46), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(47), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(48), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(49), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(50), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(51), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(52), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(53), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(54), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(55), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(56), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(57), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(58), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(59), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(60), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(61), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(62), { 0x000000f9 } },
+	{ AR5K_RF_GAIN(63), { 0x000000f9 } },
+};
+
 static const struct ath5k_gain_opt rfgain_opt_5112 = {
 	1,
 	8,
@@ -1588,8 +1656,8 @@ int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
 		freq = 0; /* only 2Ghz */
 		break;
 	case AR5K_RF2425:
-		ath5k_rfg = rfgain_2413;
-		size = ARRAY_SIZE(rfgain_2413);
+		ath5k_rfg = rfgain_2425;
+		size = ARRAY_SIZE(rfgain_2425);
 		freq = 0; /* only 2Ghz */
 		break;
 	default:
@@ -1830,9 +1898,6 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
 	data = data0 = data1 = data2 = 0;
 	c = channel->center_freq;
 
-	/*
-	 * Set the channel on the RF5112 or newer
-	 */
 	if (c < 4800) {
 		if (!((c - 2224) % 5)) {
 			data0 = ((2 * (c - 704)) - 3040) / 10;
@@ -1844,7 +1909,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
 			return -EINVAL;
 
 		data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
-	} else {
+	} else if ((c - (c % 5)) != 2 || c > 5435) {
 		if (!(c % 20) && c >= 5120) {
 			data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
 			data2 = ath5k_hw_bitswap(3, 2);
@@ -1856,6 +1921,9 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
 			data2 = ath5k_hw_bitswap(1, 2);
 		} else
 			return -EINVAL;
+	} else {
+		data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+		data2 = ath5k_hw_bitswap(0, 2);
 	}
 
 	data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
@@ -1866,6 +1934,45 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
 	return 0;
 }
 
+/*
+ * Set the channel on the RF2425
+ */
+static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
+		struct ieee80211_channel *channel)
+{
+	u32 data, data0, data2;
+	u16 c;
+
+	data = data0 = data2 = 0;
+	c = channel->center_freq;
+
+	if (c < 4800) {
+		data0 = ath5k_hw_bitswap((c - 2272), 8);
+		data2 = 0;
+	/* ? 5GHz ? */
+	} else if ((c - (c % 5)) != 2 || c > 5435) {
+		if (!(c % 20) && c < 5120)
+			data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
+		else if (!(c % 10))
+			data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
+		else if (!(c % 5))
+			data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
+		else
+			return -EINVAL;
+		data2 = ath5k_hw_bitswap(1, 2);
+	} else {
+		data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+		data2 = ath5k_hw_bitswap(0, 2);
+	}
+
+	data = (data0 << 4) | data2 << 2 | 0x1001;
+
+	ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
+	ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
+
+	return 0;
+}
+
 /*
  * Set a channel on the radio chip
  */
@@ -1895,6 +2002,9 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
 	case AR5K_RF5111:
 		ret = ath5k_hw_rf5111_channel(ah, channel);
 		break;
+	case AR5K_RF2425:
+		ret = ath5k_hw_rf2425_channel(ah, channel);
+		break;
 	default:
 		ret = ath5k_hw_rf5112_channel(ah, channel);
 		break;
@@ -1903,6 +2013,15 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
 	if (ret)
 		return ret;
 
+	/* Set JAPAN setting for channel 14 */
+	if (channel->center_freq == 2484) {
+		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
+				AR5K_PHY_CCKTXCTL_JAPAN);
+	} else {
+		AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
+				AR5K_PHY_CCKTXCTL_WORLD);
+	}
+
 	ah->ah_current_channel.center_freq = channel->center_freq;
 	ah->ah_current_channel.hw_value = channel->hw_value;
 	ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
@@ -1933,6 +2052,8 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
  * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
  * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
  *
+ * XXX: Since during noise floor calibration antennas are detached according to
+ * the patent, we should stop tx queues here.
  */
 int
 ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
@@ -1942,7 +2063,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
 	s32 noise_floor;
 
 	/*
-	 * Enable noise floor calibration and wait until completion
+	 * Enable noise floor calibration
 	 */
 	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
 				AR5K_PHY_AGCCTL_NF);
@@ -1952,7 +2073,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
 	if (ret) {
 		ATH5K_ERR(ah->ah_sc,
 			"noise floor calibration timeout (%uMHz)\n", freq);
-		return ret;
+		return -EAGAIN;
 	}
 
 	/* Wait until the noise floor is calibrated and read the value */
@@ -1974,7 +2095,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
 	if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
 		ATH5K_ERR(ah->ah_sc,
 			"noise floor calibration failed (%uMHz)\n", freq);
-		return -EIO;
+		return -EAGAIN;
 	}
 
 	ah->ah_noise_floor = noise_floor;
@@ -2087,38 +2208,66 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
 }
 
 /*
- * Perform a PHY calibration on RF5111/5112
+ * Perform a PHY calibration on RF5111/5112 and newer chips
  */
 static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
 		struct ieee80211_channel *channel)
 {
 	u32 i_pwr, q_pwr;
 	s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
+	int i;
 	ATH5K_TRACE(ah->ah_sc);
 
 	if (!ah->ah_calibration ||
-			ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
+		ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
 		goto done;
 
-	ah->ah_calibration = false;
+	/* Calibration has finished, get the results and re-run */
+	for (i = 0; i <= 10; i++) {
+		iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
+		i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
+		q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
+	}
 
-	iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
-	i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
-	q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
 	i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
-	q_coffd = q_pwr >> 6;
+	q_coffd = q_pwr >> 7;
 
+	/* No correction */
 	if (i_coffd == 0 || q_coffd == 0)
 		goto done;
 
 	i_coff = ((-iq_corr) / i_coffd) & 0x3f;
-	q_coff = (((s32)i_pwr / q_coffd) - 64) & 0x1f;
 
-	/* Commit new IQ value */
+	/* Boundary check */
+	if (i_coff > 31)
+		i_coff = 31;
+	if (i_coff < -32)
+		i_coff = -32;
+
+	q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
+
+	/* Boundary check */
+	if (q_coff > 15)
+		q_coff = 15;
+	if (q_coff < -16)
+		q_coff = -16;
+
+	/* Commit new I/Q value */
 	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
 		((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
 
+	/* Re-enable calibration -if we don't we'll commit
+	 * the same values again and again */
+	AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+			AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+	AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
+
 done:
+
+	/* TODO: Separate noise floor calibration from I/Q calibration
+	 * since noise floor calibration interrupts rx path while I/Q
+	 * calibration doesn't. We don't need to run noise floor calibration
+	 * as often as I/Q calibration.*/
 	ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
 
 	/* Request RF gain */

Файловите разлики са ограничени, защото са твърде много
+ 410 - 191
drivers/net/wireless/ath5k/reg.h


+ 3 - 2
drivers/net/wireless/ipw2200.c

@@ -305,9 +305,10 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
 #define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
 
 /* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write8(ipw, ofs, val) \
+#define ipw_write8(ipw, ofs, val) do { \
  IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write8(ipw, ofs, val)
+ _ipw_write8(ipw, ofs, val); \
+ } while (0)
 
 /* 16-bit direct write (low 4K) */
 #define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))

+ 51 - 47
drivers/net/wireless/iwlwifi/Kconfig

@@ -14,18 +14,49 @@ config IWLWIFI_LEDS
 	default n
 
 config IWLWIFI_RFKILL
-	boolean "IWLWIFI RF kill support"
+	boolean "Iwlwifi RF kill support"
 	depends on IWLCORE
 
-config IWL4965
-	tristate "Intel Wireless WiFi 4965AGN"
+config IWLWIFI_DEBUG
+	bool "Enable full debugging output in iwlagn driver"
+	depends on IWLCORE
+	---help---
+	  This option will enable debug tracing output for the iwlwifi drivers
+
+	  This will result in the kernel module being ~100k larger.  You can
+	  control which debug output is sent to the kernel log by setting the
+	  value in
+
+		/sys/class/net/wlan0/device/debug_level
+
+	  This entry will only exist if this option is enabled.
+
+	  To set a value, simply echo an 8-byte hex value to the same file:
+
+		  % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
+
+	  You can find the list of debug mask values in:
+		  drivers/net/wireless/iwlwifi/iwl-debug.h
+
+	  If this is your first time using this driver, you should say Y here
+	  as the debug information can assist others in helping you resolve
+	  any problems you may encounter.
+
+config IWLWIFI_DEBUGFS
+        bool "Iwlwifi debugfs support"
+        depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
+        ---help---
+	  Enable creation of debugfs files for the iwlwifi drivers.
+
+config IWLAGN
+	tristate "Intel Wireless WiFi Next Gen AGN"
 	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
 	select FW_LOADER
 	select IWLCORE
 	---help---
 	  Select to build the driver supporting the:
 
-	  Intel Wireless WiFi Link 4965AGN
+	  Intel Wireless WiFi Link Next-Gen AGN
 
 	  This driver uses the kernel's mac80211 subsystem.
 
@@ -42,60 +73,33 @@ config IWL4965
 	  If you want to compile the driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
 	  say M here and read <file:Documentation/kbuild/modules.txt>.  The
-	  module will be called iwl4965.ko.
-
-config IWL4965_LEDS
-	bool "Enable LEDS features in iwl4965 driver"
-	depends on IWL4965
-	select IWLWIFI_LEDS
-	---help---
-	  This option enables LEDS for the iwlwifi drivers
+	  module will be called iwlagn.ko.
 
-
-config IWL4965_SPECTRUM_MEASUREMENT
-	bool "Enable Spectrum Measurement in iwl4965 driver"
-	depends on IWL4965
+config IWLAGN_SPECTRUM_MEASUREMENT
+	bool "Enable Spectrum Measurement in iwlagn driver"
+	depends on IWLAGN
 	---help---
-	  This option will enable spectrum measurement for the iwl4965 driver.
+	  This option will enable spectrum measurement for the iwlagn driver.
 
-config IWLWIFI_DEBUG
-	bool "Enable full debugging output in iwl4965 driver"
-	depends on IWL4965
+config IWLAGN_LEDS
+	bool "Enable LEDS features in iwlagn driver"
+	depends on IWLAGN
+	select IWLWIFI_LEDS
 	---help---
-	  This option will enable debug tracing output for the iwl4965
-	  driver.
-
-	  This will result in the kernel module being ~100k larger.  You can
-	  control which debug output is sent to the kernel log by setting the
-	  value in
-
-		/sys/class/net/wlan0/device/debug_level
-
-	  This entry will only exist if this option is enabled.
-
-	  To set a value, simply echo an 8-byte hex value to the same file:
-
-		  % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
+	  This option enables LEDS for the iwlagn drivers
 
-	  You can find the list of debug mask values in:
-		  drivers/net/wireless/iwlwifi/iwl-4965-debug.h
 
-	  If this is your first time using this driver, you should say Y here
-	  as the debug information can assist others in helping you resolve
-	  any problems you may encounter.
+config IWL4965
+	bool "Intel Wireless WiFi 4965AGN"
+	depends on IWLAGN
+	---help---
+	  This option enables support for Intel Wireless WiFi Link 4965AGN
 
 config IWL5000
 	bool "Intel Wireless WiFi 5000AGN"
-	depends on IWL4965
+	depends on IWLAGN
 	---help---
 	  This option enables support for Intel Wireless WiFi Link 5000AGN Family
-	  Dependency on 4965 is temporary
-
-config IWLWIFI_DEBUGFS
-        bool "Iwlwifi debugfs support"
-        depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
-        ---help---
-	  Enable creation of debugfs files for the iwlwifi drivers.
 
 config IWL3945
 	tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"

+ 6 - 7
drivers/net/wireless/iwlwifi/Makefile

@@ -6,15 +6,14 @@ iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
 iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
 iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
 
+obj-$(CONFIG_IWLAGN)	+= iwlagn.o
+iwlagn-objs		:= iwl-agn.o iwl-agn-rs.o
+
+iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
+iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
+
 obj-$(CONFIG_IWL3945)	+= iwl3945.o
 iwl3945-objs		:= iwl3945-base.o iwl-3945.o iwl-3945-rs.o
 iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
 
-obj-$(CONFIG_IWL4965)	+= iwl4965.o
-iwl4965-objs		:= iwl4965-base.o iwl-4965.o iwl-4965-rs.o
-
-ifeq ($(CONFIG_IWL5000),y)
-	iwl4965-objs += iwl-5000.o
-endif
-
 

+ 17 - 16
drivers/net/wireless/iwlwifi/iwl-3945-led.c

@@ -206,12 +206,12 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
 static int iwl3945_led_register_led(struct iwl3945_priv *priv,
 				   struct iwl3945_led *led,
 				   enum led_type type, u8 set_led,
-				   const char *name, char *trigger)
+				   char *trigger)
 {
 	struct device *device = wiphy_dev(priv->hw->wiphy);
 	int ret;
 
-	led->led_dev.name = name;
+	led->led_dev.name = led->name;
 	led->led_dev.brightness_set = iwl3945_led_brightness_set;
 	led->led_dev.default_trigger = trigger;
 
@@ -308,7 +308,6 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
 int iwl3945_led_register(struct iwl3945_priv *priv)
 {
 	char *trigger;
-	char name[32];
 	int ret;
 
 	priv->last_blink_rate = 0;
@@ -318,7 +317,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
 	priv->allow_blinking = 0;
 
 	trigger = ieee80211_get_radio_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:radio",
+	snprintf(priv->led[IWL_LED_TRG_RADIO].name,
+		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
 		 wiphy_name(priv->hw->wiphy));
 
 	priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
@@ -327,19 +327,20 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
 
 	ret = iwl3945_led_register_led(priv,
 				   &priv->led[IWL_LED_TRG_RADIO],
-				   IWL_LED_TRG_RADIO, 1,
-				   name, trigger);
+				   IWL_LED_TRG_RADIO, 1, trigger);
+
 	if (ret)
 		goto exit_fail;
 
 	trigger = ieee80211_get_assoc_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:assoc",
+	snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
+		 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
 		 wiphy_name(priv->hw->wiphy));
 
 	ret = iwl3945_led_register_led(priv,
 				   &priv->led[IWL_LED_TRG_ASSOC],
-				   IWL_LED_TRG_ASSOC, 0,
-				   name, trigger);
+				   IWL_LED_TRG_ASSOC, 0, trigger);
+
 	/* for assoc always turn led on */
 	priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
 	priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
@@ -349,14 +350,13 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
 		goto exit_fail;
 
 	trigger = ieee80211_get_rx_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:RX",
+	snprintf(priv->led[IWL_LED_TRG_RX].name,
+		 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
 		 wiphy_name(priv->hw->wiphy));
 
-
 	ret = iwl3945_led_register_led(priv,
 				   &priv->led[IWL_LED_TRG_RX],
-				   IWL_LED_TRG_RX, 0,
-				   name, trigger);
+				   IWL_LED_TRG_RX, 0, trigger);
 
 	priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
 	priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
@@ -366,13 +366,14 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
 		goto exit_fail;
 
 	trigger = ieee80211_get_tx_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:TX",
+	snprintf(priv->led[IWL_LED_TRG_TX].name,
+		 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
 		 wiphy_name(priv->hw->wiphy));
 
 	ret = iwl3945_led_register_led(priv,
 				   &priv->led[IWL_LED_TRG_TX],
-				   IWL_LED_TRG_TX, 0,
-				   name, trigger);
+				   IWL_LED_TRG_TX, 0, trigger);
+
 	priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
 	priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
 	priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;

+ 1 - 0
drivers/net/wireless/iwlwifi/iwl-3945-led.h

@@ -50,6 +50,7 @@ enum led_type {
 struct iwl3945_led {
 	struct iwl3945_priv *priv;
 	struct led_classdev led_dev;
+	char name[32];
 
 	int (*led_on) (struct iwl3945_priv *priv, int led_id);
 	int (*led_off) (struct iwl3945_priv *priv, int led_id);

+ 9 - 8
drivers/net/wireless/iwlwifi/iwl-3945.c

@@ -710,10 +710,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
 		return;
 	}
 
-	if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-		iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
-		return;
-	}
+
 
 	/* Convert 3945's rssi indicator to dBm */
 	rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
@@ -775,6 +772,11 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
 		priv->last_rx_noise = rx_status.noise;
 	}
 
+	if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
+		iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
+		return;
+	}
+
 	switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
 	case IEEE80211_FTYPE_MGMT:
 		switch (le16_to_cpu(header->frame_control) &
@@ -793,8 +795,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
 					struct ieee80211_mgmt *mgmt =
 					    (struct ieee80211_mgmt *)header;
 					__le32 *pos;
-					pos =
-					    (__le32 *) & mgmt->u.beacon.
+					pos = (__le32 *)&mgmt->u.beacon.
 					    timestamp;
 					priv->timestamp0 = le32_to_cpu(pos[0]);
 					priv->timestamp1 = le32_to_cpu(pos[1]);
@@ -1507,7 +1508,7 @@ static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
  */
 static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
 {
-	return (((temperature < -260) || (temperature > 25)) ? 1 : 0);
+	return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
 }
 
 int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
@@ -2628,7 +2629,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
 	tx_beacon_cmd->tx.supp_rates[1] =
 		(IWL_CCK_BASIC_RATES_MASK & 0xF);
 
-	return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size);
+	return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
 }
 
 void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)

+ 40 - 116
drivers/net/wireless/iwlwifi/iwl-4965.c

@@ -341,39 +341,6 @@ err:
 	return -EINVAL;
 
 }
-int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
-{
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->lock, flags);
-	ret = iwl_grab_nic_access(priv);
-	if (ret) {
-		spin_unlock_irqrestore(&priv->lock, flags);
-		return ret;
-	}
-
-	if (src == IWL_PWR_SRC_VAUX) {
-		u32 val;
-		ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
-					    &val);
-
-		if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
-			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-					       APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
-					       ~APMG_PS_CTRL_MSK_PWR_SRC);
-		}
-	} else {
-		iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
-				       APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
-				       ~APMG_PS_CTRL_MSK_PWR_SRC);
-	}
-
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	return ret;
-}
 
 /*
  * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
@@ -875,18 +842,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
 	return 0;
 }
 
-/* set card power command */
-static int iwl4965_set_power(struct iwl_priv *priv,
-		      void *cmd)
-{
-	int ret = 0;
-
-	ret = iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
-				    sizeof(struct iwl4965_powertable_cmd),
-				    cmd, NULL);
-	return ret;
-}
-
 static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
 {
 	s32 sign = 1;
@@ -1560,11 +1515,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
 					  c, atten_value, power_index,
 					tx_power.s.radio_tx_gain[c],
 					tx_power.s.dsp_predis_atten[c]);
-		}/* for each chain */
+		} /* for each chain */
 
 		tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
 
-	}/* for each rate */
+	} /* for each rate */
 
 	return 0;
 }
@@ -1701,38 +1656,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
 	return le32_to_cpu(s->rb_closed) & 0xFFF;
 }
 
-unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
-			  struct iwl_frame *frame, u8 rate)
-{
-	struct iwl4965_tx_beacon_cmd *tx_beacon_cmd;
-	unsigned int frame_size;
-
-	tx_beacon_cmd = &frame->u.beacon;
-	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
-
-	tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
-	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-
-	frame_size = iwl4965_fill_beacon_frame(priv,
-				tx_beacon_cmd->frame,
-				iwl_bcast_addr,
-				sizeof(frame->u) - sizeof(*tx_beacon_cmd));
-
-	BUG_ON(frame_size > MAX_MPDU_SIZE);
-	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
-
-	if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
-		tx_beacon_cmd->tx.rate_n_flags =
-			iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
-	else
-		tx_beacon_cmd->tx.rate_n_flags =
-			iwl_hw_set_rate_n_flags(rate, 0);
-
-	tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
-				TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
-	return (sizeof(*tx_beacon_cmd) + frame_size);
-}
-
 static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
 {
 	priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
@@ -2079,39 +2002,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
 	return 0;
 }
 
-int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
-			     enum ieee80211_ampdu_mlme_action action,
-			     const u8 *addr, u16 tid, u16 *ssn)
-{
-	struct iwl_priv *priv = hw->priv;
-	DECLARE_MAC_BUF(mac);
-
-	IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
-		     print_mac(mac, addr), tid);
-
-	if (!(priv->cfg->sku & IWL_SKU_N))
-		return -EACCES;
-
-	switch (action) {
-	case IEEE80211_AMPDU_RX_START:
-		IWL_DEBUG_HT("start Rx\n");
-		return iwl_rx_agg_start(priv, addr, tid, *ssn);
-	case IEEE80211_AMPDU_RX_STOP:
-		IWL_DEBUG_HT("stop Rx\n");
-		return iwl_rx_agg_stop(priv, addr, tid);
-	case IEEE80211_AMPDU_TX_START:
-		IWL_DEBUG_HT("start Tx\n");
-		return iwl_tx_agg_start(priv, addr, tid, ssn);
-	case IEEE80211_AMPDU_TX_STOP:
-		IWL_DEBUG_HT("stop Tx\n");
-		return iwl_tx_agg_stop(priv, addr, tid);
-	default:
-		IWL_DEBUG_HT("unknown\n");
-		return -EINVAL;
-		break;
-	}
-	return 0;
-}
 
 static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
 {
@@ -2240,9 +2130,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
 				bitmap = bitmap << sh;
 				sh = 0;
 			}
-			bitmap |= (1 << sh);
-			IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
-					   start, (u32)(bitmap & 0xFFFFFFFF));
+			bitmap |= 1ULL << sh;
+			IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+					   start, (unsigned long long)bitmap);
 		}
 
 		agg->bitmap = bitmap;
@@ -2368,6 +2258,40 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
 		IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
+static int iwl4965_calc_rssi(struct iwl_priv *priv,
+			     struct iwl_rx_phy_res *rx_resp)
+{
+	/* data from PHY/DSP regarding signal strength, etc.,
+	 *   contents are always there, not configurable by host.  */
+	struct iwl4965_rx_non_cfg_phy *ncphy =
+	    (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
+	u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK)
+			>> IWL49_AGC_DB_POS;
+
+	u32 valid_antennae =
+	    (le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK)
+			>> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET;
+	u8 max_rssi = 0;
+	u32 i;
+
+	/* Find max rssi among 3 possible receivers.
+	 * These values are measured by the digital signal processor (DSP).
+	 * They should stay fairly constant even as the signal strength varies,
+	 *   if the radio's automatic gain control (AGC) is working right.
+	 * AGC value (see below) will provide the "interesting" info. */
+	for (i = 0; i < 3; i++)
+		if (valid_antennae & (1 << i))
+			max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
+
+	IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+		ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
+		max_rssi, agc);
+
+	/* dBm = max_rssi dB - agc dB - constant.
+	 * Higher AGC (higher radio gain) means lower signal. */
+	return max_rssi - agc - IWL_RSSI_OFFSET;
+}
+
 
 /* Set up 4965-specific Rx frame reply handlers */
 static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
@@ -2399,6 +2323,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
 	.chain_noise_reset = iwl4965_chain_noise_reset,
 	.gain_computation = iwl4965_gain_computation,
 	.rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
+	.calc_rssi = iwl4965_calc_rssi,
 };
 
 static struct iwl_lib_ops iwl4965_lib = {
@@ -2440,7 +2365,6 @@ static struct iwl_lib_ops iwl4965_lib = {
 		.check_version = iwl4965_eeprom_check_version,
 		.query_addr = iwlcore_eeprom_query_addr,
 	},
-	.set_power = iwl4965_set_power,
 	.send_tx_power	= iwl4965_send_tx_power,
 	.update_chain_flags = iwl4965_update_chain_flags,
 	.temperature = iwl4965_temperature_calib,

+ 64 - 7
drivers/net/wireless/iwlwifi/iwl-5000.c

@@ -93,6 +93,13 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
 	iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 		    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 
+	/* Set FH wait treshold to maximum (HW error during stress W/A) */
+	iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
+
+	/* enable HAP INTA to move device L1a -> L0s */
+	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+		    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
+
 	iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
 
 	/* set "initialization complete" bit to move adapter
@@ -230,6 +237,16 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
 		    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
 		    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 
+	/* W/A : NIC is stuck in a reset state after Early PCIe power off
+	 * (PCIe power is lost before PERST# is asserted),
+	 * causing ME FW to lose ownership and not being able to obtain it back.
+	 */
+	iwl_grab_nic_access(priv);
+	iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+				APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
+				~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
+	iwl_release_nic_access(priv);
+
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
@@ -924,8 +941,8 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
 	len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
 
 	if (txq_id != IWL_CMD_QUEUE_NUM) {
-		sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id;
-		sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl;
+		sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
+		sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
 
 		switch (sec_ctl & TX_CMD_SEC_MSK) {
 		case TX_CMD_SEC_CCM:
@@ -964,7 +981,7 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
 	u8 sta = 0;
 
 	if (txq_id != IWL_CMD_QUEUE_NUM)
-		sta = txq->cmd[txq->q.read_ptr].cmd.tx.sta_id;
+		sta = txq->cmd[txq->q.read_ptr]->cmd.tx.sta_id;
 
 	shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr].
 					val = cpu_to_le16(1 | (sta << 12));
@@ -1131,7 +1148,7 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
 
 static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
 {
-	return le32_to_cpup((__le32*)&tx_resp->status +
+	return le32_to_cpup((__le32 *)&tx_resp->status +
 			    tx_resp->frame_count) & MAX_SN;
 }
 
@@ -1228,9 +1245,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
 				bitmap = bitmap << sh;
 				sh = 0;
 			}
-			bitmap |= (1 << sh);
-			IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
-					   start, (u32)(bitmap & 0xFFFFFFFF));
+			bitmap |= 1ULL << sh;
+			IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+					   start, (unsigned long long)bitmap);
 		}
 
 		agg->bitmap = bitmap;
@@ -1444,6 +1461,44 @@ static void iwl5000_temperature(struct iwl_priv *priv)
 	priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
 }
 
+/* Calc max signal level (dBm) among 3 possible receivers */
+static int iwl5000_calc_rssi(struct iwl_priv *priv,
+			     struct iwl_rx_phy_res *rx_resp)
+{
+	/* data from PHY/DSP regarding signal strength, etc.,
+	 *   contents are always there, not configurable by host
+	 */
+	struct iwl5000_non_cfg_phy *ncphy =
+		(struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
+	u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
+	u8 agc;
+
+	val  = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
+	agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
+
+	/* Find max rssi among 3 possible receivers.
+	 * These values are measured by the digital signal processor (DSP).
+	 * They should stay fairly constant even as the signal strength varies,
+	 *   if the radio's automatic gain control (AGC) is working right.
+	 * AGC value (see below) will provide the "interesting" info.
+	 */
+	val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
+	rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
+	rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
+	val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
+	rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
+
+	max_rssi = max_t(u32, rssi_a, rssi_b);
+	max_rssi = max_t(u32, max_rssi, rssi_c);
+
+	IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+		rssi_a, rssi_b, rssi_c, max_rssi, agc);
+
+	/* dBm = max_rssi dB - agc dB - constant.
+	 * Higher AGC (higher radio gain) means lower signal. */
+	return max_rssi - agc - IWL_RSSI_OFFSET;
+}
+
 static struct iwl_hcmd_ops iwl5000_hcmd = {
 	.rxon_assoc = iwl5000_send_rxon_assoc,
 };
@@ -1454,6 +1509,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
 	.gain_computation = iwl5000_gain_computation,
 	.chain_noise_reset = iwl5000_chain_noise_reset,
 	.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
+	.calc_rssi = iwl5000_calc_rssi,
 };
 
 static struct iwl_lib_ops iwl5000_lib = {
@@ -1474,6 +1530,7 @@ static struct iwl_lib_ops iwl5000_lib = {
 	.alive_notify = iwl5000_alive_notify,
 	.send_tx_power = iwl5000_send_tx_power,
 	.temperature = iwl5000_temperature,
+	.update_chain_flags = iwl4965_update_chain_flags,
 	.apm_ops = {
 		.init =	iwl5000_apm_init,
 		.reset = iwl5000_apm_reset,

+ 114 - 213
drivers/net/wireless/iwlwifi/iwl-4965-rs.c → drivers/net/wireless/iwlwifi/iwl-agn-rs.c

@@ -42,7 +42,7 @@
 #include "iwl-core.h"
 #include "iwl-helpers.h"
 
-#define RS_NAME "iwl-4965-rs"
+#define RS_NAME "iwl-agn-rs"
 
 #define NUM_TRY_BEFORE_ANT_TOGGLE 1
 #define IWL_NUMBER_TRY      1
@@ -77,9 +77,9 @@ static const u8 ant_toggle_lookup[] = {
 };
 
 /**
- * struct iwl4965_rate_scale_data -- tx success history for one rate
+ * struct iwl_rate_scale_data -- tx success history for one rate
  */
-struct iwl4965_rate_scale_data {
+struct iwl_rate_scale_data {
 	u64 data;		/* bitmap of successful frames */
 	s32 success_counter;	/* number of frames successful */
 	s32 success_ratio;	/* per-cent * 128  */
@@ -89,12 +89,12 @@ struct iwl4965_rate_scale_data {
 };
 
 /**
- * struct iwl4965_scale_tbl_info -- tx params and success history for all rates
+ * struct iwl_scale_tbl_info -- tx params and success history for all rates
  *
- * There are two of these in struct iwl4965_lq_sta,
+ * There are two of these in struct iwl_lq_sta,
  * one for "active", and one for "search".
  */
-struct iwl4965_scale_tbl_info {
+struct iwl_scale_tbl_info {
 	enum iwl_table_type lq_type;
 	u8 ant_type;
 	u8 is_SGI;	/* 1 = short guard interval */
@@ -103,10 +103,10 @@ struct iwl4965_scale_tbl_info {
 	u8 action;	/* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
 	s32 *expected_tpt;	/* throughput metrics; expected_tpt_G, etc. */
 	u32 current_rate;  /* rate_n_flags, uCode API format */
-	struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
+	struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
 };
 
-struct iwl4965_traffic_load {
+struct iwl_traffic_load {
 	unsigned long time_stamp;	/* age of the oldest statistics */
 	u32 packet_count[TID_QUEUE_MAX_SIZE];   /* packet count in this time
 						 * slice */
@@ -118,11 +118,11 @@ struct iwl4965_traffic_load {
 };
 
 /**
- * struct iwl4965_lq_sta -- driver's rate scaling private structure
+ * struct iwl_lq_sta -- driver's rate scaling private structure
  *
  * Pointer to this gets passed back and forth between driver and mac80211.
  */
-struct iwl4965_lq_sta {
+struct iwl_lq_sta {
 	u8 active_tbl;		/* index of active table, range 0-1 */
 	u8 enable_counter;	/* indicates HT mode */
 	u8 stay_in_tbl;		/* 1: disallow, 0: allow search for new mode */
@@ -153,8 +153,8 @@ struct iwl4965_lq_sta {
 	u16 active_rate_basic;
 
 	struct iwl_link_quality_cmd lq;
-	struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
-	struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT];
+	struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
+	struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
 	u8 tx_agg_tid_en;
 #ifdef CONFIG_MAC80211_DEBUGFS
 	struct dentry *rs_sta_dbgfs_scale_table_file;
@@ -170,16 +170,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 				   struct ieee80211_hdr *hdr,
 				   struct sta_info *sta);
 static void rs_fill_link_cmd(const struct iwl_priv *priv,
-			     struct iwl4965_lq_sta *lq_sta,
-			     u32 rate_n_flags);
+			     struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
 
 
 #ifdef CONFIG_MAC80211_DEBUGFS
-static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
-					u32 *rate_n_flags, int index);
+static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
+			     u32 *rate_n_flags, int index);
 #else
-static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
-					u32 *rate_n_flags, int index)
+static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
+			     u32 *rate_n_flags, int index)
 {}
 #endif
 
@@ -234,7 +233,7 @@ static inline u8 rs_extract_rate(u32 rate_n_flags)
 	return (u8)(rate_n_flags & 0xFF);
 }
 
-static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
+static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
 {
 	window->data = 0;
 	window->success_counter = 0;
@@ -246,14 +245,14 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
 
 static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
 {
-	return ((ant_type & valid_antenna) == ant_type);
+	return (ant_type & valid_antenna) == ant_type;
 }
 
 /*
  *	removes the old data from the statistics. All data that is older than
  *	TID_MAX_TIME_DIFF, will be deleted.
  */
-static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
+static void rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time)
 {
 	/* The oldest age we want to keep */
 	u32 oldest_time = curr_time - TID_MAX_TIME_DIFF;
@@ -274,13 +273,13 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
  *	increment traffic load value for tid and also remove
  *	any old values if passed the certain time period
  */
-static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
+static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
 			   struct ieee80211_hdr *hdr)
 {
 	u32 curr_time = jiffies_to_msecs(jiffies);
 	u32 time_diff;
 	s32 index;
-	struct iwl4965_traffic_load *tl = NULL;
+	struct iwl_traffic_load *tl = NULL;
 	__le16 fc = hdr->frame_control;
 	u8 tid;
 
@@ -325,12 +324,12 @@ static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
 /*
 	get the traffic load value for tid
 */
-static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid)
+static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
 {
 	u32 curr_time = jiffies_to_msecs(jiffies);
 	u32 time_diff;
 	s32 index;
-	struct iwl4965_traffic_load *tl = NULL;
+	struct iwl_traffic_load *tl = NULL;
 
 	if (tid >= TID_MAX_LOAD_COUNT)
 		return 0;
@@ -354,8 +353,8 @@ static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid)
 }
 
 static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
-				struct iwl4965_lq_sta *lq_data, u8 tid,
-				struct sta_info *sta)
+				      struct iwl_lq_sta *lq_data, u8 tid,
+				      struct sta_info *sta)
 {
 	unsigned long state;
 	DECLARE_MAC_BUF(mac);
@@ -373,8 +372,8 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
 }
 
 static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
-				struct iwl4965_lq_sta *lq_data,
-				struct sta_info *sta)
+			      struct iwl_lq_sta *lq_data,
+			      struct sta_info *sta)
 {
 	if ((tid < TID_MAX_LOAD_COUNT))
 		rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
@@ -385,9 +384,9 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
 
 static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
 {
-	return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
-		!!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
-		!!(rate_n_flags & RATE_MCS_ANT_C_MSK));
+	return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
+	       !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
+	       !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
 }
 
 /**
@@ -397,11 +396,11 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
  * at this rate.  window->data contains the bitmask of successful
  * packets.
  */
-static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
+static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
 			      int scale_index, s32 tpt, int retries,
 			      int successes)
 {
-	struct iwl4965_rate_scale_data *window = NULL;
+	struct iwl_rate_scale_data *window = NULL;
 	static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
 	s32 fail_count;
 
@@ -473,7 +472,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
  * Fill uCode API rate_n_flags field, based on "search" or "active" table.
  */
 /* FIXME:RS:remove this function and put the flags statically in the table */
-static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl,
+static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
 				       int index, u8 use_green)
 {
 	u32 rate_n_flags = 0;
@@ -530,7 +529,7 @@ static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl,
  */
 static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
 				    enum ieee80211_band band,
-				    struct iwl4965_scale_tbl_info *tbl,
+				    struct iwl_scale_tbl_info *tbl,
 				    int *rate_idx)
 {
 	u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
@@ -591,7 +590,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
 /* switch to another antenna/antennas and return 1 */
 /* if no other valid antenna found, return 0 */
 static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
-			      struct iwl4965_scale_tbl_info *tbl)
+			     struct iwl_scale_tbl_info *tbl)
 {
 	u8 new_ant_type;
 
@@ -621,9 +620,9 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
 #if 0
 static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
 {
-	return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
+	return (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
 		priv->current_ht_config.is_green_field &&
-		!priv->current_ht_config.non_GF_STA_present);
+		!priv->current_ht_config.non_GF_STA_present;
 }
 #endif
 static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
@@ -638,9 +637,9 @@ static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf
  * basic available rates.
  *
  */
-static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
-				   struct ieee80211_hdr *hdr,
-				   enum iwl_table_type rate_type)
+static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
+				  struct ieee80211_hdr *hdr,
+				  enum iwl_table_type rate_type)
 {
 	if (hdr && is_multicast_ether_addr(hdr->addr1) &&
 	    lq_sta->active_rate_basic)
@@ -714,9 +713,9 @@ static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
 	return (high << 8) | low;
 }
 
-static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
-			     struct iwl4965_scale_tbl_info *tbl, u8 scale_index,
-			     u8 ht_possible)
+static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
+			     struct iwl_scale_tbl_info *tbl,
+			     u8 scale_index, u8 ht_possible)
 {
 	s32 low;
 	u16 rate_mask;
@@ -780,7 +779,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
 	int status;
 	u8 retries;
 	int rs_index, index = 0;
-	struct iwl4965_lq_sta *lq_sta;
+	struct iwl_lq_sta *lq_sta;
 	struct iwl_link_quality_cmd *table;
 	struct sta_info *sta;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -788,11 +787,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hw *hw = local_to_hw(local);
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct iwl4965_rate_scale_data *window = NULL;
-	struct iwl4965_rate_scale_data *search_win = NULL;
+	struct iwl_rate_scale_data *window = NULL;
+	struct iwl_rate_scale_data *search_win = NULL;
 	u32 tx_rate;
-	struct iwl4965_scale_tbl_info tbl_type;
-	struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
+	struct iwl_scale_tbl_info tbl_type;
+	struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
 	u8 active_index = 0;
 	__le16 fc = hdr->frame_control;
 	s32 tpt = 0;
@@ -820,7 +819,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
 		goto out;
 
 
-	lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
+	lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
 
 	if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
 	    !lq_sta->ibss_sta_added)
@@ -831,10 +830,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
 
 	curr_tbl = &(lq_sta->lq_info[active_index]);
 	search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
-	window = (struct iwl4965_rate_scale_data *)
-	    &(curr_tbl->win[0]);
-	search_win = (struct iwl4965_rate_scale_data *)
-	    &(search_tbl->win[0]);
+	window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
+	search_win = (struct iwl_rate_scale_data *)&(search_tbl->win[0]);
 
 	/*
 	 * Ignore this Tx frame response if its initial rate doesn't match
@@ -983,7 +980,7 @@ out:
  * searching for a new mode.
  */
 static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
-				 struct iwl4965_lq_sta *lq_sta)
+				 struct iwl_lq_sta *lq_sta)
 {
 	IWL_DEBUG_RATE("we are staying in the same table\n");
 	lq_sta->stay_in_tbl = 1;	/* only place this gets set */
@@ -1004,8 +1001,8 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
 /*
  * Find correct throughput table for given mode of modulation
  */
-static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
-				      struct iwl4965_scale_tbl_info *tbl)
+static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
+				      struct iwl_scale_tbl_info *tbl)
 {
 	if (is_legacy(tbl->lq_type)) {
 		if (!is_a_band(tbl->lq_type))
@@ -1050,12 +1047,12 @@ static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
  * bit rate will typically need to increase, but not if performance was bad.
  */
 static s32 rs_get_best_rate(struct iwl_priv *priv,
-			    struct iwl4965_lq_sta *lq_sta,
-			    struct iwl4965_scale_tbl_info *tbl,	/* "search" */
+			    struct iwl_lq_sta *lq_sta,
+			    struct iwl_scale_tbl_info *tbl,	/* "search" */
 			    u16 rate_mask, s8 index)
 {
 	/* "active" values */
-	struct iwl4965_scale_tbl_info *active_tbl =
+	struct iwl_scale_tbl_info *active_tbl =
 	    &(lq_sta->lq_info[lq_sta->active_tbl]);
 	s32 active_sr = active_tbl->win[index].success_ratio;
 	s32 active_tpt = active_tbl->expected_tpt[index];
@@ -1143,10 +1140,10 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
  * Set up search table for MIMO
  */
 static int rs_switch_to_mimo2(struct iwl_priv *priv,
-			     struct iwl4965_lq_sta *lq_sta,
+			     struct iwl_lq_sta *lq_sta,
 			     struct ieee80211_conf *conf,
 			     struct sta_info *sta,
-			     struct iwl4965_scale_tbl_info *tbl, int index)
+			     struct iwl_scale_tbl_info *tbl, int index)
 {
 	u16 rate_mask;
 	s32 rate;
@@ -1210,10 +1207,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
  * Set up search table for SISO
  */
 static int rs_switch_to_siso(struct iwl_priv *priv,
-			     struct iwl4965_lq_sta *lq_sta,
+			     struct iwl_lq_sta *lq_sta,
 			     struct ieee80211_conf *conf,
 			     struct sta_info *sta,
-			     struct iwl4965_scale_tbl_info *tbl, int index)
+			     struct iwl_scale_tbl_info *tbl, int index)
 {
 	u16 rate_mask;
 	u8 is_green = lq_sta->is_green;
@@ -1270,18 +1267,17 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
  * Try to switch to new modulation mode from legacy
  */
 static int rs_move_legacy_other(struct iwl_priv *priv,
-				struct iwl4965_lq_sta *lq_sta,
+				struct iwl_lq_sta *lq_sta,
 				struct ieee80211_conf *conf,
 				struct sta_info *sta,
 				int index)
 {
-	struct iwl4965_scale_tbl_info *tbl =
-	    &(lq_sta->lq_info[lq_sta->active_tbl]);
-	struct iwl4965_scale_tbl_info *search_tbl =
-	    &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
-	struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
-	u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
-		  (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
+	struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+	struct iwl_scale_tbl_info *search_tbl =
+				&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+	struct iwl_rate_scale_data *window = &(tbl->win[index]);
+	u32 sz = (sizeof(struct iwl_scale_tbl_info) -
+		  (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
 	u8 start_action = tbl->action;
 	u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
 	int ret = 0;
@@ -1360,19 +1356,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
  * Try to switch to new modulation mode from SISO
  */
 static int rs_move_siso_to_other(struct iwl_priv *priv,
-				 struct iwl4965_lq_sta *lq_sta,
+				 struct iwl_lq_sta *lq_sta,
 				 struct ieee80211_conf *conf,
-				 struct sta_info *sta,
-				 int index)
+				 struct sta_info *sta, int index)
 {
 	u8 is_green = lq_sta->is_green;
-	struct iwl4965_scale_tbl_info *tbl =
-	    &(lq_sta->lq_info[lq_sta->active_tbl]);
-	struct iwl4965_scale_tbl_info *search_tbl =
-	    &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
-	struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
-	u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
-		  (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
+	struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+	struct iwl_scale_tbl_info *search_tbl =
+				&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+	struct iwl_rate_scale_data *window = &(tbl->win[index]);
+	u32 sz = (sizeof(struct iwl_scale_tbl_info) -
+		  (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
 	u8 start_action = tbl->action;
 	u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
 	int ret;
@@ -1455,18 +1449,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
  * Try to switch to new modulation mode from MIMO
  */
 static int rs_move_mimo_to_other(struct iwl_priv *priv,
-				 struct iwl4965_lq_sta *lq_sta,
+				 struct iwl_lq_sta *lq_sta,
 				 struct ieee80211_conf *conf,
-				 struct sta_info *sta,
-				 int index)
+				 struct sta_info *sta, int index)
 {
 	s8 is_green = lq_sta->is_green;
-	struct iwl4965_scale_tbl_info *tbl =
-	    &(lq_sta->lq_info[lq_sta->active_tbl]);
-	struct iwl4965_scale_tbl_info *search_tbl =
-	    &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
-	u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
-		  (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
+	struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+	struct iwl_scale_tbl_info *search_tbl =
+				&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+	u32 sz = (sizeof(struct iwl_scale_tbl_info) -
+		  (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
 	u8 start_action = tbl->action;
 	/*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/
 	int ret;
@@ -1552,9 +1544,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
  * 2) # times calling this function
  * 3) elapsed time in this mode (not used, for now)
  */
-static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
+static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
 {
-	struct iwl4965_scale_tbl_info *tbl;
+	struct iwl_scale_tbl_info *tbl;
 	int i;
 	int active_tbl;
 	int flush_interval_passed = 0;
@@ -1642,7 +1634,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 	int high = IWL_RATE_INVALID;
 	int index;
 	int i;
-	struct iwl4965_rate_scale_data *window = NULL;
+	struct iwl_rate_scale_data *window = NULL;
 	int current_tpt = IWL_INVALID_VALUE;
 	int low_tpt = IWL_INVALID_VALUE;
 	int high_tpt = IWL_INVALID_VALUE;
@@ -1651,8 +1643,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 	__le16 fc;
 	u16 rate_mask;
 	u8 update_lq = 0;
-	struct iwl4965_lq_sta *lq_sta;
-	struct iwl4965_scale_tbl_info *tbl, *tbl1;
+	struct iwl_lq_sta *lq_sta;
+	struct iwl_scale_tbl_info *tbl, *tbl1;
 	u16 rate_scale_index_msk = 0;
 	u32 rate;
 	u8 is_green = 0;
@@ -1675,7 +1667,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 	if (!sta || !sta->rate_ctrl_priv)
 		return;
 
-	lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
+	lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
 
 	tid = rs_tl_add_packet(lq_sta, hdr);
 
@@ -2030,8 +2022,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
 			     struct ieee80211_conf *conf,
 			     struct sta_info *sta)
 {
-	struct iwl4965_lq_sta *lq_sta;
-	struct iwl4965_scale_tbl_info *tbl;
+	struct iwl_lq_sta *lq_sta;
+	struct iwl_scale_tbl_info *tbl;
 	int rate_idx;
 	int i;
 	u32 rate;
@@ -2042,7 +2034,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
 	if (!sta || !sta->rate_ctrl_priv)
 		goto out;
 
-	lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
+	lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
 	i = sta->last_txrate_idx;
 
 	if ((lq_sta->lq.sta_id == 0xff) &&
@@ -2096,7 +2088,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
 	struct sta_info *sta;
 	__le16 fc;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
-	struct iwl4965_lq_sta *lq_sta;
+	struct iwl_lq_sta *lq_sta;
 
 	IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
@@ -2113,7 +2105,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
 		goto out;
 	}
 
-	lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
+	lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
 	i = sta->last_txrate_idx;
 
 	if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
@@ -2149,14 +2141,14 @@ out:
 
 static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
 {
-	struct iwl4965_lq_sta *lq_sta;
+	struct iwl_lq_sta *lq_sta;
 	struct iwl_priv *priv;
 	int i, j;
 
 	priv = (struct iwl_priv *)priv_rate;
 	IWL_DEBUG_RATE("create station rate scale window\n");
 
-	lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp);
+	lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp);
 
 	if (lq_sta == NULL)
 		return NULL;
@@ -2165,7 +2157,7 @@ static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
 
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
-			rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
+			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
 
 	return lq_sta;
 }
@@ -2178,7 +2170,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
 	struct ieee80211_conf *conf = &local->hw.conf;
 	struct ieee80211_supported_band *sband;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
-	struct iwl4965_lq_sta *lq_sta = priv_sta;
+	struct iwl_lq_sta *lq_sta = priv_sta;
 
 	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
@@ -2187,7 +2179,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
 	sta->txrate_idx = 3;
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
-			rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
+			rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
 
 	IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n");
 	/* TODO: what is a good starting rate for STA? About middle? Maybe not
@@ -2271,10 +2263,9 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
 }
 
 static void rs_fill_link_cmd(const struct iwl_priv *priv,
-			     struct iwl4965_lq_sta *lq_sta,
-			     u32 new_rate)
+			     struct iwl_lq_sta *lq_sta, u32 new_rate)
 {
-	struct iwl4965_scale_tbl_info tbl_type;
+	struct iwl_scale_tbl_info tbl_type;
 	int index = 0;
 	int rate_idx;
 	int repeat_rate = 0;
@@ -2402,6 +2393,7 @@ static void rs_free(void *priv_rate)
 
 static void rs_clear(void *priv_rate)
 {
+#ifdef CONFIG_IWLWIFI_DEBUG
 	struct iwl_priv *priv = (struct iwl_priv *) priv_rate;
 
 	IWL_DEBUG_RATE("enter\n");
@@ -2409,11 +2401,12 @@ static void rs_clear(void *priv_rate)
 	/* TODO - add rate scale state reset */
 
 	IWL_DEBUG_RATE("leave\n");
+#endif /* CONFIG_IWLWIFI_DEBUG */
 }
 
 static void rs_free_sta(void *priv_rate, void *priv_sta)
 {
-	struct iwl4965_lq_sta *lq_sta = priv_sta;
+	struct iwl_lq_sta *lq_sta = priv_sta;
 	struct iwl_priv *priv;
 
 	priv = (struct iwl_priv *)priv_rate;
@@ -2429,8 +2422,8 @@ static int open_file_generic(struct inode *inode, struct file *file)
 	file->private_data = inode->i_private;
 	return 0;
 }
-static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
-				u32 *rate_n_flags, int index)
+static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
+			     u32 *rate_n_flags, int index)
 {
 	struct iwl_priv *priv;
 
@@ -2453,7 +2446,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
 static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
 			const char __user *user_buf, size_t count, loff_t *ppos)
 {
-	struct iwl4965_lq_sta *lq_sta = file->private_data;
+	struct iwl_lq_sta *lq_sta = file->private_data;
 	struct iwl_priv *priv;
 	char buf[64];
 	int buf_size;
@@ -2493,7 +2486,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 	int desc = 0;
 	int i = 0;
 
-	struct iwl4965_lq_sta *lq_sta = file->private_data;
+	struct iwl_lq_sta *lq_sta = file->private_data;
 
 	desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
 	desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
@@ -2541,7 +2534,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
 	int desc = 0;
 	int i, j;
 
-	struct iwl4965_lq_sta *lq_sta = file->private_data;
+	struct iwl_lq_sta *lq_sta = file->private_data;
 	for (i = 0; i < LQ_SIZE; i++) {
 		desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
 				"rate=0x%X\n",
@@ -2570,7 +2563,7 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
 static void rs_add_debugfs(void *priv, void *priv_sta,
 					struct dentry *dir)
 {
-	struct iwl4965_lq_sta *lq_sta = priv_sta;
+	struct iwl_lq_sta *lq_sta = priv_sta;
 	lq_sta->rs_sta_dbgfs_scale_table_file =
 		debugfs_create_file("rate_scale_table", 0600, dir,
 				lq_sta, &rs_sta_dbgfs_scale_table_ops);
@@ -2585,7 +2578,7 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
 
 static void rs_remove_debugfs(void *priv, void *priv_sta)
 {
-	struct iwl4965_lq_sta *lq_sta = priv_sta;
+	struct iwl_lq_sta *lq_sta = priv_sta;
 	debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
 	debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
 	debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
@@ -2609,104 +2602,12 @@ static struct rate_control_ops rs_ops = {
 #endif
 };
 
-int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
-{
-	struct ieee80211_local *local = hw_to_local(hw);
-	struct iwl_priv *priv = hw->priv;
-	struct iwl4965_lq_sta *lq_sta;
-	struct sta_info *sta;
-	int cnt = 0, i;
-	u32 samples = 0, success = 0, good = 0;
-	unsigned long now = jiffies;
-	u32 max_time = 0;
-	u8 lq_type, antenna;
-
-	rcu_read_lock();
-
-	sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
-	if (!sta || !sta->rate_ctrl_priv) {
-		if (sta)
-			IWL_DEBUG_RATE("leave - no private rate data!\n");
-		else
-			IWL_DEBUG_RATE("leave - no station!\n");
-		rcu_read_unlock();
-		return sprintf(buf, "station %d not found\n", sta_id);
-	}
-
-	lq_sta = (void *)sta->rate_ctrl_priv;
-
-	lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type;
-	antenna = lq_sta->lq_info[lq_sta->active_tbl].ant_type;
-
-	if (is_legacy(lq_type))
-		i = IWL_RATE_54M_INDEX;
-	else
-		i = IWL_RATE_60M_INDEX;
-	while (1) {
-		u64 mask;
-		int j;
-		int active = lq_sta->active_tbl;
-
-		cnt +=
-		    sprintf(&buf[cnt], " %2dMbs: ", iwl_rates[i].ieee / 2);
-
-		mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
-		for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
-			buf[cnt++] =
-				(lq_sta->lq_info[active].win[i].data & mask)
-				? '1' : '0';
-
-		samples += lq_sta->lq_info[active].win[i].counter;
-		good += lq_sta->lq_info[active].win[i].success_counter;
-		success += lq_sta->lq_info[active].win[i].success_counter *
-			   iwl_rates[i].ieee;
-
-		if (lq_sta->lq_info[active].win[i].stamp) {
-			int delta =
-				   jiffies_to_msecs(now -
-				   lq_sta->lq_info[active].win[i].stamp);
-
-			if (delta > max_time)
-				max_time = delta;
-
-			cnt += sprintf(&buf[cnt], "%5dms\n", delta);
-		} else
-			buf[cnt++] = '\n';
-
-		j = iwl4965_get_prev_ieee_rate(i);
-		if (j == i)
-			break;
-		i = j;
-	}
-
-	/*
-	 * Display the average rate of all samples taken.
-	 * NOTE: We multiply # of samples by 2 since the IEEE measurement
-	 * added from iwl_rates is actually 2X the rate.
-	 */
-	if (samples)
-		cnt += sprintf(&buf[cnt],
-			 "\nAverage rate is %3d.%02dMbs over last %4dms\n"
-			 "%3d%% success (%d good packets over %d tries)\n",
-			 success / (2 * samples), (success * 5 / samples) % 10,
-			 max_time, good * 100 / samples, good, samples);
-	else
-		cnt += sprintf(&buf[cnt], "\nAverage rate: 0Mbs\n");
-
-	cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d "
-			 "active_search %d rate index %d\n", lq_type, antenna,
-			 lq_sta->search_better_tbl, sta->last_txrate_idx);
-
-	rcu_read_unlock();
-	return cnt;
-}
-
-int iwl4965_rate_control_register(void)
+int iwlagn_rate_control_register(void)
 {
 	return ieee80211_rate_control_register(&rs_ops);
 }
 
-void iwl4965_rate_control_unregister(void)
+void iwlagn_rate_control_unregister(void)
 {
 	ieee80211_rate_control_unregister(&rs_ops);
 }

+ 7 - 16
drivers/net/wireless/iwlwifi/iwl-4965-rs.h → drivers/net/wireless/iwlwifi/iwl-agn-rs.h

@@ -24,8 +24,8 @@
  *
  *****************************************************************************/
 
-#ifndef __iwl_4965_rs_h__
-#define __iwl_4965_rs_h__
+#ifndef __iwl_agn_rs_h__
+#define __iwl_agn_rs_h__
 
 #include "iwl-dev.h"
 
@@ -88,7 +88,7 @@ enum {
 #define	IWL_RATE_5M_MASK   (1 << IWL_RATE_5M_INDEX)
 #define	IWL_RATE_11M_MASK  (1 << IWL_RATE_11M_INDEX)
 
-/* 4965 uCode API values for legacy bit rates, both OFDM and CCK */
+/* uCode API values for legacy bit rates, both OFDM and CCK */
 enum {
 	IWL_RATE_6M_PLCP  = 13,
 	IWL_RATE_9M_PLCP  = 15,
@@ -107,7 +107,7 @@ enum {
 	/*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
 };
 
-/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */
+/* uCode API values for OFDM high-throughput (HT) bit rates */
 enum {
 	IWL_RATE_SISO_6M_PLCP = 0,
 	IWL_RATE_SISO_12M_PLCP = 1,
@@ -286,15 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
 	return rate;
 }
 
-/**
- * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
- *
- * NOTE:  This is provided as a quick mechanism for a user to visualize
- * the performance of the rate control algorithm and is not meant to be
- * parsed software.
- */
-extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
-
 /**
  * iwl4965_rate_control_register - Register the rate control algorithm callbacks
  *
@@ -305,7 +296,7 @@ extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
  * ieee80211_register_hw
  *
  */
-extern int iwl4965_rate_control_register(void);
+extern int iwlagn_rate_control_register(void);
 
 /**
  * iwl4965_rate_control_unregister - Unregister the rate control callbacks
@@ -313,6 +304,6 @@ extern int iwl4965_rate_control_register(void);
  * This should be called after calling ieee80211_unregister_hw, but before
  * the driver is unloaded.
  */
-extern void iwl4965_rate_control_unregister(void);
+extern void iwlagn_rate_control_unregister(void);
 
-#endif
+#endif /* __iwl_agn__rs__ */

+ 148 - 84
drivers/net/wireless/iwlwifi/iwl4965-base.c → drivers/net/wireless/iwlwifi/iwl-agn.c

@@ -65,7 +65,7 @@
  * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
  */
 
-#define DRV_DESCRIPTION	"Intel(R) Wireless WiFi Link 4965AGN driver for Linux"
+#define DRV_DESCRIPTION	"Intel(R) Wireless WiFi Link AGN driver for Linux"
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 #define VD "d"
@@ -73,7 +73,7 @@
 #define VD
 #endif
 
-#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
 #define VS "s"
 #else
 #define VS
@@ -86,6 +86,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("iwl4965");
 
 /*************** STATION TABLE MANAGEMENT ****
  * mac80211 should be examined to determine if sta_info is duplicating
@@ -444,11 +445,10 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
 	list_add(&frame->list, &priv->free_frames);
 }
 
-unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
-				struct ieee80211_hdr *hdr,
-				const u8 *dest, int left)
+static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
+					  struct ieee80211_hdr *hdr,
+					  const u8 *dest, int left)
 {
-
 	if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
 	    ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
 	     (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
@@ -487,6 +487,38 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
 		return IWL_RATE_6M_PLCP;
 }
 
+unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
+				       struct iwl_frame *frame, u8 rate)
+{
+	struct iwl_tx_beacon_cmd *tx_beacon_cmd;
+	unsigned int frame_size;
+
+	tx_beacon_cmd = &frame->u.beacon;
+	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
+
+	tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
+	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+
+	frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
+				iwl_bcast_addr,
+				sizeof(frame->u) - sizeof(*tx_beacon_cmd));
+
+	BUG_ON(frame_size > MAX_MPDU_SIZE);
+	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
+
+	if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
+		tx_beacon_cmd->tx.rate_n_flags =
+			iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
+	else
+		tx_beacon_cmd->tx.rate_n_flags =
+			iwl_hw_set_rate_n_flags(rate, 0);
+
+	tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
+				     TX_CMD_FLG_TSF_MSK |
+				     TX_CMD_FLG_STA_RATE_MSK;
+
+	return sizeof(*tx_beacon_cmd) + frame_size;
+}
 static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
 {
 	struct iwl_frame *frame;
@@ -608,7 +640,6 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
 }
 
 #define MAX_UCODE_BEACON_INTERVAL	4096
-#define INTEL_CONN_LISTEN_INTERVAL	__constant_cpu_to_le16(0xA)
 
 static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val)
 {
@@ -638,7 +669,7 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
 	priv->rxon_timing.timestamp.dw[0] =
 				cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
 
-	priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
+	priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
 
 	tsf = priv->timestamp;
 
@@ -853,7 +884,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
 		   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
 }
 
-#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
 
 #include "iwl-spectrum.h"
 
@@ -1057,7 +1088,7 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
 					  struct iwl_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 	struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
 
@@ -1231,6 +1262,37 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
 		wake_up_interruptible(&priv->wait_command_queue);
 }
 
+int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	ret = iwl_grab_nic_access(priv);
+	if (ret)
+		goto err;
+
+	if (src == IWL_PWR_SRC_VAUX) {
+		u32 val;
+		ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
+					    &val);
+
+		if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
+			iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+					       APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
+					       ~APMG_PS_CTRL_MSK_PWR_SRC);
+	} else {
+		iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+				       APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+				       ~APMG_PS_CTRL_MSK_PWR_SRC);
+	}
+
+	iwl_release_nic_access(priv);
+err:
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return ret;
+}
+
 /**
  * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks
  *
@@ -2170,17 +2232,16 @@ static int __iwl4965_up(struct iwl_priv *priv)
 	}
 
 	/* If platform's RF_KILL switch is NOT set to KILL */
-	if (iwl_read32(priv, CSR_GP_CNTRL) &
-				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
 		clear_bit(STATUS_RF_KILL_HW, &priv->status);
 	else
 		set_bit(STATUS_RF_KILL_HW, &priv->status);
 
-	if (!test_bit(STATUS_IN_SUSPEND, &priv->status) &&
-	    iwl_is_rfkill(priv)) {
+	if (iwl_is_rfkill(priv)) {
+		iwl4965_enable_interrupts(priv);
 		IWL_WARNING("Radio disabled by %s RF Kill switch\n",
 		    test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
-		return -ENODEV;
+		return 0;
 	}
 
 	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
@@ -2216,11 +2277,6 @@ static int __iwl4965_up(struct iwl_priv *priv)
 	memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
 	       priv->ucode_data.len);
 
-	/* We return success when we resume from suspend and rf_kill is on. */
-	if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
-	    test_bit(STATUS_RF_KILL_SW, &priv->status))
-		return 0;
-
 	for (i = 0; i < MAX_HW_RESTARTS; i++) {
 
 		iwl_clear_stations_table(priv);
@@ -2415,7 +2471,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
 	unsigned long flags;
 
 	if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
-		IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
+		IWL_ERROR("%s Should not be called in AP mode\n", __func__);
 		return;
 	}
 
@@ -2491,7 +2547,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
 
 	default:
 		IWL_ERROR("%s Should not be called in %d mode\n",
-				__FUNCTION__, priv->iw_mode);
+			  __func__, priv->iw_mode);
 		break;
 	}
 
@@ -2589,6 +2645,9 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
 	if (ret)
 		goto out_release_irq;
 
+	if (iwl_is_rfkill(priv))
+		goto out;
+
 	IWL_DEBUG_INFO("Start UP work done.\n");
 
 	if (test_bit(STATUS_IN_SUSPEND, &priv->status))
@@ -2608,6 +2667,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
 		}
 	}
 
+out:
 	priv->is_open = 1;
 	IWL_DEBUG_MAC80211("leave\n");
 	return 0;
@@ -2773,6 +2833,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
 
 	spin_lock_irqsave(&priv->lock, flags);
 
+
 	/* if we are switching from ht to 2.4 clear flags
 	 * from any ht related info since 2.4 does not
 	 * support ht */
@@ -3102,6 +3163,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
 		if (bss_conf->assoc) {
 			priv->assoc_id = bss_conf->aid;
 			priv->beacon_int = bss_conf->beacon_int;
+			priv->power_data.dtim_period = bss_conf->dtim_period;
 			priv->timestamp = bss_conf->timestamp;
 			priv->assoc_capability = bss_conf->assoc_capability;
 			priv->next_scan_jiffies = jiffies +
@@ -3345,6 +3407,39 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
 	return 0;
 }
 
+static int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
+			     enum ieee80211_ampdu_mlme_action action,
+			     const u8 *addr, u16 tid, u16 *ssn)
+{
+	struct iwl_priv *priv = hw->priv;
+	DECLARE_MAC_BUF(mac);
+
+	IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
+		     print_mac(mac, addr), tid);
+
+	if (!(priv->cfg->sku & IWL_SKU_N))
+		return -EACCES;
+
+	switch (action) {
+	case IEEE80211_AMPDU_RX_START:
+		IWL_DEBUG_HT("start Rx\n");
+		return iwl_rx_agg_start(priv, addr, tid, *ssn);
+	case IEEE80211_AMPDU_RX_STOP:
+		IWL_DEBUG_HT("stop Rx\n");
+		return iwl_rx_agg_stop(priv, addr, tid);
+	case IEEE80211_AMPDU_TX_START:
+		IWL_DEBUG_HT("start Tx\n");
+		return iwl_tx_agg_start(priv, addr, tid, ssn);
+	case IEEE80211_AMPDU_TX_STOP:
+		IWL_DEBUG_HT("stop Tx\n");
+		return iwl_tx_agg_stop(priv, addr, tid);
+	default:
+		IWL_DEBUG_HT("unknown\n");
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
 static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
 				struct ieee80211_tx_queue_stats *stats)
 {
@@ -3592,15 +3687,6 @@ static ssize_t show_temperature(struct device *d,
 
 static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
 
-static ssize_t show_rs_window(struct device *d,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	struct iwl_priv *priv = d->driver_data;
-	return iwl4965_fill_rs_info(priv->hw, buf, IWL_AP_ID);
-}
-static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL);
-
 static ssize_t show_tx_power(struct device *d,
 			     struct device_attribute *attr, char *buf)
 {
@@ -3699,7 +3785,7 @@ static ssize_t store_filter_flags(struct device *d,
 static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
 		   store_filter_flags);
 
-#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
 
 static ssize_t show_measurement(struct device *d,
 				struct device_attribute *attr, char *buf)
@@ -3707,7 +3793,7 @@ static ssize_t show_measurement(struct device *d,
 	struct iwl_priv *priv = dev_get_drvdata(d);
 	struct iwl4965_spectrum_notification measure_report;
 	u32 size = sizeof(measure_report), len = 0, ofs = 0;
-	u8 *data = (u8 *) & measure_report;
+	u8 *data = (u8 *)&measure_report;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
@@ -3770,7 +3856,7 @@ static ssize_t store_measurement(struct device *d,
 
 static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
 		   show_measurement, store_measurement);
-#endif /* CONFIG_IWL4965_SPECTRUM_MEASUREMENT */
+#endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
 
 static ssize_t store_retry_rate(struct device *d,
 				struct device_attribute *attr,
@@ -3800,77 +3886,54 @@ static ssize_t store_power_level(struct device *d,
 				 const char *buf, size_t count)
 {
 	struct iwl_priv *priv = dev_get_drvdata(d);
-	int rc;
+	int ret;
 	int mode;
 
 	mode = simple_strtoul(buf, NULL, 0);
 	mutex_lock(&priv->mutex);
 
 	if (!iwl_is_ready(priv)) {
-		rc = -EAGAIN;
+		ret = -EAGAIN;
 		goto out;
 	}
 
-	rc = iwl_power_set_user_mode(priv, mode);
-	if (rc) {
+	ret = iwl_power_set_user_mode(priv, mode);
+	if (ret) {
 		IWL_DEBUG_MAC80211("failed setting power mode.\n");
 		goto out;
 	}
-	rc = count;
+	ret = count;
 
  out:
 	mutex_unlock(&priv->mutex);
-	return rc;
+	return ret;
 }
 
-#define MAX_WX_STRING 80
-
-/* Values are in microsecond */
-static const s32 timeout_duration[] = {
-	350000,
-	250000,
-	75000,
-	37000,
-	25000,
-};
-static const s32 period_duration[] = {
-	400000,
-	700000,
-	1000000,
-	1000000,
-	1000000
-};
-
 static ssize_t show_power_level(struct device *d,
 				struct device_attribute *attr, char *buf)
 {
 	struct iwl_priv *priv = dev_get_drvdata(d);
+	int mode = priv->power_data.user_power_setting;
+	int system = priv->power_data.system_power_setting;
 	int level = priv->power_data.power_mode;
 	char *p = buf;
 
-	p += sprintf(p, "%d ", level);
-	switch (level) {
-	case IWL_POWER_MODE_CAM:
-	case IWL_POWER_AC:
-		p += sprintf(p, "(AC)");
+	switch (system) {
+	case IWL_POWER_SYS_AUTO:
+		p += sprintf(p, "SYSTEM:auto");
 		break;
-	case IWL_POWER_BATTERY:
-		p += sprintf(p, "(BATTERY)");
+	case IWL_POWER_SYS_AC:
+		p += sprintf(p, "SYSTEM:ac");
+		break;
+	case IWL_POWER_SYS_BATTERY:
+		p += sprintf(p, "SYSTEM:battery");
 		break;
-	default:
-		p += sprintf(p,
-			     "(Timeout %dms, Period %dms)",
-			     timeout_duration[level - 1] / 1000,
-			     period_duration[level - 1] / 1000);
 	}
-/*
-	if (!(priv->power_mode & IWL_POWER_ENABLED))
-		p += sprintf(p, " OFF\n");
-	else
-		p += sprintf(p, " \n");
-*/
-	p += sprintf(p, " \n");
-	return (p - buf + 1);
+
+	p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO)?"fixed":"auto");
+	p += sprintf(p, "\tINDEX:%d", level);
+	p += sprintf(p, "\n");
+	return p - buf + 1;
 }
 
 static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
@@ -3945,7 +4008,7 @@ static ssize_t show_statistics(struct device *d,
 	struct iwl_priv *priv = dev_get_drvdata(d);
 	u32 size = sizeof(struct iwl_notif_statistics);
 	u32 len = 0, ofs = 0;
-	u8 *data = (u8 *) & priv->statistics;
+	u8 *data = (u8 *)&priv->statistics;
 	int rc = 0;
 
 	if (!iwl_is_alive(priv))
@@ -4041,12 +4104,11 @@ static struct attribute *iwl4965_sysfs_entries[] = {
 	&dev_attr_channels.attr,
 	&dev_attr_flags.attr,
 	&dev_attr_filter_flags.attr,
-#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
 	&dev_attr_measurement.attr,
 #endif
 	&dev_attr_power_level.attr,
 	&dev_attr_retry_rate.attr,
-	&dev_attr_rs_window.attr,
 	&dev_attr_statistics.attr,
 	&dev_attr_status.attr,
 	&dev_attr_temperature.attr,
@@ -4394,8 +4456,10 @@ static int iwl4965_pci_resume(struct pci_dev *pdev)
 
 /* Hardware specific file defines the PCI IDs table for that hardware module */
 static struct pci_device_id iwl_hw_card_ids[] = {
+#ifdef CONFIG_IWL4965
 	{IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
 	{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
+#endif /* CONFIG_IWL4965 */
 #ifdef CONFIG_IWL5000
 	{IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)},
 	{IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)},
@@ -4431,7 +4495,7 @@ static int __init iwl4965_init(void)
 	printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
 	printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
 
-	ret = iwl4965_rate_control_register();
+	ret = iwlagn_rate_control_register();
 	if (ret) {
 		IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
 		return ret;
@@ -4446,14 +4510,14 @@ static int __init iwl4965_init(void)
 	return ret;
 
 error_register:
-	iwl4965_rate_control_unregister();
+	iwlagn_rate_control_unregister();
 	return ret;
 }
 
 static void __exit iwl4965_exit(void)
 {
 	pci_unregister_driver(&iwl_driver);
-	iwl4965_rate_control_unregister();
+	iwlagn_rate_control_unregister();
 }
 
 module_exit(iwl4965_exit);

+ 31 - 13
drivers/net/wireless/iwlwifi/iwl-commands.h

@@ -666,8 +666,7 @@ struct iwl4965_rxon_assoc_cmd {
 	__le16 reserved;
 } __attribute__ ((packed));
 
-
-
+#define IWL_CONN_MAX_LISTEN_INTERVAL	10
 
 /*
  * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
@@ -1076,10 +1075,12 @@ struct iwl4965_rx_frame {
 } __attribute__ ((packed));
 
 /* Fixed (non-configurable) rx data from phy */
-#define RX_PHY_FLAGS_ANTENNAE_OFFSET		(4)
-#define RX_PHY_FLAGS_ANTENNAE_MASK		(0x70)
-#define IWL_AGC_DB_MASK 	(0x3f80)	/* MASK(7,13) */
-#define IWL_AGC_DB_POS		(7)
+
+#define IWL49_RX_RES_PHY_CNT 14
+#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET	(4)
+#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK	(0x70)
+#define IWL49_AGC_DB_MASK			(0x3f80)	/* MASK(7,13) */
+#define IWL49_AGC_DB_POS			(7)
 struct iwl4965_rx_non_cfg_phy {
 	__le16 ant_selection;	/* ant A bit 4, ant B bit 5, ant C bit 6 */
 	__le16 agc_info;	/* agc code 0:6, agc dB 7:13, reserved 14:15 */
@@ -1087,12 +1088,30 @@ struct iwl4965_rx_non_cfg_phy {
 	u8 pad[0];
 } __attribute__ ((packed));
 
+
+#define IWL50_RX_RES_PHY_CNT 8
+#define IWL50_RX_RES_AGC_IDX     1
+#define IWL50_RX_RES_RSSI_AB_IDX 2
+#define IWL50_RX_RES_RSSI_C_IDX  3
+#define IWL50_OFDM_AGC_MSK 0xfe00
+#define IWL50_OFDM_AGC_BIT_POS 9
+#define IWL50_OFDM_RSSI_A_MSK 0x00ff
+#define IWL50_OFDM_RSSI_A_BIT_POS 0
+#define IWL50_OFDM_RSSI_B_MSK 0xff0000
+#define IWL50_OFDM_RSSI_B_BIT_POS 16
+#define IWL50_OFDM_RSSI_C_MSK 0x00ff
+#define IWL50_OFDM_RSSI_C_BIT_POS 0
+
+struct iwl5000_non_cfg_phy {
+	__le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT];  /* upto 8 phy entries */
+} __attribute__ ((packed));
+
+
 /*
  * REPLY_RX = 0xc3 (response only, not a command)
  * Used only for legacy (non 11n) frames.
  */
-#define RX_RES_PHY_CNT 14
-struct iwl4965_rx_phy_res {
+struct iwl_rx_phy_res {
 	u8 non_cfg_phy_cnt;     /* non configurable DSP phy data byte count */
 	u8 cfg_phy_cnt;		/* configurable DSP phy data byte count */
 	u8 stat_id;		/* configurable DSP phy data set ID */
@@ -1101,8 +1120,7 @@ struct iwl4965_rx_phy_res {
 	__le32 beacon_time_stamp; /* beacon at on-air rise */
 	__le16 phy_flags;	/* general phy flags: band, modulation, ... */
 	__le16 channel;		/* channel number */
-	__le16 non_cfg_phy[RX_RES_PHY_CNT];	/* upto 14 phy entries */
-	__le32 reserved2;
+	u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */
 	__le32 rate_n_flags;	/* RATE_MCS_* */
 	__le16 byte_count;	/* frame's byte-count */
 	__le16 reserved3;
@@ -1993,7 +2011,7 @@ struct iwl4965_spectrum_notification {
  *****************************************************************************/
 
 /**
- * struct iwl4965_powertable_cmd - Power Table Command
+ * struct iwl_powertable_cmd - Power Table Command
  * @flags: See below:
  *
  * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
@@ -2027,7 +2045,7 @@ struct iwl4965_spectrum_notification {
 #define IWL_POWER_PCI_PM_MSK			__constant_cpu_to_le16(1 << 3)
 #define IWL_POWER_FAST_PD			__constant_cpu_to_le16(1 << 4)
 
-struct iwl4965_powertable_cmd {
+struct iwl_powertable_cmd {
 	__le16 flags;
 	u8 keep_alive_seconds;
 	u8 debug_flags;
@@ -2324,7 +2342,7 @@ struct iwl4965_beacon_notif {
 /*
  * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
  */
-struct iwl4965_tx_beacon_cmd {
+struct iwl_tx_beacon_cmd {
 	struct iwl_tx_cmd tx;
 	__le16 tim_idx;
 	u8 tim_size;

+ 4 - 3
drivers/net/wireless/iwlwifi/iwl-core.c

@@ -383,8 +383,8 @@ void iwl_reset_qos(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_reset_qos);
 
-#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */
-#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */
+#define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */
+#define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */
 static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
 			      struct ieee80211_ht_info *ht_info,
 			      enum ieee80211_band band)
@@ -815,7 +815,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
 {
 	int ret;
 	struct ieee80211_hw *hw = priv->hw;
-	hw->rate_control_algorithm = "iwl-4965-rs";
+	hw->rate_control_algorithm = "iwl-agn-rs";
 
 	/* Tell mac80211 our characteristics */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
@@ -827,6 +827,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
 		hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
 
 	hw->conf.beacon_int = 100;
+	hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
 
 	if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
 		priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =

+ 2 - 1
drivers/net/wireless/iwlwifi/iwl-core.h

@@ -95,6 +95,8 @@ struct iwl_hcmd_utils_ops {
 	void (*chain_noise_reset)(struct iwl_priv *priv);
 	void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
 			__le32 *tx_flags);
+	int  (*calc_rssi)(struct iwl_priv *priv,
+			  struct iwl_rx_phy_res *rx_resp);
 };
 
 struct iwl_lib_ops {
@@ -139,7 +141,6 @@ struct iwl_lib_ops {
 		int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
 	} apm_ops;
 	/* power */
-	int (*set_power)(struct iwl_priv *priv, void *cmd);
 	int (*send_tx_power) (struct iwl_priv *priv);
 	void (*update_chain_flags)(struct iwl_priv *priv);
 	void (*temperature) (struct iwl_priv *priv);

+ 9 - 1
drivers/net/wireless/iwlwifi/iwl-csr.h

@@ -104,6 +104,7 @@
  *  3-2:  0 = A, 1 = B, 2 = C, 3 = D step
  */
 #define CSR_HW_REV_WA_REG	(CSR_BASE+0x22C)
+#define CSR_DBG_HPET_MEM_REG	(CSR_BASE+0x240)
 
 /* Bits for CSR_HW_IF_CONFIG_REG */
 #define CSR49_HW_IF_CONFIG_REG_BIT_4965_R	(0x00000010)
@@ -118,7 +119,12 @@
 #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A    (0x00000000)
 #define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B    (0x00001000)
 
-#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM     (0x00200000)
+#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A		(0x00080000)
+#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM		(0x00200000)
+#define CSR_HW_IF_CONFIG_REG_BIT_PCI_OWN_SEM		(0x00400000)
+#define CSR_HW_IF_CONFIG_REG_BIT_ME_OWN			(0x02000000)
+#define CSR_HW_IF_CONFIG_REG_BIT_WAKE_ME		(0x08000000)
+
 
 /* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
  * acknowledged (reset) by host writing "1" to flagged bits. */
@@ -236,6 +242,8 @@
 #define CSR39_ANA_PLL_CFG_VAL        (0x01000000)
 #define CSR50_ANA_PLL_CFG_VAL        (0x00880300)
 
+/* HPET MEM debug */
+#define CSR_DBG_HPET_MEM_REG_VAL	(0xFFFF0000)
 /*=== HBUS (Host-side Bus) ===*/
 #define HBUS_BASE	(0x400)
 /*

+ 2 - 2
drivers/net/wireless/iwlwifi/iwl-debug.h

@@ -33,12 +33,12 @@
 #define IWL_DEBUG(level, fmt, args...) \
 do { if (priv->debug_level & (level)) \
   dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
-	 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
 
 #define IWL_DEBUG_LIMIT(level, fmt, args...) \
 do { if ((priv->debug_level & (level)) && net_ratelimit()) \
   dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
-	 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+	 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 struct iwl_debugfs {

+ 7 - 4
drivers/net/wireless/iwlwifi/iwl-debugfs.c

@@ -231,7 +231,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
 	DECLARE_MAC_BUF(mac);
 
 	buf = kmalloc(bufsz, GFP_KERNEL);
-	if(!buf)
+	if (!buf)
 		return -ENOMEM;
 
 	pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
@@ -364,16 +364,19 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 {
 	struct iwl_debugfs *dbgfs;
 	struct dentry *phyd = priv->hw->wiphy->debugfsdir;
+	int ret = 0;
 
 	dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
 	if (!dbgfs) {
+		ret = -ENOMEM;
 		goto err;
 	}
 
 	priv->dbgfs = dbgfs;
 	dbgfs->name = name;
 	dbgfs->dir_drv = debugfs_create_dir(name, phyd);
-	if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)){
+	if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) {
+		ret = -ENOENT;
 		goto err;
 	}
 
@@ -394,7 +397,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 err:
 	IWL_ERROR("Can't open the debugfs directory\n");
 	iwl_dbgfs_unregister(priv);
-	return -ENOENT;
+	return ret;
 }
 EXPORT_SYMBOL(iwl_dbgfs_register);
 
@@ -404,7 +407,7 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
  */
 void iwl_dbgfs_unregister(struct iwl_priv *priv)
 {
-	if (!(priv->dbgfs))
+	if (!priv->dbgfs)
 		return;
 
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);

+ 7 - 15
drivers/net/wireless/iwlwifi/iwl-dev.h

@@ -36,7 +36,7 @@
 #include <linux/kernel.h>
 #include <net/ieee80211_radiotap.h>
 
-#define DRV_NAME        "iwl4965"
+#define DRV_NAME        "iwlagn"
 #include "iwl-rfkill.h"
 #include "iwl-eeprom.h"
 #include "iwl-4965-hw.h"
@@ -45,6 +45,7 @@
 #include "iwl-debug.h"
 #include "iwl-led.h"
 #include "iwl-power.h"
+#include "iwl-agn-rs.h"
 
 /* configuration for the iwl4965 */
 extern struct iwl_cfg iwl4965_agn_cfg;
@@ -134,8 +135,7 @@ struct iwl_tx_info {
 struct iwl_tx_queue {
 	struct iwl_queue q;
 	struct iwl_tfd_frame *bd;
-	struct iwl_cmd *cmd;
-	dma_addr_t dma_addr_cmd;
+	struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
 	struct iwl_tx_info *txb;
 	int need_update;
 	int sched_retry;
@@ -191,7 +191,6 @@ struct iwl4965_clip_group {
 	const s8 clip_powers[IWL_MAX_RATES];
 };
 
-#include "iwl-4965-rs.h"
 
 #define IWL_TX_FIFO_AC0	0
 #define IWL_TX_FIFO_AC1	1
@@ -219,7 +218,7 @@ enum iwl_pwr_src {
 struct iwl_frame {
 	union {
 		struct ieee80211_hdr frame;
-		struct iwl4965_tx_beacon_cmd beacon;
+		struct iwl_tx_beacon_cmd beacon;
 		u8 raw[IEEE80211_FRAME_LEN];
 		u8 cmd[360];
 	} u;
@@ -283,10 +282,9 @@ struct iwl_cmd {
 		u32 val32;
 		struct iwl4965_bt_cmd bt;
 		struct iwl4965_rxon_time_cmd rxon_time;
-		struct iwl4965_powertable_cmd powertable;
+		struct iwl_powertable_cmd powertable;
 		struct iwl_qosparam_cmd qosparam;
 		struct iwl_tx_cmd tx;
-		struct iwl4965_tx_beacon_cmd tx_beacon;
 		struct iwl4965_rxon_assoc_cmd rxon_assoc;
 		struct iwl_rem_sta_cmd rm_sta;
 		u8 *indirect;
@@ -590,6 +588,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
 					const u8 *dest, int left);
 extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
 int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
+extern int iwl4965_set_power(struct iwl_priv *priv, void *cmd);
 
 extern const u8 iwl_bcast_addr[ETH_ALEN];
 
@@ -642,10 +641,6 @@ struct iwl_priv;
  * Forward declare iwl-4965.c functions for iwl-base.c
  */
 extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
-
-int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
-				    enum ieee80211_ampdu_mlme_action action,
-				    const u8 *addr, u16 tid, u16 *ssn);
 int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
 					u8 tid, int txq_id);
 
@@ -812,14 +807,11 @@ struct iwl_chain_noise_data {
 #define EEPROM_SEM_RETRY_LIMIT 1000	/* number of attempts (not time) */
 
 
-#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
-
 enum {
 	MEASUREMENT_READY = (1 << 0),
 	MEASUREMENT_ACTIVE = (1 << 1),
 };
 
-#endif
 
 #define IWL_MAX_NUM_QUEUES	20 /* FIXME: do dynamic allocation */
 
@@ -844,7 +836,7 @@ struct iwl_priv {
 
 	struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
 
-#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
 	/* spectrum measurement report caching */
 	struct iwl4965_spectrum_notification measure_report;
 	u8 measurement_status;

+ 1 - 2
drivers/net/wireless/iwlwifi/iwl-eeprom.c

@@ -273,8 +273,7 @@ EXPORT_SYMBOL(iwl_eeprom_init);
 
 void iwl_eeprom_free(struct iwl_priv *priv)
 {
-	if(priv->eeprom)
-		kfree(priv->eeprom);
+	kfree(priv->eeprom);
 	priv->eeprom = NULL;
 }
 EXPORT_SYMBOL(iwl_eeprom_free);

+ 1 - 1
drivers/net/wireless/iwlwifi/iwl-hcmd.c

@@ -228,7 +228,7 @@ cancel:
 		 * TX cmd queue. Otherwise in case the cmd comes
 		 * in later, it will possibly set an invalid
 		 * address (cmd->meta.source). */
-		qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
+		qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
 		qcmd->meta.flags &= ~CMD_WANT_SKB;
 	}
 fail:

+ 41 - 28
drivers/net/wireless/iwlwifi/iwl-led.c

@@ -161,11 +161,31 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
 /* Set led register off */
 static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
 {
-	IWL_DEBUG_LED("radio off\n");
+	IWL_DEBUG_LED("LED Reg off\n");
 	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
 	return 0;
 }
 
+/*
+ * Set led register in case of disassociation according to rfkill state
+ */
+static int iwl_led_associate(struct iwl_priv *priv, int led_id)
+{
+	IWL_DEBUG_LED("Associated\n");
+	priv->allow_blinking = 1;
+	return iwl4965_led_on_reg(priv, led_id);
+}
+static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
+{
+	priv->allow_blinking = 0;
+	if (iwl_is_rfkill(priv))
+		iwl4965_led_off_reg(priv, led_id);
+	else
+		iwl4965_led_on_reg(priv, led_id);
+
+	return 0;
+}
+
 /*
  * brightness call back function for Tx/Rx LED
  */
@@ -199,16 +219,10 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
 			led_type_str[led->type], brightness);
 	switch (brightness) {
 	case LED_FULL:
-		if (led->type == IWL_LED_TRG_ASSOC)
-			priv->allow_blinking = 1;
-
 		if (led->led_on)
 			led->led_on(priv, IWL_LED_LINK);
 		break;
 	case LED_OFF:
-		if (led->type == IWL_LED_TRG_ASSOC)
-			priv->allow_blinking = 0;
-
 		if (led->led_off)
 			led->led_off(priv, IWL_LED_LINK);
 		break;
@@ -228,12 +242,12 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
  */
 static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
 				   enum led_type type, u8 set_led,
-				   const char *name, char *trigger)
+				   char *trigger)
 {
 	struct device *device = wiphy_dev(priv->hw->wiphy);
 	int ret;
 
-	led->led_dev.name = name;
+	led->led_dev.name = led->name;
 	led->led_dev.brightness_set = iwl_led_brightness_set;
 	led->led_dev.default_trigger = trigger;
 
@@ -284,12 +298,6 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
 	return i;
 }
 
-static inline int is_rf_kill(struct iwl_priv *priv)
-{
-	return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
-		test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
 /*
  * this function called from handler. Since setting Led command can
  * happen very frequent we postpone led command to be called from
@@ -303,7 +311,7 @@ void iwl_leds_background(struct iwl_priv *priv)
 		priv->last_blink_time = 0;
 		return;
 	}
-	if (is_rf_kill(priv)) {
+	if (iwl_is_rfkill(priv)) {
 		priv->last_blink_time = 0;
 		return;
 	}
@@ -337,7 +345,6 @@ EXPORT_SYMBOL(iwl_leds_background);
 int iwl_leds_register(struct iwl_priv *priv)
 {
 	char *trigger;
-	char name[32];
 	int ret;
 
 	priv->last_blink_rate = 0;
@@ -346,7 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv)
 	priv->allow_blinking = 0;
 
 	trigger = ieee80211_get_radio_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:radio",
+	snprintf(priv->led[IWL_LED_TRG_RADIO].name,
+		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
 		 wiphy_name(priv->hw->wiphy));
 
 	priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
@@ -354,31 +362,33 @@ int iwl_leds_register(struct iwl_priv *priv)
 	priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
 
 	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
-				   IWL_LED_TRG_RADIO, 1, name, trigger);
+				   IWL_LED_TRG_RADIO, 1, trigger);
 	if (ret)
 		goto exit_fail;
 
 	trigger = ieee80211_get_assoc_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:assoc",
+	snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
+		 sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
 		 wiphy_name(priv->hw->wiphy));
 
 	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
-				   IWL_LED_TRG_ASSOC, 0, name, trigger);
+				   IWL_LED_TRG_ASSOC, 0, trigger);
 
 	/* for assoc always turn led on */
-	priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg;
-	priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg;
+	priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
+	priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
 	priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
 
 	if (ret)
 		goto exit_fail;
 
 	trigger = ieee80211_get_rx_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:RX", wiphy_name(priv->hw->wiphy));
-
+	snprintf(priv->led[IWL_LED_TRG_RX].name,
+		 sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
+		 wiphy_name(priv->hw->wiphy));
 
 	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
-				   IWL_LED_TRG_RX, 0, name, trigger);
+				   IWL_LED_TRG_RX, 0, trigger);
 
 	priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
 	priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
@@ -388,9 +398,12 @@ int iwl_leds_register(struct iwl_priv *priv)
 		goto exit_fail;
 
 	trigger = ieee80211_get_tx_led_name(priv->hw);
-	snprintf(name, sizeof(name), "iwl-%s:TX", wiphy_name(priv->hw->wiphy));
+	snprintf(priv->led[IWL_LED_TRG_TX].name,
+		 sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
+		 wiphy_name(priv->hw->wiphy));
+
 	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
-				   IWL_LED_TRG_TX, 0, name, trigger);
+				   IWL_LED_TRG_TX, 0, trigger);
 
 	priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
 	priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;

+ 1 - 0
drivers/net/wireless/iwlwifi/iwl-led.h

@@ -52,6 +52,7 @@ enum led_type {
 struct iwl_led {
 	struct iwl_priv *priv;
 	struct led_classdev led_dev;
+	char name[32];
 
 	int (*led_on) (struct iwl_priv *priv, int led_id);
 	int (*led_off) (struct iwl_priv *priv, int led_id);

+ 28 - 17
drivers/net/wireless/iwlwifi/iwl-power.c

@@ -82,7 +82,7 @@
 
 /* default power management (not Tx power) table values */
 /* for tim  0-10 */
-static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
+static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
 	{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
@@ -93,7 +93,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
 
 
 /* for tim = 3-10 */
-static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
+static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
 	{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
@@ -103,7 +103,7 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
 };
 
 /* for tim > 11 */
-static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = {
+static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
 	{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
@@ -112,12 +112,19 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = {
 	{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
 };
 
+/* set card power command */
+static int iwl_set_power(struct iwl_priv *priv, void *cmd)
+{
+	return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
+				      sizeof(struct iwl_powertable_cmd),
+				      cmd, NULL);
+}
 /* decide the right power level according to association status
  * and battery status
  */
 static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
 {
-	u16 mode = priv->power_data.user_power_setting;
+	u16 mode;
 
 	switch (priv->power_data.user_power_setting) {
 	case IWL_POWER_AUTO:
@@ -129,12 +136,16 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
 		else
 			mode = IWL_POWER_ON_AC_DISASSOC;
 		break;
+	/* FIXME: remove battery and ac from here */
 	case IWL_POWER_BATTERY:
 		mode = IWL_POWER_INDEX_3;
 		break;
 	case IWL_POWER_AC:
 		mode = IWL_POWER_MODE_CAM;
 		break;
+	default:
+		mode = priv->power_data.user_power_setting;
+		break;
 	}
 	return mode;
 }
@@ -144,7 +155,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
 {
 	int ret = 0, i;
 	struct iwl_power_mgr *pow_data;
-	int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC;
+	int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
 	u16 pci_pm;
 
 	IWL_DEBUG_POWER("Initialize power \n");
@@ -162,11 +173,11 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
 	if (ret != 0)
 		return 0;
 	else {
-		struct iwl4965_powertable_cmd *cmd;
+		struct iwl_powertable_cmd *cmd;
 
 		IWL_DEBUG_POWER("adjust power command flags\n");
 
-		for (i = 0; i < IWL_POWER_AC; i++) {
+		for (i = 0; i < IWL_POWER_MAX; i++) {
 			cmd = &pow_data->pwr_range_0[i].cmd;
 
 			if (pci_pm & 0x1)
@@ -180,7 +191,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
 
 /* adjust power command according to dtim period and power level*/
 static int iwl_update_power_command(struct iwl_priv *priv,
-				    struct iwl4965_powertable_cmd *cmd,
+				    struct iwl_powertable_cmd *cmd,
 				    u16 mode)
 {
 	int ret = 0, i;
@@ -204,7 +215,7 @@ static int iwl_update_power_command(struct iwl_priv *priv,
 		range = &pow_data->pwr_range_2[0];
 
 	period = pow_data->dtim_period;
-	memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd));
+	memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd));
 
 	if (period == 0) {
 		period = 1;
@@ -258,17 +269,18 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
 	* else user level */
 
 	switch (setting->system_power_setting) {
-	case IWL_POWER_AUTO:
+	case IWL_POWER_SYS_AUTO:
 		final_mode = iwl_get_auto_power_mode(priv);
 		break;
-	case IWL_POWER_BATTERY:
+	case IWL_POWER_SYS_BATTERY:
 		final_mode = IWL_POWER_INDEX_3;
 		break;
-	case IWL_POWER_AC:
+	case IWL_POWER_SYS_AC:
 		final_mode = IWL_POWER_MODE_CAM;
 		break;
 	default:
-		final_mode = setting->system_power_setting;
+		final_mode = IWL_POWER_INDEX_3;
+		WARN_ON(1);
 	}
 
 	if (setting->critical_power_setting > final_mode)
@@ -280,7 +292,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
 
 	if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
 	    ((setting->power_mode != final_mode) || refresh)) {
-		struct iwl4965_powertable_cmd cmd;
+		struct iwl_powertable_cmd cmd;
 
 		if (final_mode != IWL_POWER_MODE_CAM)
 			set_bit(STATUS_POWER_PMI, &priv->status);
@@ -291,8 +303,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
 		if (final_mode == IWL_POWER_INDEX_5)
 			cmd.flags |= IWL_POWER_FAST_PD;
 
-		if (priv->cfg->ops->lib->set_power)
-			ret = priv->cfg->ops->lib->set_power(priv, &cmd);
+		ret = iwl_set_power(priv, &cmd);
 
 		if (final_mode == IWL_POWER_MODE_CAM)
 			clear_bit(STATUS_POWER_PMI, &priv->status);
@@ -388,7 +399,7 @@ void iwl_power_initialize(struct iwl_priv *priv)
 	iwl_power_init_handle(priv);
 	priv->power_data.user_power_setting = IWL_POWER_AUTO;
 	priv->power_data.power_disabled = 0;
-	priv->power_data.system_power_setting = IWL_POWER_AUTO;
+	priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
 	priv->power_data.is_battery_active = 0;
 	priv->power_data.power_disabled = 0;
 	priv->power_data.critical_power_setting = 0;

+ 23 - 10
drivers/net/wireless/iwlwifi/iwl-power.h

@@ -33,12 +33,25 @@
 
 struct iwl_priv;
 
-#define IWL_POWER_MODE_CAM	0x00    /* Continuously Aware Mode, always on */
-#define IWL_POWER_INDEX_3	0x03
-#define IWL_POWER_INDEX_5	0x05
-#define IWL_POWER_AC		0x06
-#define IWL_POWER_BATTERY	0x07
-#define IWL_POWER_AUTO		0x08
+enum {
+	IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */
+	IWL_POWER_INDEX_1,
+	IWL_POWER_INDEX_2,
+	IWL_POWER_INDEX_3,
+	IWL_POWER_INDEX_4,
+	IWL_POWER_INDEX_5,
+	IWL_POWER_AUTO,
+	IWL_POWER_MAX = IWL_POWER_AUTO,
+	IWL_POWER_AC,
+	IWL_POWER_BATTERY,
+};
+
+enum {
+	IWL_POWER_SYS_AUTO,
+	IWL_POWER_SYS_AC,
+	IWL_POWER_SYS_BATTERY,
+};
+
 #define IWL_POWER_LIMIT		0x08
 #define IWL_POWER_MASK		0x0F
 #define IWL_POWER_ENABLED	0x10
@@ -46,15 +59,15 @@ struct iwl_priv;
 /* Power management (not Tx power) structures */
 
 struct iwl_power_vec_entry {
-	struct iwl4965_powertable_cmd cmd;
+	struct iwl_powertable_cmd cmd;
 	u8 no_dtim;
 };
 
 struct iwl_power_mgr {
 	spinlock_t lock;
-	struct iwl_power_vec_entry pwr_range_0[IWL_POWER_AC];
-	struct iwl_power_vec_entry pwr_range_1[IWL_POWER_AC];
-	struct iwl_power_vec_entry pwr_range_2[IWL_POWER_AC];
+	struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];
+	struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];
+	struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
 	u32 dtim_period;
 	/* final power level that used to calculate final power command */
 	u8 power_mode;

+ 7 - 5
drivers/net/wireless/iwlwifi/iwl-prph.h

@@ -84,14 +84,16 @@
 #define APMG_CLK_VAL_DMA_CLK_RQT	(0x00000200)
 #define APMG_CLK_VAL_BSM_CLK_RQT	(0x00000800)
 
-#define APMG_PS_CTRL_VAL_RESET_REQ	(0x04000000)
 
-#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS	(0x00000800)
+#define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS	(0x00400000)
+#define APMG_PS_CTRL_VAL_RESET_REQ		(0x04000000)
+#define APMG_PS_CTRL_MSK_PWR_SRC		(0x03000000)
+#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN		(0x00000000)
+#define APMG_PS_CTRL_VAL_PWR_SRC_MAX		(0x01000000) /* 3945 only */
+#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX		(0x02000000)
 
-#define APMG_PS_CTRL_MSK_PWR_SRC              (0x03000000)
-#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN        (0x00000000)
-#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX         (0x01000000)
 
+#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS		(0x00000800)
 
 /**
  * BSM (Bootstrap State Machine)

+ 16 - 43
drivers/net/wireless/iwlwifi/iwl-rx.c

@@ -791,7 +791,7 @@ static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
 
 static void iwl_add_radiotap(struct iwl_priv *priv,
 				 struct sk_buff *skb,
-				 struct iwl4965_rx_phy_res *rx_start,
+				 struct iwl_rx_phy_res *rx_start,
 				 struct ieee80211_rx_status *stats,
 				 u32 ampdu_status)
 {
@@ -1010,8 +1010,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 				       struct ieee80211_rx_status *stats)
 {
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-	struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
-	    (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
+	struct iwl_rx_phy_res *rx_start = (include_phy) ?
+	    (struct iwl_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
 	struct ieee80211_hdr *hdr;
 	u16 len;
 	__le32 *rx_end;
@@ -1020,7 +1020,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 	u32 ampdu_status_legacy;
 
 	if (!include_phy && priv->last_phy_res[0])
-		rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
+		rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
 
 	if (!rx_start) {
 		IWL_ERROR("MPDU frame without a PHY data\n");
@@ -1032,8 +1032,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 
 		len = le16_to_cpu(rx_start->byte_count);
 
-		rx_end = (__le32 *) ((u8 *) &pkt->u.raw[0] +
-				  sizeof(struct iwl4965_rx_phy_res) +
+		rx_end = (__le32 *)((u8 *) &pkt->u.raw[0] +
+				  sizeof(struct iwl_rx_phy_res) +
 				  rx_start->cfg_phy_cnt + len);
 
 	} else {
@@ -1084,40 +1084,13 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 }
 
 /* Calc max signal level (dBm) among 3 possible receivers */
-static int iwl_calc_rssi(struct iwl_priv *priv,
-			     struct iwl4965_rx_phy_res *rx_resp)
+static inline int iwl_calc_rssi(struct iwl_priv *priv,
+				struct iwl_rx_phy_res *rx_resp)
 {
-	/* data from PHY/DSP regarding signal strength, etc.,
-	 *   contents are always there, not configurable by host.  */
-	struct iwl4965_rx_non_cfg_phy *ncphy =
-	    (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy;
-	u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK)
-			>> IWL_AGC_DB_POS;
-
-	u32 valid_antennae =
-	    (le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK)
-			>> RX_PHY_FLAGS_ANTENNAE_OFFSET;
-	u8 max_rssi = 0;
-	u32 i;
-
-	/* Find max rssi among 3 possible receivers.
-	 * These values are measured by the digital signal processor (DSP).
-	 * They should stay fairly constant even as the signal strength varies,
-	 *   if the radio's automatic gain control (AGC) is working right.
-	 * AGC value (see below) will provide the "interesting" info. */
-	for (i = 0; i < 3; i++)
-		if (valid_antennae & (1 << i))
-			max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
-
-	IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
-		ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
-		max_rssi, agc);
-
-	/* dBm = max_rssi dB - agc dB - constant.
-	 * Higher AGC (higher radio gain) means lower signal. */
-	return max_rssi - agc - IWL_RSSI_OFFSET;
+	return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
 }
 
+
 static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
 {
 	unsigned long flags;
@@ -1180,9 +1153,9 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
 	 *   this rx packet for legacy frames,
 	 *   or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
 	int include_phy = (pkt->hdr.cmd == REPLY_RX);
-	struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
-		(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
-		(struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
+	struct iwl_rx_phy_res *rx_start = (include_phy) ?
+		(struct iwl_rx_phy_res *)&(pkt->u.raw[0]) :
+		(struct iwl_rx_phy_res *)&priv->last_phy_res[1];
 	__le32 *rx_end;
 	unsigned int len = 0;
 	u16 fc;
@@ -1210,7 +1183,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
 
 	if (!include_phy) {
 		if (priv->last_phy_res[0])
-			rx_start = (struct iwl4965_rx_phy_res *)
+			rx_start = (struct iwl_rx_phy_res *)
 				&priv->last_phy_res[1];
 		else
 			rx_start = NULL;
@@ -1227,7 +1200,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
 
 		len = le16_to_cpu(rx_start->byte_count);
 		rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
-				  sizeof(struct iwl4965_rx_phy_res) + len);
+				  sizeof(struct iwl_rx_phy_res) + len);
 	} else {
 		struct iwl4965_rx_mpdu_res_start *amsdu =
 			(struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
@@ -1316,6 +1289,6 @@ void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 	priv->last_phy_res[0] = 1;
 	memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
-	       sizeof(struct iwl4965_rx_phy_res));
+	       sizeof(struct iwl_rx_phy_res));
 }
 EXPORT_SYMBOL(iwl_rx_reply_rx_phy);

+ 1 - 0
drivers/net/wireless/iwlwifi/iwl-scan.c

@@ -202,6 +202,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
 		clear_bit(STATUS_SCAN_HW, &priv->status);
 	}
 
+	priv->alloc_rxb_skb--;
 	dev_kfree_skb_any(cmd.meta.u.skb);
 
 	return ret;

+ 2 - 2
drivers/net/wireless/iwlwifi/iwl-sta.c

@@ -823,7 +823,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
 	if (lq->sta_id == 0xFF)
 		lq->sta_id = IWL_AP_ID;
 
-	iwl_dump_lq_cmd(priv,lq);
+	iwl_dump_lq_cmd(priv, lq);
 
 	if (iwl_is_associated(priv) && priv->assoc_station_added)
 		return  iwl_send_cmd(priv, &cmd);
@@ -839,7 +839,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
  * for automatic fallback during transmission.
  *
  * NOTE: This sets up a default set of values.  These will be replaced later
- *       if the driver's iwl-4965-rs rate scaling algorithm is used, instead of
+ *       if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
  *       rc80211_simple.
  *
  * NOTE: Run REPLY_ADD_STA command to set up station table entry, before

+ 59 - 27
drivers/net/wireless/iwlwifi/iwl-tx.c

@@ -208,11 +208,12 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
  * Free all buffers.
  * 0-fill, but do not free "txq" descriptor structure.
  */
-static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
 {
+	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct iwl_queue *q = &txq->q;
 	struct pci_dev *dev = priv->pci_dev;
-	int len;
+	int i, slots_num, len;
 
 	if (q->n_bd == 0)
 		return;
@@ -227,7 +228,12 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 		len += IWL_MAX_SCAN_SIZE;
 
 	/* De-alloc array of command/tx buffers */
-	pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
+	slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
+			TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+	for (i = 0; i < slots_num; i++)
+		kfree(txq->cmd[i]);
+	if (txq_id == IWL_CMD_QUEUE_NUM)
+		kfree(txq->cmd[slots_num]);
 
 	/* De-alloc circular buffer of TFDs */
 	if (txq->q.n_bd)
@@ -400,8 +406,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
 			     struct iwl_tx_queue *txq,
 			     int slots_num, u32 txq_id)
 {
-	struct pci_dev *dev = priv->pci_dev;
-	int len;
+	int i, len;
 	int rc = 0;
 
 	/*
@@ -412,17 +417,25 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
 	 * For normal Tx queues (all other queues), no super-size command
 	 * space is needed.
 	 */
-	len = sizeof(struct iwl_cmd) * slots_num;
-	if (txq_id == IWL_CMD_QUEUE_NUM)
-		len +=  IWL_MAX_SCAN_SIZE;
-	txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
-	if (!txq->cmd)
-		return -ENOMEM;
+	len = sizeof(struct iwl_cmd);
+	for (i = 0; i <= slots_num; i++) {
+		if (i == slots_num) {
+			if (txq_id == IWL_CMD_QUEUE_NUM)
+				len += IWL_MAX_SCAN_SIZE;
+			else
+				continue;
+		}
+
+		txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA);
+		if (!txq->cmd[i])
+			return -ENOMEM;
+	}
 
 	/* Alloc driver data array and TFD circular buffer */
 	rc = iwl_tx_queue_alloc(priv, txq, txq_id);
 	if (rc) {
-		pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
+		for (i = 0; i < slots_num; i++)
+			kfree(txq->cmd[i]);
 
 		return -ENOMEM;
 	}
@@ -451,7 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 
 	/* Tx queues */
 	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
-		iwl_tx_queue_free(priv, &priv->txq[txq_id]);
+		iwl_tx_queue_free(priv, txq_id);
 
 	/* Keep-warm buffer */
 	iwl_kw_free(priv);
@@ -859,7 +872,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	txq->txb[q->write_ptr].skb[0] = skb;
 
 	/* Set up first empty entry in queue's array of Tx/cmd buffers */
-	out_cmd = &txq->cmd[idx];
+	out_cmd = txq->cmd[idx];
 	tx_cmd = &out_cmd->cmd.tx;
 	memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
 	memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
@@ -899,8 +912,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 	/* Physical address of this Tx command's header (not MAC header!),
 	 * within command buffer array. */
-	txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx +
-		     offsetof(struct iwl_cmd, hdr);
+	txcmd_phys = pci_map_single(priv->pci_dev, out_cmd,
+				sizeof(struct iwl_cmd), PCI_DMA_TODEVICE);
+	txcmd_phys += offsetof(struct iwl_cmd, hdr);
 
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
@@ -962,16 +976,16 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	if (ret)
 		return ret;
 
-	if ((iwl_queue_space(q) < q->high_mark)
-	    && priv->mac80211_registered) {
+	if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
 		if (wait_write_ptr) {
 			spin_lock_irqsave(&priv->lock, flags);
 			txq->need_update = 1;
 			iwl_txq_update_write_ptr(priv, txq);
 			spin_unlock_irqrestore(&priv->lock, flags);
+		} else {
+			ieee80211_stop_queue(priv->hw,
+					     skb_get_queue_mapping(skb));
 		}
-
-		ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
 	}
 
 	return 0;
@@ -1004,7 +1018,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	u32 idx;
 	u16 fix_size;
 	dma_addr_t phys_addr;
-	int ret;
+	int len, ret;
 	unsigned long flags;
 
 	cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
@@ -1034,7 +1048,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	control_flags = (u32 *) tfd;
 
 	idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
-	out_cmd = &txq->cmd[idx];
+	out_cmd = txq->cmd[idx];
 
 	out_cmd->hdr.cmd = cmd->id;
 	memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
@@ -1048,9 +1062,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 			INDEX_TO_SEQ(q->write_ptr));
 	if (out_cmd->meta.flags & CMD_SIZE_HUGE)
 		out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
-
-	phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
-			offsetof(struct iwl_cmd, hdr);
+	len = (idx == TFD_CMD_SLOTS) ?
+			IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
+	phys_addr = pci_map_single(priv->pci_dev, out_cmd, len,
+						PCI_DMA_TODEVICE);
+	phys_addr += offsetof(struct iwl_cmd, hdr);
 	iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
 
 	IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
@@ -1115,6 +1131,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
 {
 	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct iwl_queue *q = &txq->q;
+	struct iwl_tfd_frame *bd = &txq->bd[index];
+	dma_addr_t dma_addr;
+	int is_odd, buf_len;
 	int nfreed = 0;
 
 	if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
@@ -1132,6 +1151,19 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
 					q->write_ptr, q->read_ptr);
 			queue_work(priv->workqueue, &priv->restart);
 		}
+		is_odd = (index/2) & 0x1;
+		if (is_odd) {
+			dma_addr = IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
+					(IWL_GET_BITS(bd->pa[index],
+							tb2_addr_hi20) << 16);
+			buf_len = IWL_GET_BITS(bd->pa[index], tb2_len);
+		} else {
+			dma_addr = le32_to_cpu(bd->pa[index].tb1_addr);
+			buf_len = IWL_GET_BITS(bd->pa[index], tb1_len);
+		}
+
+		pci_unmap_single(priv->pci_dev, dma_addr, buf_len,
+				 PCI_DMA_TODEVICE);
 		nfreed++;
 	}
 }
@@ -1163,7 +1195,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 	BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
 
 	cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
-	cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
+	cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
 
 	/* Input error checking is done when commands are added to queue. */
 	if (cmd->meta.flags & CMD_WANT_SKB) {
@@ -1391,7 +1423,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
 	/* For each frame attempted in aggregation,
 	 * update driver's record of tx frame's status. */
 	for (i = 0; i < agg->frame_count ; i++) {
-		ack = bitmap & (1 << i);
+		ack = bitmap & (1ULL << i);
 		successes += !!ack;
 		IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
 			ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,

+ 23 - 35
drivers/net/wireless/iwlwifi/iwl3945-base.c

@@ -275,10 +275,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
 	return 0;
 
  error:
-	if (txq->txb) {
-		kfree(txq->txb);
-		txq->txb = NULL;
-	}
+	kfree(txq->txb);
+	txq->txb = NULL;
 
 	return -ENOMEM;
 }
@@ -365,10 +363,8 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t
 				    txq->q.n_bd, txq->bd, txq->q.dma_addr);
 
 	/* De-alloc array of per-TFD driver data */
-	if (txq->txb) {
-		kfree(txq->txb);
-		txq->txb = NULL;
-	}
+	kfree(txq->txb);
+	txq->txb = NULL;
 
 	/* 0-fill queue descriptor structure */
 	memset(txq, 0, sizeof(*txq));
@@ -2703,9 +2699,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
 
 	if (!ieee80211_has_morefrags(hdr->frame_control)) {
 		txq->need_update = 1;
-		if (qc) {
+		if (qc)
 			priv->stations[sta_id].tid[tid].seq_number = seq_number;
-		}
 	} else {
 		wait_write_ptr = 1;
 		txq->need_update = 0;
@@ -3813,7 +3808,7 @@ int iwl3945_calc_db_from_ratio(int sig_ratio)
 	/* 100:1 or higher, divide by 10 and use table,
 	 *   add 20 dB to make up for divide by 10 */
 	if (sig_ratio >= 100)
-		return (20 + (int)ratio2dB[sig_ratio/10]);
+		return 20 + (int)ratio2dB[sig_ratio/10];
 
 	/* We shouldn't see this */
 	if (sig_ratio < 1)
@@ -5088,7 +5083,7 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
  * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
  *     looking at all data.
  */
-static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
 {
 	u32 val;
 	u32 save_len = len;
@@ -5237,7 +5232,7 @@ static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
 	val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
 	for (reg = BSM_SRAM_LOWER_BOUND;
 	     reg < BSM_SRAM_LOWER_BOUND + len;
-	     reg += sizeof(u32), image ++) {
+	     reg += sizeof(u32), image++) {
 		val = iwl3945_read_prph(priv, reg);
 		if (val != le32_to_cpu(*image)) {
 			IWL_ERROR("BSM uCode verification failed at "
@@ -6336,7 +6331,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
 	DECLARE_MAC_BUF(mac);
 
 	if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
-		IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
+		IWL_ERROR("%s Should not be called in AP mode\n", __func__);
 		return;
 	}
 
@@ -6417,7 +6412,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
 
 	default:
 		 IWL_ERROR("%s Should not be called in %d mode\n",
-			   __FUNCTION__, priv->iw_mode);
+			   __func__, priv->iw_mode);
 		break;
 	}
 
@@ -6594,12 +6589,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 
 	IWL_DEBUG_MAC80211("enter\n");
 
-	if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-		IWL_DEBUG_MAC80211("leave - monitor\n");
-		dev_kfree_skb_any(skb);
-		return 0;
-	}
-
 	IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
 		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
@@ -7456,7 +7445,7 @@ static ssize_t show_measurement(struct device *d,
 	struct iwl3945_priv *priv = dev_get_drvdata(d);
 	struct iwl3945_spectrum_notification measure_report;
 	u32 size = sizeof(measure_report), len = 0, ofs = 0;
-	u8 *data = (u8 *) & measure_report;
+	u8 *data = (u8 *)&measure_report;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
@@ -7627,7 +7616,7 @@ static ssize_t show_power_level(struct device *d,
 	else
 		p += sprintf(p, " \n");
 
-	return (p - buf + 1);
+	return p - buf + 1;
 
 }
 
@@ -7649,7 +7638,7 @@ static ssize_t show_statistics(struct device *d,
 	struct iwl3945_priv *priv = dev_get_drvdata(d);
 	u32 size = sizeof(struct iwl3945_notif_statistics);
 	u32 len = 0, ofs = 0;
-	u8 *data = (u8 *) & priv->statistics;
+	u8 *data = (u8 *)&priv->statistics;
 	int rc = 0;
 
 	if (!iwl3945_is_alive(priv))
@@ -8003,16 +7992,16 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
 	/* nic init */
 	iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
-                    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-        iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-        err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
-                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-        if (err < 0) {
-                IWL_DEBUG_INFO("Failed to init the card\n");
+			CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+	iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+	err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
+			       CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+			       CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+	if (err < 0) {
+		IWL_DEBUG_INFO("Failed to init the card\n");
 		goto out_remove_sysfs;
-        }
+	}
 	/* Read the EEPROM */
 	err = iwl3945_eeprom_init(priv);
 	if (err) {
@@ -8114,9 +8103,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 	iwl3945_unset_hw_setting(priv);
 	iwl3945_clear_stations_table(priv);
 
-	if (priv->mac80211_registered) {
+	if (priv->mac80211_registered)
 		ieee80211_unregister_hw(priv->hw);
-	}
 
 	/*netif_stop_queue(dev); */
 	flush_workqueue(priv->workqueue);

+ 9 - 6
drivers/net/wireless/libertas/main.c

@@ -297,9 +297,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
 			lbs_add_rtap(priv);
 		}
 		priv->monitormode = monitor_mode;
-	}
-
-	else {
+	} else {
 		if (!priv->monitormode)
 			return strlen(buf);
 		priv->monitormode = 0;
@@ -1242,8 +1240,6 @@ int lbs_start_card(struct lbs_private *priv)
 		lbs_pr_err("cannot register ethX device\n");
 		goto done;
 	}
-	if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
-		lbs_pr_err("cannot register lbs_rtap attribute\n");
 
 	lbs_update_channel(priv);
 
@@ -1275,6 +1271,13 @@ int lbs_start_card(struct lbs_private *priv)
 
 			if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
 				lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+			/* While rtap isn't related to mesh, only mesh-enabled
+			 * firmware implements the rtap functionality via
+			 * CMD_802_11_MONITOR_MODE.
+			 */
+			if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
+				lbs_pr_err("cannot register lbs_rtap attribute\n");
 		}
 	}
 
@@ -1306,9 +1309,9 @@ void lbs_stop_card(struct lbs_private *priv)
 	netif_carrier_off(priv->dev);
 
 	lbs_debugfs_remove_one(priv);
-	device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
 	if (priv->mesh_tlv) {
 		device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+		device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
 	}
 
 	/* Flush pending command nodes */

+ 1 - 0
drivers/net/wireless/p54/p54.h

@@ -52,6 +52,7 @@ struct p54_common {
 	int (*open)(struct ieee80211_hw *dev);
 	void (*stop)(struct ieee80211_hw *dev);
 	int mode;
+	struct mutex conf_mutex;
 	u8 mac_addr[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
 	struct pda_iq_autocal_entry *iq_autocal;

+ 6 - 0
drivers/net/wireless/p54/p54common.c

@@ -886,9 +886,12 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
 static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 {
 	int ret;
+	struct p54_common *priv = dev->priv;
 
+	mutex_lock(&priv->conf_mutex);
 	ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
 	p54_set_vdcf(dev);
+	mutex_unlock(&priv->conf_mutex);
 	return ret;
 }
 
@@ -898,10 +901,12 @@ static int p54_config_interface(struct ieee80211_hw *dev,
 {
 	struct p54_common *priv = dev->priv;
 
+	mutex_lock(&priv->conf_mutex);
 	p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642);
 	p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
 	p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
 	memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
 
@@ -1009,6 +1014,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
 	}
 
 	p54_init_vdcf(dev);
+	mutex_init(&priv->conf_mutex);
 
 	return dev;
 }

+ 1 - 1
drivers/net/wireless/prism54/isl_ioctl.c

@@ -2518,7 +2518,7 @@ enum {
 
 #define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
 #define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
-((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
+	offsetof(struct prism2_hostapd_param, u.generic_elem.data)
 
 /* Maximum length for algorithm names (-1 for nul termination)
  * used in ioctl() */

+ 1 - 0
drivers/net/wireless/rt2x00/rt2500pci.c

@@ -1220,6 +1220,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
 			   test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
+	rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
 	rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
 	rt2x00_desc_write(txd, 0, word);
 }

+ 17 - 3
drivers/net/wireless/rt2x00/rt2500usb.c

@@ -633,6 +633,16 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
 	rt2x00dev->link.vgc_level = value;
 }
 
+/*
+ * NOTE: This function is directly ported from legacy driver, but
+ * despite it being declared it was never called. Although link tuning
+ * sounds like a good idea, and usually works well for the other drivers,
+ * it does _not_ work with rt2500usb. Enabling this function will result
+ * in TX capabilities only until association kicks in. Immediately
+ * after the successful association all TX frames will be kept in the
+ * hardware queue and never transmitted.
+ */
+#if 0
 static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
 {
 	int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
@@ -752,6 +762,9 @@ dynamic_cca_tune:
 		rt2x00dev->link.vgc_level = r17;
 	}
 }
+#else
+#define rt2500usb_link_tuner	NULL
+#endif
 
 /*
  * Initialization functions.
@@ -1376,6 +1389,9 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 		rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp);
 		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word);
 		EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word);
+	} else {
+		rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp);
+		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word);
 	}
 
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &word);
@@ -1384,9 +1400,6 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 		rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41);
 		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word);
 		EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word);
-	} else {
-		rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp);
-		rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word);
 	}
 
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word);
@@ -1737,6 +1750,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 	__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
+	__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);
 
 	/*
 	 * Set the rssi offset.

+ 6 - 0
drivers/net/wireless/rt2x00/rt2x00.h

@@ -368,6 +368,12 @@ struct rt2x00_intf {
 #define DELAYED_CONFIG_ERP		0x00000002
 #define DELAYED_LED_ASSOC		0x00000004
 
+	/*
+	 * Software sequence counter, this is only required
+	 * for hardware which doesn't support hardware
+	 * sequence counting.
+	 */
+	spinlock_t seqlock;
 	u16 seqno;
 };
 

+ 4 - 0
drivers/net/wireless/rt2x00/rt2x00config.c

@@ -254,6 +254,8 @@ config:
 			libconf.ant.rx = default_ant->rx;
 		else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
 			libconf.ant.rx = ANTENNA_B;
+		else
+			libconf.ant.rx = active_ant->rx;
 
 		if (conf->antenna_sel_tx)
 			libconf.ant.tx = conf->antenna_sel_tx;
@@ -261,6 +263,8 @@ config:
 			libconf.ant.tx = default_ant->tx;
 		else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
 			libconf.ant.tx = ANTENNA_B;
+		else
+			libconf.ant.tx = active_ant->tx;
 	}
 
 	if (flags & CONFIG_UPDATE_SLOT_TIME) {

+ 7 - 10
drivers/net/wireless/rt2x00/rt2x00debug.c

@@ -372,9 +372,6 @@ static ssize_t rt2x00debug_write_##__name(struct file *file,	\
 	if (*offset)						\
 		return 0;					\
 								\
-	if (!capable(CAP_NET_ADMIN))				\
-		return -EPERM;					\
-								\
 	if (intf->offset_##__name >= debug->__name.word_count)	\
 		return -EINVAL;					\
 								\
@@ -454,7 +451,7 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name,
 	data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__);
 	blob->size = strlen(blob->data);
 
-	return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob);
+	return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
 }
 
 static struct dentry *rt2x00debug_create_file_chipset(const char *name,
@@ -482,7 +479,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
 	data += sprintf(data, "rf length: %d\n", debug->rf.word_count);
 	blob->size = strlen(blob->data);
 
-	return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob);
+	return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
 }
 
 void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
@@ -517,7 +514,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 	if (IS_ERR(intf->chipset_entry))
 		goto exit;
 
-	intf->dev_flags = debugfs_create_file("dev_flags", S_IRUGO,
+	intf->dev_flags = debugfs_create_file("dev_flags", S_IRUSR,
 					      intf->driver_folder, intf,
 					      &rt2x00debug_fop_dev_flags);
 	if (IS_ERR(intf->dev_flags))
@@ -532,7 +529,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 ({								\
 	(__intf)->__name##_off_entry =				\
 	    debugfs_create_u32(__stringify(__name) "_offset",	\
-			       S_IRUGO | S_IWUSR,		\
+			       S_IRUSR | S_IWUSR,		\
 			       (__intf)->register_folder,	\
 			       &(__intf)->offset_##__name);	\
 	if (IS_ERR((__intf)->__name##_off_entry))		\
@@ -540,7 +537,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 								\
 	(__intf)->__name##_val_entry =				\
 	    debugfs_create_file(__stringify(__name) "_value",	\
-				S_IRUGO | S_IWUSR,		\
+				S_IRUSR | S_IWUSR,		\
 				(__intf)->register_folder,	\
 				(__intf), &rt2x00debug_fop_##__name);\
 	if (IS_ERR((__intf)->__name##_val_entry))		\
@@ -560,7 +557,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 		goto exit;
 
 	intf->queue_frame_dump_entry =
-	    debugfs_create_file("dump", S_IRUGO, intf->queue_folder,
+	    debugfs_create_file("dump", S_IRUSR, intf->queue_folder,
 				intf, &rt2x00debug_fop_queue_dump);
 	if (IS_ERR(intf->queue_frame_dump_entry))
 		goto exit;
@@ -569,7 +566,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 	init_waitqueue_head(&intf->frame_dump_waitqueue);
 
 	intf->queue_stats_entry =
-	    debugfs_create_file("queue", S_IRUGO, intf->queue_folder,
+	    debugfs_create_file("queue", S_IRUSR, intf->queue_folder,
 				intf, &rt2x00debug_fop_queue_stats);
 
 	return;

+ 1 - 0
drivers/net/wireless/rt2x00/rt2x00mac.c

@@ -247,6 +247,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 		rt2x00dev->intf_sta_count++;
 
 	spin_lock_init(&intf->lock);
+	spin_lock_init(&intf->seqlock);
 	intf->beacon = entry;
 
 	if (conf->type == IEEE80211_IF_TYPE_AP)

+ 3 - 2
drivers/net/wireless/rt2x00/rt2x00queue.c

@@ -128,6 +128,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 	unsigned int data_length;
 	unsigned int duration;
 	unsigned int residual;
+	unsigned long irqflags;
 
 	memset(txdesc, 0, sizeof(*txdesc));
 
@@ -213,14 +214,14 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 	 * sequence counter given by mac80211.
 	 */
 	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-		spin_lock(&intf->lock);
+		spin_lock_irqsave(&intf->seqlock, irqflags);
 
 		if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
 			intf->seqno += 0x10;
 		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
 		hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
 
-		spin_unlock(&intf->lock);
+		spin_unlock_irqrestore(&intf->seqlock, irqflags);
 
 		__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
 	}

+ 2 - 2
drivers/net/wireless/rt2x00/rt2x00usb.c

@@ -124,7 +124,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
 
 int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
 					const u8 request, const u8 requesttype,
-					const u16 offset, void *buffer,
+					const u16 offset, const void *buffer,
 					const u16 buffer_length,
 					const int timeout)
 {
@@ -134,7 +134,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
 
 	mutex_lock(&rt2x00dev->usb_cache_mutex);
 
-	tb  = buffer;
+	tb  = (char *)buffer;
 	off = offset;
 	len = buffer_length;
 	while (len && !status) {

+ 1 - 1
drivers/net/wireless/rt2x00/rt2x00usb.h

@@ -185,7 +185,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
  */
 int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
 					const u8 request, const u8 requesttype,
-					const u16 offset, void *buffer,
+					const u16 offset, const void *buffer,
 					const u16 buffer_length,
 					const int timeout);
 

+ 5 - 0
drivers/net/wireless/rt2x00/rt61pci.c

@@ -1003,6 +1003,11 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
 		return -EBUSY;
 	}
 
+	/*
+	 * Hardware needs another millisecond before it is ready.
+	 */
+	msleep(1);
+
 	/*
 	 * Reset MAC and BBP registers.
 	 */

+ 4 - 0
drivers/net/wireless/rtl8187.h

@@ -94,6 +94,10 @@ struct rtl8187_priv {
 	const struct rtl818x_rf_ops *rf;
 	struct ieee80211_vif *vif;
 	int mode;
+	/* The mutex protects the TX loopback state.
+	 * Any attempt to set channels concurrently locks the device.
+	 */
+	struct mutex conf_mutex;
 
 	/* rtl8187 specific */
 	struct ieee80211_channel channels[14];

+ 16 - 1
drivers/net/wireless/rtl8187_dev.c

@@ -31,6 +31,8 @@ MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
 MODULE_LICENSE("GPL");
 
 static struct usb_device_id rtl8187_table[] __devinitdata = {
+	/* Asus */
+	{USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
 	/* Realtek */
 	{USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
 	{USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
@@ -726,6 +728,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 	if (ret)
 		return ret;
 
+	mutex_lock(&priv->conf_mutex);
 	if (priv->is_rtl8187b) {
 		reg = RTL818X_RX_CONF_MGMT |
 		      RTL818X_RX_CONF_DATA |
@@ -747,6 +750,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 				  (7 << 0  /* long retry limit */) |
 				  (7 << 21 /* MAX TX DMA */));
 		rtl8187_init_urbs(dev);
+		mutex_unlock(&priv->conf_mutex);
 		return 0;
 	}
 
@@ -790,6 +794,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 	reg |= RTL818X_CMD_TX_ENABLE;
 	reg |= RTL818X_CMD_RX_ENABLE;
 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+	mutex_unlock(&priv->conf_mutex);
 
 	return 0;
 }
@@ -801,6 +806,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
 	struct sk_buff *skb;
 	u32 reg;
 
+	mutex_lock(&priv->conf_mutex);
 	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
 
 	reg = rtl818x_ioread8(priv, &priv->map->CMD);
@@ -820,7 +826,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
 		usb_kill_urb(info->urb);
 		kfree_skb(skb);
 	}
-	return;
+	mutex_unlock(&priv->conf_mutex);
 }
 
 static int rtl8187_add_interface(struct ieee80211_hw *dev,
@@ -840,6 +846,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
 		return -EOPNOTSUPP;
 	}
 
+	mutex_lock(&priv->conf_mutex);
 	priv->vif = conf->vif;
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -848,6 +855,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
 				 ((u8 *)conf->mac_addr)[i]);
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
+	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
 
@@ -855,8 +863,10 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
 				     struct ieee80211_if_init_conf *conf)
 {
 	struct rtl8187_priv *priv = dev->priv;
+	mutex_lock(&priv->conf_mutex);
 	priv->mode = IEEE80211_IF_TYPE_MNTR;
 	priv->vif = NULL;
+	mutex_unlock(&priv->conf_mutex);
 }
 
 static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
@@ -864,6 +874,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 	struct rtl8187_priv *priv = dev->priv;
 	u32 reg;
 
+	mutex_lock(&priv->conf_mutex);
 	reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
 	/* Enable TX loopback on MAC level to avoid TX during channel
 	 * changes, as this has be seen to causes problems and the
@@ -896,6 +907,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 	rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
 	rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
 	rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
+	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
 
@@ -907,6 +919,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
 	int i;
 	u8 reg;
 
+	mutex_lock(&priv->conf_mutex);
 	for (i = 0; i < ETH_ALEN; i++)
 		rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
 
@@ -920,6 +933,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
 		rtl818x_iowrite8(priv, &priv->map->MSR, reg);
 	}
 
+	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
 
@@ -1187,6 +1201,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
 		printk(KERN_ERR "rtl8187: Cannot register device\n");
 		goto err_free_dev;
 	}
+	mutex_init(&priv->conf_mutex);
 
 	printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
 	       wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),

+ 13 - 0
include/linux/ieee80211.h

@@ -506,6 +506,19 @@ struct ieee80211_channel_sw_ie {
 	u8 count;
 } __attribute__ ((packed));
 
+/**
+ * struct ieee80211_tim
+ *
+ * This structure refers to "Traffic Indication Map information element"
+ */
+struct ieee80211_tim_ie {
+	u8 dtim_count;
+	u8 dtim_period;
+	u8 bitmap_ctrl;
+	/* variable size: 1 - 251 bytes */
+	u8 virtual_map[0];
+} __attribute__ ((packed));
+
 struct ieee80211_mgmt {
 	__le16 frame_control;
 	__le16 duration;

+ 1 - 3
include/linux/netdevice.h

@@ -61,9 +61,7 @@ struct wireless_dev;
 #define NET_XMIT_DROP		1	/* skb dropped			*/
 #define NET_XMIT_CN		2	/* congestion notification	*/
 #define NET_XMIT_POLICED	3	/* skb is shot by police	*/
-#define NET_XMIT_BYPASS		4	/* packet does not leave via dequeue;
-					   (TC use only - dev_queue_xmit
-					   returns this as NET_XMIT_SUCCESS) */
+#define NET_XMIT_MASK		0xFFFF	/* qdisc flags in net/sch_generic.h */
 
 /* Backlog congestion levels */
 #define NET_RX_SUCCESS		0   /* keep 'em coming, baby */

+ 1 - 11
include/net/dst.h

@@ -252,17 +252,7 @@ static inline int dst_output(struct sk_buff *skb)
 /* Input packet from network to transport.  */
 static inline int dst_input(struct sk_buff *skb)
 {
-	int err;
-
-	for (;;) {
-		err = skb->dst->input(skb);
-
-		if (likely(err == 0))
-			return err;
-		/* Oh, Jamal... Seems, I will not forgive you this mess. :-) */
-		if (unlikely(err != NET_XMIT_BYPASS))
-			return err;
-	}
+	return skb->dst->input(skb);
 }
 
 static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)

+ 0 - 1
include/net/flow.h

@@ -47,7 +47,6 @@ struct flowi {
 #define fl4_scope	nl_u.ip4_u.scope
 
 	__u8	proto;
-	__u8	flags;
 	union {
 		struct {
 			__be16	sport;

+ 11 - 2
include/net/mac80211.h

@@ -177,9 +177,10 @@ enum ieee80211_bss_change {
  * @aid: association ID number, valid only when @assoc is true
  * @use_cts_prot: use CTS protection
  * @use_short_preamble: use 802.11b short preamble
+ * @dtim_period: num of beacons before the next DTIM, for PSM
  * @timestamp: beacon timestamp
  * @beacon_int: beacon interval
- * @assoc_capability: capabbilities taken from assoc resp
+ * @assoc_capability: capabilities taken from assoc resp
  * @assoc_ht: association in HT mode
  * @ht_conf: ht capabilities
  * @ht_bss_conf: ht extended capabilities
@@ -191,6 +192,7 @@ struct ieee80211_bss_conf {
 	/* erp related data */
 	bool use_cts_prot;
 	bool use_short_preamble;
+	u8 dtim_period;
 	u16 beacon_int;
 	u16 assoc_capability;
 	u64 timestamp;
@@ -430,6 +432,7 @@ enum ieee80211_conf_flags {
  * @radio_enabled: when zero, driver is required to switch off the radio.
  *	TODO make a flag
  * @beacon_int: beacon interval (TODO make interface config)
+ * @listen_interval: listen interval in units of beacon interval
  * @flags: configuration flags defined above
  * @power_level: requested transmit power (in dBm)
  * @max_antenna_gain: maximum antenna gain (in dBi)
@@ -444,6 +447,7 @@ struct ieee80211_conf {
 	int radio_enabled;
 
 	int beacon_int;
+	u16 listen_interval;
 	u32 flags;
 	int power_level;
 	int max_antenna_gain;
@@ -785,6 +789,9 @@ enum ieee80211_hw_flags {
  * @max_signal: Maximum value for signal (rssi) in RX information, used
  *     only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB
  *
+ * @max_listen_interval: max listen interval in units of beacon interval
+ *     that HW supports
+ *
  * @queues: number of available hardware transmit queues for
  *	data packets. WMM/QoS requires at least four, these
  *	queues need to have configurable access parameters.
@@ -812,7 +819,9 @@ struct ieee80211_hw {
 	unsigned int extra_tx_headroom;
 	int channel_change_time;
 	int vif_data_size;
-	u16 queues, ampdu_queues;
+	u16 queues;
+	u16 ampdu_queues;
+	u16 max_listen_interval;
 	s8 max_signal;
 };
 

+ 25 - 1
include/net/sch_generic.h

@@ -193,10 +193,22 @@ static inline struct Qdisc *qdisc_root(struct Qdisc *qdisc)
 	return qdisc->dev_queue->qdisc;
 }
 
+/* The qdisc root lock is a mechanism by which to top level
+ * of a qdisc tree can be locked from any qdisc node in the
+ * forest.  This allows changing the configuration of some
+ * aspect of the qdisc tree while blocking out asynchronous
+ * qdisc access in the packet processing paths.
+ *
+ * It is only legal to do this when the root will not change
+ * on us.  Otherwise we'll potentially lock the wrong qdisc
+ * root.  This is enforced by holding the RTNL semaphore, which
+ * all users of this lock accessor must do.
+ */
 static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc)
 {
 	struct Qdisc *root = qdisc_root(qdisc);
 
+	ASSERT_RTNL();
 	return qdisc_lock(root);
 }
 
@@ -331,6 +343,18 @@ static inline unsigned int qdisc_pkt_len(struct sk_buff *skb)
 	return qdisc_skb_cb(skb)->pkt_len;
 }
 
+/* additional qdisc xmit flags (NET_XMIT_MASK in linux/netdevice.h) */
+enum net_xmit_qdisc_t {
+	__NET_XMIT_STOLEN = 0x00010000,
+	__NET_XMIT_BYPASS = 0x00020000,
+};
+
+#ifdef CONFIG_NET_CLS_ACT
+#define net_xmit_drop_count(e)	((e) & __NET_XMIT_STOLEN ? 0 : 1)
+#else
+#define net_xmit_drop_count(e)	(1)
+#endif
+
 static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
 #ifdef CONFIG_NET_SCHED
@@ -343,7 +367,7 @@ static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch)
 {
 	qdisc_skb_cb(skb)->pkt_len = skb->len;
-	return qdisc_enqueue(skb, sch);
+	return qdisc_enqueue(skb, sch) & NET_XMIT_MASK;
 }
 
 static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,

+ 1 - 2
include/net/sctp/structs.h

@@ -524,8 +524,7 @@ static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id,
  */
 struct sctp_af {
 	int		(*sctp_xmit)	(struct sk_buff *skb,
-					 struct sctp_transport *,
-					 int ipfragok);
+					 struct sctp_transport *);
 	int		(*setsockopt)	(struct sock *sk,
 					 int level,
 					 int optname,

+ 4 - 10
net/ax25/sysctl_net_ax25.c

@@ -36,6 +36,7 @@ static struct ctl_path ax25_path[] = {
 	{ .procname = "ax25", .ctl_name = NET_AX25, },
 	{ }
 };
+
 static const ctl_table ax25_param_table[] = {
 	{
 		.ctl_name	= NET_AX25_IP_DEFAULT_MODE,
@@ -167,6 +168,7 @@ static const ctl_table ax25_param_table[] = {
 		.extra1		= &min_proto,
 		.extra2		= &max_proto
 	},
+#ifdef CONFIG_AX25_DAMA_SLAVE
 	{
 		.ctl_name	= NET_AX25_DAMA_SLAVE_TIMEOUT,
 		.procname	= "dama_slave_timeout",
@@ -177,6 +179,8 @@ static const ctl_table ax25_param_table[] = {
 		.extra1		= &min_ds_timeout,
 		.extra2		= &max_ds_timeout
 	},
+#endif
+
 	{ .ctl_name = 0 }	/* that's all, folks! */
 };
 
@@ -210,16 +214,6 @@ void ax25_register_sysctl(void)
 		ax25_table[n].procname     = ax25_dev->dev->name;
 		ax25_table[n].mode         = 0555;
 
-#ifndef CONFIG_AX25_DAMA_SLAVE
-		/*
-		 * We do not wish to have a representation of this parameter
-		 * in /proc/sys/ when configured *not* to include the
-		 * AX.25 DAMA slave code, do we?
-		 */
-
-		child[AX25_VALUES_DS_TIMEOUT].procname = NULL;
-#endif
-
 		child[AX25_MAX_VALUES].ctl_name = 0;	/* just in case... */
 
 		for (k = 0; k < AX25_MAX_VALUES; k++)

+ 1 - 1
net/bridge/br_netfilter.c

@@ -113,7 +113,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
 	struct rtable *rt = &br->fake_rtable;
 
 	atomic_set(&rt->u.dst.__refcnt, 1);
-	rt->u.dst.dev = &br->dev;
+	rt->u.dst.dev = br->dev;
 	rt->u.dst.path = &rt->u.dst;
 	rt->u.dst.metrics[RTAX_MTU - 1] = 1500;
 	rt->u.dst.flags	= DST_NOXFRM;

+ 18 - 7
net/bridge/br_stp.c

@@ -368,14 +368,25 @@ static void br_make_blocking(struct net_bridge_port *p)
 /* called under bridge lock */
 static void br_make_forwarding(struct net_bridge_port *p)
 {
-	if (p->state == BR_STATE_BLOCKING) {
-		if (p->br->stp_enabled == BR_KERNEL_STP)
-			p->state = BR_STATE_LISTENING;
-		else
-			p->state = BR_STATE_LEARNING;
+	struct net_bridge *br = p->br;
 
-		br_log_state(p);
-		mod_timer(&p->forward_delay_timer, jiffies + p->br->forward_delay);	}
+	if (p->state != BR_STATE_BLOCKING)
+		return;
+
+	if (br->forward_delay == 0) {
+		p->state = BR_STATE_FORWARDING;
+		br_topology_change_detection(br);
+		del_timer(&p->forward_delay_timer);
+	}
+	else if (p->br->stp_enabled == BR_KERNEL_STP)
+		p->state = BR_STATE_LISTENING;
+	else
+		p->state = BR_STATE_LEARNING;
+
+	br_log_state(p);
+
+	if (br->forward_delay != 0)
+		mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay);
 }
 
 /* called under bridge lock */

+ 22 - 10
net/core/dev.c

@@ -1796,7 +1796,7 @@ gso:
 	skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
 #endif
 	if (q->enqueue) {
-		spinlock_t *root_lock = qdisc_root_lock(q);
+		spinlock_t *root_lock = qdisc_lock(q);
 
 		spin_lock(root_lock);
 
@@ -1805,7 +1805,6 @@ gso:
 
 		spin_unlock(root_lock);
 
-		rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
 		goto out;
 	}
 
@@ -1909,7 +1908,6 @@ int netif_rx(struct sk_buff *skb)
 	if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
 		if (queue->input_pkt_queue.qlen) {
 enqueue:
-			dev_hold(skb->dev);
 			__skb_queue_tail(&queue->input_pkt_queue, skb);
 			local_irq_restore(flags);
 			return NET_RX_SUCCESS;
@@ -1995,7 +1993,7 @@ static void net_tx_action(struct softirq_action *h)
 			smp_mb__before_clear_bit();
 			clear_bit(__QDISC_STATE_SCHED, &q->state);
 
-			root_lock = qdisc_root_lock(q);
+			root_lock = qdisc_lock(q);
 			if (spin_trylock(root_lock)) {
 				qdisc_run(q);
 				spin_unlock(root_lock);
@@ -2270,6 +2268,20 @@ out:
 	return ret;
 }
 
+/* Network device is going away, flush any packets still pending  */
+static void flush_backlog(void *arg)
+{
+	struct net_device *dev = arg;
+	struct softnet_data *queue = &__get_cpu_var(softnet_data);
+	struct sk_buff *skb, *tmp;
+
+	skb_queue_walk_safe(&queue->input_pkt_queue, skb, tmp)
+		if (skb->dev == dev) {
+			__skb_unlink(skb, &queue->input_pkt_queue);
+			kfree_skb(skb);
+		}
+}
+
 static int process_backlog(struct napi_struct *napi, int quota)
 {
 	int work = 0;
@@ -2279,7 +2291,6 @@ static int process_backlog(struct napi_struct *napi, int quota)
 	napi->weight = weight_p;
 	do {
 		struct sk_buff *skb;
-		struct net_device *dev;
 
 		local_irq_disable();
 		skb = __skb_dequeue(&queue->input_pkt_queue);
@@ -2288,14 +2299,9 @@ static int process_backlog(struct napi_struct *napi, int quota)
 			local_irq_enable();
 			break;
 		}
-
 		local_irq_enable();
 
-		dev = skb->dev;
-
 		netif_receive_skb(skb);
-
-		dev_put(dev);
 	} while (++work < quota && jiffies == start_time);
 
 	return work;
@@ -3988,6 +3994,10 @@ int register_netdevice(struct net_device *dev)
 		}
 	}
 
+	/* Enable software GSO if SG is supported. */
+	if (dev->features & NETIF_F_SG)
+		dev->features |= NETIF_F_GSO;
+
 	netdev_initialize_kobject(dev);
 	ret = netdev_register_kobject(dev);
 	if (ret)
@@ -4165,6 +4175,8 @@ void netdev_run_todo(void)
 
 		dev->reg_state = NETREG_UNREGISTERED;
 
+		on_each_cpu(flush_backlog, dev, 1);
+
 		netdev_wait_allrefs(dev);
 
 		/* paranoia */

+ 7 - 6
net/core/neighbour.c

@@ -2281,6 +2281,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
 	struct neighbour *n = neigh_get_first(seq);
 
 	if (n) {
+		--(*pos);
 		while (*pos) {
 			n = neigh_get_next(seq, n, pos);
 			if (!n)
@@ -2341,6 +2342,7 @@ static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos)
 	struct pneigh_entry *pn = pneigh_get_first(seq);
 
 	if (pn) {
+		--(*pos);
 		while (*pos) {
 			pn = pneigh_get_next(seq, pn, pos);
 			if (!pn)
@@ -2354,10 +2356,11 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
 {
 	struct neigh_seq_state *state = seq->private;
 	void *rc;
+	loff_t idxpos = *pos;
 
-	rc = neigh_get_idx(seq, pos);
+	rc = neigh_get_idx(seq, &idxpos);
 	if (!rc && !(state->flags & NEIGH_SEQ_NEIGH_ONLY))
-		rc = pneigh_get_idx(seq, pos);
+		rc = pneigh_get_idx(seq, &idxpos);
 
 	return rc;
 }
@@ -2366,7 +2369,6 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
 	__acquires(tbl->lock)
 {
 	struct neigh_seq_state *state = seq->private;
-	loff_t pos_minus_one;
 
 	state->tbl = tbl;
 	state->bucket = 0;
@@ -2374,8 +2376,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
 
 	read_lock_bh(&tbl->lock);
 
-	pos_minus_one = *pos - 1;
-	return *pos ? neigh_get_idx_any(seq, &pos_minus_one) : SEQ_START_TOKEN;
+	return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
 }
 EXPORT_SYMBOL(neigh_seq_start);
 
@@ -2385,7 +2386,7 @@ void *neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 	void *rc;
 
 	if (v == SEQ_START_TOKEN) {
-		rc = neigh_get_idx(seq, pos);
+		rc = neigh_get_first(seq);
 		goto out;
 	}
 

+ 7 - 3
net/core/pktgen.c

@@ -2085,15 +2085,19 @@ static inline int f_pick(struct pktgen_dev *pkt_dev)
 		if (pkt_dev->flows[flow].count >= pkt_dev->lflow) {
 			/* reset time */
 			pkt_dev->flows[flow].count = 0;
+			pkt_dev->flows[flow].flags = 0;
 			pkt_dev->curfl += 1;
 			if (pkt_dev->curfl >= pkt_dev->cflows)
 				pkt_dev->curfl = 0; /*reset */
 		}
 	} else {
 		flow = random32() % pkt_dev->cflows;
+		pkt_dev->curfl = flow;
 
-		if (pkt_dev->flows[flow].count > pkt_dev->lflow)
+		if (pkt_dev->flows[flow].count > pkt_dev->lflow) {
 			pkt_dev->flows[flow].count = 0;
+			pkt_dev->flows[flow].flags = 0;
+		}
 	}
 
 	return pkt_dev->curfl;
@@ -2162,7 +2166,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
 			mc = random32() % pkt_dev->src_mac_count;
 		else {
 			mc = pkt_dev->cur_src_mac_offset++;
-			if (pkt_dev->cur_src_mac_offset >
+			if (pkt_dev->cur_src_mac_offset >=
 			    pkt_dev->src_mac_count)
 				pkt_dev->cur_src_mac_offset = 0;
 		}
@@ -2189,7 +2193,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
 
 		else {
 			mc = pkt_dev->cur_dst_mac_offset++;
-			if (pkt_dev->cur_dst_mac_offset >
+			if (pkt_dev->cur_dst_mac_offset >=
 			    pkt_dev->dst_mac_count) {
 				pkt_dev->cur_dst_mac_offset = 0;
 			}

+ 1 - 0
net/ipv4/sysctl_net_ipv4.c

@@ -232,6 +232,7 @@ static struct ctl_table ipv4_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &ipv4_doint_and_flush,
 		.strategy	= &ipv4_doint_and_flush_strategy,
+		.extra2		= &init_net,
 	},
 	{
 		.ctl_name	= NET_IPV4_NO_PMTU_DISC,

+ 1 - 1
net/ipv6/ip6_output.c

@@ -269,7 +269,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
 	skb->mark = sk->sk_mark;
 
 	mtu = dst_mtu(dst);
-	if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
+	if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
 		IP6_INC_STATS(ip6_dst_idev(skb->dst),
 			      IPSTATS_MIB_OUTREQUESTS);
 		return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,

+ 2 - 0
net/ipv6/ipv6_sockglue.c

@@ -346,6 +346,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 		 */
 		if (optlen == 0)
 			optval = NULL;
+		else if (optval == NULL)
+			goto e_inval;
 		else if (optlen < sizeof(struct ipv6_opt_hdr) ||
 			 optlen & 0x7 || optlen > 8 * 255)
 			goto e_inval;

+ 11 - 11
net/ipv6/syncookies.c

@@ -199,10 +199,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 	ireq6 = inet6_rsk(req);
 	treq = tcp_rsk(req);
 
-	if (security_inet_conn_request(sk, skb, req)) {
-		reqsk_free(req);
-		goto out;
-	}
+	if (security_inet_conn_request(sk, skb, req))
+		goto out_free;
 
 	req->mss = mss;
 	ireq->rmt_port = th->source;
@@ -255,14 +253,13 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 		fl.fl_ip_dport = inet_rsk(req)->rmt_port;
 		fl.fl_ip_sport = inet_sk(sk)->sport;
 		security_req_classify_flow(req, &fl);
-		if (ip6_dst_lookup(sk, &dst, &fl)) {
-			reqsk_free(req);
-			goto out;
-		}
+		if (ip6_dst_lookup(sk, &dst, &fl))
+			goto out_free;
+
 		if (final_p)
 			ipv6_addr_copy(&fl.fl6_dst, final_p);
 		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
-			goto out;
+			goto out_free;
 	}
 
 	req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
@@ -273,7 +270,10 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 	ireq->rcv_wscale = rcv_wscale;
 
 	ret = get_cookie_sock(sk, skb, req, dst);
-
-out:	return ret;
+out:
+	return ret;
+out_free:
+	reqsk_free(req);
+	return NULL;
 }
 

+ 2 - 0
net/mac80211/ieee80211_i.h

@@ -82,6 +82,7 @@ struct ieee80211_sta_bss {
 
 	u8 bssid[ETH_ALEN];
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 dtim_period;
 	u16 capability; /* host byte order */
 	enum ieee80211_band band;
 	int freq;
@@ -586,6 +587,7 @@ struct ieee80211_local {
 	struct timer_list sta_cleanup;
 
 	unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
+	unsigned long queues_pending_run[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
 	struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES];
 	struct tasklet_struct tx_pending_tasklet;
 

+ 5 - 0
net/mac80211/main.c

@@ -1689,6 +1689,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	if (local->hw.conf.beacon_int < 10)
 		local->hw.conf.beacon_int = 100;
 
+	if (local->hw.max_listen_interval == 0)
+		local->hw.max_listen_interval = 1;
+
+	local->hw.conf.listen_interval = local->hw.max_listen_interval;
+
 	local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
 						  IEEE80211_HW_SIGNAL_DB |
 						  IEEE80211_HW_SIGNAL_DBM) ?

+ 32 - 7
net/mac80211/mlme.c

@@ -551,6 +551,7 @@ static void ieee80211_set_associated(struct net_device *dev,
 			/* set timing information */
 			sdata->bss_conf.beacon_int = bss->beacon_int;
 			sdata->bss_conf.timestamp = bss->timestamp;
+			sdata->bss_conf.dtim_period = bss->dtim_period;
 
 			changed |= ieee80211_handle_bss_capability(sdata, bss);
 
@@ -773,7 +774,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
 		mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
 						   IEEE80211_STYPE_REASSOC_REQ);
 		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
-		mgmt->u.reassoc_req.listen_interval = cpu_to_le16(1);
+		mgmt->u.reassoc_req.listen_interval =
+				cpu_to_le16(local->hw.conf.listen_interval);
 		memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
 		       ETH_ALEN);
 	} else {
@@ -781,7 +783,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
 		mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
 						   IEEE80211_STYPE_ASSOC_REQ);
 		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
-		mgmt->u.assoc_req.listen_interval = cpu_to_le16(1);
+		mgmt->u.reassoc_req.listen_interval =
+				cpu_to_le16(local->hw.conf.listen_interval);
 	}
 
 	/* SSID */
@@ -2688,6 +2691,16 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 	bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
 	bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
 
+	if (elems->tim) {
+		struct ieee80211_tim_ie *tim_ie =
+			(struct ieee80211_tim_ie *)elems->tim;
+		bss->dtim_period = tim_ie->dtim_period;
+	}
+
+	/* set default value for buggy APs */
+	if (!elems->tim || bss->dtim_period == 0)
+		bss->dtim_period = 1;
+
 	bss->supp_rates_len = 0;
 	if (elems->supp_rates) {
 		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
@@ -3650,11 +3663,21 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
 		       "%s\n", print_mac(mac, bssid),
 		       print_mac(mac2, ifsta->bssid));
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
-	if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
-	    (bss = ieee80211_rx_bss_get(dev, bssid,
-					local->hw.conf.channel->center_freq,
-					ifsta->ssid, ifsta->ssid_len))) {
+
+	if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
 		int ret;
+		int search_freq;
+
+		if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
+			search_freq = bss->freq;
+		else
+			search_freq = local->hw.conf.channel->center_freq;
+
+		bss = ieee80211_rx_bss_get(dev, bssid, search_freq,
+					   ifsta->ssid, ifsta->ssid_len);
+		if (!bss)
+			goto dont_join;
+
 		printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
 		       " based on configured SSID\n",
 		       dev->name, print_mac(mac, bssid));
@@ -3662,6 +3685,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
 		ieee80211_rx_bss_put(local, bss);
 		return ret;
 	}
+
+dont_join:
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
 	printk(KERN_DEBUG "   did not try to join ibss\n");
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
@@ -3895,7 +3920,7 @@ done:
 	if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
 		struct ieee80211_if_sta *ifsta = &sdata->u.sta;
 		if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
-		    (!ifsta->state == IEEE80211_IBSS_JOINED &&
+		    (!(ifsta->state == IEEE80211_IBSS_JOINED) &&
 		    !ieee80211_sta_active_ibss(dev)))
 			ieee80211_sta_find_ibss(dev, ifsta);
 	}

+ 12 - 5
net/mac80211/tx.c

@@ -1060,13 +1060,14 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
 			  struct ieee80211_tx_data *tx)
 {
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_tx_info *info;
 	int ret, i;
 
-	if (netif_subqueue_stopped(local->mdev, skb))
-		return IEEE80211_TX_AGAIN;
-
 	if (skb) {
+		if (netif_subqueue_stopped(local->mdev, skb))
+			return IEEE80211_TX_AGAIN;
+		info =  IEEE80211_SKB_CB(skb);
+
 		ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
 				     "TX to low-level driver", skb);
 		ret = local->ops->tx(local_to_hw(local), skb);
@@ -1215,6 +1216,7 @@ retry:
 
 		if (ret == IEEE80211_TX_FRAG_AGAIN)
 			skb = NULL;
+
 		set_bit(queue, local->queues_pending);
 		smp_mb();
 		/*
@@ -1708,14 +1710,19 @@ void ieee80211_tx_pending(unsigned long data)
 	netif_tx_lock_bh(dev);
 	for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
 		/* Check that this queue is ok */
-		if (__netif_subqueue_stopped(local->mdev, i))
+		if (__netif_subqueue_stopped(local->mdev, i) &&
+		    !test_bit(i, local->queues_pending_run))
 			continue;
 
 		if (!test_bit(i, local->queues_pending)) {
+			clear_bit(i, local->queues_pending_run);
 			ieee80211_wake_queue(&local->hw, i);
 			continue;
 		}
 
+		clear_bit(i, local->queues_pending_run);
+		netif_start_subqueue(local->mdev, i);
+
 		store = &local->pending_packet[i];
 		tx.extra_frag = store->extra_frag;
 		tx.num_extra_frag = store->num_extra_frag;

+ 1 - 0
net/mac80211/util.c

@@ -361,6 +361,7 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
 	struct ieee80211_local *local = hw_to_local(hw);
 
 	if (test_bit(queue, local->queues_pending)) {
+		set_bit(queue, local->queues_pending_run);
 		tasklet_schedule(&local->tx_pending_tasklet);
 	} else {
 		netif_wake_subqueue(local->mdev, queue);

+ 4 - 2
net/mac80211/wme.c

@@ -241,12 +241,14 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local,
 	} else {
 		struct netdev_queue *txq;
 		spinlock_t *root_lock;
+		struct Qdisc *q;
 
 		txq = netdev_get_tx_queue(local->mdev, agg_queue);
-		root_lock = qdisc_root_lock(txq->qdisc);
+		q = rcu_dereference(txq->qdisc);
+		root_lock = qdisc_lock(q);
 
 		spin_lock_bh(root_lock);
-		qdisc_reset(txq->qdisc);
+		qdisc_reset(q);
 		spin_unlock_bh(root_lock);
 	}
 }

+ 39 - 15
net/rfkill/rfkill-input.c

@@ -109,6 +109,25 @@ static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
 static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
 static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
 
+static void rfkill_schedule_evsw_rfkillall(int state)
+{
+	/* EVERY radio type. state != 0 means radios ON */
+	/* handle EPO (emergency power off) through shortcut */
+	if (state) {
+		rfkill_schedule_set(&rfkill_wwan,
+				    RFKILL_STATE_UNBLOCKED);
+		rfkill_schedule_set(&rfkill_wimax,
+				    RFKILL_STATE_UNBLOCKED);
+		rfkill_schedule_set(&rfkill_uwb,
+				    RFKILL_STATE_UNBLOCKED);
+		rfkill_schedule_set(&rfkill_bt,
+				    RFKILL_STATE_UNBLOCKED);
+		rfkill_schedule_set(&rfkill_wlan,
+				    RFKILL_STATE_UNBLOCKED);
+	} else
+		rfkill_schedule_epo();
+}
+
 static void rfkill_event(struct input_handle *handle, unsigned int type,
 			unsigned int code, int data)
 {
@@ -132,21 +151,7 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
 	} else if (type == EV_SW) {
 		switch (code) {
 		case SW_RFKILL_ALL:
-			/* EVERY radio type. data != 0 means radios ON */
-			/* handle EPO (emergency power off) through shortcut */
-			if (data) {
-				rfkill_schedule_set(&rfkill_wwan,
-						    RFKILL_STATE_UNBLOCKED);
-				rfkill_schedule_set(&rfkill_wimax,
-						    RFKILL_STATE_UNBLOCKED);
-				rfkill_schedule_set(&rfkill_uwb,
-						    RFKILL_STATE_UNBLOCKED);
-				rfkill_schedule_set(&rfkill_bt,
-						    RFKILL_STATE_UNBLOCKED);
-				rfkill_schedule_set(&rfkill_wlan,
-						    RFKILL_STATE_UNBLOCKED);
-			} else
-				rfkill_schedule_epo();
+			rfkill_schedule_evsw_rfkillall(data);
 			break;
 		default:
 			break;
@@ -168,6 +173,7 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
 	handle->handler = handler;
 	handle->name = "rfkill";
 
+	/* causes rfkill_start() to be called */
 	error = input_register_handle(handle);
 	if (error)
 		goto err_free_handle;
@@ -185,6 +191,23 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
 	return error;
 }
 
+static void rfkill_start(struct input_handle *handle)
+{
+	/* Take event_lock to guard against configuration changes, we
+	 * should be able to deal with concurrency with rfkill_event()
+	 * just fine (which event_lock will also avoid). */
+	spin_lock_irq(&handle->dev->event_lock);
+
+	if (test_bit(EV_SW, handle->dev->evbit)) {
+		if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))
+			rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
+							handle->dev->sw));
+		/* add resync for further EV_SW events here */
+	}
+
+	spin_unlock_irq(&handle->dev->event_lock);
+}
+
 static void rfkill_disconnect(struct input_handle *handle)
 {
 	input_close_device(handle);
@@ -225,6 +248,7 @@ static struct input_handler rfkill_handler = {
 	.event =	rfkill_event,
 	.connect =	rfkill_connect,
 	.disconnect =	rfkill_disconnect,
+	.start =	rfkill_start,
 	.name =		"rfkill",
 	.id_table =	rfkill_ids,
 };

+ 14 - 1
net/rfkill/rfkill.c

@@ -105,6 +105,16 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
 #endif /* CONFIG_RFKILL_LEDS */
 }
 
+#ifdef CONFIG_RFKILL_LEDS
+static void rfkill_led_trigger_activate(struct led_classdev *led)
+{
+	struct rfkill *rfkill = container_of(led->trigger,
+			struct rfkill, led_trigger);
+
+	rfkill_led_trigger(rfkill, rfkill->state);
+}
+#endif /* CONFIG_RFKILL_LEDS */
+
 static void notify_rfkill_state_change(struct rfkill *rfkill)
 {
 	blocking_notifier_call_chain(&rfkill_notifier_list,
@@ -589,7 +599,10 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill)
 #ifdef CONFIG_RFKILL_LEDS
 	int error;
 
-	rfkill->led_trigger.name = rfkill->dev.bus_id;
+	if (!rfkill->led_trigger.name)
+		rfkill->led_trigger.name = rfkill->dev.bus_id;
+	if (!rfkill->led_trigger.activate)
+		rfkill->led_trigger.activate = rfkill_led_trigger_activate;
 	error = led_trigger_register(&rfkill->led_trigger);
 	if (error)
 		rfkill->led_trigger.name = NULL;

+ 8 - 6
net/sched/sch_atm.c

@@ -415,7 +415,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
 			kfree_skb(skb);
-			return NET_XMIT_SUCCESS;
+			return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			kfree_skb(skb);
 			goto drop;
@@ -432,9 +432,11 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	ret = qdisc_enqueue(skb, flow->q);
 	if (ret != 0) {
 drop: __maybe_unused
-		sch->qstats.drops++;
-		if (flow)
-			flow->qstats.drops++;
+		if (net_xmit_drop_count(ret)) {
+			sch->qstats.drops++;
+			if (flow)
+				flow->qstats.drops++;
+		}
 		return ret;
 	}
 	sch->bstats.bytes += qdisc_pkt_len(skb);
@@ -455,7 +457,7 @@ drop: __maybe_unused
 		return 0;
 	}
 	tasklet_schedule(&p->task);
-	return NET_XMIT_BYPASS;
+	return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 }
 
 /*
@@ -530,7 +532,7 @@ static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
 	if (!ret) {
 		sch->q.qlen++;
 		sch->qstats.requeues++;
-	} else {
+	} else if (net_xmit_drop_count(ret)) {
 		sch->qstats.drops++;
 		p->link.qstats.drops++;
 	}

+ 17 - 10
net/sched/sch_cbq.c

@@ -230,7 +230,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 	    (cl = cbq_class_lookup(q, prio)) != NULL)
 		return cl;
 
-	*qerr = NET_XMIT_BYPASS;
+	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	for (;;) {
 		int result = 0;
 		defmap = head->defaults;
@@ -256,7 +256,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
-			*qerr = NET_XMIT_SUCCESS;
+			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
 		case TC_ACT_RECLASSIFY:
@@ -377,7 +377,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	q->rx_class = cl;
 #endif
 	if (cl == NULL) {
-		if (ret == NET_XMIT_BYPASS)
+		if (ret & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
@@ -397,9 +397,11 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		return ret;
 	}
 
-	sch->qstats.drops++;
-	cbq_mark_toplevel(q, cl);
-	cl->qstats.drops++;
+	if (net_xmit_drop_count(ret)) {
+		sch->qstats.drops++;
+		cbq_mark_toplevel(q, cl);
+		cl->qstats.drops++;
+	}
 	return ret;
 }
 
@@ -430,8 +432,10 @@ cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
 			cbq_activate_class(cl);
 		return 0;
 	}
-	sch->qstats.drops++;
-	cl->qstats.drops++;
+	if (net_xmit_drop_count(ret)) {
+		sch->qstats.drops++;
+		cl->qstats.drops++;
+	}
 	return ret;
 }
 
@@ -664,13 +668,15 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
 	q->rx_class = NULL;
 
 	if (cl && (cl = cbq_reclassify(skb, cl)) != NULL) {
+		int ret;
 
 		cbq_mark_toplevel(q, cl);
 
 		q->rx_class = cl;
 		cl->q->__parent = sch;
 
-		if (qdisc_enqueue(skb, cl->q) == 0) {
+		ret = qdisc_enqueue(skb, cl->q);
+		if (ret == NET_XMIT_SUCCESS) {
 			sch->q.qlen++;
 			sch->bstats.packets++;
 			sch->bstats.bytes += qdisc_pkt_len(skb);
@@ -678,7 +684,8 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
 				cbq_activate_class(cl);
 			return 0;
 		}
-		sch->qstats.drops++;
+		if (net_xmit_drop_count(ret))
+			sch->qstats.drops++;
 		return 0;
 	}
 

+ 6 - 4
net/sched/sch_dsmark.c

@@ -236,7 +236,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
 			kfree_skb(skb);
-			return NET_XMIT_SUCCESS;
+			return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 
 		case TC_ACT_SHOT:
 			goto drop;
@@ -254,7 +254,8 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 	err = qdisc_enqueue(skb, p->q);
 	if (err != NET_XMIT_SUCCESS) {
-		sch->qstats.drops++;
+		if (net_xmit_drop_count(err))
+			sch->qstats.drops++;
 		return err;
 	}
 
@@ -267,7 +268,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 drop:
 	kfree_skb(skb);
 	sch->qstats.drops++;
-	return NET_XMIT_BYPASS;
+	return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 }
 
 static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
@@ -321,7 +322,8 @@ static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
 
 	err = p->q->ops->requeue(skb, p->q);
 	if (err != NET_XMIT_SUCCESS) {
-		sch->qstats.drops++;
+		if (net_xmit_drop_count(err))
+			sch->qstats.drops++;
 		return err;
 	}
 

+ 6 - 6
net/sched/sch_generic.c

@@ -29,7 +29,7 @@
 /* Main transmission queue. */
 
 /* Modifications to data participating in scheduling must be protected with
- * qdisc_root_lock(qdisc) spinlock.
+ * qdisc_lock(qdisc) spinlock.
  *
  * The idea is the following:
  * - enqueue, dequeue are serialized via qdisc root lock
@@ -126,7 +126,7 @@ static inline int qdisc_restart(struct Qdisc *q)
 	if (unlikely((skb = dequeue_skb(q)) == NULL))
 		return 0;
 
-	root_lock = qdisc_root_lock(q);
+	root_lock = qdisc_lock(q);
 
 	/* And release qdisc */
 	spin_unlock(root_lock);
@@ -507,7 +507,7 @@ errout:
 }
 EXPORT_SYMBOL(qdisc_create_dflt);
 
-/* Under qdisc_root_lock(qdisc) and BH! */
+/* Under qdisc_lock(qdisc) and BH! */
 
 void qdisc_reset(struct Qdisc *qdisc)
 {
@@ -543,7 +543,7 @@ static void __qdisc_destroy(struct rcu_head *head)
 	kfree((char *) qdisc - qdisc->padded);
 }
 
-/* Under qdisc_root_lock(qdisc) and BH! */
+/* Under qdisc_lock(qdisc) and BH! */
 
 void qdisc_destroy(struct Qdisc *qdisc)
 {
@@ -659,7 +659,7 @@ static bool some_qdisc_is_running(struct net_device *dev, int lock)
 
 		dev_queue = netdev_get_tx_queue(dev, i);
 		q = dev_queue->qdisc;
-		root_lock = qdisc_root_lock(q);
+		root_lock = qdisc_lock(q);
 
 		if (lock)
 			spin_lock_bh(root_lock);
@@ -735,7 +735,7 @@ static void shutdown_scheduler_queue(struct net_device *dev,
 	struct Qdisc *qdisc_default = _qdisc_default;
 
 	if (qdisc) {
-		spinlock_t *root_lock = qdisc_root_lock(qdisc);
+		spinlock_t *root_lock = qdisc_lock(qdisc);
 
 		dev_queue->qdisc = qdisc_default;
 		dev_queue->qdisc_sleeping = qdisc_default;

+ 7 - 5
net/sched/sch_hfsc.c

@@ -1159,14 +1159,14 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 		if (cl->level == 0)
 			return cl;
 
-	*qerr = NET_XMIT_BYPASS;
+	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	tcf = q->root.filter_list;
 	while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
-			*qerr = NET_XMIT_SUCCESS;
+			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
 		}
@@ -1578,7 +1578,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 	cl = hfsc_classify(skb, sch, &err);
 	if (cl == NULL) {
-		if (err == NET_XMIT_BYPASS)
+		if (err & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return err;
@@ -1586,8 +1586,10 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 	err = qdisc_enqueue(skb, cl->qdisc);
 	if (unlikely(err != NET_XMIT_SUCCESS)) {
-		cl->qstats.drops++;
-		sch->qstats.drops++;
+		if (net_xmit_drop_count(err)) {
+			cl->qstats.drops++;
+			sch->qstats.drops++;
+		}
 		return err;
 	}
 

+ 14 - 10
net/sched/sch_htb.c

@@ -214,14 +214,14 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch,
 	if ((cl = htb_find(skb->priority, sch)) != NULL && cl->level == 0)
 		return cl;
 
-	*qerr = NET_XMIT_BYPASS;
+	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	tcf = q->filter_list;
 	while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
 		switch (result) {
 		case TC_ACT_QUEUED:
 		case TC_ACT_STOLEN:
-			*qerr = NET_XMIT_SUCCESS;
+			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
 		}
@@ -567,14 +567,16 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		}
 #ifdef CONFIG_NET_CLS_ACT
 	} else if (!cl) {
-		if (ret == NET_XMIT_BYPASS)
+		if (ret & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
 #endif
-	} else if (qdisc_enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
-		sch->qstats.drops++;
-		cl->qstats.drops++;
+	} else if ((ret = qdisc_enqueue(skb, cl->un.leaf.q)) != NET_XMIT_SUCCESS) {
+		if (net_xmit_drop_count(ret)) {
+			sch->qstats.drops++;
+			cl->qstats.drops++;
+		}
 		return NET_XMIT_DROP;
 	} else {
 		cl->bstats.packets +=
@@ -610,15 +612,17 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
 		}
 #ifdef CONFIG_NET_CLS_ACT
 	} else if (!cl) {
-		if (ret == NET_XMIT_BYPASS)
+		if (ret & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
 #endif
-	} else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) !=
+	} else if ((ret = cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q)) !=
 		   NET_XMIT_SUCCESS) {
-		sch->qstats.drops++;
-		cl->qstats.drops++;
+		if (net_xmit_drop_count(ret)) {
+			sch->qstats.drops++;
+			cl->qstats.drops++;
+		}
 		return NET_XMIT_DROP;
 	} else
 		htb_activate(q, cl);

+ 3 - 2
net/sched/sch_netem.c

@@ -176,7 +176,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 	if (count == 0) {
 		sch->qstats.drops++;
 		kfree_skb(skb);
-		return NET_XMIT_BYPASS;
+		return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	}
 
 	skb_orphan(skb);
@@ -240,8 +240,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		sch->q.qlen++;
 		sch->bstats.bytes += qdisc_pkt_len(skb);
 		sch->bstats.packets++;
-	} else
+	} else if (net_xmit_drop_count(ret)) {
 		sch->qstats.drops++;
+	}
 
 	pr_debug("netem: enqueue ret %d\n", ret);
 	return ret;

+ 8 - 6
net/sched/sch_prio.c

@@ -38,14 +38,14 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 	struct tcf_result res;
 	int err;
 
-	*qerr = NET_XMIT_BYPASS;
+	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	if (TC_H_MAJ(skb->priority) != sch->handle) {
 		err = tc_classify(skb, q->filter_list, &res);
 #ifdef CONFIG_NET_CLS_ACT
 		switch (err) {
 		case TC_ACT_STOLEN:
 		case TC_ACT_QUEUED:
-			*qerr = NET_XMIT_SUCCESS;
+			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return NULL;
 		}
@@ -74,7 +74,7 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 #ifdef CONFIG_NET_CLS_ACT
 	if (qdisc == NULL) {
 
-		if (ret == NET_XMIT_BYPASS)
+		if (ret & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
@@ -88,7 +88,8 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		sch->q.qlen++;
 		return NET_XMIT_SUCCESS;
 	}
-	sch->qstats.drops++;
+	if (net_xmit_drop_count(ret))
+		sch->qstats.drops++;
 	return ret;
 }
 
@@ -102,7 +103,7 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
 	qdisc = prio_classify(skb, sch, &ret);
 #ifdef CONFIG_NET_CLS_ACT
 	if (qdisc == NULL) {
-		if (ret == NET_XMIT_BYPASS)
+		if (ret & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
@@ -114,7 +115,8 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
 		sch->qstats.requeues++;
 		return 0;
 	}
-	sch->qstats.drops++;
+	if (net_xmit_drop_count(ret))
+		sch->qstats.drops++;
 	return NET_XMIT_DROP;
 }
 

+ 1 - 1
net/sched/sch_red.c

@@ -97,7 +97,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 		sch->bstats.bytes += qdisc_pkt_len(skb);
 		sch->bstats.packets++;
 		sch->q.qlen++;
-	} else {
+	} else if (net_xmit_drop_count(ret)) {
 		q->stats.pdrop++;
 		sch->qstats.drops++;
 	}

+ 4 - 4
net/sched/sch_sfq.c

@@ -171,14 +171,14 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
 	if (!q->filter_list)
 		return sfq_hash(q, skb) + 1;
 
-	*qerr = NET_XMIT_BYPASS;
+	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	result = tc_classify(skb, q->filter_list, &res);
 	if (result >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
 		switch (result) {
 		case TC_ACT_STOLEN:
 		case TC_ACT_QUEUED:
-			*qerr = NET_XMIT_SUCCESS;
+			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 		case TC_ACT_SHOT:
 			return 0;
 		}
@@ -285,7 +285,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
 	hash = sfq_classify(skb, sch, &ret);
 	if (hash == 0) {
-		if (ret == NET_XMIT_BYPASS)
+		if (ret & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
@@ -339,7 +339,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc *sch)
 
 	hash = sfq_classify(skb, sch, &ret);
 	if (hash == 0) {
-		if (ret == NET_XMIT_BYPASS)
+		if (ret & __NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;

+ 2 - 1
net/sched/sch_tbf.c

@@ -135,7 +135,8 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 
 	ret = qdisc_enqueue(skb, q->qdisc);
 	if (ret != 0) {
-		sch->qstats.drops++;
+		if (net_xmit_drop_count(ret))
+			sch->qstats.drops++;
 		return ret;
 	}
 

+ 5 - 3
net/sctp/ipv6.c

@@ -195,8 +195,7 @@ out:
 }
 
 /* Based on tcp_v6_xmit() in tcp_ipv6.c. */
-static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
-			int ipfragok)
+static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
 {
 	struct sock *sk = skb->sk;
 	struct ipv6_pinfo *np = inet6_sk(sk);
@@ -231,7 +230,10 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
 
 	SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
 
-	return ip6_xmit(sk, skb, &fl, np->opt, ipfragok);
+	if (!(transport->param_flags & SPP_PMTUD_ENABLE))
+		skb->local_df = 1;
+
+	return ip6_xmit(sk, skb, &fl, np->opt, 0);
 }
 
 /* Returns the dst cache entry for the given source and destination ip

+ 2 - 4
net/sctp/output.c

@@ -586,10 +586,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
 	SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
 			  nskb->len);
 
-	if (tp->param_flags & SPP_PMTUD_ENABLE)
-		(*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
-	else
-		(*tp->af_specific->sctp_xmit)(nskb, tp, 1);
+	nskb->local_df = packet->ipfragok;
+	(*tp->af_specific->sctp_xmit)(nskb, tp);
 
 out:
 	packet->size = packet->overhead;

+ 7 - 2
net/sctp/protocol.c

@@ -862,16 +862,21 @@ static int sctp_inet_supported_addrs(const struct sctp_sock *opt,
 
 /* Wrapper routine that calls the ip transmit routine. */
 static inline int sctp_v4_xmit(struct sk_buff *skb,
-			       struct sctp_transport *transport, int ipfragok)
+			       struct sctp_transport *transport)
 {
+	struct inet_sock *inet = inet_sk(skb->sk);
+
 	SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
 			  "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n",
 			  __func__, skb, skb->len,
 			  NIPQUAD(skb->rtable->rt_src),
 			  NIPQUAD(skb->rtable->rt_dst));
 
+	inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
+			 IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
+
 	SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
-	return ip_queue_xmit(skb, ipfragok);
+	return ip_queue_xmit(skb, 0);
 }
 
 static struct sctp_af sctp_af_inet;

Някои файлове не бяха показани, защото твърде много файлове са промени