From 5b36c9b4a9872f7852b8ce7cffbfc2f6d6c25371 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 23 Jul 2011 13:57:33 +0200 Subject: [PATCH 001/287] b43: read correct register on bcma bus. This causes an databus error on a Broadcom SoC using bcma. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/net/wireless/b43/dma.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 83cba22ac6e8..481e534534eb 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -795,9 +795,23 @@ static u64 supported_dma_mask(struct b43_wldev *dev) u32 tmp; u16 mmio_base; - tmp = b43_read32(dev, SSB_TMSHIGH); - if (tmp & SSB_TMSHIGH_DMA64) - return DMA_BIT_MASK(64); + switch (dev->dev->bus_type) { +#ifdef CONFIG_B43_BCMA + case B43_BUS_BCMA: + tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST); + if (tmp & BCMA_IOST_DMA64) + return DMA_BIT_MASK(64); + break; +#endif +#ifdef CONFIG_B43_SSB + case B43_BUS_SSB: + tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); + if (tmp & SSB_TMSHIGH_DMA64) + return DMA_BIT_MASK(64); + break; +#endif + } + mmio_base = b43_dmacontroller_base(0, 0); b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK); tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL); From 15052f81d255eac44e745bc630b36aa86779ad9d Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 29 Jul 2011 17:38:15 +0530 Subject: [PATCH 002/287] ath9k_hw: Fix incorrect Tx control power in AR9003 template CTL power data incorrect in ctlPowerData_2G field of ar9300_eeprom. Setting incorrect CTL power in calibration is causing lower tx power. Tx power was reported as 3dBm while operating in channel 6 HT40+/ in channel 11 HT40- due to CTL powers in the calibration is set to zero. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index d109c25417f4..6cfc9ebcd5c4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -307,7 +307,7 @@ static const struct ar9300_eeprom ar9300_default = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -884,7 +884,7 @@ static const struct ar9300_eeprom ar9300_x113 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -2040,7 +2040,7 @@ static const struct ar9300_eeprom ar9300_x112 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, From 1fa707aa3e5c43b094983787267d80d0dfa44e4d Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 29 Jul 2011 17:38:17 +0530 Subject: [PATCH 003/287] ath9k_hw: update PMU to improve ripple issue for AR9485 The commit ebefce3d13f8b5a871337ff7c3821ee140c1ea8a failed to set proper PMU value to address ripple issue for AR9485. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 6cfc9ebcd5c4..c34bef1bf2b0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3734,7 +3734,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) } } else { reg_pmu_set = (5 << 1) | (7 << 4) | - (1 << 8) | (2 << 14) | + (2 << 8) | (2 << 14) | (6 << 17) | (1 << 20) | (3 << 24) | (1 << 28); } From 03f18fa16cd805916a56d027b4ee52ba26e6d6ab Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 2 Aug 2011 16:52:33 -0500 Subject: [PATCH 004/287] rtlwifi: rtl892cu: New USB IDs This patch fixes several problems in the USB_DEVICE table, including missing IDs, reversed vendor/product codes, and a duplicate ID. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 942f7a3969a7..ef63c0df006a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -281,6 +281,8 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)}, /* 8188CE-VAU USB minCard (b/g mode only) */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, + /* 8188RU in Alfa AWUS036NHR */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, /* 8188 Combo for BC4 */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, @@ -303,20 +305,23 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ - {RTL_USB_DEVICE(0x3358, 0x13d3, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ + {RTL_USB_DEVICE(0x13d3, 0x3358, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ /* Russian customer -Azwave (8188CE-VAU b/g mode only) */ - {RTL_USB_DEVICE(0x3359, 0x13d3, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(0x13d3, 0x3359, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(0x4855, 0x0090, rtl92cu_hal_cfg)}, /* Feixun */ + {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ + {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ /****** 8192CU ********/ {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ - {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Abocom -Abocom*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ From b8b1ec61c006ed1d3104093556544e858cc2ddd1 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Wed, 3 Aug 2011 21:09:49 +0200 Subject: [PATCH 005/287] rt2x00: Add new rt73 buffalo USB id Reported-by: Maik-Holger Freudenberg Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6a93939f44e8..0baeb894f093 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2420,6 +2420,7 @@ static struct usb_device_id rt73usb_device_table[] = { /* Buffalo */ { USB_DEVICE(0x0411, 0x00d8) }, { USB_DEVICE(0x0411, 0x00d9) }, + { USB_DEVICE(0x0411, 0x00e6) }, { USB_DEVICE(0x0411, 0x00f4) }, { USB_DEVICE(0x0411, 0x0116) }, { USB_DEVICE(0x0411, 0x0119) }, From 118c9db51e7acaf8f16deae8311cce6588b83e31 Mon Sep 17 00:00:00 2001 From: Alex Hacker Date: Thu, 4 Aug 2011 13:47:32 +0600 Subject: [PATCH 006/287] ath9k: fix a misprint which leads to incorrect calibration This patch addresses an issue with incorrect HW register AR_PHY_TX_IQCAL_CORR_COEFF_B1 definition which leads to incorrect clibration. Cc: stable@kernel.org Signed-off-by: Alex Hacker Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 6de3f0bc18e6..5c590429f120 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -850,7 +850,7 @@ #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) -#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) +#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) /* * Channel 2 Register Map From 276b02e2a0ada2e0196852c312560ffdabcebddc Mon Sep 17 00:00:00 2001 From: Anthony Bourguignon Date: Fri, 5 Aug 2011 07:46:32 +0200 Subject: [PATCH 007/287] rt2x00: Add rt2870 device id for Dvico usb key This patch add a device id for the wifi usb keys shiped by DVICO with some of their tvix hardware. Signed-off-by: Anthony Bourguignon Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 507559361d87..939563162fb3 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -921,6 +921,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c16) }, /* Draytek */ { USB_DEVICE(0x07fa, 0x7712) }, + /* DVICO */ + { USB_DEVICE(0x0fe9, 0xb307) }, /* Edimax */ { USB_DEVICE(0x7392, 0x7711) }, { USB_DEVICE(0x7392, 0x7717) }, From bdc71bc59231f5542af13b5061b9ab124d093050 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sun, 7 Aug 2011 19:36:07 -0400 Subject: [PATCH 008/287] ath5k: fix error handling in ath5k_beacon_send This cleans up error handling for the beacon in case of dma mapping failure. We need to free the skb when dma mapping fails instead of nulling and leaking the pointer, and we should bail out to avoid giving the hardware the bad descriptor. Finally, we need to perform the null check after trying to update the beacon, or else beacons will never be sent after a single mapping failure. Cc: stable@kernel.org Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index f54dff44ed50..c3119a6caace 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1735,6 +1735,8 @@ ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf) if (dma_mapping_error(ah->dev, bf->skbaddr)) { ATH5K_ERR(ah, "beacon DMA mapping failed\n"); + dev_kfree_skb_any(skb); + bf->skb = NULL; return -EIO; } @@ -1819,8 +1821,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ath5k_txbuf_free_skb(ah, avf->bbuf); avf->bbuf->skb = skb; ret = ath5k_beacon_setup(ah, avf->bbuf); - if (ret) - avf->bbuf->skb = NULL; out: return ret; } @@ -1840,6 +1840,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) struct ath5k_vif *avf; struct ath5k_buf *bf; struct sk_buff *skb; + int err; ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "in beacon_send\n"); @@ -1888,11 +1889,6 @@ ath5k_beacon_send(struct ath5k_hw *ah) avf = (void *)vif->drv_priv; bf = avf->bbuf; - if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION || - ah->opmode == NL80211_IFTYPE_MONITOR)) { - ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); - return; - } /* * Stop any current dma and put the new frame on the queue. @@ -1906,8 +1902,17 @@ ath5k_beacon_send(struct ath5k_hw *ah) /* refresh the beacon for AP or MESH mode */ if (ah->opmode == NL80211_IFTYPE_AP || - ah->opmode == NL80211_IFTYPE_MESH_POINT) - ath5k_beacon_update(ah->hw, vif); + ah->opmode == NL80211_IFTYPE_MESH_POINT) { + err = ath5k_beacon_update(ah->hw, vif); + if (err) + return; + } + + if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION || + ah->opmode == NL80211_IFTYPE_MONITOR)) { + ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf->skb); + return; + } trace_ath5k_tx(ah, bf->skb, &ah->txqs[ah->bhalq]); From 059c4383550b158bc1b6d34d8ab085e81cb3d71b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 8 Aug 2011 13:18:03 +0200 Subject: [PATCH 009/287] drivers/net/wireless/wl1251: add missing kfree In each case, the kfree already at the end of the function is also needed in the error case. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @exists@ local idexpression x; statement S,S1; expression E; identifier fl; expression *ptr != NULL; @@ x = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S <... when != x when != if (...) { <+...kfree(x)...+> } when any when != true x == NULL x->fl ...> ( if (x == NULL) S1 | if (...) { ... when != x when forall ( return \(0\|<+...x...+>\|ptr\); | * return ...; ) } ) // Signed-off-by: Julia Lawall Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/acx.c | 6 +----- drivers/net/wireless/wl1251/cmd.c | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/wl1251/acx.c index ef8370edace7..ad87a1ac6462 100644 --- a/drivers/net/wireless/wl1251/acx.c +++ b/drivers/net/wireless/wl1251/acx.c @@ -140,8 +140,6 @@ int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth) auth->sleep_auth = sleep_auth; ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); - if (ret < 0) - return ret; out: kfree(auth); @@ -681,10 +679,8 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl) ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD, detection, sizeof(*detection)); - if (ret < 0) { + if (ret < 0) wl1251_warning("failed to set cca threshold: %d", ret); - return ret; - } out: kfree(detection); diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/wl1251/cmd.c index 81f164bc4888..d14d69d733a0 100644 --- a/drivers/net/wireless/wl1251/cmd.c +++ b/drivers/net/wireless/wl1251/cmd.c @@ -241,7 +241,7 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) if (ret < 0) { wl1251_error("tx %s cmd for channel %d failed", enable ? "start" : "stop", channel); - return ret; + goto out; } wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", From 4b1bfb7d2d125af6653d6c2305356b2677f79dc6 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 10 Aug 2011 15:32:22 +0200 Subject: [PATCH 010/287] rt2x00: fix crash in rt2800usb_write_tx_desc Patch should fix this oops: BUG: unable to handle kernel NULL pointer dereference at 000000a0 IP: [] rt2800usb_write_tx_desc+0x18/0xc0 [rt2800usb] *pdpt = 000000002408c001 *pde = 0000000024079067 *pte = 0000000000000000 Oops: 0000 [#1] SMP EIP: 0060:[] EFLAGS: 00010282 CPU: 0 EIP is at rt2800usb_write_tx_desc+0x18/0xc0 [rt2800usb] EAX: 00000035 EBX: ef2bef10 ECX: 00000000 EDX: d40958a0 ESI: ef1865f8 EDI: ef1865f8 EBP: d4095878 ESP: d409585c DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Call Trace: [] rt2x00queue_write_tx_frame+0x155/0x300 [rt2x00lib] [] rt2x00mac_tx+0x7c/0x370 [rt2x00lib] [] ? mark_held_locks+0x62/0x90 [] ? _raw_spin_unlock_irqrestore+0x35/0x60 [] ? trace_hardirqs_on_caller+0x5a/0x170 [] ? trace_hardirqs_on+0xb/0x10 [] __ieee80211_tx+0x5c/0x1e0 [mac80211] [] ieee80211_tx+0xbc/0xe0 [mac80211] [] ? ieee80211_tx+0x23/0xe0 [mac80211] [] ieee80211_xmit+0xc1/0x200 [mac80211] [] ? ieee80211_tx+0xe0/0xe0 [mac80211] [] ? lock_release_holdtime+0x35/0x1b0 [] ? ieee80211_subif_start_xmit+0x446/0x5f0 [mac80211] [] ieee80211_subif_start_xmit+0x29d/0x5f0 [mac80211] [] ? ieee80211_subif_start_xmit+0x3e4/0x5f0 [mac80211] [] ? sock_setsockopt+0x6a8/0x6f0 [] ? sock_setsockopt+0x520/0x6f0 [] dev_hard_start_xmit+0x2ef/0x650 Oops might happen because we perform parallel putting new entries in a queue (rt2x00queue_write_tx_frame()) and removing entries after finishing transmitting (rt2800usb_work_txdone()). There are cases when _txdone may process an entry that was not fully send and nullify entry->skb . To fix check in _txdone if entry has flags that indicate pending transmission and wait until flags get cleared. Reported-by: Justin Piszcz Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 939563162fb3..2cb25ea13c52 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -464,6 +464,15 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) int wcid, ack, pid; int tx_wcid, tx_ack, tx_pid; + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { + WARNING(entry->queue->rt2x00dev, + "Data pending for entry %u in queue %u\n", + entry->entry_idx, entry->queue->qid); + cond_resched(); + return false; + } + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); @@ -558,8 +567,10 @@ static void rt2800usb_work_txdone(struct work_struct *work) while (!rt2x00queue_empty(queue)) { entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) break; + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); else if (rt2x00queue_status_timeout(entry)) From df71c9cfceea801e7e26e2c74241758ef9c042e5 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 10 Aug 2011 15:32:23 +0200 Subject: [PATCH 011/287] rt2x00: fix order of entry flags modification In rt2800usb_work_txdone we check flags in order: - ENTRY_OWNER_DEVICE_DATA - ENTRY_DATA_STATUS_PENDING - ENTRY_DATA_IO_FAILED Modify flags in separate order in rt2x00usb_interrupt_txdone, to avoid processing entries in _txdone with wrong flags or skip processing ready entries. Reported-by: Justin Piszcz Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index b6b4542c2460..7fbb55c9da82 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -262,23 +262,20 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; - - if (rt2x00dev->ops->lib->tx_dma_done) - rt2x00dev->ops->lib->tx_dma_done(entry); - - /* - * Report the frame as DMA done - */ - rt2x00lib_dmadone(entry); - /* * Check if the frame was correctly uploaded */ if (urb->status) set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + /* + * Report the frame as DMA done + */ + rt2x00lib_dmadone(entry); + if (rt2x00dev->ops->lib->tx_dma_done) + rt2x00dev->ops->lib->tx_dma_done(entry); /* * Schedule the delayed work for reading the TX status * from the device. From 674db1344443204b6ce3293f2df8fd1b7665deea Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 10 Aug 2011 15:32:24 +0200 Subject: [PATCH 012/287] rt2x00: fix crash in rt2800usb_get_txwi Patch should fix this oops: BUG: unable to handle kernel NULL pointer dereference at 000000a0 IP: [] rt2800usb_get_txwi+0x19/0x70 [rt2800usb] *pdpt = 0000000000000000 *pde = f000ff53f000ff53 Oops: 0000 [#1] SMP Pid: 198, comm: kworker/u:3 Tainted: G W 3.0.0-wl+ #9 LENOVO 6369CTO/6369CTO EIP: 0060:[] EFLAGS: 00010283 CPU: 1 EIP is at rt2800usb_get_txwi+0x19/0x70 [rt2800usb] EAX: 00000000 EBX: f465e140 ECX: f4494960 EDX: ef24c5f8 ESI: 810f21f5 EDI: f1da9960 EBP: f4581e80 ESP: f4581e70 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process kworker/u:3 (pid: 198, ti=f4580000 task=f4494960 task.ti=f4580000) Call Trace: [] rt2800_txdone_entry+0x2f/0xf0 [rt2800lib] [] ? warn_slowpath_common+0x7d/0xa0 [] ? rt2800usb_work_txdone+0x288/0x360 [rt2800usb] [] ? rt2800usb_work_txdone+0x288/0x360 [rt2800usb] [] rt2800usb_work_txdone+0x263/0x360 [rt2800usb] [] process_one_work+0x186/0x440 [] ? process_one_work+0x10a/0x440 [] ? rt2800usb_probe_hw+0x120/0x120 [rt2800usb] [] worker_thread+0x133/0x310 [] ? trace_hardirqs_on+0xb/0x10 [] ? manage_workers+0x1e0/0x1e0 [] kthread+0x7c/0x90 [] ? __init_kthread_worker+0x60/0x60 [] kernel_thread_helper+0x6/0x1 Oops might happen because we check rt2x00queue_empty(queue) twice, but this condition can change and we can process entry in rt2800_txdone_entry(), which was already processed by rt2800usb_txdone_entry_check() -> rt2x00lib_txdone_noinfo() and has nullify entry->skb . Reported-by: Justin Piszcz Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 2cb25ea13c52..dbf501ca317f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -538,12 +538,11 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); if (rt2800usb_txdone_entry_check(entry, reg)) break; + entry = NULL; } - if (!entry || rt2x00queue_empty(queue)) - break; - - rt2800_txdone_entry(entry, reg); + if (entry) + rt2800_txdone_entry(entry, reg); } } From 8475e2336cf80ba6e7b27715b4b3214d73c211ab Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 3 Aug 2011 17:22:45 +0300 Subject: [PATCH 013/287] Bluetooth: unlock if allocation fails in hci_blacklist_add() There was a small typo here so we never actually hit the goto which would call hci_dev_unlock_bh(). Signed-off-by: Dan Carpenter Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ec0bc3f60f2e..fca62dcd7f1b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1327,7 +1327,7 @@ int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr) entry = kzalloc(sizeof(struct bdaddr_list), GFP_KERNEL); if (!entry) { - return -ENOMEM; + err = -ENOMEM; goto err; } From 4935f1c164ac528dff3538f97953b385ba500710 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 9 Aug 2011 17:16:28 +0200 Subject: [PATCH 014/287] Bluetooth: btusb: be quiet on device disconnect Disabling the bluetooth usb device embedded in (some) ThinkPads tends to lead to errors like these: btusb_bulk_complete: hci0 urb ffff88011b9bfd68 failed to resubmit (19) btusb_intr_complete: hci0 urb ffff88011b46a318 failed to resubmit (19) btusb_bulk_complete: hci0 urb ffff88011b46a000 failed to resubmit (19) That is because usb_disconnect() doesn't "quiesces" pending urbs. Disconnecting a device is a normal thing to happen so it's no big deal that usb_submit_urb() returns -ENODEV. The simplest way to get rid of these errors is to stop treating that return as an error. Trivial, actually. While we're at it, add comments to be explicit about the reasons we're not complaining about -EPERM and -ENODEV. Signed-off-by: Paul Bolle Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 91d13a9e8c65..9e4448efb104 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -256,7 +256,9 @@ static void btusb_intr_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); @@ -341,7 +343,9 @@ static void btusb_bulk_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); @@ -431,7 +435,9 @@ static void btusb_isoc_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - if (err != -EPERM) + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); From 8e7c3d2e4ba18ee4cdcc1f89aec944fbff4ce735 Mon Sep 17 00:00:00 2001 From: Ricardo Mendoza Date: Wed, 13 Jul 2011 16:04:29 +0100 Subject: [PATCH 015/287] Bluetooth: Add Toshiba laptops AR30XX device ID Blacklist Toshiba-branded AR3011 based AR5B195 [0930:0215] and add to ath3k.c for firmware loading. Signed-off-by: Ricardo Mendoza Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 1 + drivers/bluetooth/btusb.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index a5854735bb2e..db7cb8111fbe 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, { USB_DEVICE(0x13d3, 0x3304) }, + { USB_DEVICE(0x0930, 0x0215) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 9e4448efb104..3ef476070baf 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -106,6 +106,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, From e5842cdb0f4f2c68f6acd39e286e5d10d8c073e8 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:35 -0400 Subject: [PATCH 016/287] Bluetooth: rfcomm: Remove unnecessary krfcommd event Removed superfluous event handling which was used to signal that the rfcomm kthread had been woken. This appears to have been used to prevent lost wakeups. Correctly ordering when the task state is set to TASK_INTERRUPTIBLE is sufficient to prevent lost wakeups. To prevent wakeups which occurred prior to initially setting TASK_INTERRUPTIBLE from being lost, the main work of the thread loop - rfcomm_process_sessions() - is performed prior to sleeping. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/core.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 5759bb7054f7..5ba3f6df665c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex); #define rfcomm_lock() mutex_lock(&rfcomm_mutex) #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) -static unsigned long rfcomm_event; static LIST_HEAD(session_list); @@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void) { if (!rfcomm_thread) return; - set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); wake_up_process(rfcomm_thread); } @@ -2038,19 +2036,18 @@ static int rfcomm_run(void *unused) rfcomm_add_listener(BDADDR_ANY); - while (!kthread_should_stop()) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { - /* No pending events. Let's sleep. - * Incoming connections and data will wake us up. */ - schedule(); - } - set_current_state(TASK_RUNNING); + + if (kthread_should_stop()) + break; /* Process stuff */ - clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); rfcomm_process_sessions(); + + schedule(); } + __set_current_state(TASK_RUNNING); rfcomm_kill_listener(); From 950e2d51e866623e4c360280aa63b85ab66d3403 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:41 -0400 Subject: [PATCH 017/287] Bluetooth: rfcomm: Fix lost wakeups waiting to accept socket Fix race conditions which can cause lost wakeups (or missed signals) while waiting to accept an rfcomm socket connection. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/sock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 8f01e6b11a70..482722bbc7a0 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f lock_sock(sk); - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; - goto done; - } - if (sk->sk_type != SOCK_STREAM) { err = -EINVAL; goto done; @@ -501,19 +496,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); - while (!(nsk = bt_accept_dequeue(sk, newsock))) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { - err = -EAGAIN; + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; break; } - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); + nsk = bt_accept_dequeue(sk, newsock); + if (nsk) + break; - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; + if (!timeo) { + err = -EAGAIN; break; } @@ -521,8 +517,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f err = sock_intr_errno(timeo); break; } + + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock(sk); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); if (err) From 9be4e3fbf2d3603e7a7010ede0697166738a788b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:46 -0400 Subject: [PATCH 018/287] Bluetooth: Fix lost wakeups waiting for sock state change Fix race conditions which can cause lost wakeups while waiting for sock state to change. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/af_bluetooth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8add9b499912..117e0d161780 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -494,9 +494,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) BT_DBG("sk %p", sk); add_wait_queue(sk_sleep(sk), &wait); + set_current_state(TASK_INTERRUPTIBLE); while (sk->sk_state != state) { - set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { err = -EINPROGRESS; break; @@ -510,12 +509,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); + set_current_state(TASK_INTERRUPTIBLE); err = sock_error(sk); if (err) break; } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); return err; } From f9a3c20aa07462108fc6fd759dea956053f020bb Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:10:52 -0400 Subject: [PATCH 019/287] Bluetooth: l2cap: Fix lost wakeups waiting to accept socket Fix race conditions which can cause lost wakeups (or misssed signals) while waiting to accept an l2cap socket connection. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_sock.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5c36b3e8739c..7d713b1c4cbd 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -235,30 +235,26 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl lock_sock_nested(sk, SINGLE_DEPTH_NESTING); - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; - goto done; - } - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); BT_DBG("sk %p timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); - while (!(nsk = bt_accept_dequeue(sk, newsock))) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { - err = -EAGAIN; + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; break; } - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + nsk = bt_accept_dequeue(sk, newsock); + if (nsk) + break; - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; + if (!timeo) { + err = -EAGAIN; break; } @@ -266,8 +262,12 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl err = sock_intr_errno(timeo); break; } + + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock_nested(sk, SINGLE_DEPTH_NESTING); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); if (err) From 552b0d3cb9ff648aa503011ef50ca24019cd0f5f Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:11:01 -0400 Subject: [PATCH 020/287] Bluetooth: sco: Fix lost wakeups waiting to accept socket Fix race conditions which can cause lost wakeups (or missed signals) while waiting to accept a sco socket connection. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/sco.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 4c3621b5e0aa..8270f05e3f1f 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -564,30 +564,26 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag lock_sock(sk); - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; - goto done; - } - timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); BT_DBG("sk %p timeo %ld", sk, timeo); /* Wait for an incoming connection. (wake-one). */ add_wait_queue_exclusive(sk_sleep(sk), &wait); - while (!(ch = bt_accept_dequeue(sk, newsock))) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!timeo) { - err = -EAGAIN; + + if (sk->sk_state != BT_LISTEN) { + err = -EBADFD; break; } - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); + ch = bt_accept_dequeue(sk, newsock); + if (ch) + break; - if (sk->sk_state != BT_LISTEN) { - err = -EBADFD; + if (!timeo) { + err = -EAGAIN; break; } @@ -595,8 +591,12 @@ static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flag err = sock_intr_errno(timeo); break; } + + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock(sk); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); if (err) From 38d57555616afcdad7381b02b523d494327494cd Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:11:07 -0400 Subject: [PATCH 021/287] Bluetooth: bnep: Fix lost wakeup of session thread Fix race condition which can result in missing the wakeup intended to stop the session thread. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index ca39fcf010ce..7e8ff3c24942 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -484,9 +484,11 @@ static int bnep_session(void *arg) init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); - while (!kthread_should_stop()) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; /* RX */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { skb_orphan(skb); @@ -504,7 +506,7 @@ static int bnep_session(void *arg) schedule(); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); /* Cleanup session */ From 3a3f5c7df55a1294c9e6e2d0b8cea604b137438f Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 24 Jul 2011 00:11:10 -0400 Subject: [PATCH 022/287] Bluetooth: cmtp: Fix lost wakeup of session thread Fix race condition which can result in missing the wakeup intended to stop the session thread. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index c5b11af908be..2eb854ab10f6 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -292,9 +292,11 @@ static int cmtp_session(void *arg) init_waitqueue_entry(&wait, current); add_wait_queue(sk_sleep(sk), &wait); - while (!kthread_should_stop()) { + while (1) { set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; if (sk->sk_state != BT_CONNECTED) break; @@ -307,7 +309,7 @@ static int cmtp_session(void *arg) schedule(); } - set_current_state(TASK_RUNNING); + __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); down_write(&cmtp_session_sem); From a71a0cf4e9cdb1c43843977a1efc43f96f6efc21 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Mon, 25 Jul 2011 18:36:26 -0400 Subject: [PATCH 023/287] Bluetooth: l2cap: Fix lost wakeup waiting for ERTM acks Fix race condition which can result in missing wakeup during l2cap socket shutdown. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 3204ba8a701c..b3bdb482bbe6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1159,9 +1159,8 @@ int __l2cap_wait_ack(struct sock *sk) int timeo = HZ/5; add_wait_queue(sk_sleep(sk), &wait); - while ((chan->unacked_frames > 0 && chan->conn)) { - set_current_state(TASK_INTERRUPTIBLE); - + set_current_state(TASK_INTERRUPTIBLE); + while (chan->unacked_frames > 0 && chan->conn) { if (!timeo) timeo = HZ/5; @@ -1173,6 +1172,7 @@ int __l2cap_wait_ack(struct sock *sk) release_sock(sk); timeo = schedule_timeout(timeo); lock_sock(sk); + set_current_state(TASK_INTERRUPTIBLE); err = sock_error(sk); if (err) From 6be6b11f006840ba7d8d4b959b3fa0c522f8468a Mon Sep 17 00:00:00 2001 From: Chen Ganir Date: Thu, 28 Jul 2011 15:42:09 +0300 Subject: [PATCH 024/287] Bluetooth: Fixed wrong L2CAP Sock timer value L2CAP connection timeout needs to be assigned as miliseconds and not as jiffies. Signed-off-by: Chen Ganir Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 7d713b1c4cbd..61f1f623091d 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -993,7 +993,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p INIT_LIST_HEAD(&bt_sk(sk)->accept_q); sk->sk_destruct = l2cap_sock_destruct; - sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); + sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT; sock_reset_flag(sk, SOCK_ZAPPED); From 7bdb8a5cf17f66614a9897645efcd4ccc27535ee Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 26 Jul 2011 22:46:54 +0200 Subject: [PATCH 025/287] Bluetooth: Don't use cmd_timer to timeout HCI reset command No command should be send before Command Complete event for HCI reset is received. This fix regression introduced by commit 6bd32326cda(Bluetooth: Use proper timer for hci command timout) for chips whose reset command takes longer to complete (e.g. CSR) resulting in next command being send before HCI reset completed. Signed-off-by: Szymon Janc Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index fca62dcd7f1b..56943add45cc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1209,7 +1209,6 @@ static void hci_cmd_timer(unsigned long arg) BT_ERR("%s command tx timeout", hdev->name); atomic_set(&hdev->cmd_cnt, 1); - clear_bit(HCI_RESET, &hdev->flags); tasklet_schedule(&hdev->cmd_task); } @@ -2408,7 +2407,10 @@ static void hci_cmd_task(unsigned long arg) if (hdev->sent_cmd) { atomic_dec(&hdev->cmd_cnt); hci_send_frame(skb); - mod_timer(&hdev->cmd_timer, + if (test_bit(HCI_RESET, &hdev->flags)) + del_timer(&hdev->cmd_timer); + else + mod_timer(&hdev->cmd_timer, jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); } else { skb_queue_head(&hdev->cmd_q, skb); From 751c10a56802513a6b057c8cf1552cecc1c9afde Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:41:35 -0400 Subject: [PATCH 026/287] Bluetooth: bnep: Fix deadlock in session deletion Commit f4d7cd4a4c introduced the usage of kthread API. kthread_stop is a blocking function which returns only when the thread exits. In this case, the thread can't exit because it's waiting for the write lock, which is being held by bnep_del_connection() which is waiting for the thread to exit -- deadlock. Use atomic_t/wake_up_process instead to signal to the thread to exit. Signed-off-by: Jaikumar Ganesh Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/bnep/bnep.h | 1 + net/bluetooth/bnep/core.c | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index 8e6c06158f8e..e7ee5314f39a 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h @@ -155,6 +155,7 @@ struct bnep_session { unsigned int role; unsigned long state; unsigned long flags; + atomic_t terminate; struct task_struct *task; struct ethhdr eh; diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 7e8ff3c24942..d9edfe8bf9d6 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c @@ -487,7 +487,7 @@ static int bnep_session(void *arg) while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) + if (atomic_read(&s->terminate)) break; /* RX */ while ((skb = skb_dequeue(&sk->sk_receive_queue))) { @@ -642,9 +642,10 @@ int bnep_del_connection(struct bnep_conndel_req *req) down_read(&bnep_session_sem); s = __bnep_get_session(req->dst); - if (s) - kthread_stop(s->task); - else + if (s) { + atomic_inc(&s->terminate); + wake_up_process(s->task); + } else err = -ENOENT; up_read(&bnep_session_sem); From 7176522cdca1f0b78a1434b41761f0334511822a Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:44:21 -0400 Subject: [PATCH 027/287] Bluetooth: cmtp: Fix deadlock in session deletion Commit fada4ac339 introduced the usage of kthread API. kthread_stop is a blocking function which returns only when the thread exits. In this case, the thread can't exit because it's waiting for the write lock, which is being held by cmtp_del_connection() which is waiting for the thread to exit -- deadlock. Revert cmtp_reset_ctr to its original behavior: non-blocking signalling for the session to terminate. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/capi.c | 3 ++- net/bluetooth/cmtp/cmtp.h | 1 + net/bluetooth/cmtp/core.c | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 040f67b12978..50f0d135eb8f 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -386,7 +386,8 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl) capi_ctr_down(ctrl); - kthread_stop(session->task); + atomic_inc(&session->terminate); + wake_up_process(session->task); } static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) diff --git a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h index db43b54ac9af..c32638dddbf9 100644 --- a/net/bluetooth/cmtp/cmtp.h +++ b/net/bluetooth/cmtp/cmtp.h @@ -81,6 +81,7 @@ struct cmtp_session { char name[BTNAMSIZ]; + atomic_t terminate; struct task_struct *task; wait_queue_head_t wait; diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 2eb854ab10f6..42cb2f4c0db1 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -295,7 +295,7 @@ static int cmtp_session(void *arg) while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (kthread_should_stop()) + if (atomic_read(&session->terminate)) break; if (sk->sk_state != BT_CONNECTED) break; @@ -416,7 +416,8 @@ int cmtp_del_connection(struct cmtp_conndel_req *req) skb_queue_purge(&session->transmit); /* Stop session thread */ - kthread_stop(session->task); + atomic_inc(&session->terminate); + wake_up_process(session->task); } else err = -ENOENT; From e9d5cb541b22aa651edc29990092ec5f8174cd39 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:51:26 -0400 Subject: [PATCH 028/287] Bluetooth: hidp: Fix session cleanup on failed conn add Once the session thread is running, cleanup must be handled by the session thread only. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 43b4c2deb7cc..7e19a012970e 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -1044,8 +1044,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, } err = hid_add_device(session->hid); - if (err < 0) - goto err_add_device; + if (err < 0) { + atomic_inc(&session->terminate); + wake_up_process(session->task); + up_write(&hidp_session_sem); + return err; + } if (session->input) { hidp_send_ctrl_message(session, @@ -1059,12 +1063,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, up_write(&hidp_session_sem); return 0; -err_add_device: - hid_destroy_device(session->hid); - session->hid = NULL; - atomic_inc(&session->terminate); - wake_up_process(session->task); - unlink: hidp_del_timer(session); From 1c97e94c0b7c56319754ee6f9ccd2e93fe1ee2b3 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:51:34 -0400 Subject: [PATCH 029/287] Bluetooth: hidp: Fix memory leak of cached report descriptor Free the cached HID report descriptor on thread terminate. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 7e19a012970e..26f0d109ff41 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -764,6 +764,7 @@ static int hidp_session(void *arg) up_write(&hidp_session_sem); + kfree(session->rd_data); kfree(session); return 0; } From 615aedd6e5add8104f031b0d547285652d04d330 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:51:50 -0400 Subject: [PATCH 030/287] Bluetooth: hidp: Only free input device if failed register When an hidp connection is added for a boot protocol input device, only free the allocated device if device registration fails. Subsequent failures should only unregister the device (the input device api documents that unregister will also free the allocated device). Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 26f0d109ff41..a859f9078df6 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -842,6 +842,8 @@ static int hidp_setup_input(struct hidp_session *session, err = input_register_device(input); if (err < 0) { + input_free_device(input); + session->input = NULL; hci_conn_put_device(session->conn); return err; } @@ -1089,7 +1091,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, failed: up_write(&hidp_session_sem); - input_free_device(session->input); kfree(session); return err; } From ff062ea109217329b88693bc9081da893eb8b71b Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:52:01 -0400 Subject: [PATCH 031/287] Bluetooth: hidp: Don't release device ref if never held When an hidp connection is added for a boot protocol input device, don't release a device reference that was never acquired. The device reference is acquired when the session is linked to the session list (which hasn't happened yet when hidp_setup_input is called). Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hidp/core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index a859f9078df6..fb68f344c34a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -844,7 +844,6 @@ static int hidp_setup_input(struct hidp_session *session, if (err < 0) { input_free_device(input); session->input = NULL; - hci_conn_put_device(session->conn); return err; } From 687beaa0d1d937c327e2f97b4b4fa6c23ca70624 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 5 Aug 2011 10:53:52 -0400 Subject: [PATCH 032/287] Bluetooth: cmtp: Fix session cleanup on failed conn add Once the session thread is running, cleanup must be handled by the session thread only. Signed-off-by: Peter Hurley Signed-off-by: Gustavo F. Padovan --- net/bluetooth/cmtp/core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 42cb2f4c0db1..521baa4fe835 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -382,16 +382,17 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) if (!(session->flags & (1 << CMTP_LOOPBACK))) { err = cmtp_attach_device(session); - if (err < 0) - goto detach; + if (err < 0) { + atomic_inc(&session->terminate); + wake_up_process(session->task); + up_write(&cmtp_session_sem); + return err; + } } up_write(&cmtp_session_sem); return 0; -detach: - cmtp_detach_device(session); - unlink: __cmtp_unlink_session(session); From f8afdf481f0fef5e170c6c928cec42879d505654 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 12 Aug 2011 13:31:30 -0400 Subject: [PATCH 033/287] drivers/net/wireless/wl12xx: add missing kfree In each case, the freed data should be freed in the error handling code as well. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @exists@ local idexpression x; statement S,S1; expression E; identifier fl; expression *ptr != NULL; @@ x = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S <... when != x when != if (...) { <+...kfree(x)...+> } when any when != true x == NULL x->fl ...> ( if (x == NULL) S1 | if (...) { ... when != x when forall ( return \(0\|<+...x...+>\|ptr\); | * return ...; ) } ) // Signed-off-by: Julia Lawall Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/acx.c | 6 +----- drivers/net/wireless/wl12xx/testmode.c | 5 ++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 7e33f1f4f3d4..34f6ab53e519 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -77,8 +77,6 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) auth->sleep_auth = sleep_auth; ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); - if (ret < 0) - return ret; out: kfree(auth); @@ -624,10 +622,8 @@ int wl1271_acx_cca_threshold(struct wl1271 *wl) ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD, detection, sizeof(*detection)); - if (ret < 0) { + if (ret < 0) wl1271_warning("failed to set cca threshold: %d", ret); - return ret; - } out: kfree(detection); diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 5d5e1ef87206..88add68bd9ac 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -139,12 +139,15 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) if (ret < 0) { wl1271_warning("testmode cmd interrogate failed: %d", ret); + kfree(cmd); return ret; } skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd)); - if (!skb) + if (!skb) { + kfree(cmd); return -ENOMEM; + } NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd); From 4eb60d869fdad7acd098b53bfd1863c311d8933d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 13 Aug 2011 09:02:43 -0700 Subject: [PATCH 034/287] Revert "iwlagn: sysfs couldn't find the priv pointer" This reverts commit cc1a93e68f6c0d736b771f0746e8e4186f483fdc. This fix introduced a bug: bad pointer in unload. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 69d4ec467dca..fb7e436b40c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -134,7 +134,6 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_data) { bus->drv_data = drv_data; - pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_data); } static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], @@ -455,6 +454,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); } + pci_set_drvdata(pdev, bus); + bus->dev = &pdev->dev; bus->irq = pdev->irq; bus->ops = &pci_ops; @@ -493,12 +494,11 @@ static void iwl_pci_down(struct iwl_bus *bus) static void __devexit iwl_pci_remove(struct pci_dev *pdev) { - struct iwl_priv *priv = pci_get_drvdata(pdev); - void *bus_specific = priv->bus->bus_specific; + struct iwl_bus *bus = pci_get_drvdata(pdev); - iwl_remove(priv); + iwl_remove(bus->drv_data); - iwl_pci_down(bus_specific); + iwl_pci_down(bus); } #ifdef CONFIG_PM @@ -506,20 +506,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) static int iwl_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl_bus *bus = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx. */ - return iwl_suspend(priv); + return iwl_suspend(bus->drv_data); } static int iwl_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl_bus *bus = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if @@ -532,7 +532,7 @@ static int iwl_pci_resume(struct device *device) */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - return iwl_resume(priv); + return iwl_resume(bus->drv_data); } static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); From 16a9d06c753abc44f66f88e03bbecb3f1e45d71b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sat, 13 Aug 2011 09:02:44 -0700 Subject: [PATCH 035/287] iwlagn: sysfs couldn't find the priv pointer This bug has been introduced by: d593411084a56124aa9d80aafa15db8463b2d8f7 Author: Emmanuel Grumbach Date: Mon Jul 11 10:48:51 2011 +0300 iwlagn: simplify the bus architecture Revert part of the buggy patch: dev_get_drvdata will now return iwl_priv as it did before the patch. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 39 +++++++++++--------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index fb7e436b40c7..2fdbffa079c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -134,6 +134,7 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_data) { bus->drv_data = drv_data; + pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_data); } static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], @@ -454,8 +455,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); } - pci_set_drvdata(pdev, bus); - bus->dev = &pdev->dev; bus->irq = pdev->irq; bus->ops = &pci_ops; @@ -479,26 +478,22 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return err; } -static void iwl_pci_down(struct iwl_bus *bus) -{ - struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus->bus_specific; - - pci_disable_msi(pci_bus->pci_dev); - pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base); - pci_release_regions(pci_bus->pci_dev); - pci_disable_device(pci_bus->pci_dev); - pci_set_drvdata(pci_bus->pci_dev, NULL); - - kfree(bus); -} - static void __devexit iwl_pci_remove(struct pci_dev *pdev) { - struct iwl_bus *bus = pci_get_drvdata(pdev); + struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl_bus *bus = priv->bus; + struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); + struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - iwl_remove(bus->drv_data); + iwl_remove(priv); - iwl_pci_down(bus); + pci_disable_msi(pci_dev); + pci_iounmap(pci_dev, pci_bus->hw_base); + pci_release_regions(pci_dev); + pci_disable_device(pci_dev); + pci_set_drvdata(pci_dev, NULL); + + kfree(bus); } #ifdef CONFIG_PM @@ -506,20 +501,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) static int iwl_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_bus *bus = pci_get_drvdata(pdev); + struct iwl_priv *priv = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx. */ - return iwl_suspend(bus->drv_data); + return iwl_suspend(priv); } static int iwl_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_bus *bus = pci_get_drvdata(pdev); + struct iwl_priv *priv = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if @@ -532,7 +527,7 @@ static int iwl_pci_resume(struct device *device) */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - return iwl_resume(bus->drv_data); + return iwl_resume(priv); } static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); From ecb4433550f0620f3d1471ae7099037ede30a91e Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 12 Aug 2011 14:00:59 +0200 Subject: [PATCH 036/287] mac80211: fix suspend/resume races with unregister hw Do not call ->suspend, ->resume methods after we unregister wiphy. Also delete sta_clanup timer after we finish wiphy unregister to avoid this: WARNING: at lib/debugobjects.c:262 debug_print_object+0x85/0xa0() Hardware name: 6369CTO ODEBUG: free active (active state 0) object type: timer_list hint: sta_info_cleanup+0x0/0x180 [mac80211] Modules linked in: aes_i586 aes_generic fuse bridge stp llc autofs4 sunrpc cpufreq_ondemand acpi_cpufreq mperf ext2 dm_mod uinput thinkpad_acpi hwmon sg arc4 rt2800usb rt2800lib crc_ccitt rt2x00usb rt2x00lib mac80211 cfg80211 i2c_i801 iTCO_wdt iTCO_vendor_support e1000e ext4 mbcache jbd2 sd_mod crc_t10dif sr_mod cdrom yenta_socket ahci libahci pata_acpi ata_generic ata_piix i915 drm_kms_helper drm i2c_algo_bit video [last unloaded: microcode] Pid: 5663, comm: pm-hibernate Not tainted 3.1.0-rc1-wl+ #19 Call Trace: [] warn_slowpath_common+0x6d/0xa0 [] ? debug_print_object+0x85/0xa0 [] ? debug_print_object+0x85/0xa0 [] warn_slowpath_fmt+0x2e/0x30 [] debug_print_object+0x85/0xa0 [] ? sta_info_alloc+0x1a0/0x1a0 [mac80211] [] debug_check_no_obj_freed+0xe2/0x180 [] kfree+0x8b/0x150 [] cfg80211_dev_free+0x7e/0x90 [cfg80211] [] wiphy_dev_release+0xd/0x10 [cfg80211] [] device_release+0x19/0x80 [] kobject_release+0x7a/0x1c0 [] ? rtnl_unlock+0x8/0x10 [] ? wiphy_resume+0x6b/0x80 [cfg80211] [] ? kobject_del+0x30/0x30 [] kref_put+0x2d/0x60 [] kobject_put+0x1d/0x50 [] ? mutex_lock+0x14/0x40 [] put_device+0xf/0x20 [] dpm_resume+0xca/0x160 [] hibernation_snapshot+0xcd/0x260 [] ? freeze_processes+0x3f/0x90 [] hibernate+0xcb/0x1e0 [] ? pm_async_store+0x40/0x40 [] state_store+0xa0/0xb0 [] ? pm_async_store+0x40/0x40 [] kobj_attr_store+0x20/0x30 [] sysfs_write_file+0x94/0xf0 [] vfs_write+0x9a/0x160 [] ? sysfs_open_file+0x200/0x200 [] sys_write+0x3d/0x70 [] sysenter_do_call+0x12/0x28 Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- include/net/cfg80211.h | 3 +++ net/mac80211/main.c | 2 +- net/wireless/core.c | 7 +++++++ net/wireless/sysfs.c | 6 ++++-- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d17f47fc9e31..408ae4882d22 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1865,6 +1865,9 @@ struct wiphy { * you need use set_wiphy_dev() (see below) */ struct device dev; + /* protects ->resume, ->suspend sysfs callbacks against unregister hw */ + bool registered; + /* dir in debugfs: ieee80211/ */ struct dentry *debugfsdir; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 866f269183cf..acb44230b251 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1012,7 +1012,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) cancel_work_sync(&local->reconfig_filter); ieee80211_clear_tx_pending(local); - sta_info_stop(local); rate_control_deinitialize(local); if (skb_queue_len(&local->skb_queue) || @@ -1024,6 +1023,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) destroy_workqueue(local->workqueue); wiphy_unregister(local->hw.wiphy); + sta_info_stop(local); ieee80211_wep_free(local); ieee80211_led_exit(local); kfree(local->int_scan_req); diff --git a/net/wireless/core.c b/net/wireless/core.c index 645437cfc464..c14865172da7 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -616,6 +616,9 @@ int wiphy_register(struct wiphy *wiphy) if (res) goto out_rm_dev; + rtnl_lock(); + rdev->wiphy.registered = true; + rtnl_unlock(); return 0; out_rm_dev: @@ -647,6 +650,10 @@ void wiphy_unregister(struct wiphy *wiphy) { struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + rtnl_lock(); + rdev->wiphy.registered = false; + rtnl_unlock(); + rfkill_unregister(rdev->rfkill); /* protect the device list */ diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index c6e4ca6a7d2e..ff574597a854 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -93,7 +93,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) if (rdev->ops->suspend) { rtnl_lock(); - ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); + if (rdev->wiphy.registered) + ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan); rtnl_unlock(); } @@ -112,7 +113,8 @@ static int wiphy_resume(struct device *dev) if (rdev->ops->resume) { rtnl_lock(); - ret = rdev->ops->resume(&rdev->wiphy); + if (rdev->wiphy.registered) + ret = rdev->ops->resume(&rdev->wiphy); rtnl_unlock(); } From 543cc38c8fe86deba4169977c61eb88491036837 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 12 Aug 2011 14:02:04 +0200 Subject: [PATCH 037/287] rt2x00: do not drop usb dev reference counter on suspend When hibernating ->resume may not be called by usb core, but disconnect and probe instead, so we do not increase the counter after decreasing it in ->supend. As a result we free memory early, and get crash when unplugging usb dongle. BUG: unable to handle kernel paging request at 6b6b6b9f IP: [] driver_sysfs_remove+0x10/0x30 *pdpt = 0000000034f21001 *pde = 0000000000000000 Pid: 20, comm: khubd Not tainted 3.1.0-rc1-wl+ #20 LENOVO 6369CTO/6369CTO EIP: 0060:[] EFLAGS: 00010202 CPU: 1 EIP is at driver_sysfs_remove+0x10/0x30 EAX: 6b6b6b6b EBX: f52bba34 ECX: 00000000 EDX: 6b6b6b6b ESI: 6b6b6b6b EDI: c0a0ea20 EBP: f61c9e68 ESP: f61c9e64 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process khubd (pid: 20, ti=f61c8000 task=f6138270 task.ti=f61c8000) Call Trace: [] __device_release_driver+0x1f/0xa0 [] device_release_driver+0x20/0x40 [] bus_remove_device+0x84/0xe0 [] ? device_remove_attrs+0x2a/0x80 [] device_del+0xe7/0x170 [] usb_disconnect+0xd4/0x180 [] hub_thread+0x691/0x1600 [] ? wake_up_bit+0x30/0x30 [] ? complete+0x49/0x60 [] ? hub_disconnect+0xd0/0xd0 [] ? hub_disconnect+0xd0/0xd0 [] kthread+0x74/0x80 [] ? kthread_worker_fn+0x150/0x150 [] kernel_thread_helper+0x6/0x10 Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00usb.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 7fbb55c9da82..1e31050dafc9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -871,18 +871,8 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state) { struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); struct rt2x00_dev *rt2x00dev = hw->priv; - int retval; - - retval = rt2x00lib_suspend(rt2x00dev, state); - if (retval) - return retval; - /* - * Decrease usbdev refcount. - */ - usb_put_dev(interface_to_usbdev(usb_intf)); - - return 0; + return rt2x00lib_suspend(rt2x00dev, state); } EXPORT_SYMBOL_GPL(rt2x00usb_suspend); @@ -891,8 +881,6 @@ int rt2x00usb_resume(struct usb_interface *usb_intf) struct ieee80211_hw *hw = usb_get_intfdata(usb_intf); struct rt2x00_dev *rt2x00dev = hw->priv; - usb_get_dev(interface_to_usbdev(usb_intf)); - return rt2x00lib_resume(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00usb_resume); From b503c7a273c0a3018ad11ea8c513c639120afbf4 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Fri, 19 Aug 2011 18:43:06 +0530 Subject: [PATCH 038/287] ath9k_hw: Fix STA (AR9485) bringup issue due to incorrect MAC address Due to some recent optimization done in the way the mac address bytes are written into the OTP memory, some AR9485 chipsets were forced to use the first byte from the eeprom template and the remaining bytes are read from OTP. AR9485 happens to use generic eeprom template which has 0x1 as the first byte causes issues in bringing up the card. So fixed the eeprom template accordingly to address the issue. Cc: stable@kernel.org Cc: Paul Stewart Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c34bef1bf2b0..1b9400371eaf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -69,7 +69,7 @@ static int ar9003_hw_power_interpolate(int32_t x, static const struct ar9300_eeprom ar9300_default = { .eepromVersion = 2, .templateVersion = 2, - .macAddr = {1, 2, 3, 4, 5, 6}, + .macAddr = {0, 2, 3, 4, 5, 6}, .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, .baseEepHeader = { From 886b66ef2f2d4984f6c72d86a9d8a3ffe4344fa5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 19 Aug 2011 22:14:47 +0200 Subject: [PATCH 039/287] bcma: add uevent to the bus, to autoload drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: David Woodhouse Acked-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/bcma/main.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 873e2e4ac55f..73b7b1a18fab 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -15,6 +15,7 @@ MODULE_LICENSE("GPL"); static int bcma_bus_match(struct device *dev, struct device_driver *drv); static int bcma_device_probe(struct device *dev); static int bcma_device_remove(struct device *dev); +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env); static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -49,6 +50,7 @@ static struct bus_type bcma_bus_type = { .match = bcma_bus_match, .probe = bcma_device_probe, .remove = bcma_device_remove, + .uevent = bcma_device_uevent, .dev_attrs = bcma_device_attrs, }; @@ -227,6 +229,16 @@ static int bcma_device_remove(struct device *dev) return 0; } +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct bcma_device *core = container_of(dev, struct bcma_device, dev); + + return add_uevent_var(env, + "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X", + core->id.manuf, core->id.id, + core->id.rev, core->id.class); +} + static int __init bcma_modinit(void) { int err; From 80900d0140a7648587982c8f299830e900e49165 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 22 Aug 2011 23:19:48 +0300 Subject: [PATCH 040/287] wl12xx: Remove obsolete testmode NVS push command The testmode NVS push command is no longer in use. In addition, it has several implementation issues that prevent it from working correctly: 1. wl1271_tm_cmd_configure relies on wl->chip.id being set. However, since the device was not necessarily booted by the time the function is called, wl->chip.id will be initialized to 0. 2. The NVS file is fetched by calling request_firmware() before it is possible to push an NVS file. 3. The maximum allowed size of nl binary payloads is not sufficient for pushing NVS files. 4. Pushing 128x NVS files will always fail due to a bug in the validation code. 5. In case the pushed NVS file is found invalid, the mutex will be kept locked and the nvs member will become a dangling pointer. Since this feature is not being used, remove it completely instead of fixing it. Signed-off-by: Ido Yariv Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/testmode.c | 45 -------------------------- 1 file changed, 45 deletions(-) diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 88add68bd9ac..4ae8effaee22 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -36,7 +36,6 @@ enum wl1271_tm_commands { WL1271_TM_CMD_TEST, WL1271_TM_CMD_INTERROGATE, WL1271_TM_CMD_CONFIGURE, - WL1271_TM_CMD_NVS_PUSH, WL1271_TM_CMD_SET_PLT_MODE, WL1271_TM_CMD_RECOVER, @@ -190,48 +189,6 @@ static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) return 0; } -static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) -{ - int ret = 0; - size_t len; - void *buf; - - wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push"); - - if (!tb[WL1271_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[WL1271_TM_ATTR_DATA]); - len = nla_len(tb[WL1271_TM_ATTR_DATA]); - - mutex_lock(&wl->mutex); - - kfree(wl->nvs); - - if ((wl->chip.id == CHIP_ID_1283_PG20) && - (len != sizeof(struct wl128x_nvs_file))) - return -EINVAL; - else if (len != sizeof(struct wl1271_nvs_file)) - return -EINVAL; - - wl->nvs = kzalloc(len, GFP_KERNEL); - if (!wl->nvs) { - wl1271_error("could not allocate memory for the nvs file"); - ret = -ENOMEM; - goto out; - } - - memcpy(wl->nvs, buf, len); - wl->nvs_len = len; - - wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); - -out: - mutex_unlock(&wl->mutex); - - return ret; -} - static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) { u32 val; @@ -288,8 +245,6 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) return wl1271_tm_cmd_interrogate(wl, tb); case WL1271_TM_CMD_CONFIGURE: return wl1271_tm_cmd_configure(wl, tb); - case WL1271_TM_CMD_NVS_PUSH: - return wl1271_tm_cmd_nvs_push(wl, tb); case WL1271_TM_CMD_SET_PLT_MODE: return wl1271_tm_cmd_set_plt_mode(wl, tb); case WL1271_TM_CMD_RECOVER: From a15f1c45f393982196c981a8df8b534cc9f3bb80 Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 22 Aug 2011 23:19:49 +0300 Subject: [PATCH 041/287] wl12xx: Fix validation of pm_runtime_get_sync return value wl1271_sdio_power_on checks if the return value of pm_runtime_get_sync is non-zero, and if so bails out. However, pm_runtime_get_sync can return a positive number which does not suggest an error has occurred. This is problematic for two reasons: 1. The function will needlessly bail out without decrementing back the runtime PM reference counter. 2. wl1271_power_on only checks if wl1271_power_on return value is negative. This means that wl1271_power_on will continue even if wl1271_sdio_power_on bailed out. As a result, sdio transactions will be initiated without properly enabling the sdio function and claiming the host. This could even lead to a kernel panic. Fix this by only checking that the return value of pm_runtime_get_sync is non-negative. Signed-off-by: Ido Yariv Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 5cf18c2c23f0..fb1fd5af75ea 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -164,7 +164,7 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) /* If enabled, tell runtime PM not to power off the card */ if (pm_runtime_enabled(&func->dev)) { ret = pm_runtime_get_sync(&func->dev); - if (ret) + if (ret < 0) goto out; } else { /* Runtime PM is disabled: power up the card manually */ From 7a5e4877c14de0827dbda8efa5080089757a8733 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 23 Aug 2011 11:42:25 +0300 Subject: [PATCH 042/287] wl12xx: add max_sched_scan_ssids value to the hw description After commit 5a865ba, we require a separate value to indicate the number of supported SSIDs in scheduled scans. This patch adds a proper value to the wl12xx driver. This fixes a regression in 3.1-rc3 where scheduled scans were not working properly with the wl12xx driver. Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e58c22d21e39..b70ae40ad660 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4283,6 +4283,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); wl->hw->wiphy->max_scan_ssids = 1; + wl->hw->wiphy->max_sched_scan_ssids = 1; /* * Maximum length of elements in scanning probe request templates * should be the maximum length possible for a template, without From 66cb54bd24086b2d871a03035de9b0e79b2b725e Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Wed, 24 Aug 2011 00:44:32 +0400 Subject: [PATCH 043/287] carl9170: Fix mismatch in carl9170_op_set_key mutex lock-unlock If is_main_vif(ar, vif) reports that we have to fall back to software encryption, we goto err_softw; before locking ar->mutex. As a result, we have unprotected call to carl9170_set_operating_mode and unmatched mutex_unlock. The patch fix the issue by adding mutex_lock before goto. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Cc: Acked-By: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 0122930b14c7..0474e6638d21 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1066,8 +1066,10 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, * the high througput speed in 802.11n networks. */ - if (!is_main_vif(ar, vif)) + if (!is_main_vif(ar, vif)) { + mutex_lock(&ar->mutex); goto err_softw; + } /* * While the hardware supports *catch-all* key, for offloading From 8b2a3827bb12430d932cd479b22d906baf08c212 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 24 Aug 2011 21:38:07 +0530 Subject: [PATCH 044/287] ath9k: Fix PS wrappers in ath9k_set_coverage_class this callback is called during suspend/resume and also via iw command. it configures parameters like sifs, slottime, acktimeout in ath9k_hw_init_global_settings where few REG_READ, REG_RMW are also done and hence the need for PS wrappers Cc: stable@kernel.org Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9098aaad97a9..6530694a59ae 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2283,7 +2283,11 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) mutex_lock(&sc->mutex); ah->coverage_class = coverage_class; + + ath9k_ps_wakeup(sc); ath9k_hw_init_global_settings(ah); + ath9k_ps_restore(sc); + mutex_unlock(&sc->mutex); } From e9eb8cbe77139470651c858b8b7a3d20d332cf47 Mon Sep 17 00:00:00 2001 From: Guy Eilam Date: Tue, 16 Aug 2011 19:49:12 +0300 Subject: [PATCH 045/287] wl12xx: use 2 spare TX blocks for GEM cipher Add tx_spare_blocks member to the wl1271 struct for more generic configuration of the amount of spare TX blocks that should be used. The default value is 1. In case GEM cipher is used by the STA, we need 2 spare TX blocks instead of just 1. Signed-off-by: Guy Eilam Acked-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 13 +++++++++++++ drivers/net/wireless/wl12xx/tx.c | 8 +++++--- drivers/net/wireless/wl12xx/tx.h | 1 + drivers/net/wireless/wl12xx/wl12xx.h | 3 +++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 82f4408e89ad..20e7bc78a7fe 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2064,6 +2064,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, wl->session_counter = 0; wl->rate_set = CONF_TX_RATE_MASK_BASIC; wl->vif = NULL; + wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; wl1271_free_ap_keys(wl); memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); wl->ap_fw_ps_map = 0; @@ -2653,6 +2654,17 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + /* + * A STA set to GEM cipher requires 2 tx spare blocks. + * Return to default value when GEM cipher key is removed + */ + if (key_type == KEY_GEM) { + if (action == KEY_ADD_OR_REPLACE) + wl->tx_spare_blocks = 2; + else if (action == KEY_REMOVE) + wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; + } + addr = sta ? sta->addr : bcast_addr; if (is_zero_ether_addr(addr)) { @@ -4599,6 +4611,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->sched_scanning = false; wl->tx_security_seq = 0; wl->tx_security_last_seq_lsb = 0; + wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; wl->role_id = WL12XX_INVALID_ROLE_ID; wl->system_hlid = WL12XX_SYSTEM_HLID; wl->sta_hlid = WL12XX_INVALID_LINK_ID; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 0f1578577b1a..08227e69616b 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -204,9 +204,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, u32 len; u32 total_blocks; int id, ret = -EBUSY, ac; - - /* we use 1 spare block */ - u32 spare_blocks = 1; + u32 spare_blocks = wl->tx_spare_blocks; if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) return -EAGAIN; @@ -220,6 +218,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, in the firmware */ len = wl12xx_calc_packet_alignment(wl, total_len); + /* in case of a dummy packet, use default amount of spare mem blocks */ + if (unlikely(wl12xx_is_dummy_packet(wl, skb))) + spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; + total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + spare_blocks; diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 7da35c0e411b..6519be4b2c38 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -25,6 +25,7 @@ #ifndef __TX_H__ #define __TX_H__ +#define TX_HW_BLOCK_SPARE_DEFAULT 1 #define TX_HW_BLOCK_SIZE 252 #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 61a7c2163ea2..fb2753c46300 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -425,6 +425,9 @@ struct wl1271 { u32 tx_allocated_blocks; u32 tx_results_count; + /* amount of spare TX blocks to use */ + u32 tx_spare_blocks; + /* Accounting for allocated / available Tx packets in HW */ u32 tx_pkts_freed[NUM_TX_QUEUES]; u32 tx_allocated_pkts[NUM_TX_QUEUES]; From cabb81c9a8d8dd7e5f220244246332ab24ef6d80 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 23 Aug 2011 15:56:22 +0300 Subject: [PATCH 046/287] wl12xx: allow 11a AP-mode for wl127x devices There was a check preventing 127x devices from using the 11a band when operating as AP. Since we now support this functionality, remove the check. With this patch, a 11a AP starts ok on 127x cards. Signed-off-by: Arik Nemtsov Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/boot.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index cc70422c0575..6d5664bfc37d 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -294,9 +294,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) */ if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { - /* for now 11a is unsupported in AP mode */ - if (wl->bss_type != BSS_TYPE_AP_BSS && - nvs->general_params.dual_mode_select) + if (nvs->general_params.dual_mode_select) wl->enable_11a = true; } From 53835a2d19f533acb0de2466d1ece7b673556419 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 23 Aug 2011 15:56:23 +0300 Subject: [PATCH 047/287] wl12xx: initialize rate_set on band rates initialization In some corner cases, (invalid) 11g rates were used while working on 11a band. Take care of it by initializing rate_set according to the configured band. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 20e7bc78a7fe..3702e61a89f6 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2200,10 +2200,14 @@ static int wl1271_unjoin(struct wl1271 *wl) static void wl1271_set_band_rate(struct wl1271 *wl) { - if (wl->band == IEEE80211_BAND_2GHZ) + if (wl->band == IEEE80211_BAND_2GHZ) { wl->basic_rate_set = wl->conf.tx.basic_rate; - else + wl->rate_set = wl->conf.tx.basic_rate; + } else { wl->basic_rate_set = wl->conf.tx.basic_rate_5; + wl->rate_set = wl->conf.tx.basic_rate_5; + } + } static bool wl12xx_is_roc(struct wl1271 *wl) From a879ed790a6108a3372be2d22a1ae81f59ab8db8 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 23 Aug 2011 16:37:02 +0300 Subject: [PATCH 048/287] wl12xx: increase psm_entry_retries In congested env, sometimes 5 psm entry retries are not enough. Increase the retries count to 8. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 3702e61a89f6..3edc1d867836 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -236,7 +236,7 @@ static struct conf_drv_settings default_conf = { .ps_poll_recovery_period = 700, .bet_enable = CONF_BET_MODE_ENABLE, .bet_max_consecutive = 50, - .psm_entry_retries = 5, + .psm_entry_retries = 8, .psm_exit_retries = 16, .psm_entry_nullfunc_retries = 3, .psm_entry_hangover_period = 1, From 05dba3550603b9dc8609b5ea7c3ffba4e3bb97f2 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Tue, 23 Aug 2011 16:37:01 +0300 Subject: [PATCH 049/287] wl12xx: enter psm only after station role was started The station didn't get into psm after recovery, because psm was configured before sta role was started. Move wl1271_ps_set_mode() to be executed only after the role was started. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 3edc1d867836..0f72af9fc267 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3361,19 +3361,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, ret = wl1271_acx_conn_monit_params(wl, true); if (ret < 0) goto out; - - /* If we want to go in PSM but we're not there yet */ - if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && - !test_bit(WL1271_FLAG_PSM, &wl->flags)) { - enum wl1271_cmd_ps_mode mode; - - mode = STATION_POWER_SAVE_MODE; - ret = wl1271_ps_set_mode(wl, mode, - wl->basic_rate, - true); - if (ret < 0) - goto out; - } } else { /* use defaults when not associated */ bool was_assoc = @@ -3517,6 +3504,19 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (ret < 0) goto out; } + + /* If we want to go in PSM but we're not there yet */ + if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && + !test_bit(WL1271_FLAG_PSM, &wl->flags)) { + enum wl1271_cmd_ps_mode mode; + + mode = STATION_POWER_SAVE_MODE; + ret = wl1271_ps_set_mode(wl, mode, + wl->basic_rate, + true); + if (ret < 0) + goto out; + } } /* Handle new association with HT. Do this after join. */ From f952079a19c69843f4da2f7e0da008192421c6ce Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 23 Aug 2011 18:34:44 +0300 Subject: [PATCH 050/287] wl12xx: add support for multiple SSIDs in sched_scan The wl12xx firmwares support multiple SSIDs in a single sched_scan run. This patch implements support for it. We use three different types os sched_scan: FILTER_ANY (ie. not filtering, only wildcard SSID in the probe_reqs); FILTER_LIST (ie. send out probe_reqs with the specified SSIDs and only report if they are found); and FILTER_DISABLED (ie. send out probe_reqs with the specified SSIDs, but report anything found). Since we still don't have proper filter support in nl80211/cfg80211 yet, we cannot use filters when the wildcard SSID is used. Thus, we will not filter anything if the wildcard SSID is specified. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 1 + drivers/net/wireless/wl12xx/scan.c | 63 ++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 0f72af9fc267..bde84027ab7f 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4491,6 +4491,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); wl->hw->wiphy->max_scan_ssids = 1; + wl->hw->wiphy->max_sched_scan_ssids = 8; /* * Maximum length of elements in scanning probe request templates * should be the maximum length possible for a template, without diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 7229eaa89018..af9d53c8e19c 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -473,6 +473,48 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, cfg->passive[2] || cfg->active[2]; } +/* Returns 0 if no wildcard is used, 1 if wildcard is used or a + * negative value on error */ +static int +wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, + struct cfg80211_sched_scan_request *req) +{ + struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; + struct cfg80211_ssid *ssid = req->ssids; + int ret, wildcard = 0; + + wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + while ((cmd->n_ssids < req->n_ssids) && ssid) { + if (ssid->ssid_len == 0) + wildcard = 1; + cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_HIDDEN; + cmd->ssids[cmd->n_ssids].len = ssid->ssid_len; + memcpy(cmd->ssids[cmd->n_ssids].ssid, ssid->ssid, + ssid->ssid_len); + ssid++; + cmd->n_ssids++; + } + + wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd)); + + ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd, + sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("cmd sched scan ssid list failed"); + goto out; + } + + ret = wildcard; +out: + kfree(cmd); + return ret; +} + int wl1271_scan_sched_scan_config(struct wl1271 *wl, struct cfg80211_sched_scan_request *req, struct ieee80211_sched_scan_ies *ies) @@ -504,14 +546,21 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) cfg->intervals[i] = cpu_to_le32(req->interval); - if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) { - cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; - cfg->ssid_len = req->ssids[0].ssid_len; - memcpy(cfg->ssid, req->ssids[0].ssid, - req->ssids[0].ssid_len); - } else { + cfg->ssid_len = 0; + if (req->n_ssids == 0) { + wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_ANY"); cfg->filter_type = SCAN_SSID_FILTER_ANY; - cfg->ssid_len = 0; + } else { + ret = wl12xx_scan_sched_scan_ssid_list(wl, req); + if (ret < 0) + goto out; + if (ret) { + wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_DISABLED"); + cfg->filter_type = SCAN_SSID_FILTER_DISABLED; + } else { + wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_LIST"); + cfg->filter_type = SCAN_SSID_FILTER_LIST; + } } if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { From bd4932b8ee2fbdbcf168930de9dcfed1018a085d Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 23 Aug 2011 18:34:45 +0300 Subject: [PATCH 051/287] wl12xx: use SCAN_SSID_TYPE_PUBLIC when using the wildcard in sched_scan When we are scanning for the wildcard SSID in a scheduled scan, we should use SCAN_SSID_TYPE_PUBLIC so that we don't filter out the scan results. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/scan.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index af9d53c8e19c..af4ad2353f59 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -490,9 +490,12 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, return -ENOMEM; while ((cmd->n_ssids < req->n_ssids) && ssid) { - if (ssid->ssid_len == 0) + if (ssid->ssid_len == 0) { wildcard = 1; - cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_HIDDEN; + cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC; + } else { + cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_HIDDEN; + } cmd->ssids[cmd->n_ssids].len = ssid->ssid_len; memcpy(cmd->ssids[cmd->n_ssids].ssid, ssid->ssid, ssid->ssid_len); From 1c1bdd324cd50ac55f7ebf95ef249d946c6e4361 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 26 Aug 2011 12:42:11 +0530 Subject: [PATCH 052/287] ath9k_hw: Fix init mode register regression The commit 172805ad46b78717a738ca5c7908c68f0326d3a9 overwirtes additional clock settings of AR9330 to all AR9300 chips. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 1baca8e4715d..fcafec0605f4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -671,7 +671,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); - if (AR_SREV_9300(ah)) + if (AR_SREV_9330(ah)) REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) From 7c2510120e9b43b0caf32c3786a6ab831f7d9e87 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Fri, 26 Aug 2011 17:24:59 +0200 Subject: [PATCH 053/287] iwlegacy: fix BUG_ON(info->control.rates[0].idx < 0) When trying to connect to 5GHz we can provide negative index to mac80211 what trigger BUG_ON. Reason of iwl-3945-rs malfunction on 5GHz is unknown and needs further investigation. For now, to do not trigger a bug, correct value and just print WARNING. Address bug: https://bugzilla.redhat.com/show_bug.cgi?id=730653 Reported-and-tested-by: Jan Teichmann Cc: stable@kernel.org Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/iwl-3945-rs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c index 977bd2477c6a..164bcae821f8 100644 --- a/drivers/net/wireless/iwlegacy/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-3945-rs.c @@ -822,12 +822,15 @@ static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, out: - rs_sta->last_txrate_idx = index; - if (sband->band == IEEE80211_BAND_5GHZ) - info->control.rates[0].idx = rs_sta->last_txrate_idx - - IWL_FIRST_OFDM_RATE; - else + if (sband->band == IEEE80211_BAND_5GHZ) { + if (WARN_ON_ONCE(index < IWL_FIRST_OFDM_RATE)) + index = IWL_FIRST_OFDM_RATE; + rs_sta->last_txrate_idx = index; + info->control.rates[0].idx = index - IWL_FIRST_OFDM_RATE; + } else { + rs_sta->last_txrate_idx = index; info->control.rates[0].idx = rs_sta->last_txrate_idx; + } IWL_DEBUG_RATE(priv, "leave: %d\n", index); } From 0e4660cbe51276e86dbdab17228733dbcdb49249 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 29 Aug 2011 10:06:14 +0200 Subject: [PATCH 054/287] ath9k_hw: fix calibration on 5 ghz ADC calibrations cannot run on 5 GHz with fast clock enabled. They need to be disabled, otherwise they'll hang and IQ mismatch calibration will not be run either. Signed-off-by: Felix Fietkau Reported-by: Adrian Chadd Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 2d4c0910295b..2d394af82171 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -41,7 +41,8 @@ static bool ar9002_hw_is_cal_supported(struct ath_hw *ah, case ADC_DC_CAL: /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */ if (!IS_CHAN_B(chan) && - !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) + !((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) && + IS_CHAN_HT20(chan))) supported = true; break; } From 3401dc6eba788ebc7c14ce51018d775b1c263399 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 3 Sep 2011 10:58:47 -0500 Subject: [PATCH 055/287] rtlwifi: rtl8192su: Fix problem connecting to HT-enabled AP The driver fails to connect to 802.11n-enabled APs. The patch fixes Bug #42262. Signed-off-by: George Signed-off-by: Larry Finger Cc: Stable [2.6.39+] Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 906e7aa55bc3..3e52a5496224 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -549,15 +549,16 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, (tcb_desc->rts_use_shortpreamble ? 1 : 0) : (tcb_desc->rts_use_shortgi ? 1 : 0))); if (mac->bw_40) { - if (tcb_desc->packet_bw) { + if (rate_flag & IEEE80211_TX_RC_DUP_DATA) { SET_TX_DESC_DATA_BW(txdesc, 1); SET_TX_DESC_DATA_SC(txdesc, 3); + } else if(rate_flag & IEEE80211_TX_RC_40_MHZ_WIDTH){ + SET_TX_DESC_DATA_BW(txdesc, 1); + SET_TX_DESC_DATA_SC(txdesc, mac->cur_40_prime_sc); } else { SET_TX_DESC_DATA_BW(txdesc, 0); - if (rate_flag & IEEE80211_TX_RC_DUP_DATA) - SET_TX_DESC_DATA_SC(txdesc, - mac->cur_40_prime_sc); - } + SET_TX_DESC_DATA_SC(txdesc, 0); + } } else { SET_TX_DESC_DATA_BW(txdesc, 0); SET_TX_DESC_DATA_SC(txdesc, 0); From bac2555c6d86387132930af4d14cb47c4dd3f4f7 Mon Sep 17 00:00:00 2001 From: George Date: Sat, 3 Sep 2011 10:58:48 -0500 Subject: [PATCH 056/287] rtlwifi: Fix problem when switching connections The driver fails to clear encryption keys making it impossible to switch connections. Signed-off-by: George Signed-off-by: Larry Finger Cc: Stable [2.6.39+] Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 1bdc1aa305c0..04c4e9eb6ee6 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -610,6 +610,11 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->link_state = MAC80211_NOLINK; memset(mac->bssid, 0, 6); + + /* reset sec info */ + rtl_cam_reset_sec_info(hw); + + rtl_cam_reset_all_entry(hw); mac->vendor = PEER_UNKNOWN; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, @@ -1063,6 +1068,9 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, *or clear all entry here. */ rtl_cam_delete_one_entry(hw, mac_addr, key_idx); + + rtl_cam_reset_sec_info(hw); + break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, From 4bae7d976976fa52d345805ba686934cd548343e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Sep 2011 12:47:39 +0200 Subject: [PATCH 057/287] mac80211: fix missing sta_lock in __sta_info_destroy Since my commit 34e895075e21be3e21e71d6317440d1ee7969ad0 ("mac80211: allow station add/remove to sleep") there is a race in mac80211 when it clears the TIM bit because a sleeping station disconnected, the spinlock isn't held around the relevant code any more. Use the right API to acquire the spinlock correctly. Cc: stable@kernel.org [2.6.34+] Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/sta_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 3db78b696c5c..21070e9bc8d0 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -665,7 +665,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) BUG_ON(!sdata->bss); atomic_dec(&sdata->bss->num_sta_ps); - __sta_info_clear_tim_bit(sdata->bss, sta); + sta_info_clear_tim_bit(sta); } local->num_sta--; From 6a6b3f3e13decfc4b97263a83ea4e80ac8cc89ae Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 9 Sep 2011 10:41:08 +0530 Subject: [PATCH 058/287] ath9k: Fix kernel panic on unplugging the device when the device is yanked out ath_pci_remove starts doing the cleanups, unregistering the hardware etc. so we should bail out immediately when we get drv_flush callback from mac80211 when the card is being unplugged. the panic occurs after we had associated to an AP. EIP: 0060:[] EFLAGS: 00010246 CPU: 0 EIP is at ath_reset+0xa0/0x1c0 [ath9k] EAX: 00000000 EBX: 000697c0 ECX: 00000002 EDX: f3c3ccf0 ESI: 00000000 EDI: 00000000 EBP: f43e7b78 ESP: f43e7b50 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process kworker/u:2 (pid: 182, ti=f43e6000 task=f3c3c7c0 task.ti=f43e6000) Stack: 0000002a 00000000 00000000 003e7b78 0000000f eaaa8500 ffffffea eaaa97c0 eaaaa000 00000001 f43e7ba8 fb315d23 f99e7721 ecece680 eaaac738 eaaa8500 eaaaa020 000000c8 000000c8 00000000 eaaa8d58 eaaa8500 f43e7bd0 fb080b29 Call Trace: [] ath9k_flush+0x103/0x170 [ath9k] [] __ieee80211_recalc_idle+0x2c9/0x400 [mac80211] [] ieee80211_recalc_idle+0x2e/0x60 [mac80211] [] ieee80211_mgd_deauth+0x173/0x210 [mac80211] [] ieee80211_deauth+0x19/0x20 [mac80211] [] __cfg80211_mlme_deauth+0xf3/0x140 [cfg80211] [] ? __mutex_lock_common+0x1f0/0x380 [] __cfg80211_disconnect+0x18d/0x1f0 [cfg80211] [] cfg80211_netdev_notifier_call+0x159/0x5c0 [cfg80211] [] ? packet_notifier+0x174/0x1f0 [] notifier_call_chain+0x82/0xb0 [] raw_notifier_call_chain+0x1f/0x30 [] call_netdevice_notifiers+0x2c/0x60 [] ? trace_hardirqs_on_caller+0xf4/0x180 [] __dev_close_many+0x4c/0xd0 [] dev_close_many+0x6d/0xc0 [] rollback_registered_many+0x93/0x1c0 [] ? trace_hardirqs_on+0xb/0x10 [] unregister_netdevice_many+0x15/0x50 [] ieee80211_remove_interfaces+0x7b/0xb0 [mac80211] [] ieee80211_unregister_hw+0x4b/0x110 [mac80211] [] ath9k_deinit_device+0x3a/0x60 [ath9k] [] ath_pci_remove+0x46/0x90 [ath9k] [] pci_device_remove+0x44/0x100 [] __device_release_driver+0x64/0xb0 [] device_release_driver+0x27/0x40 [] bus_remove_device+0x7b/0xa0 [] device_del+0xf1/0x180 [] device_unregister+0x10/0x20 [] pci_stop_bus_device+0x6e/0x80 [] pci_remove_bus_device+0x12/0xa0 [] pciehp_unconfigure_device+0x89/0x180 [] ? mark_held_locks+0x64/0x100 [] ? __mutex_unlock_slowpath+0xaf/0x140 [] pciehp_disable_slot+0x64/0x1b0 [] pciehp_power_thread+0xd0/0x100 [] ? process_one_work+0x100/0x4d0 [] process_one_work+0x17c/0x4d0 [] ? process_one_work+0x100/0x4d0 [] ? queue_interrupt_event+0xa0/0xa0 [] worker_thread+0x13b/0x320 [] ? trace_hardirqs_on+0xb/0x10 [] ? manage_workers+0x1e0/0x1e0 [] kthread+0x84/0x90 [] ? __init_kthread_worker+0x60/0x60 [] kernel_thread_helper+0x6/0x10 Cc: Rajkumar Manoharan Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6530694a59ae..722967b86cf1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2303,6 +2303,12 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) mutex_lock(&sc->mutex); cancel_delayed_work_sync(&sc->tx_complete_work); + if (ah->ah_flags & AH_UNPLUGGED) { + ath_dbg(common, ATH_DBG_ANY, "Device has been unplugged!\n"); + mutex_unlock(&sc->mutex); + return; + } + if (sc->sc_flags & SC_OP_INVALID) { ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); mutex_unlock(&sc->mutex); From 456fc37e4519f3f551830ce01c58ddaa35807204 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Sep 2011 21:08:25 +0200 Subject: [PATCH 059/287] iwlagn: fix stack corruption Alexander reported a strange crash in iwlagn that Meenakshi and Wey couldn't reproduce. I just ran into the same issue and tracked it down to stack corruption. This fixes it. The problem was introduced in commit 4b8b99b6e650d0527f3a123744b7459976581d14 Author: Wey-Yi Guy Date: Fri Jul 8 14:29:48 2011 -0700 iwlagn: radio sensor offset in le16 format Cc: Wey-Yi Guy Cc: Meenakshi Venkataraman Reported-by: Alexander Diewald Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index a895a099d086..56211006a182 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -167,7 +167,7 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); - memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(offset_calib)); + memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(*offset_calib)); if (!(cmd.radio_sensor_offset)) cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; From 282cdb325aea4ebbc42ce753b47cc96145eb54bc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Sep 2011 12:09:10 -0700 Subject: [PATCH 060/287] iwlagn: fix command queue timeout If the command queue is constantly busy, which can happen in P2P, the hangcheck timer will frequently find a command in it and will eventually reset the device because nothing sets the timestamp for this queue when commands are processed. Fix this by setting the timestamp when a command completes. Cc: stable@kernel.org #2.6.39, #3.0.0 #3.1.0 Signed-off-by: Johannes Berg SIgned-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c index a6b2b1db0b1d..222d410c586e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c @@ -771,6 +771,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; + txq->time_stamp = jiffies; + iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); /* Input error checking is done when commands are added to queue. */ From 2cca397f76a4a48ac20c34ec1e35bac8c6b08d1c Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 6 Sep 2011 12:10:43 -0700 Subject: [PATCH 061/287] mac80211: Defer tranmission of mesh path errors Under failure conditions, the mesh stack sends PERR messages to the previous sender of the failed frame. This happens in the tx feedback path, in which the transmission queue lock may be taken. Avoid a deadlock by sending the path error via the pending queue. Signed-off-by: John W. Linville --- net/mac80211/mesh_hwmp.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index fd4f76a3e139..63df0bc3dba4 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -8,6 +8,7 @@ */ #include +#include "wme.h" #include "mesh.h" #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG @@ -202,6 +203,27 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, return 0; } + +/* Headroom is not adjusted. Caller should ensure that skb has sufficient + * headroom in case the frame is encrypted. */ +static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + + skb_set_mac_header(skb, 0); + skb_set_network_header(skb, 0); + skb_set_transport_header(skb, 0); + + /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */ + skb_set_queue_mapping(skb, IEEE80211_AC_VO); + skb->priority = 7; + + info->control.vif = &sdata->vif; + ieee80211_set_qos_hdr(local, skb); +} + /** * mesh_send_path error - Sends a PERR mesh management frame * @@ -209,6 +231,10 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, * @target_sn: SN of the broken destination * @target_rcode: reason code for this PERR * @ra: node this frame is addressed to + * + * Note: This function may be called with driver locks taken that the driver + * also acquires in the TX path. To avoid a deadlock we don't transmit the + * frame directly but add it to the pending queue instead. */ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode, const u8 *ra, @@ -222,7 +248,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, if (!skb) return -1; - skb_reserve(skb, local->hw.extra_tx_headroom); + skb_reserve(skb, local->tx_headroom + local->hw.extra_tx_headroom); /* 25 is the size of the common mgmt part (24) plus the size of the * common action part (1) */ @@ -263,7 +289,9 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, pos += 4; memcpy(pos, &target_rcode, 2); - ieee80211_tx_skb(sdata, skb); + /* see note in function header */ + prepare_frame_for_deferred_tx(sdata, skb); + ieee80211_add_pending_skb(local, skb); return 0; } From adb5066ae2cefede1807c29ac16e1faa381416da Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 28 Aug 2011 01:52:10 +0200 Subject: [PATCH 062/287] ath9k_hw: do not apply the 2.4 ghz ack timeout workaround to cts It is only used to workaround interoperability issues related to longer delays in receiving the block ack, so it is not necessary to apply it to the CTS exchange. Should improve throughput slightly, especially when there are lots of retransmissions. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 3a16ba256ef9..468ac4b17dfb 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -960,7 +960,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &common->hw->conf; const struct ath9k_channel *chan = ah->curchan; - int acktimeout; + int acktimeout, ctstimeout; int slottime; int sifstime; int rx_lat = 0, tx_lat = 0, eifs = 0; @@ -1017,6 +1017,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) /* As defined by IEEE 802.11-2007 17.3.8.6 */ acktimeout = slottime + sifstime + 3 * ah->coverage_class; + ctstimeout = acktimeout; /* * Workaround for early ACK timeouts, add an offset to match the @@ -1031,7 +1032,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ath9k_hw_set_sifs_time(ah, sifstime); ath9k_hw_setslottime(ah, slottime); ath9k_hw_set_ack_timeout(ah, acktimeout); - ath9k_hw_set_cts_timeout(ah, acktimeout); + ath9k_hw_set_cts_timeout(ah, ctstimeout); if (ah->globaltxtimeout != (u32) -1) ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); From f533d0fa5efe4bb7a08ead8c6fcf7af243a9035f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 28 Aug 2011 14:28:43 +0200 Subject: [PATCH 063/287] b43: LCN-PHY: add R/W ops for PHY and radio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 42 ++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 4b2cd6d24ce9..cf75d3dce88d 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -232,6 +232,46 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev) { } +/************************************************** + * R/W ops. + **************************************************/ + +static u16 b43_phy_lcn_op_read(struct b43_wldev *dev, u16 reg) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + return b43_read16(dev, B43_MMIO_PHY_DATA); +} + +static void b43_phy_lcn_op_write(struct b43_wldev *dev, u16 reg, u16 value) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, value); +} + +static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, + u16 set) +{ + b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); + b43_write16(dev, B43_MMIO_PHY_DATA, + (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); +} + +static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg) +{ + /* LCN-PHY needs 0x200 for read access */ + reg |= 0x200; + + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); + return b43_read16(dev, B43_MMIO_RADIO24_DATA); +} + +static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg, + u16 value) +{ + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg); + b43_write16(dev, B43_MMIO_RADIO24_DATA, value); +} + /************************************************** * PHY ops struct. **************************************************/ @@ -241,13 +281,11 @@ const struct b43_phy_operations b43_phyops_lcn = { .free = b43_phy_lcn_op_free, .prepare_structs = b43_phy_lcn_op_prepare_structs, .init = b43_phy_lcn_op_init, - /* .phy_read = b43_phy_lcn_op_read, .phy_write = b43_phy_lcn_op_write, .phy_maskset = b43_phy_lcn_op_maskset, .radio_read = b43_phy_lcn_op_radio_read, .radio_write = b43_phy_lcn_op_radio_write, - */ .software_rfkill = b43_phy_lcn_op_software_rfkill, .switch_analog = b43_phy_lcn_op_switch_analog, /* From bd3bf693c72826d7c5be9df09fe3d1198b89b538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 28 Aug 2011 14:28:44 +0200 Subject: [PATCH 064/287] b43: LCN-PHY: implement more PHY ops before radio init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 56 ++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index cf75d3dce88d..9707a2b9cbe0 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -48,7 +48,7 @@ static void b43_radio_2064_init(struct b43_wldev *dev) b43_phy_write(dev, 0x4ea, 0x4688); b43_phy_maskset(dev, 0x4eb, ~0x7, 0x2); b43_phy_mask(dev, 0x4eb, ~0x01c0); - b43_phy_maskset(dev, 0x4eb, 0xff00, 0x19); + b43_phy_maskset(dev, 0x46a, 0xff00, 0x19); b43_lcntab_write(dev, B43_LCNTAB16(0x00, 0x55), 0); @@ -120,6 +120,57 @@ static void b43_phy_lcn_clear_0x07_table(struct b43_wldev *dev) } } +static void b43_phy_lcn_pre_radio_init(struct b43_wldev *dev) +{ + b43_radio_write(dev, 0x11c, 0); + + b43_phy_write(dev, 0x43b, 0); + b43_phy_write(dev, 0x43c, 0); + b43_phy_write(dev, 0x44c, 0); + b43_phy_write(dev, 0x4e6, 0); + b43_phy_write(dev, 0x4f9, 0); + b43_phy_write(dev, 0x4b0, 0); + b43_phy_write(dev, 0x938, 0); + b43_phy_write(dev, 0x4b0, 0); + b43_phy_write(dev, 0x44e, 0); + + b43_phy_set(dev, 0x567, 0x03); + + b43_phy_set(dev, 0x44a, 0x44); + b43_phy_write(dev, 0x44a, 0x80); + + b43_phy_maskset(dev, 0x634, ~0xff, 0xc); + b43_phy_maskset(dev, 0x634, ~0xff, 0xa); + + b43_phy_write(dev, 0x910, 0x1); + + b43_phy_maskset(dev, 0x448, ~0x300, 0x100); + b43_phy_maskset(dev, 0x608, ~0xff, 0x17); + b43_phy_maskset(dev, 0x604, ~0x7ff, 0x3ea); + + b43_phy_set(dev, 0x805, 0x1); + + b43_phy_maskset(dev, 0x42f, ~0x7, 0x3); + b43_phy_maskset(dev, 0x030, ~0x7, 0x3); + + b43_phy_write(dev, 0x414, 0x1e10); + b43_phy_write(dev, 0x415, 0x0640); + + b43_phy_maskset(dev, 0x4df, (u16) ~0xff00, 0xf700); + + b43_phy_set(dev, 0x44a, 0x44); + b43_phy_write(dev, 0x44a, 0x80); + + b43_phy_maskset(dev, 0x434, ~0xff, 0xfd); + b43_phy_maskset(dev, 0x420, ~0xff, 0x10); + + b43_radio_set(dev, 0x09b, 0xf0); + + b43_phy_write(dev, 0x7d6, 0x0902); + + /* TODO: more ops */ +} + /************************************************** * Basic PHY ops. **************************************************/ @@ -170,8 +221,7 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev) /* TODO: various tables ops here */ b43_phy_lcn_clean_0x18_table(dev); - /* TODO: some ops here */ - + b43_phy_lcn_pre_radio_init(dev); b43_phy_lcn_clear_0x07_table(dev); if (dev->phy.radio_ver == 0x2064) From 39f7d33c499980267f68fcb1fadd03bdcbc9ab9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 28 Aug 2011 14:59:58 +0200 Subject: [PATCH 065/287] b43: LCN-PHY: prepare functions for channel switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switching is not fully implemented yet, prepare place for the code. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 86 +++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 9707a2b9cbe0..483953665d08 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -31,6 +31,48 @@ * Radio 2064. **************************************************/ +static void b43_radio_2064_channel_setup(struct b43_wldev *dev) +{ + u16 save[2]; + + b43_radio_set(dev, 0x09d, 0x4); + b43_radio_write(dev, 0x09e, 0xf); + + b43_radio_write(dev, 0x02a, 0xb); + b43_radio_maskset(dev, 0x030, ~0x3, 0xa); + b43_radio_maskset(dev, 0x091, ~0x3, 0); + b43_radio_maskset(dev, 0x038, ~0xf, 0x7); + b43_radio_maskset(dev, 0x030, ~0xc, 0x8); + b43_radio_maskset(dev, 0x05e, ~0xf, 0x8); + b43_radio_maskset(dev, 0x05e, ~0xf0, 0x80); + b43_radio_write(dev, 0x06c, 0x80); + + save[0] = b43_radio_read(dev, 0x044); + save[1] = b43_radio_read(dev, 0x12b); + + b43_radio_set(dev, 0x044, 0x7); + b43_radio_set(dev, 0x12b, 0xe); + + /* TODO */ + + b43_radio_write(dev, 0x040, 0xfb); + + b43_radio_write(dev, 0x041, 0x9a); + b43_radio_write(dev, 0x042, 0xa3); + b43_radio_write(dev, 0x043, 0x0c); + + /* TODO */ + + b43_radio_set(dev, 0x044, 0x0c); + udelay(1); + + b43_radio_write(dev, 0x044, save[0]); + b43_radio_write(dev, 0x12b, save[1]); + + b43_radio_write(dev, 0x038, 0x0); + b43_radio_write(dev, 0x091, 0x7); +} + static void b43_radio_2064_init(struct b43_wldev *dev) { b43_radio_write(dev, 0x09c, 0x0020); @@ -171,6 +213,32 @@ static void b43_phy_lcn_pre_radio_init(struct b43_wldev *dev) /* TODO: more ops */ } +/************************************************** + * Channel switching ops. + **************************************************/ + +static int b43_phy_lcn_set_channel(struct b43_wldev *dev, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type) +{ + /* TODO: PLL and PHY ops */ + + b43_phy_set(dev, 0x44a, 0x44); + b43_phy_write(dev, 0x44a, 0x80); + + b43_phy_set(dev, 0x44a, 0x44); + b43_phy_write(dev, 0x44a, 0x80); + + b43_radio_2064_channel_setup(dev); + mdelay(1); + + b43_phy_lcn_afe_set_unset(dev); + + /* TODO */ + + return 0; +} + /************************************************** * Basic PHY ops. **************************************************/ @@ -265,6 +333,22 @@ static void b43_phy_lcn_op_switch_analog(struct b43_wldev *dev, bool on) } } +static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev, + unsigned int new_channel) +{ + struct ieee80211_channel *channel = dev->wl->hw->conf.channel; + enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; + + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if ((new_channel < 1) || (new_channel > 14)) + return -EINVAL; + } else { + return -EINVAL; + } + + return b43_phy_lcn_set_channel(dev, channel, channel_type); +} + static unsigned int b43_phy_lcn_op_get_default_chan(struct b43_wldev *dev) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) @@ -338,9 +422,7 @@ const struct b43_phy_operations b43_phyops_lcn = { .radio_write = b43_phy_lcn_op_radio_write, .software_rfkill = b43_phy_lcn_op_software_rfkill, .switch_analog = b43_phy_lcn_op_switch_analog, - /* .switch_channel = b43_phy_lcn_op_switch_channel, - */ .get_default_chan = b43_phy_lcn_op_get_default_chan, .recalc_txpower = b43_phy_lcn_op_recalc_txpower, .adjust_txpower = b43_phy_lcn_op_adjust_txpower, From e2d646ce6cc638d229b3079981d5b0c7bc95db7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 28 Aug 2011 18:47:22 +0200 Subject: [PATCH 066/287] ssb: use u16 for storing board rev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specs say about size 2 (u16) and my 14e4:4727 has board rev 0x1211. Signed-off-by: RafaÅ‚ MiÅ‚ecki Acked-by: Larry Finger Signed-off-by: John W. Linville --- include/linux/ssb/ssb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 8623217f84d0..f10ed7b4a714 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -25,7 +25,7 @@ struct ssb_sprom { u8 et1phyaddr; /* MII address for enet1 */ u8 et0mdcport; /* MDIO for enet0 */ u8 et1mdcport; /* MDIO for enet1 */ - u8 board_rev; /* Board revision number from SPROM. */ + u16 board_rev; /* Board revision number from SPROM. */ u8 country_code; /* Country Code */ u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */ u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */ From d703a5ae3ab33226d143917051666fe20b528d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 28 Aug 2011 18:47:23 +0200 Subject: [PATCH 067/287] bcma: extract some basic info about board from SPROM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 166ed13ec066..d7292390d236 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -133,6 +133,15 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i]; *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); } + + bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)]; + + bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; + bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; + bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; + bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; + + bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; } int bcma_sprom_get(struct bcma_bus *bus) From 765b07e46725287ceb1be648b6cb5988fbb585f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 28 Aug 2011 19:59:28 +0200 Subject: [PATCH 068/287] b43: LCN-PHY: implement saving and restoring PHY & radio configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 483953665d08..b617e1f8ca28 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -213,6 +213,39 @@ static void b43_phy_lcn_pre_radio_init(struct b43_wldev *dev) /* TODO: more ops */ } +static void b43_phy_lcn_save_configsth_restore(struct b43_wldev *dev) +{ + u8 i; + + u16 save_radio_regs[6][2] = { + { 0x007, 0 }, { 0x0ff, 0 }, { 0x11f, 0 }, { 0x005, 0 }, + { 0x025, 0 }, { 0x112, 0 }, + }; + u16 save_phy_regs[14][2] = { + { 0x503, 0 }, { 0x4a4, 0 }, { 0x4d0, 0 }, { 0x4d9, 0 }, + { 0x4da, 0 }, { 0x4a6, 0 }, { 0x938, 0 }, { 0x939, 0 }, + { 0x4d8, 0 }, { 0x4d0, 0 }, { 0x4d7, 0 }, { 0x4a5, 0 }, + { 0x40d, 0 }, { 0x4a2, 0 }, + }; + u16 save_radio_4a4; + + for (i = 0; i < 6; i++) + save_radio_regs[i][1] = b43_radio_read(dev, + save_radio_regs[i][0]); + for (i = 0; i < 14; i++) + save_phy_regs[i][1] = b43_phy_read(dev, save_phy_regs[i][0]); + save_radio_4a4 = b43_radio_read(dev, 0x4a4); + + /* TODO: config sth */ + + for (i = 0; i < 6; i++) + b43_radio_write(dev, save_radio_regs[i][0], + save_radio_regs[i][1]); + for (i = 0; i < 14; i++) + b43_phy_write(dev, save_phy_regs[i][0], save_phy_regs[i][1]); + b43_radio_write(dev, 0x4a4, save_radio_4a4); +} + /************************************************** * Channel switching ops. **************************************************/ @@ -297,6 +330,8 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev) else B43_WARN_ON(1); + b43_phy_lcn_save_configsth_restore(dev); + return 0; } From f0425beda4d404a6e751439b562100b902ba9c98 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 28 Aug 2011 21:11:01 +0200 Subject: [PATCH 069/287] mac80211: retry sending failed BAR frames later instead of tearing down aggr Unfortunately failed BAR tx attempts happen more frequently than I expected, and the resulting aggregation teardowns cause performance issues, as the aggregation session does not always get re-established properly. Instead of tearing down the entire aggr session, we can simply store the SSN of the last failed BAR tx attempt, wait for the first successful tx status event, and then send another BAR with the same SSN. Signed-off-by: Felix Fietkau Cc: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/sta_info.h | 5 +++++ net/mac80211/status.c | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index e9eb565506da..56a3d38a2cd1 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -86,6 +86,8 @@ enum ieee80211_sta_info_flags { * @stop_initiator: initiator of a session stop * @tx_stop: TX DelBA frame when stopping * @buf_size: reorder buffer size at receiver + * @failed_bar_ssn: ssn of the last failed BAR tx attempt + * @bar_pending: BAR needs to be re-sent * * This structure's lifetime is managed by RCU, assignments to * the array holding it must hold the aggregation mutex. @@ -106,6 +108,9 @@ struct tid_ampdu_tx { u8 stop_initiator; bool tx_stop; u8 buf_size; + + u16 failed_bar_ssn; + bool bar_pending; }; /** diff --git a/net/mac80211/status.c b/net/mac80211/status.c index e51bd2a1a073..ba405bc4f812 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -127,12 +127,32 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, dev_kfree_skb(skb); } +static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid) +{ + struct tid_ampdu_tx *tid_tx; + + tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); + if (!tid_tx || !tid_tx->bar_pending) + return; + + tid_tx->bar_pending = false; + ieee80211_send_bar(sta->sdata, addr, tid, tid_tx->failed_bar_ssn); +} + static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) { struct ieee80211_mgmt *mgmt = (void *) skb->data; struct ieee80211_local *local = sta->local; struct ieee80211_sub_if_data *sdata = sta->sdata; + if (ieee80211_is_data_qos(mgmt->frame_control)) { + struct ieee80211_hdr *hdr = (void *) skb->data; + u8 *qc = ieee80211_get_qos_ctl(hdr); + u16 tid = qc[0] & 0xf; + + ieee80211_check_pending_bar(sta, hdr->addr1, tid); + } + if (ieee80211_is_action(mgmt->frame_control) && sdata->vif.type == NL80211_IFTYPE_STATION && mgmt->u.action.category == WLAN_CATEGORY_HT && @@ -161,6 +181,18 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) } } +static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn) +{ + struct tid_ampdu_tx *tid_tx; + + tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); + if (!tid_tx) + return; + + tid_tx->failed_bar_ssn = ssn; + tid_tx->bar_pending = true; +} + /* * Use a static threshold for now, best value to be determined * by testing ... @@ -254,10 +286,13 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) */ bar = (struct ieee80211_bar *) skb->data; if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) { + u16 ssn = le16_to_cpu(bar->start_seq_num); + tid = (bar->control & IEEE80211_BAR_CTRL_TID_INFO_MASK) >> IEEE80211_BAR_CTRL_TID_INFO_SHIFT; - ieee80211_stop_tx_ba_session(&sta->sta, tid); + + ieee80211_set_bar_pending(sta, tid, ssn); } } From f4b34b550a5428345f3794e62de48ad5a3db3954 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Mon, 29 Aug 2011 14:23:03 +0530 Subject: [PATCH 070/287] cfg80211/nl80211: Indicate roaming feature capability to userspace. When the rssi of the current AP drops, both wpa_supplicant and the firmware may do a background scan to find a better AP and try to associate. Since firmware based roaming is faster, inform wpa_supplicant to avoid roaming and let the firmware decide to roam if necessary. For fullmac drivers like ath6kl, it is just enough to provide the ESSID and the firmware will decide on the BSSID. Since it is not possible to do pre-auth during roaming for fullmac drivers, the wpa_supplicant needs to completely disconnect with the old AP and reconnect with the new AP. This consumes lot of time and it is better to leave the roaming decision to the firmware. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- include/linux/nl80211.h | 5 +++++ include/net/cfg80211.h | 3 +++ net/wireless/nl80211.c | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 0343504082a8..f2d75e3ceb43 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1045,6 +1045,9 @@ enum nl80211_commands { * @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration * of the station, see &enum nl80211_sta_wme_attr. * + * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of + * roaming to another AP in the same ESS if the signal lever is low. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1257,6 +1260,8 @@ enum nl80211_attrs { NL80211_ATTR_STA_WME, + NL80211_ATTR_ROAM_SUPPORT, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index eb2659aefd97..53609dec2c9f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1619,6 +1619,8 @@ struct cfg80211_ops { * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans. + * @WIPHY_FLAG_SUPPORTS_FW_ROAM: The device supports roaming feature in the + * firmware. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -1633,6 +1635,7 @@ enum wiphy_flags { WIPHY_FLAG_MESH_AUTH = BIT(10), WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), WIPHY_FLAG_ENFORCE_COMBINATIONS = BIT(12), + WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13), }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index bddb5595c659..ad13903c9b89 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -189,6 +189,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { .len = IEEE80211_MAX_DATA_LEN }, [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, + [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, }; /* policy for the key attributes */ @@ -720,6 +721,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); + if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) + NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT); + NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, sizeof(u32) * dev->wiphy.n_cipher_suites, dev->wiphy.cipher_suites); From b8b0b974f212798585d397eefe0c81f5ba3c2829 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 29 Aug 2011 13:39:46 +0200 Subject: [PATCH 071/287] ath9k_hw: drop an unused column in AR5008-AR9002 initvals It was used for the defunct 'turbo' mode which was never implemented in the driver. Saves ~7.5k uncompressed Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar5008_initvals.h | 129 +- .../net/wireless/ath/ath9k/ar9001_initvals.h | 266 +- drivers/net/wireless/ath/ath9k/ar9002_hw.c | 48 +- .../net/wireless/ath/ath9k/ar9002_initvals.h | 3403 +++++++++-------- 4 files changed, 1934 insertions(+), 1912 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index 234617c948a1..68b0561c6bb8 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h @@ -14,70 +14,71 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -static const u32 ar5416Modes[][6] = { - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, - {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, - {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, - {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, - {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, - {0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0}, - {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de}, - {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, - {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, - {0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18}, - {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190}, - {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, - {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134}, - {0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b}, - {0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020}, - {0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80}, - {0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80}, - {0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80}, - {0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120}, - {0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00}, - {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, - {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, - {0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c}, - {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, - {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, - {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, - {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788}, - {0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, - {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa}, - {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, - {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402}, - {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06}, - {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b}, - {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b}, - {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a}, - {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf}, - {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f}, - {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f}, - {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f}, - {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +static const u32 ar5416Modes[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0}, + {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de}, + {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18}, + {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190}, + {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134}, + {0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b}, + {0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020}, + {0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80}, + {0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80}, + {0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80}, + {0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120}, + {0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00}, + {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, + {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788}, + {0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120}, + {0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120}, + {0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa}, + {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, + {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402}, + {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06}, + {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b}, + {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b}, + {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a}, + {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf}, + {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f}, + {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f}, + {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f}, + {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; static const u32 ar5416Common[][2] = { diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h index 6d2e2f3303f9..e8bdc75405f1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h @@ -14,73 +14,74 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -static const u32 ar5416Modes_9100[][6] = { - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, - {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, - {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, - {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, - {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, - {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, - {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2}, - {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, - {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, - {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, - {0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0}, - {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, - {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, - {0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, - {0x00009940, 0x00750604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204}, - {0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020}, - {0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e}, - {0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff}, - {0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, - {0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, - {0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, - {0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120}, - {0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00}, - {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, - {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, - {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329}, - {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, - {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, - {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, - {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788}, - {0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, - {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa}, - {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, - {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402}, - {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06}, - {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b}, - {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b}, - {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a}, - {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf}, - {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f}, - {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f}, - {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f}, - {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +static const u32 ar5416Modes_9100[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2}, + {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20}, + {0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0}, + {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009940, 0x00750604, 0x00754604, 0xfff81204, 0xfff81204}, + {0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020}, + {0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e}, + {0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff}, + {0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, + {0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, + {0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0}, + {0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120}, + {0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00}, + {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, + {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788}, + {0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120}, + {0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120}, + {0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa}, + {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, + {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402}, + {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06}, + {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b}, + {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b}, + {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a}, + {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf}, + {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f}, + {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f}, + {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f}, + {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; static const u32 ar5416Common_9100[][2] = { @@ -666,71 +667,72 @@ static const u32 ar5416Addac_9100[][2] = { {0x000098cc, 0x00000000}, }; -static const u32 ar5416Modes_9160[][6] = { - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, - {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, - {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, - {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, - {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, - {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, - {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68}, - {0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2}, - {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, - {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, - {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, - {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0}, - {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, - {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, - {0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, - {0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020}, - {0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, - {0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, - {0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, - {0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120}, - {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce}, - {0x000099bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00}, - {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, - {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, - {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329}, - {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, - {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, - {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, - {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788}, - {0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120}, - {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, - {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa}, - {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, - {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402}, - {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06}, - {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b}, - {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b}, - {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a}, - {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf}, - {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f}, - {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f}, - {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f}, - {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +static const u32 ar5416Modes_9160[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68}, + {0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2}, + {0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20}, + {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0}, + {0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020}, + {0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, + {0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, + {0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40}, + {0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120}, + {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x000099bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00}, + {0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880}, + {0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788}, + {0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120}, + {0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120}, + {0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa}, + {0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000}, + {0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402}, + {0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06}, + {0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b}, + {0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b}, + {0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a}, + {0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf}, + {0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f}, + {0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f}, + {0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f}, + {0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000}, + {0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; static const u32 ar5416Common_9160[][2] = { diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index b54ab78fb092..626d547d2f06 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -30,7 +30,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) { if (AR_SREV_9271(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271, - ARRAY_SIZE(ar9271Modes_9271), 6); + ARRAY_SIZE(ar9271Modes_9271), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, ARRAY_SIZE(ar9271Common_9271), 2); INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271, @@ -41,21 +41,21 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2); INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, ar9271Modes_9271_1_0_only, - ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6); + ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, - ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6); + ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271, ar9271Modes_high_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6); + ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, ar9271Modes_normal_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6); + ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); return; } if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, - ARRAY_SIZE(ar9287Modes_9287_1_1), 6); + ARRAY_SIZE(ar9287Modes_9287_1_1), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1, ARRAY_SIZE(ar9287Common_9287_1_1), 2); if (ah->config.pcie_clock_req) @@ -71,7 +71,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, - ARRAY_SIZE(ar9285Modes_9285_1_2), 6); + ARRAY_SIZE(ar9285Modes_9285_1_2), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, ARRAY_SIZE(ar9285Common_9285_1_2), 2); @@ -87,7 +87,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) } } else if (AR_SREV_9280_20_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, - ARRAY_SIZE(ar9280Modes_9280_2), 6); + ARRAY_SIZE(ar9280Modes_9280_2), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, ARRAY_SIZE(ar9280Common_9280_2), 2); @@ -105,7 +105,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); } else if (AR_SREV_9160_10_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, - ARRAY_SIZE(ar5416Modes_9160), 6); + ARRAY_SIZE(ar5416Modes_9160), 5); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, ARRAY_SIZE(ar5416Common_9160), 2); INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160, @@ -134,7 +134,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) } } else if (AR_SREV_9100_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100, - ARRAY_SIZE(ar5416Modes_9100), 6); + ARRAY_SIZE(ar5416Modes_9100), 5); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, ARRAY_SIZE(ar5416Common_9100), 2); INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100, @@ -157,7 +157,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar5416Addac_9100), 2); } else { INIT_INI_ARRAY(&ah->iniModes, ar5416Modes, - ARRAY_SIZE(ar5416Modes), 6); + ARRAY_SIZE(ar5416Modes), 5); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, ARRAY_SIZE(ar5416Common), 2); INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, @@ -207,19 +207,19 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9280Modes_backoff_13db_rxgain_9280_2, - ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6); + ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 5); else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9280Modes_backoff_23db_rxgain_9280_2, - ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6); + ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 5); else INIT_INI_ARRAY(&ah->iniModesRxGain, ar9280Modes_original_rxgain_9280_2, - ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); + ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5); } else { INIT_INI_ARRAY(&ah->iniModesRxGain, ar9280Modes_original_rxgain_9280_2, - ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); + ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5); } } @@ -234,15 +234,15 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9280Modes_high_power_tx_gain_9280_2, - ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6); + ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 5); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9280Modes_original_tx_gain_9280_2, - ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); + ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5); } else { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9280Modes_original_tx_gain_9280_2, - ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); + ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5); } } @@ -251,14 +251,14 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) if (AR_SREV_9287_11_OR_LATER(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9287Modes_rx_gain_9287_1_1, - ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); + ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 5); else if (AR_SREV_9280_20(ah)) ar9280_20_hw_init_rxgain_ini(ah); if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9287Modes_tx_gain_9287_1_1, - ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); + ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); } else if (AR_SREV_9280_20(ah)) { ar9280_20_hw_init_txgain_ini(ah); } else if (AR_SREV_9285_12_OR_LATER(ah)) { @@ -270,24 +270,24 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9285Modes_XE2_0_high_power, ARRAY_SIZE( - ar9285Modes_XE2_0_high_power), 6); + ar9285Modes_XE2_0_high_power), 5); } else { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9285Modes_high_power_tx_gain_9285_1_2, ARRAY_SIZE( - ar9285Modes_high_power_tx_gain_9285_1_2), 6); + ar9285Modes_high_power_tx_gain_9285_1_2), 5); } } else { if (AR_SREV_9285E_20(ah)) { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9285Modes_XE2_0_normal_power, ARRAY_SIZE( - ar9285Modes_XE2_0_normal_power), 6); + ar9285Modes_XE2_0_normal_power), 5); } else { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9285Modes_original_tx_gain_9285_1_2, ARRAY_SIZE( - ar9285Modes_original_tx_gain_9285_1_2), 6); + ar9285Modes_original_tx_gain_9285_1_2), 5); } } } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index 7573257731b6..863db321070d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -14,53 +14,54 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -static const u32 ar9280Modes_9280_2[][6] = { - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, - {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, - {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, - {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, - {0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e}, - {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0}, - {0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, - {0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e}, - {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18}, - {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, - {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b, 0x00000016}, - {0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, - {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010}, - {0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, - {0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, - {0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210}, - {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce}, - {0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c}, - {0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444}, - {0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, - {0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019}, - {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, - {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000, 0x13c88000}, - {0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000}, - {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, - {0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000, 0x0c000000}, - {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000}, +static const u32 ar9280Modes_9280_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009850, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20}, + {0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000268, 0x0000000b}, + {0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010}, + {0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, + {0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010}, + {0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210}, + {0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c}, + {0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444}, + {0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019}, + {0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a23c, 0x13c88000, 0x13c88000, 0x13c88001, 0x13c88000}, + {0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e}, + {0x0000a388, 0x0c000000, 0x0c000000, 0x08000000, 0x0c000000}, + {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000}, }; static const u32 ar9280Common_9280_2[][2] = { @@ -424,471 +425,476 @@ static const u32 ar9280Modes_fast_clock_9280_2[][3] = { {0x00009918, 0x0000000b, 0x00000016}, }; -static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = { - {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, - {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, - {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, - {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, - {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, - {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, - {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, - {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, - {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, - {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, - {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, - {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, - {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, - {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, - {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, - {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, - {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, - {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, - {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, - {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, - {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, - {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, - {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, - {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, - {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, - {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, - {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, - {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, - {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, - {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, - {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, - {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, - {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, - {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, - {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, - {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, - {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, - {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, - {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, - {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, - {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, - {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, - {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, - {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, - {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, - {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, - {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, - {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10}, - {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b80, 0x00008b80, 0x00008b80}, - {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b84, 0x00008b84, 0x00008b84}, - {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b88, 0x00008b88, 0x00008b88}, - {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b8c, 0x00008b8c, 0x00008b8c}, - {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b90, 0x00008b90, 0x00008b90}, - {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b94, 0x00008b94, 0x00008b94}, - {0x00009adc, 0x0000b390, 0x0000b390, 0x00008b98, 0x00008b98, 0x00008b98}, - {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008ba4, 0x00008ba4, 0x00008ba4}, - {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008ba8, 0x00008ba8, 0x00008ba8}, - {0x00009ae8, 0x0000b780, 0x0000b780, 0x00008bac, 0x00008bac, 0x00008bac}, - {0x00009aec, 0x0000b784, 0x0000b784, 0x00008bb0, 0x00008bb0, 0x00008bb0}, - {0x00009af0, 0x0000b788, 0x0000b788, 0x00008bb4, 0x00008bb4, 0x00008bb4}, - {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008ba1, 0x00008ba1, 0x00008ba1}, - {0x00009af8, 0x0000b790, 0x0000b790, 0x00008ba5, 0x00008ba5, 0x00008ba5}, - {0x00009afc, 0x0000b794, 0x0000b794, 0x00008ba9, 0x00008ba9, 0x00008ba9}, - {0x00009b00, 0x0000b798, 0x0000b798, 0x00008bad, 0x00008bad, 0x00008bad}, - {0x00009b04, 0x0000d784, 0x0000d784, 0x00008bb1, 0x00008bb1, 0x00008bb1}, - {0x00009b08, 0x0000d788, 0x0000d788, 0x00008bb5, 0x00008bb5, 0x00008bb5}, - {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008ba2, 0x00008ba2, 0x00008ba2}, - {0x00009b10, 0x0000d790, 0x0000d790, 0x00008ba6, 0x00008ba6, 0x00008ba6}, - {0x00009b14, 0x0000f780, 0x0000f780, 0x00008baa, 0x00008baa, 0x00008baa}, - {0x00009b18, 0x0000f784, 0x0000f784, 0x00008bae, 0x00008bae, 0x00008bae}, - {0x00009b1c, 0x0000f788, 0x0000f788, 0x00008bb2, 0x00008bb2, 0x00008bb2}, - {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008bb6, 0x00008bb6, 0x00008bb6}, - {0x00009b24, 0x0000f790, 0x0000f790, 0x00008ba3, 0x00008ba3, 0x00008ba3}, - {0x00009b28, 0x0000f794, 0x0000f794, 0x00008ba7, 0x00008ba7, 0x00008ba7}, - {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008bab, 0x00008bab, 0x00008bab}, - {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008baf, 0x00008baf, 0x00008baf}, - {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008bb3, 0x00008bb3, 0x00008bb3}, - {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008bb7, 0x00008bb7, 0x00008bb7}, - {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008bc3, 0x00008bc3, 0x00008bc3}, - {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008bc7, 0x00008bc7, 0x00008bc7}, - {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008bcb, 0x00008bcb, 0x00008bcb}, - {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008bcf, 0x00008bcf, 0x00008bcf}, - {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008bd3, 0x00008bd3, 0x00008bd3}, - {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008bd7, 0x00008bd7, 0x00008bd7}, - {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb, 0x00008bdb}, - {0x00009848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, - {0x0000a848, 0x00001066, 0x00001066, 0x00001055, 0x00001055, 0x00001055}, +static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290}, + {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308}, + {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b80, 0x00008b80}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b84, 0x00008b84}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b88, 0x00008b88}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b8c, 0x00008b8c}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b90, 0x00008b90}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b94, 0x00008b94}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008b98, 0x00008b98}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008ba4, 0x00008ba4}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008ba8, 0x00008ba8}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x00008bac, 0x00008bac}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00008bb0, 0x00008bb0}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00008bb4, 0x00008bb4}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008ba1, 0x00008ba1}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00008ba5, 0x00008ba5}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x00008ba9, 0x00008ba9}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x00008bad, 0x00008bad}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x00008bb1, 0x00008bb1}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00008bb5, 0x00008bb5}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008ba2, 0x00008ba2}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00008ba6, 0x00008ba6}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x00008baa, 0x00008baa}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00008bae, 0x00008bae}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x00008bb2, 0x00008bb2}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008bb6, 0x00008bb6}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x00008ba3, 0x00008ba3}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x00008ba7, 0x00008ba7}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008bab, 0x00008bab}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008baf, 0x00008baf}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008bb3, 0x00008bb3}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008bb7, 0x00008bb7}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008bc3, 0x00008bc3}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008bc7, 0x00008bc7}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008bcb, 0x00008bcb}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008bcf, 0x00008bcf}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008bd3, 0x00008bd3}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008bd7, 0x00008bd7}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008bdb, 0x00008bdb}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008bdb, 0x00008bdb}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008bdb, 0x00008bdb}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008bdb, 0x00008bdb}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008bdb, 0x00008bdb}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008bdb, 0x00008bdb}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008bdb, 0x00008bdb}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008bdb, 0x00008bdb}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008bdb, 0x00008bdb}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008bdb, 0x00008bdb}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008bdb, 0x00008bdb}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008bdb, 0x00008bdb}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008bdb, 0x00008bdb}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008bdb, 0x00008bdb}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008bdb, 0x00008bdb}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008bdb, 0x00008bdb}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008bdb, 0x00008bdb}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008bdb, 0x00008bdb}, + {0x00009848, 0x00001066, 0x00001066, 0x00001055, 0x00001055}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001055, 0x00001055}, }; -static const u32 ar9280Modes_original_rxgain_9280_2[][6] = { - {0x00009a00, 0x00008184, 0x00008184, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a04, 0x00008188, 0x00008188, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a08, 0x0000818c, 0x0000818c, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a0c, 0x00008190, 0x00008190, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a10, 0x00008194, 0x00008194, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, - {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, - {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, - {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, - {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, - {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, - {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, - {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, - {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, - {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, - {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, - {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, - {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, - {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, - {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, - {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, - {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, - {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, - {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, - {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, - {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, - {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, - {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, - {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, - {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, - {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, - {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, - {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, - {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, - {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, - {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, - {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, - {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, - {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, - {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, - {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, - {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, - {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, - {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, - {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, - {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, - {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, - {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, - {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, - {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, - {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, - {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, - {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, - {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, - {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, - {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, - {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, - {0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c}, - {0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310}, - {0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384}, - {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388}, - {0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324}, - {0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704}, - {0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4}, - {0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8}, - {0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710}, - {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714}, - {0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720}, - {0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724}, - {0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728}, - {0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c}, - {0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0}, - {0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4}, - {0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8}, - {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0}, - {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4}, - {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8}, - {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5}, - {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9}, - {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad}, - {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1}, - {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5}, - {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9}, - {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5}, - {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9}, - {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1}, - {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5}, - {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9}, - {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6}, - {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca}, - {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce}, - {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2}, - {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6}, - {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3}, - {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7}, - {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb}, - {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf}, - {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7}, - {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db}, - {0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, - {0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063}, +static const u32 ar9280Modes_original_rxgain_9280_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009a00, 0x00008184, 0x00008184, 0x00008000, 0x00008000}, + {0x00009a04, 0x00008188, 0x00008188, 0x00008000, 0x00008000}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00008000, 0x00008000}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00008000, 0x00008000}, + {0x00009a10, 0x00008194, 0x00008194, 0x00008000, 0x00008000}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db}, + {0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063}, }; -static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = { - {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290}, - {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300}, - {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304}, - {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308}, - {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c}, - {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000}, - {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004}, - {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008}, - {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c}, - {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080}, - {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084}, - {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088}, - {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c}, - {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100}, - {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104}, - {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108}, - {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c}, - {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110}, - {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114}, - {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180}, - {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184}, - {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188}, - {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c}, - {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190}, - {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194}, - {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0}, - {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c}, - {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8}, - {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284}, - {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288}, - {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224}, - {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290}, - {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300}, - {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304}, - {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308}, - {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c}, - {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380}, - {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384}, - {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700}, - {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704}, - {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708}, - {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c}, - {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780}, - {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784}, - {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00}, - {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04}, - {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08}, - {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c}, - {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80}, - {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84}, - {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88}, - {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c}, - {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90}, - {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80}, - {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84}, - {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88}, - {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c}, - {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90}, - {0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310}, - {0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314}, - {0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320}, - {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324}, - {0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328}, - {0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c}, - {0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330}, - {0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334}, - {0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321}, - {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325}, - {0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329}, - {0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d}, - {0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331}, - {0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335}, - {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322}, - {0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326}, - {0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a}, - {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e}, - {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332}, - {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336}, - {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323}, - {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327}, - {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b}, - {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f}, - {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333}, - {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337}, - {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343}, - {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347}, - {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b}, - {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f}, - {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353}, - {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357}, - {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b}, - {0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, - {0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a}, +static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290}, + {0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300}, + {0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304}, + {0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308}, + {0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c}, + {0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000}, + {0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004}, + {0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008}, + {0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c}, + {0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080}, + {0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084}, + {0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088}, + {0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c}, + {0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100}, + {0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104}, + {0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108}, + {0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c}, + {0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110}, + {0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114}, + {0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180}, + {0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184}, + {0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188}, + {0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c}, + {0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190}, + {0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194}, + {0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0}, + {0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c}, + {0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8}, + {0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284}, + {0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288}, + {0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224}, + {0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290}, + {0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300}, + {0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304}, + {0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308}, + {0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c}, + {0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380}, + {0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384}, + {0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700}, + {0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704}, + {0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708}, + {0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c}, + {0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780}, + {0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784}, + {0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00}, + {0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04}, + {0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08}, + {0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c}, + {0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80}, + {0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84}, + {0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88}, + {0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c}, + {0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90}, + {0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80}, + {0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84}, + {0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88}, + {0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c}, + {0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90}, + {0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310}, + {0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314}, + {0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320}, + {0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324}, + {0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328}, + {0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c}, + {0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330}, + {0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334}, + {0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321}, + {0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325}, + {0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329}, + {0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d}, + {0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331}, + {0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335}, + {0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322}, + {0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326}, + {0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a}, + {0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e}, + {0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332}, + {0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336}, + {0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323}, + {0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327}, + {0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b}, + {0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f}, + {0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333}, + {0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337}, + {0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343}, + {0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347}, + {0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b}, + {0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f}, + {0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353}, + {0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357}, + {0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b}, + {0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b}, + {0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b}, + {0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b}, + {0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b}, + {0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b}, + {0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b}, + {0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b}, + {0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b}, + {0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b}, + {0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b}, + {0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b}, + {0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b}, + {0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a}, + {0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a}, }; -static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = { - {0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, - {0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce}, - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002}, - {0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008}, - {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010}, - {0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012}, - {0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014}, - {0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a}, - {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211}, - {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, - {0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411}, - {0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413}, - {0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811}, - {0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813}, - {0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14}, - {0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50}, - {0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c}, - {0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a}, - {0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92}, - {0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2}, - {0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5}, - {0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54}, - {0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5}, - {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, - {0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, - {0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, - {0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, - {0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, - {0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, - {0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, +static const u32 ar9280Modes_high_power_tx_gain_9280_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652}, + {0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002}, + {0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008}, + {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010}, + {0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012}, + {0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014}, + {0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a}, + {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211}, + {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213}, + {0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411}, + {0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413}, + {0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811}, + {0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813}, + {0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14}, + {0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50}, + {0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c}, + {0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a}, + {0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92}, + {0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2}, + {0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5}, + {0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54}, + {0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5}, + {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, + {0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, + {0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff}, + {0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, + {0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000}, + {0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, + {0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480}, }; -static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = { - {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652}, - {0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce}, - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002}, - {0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009}, - {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b}, - {0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012}, - {0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048}, - {0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a}, - {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211}, - {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213}, - {0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b}, - {0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412}, - {0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414}, - {0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a}, - {0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649}, - {0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b}, - {0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49}, - {0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48}, - {0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a}, - {0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88}, - {0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a}, - {0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9}, - {0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42}, - {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, - {0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, - {0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, - {0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, - {0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, - {0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, - {0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, +static const u32 ar9280Modes_original_tx_gain_9280_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652}, + {0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce}, + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002}, + {0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009}, + {0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b}, + {0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012}, + {0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048}, + {0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a}, + {0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211}, + {0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213}, + {0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b}, + {0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412}, + {0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414}, + {0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a}, + {0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649}, + {0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b}, + {0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49}, + {0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48}, + {0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a}, + {0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88}, + {0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a}, + {0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9}, + {0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42}, + {0x0000a3ec, 0x00f70081, 0x00f70081, 0x00f70081, 0x00f70081}, + {0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, + {0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff}, + {0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, + {0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000}, + {0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, + {0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480}, }; static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = { @@ -947,309 +953,310 @@ static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = { {0x00004044, 0x00000000}, }; -static const u32 ar9285Modes_9285_1_2[][6] = { - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, - {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, - {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, - {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, - {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e}, - {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0}, - {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, - {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, - {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, - {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e}, - {0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18}, - {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, - {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, - {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d}, - {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010}, - {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c}, - {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, - {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f}, - {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, - {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, - {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, - {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, - {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, - {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, - {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, - {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, - {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, - {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, - {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, - {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, - {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, - {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, - {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, - {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, - {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, - {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, - {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, - {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, - {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, - {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, - {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, - {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, - {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, - {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, - {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, - {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, - {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, - {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, - {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, - {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, - {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, - {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, - {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, - {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, - {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, - {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, - {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, - {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, - {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, - {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, - {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, - {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, - {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, - {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, - {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, - {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, - {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, - {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, - {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, - {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, - {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, - {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, - {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, - {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, - {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, - {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, - {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, - {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, - {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, - {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, - {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, - {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, - {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, - {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, - {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, - {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, - {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, - {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, - {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, - {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, - {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, - {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, - {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, - {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, - {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, - {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, - {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, - {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, - {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, - {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, - {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, - {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, - {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, - {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, - {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, - {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, - {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, - {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, - {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, - {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, - {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, - {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, - {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, - {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, - {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, - {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, - {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, - {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, - {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, - {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, - {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, - {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, - {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, - {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, - {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, - {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, - {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, - {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, - {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, - {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, - {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, - {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, - {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, - {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, - {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, - {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, - {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, - {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, - {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, - {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, - {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, - {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, - {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, - {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, - {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, - {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, - {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, - {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, - {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, - {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, - {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, - {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, - {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, - {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, - {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, - {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, - {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, - {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, - {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, - {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, - {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, - {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, - {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, - {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, - {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, - {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, - {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, - {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, - {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, - {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, - {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, - {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, - {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, - {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, - {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, - {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, - {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, - {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, - {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, - {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, - {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, - {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, - {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, - {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, - {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, - {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, - {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, - {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, - {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, - {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, - {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, - {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, - {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, - {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, - {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, - {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, - {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, - {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, - {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004}, - {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, - {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, - {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, - {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000}, - {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, +static const u32 ar9285Modes_9285_1_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620}, + {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053}, + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e}, + {0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20}, + {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d}, + {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020}, + {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c}, + {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084}, + {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088}, + {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c}, + {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100}, + {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104}, + {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108}, + {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c}, + {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110}, + {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114}, + {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180}, + {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184}, + {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188}, + {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c}, + {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190}, + {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194}, + {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0}, + {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c}, + {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8}, + {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284}, + {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288}, + {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224}, + {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290}, + {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300}, + {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304}, + {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308}, + {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c}, + {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380}, + {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384}, + {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700}, + {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704}, + {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c}, + {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780}, + {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784}, + {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00}, + {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04}, + {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08}, + {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c}, + {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80}, + {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84}, + {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88}, + {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c}, + {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90}, + {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80}, + {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84}, + {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88}, + {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c}, + {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90}, + {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c}, + {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310}, + {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384}, + {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388}, + {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324}, + {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704}, + {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4}, + {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8}, + {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710}, + {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714}, + {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720}, + {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724}, + {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728}, + {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c}, + {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0}, + {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4}, + {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8}, + {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0}, + {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4}, + {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8}, + {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5}, + {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9}, + {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad}, + {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1}, + {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5}, + {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9}, + {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5}, + {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9}, + {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1}, + {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5}, + {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9}, + {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6}, + {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca}, + {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce}, + {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2}, + {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6}, + {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3}, + {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7}, + {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb}, + {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf}, + {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7}, + {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084}, + {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100}, + {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104}, + {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110}, + {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114}, + {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180}, + {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c}, + {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190}, + {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c}, + {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8}, + {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288}, + {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224}, + {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290}, + {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304}, + {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c}, + {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384}, + {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700}, + {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704}, + {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c}, + {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780}, + {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784}, + {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04}, + {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08}, + {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c}, + {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90}, + {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80}, + {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84}, + {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88}, + {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c}, + {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90}, + {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c}, + {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310}, + {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384}, + {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388}, + {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324}, + {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704}, + {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4}, + {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8}, + {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710}, + {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714}, + {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720}, + {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0}, + {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4}, + {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8}, + {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0}, + {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8}, + {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5}, + {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9}, + {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1}, + {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5}, + {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9}, + {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9}, + {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1}, + {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5}, + {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6}, + {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca}, + {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce}, + {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6}, + {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3}, + {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7}, + {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf}, + {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7}, + {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004}, + {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000}, + {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e}, }; static const u32 ar9285Common_9285_1_2[][2] = { @@ -1572,164 +1579,168 @@ static const u32 ar9285Common_9285_1_2[][2] = { {0x00007870, 0x10142c00}, }; -static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, - {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, - {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, - {0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803}, - {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, - {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, - {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, - {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, - {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, - {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, - {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, +static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240}, + {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241}, + {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600}, + {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802}, + {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805}, + {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40}, + {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80}, + {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, + {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, + {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, + {0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803}, + {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, + {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, + {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, + {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, + {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, }; -static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, - {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, - {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, - {0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801}, - {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, - {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, - {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, - {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, - {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, - {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, - {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, - {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, +static const u32 ar9285Modes_original_tx_gain_9285_1_2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608}, + {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618}, + {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9}, + {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718}, + {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758}, + {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a}, + {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f}, + {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8}, + {0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b}, + {0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e}, + {0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801}, + {0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe}, + {0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652}, + {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, + {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, }; -static const u32 ar9285Modes_XE2_0_normal_power[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, - {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, - {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae}, - {0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441}, - {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, - {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, - {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, - {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, - {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652}, - {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, - {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, - {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, - {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, +static const u32 ar9285Modes_XE2_0_normal_power[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608}, + {0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618}, + {0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9}, + {0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718}, + {0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758}, + {0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a}, + {0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f}, + {0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, + {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b}, + {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e}, + {0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441}, + {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, + {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652}, + {0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c}, + {0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, + {0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c}, + {0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c}, }; -static const u32 ar9285Modes_XE2_0_high_power[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000}, - {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, - {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b}, - {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e}, - {0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443}, - {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, - {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, - {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, - {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652}, - {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, - {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, - {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, +static const u32 ar9285Modes_XE2_0_high_power[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240}, + {0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241}, + {0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600}, + {0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802}, + {0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805}, + {0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40}, + {0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80}, + {0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8}, + {0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b}, + {0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e}, + {0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443}, + {0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe}, + {0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c}, + {0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7}, + {0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, + {0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, }; static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { @@ -1760,50 +1771,51 @@ static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { {0x00004044, 0x00000000}, }; -static const u32 ar9287Modes_9287_1_1[][6] = { - {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0}, - {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0}, - {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, - {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0}, - {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880}, - {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303}, - {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001}, - {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007}, - {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e}, - {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0}, - {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2}, - {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e}, - {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18}, - {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881}, - {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016}, - {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d}, - {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010}, - {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, - {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010}, - {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210}, - {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce}, - {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c}, - {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444}, - {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a}, - {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000}, - {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, - {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +static const u32 ar9287Modes_9287_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00}, + {0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440}, + {0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300}, + {0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200}, + {0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001}, + {0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007}, + {0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0}, + {0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2}, + {0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e}, + {0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20}, + {0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881}, + {0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898}, + {0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b}, + {0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d}, + {0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010}, + {0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, + {0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, + {0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210}, + {0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce}, + {0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c}, + {0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4}, + {0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444}, + {0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e}, + {0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; static const u32 ar9287Common_9287_1_1[][2] = { @@ -2189,313 +2201,315 @@ static const u32 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1[][2] = { {0x0000a1fc, 0xca9228ee}, }; -static const u32 ar9287Modes_tx_gain_9287_1_1[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002}, - {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004}, - {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a}, - {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c}, - {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b}, - {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a}, - {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a}, - {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a}, - {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a}, - {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, - {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a}, - {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a}, - {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c}, - {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc}, - {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4}, - {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc}, - {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede}, - {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, - {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e}, - {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e}, - {0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062}, - {0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064}, - {0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4}, - {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa}, - {0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac}, - {0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4}, - {0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4}, - {0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134}, - {0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174}, - {0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c}, - {0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e}, - {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be}, - {0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe}, - {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000}, +static const u32 ar9287Modes_tx_gain_9287_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002}, + {0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c}, + {0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b}, + {0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a}, + {0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a}, + {0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a}, + {0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a}, + {0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a}, + {0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a}, + {0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a}, + {0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c}, + {0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc}, + {0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4}, + {0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc}, + {0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede}, + {0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e}, + {0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e}, + {0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e}, + {0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062}, + {0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064}, + {0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4}, + {0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa}, + {0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac}, + {0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4}, + {0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4}, + {0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134}, + {0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174}, + {0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c}, + {0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e}, + {0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be}, + {0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe}, + {0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000}, }; -static const u32 ar9287Modes_rx_gain_9287_1_1[][6] = { - {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, - {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, - {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, - {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, - {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, - {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, - {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, - {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, - {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, - {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, - {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, - {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, - {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, - {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, - {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, - {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, - {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, - {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, - {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, - {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, - {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, - {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, - {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, - {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, - {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, - {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, - {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, - {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, - {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, - {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, - {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, - {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, - {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, - {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, - {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, - {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, - {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, - {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, - {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, - {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, - {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, - {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, - {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, - {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, - {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, - {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, - {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, - {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, - {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, - {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, - {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, - {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, - {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, - {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, - {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, - {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, - {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, - {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, - {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, - {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, - {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, - {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, - {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, - {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, - {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, - {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, - {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, - {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, - {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, - {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, - {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, - {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, - {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, - {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, - {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, - {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, - {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, - {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, - {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, - {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, - {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, - {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, - {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, - {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, - {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, - {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, - {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, - {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, - {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, - {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, - {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, - {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, - {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, - {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, - {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, - {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, - {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, - {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, - {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, - {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, - {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, - {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, - {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, - {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120}, - {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124}, - {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128}, - {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c}, - {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130}, - {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194}, - {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198}, - {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c}, - {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210}, - {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284}, - {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288}, - {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c}, - {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290}, - {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294}, - {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0}, - {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4}, - {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8}, - {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac}, - {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0}, - {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4}, - {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8}, - {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4}, - {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708}, - {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c}, - {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710}, - {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04}, - {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08}, - {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c}, - {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10}, - {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14}, - {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18}, - {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c}, - {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90}, - {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94}, - {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98}, - {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4}, - {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8}, - {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04}, - {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08}, - {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c}, - {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10}, - {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14}, - {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18}, - {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c}, - {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90}, - {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18}, - {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24}, - {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28}, - {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314}, - {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318}, - {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c}, - {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390}, - {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394}, - {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398}, - {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4}, - {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8}, - {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac}, - {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0}, - {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380}, - {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384}, - {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388}, - {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710}, - {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714}, - {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718}, - {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10}, - {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14}, - {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18}, - {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c}, - {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90}, - {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94}, - {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c}, - {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90}, - {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94}, - {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0}, - {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4}, - {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8}, - {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac}, - {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0}, - {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4}, - {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1}, - {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5}, - {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9}, - {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad}, - {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1}, - {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5}, - {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9}, - {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5}, - {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9}, - {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd}, - {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1}, - {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5}, - {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2}, - {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6}, - {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca}, - {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce}, - {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2}, - {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6}, - {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda}, - {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7}, - {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb}, - {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf}, - {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3}, - {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7}, - {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb}, - {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, - {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067}, +static const u32 ar9287Modes_rx_gain_9287_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120}, + {0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124}, + {0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128}, + {0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c}, + {0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130}, + {0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194}, + {0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198}, + {0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c}, + {0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210}, + {0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284}, + {0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288}, + {0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c}, + {0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290}, + {0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294}, + {0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0}, + {0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4}, + {0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8}, + {0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac}, + {0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0}, + {0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4}, + {0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8}, + {0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4}, + {0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708}, + {0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c}, + {0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710}, + {0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04}, + {0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08}, + {0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c}, + {0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10}, + {0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14}, + {0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c}, + {0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90}, + {0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94}, + {0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98}, + {0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4}, + {0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8}, + {0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04}, + {0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08}, + {0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c}, + {0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10}, + {0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14}, + {0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18}, + {0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c}, + {0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90}, + {0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18}, + {0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24}, + {0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28}, + {0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314}, + {0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318}, + {0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c}, + {0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390}, + {0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394}, + {0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398}, + {0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4}, + {0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8}, + {0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac}, + {0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0}, + {0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380}, + {0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384}, + {0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388}, + {0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710}, + {0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714}, + {0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718}, + {0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10}, + {0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14}, + {0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18}, + {0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c}, + {0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90}, + {0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94}, + {0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c}, + {0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90}, + {0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94}, + {0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0}, + {0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4}, + {0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8}, + {0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac}, + {0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0}, + {0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4}, + {0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1}, + {0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5}, + {0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9}, + {0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad}, + {0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1}, + {0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5}, + {0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9}, + {0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5}, + {0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9}, + {0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd}, + {0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1}, + {0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5}, + {0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2}, + {0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6}, + {0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca}, + {0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce}, + {0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2}, + {0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6}, + {0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda}, + {0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7}, + {0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb}, + {0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf}, + {0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3}, + {0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7}, + {0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120}, + {0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c}, + {0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130}, + {0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c}, + {0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210}, + {0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284}, + {0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290}, + {0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294}, + {0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8}, + {0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac}, + {0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4}, + {0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8}, + {0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4}, + {0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c}, + {0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04}, + {0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c}, + {0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10}, + {0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14}, + {0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c}, + {0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90}, + {0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94}, + {0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4}, + {0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8}, + {0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04}, + {0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18}, + {0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c}, + {0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90}, + {0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18}, + {0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24}, + {0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28}, + {0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314}, + {0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318}, + {0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c}, + {0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390}, + {0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394}, + {0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398}, + {0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4}, + {0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8}, + {0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac}, + {0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0}, + {0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380}, + {0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714}, + {0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718}, + {0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10}, + {0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14}, + {0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c}, + {0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90}, + {0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94}, + {0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90}, + {0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94}, + {0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0}, + {0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8}, + {0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac}, + {0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0}, + {0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1}, + {0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5}, + {0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9}, + {0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1}, + {0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5}, + {0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9}, + {0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9}, + {0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd}, + {0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1}, + {0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2}, + {0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6}, + {0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca}, + {0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2}, + {0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6}, + {0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda}, + {0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb}, + {0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf}, + {0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3}, + {0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb}, + {0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067}, + {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067}, }; static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { @@ -2526,310 +2540,311 @@ static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { {0x00004044, 0x00000000}, }; -static const u32 ar9271Modes_9271[][6] = { - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180}, - {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880}, - {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303}, - {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x00009828, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001}, - {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, - {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e}, - {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0}, - {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, - {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059}, - {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, - {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e}, - {0x00009860, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18}, - {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00}, - {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881}, - {0x00009910, 0x30002310, 0x30002310, 0x30002310, 0x30002310, 0x30002310}, - {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0}, - {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016}, - {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d}, - {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010}, - {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c}, - {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, - {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f}, - {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, - {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, - {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, - {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, - {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, - {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, - {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, - {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, - {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, - {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, - {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, - {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, - {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, - {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, - {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, - {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, - {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, - {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, - {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, - {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, - {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, - {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, - {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, - {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, - {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, - {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, - {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, - {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, - {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, - {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, - {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, - {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, - {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, - {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, - {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, - {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, - {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, - {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, - {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, - {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, - {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, - {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, - {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, - {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, - {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, - {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, - {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, - {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, - {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, - {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, - {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, - {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, - {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, - {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, - {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, - {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, - {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, - {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, - {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, - {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, - {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, - {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, - {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, - {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, - {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, - {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, - {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, - {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, - {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, - {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, - {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, - {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, - {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, - {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, - {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, - {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, - {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, - {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, - {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, - {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, - {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, - {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, - {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, - {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, - {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, - {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, - {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, - {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, - {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, - {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, - {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, - {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000}, - {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000}, - {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000}, - {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000}, - {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000}, - {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000}, - {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000}, - {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000}, - {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000}, - {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000}, - {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000}, - {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000}, - {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000}, - {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000}, - {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000}, - {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000}, - {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000}, - {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000}, - {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000}, - {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000}, - {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000}, - {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000}, - {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000}, - {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000}, - {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000}, - {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000}, - {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000}, - {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000}, - {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000}, - {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000}, - {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000}, - {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000}, - {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000}, - {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000}, - {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000}, - {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000}, - {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000}, - {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000}, - {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000}, - {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000}, - {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000}, - {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000}, - {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000}, - {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000}, - {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000}, - {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000}, - {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000}, - {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000}, - {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000}, - {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000}, - {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000}, - {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000}, - {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000}, - {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000}, - {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000}, - {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000}, - {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000}, - {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000}, - {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000}, - {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000}, - {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000}, - {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000}, - {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000}, - {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000}, - {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000}, - {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000}, - {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000}, - {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000}, - {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000}, - {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000}, - {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000}, - {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000}, - {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000}, - {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000}, - {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000}, - {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000}, - {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000}, - {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000}, - {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000}, - {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000}, - {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000}, - {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000}, - {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000}, - {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000}, - {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000}, - {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000}, - {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000}, - {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000}, - {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000}, - {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000}, - {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004}, - {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, - {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000}, - {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, - {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000}, - {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000}, - {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e}, +static const u32 ar9271Modes_9271[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, + {0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300}, + {0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x00009828, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001}, + {0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007}, + {0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e}, + {0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620}, + {0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053}, + {0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053}, + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e}, + {0x00009860, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18}, + {0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x00009910, 0x30002310, 0x30002310, 0x30002310, 0x30002310}, + {0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, + {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d}, + {0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020}, + {0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c}, + {0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77}, + {0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f}, + {0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8}, + {0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384}, + {0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084}, + {0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088}, + {0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c}, + {0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100}, + {0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104}, + {0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108}, + {0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c}, + {0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110}, + {0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114}, + {0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180}, + {0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184}, + {0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188}, + {0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c}, + {0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190}, + {0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194}, + {0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0}, + {0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c}, + {0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8}, + {0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284}, + {0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288}, + {0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224}, + {0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290}, + {0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300}, + {0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304}, + {0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308}, + {0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c}, + {0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380}, + {0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384}, + {0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700}, + {0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704}, + {0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708}, + {0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c}, + {0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780}, + {0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784}, + {0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00}, + {0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04}, + {0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08}, + {0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c}, + {0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80}, + {0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84}, + {0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88}, + {0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c}, + {0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90}, + {0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80}, + {0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84}, + {0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88}, + {0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c}, + {0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90}, + {0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c}, + {0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310}, + {0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384}, + {0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388}, + {0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324}, + {0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704}, + {0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4}, + {0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8}, + {0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710}, + {0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714}, + {0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720}, + {0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724}, + {0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728}, + {0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c}, + {0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0}, + {0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4}, + {0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8}, + {0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0}, + {0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4}, + {0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8}, + {0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5}, + {0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9}, + {0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad}, + {0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1}, + {0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5}, + {0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9}, + {0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5}, + {0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9}, + {0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1}, + {0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5}, + {0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9}, + {0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6}, + {0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca}, + {0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce}, + {0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2}, + {0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6}, + {0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3}, + {0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7}, + {0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb}, + {0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf}, + {0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7}, + {0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084}, + {0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088}, + {0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c}, + {0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100}, + {0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104}, + {0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108}, + {0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c}, + {0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110}, + {0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114}, + {0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180}, + {0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184}, + {0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188}, + {0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c}, + {0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190}, + {0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194}, + {0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0}, + {0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c}, + {0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8}, + {0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284}, + {0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288}, + {0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224}, + {0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290}, + {0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300}, + {0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304}, + {0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308}, + {0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c}, + {0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380}, + {0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384}, + {0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700}, + {0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704}, + {0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708}, + {0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c}, + {0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780}, + {0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784}, + {0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00}, + {0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04}, + {0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08}, + {0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c}, + {0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80}, + {0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84}, + {0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88}, + {0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c}, + {0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90}, + {0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80}, + {0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84}, + {0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88}, + {0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c}, + {0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90}, + {0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c}, + {0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310}, + {0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384}, + {0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388}, + {0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324}, + {0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704}, + {0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4}, + {0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8}, + {0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710}, + {0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714}, + {0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720}, + {0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724}, + {0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728}, + {0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c}, + {0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0}, + {0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4}, + {0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8}, + {0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0}, + {0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4}, + {0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8}, + {0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5}, + {0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9}, + {0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad}, + {0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1}, + {0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5}, + {0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9}, + {0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5}, + {0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9}, + {0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1}, + {0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5}, + {0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9}, + {0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6}, + {0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca}, + {0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce}, + {0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2}, + {0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6}, + {0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3}, + {0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7}, + {0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb}, + {0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf}, + {0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7}, + {0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db}, + {0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004}, + {0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000}, + {0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000}, + {0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a}, + {0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000}, + {0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e}, }; static const u32 ar9271Common_9271[][2] = { @@ -3175,91 +3190,95 @@ static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = { {0x0000a1fc, 0xca9228ee}, }; -static const u32 ar9271Modes_9271_1_0_only[][6] = { - {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, +static const u32 ar9271Modes_9271_1_0_only[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, + {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, }; -static const u32 ar9271Modes_9271_ANI_reg[][6] = { - {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, - {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e}, - {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881}, - {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8}, - {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d}, - {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, +static const u32 ar9271Modes_9271_ANI_reg[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, + {0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e}, + {0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881}, + {0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8}, + {0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d}, + {0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, }; -static const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000}, - {0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029}, - {0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff}, - {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, - {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, - {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652}, - {0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, - {0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd}, - {0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, - {0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd}, - {0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, - {0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd}, +static const u32 ar9271Modes_normal_power_tx_gain_9271[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200}, + {0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208}, + {0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610}, + {0x0000a314, 0x00000000, 0x00000000, 0x00024650, 0x00024650}, + {0x0000a318, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0}, + {0x0000a31c, 0x00000000, 0x00000000, 0x000316d2, 0x000316d2}, + {0x0000a320, 0x00000000, 0x00000000, 0x00039758, 0x00039758}, + {0x0000a324, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759}, + {0x0000a328, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c}, + {0x0000a330, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e}, + {0x0000a334, 0x000368de, 0x000368de, 0x0004979f, 0x0004979f}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0004d7df, 0x0004d7df}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029}, + {0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff}, + {0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4}, + {0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04}, + {0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21c652, 0x0a21c652}, + {0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, + {0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd}, + {0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, + {0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd}, + {0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd}, + {0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd}, }; -static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = { - {0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000}, - {0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000}, - {0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000}, - {0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000}, - {0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000}, - {0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000}, - {0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000}, - {0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000}, - {0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000}, - {0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000}, - {0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000}, - {0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000}, - {0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000}, - {0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000}, - {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000}, - {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000}, - {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000}, - {0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b}, - {0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff}, - {0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6}, - {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, - {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a214652, 0x0a214652, 0x0a22a652}, - {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, - {0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063}, - {0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63}, - {0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063}, - {0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63}, - {0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063}, +static const u32 ar9271Modes_high_power_tx_gain_9271[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000}, + {0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200}, + {0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201}, + {0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240}, + {0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241}, + {0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600}, + {0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800}, + {0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802}, + {0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805}, + {0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41}, + {0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00}, + {0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40}, + {0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80}, + {0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de}, + {0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e}, + {0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e}, + {0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df}, + {0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b}, + {0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff}, + {0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba}, + {0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00}, + {0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a214652, 0x0a214652}, + {0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7}, + {0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063}, + {0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63}, + {0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063}, + {0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63}, + {0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063}, }; From 3c42e6ef28d89fc2157d4d65869471f607fcf64e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 29 Aug 2011 13:39:47 +0200 Subject: [PATCH 072/287] ath9k_hw: fix the last register write for ar5416 addac The previous register used in these initvals was probably accidentally copied over from the AR9100 values. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_initvals.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h index 68b0561c6bb8..f81e7fc60a36 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h @@ -669,6 +669,6 @@ static const u32 ar5416Addac[][2] = { {0x0000989c, 0x00000000}, {0x0000989c, 0x00000000}, {0x0000989c, 0x00000000}, - {0x000098cc, 0x00000000}, + {0x000098c4, 0x00000000}, }; From 2a36a0ec1550ffb4d608134e2504a6a67d1d1740 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 29 Aug 2011 17:12:44 +0530 Subject: [PATCH 073/287] mwl8k: Set hardware flag IEEE80211_HW_AP_LINK_PS This will avoid mac80211 to trigger PS mode for connected station based on the PM bit of incoming frames. AP firmware is capable of handling such frames and buffering TX frames destined to the stations that are in PS mode. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 771280a47ea7..ea1395aafa39 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -5501,6 +5501,14 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) /* Set rssi values to dBm */ hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; + + /* + * Ask mac80211 to not to trigger PS mode + * based on PM bit of incoming frames. + */ + if (priv->ap_fw) + hw->flags |= IEEE80211_HW_AP_LINK_PS; + hw->vif_data_size = sizeof(struct mwl8k_vif); hw->sta_data_size = sizeof(struct mwl8k_sta); From 3459731a39894e5377283b3ccf2fede54e19aae1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 29 Aug 2011 18:57:54 +0200 Subject: [PATCH 074/287] ath9k: fix checks for first subframe delimiter padding The commit "ath9k_hw: Fix exceed transmission burst-time of 5GHz" added a padding of 60 delimiters on the first subframe to work around an issue on AR9380, but it lacked the checks to prevent it from being applied to pre-AR9380, enterprise AR9380 or AR9580+ Signed-off-by: Felix Fietkau Cc: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/reg.h | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 17a272f4d8d6..5d34381c44c3 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1132,7 +1132,7 @@ enum { #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 -#define AR_ENT_OTP_MPSD 0x00800000 +#define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000 #define AR_CH0_BB_DPLL1 0x16180 #define AR_CH0_BB_DPLL1_REFDIV 0xF8000000 diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 68066c56e4e5..29bcc55a6f9e 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -709,7 +709,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, * Add delimiter when using RTS/CTS with aggregation * and non enterprise AR9003 card */ - if (first_subfrm) + if (first_subfrm && !AR_SREV_9580_10_OR_LATER(sc->sc_ah) && + (sc->sc_ah->ent_mode & AR_ENT_OTP_MIN_PKT_SIZE_DISABLE)) ndelim = max(ndelim, FIRST_DESC_NDELIMS); /* From 5982b47aa410e6aef55a5b0087269f5c9c172110 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Mon, 29 Aug 2011 13:21:10 -0700 Subject: [PATCH 075/287] mwifiex: replace kmalloc & memcpy sequence with kmemdup Sequence of kmalloc/kzalloc and memcpy is replaced with kmemdup. Cc: Walter Harms Signed-off-by: Yogesh Ashok Powar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/join.c | 3 +-- drivers/net/wireless/mwifiex/scan.c | 6 +++--- drivers/net/wireless/mwifiex/sta_ioctl.c | 9 +++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 5cdad92277fa..62b4c2938608 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -147,13 +147,12 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1, u8 *ptr = rate1, *tmp; u32 i, j; - tmp = kmalloc(rate1_size, GFP_KERNEL); + tmp = kmemdup(rate1, rate1_size, GFP_KERNEL); if (!tmp) { dev_err(priv->adapter->dev, "failed to alloc tmp buf\n"); return -ENOMEM; } - memcpy(tmp, rate1, rate1_size); memset(rate1, 0, rate1_size); for (i = 0; rate2[i] && i < rate2_size; i++) { diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 37ca2f90ad63..8d8588db1cd9 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1479,12 +1479,12 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, dev_err(priv->adapter->dev, " failed to alloc bss_desc\n"); return -ENOMEM; } - beacon_ie = kzalloc(ie_len, GFP_KERNEL); + + beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL); if (!beacon_ie) { dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); return -ENOMEM; } - memcpy(beacon_ie, ie_buf, ie_len); ret = mwifiex_fill_new_bss_desc(priv, bssid, rssi, beacon_ie, ie_len, beacon_period, @@ -1986,7 +1986,7 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) priv->curr_bcn_size = curr_bss->beacon_buf_size; kfree(priv->curr_bcn_buf); - priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size, + priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, GFP_KERNEL); if (!priv->curr_bcn_buf) { dev_err(priv->adapter->dev, diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 3fca219bcfb6..eb569fa9adba 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -199,13 +199,14 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, dev_err(priv->adapter->dev, " failed to alloc bss_desc\n"); return -ENOMEM; } - beacon_ie = kzalloc(bss->len_beacon_ies, GFP_KERNEL); + + beacon_ie = kmemdup(bss->information_elements, + bss->len_beacon_ies, GFP_KERNEL); if (!beacon_ie) { - dev_err(priv->adapter->dev, " failed to alloc bss_desc\n"); + dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); return -ENOMEM; } - memcpy(beacon_ie, bss->information_elements, - bss->len_beacon_ies); + ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal, beacon_ie, bss->len_beacon_ies, bss->beacon_interval, From af089c15cb13e1c5d984e41f495c8363dd5b1e30 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:03 -0700 Subject: [PATCH 076/287] mac80211: Fix RCU pointer dereference in mesh_path_discard_frame() Reported by Pedro Larbig (ASPj) Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index ede4f5242e0b..2218eaf48bcb 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -991,9 +991,14 @@ void mesh_path_discard_frame(struct sk_buff *skb, da = hdr->addr3; ra = hdr->addr1; + rcu_read_lock(); mpath = mesh_path_lookup(da, sdata); - if (mpath) + if (mpath) { + spin_lock_bh(&mpath->state_lock); sn = ++mpath->sn; + spin_unlock_bh(&mpath->state_lock); + } + rcu_read_unlock(); mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, skb->data, cpu_to_le32(sn), reason, ra, sdata); } From ece1a2e7e86078c8379937b546e32cb7f25fcb6c Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:04 -0700 Subject: [PATCH 077/287] mac80211: Remove mesh paths when an interface is removed When an interface is removed, the mesh paths associated with it should also be removed. This fixes a bug we observed when reloading a device driver module without reloading mac80211s. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 2 +- net/mac80211/iface.c | 6 ++++++ net/mac80211/mesh.h | 2 +- net/mac80211/mesh_pathtbl.c | 40 ++++++++++++++++++++++++++++++++++++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0baaaecf4558..5c0d8fab0e88 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -921,7 +921,7 @@ static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, if (dst) return mesh_path_del(dst, sdata); - mesh_path_flush(sdata); + mesh_path_flush_by_iface(sdata); return 0; } diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 556e7e6ddf0a..eaa80a3d412b 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1214,6 +1214,9 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) list_del_rcu(&sdata->list); mutex_unlock(&sdata->local->iflist_mtx); + if (ieee80211_vif_is_mesh(&sdata->vif)) + mesh_path_flush_by_iface(sdata); + synchronize_rcu(); unregister_netdevice(sdata->dev); } @@ -1233,6 +1236,9 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { list_del(&sdata->list); + if (ieee80211_vif_is_mesh(&sdata->vif)) + mesh_path_flush_by_iface(sdata); + unregister_netdevice_queue(sdata->dev, &unreg_list); } mutex_unlock(&local->iflist_mtx); diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 20272072171f..57a2ad021bee 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -238,7 +238,6 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata); void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); void mesh_path_expire(struct ieee80211_sub_if_data *sdata); -void mesh_path_flush(struct ieee80211_sub_if_data *sdata); void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, size_t len); int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata); @@ -275,6 +274,7 @@ void mesh_pathtbl_unregister(void); int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata); void mesh_path_timer(unsigned long data); void mesh_path_flush_by_nexthop(struct sta_info *sta); +void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); void mesh_path_discard_frame(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata); void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 2218eaf48bcb..d07279911a0c 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -821,7 +821,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) rcu_read_unlock(); } -void mesh_path_flush(struct ieee80211_sub_if_data *sdata) +static void mesh_path_flush(struct ieee80211_sub_if_data *sdata) { struct mesh_table *tbl; struct mesh_path *mpath; @@ -850,6 +850,44 @@ static void mesh_path_node_reclaim(struct rcu_head *rp) kfree(node); } +static void mpp_path_flush(struct ieee80211_sub_if_data *sdata) +{ + struct mesh_table *tbl; + struct mesh_path *mpath; + struct mpath_node *node; + struct hlist_node *p; + int i; + + read_lock_bh(&pathtbl_resize_lock); + tbl = rcu_dereference_protected(mpp_paths, + lockdep_is_held(pathtbl_resize_lock)); + for_each_mesh_entry(tbl, p, node, i) { + mpath = node->mpath; + if (mpath->sdata != sdata) + continue; + spin_lock_bh(&tbl->hashwlock[i]); + spin_lock_bh(&mpath->state_lock); + call_rcu(&node->rcu, mesh_path_node_reclaim); + atomic_dec(&tbl->entries); + spin_unlock_bh(&tbl->hashwlock[i]); + } + read_unlock_bh(&pathtbl_resize_lock); +} + +/** + * mesh_path_flush_by_iface - Deletes all mesh paths associated with a given iface + * + * This function deletes both mesh paths as well as mesh portal paths. + * + * @sdata - interface data to match + * + */ +void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) +{ + mesh_path_flush(sdata); + mpp_path_flush(sdata); +} + /** * mesh_path_del - delete a mesh path from the table * From f5e50cd0757cc97cd1caded0d3f07ff09b5319e4 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:05 -0700 Subject: [PATCH 078/287] mac80211: Improve mpath state locking No need to take the mpath state lock when an mpath is removed. Also, no need checking the lock when reading mpath flags. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh.h | 4 +++- net/mac80211/mesh_pathtbl.c | 14 ++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 57a2ad021bee..7118e8e8855c 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -80,7 +80,9 @@ enum mesh_deferred_task_flags { * retry * @discovery_retries: number of discovery retries * @flags: mesh path flags, as specified on &enum mesh_path_flags - * @state_lock: mesh path state lock + * @state_lock: mesh path state lock used to protect changes to the + * mpath itself. No need to take this lock when adding or removing + * an mpath to a hash bucket on a path table. * @is_gate: the destination station of this path is a mesh gate * * diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index d07279911a0c..618f84148a75 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -776,18 +776,17 @@ void mesh_plink_broken(struct sta_info *sta) tbl = rcu_dereference(mesh_paths); for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; - spin_lock_bh(&mpath->state_lock); if (rcu_dereference(mpath->next_hop) == sta && mpath->flags & MESH_PATH_ACTIVE && !(mpath->flags & MESH_PATH_FIXED)) { + spin_lock_bh(&mpath->state_lock); mpath->flags &= ~MESH_PATH_ACTIVE; ++mpath->sn; spin_unlock_bh(&mpath->state_lock); mesh_path_error_tx(sdata->u.mesh.mshcfg.element_ttl, mpath->dst, cpu_to_le32(mpath->sn), reason, bcast, sdata); - } else - spin_unlock_bh(&mpath->state_lock); + } } rcu_read_unlock(); } @@ -866,7 +865,7 @@ static void mpp_path_flush(struct ieee80211_sub_if_data *sdata) if (mpath->sdata != sdata) continue; spin_lock_bh(&tbl->hashwlock[i]); - spin_lock_bh(&mpath->state_lock); + hlist_del_rcu(&node->list); call_rcu(&node->rcu, mesh_path_node_reclaim); atomic_dec(&tbl->entries); spin_unlock_bh(&tbl->hashwlock[i]); @@ -1160,15 +1159,10 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata) if (node->mpath->sdata != sdata) continue; mpath = node->mpath; - spin_lock_bh(&mpath->state_lock); if ((!(mpath->flags & MESH_PATH_RESOLVING)) && (!(mpath->flags & MESH_PATH_FIXED)) && - time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) { - spin_unlock_bh(&mpath->state_lock); + time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) mesh_path_del(mpath->dst, mpath->sdata); - } else - spin_unlock_bh(&mpath->state_lock); - } rcu_read_unlock(); } From ad99d141144c4996c810fe75f04c387214ca360a Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:06 -0700 Subject: [PATCH 079/287] mac80211: Remove redundant mesh path expiration checks Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 618f84148a75..717f38a7134c 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -359,8 +359,7 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) memcmp(dst, mpath->dst, ETH_ALEN) == 0) { if (MPATH_EXPIRED(mpath)) { spin_lock_bh(&mpath->state_lock); - if (MPATH_EXPIRED(mpath)) - mpath->flags &= ~MESH_PATH_ACTIVE; + mpath->flags &= ~MESH_PATH_ACTIVE; spin_unlock_bh(&mpath->state_lock); } return mpath; @@ -386,8 +385,7 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) memcmp(dst, mpath->dst, ETH_ALEN) == 0) { if (MPATH_EXPIRED(mpath)) { spin_lock_bh(&mpath->state_lock); - if (MPATH_EXPIRED(mpath)) - mpath->flags &= ~MESH_PATH_ACTIVE; + mpath->flags &= ~MESH_PATH_ACTIVE; spin_unlock_bh(&mpath->state_lock); } return mpath; @@ -420,8 +418,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data if (j++ == idx) { if (MPATH_EXPIRED(node->mpath)) { spin_lock_bh(&node->mpath->state_lock); - if (MPATH_EXPIRED(node->mpath)) - node->mpath->flags &= ~MESH_PATH_ACTIVE; + node->mpath->flags &= ~MESH_PATH_ACTIVE; spin_unlock_bh(&node->mpath->state_lock); } return node->mpath; From 19c50b3dc530278a0d07dceebff1683f3bdc4a2b Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:07 -0700 Subject: [PATCH 080/287] mac80211: Don't iterate twice over all mpaths when once in sufficient Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 64 +++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 717f38a7134c..4a3053b09e31 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -49,7 +49,9 @@ int mesh_paths_generation; /* This lock will have the grow table function as writer and add / delete nodes * as readers. When reading the table (i.e. doing lookups) we are well protected - * by RCU + * by RCU. We need to take this lock when modying the number of buckets + * on one of the path tables but we don't need to if adding or removing mpaths + * from hash buckets. */ static DEFINE_RWLOCK(pathtbl_resize_lock); @@ -817,6 +819,32 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) rcu_read_unlock(); } +static void mesh_path_node_reclaim(struct rcu_head *rp) +{ + struct mpath_node *node = container_of(rp, struct mpath_node, rcu); + struct ieee80211_sub_if_data *sdata = node->mpath->sdata; + + del_timer_sync(&node->mpath->timer); + atomic_dec(&sdata->u.mesh.mpaths); + kfree(node->mpath); + kfree(node); +} + +/* needs to be called with the corresponding hashwlock taken */ +static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node) +{ + struct mesh_path *mpath; + mpath = node->mpath; + spin_lock(&mpath->state_lock); + mpath->flags |= MESH_PATH_RESOLVING; + if (mpath->is_gate) + mesh_gate_del(tbl, mpath); + hlist_del_rcu(&node->list); + call_rcu(&node->rcu, mesh_path_node_reclaim); + spin_unlock(&mpath->state_lock); + atomic_dec(&tbl->entries); +} + static void mesh_path_flush(struct ieee80211_sub_if_data *sdata) { struct mesh_table *tbl; @@ -829,23 +857,15 @@ static void mesh_path_flush(struct ieee80211_sub_if_data *sdata) tbl = rcu_dereference(mesh_paths); for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; - if (mpath->sdata == sdata) - mesh_path_del(mpath->dst, mpath->sdata); + if (mpath->sdata == sdata) { + spin_lock_bh(&tbl->hashwlock[i]); + __mesh_path_del(tbl, node); + spin_unlock_bh(&tbl->hashwlock[i]); + } } rcu_read_unlock(); } -static void mesh_path_node_reclaim(struct rcu_head *rp) -{ - struct mpath_node *node = container_of(rp, struct mpath_node, rcu); - struct ieee80211_sub_if_data *sdata = node->mpath->sdata; - - del_timer_sync(&node->mpath->timer); - atomic_dec(&sdata->u.mesh.mpaths); - kfree(node->mpath); - kfree(node); -} - static void mpp_path_flush(struct ieee80211_sub_if_data *sdata) { struct mesh_table *tbl; @@ -859,12 +879,8 @@ static void mpp_path_flush(struct ieee80211_sub_if_data *sdata) lockdep_is_held(pathtbl_resize_lock)); for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; - if (mpath->sdata != sdata) - continue; spin_lock_bh(&tbl->hashwlock[i]); - hlist_del_rcu(&node->list); - call_rcu(&node->rcu, mesh_path_node_reclaim); - atomic_dec(&tbl->entries); + __mesh_path_del(tbl, node); spin_unlock_bh(&tbl->hashwlock[i]); } read_unlock_bh(&pathtbl_resize_lock); @@ -912,14 +928,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) mpath = node->mpath; if (mpath->sdata == sdata && memcmp(addr, mpath->dst, ETH_ALEN) == 0) { - spin_lock_bh(&mpath->state_lock); - if (mpath->is_gate) - mesh_gate_del(tbl, mpath); - mpath->flags |= MESH_PATH_RESOLVING; - hlist_del_rcu(&node->list); - call_rcu(&node->rcu, mesh_path_node_reclaim); - atomic_dec(&tbl->entries); - spin_unlock_bh(&mpath->state_lock); + __mesh_path_del(tbl, node); goto enddel; } } @@ -1160,6 +1169,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata) (!(mpath->flags & MESH_PATH_FIXED)) && time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) mesh_path_del(mpath->dst, mpath->sdata); + } rcu_read_unlock(); } From cd72e817480bd3a1d2cdf03b65a1f3920c1c88a0 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:08 -0700 Subject: [PATCH 081/287] mac80211: Consolidate {mesh,mpp}_path_flush into one function Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 65 +++++++++++++++---------------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 4a3053b09e31..7797f55eec46 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -790,35 +790,6 @@ void mesh_plink_broken(struct sta_info *sta) rcu_read_unlock(); } -/** - * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches - * - * @sta - mesh peer to match - * - * RCU notes: this function is called when a mesh plink transitions from - * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that - * allows path creation. This will happen before the sta can be freed (because - * sta_info_destroy() calls this) so any reader in a rcu read block will be - * protected against the plink disappearing. - */ -void mesh_path_flush_by_nexthop(struct sta_info *sta) -{ - struct mesh_table *tbl; - struct mesh_path *mpath; - struct mpath_node *node; - struct hlist_node *p; - int i; - - rcu_read_lock(); - tbl = rcu_dereference(mesh_paths); - for_each_mesh_entry(tbl, p, node, i) { - mpath = node->mpath; - if (rcu_dereference(mpath->next_hop) == sta) - mesh_path_del(mpath->dst, mpath->sdata); - } - rcu_read_unlock(); -} - static void mesh_path_node_reclaim(struct rcu_head *rp) { struct mpath_node *node = container_of(rp, struct mpath_node, rcu); @@ -845,7 +816,18 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node) atomic_dec(&tbl->entries); } -static void mesh_path_flush(struct ieee80211_sub_if_data *sdata) +/** + * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches + * + * @sta - mesh peer to match + * + * RCU notes: this function is called when a mesh plink transitions from + * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that + * allows path creation. This will happen before the sta can be freed (because + * sta_info_destroy() calls this) so any reader in a rcu read block will be + * protected against the plink disappearing. + */ +void mesh_path_flush_by_nexthop(struct sta_info *sta) { struct mesh_table *tbl; struct mesh_path *mpath; @@ -857,7 +839,7 @@ static void mesh_path_flush(struct ieee80211_sub_if_data *sdata) tbl = rcu_dereference(mesh_paths); for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; - if (mpath->sdata == sdata) { + if (rcu_dereference(mpath->next_hop) == sta) { spin_lock_bh(&tbl->hashwlock[i]); __mesh_path_del(tbl, node); spin_unlock_bh(&tbl->hashwlock[i]); @@ -866,24 +848,23 @@ static void mesh_path_flush(struct ieee80211_sub_if_data *sdata) rcu_read_unlock(); } -static void mpp_path_flush(struct ieee80211_sub_if_data *sdata) +static void table_flush_by_iface(struct mesh_table *tbl, + struct ieee80211_sub_if_data *sdata) { - struct mesh_table *tbl; struct mesh_path *mpath; struct mpath_node *node; struct hlist_node *p; int i; - read_lock_bh(&pathtbl_resize_lock); - tbl = rcu_dereference_protected(mpp_paths, - lockdep_is_held(pathtbl_resize_lock)); + WARN_ON(!rcu_read_lock_held()); for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; + if (mpath->sdata != sdata) + continue; spin_lock_bh(&tbl->hashwlock[i]); __mesh_path_del(tbl, node); spin_unlock_bh(&tbl->hashwlock[i]); } - read_unlock_bh(&pathtbl_resize_lock); } /** @@ -896,8 +877,14 @@ static void mpp_path_flush(struct ieee80211_sub_if_data *sdata) */ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) { - mesh_path_flush(sdata); - mpp_path_flush(sdata); + struct mesh_table *tbl; + + rcu_read_lock(); + tbl = rcu_dereference(mesh_paths); + table_flush_by_iface(tbl, sdata); + tbl = rcu_dereference(mpp_paths); + table_flush_by_iface(tbl, sdata); + rcu_read_unlock(); } /** From 239289e446d4e86ae94b1ca57e358b106cc4bee6 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:09 -0700 Subject: [PATCH 082/287] mac80211: Consolidate mesh path duplicated functions Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 70 +++++++++++++++---------------------- 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 7797f55eec46..a66a2cab8d34 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -48,10 +48,10 @@ static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ int mesh_paths_generation; /* This lock will have the grow table function as writer and add / delete nodes - * as readers. When reading the table (i.e. doing lookups) we are well protected - * by RCU. We need to take this lock when modying the number of buckets - * on one of the path tables but we don't need to if adding or removing mpaths - * from hash buckets. + * as readers. RCU provides sufficient protection only when reading the table + * (i.e. doing lookups). Adding or adding or removing nodes requires we take + * the read lock or we risk operating on an old table. The write lock is only + * needed when modifying the number of buckets a table. */ static DEFINE_RWLOCK(pathtbl_resize_lock); @@ -335,25 +335,14 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath, } -/** - * mesh_path_lookup - look up a path in the mesh path table - * @dst: hardware address (ETH_ALEN length) of destination - * @sdata: local subif - * - * Returns: pointer to the mesh path structure, or NULL if not found - * - * Locking: must be called within a read rcu section. - */ -struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) +static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst, + struct ieee80211_sub_if_data *sdata) { struct mesh_path *mpath; struct hlist_node *n; struct hlist_head *bucket; - struct mesh_table *tbl; struct mpath_node *node; - tbl = rcu_dereference(mesh_paths); - bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; hlist_for_each_entry_rcu(node, n, bucket, list) { mpath = node->mpath; @@ -370,30 +359,23 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) return NULL; } -struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) +/** + * mesh_path_lookup - look up a path in the mesh path table + * @dst: hardware address (ETH_ALEN length) of destination + * @sdata: local subif + * + * Returns: pointer to the mesh path structure, or NULL if not found + * + * Locking: must be called within a read rcu section. + */ +struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) { - struct mesh_path *mpath; - struct hlist_node *n; - struct hlist_head *bucket; - struct mesh_table *tbl; - struct mpath_node *node; - - tbl = rcu_dereference(mpp_paths); + return path_lookup(rcu_dereference(mesh_paths), dst, sdata); +} - bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; - hlist_for_each_entry_rcu(node, n, bucket, list) { - mpath = node->mpath; - if (mpath->sdata == sdata && - memcmp(dst, mpath->dst, ETH_ALEN) == 0) { - if (MPATH_EXPIRED(mpath)) { - spin_lock_bh(&mpath->state_lock); - mpath->flags &= ~MESH_PATH_ACTIVE; - spin_unlock_bh(&mpath->state_lock); - } - return mpath; - } - } - return NULL; +struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) +{ + return path_lookup(rcu_dereference(mpp_paths), dst, sdata); } @@ -836,7 +818,8 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) int i; rcu_read_lock(); - tbl = rcu_dereference(mesh_paths); + read_lock_bh(&pathtbl_resize_lock); + tbl = resize_dereference_mesh_paths(); for_each_mesh_entry(tbl, p, node, i) { mpath = node->mpath; if (rcu_dereference(mpath->next_hop) == sta) { @@ -845,6 +828,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) spin_unlock_bh(&tbl->hashwlock[i]); } } + read_unlock_bh(&pathtbl_resize_lock); rcu_read_unlock(); } @@ -880,10 +864,12 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) struct mesh_table *tbl; rcu_read_lock(); - tbl = rcu_dereference(mesh_paths); + read_lock_bh(&pathtbl_resize_lock); + tbl = resize_dereference_mesh_paths(); table_flush_by_iface(tbl, sdata); - tbl = rcu_dereference(mpp_paths); + tbl = resize_dereference_mpp_paths(); table_flush_by_iface(tbl, sdata); + read_unlock_bh(&pathtbl_resize_lock); rcu_read_unlock(); } From d15b84590a1d2ec021ada00a0e67ee5851a0ea2b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Aug 2011 14:17:31 -0700 Subject: [PATCH 083/287] mac80211: Remove unnecessary OOM logging messages Removing unnecessary messages saves code and text. Site specific OOM messages are duplications of a generic MM out of memory message and aren't really useful, so just delete them. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- net/mac80211/agg-rx.c | 19 ++----------------- net/mac80211/agg-tx.c | 35 ++++++++--------------------------- net/mac80211/debugfs.c | 3 +++ net/mac80211/ht.c | 6 +----- net/mac80211/mesh.c | 5 ++--- net/mac80211/mlme.c | 17 +++++------------ net/mac80211/spectmgmt.c | 6 +----- net/mac80211/tx.c | 17 +++++------------ net/mac80211/util.c | 11 +++-------- net/mac80211/work.c | 6 ++---- 10 files changed, 32 insertions(+), 93 deletions(-) diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index fd1aaf2a4a6c..e6cab51dceb0 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -167,12 +167,8 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d u16 capab; skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); - - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer " - "for addba resp frame\n", sdata->name); + if (!skb) return; - } skb_reserve(skb, local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); @@ -279,14 +275,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, /* prepare A-MPDU MLME for Rx aggregation */ tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL); - if (!tid_agg_rx) { -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_ERR "allocate rx mlme to tid %d failed\n", - tid); -#endif + if (!tid_agg_rx) goto end; - } spin_lock_init(&tid_agg_rx->reorder_lock); @@ -306,11 +296,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, tid_agg_rx->reorder_time = kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL); if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) { -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_ERR "can not allocate reordering buffer " - "to tid %d\n", tid); -#endif kfree(tid_agg_rx->reorder_buf); kfree(tid_agg_rx->reorder_time); kfree(tid_agg_rx); diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 018108d1a2fd..f10e1096c332 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -68,11 +68,9 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); - if (!skb) { - printk(KERN_ERR "%s: failed to allocate buffer " - "for addba request frame\n", sdata->name); + if (!skb) return; - } + skb_reserve(skb, local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); memset(mgmt, 0, 24); @@ -114,11 +112,9 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 u16 bar_control = 0; skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); - if (!skb) { - printk(KERN_ERR "%s: failed to allocate buffer for " - "bar frame\n", sdata->name); + if (!skb) return; - } + skb_reserve(skb, local->hw.extra_tx_headroom); bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar)); memset(bar, 0, sizeof(*bar)); @@ -413,11 +409,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, /* prepare A-MPDU MLME for Tx aggregation */ tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); if (!tid_tx) { -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_ERR "allocate tx mlme to tid %d failed\n", - tid); -#endif ret = -ENOMEM; goto err_unlock_sta; } @@ -574,14 +565,9 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, struct ieee80211_ra_tid *ra_tid; struct sk_buff *skb = dev_alloc_skb(0); - if (unlikely(!skb)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_WARNING "%s: Not enough memory, " - "dropping start BA session", sdata->name); -#endif + if (unlikely(!skb)) return; - } + ra_tid = (struct ieee80211_ra_tid *) &skb->cb; memcpy(&ra_tid->ra, ra, ETH_ALEN); ra_tid->tid = tid; @@ -727,14 +713,9 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, struct ieee80211_ra_tid *ra_tid; struct sk_buff *skb = dev_alloc_skb(0); - if (unlikely(!skb)) { -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_WARNING "%s: Not enough memory, " - "dropping stop BA session", sdata->name); -#endif + if (unlikely(!skb)) return; - } + ra_tid = (struct ieee80211_ra_tid *) &skb->cb; memcpy(&ra_tid->ra, ra, ETH_ALEN); ra_tid->tid = tid; diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 267ed45ef6a2..569609b94c8c 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -297,6 +297,9 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, char *buf = kzalloc(mxln, GFP_KERNEL); int sf = 0; /* how many written so far */ + if (!buf) + return 0; + sf += snprintf(buf, mxln - sf, "0x%x\n", local->hw.flags); if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) sf += snprintf(buf + sf, mxln - sf, "HAS_RATE_CONTROL\n"); diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 7cfc286946c0..2b9b52c69569 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -186,12 +186,8 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, u16 params; skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); - - if (!skb) { - printk(KERN_ERR "%s: failed to allocate buffer " - "for delba frame\n", sdata->name); + if (!skb) return; - } skb_reserve(skb, local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 28ab510e621a..65acbf5eed2d 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -200,10 +200,9 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, } p = kmem_cache_alloc(rm_cache, GFP_ATOMIC); - if (!p) { - printk(KERN_DEBUG "o11s: could not allocate RMC entry\n"); + if (!p) return 0; - } + p->seqnum = seqnum; p->exp_time = jiffies + RMC_TIMEOUT; memcpy(p->sa, sa, ETH_ALEN); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 60a6f273cd30..fb2f0f986de7 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -271,11 +271,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt; skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for " - "deauth/disassoc frame\n", sdata->name); + if (!skb) return; - } + skb_reserve(skb, local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); @@ -354,11 +352,9 @@ static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local, return; skb = dev_alloc_skb(local->hw.extra_tx_headroom + 30); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for 4addr " - "nullfunc frame\n", sdata->name); + if (!skb) return; - } + skb_reserve(skb, local->hw.extra_tx_headroom); nullfunc = (struct ieee80211_hdr *) skb_put(skb, 30); @@ -2441,11 +2437,8 @@ static int ieee80211_pre_assoc(struct ieee80211_sub_if_data *sdata, int err; sta = sta_info_alloc(sdata, bssid, GFP_KERNEL); - if (!sta) { - printk(KERN_DEBUG "%s: failed to alloc STA entry for" - " the AP\n", sdata->name); + if (!sta) return -ENOMEM; - } sta->dummy = true; diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 7733f66ee2c4..578eea3fc04d 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c @@ -32,12 +32,8 @@ static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_da skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + sizeof(struct ieee80211_msrment_ie)); - - if (!skb) { - printk(KERN_ERR "%s: failed to allocate buffer for " - "measurement report frame\n", sdata->name); + if (!skb) return; - } skb_reserve(skb, local->hw.extra_tx_headroom); msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 01072639666f..c9766ccb51a4 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2365,11 +2365,9 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw, local = sdata->local; skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll)); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for " - "pspoll template\n", sdata->name); + if (!skb) return NULL; - } + skb_reserve(skb, local->hw.extra_tx_headroom); pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll)); @@ -2405,11 +2403,9 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw, local = sdata->local; skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*nullfunc)); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " - "template\n", sdata->name); + if (!skb) return NULL; - } + skb_reserve(skb, local->hw.extra_tx_headroom); nullfunc = (struct ieee80211_hdr_3addr *) skb_put(skb, @@ -2444,11 +2440,8 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) + ie_ssid_len + ie_len); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for probe " - "request template\n", sdata->name); + if (!skb) return NULL; - } skb_reserve(skb, local->hw.extra_tx_headroom); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index ce916ff6ef08..1c1080274730 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -707,11 +707,9 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 6 + extra_len); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for auth " - "frame\n", sdata->name); + if (!skb) return; - } + skb_reserve(skb, local->hw.extra_tx_headroom); mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); @@ -864,11 +862,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, /* FIXME: come up with a proper value */ buf = kmalloc(200 + ie_len, GFP_KERNEL); - if (!buf) { - printk(KERN_DEBUG "%s: failed to allocate temporary IE " - "buffer\n", sdata->name); + if (!buf) return NULL; - } /* * Do not send DS Channel parameter for directed probe requests diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 380b9a7462b6..bac34394c05e 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -229,11 +229,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, wk->ie_len + /* extra IEs */ 9, /* WMM */ GFP_KERNEL); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " - "frame\n", sdata->name); + if (!skb) return; - } + skb_reserve(skb, local->hw.extra_tx_headroom); capab = WLAN_CAPABILITY_ESS; From 246c0812049f92109ab9771e34480a2ce816f005 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Aug 2011 14:17:34 -0700 Subject: [PATCH 084/287] rfkill: Remove unnecessary OOM logging messages Removing unnecessary messages saves code and text. Site specific OOM messages are duplications of a generic MM out of memory message and aren't really useful, so just delete them. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- net/rfkill/rfkill-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c index 18dc512a10f3..3ca7277a3c36 100644 --- a/net/rfkill/rfkill-regulator.c +++ b/net/rfkill/rfkill-regulator.c @@ -90,7 +90,6 @@ static int __devinit rfkill_regulator_probe(struct platform_device *pdev) pdata->type, &rfkill_regulator_ops, rfkill_data); if (rf_kill == NULL) { - dev_err(&pdev->dev, "Cannot alloc rfkill device\n"); ret = -ENOMEM; goto err_rfkill_alloc; } From 24616152b1d184864370c5ea21f8fdbd5a90d58d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 29 Aug 2011 14:17:41 -0700 Subject: [PATCH 085/287] wireless: Remove unnecessary OOM logging messages Removing unnecessary messages saves code and text. Site specific OOM messages are duplications of a generic MM out of memory message and aren't really useful, so just delete them. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- net/wireless/lib80211_crypt_ccmp.c | 2 -- net/wireless/lib80211_crypt_tkip.c | 4 ---- net/wireless/lib80211_crypt_wep.c | 4 ---- net/wireless/util.c | 5 ++--- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/net/wireless/lib80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c index dacb3b4b1bdb..755738d26bb4 100644 --- a/net/wireless/lib80211_crypt_ccmp.c +++ b/net/wireless/lib80211_crypt_ccmp.c @@ -77,8 +77,6 @@ static void *lib80211_ccmp_init(int key_idx) priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tfm)) { - printk(KERN_DEBUG "lib80211_crypt_ccmp: could not allocate " - "crypto API aes\n"); priv->tfm = NULL; goto fail; } diff --git a/net/wireless/lib80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c index 7ea4f2b0770e..38734846c19e 100644 --- a/net/wireless/lib80211_crypt_tkip.c +++ b/net/wireless/lib80211_crypt_tkip.c @@ -101,7 +101,6 @@ static void *lib80211_tkip_init(int key_idx) priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_arc4)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n")); priv->tx_tfm_arc4 = NULL; goto fail; } @@ -109,7 +108,6 @@ static void *lib80211_tkip_init(int key_idx) priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_michael)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n")); priv->tx_tfm_michael = NULL; goto fail; } @@ -117,7 +115,6 @@ static void *lib80211_tkip_init(int key_idx) priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_arc4)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API arc4\n")); priv->rx_tfm_arc4 = NULL; goto fail; } @@ -125,7 +122,6 @@ static void *lib80211_tkip_init(int key_idx) priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_michael)) { - printk(KERN_DEBUG pr_fmt("could not allocate crypto API michael_mic\n")); priv->rx_tfm_michael = NULL; goto fail; } diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c index 2f265e033ae2..c1304018fc1c 100644 --- a/net/wireless/lib80211_crypt_wep.c +++ b/net/wireless/lib80211_crypt_wep.c @@ -50,16 +50,12 @@ static void *lib80211_wep_init(int keyidx) priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm)) { - printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate " - "crypto API arc4\n"); priv->tx_tfm = NULL; goto fail; } priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm)) { - printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate " - "crypto API arc4\n"); priv->rx_tfm = NULL; goto fail; } diff --git a/net/wireless/util.c b/net/wireless/util.c index eef82f79554d..39dbf4ad7ca1 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -513,10 +513,9 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, if (head_need) skb_orphan(skb); - if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) { - pr_err("failed to reallocate Tx buffer\n"); + if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) return -ENOMEM; - } + skb->truesize += head_need; } From edf6b784c0e574696915e7b04fe42158f3112d0d Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 30 Aug 2011 09:32:38 +0300 Subject: [PATCH 086/287] mac80211: add flag to indicate HW only Tx-agg setup support When this flag is set, Tx A-MPDU sessions will not be started by mac80211. This flag is required for devices that support Tx A-MPDU setup in hardware. Signed-off-by: Arik Nemtsov Signed-off-by: John W. Linville --- include/net/mac80211.h | 5 +++++ net/mac80211/agg-tx.c | 3 ++- net/mac80211/debugfs.c | 2 ++ net/mac80211/tx.c | 3 ++- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2e752df57510..5e5029b22ac7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1096,6 +1096,10 @@ enum sta_notify_cmd { * stations based on the PM bit of incoming frames. * Use ieee80211_start_ps()/ieee8021_end_ps() to manually configure * the PS mode of connected stations. + * + * @IEEE80211_HW_TX_AMPDU_SETUP_IN_HW: The device handles TX A-MPDU session + * setup strictly in HW. mac80211 should not attempt to do this in + * software. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, @@ -1121,6 +1125,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20, IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, IEEE80211_HW_AP_LINK_PS = 1<<22, + IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, }; /** diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index f10e1096c332..250b9a53f6d9 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -360,7 +360,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, return -EINVAL; if ((tid >= STA_TID_NUM) || - !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) + !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) || + (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) return -EINVAL; #ifdef CONFIG_MAC80211_HT_DEBUG diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 569609b94c8c..c9141168fd43 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -350,6 +350,8 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n"); if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n"); + if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW) + sf += snprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n"); rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); kfree(buf); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c9766ccb51a4..2521716aa97b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1232,7 +1232,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, tx->sta = sta_info_get(sdata, hdr->addr1); if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && - (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { + (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) && + !(local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) { struct tid_ampdu_tx *tid_tx; qc = ieee80211_get_qos_ctl(hdr); From 4c5ade414912cd903906339491675352bfccbdfe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 30 Aug 2011 22:16:15 +0300 Subject: [PATCH 087/287] mac80211: handle allocation failures in mesh_pathtbl_init() The calls to kzalloc() weren't checked here and it upsets the static checkers. Obviously they're not super likely to fail, but we might as well add some error handling. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index a66a2cab8d34..55a206cfb8cc 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -1095,6 +1095,7 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) int mesh_pathtbl_init(void) { struct mesh_table *tbl_path, *tbl_mpp; + int ret; tbl_path = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); if (!tbl_path) @@ -1103,18 +1104,26 @@ int mesh_pathtbl_init(void) tbl_path->copy_node = &mesh_path_node_copy; tbl_path->mean_chain_len = MEAN_CHAIN_LEN; tbl_path->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC); + if (!tbl_path->known_gates) { + ret = -ENOMEM; + goto free_path; + } INIT_HLIST_HEAD(tbl_path->known_gates); tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); if (!tbl_mpp) { - mesh_table_free(tbl_path, true); - return -ENOMEM; + ret = -ENOMEM; + goto free_path; } tbl_mpp->free_node = &mesh_path_node_free; tbl_mpp->copy_node = &mesh_path_node_copy; tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN; tbl_mpp->known_gates = kzalloc(sizeof(struct hlist_head), GFP_ATOMIC); + if (!tbl_mpp->known_gates) { + ret = -ENOMEM; + goto free_mpp; + } INIT_HLIST_HEAD(tbl_mpp->known_gates); /* Need no locking since this is during init */ @@ -1122,6 +1131,12 @@ int mesh_pathtbl_init(void) RCU_INIT_POINTER(mpp_paths, tbl_mpp); return 0; + +free_mpp: + mesh_table_free(tbl_mpp, true); +free_path: + mesh_table_free(tbl_path, true); + return ret; } void mesh_path_expire(struct ieee80211_sub_if_data *sdata) From 81a91d575512de74b1455d0ea213bde6f7b1e026 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 31 Aug 2011 10:47:30 +0530 Subject: [PATCH 088/287] ath9k_hw: Fix rx latency of 11a mode Rx latecy to start signal(usec) of 11a is 41 not 37 and also corrected the rx delay in quarter rate. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 468ac4b17dfb..16884c416a7e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -975,7 +975,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) if (ah->misc_mode != 0) REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode); - rx_lat = 37; + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + rx_lat = 41; + else + rx_lat = 37; tx_lat = 54; if (IS_CHAN_HALF_RATE(chan)) { @@ -989,7 +992,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) sifstime = 32; } else if (IS_CHAN_QUARTER_RATE(chan)) { eifs = 340; - rx_lat *= 4; + rx_lat = (rx_lat * 4) - 1; tx_lat *= 4; if (IS_CHAN_A_FAST_CLOCK(ah, chan)) tx_lat += 22; From 427977ab2e24bb76c733cc50be97d4262028f14a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 31 Aug 2011 09:37:42 +0300 Subject: [PATCH 089/287] iwlwifi: fix double assign in iwl_start_tx_ba_trans_ready() "vif" is assigned twice. We can remove the first one. This silences a Smatch warning that "ctx" could be one step past the end of the priv->contexts[] array. Signed-off-by: Dan Carpenter Reviewed-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 20dd1a5506ed..72b9203c06e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1842,7 +1842,7 @@ void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid) { - struct ieee80211_vif *vif = priv->contexts[ctx].vif; + struct ieee80211_vif *vif; u8 *addr = priv->stations[sta_id].sta.sta.addr; if (ctx == NUM_IWL_RXON_CTX) From 4690c33df6be8bf78a0d5fe58baae33462b0bc1f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 31 Aug 2011 09:38:30 +0300 Subject: [PATCH 090/287] iwlwifi: signedness bug in iwl_trans_pcie_tx_agg_alloc() unsigned shorts and unsigned chars are never == -1. Signed-off-by: Dan Carpenter Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c index 5dd6a6d1dfd7..ea6a0bc8ca20 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c @@ -535,7 +535,7 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tid_data *tid_data; unsigned long flags; - u16 txq_id; + int txq_id; struct iwl_priv *priv = priv(trans); txq_id = iwlagn_txq_ctx_activate_free(trans); From cedb5412baeffd7326fc4869aa996d7f68d98ebb Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 31 Aug 2011 11:29:43 +0300 Subject: [PATCH 091/287] nl80211/cfg80211: add WIPHY_FLAG_AP_UAPSD flag add WIPHY_FLAG_AP_UAPSD flag to indicate uapsd support on AP mode. Advertise it to userspace by including a new NL80211_ATTR_SUPPORT_AP_UAPSD attribute. Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- include/linux/nl80211.h | 3 +++ include/net/cfg80211.h | 2 ++ net/wireless/nl80211.c | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index f2d75e3ceb43..387e6e220502 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -1044,6 +1044,8 @@ enum nl80211_commands { * * @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration * of the station, see &enum nl80211_sta_wme_attr. + * @NL80211_ATTR_SUPPORT_AP_UAPSD: the device supports uapsd when working + * as AP. * * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of * roaming to another AP in the same ESS if the signal lever is low. @@ -1259,6 +1261,7 @@ enum nl80211_attrs { NL80211_ATTR_IE_ASSOC_RESP, NL80211_ATTR_STA_WME, + NL80211_ATTR_SUPPORT_AP_UAPSD, NL80211_ATTR_ROAM_SUPPORT, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 53609dec2c9f..01c6bde99a41 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1621,6 +1621,7 @@ struct cfg80211_ops { * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans. * @WIPHY_FLAG_SUPPORTS_FW_ROAM: The device supports roaming feature in the * firmware. + * @WIPHY_FLAG_AP_UAPSD: The device supports uapsd on AP. */ enum wiphy_flags { WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), @@ -1636,6 +1637,7 @@ enum wiphy_flags { WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), WIPHY_FLAG_ENFORCE_COMBINATIONS = BIT(12), WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13), + WIPHY_FLAG_AP_UAPSD = BIT(14), }; /** diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index ad13903c9b89..0cda46ab35e5 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -720,6 +720,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); + if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) + NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD); if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT); @@ -2601,7 +2603,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) return -EINVAL; /* parse WME attributes if sta is WME capable */ - if ((params.sta_flags_set & NL80211_STA_FLAG_WME) && + if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && + (params.sta_flags_set & NL80211_STA_FLAG_WME) && info->attrs[NL80211_ATTR_STA_WME]) { struct nlattr *tb[NL80211_STA_WME_MAX + 1]; struct nlattr *nla; From a1f1c21c181be20a8b7e073e5292ff1fe77769fa Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Wed, 31 Aug 2011 16:01:48 +0300 Subject: [PATCH 092/287] nl80211/cfg80211: add match filtering for sched_scan Introduce filtering for scheduled scans to reduce the number of unnecessary results (which cause useless wake-ups). Add a new nested attribute where sets of parameters to be matched can be passed when starting a scheduled scan. Only scan results that match any of the sets will be returned. At this point, the set consists of a single parameter, an SSID. This can be easily extended in the future to support more complex matches. Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- include/linux/nl80211.h | 43 ++++++++++++++++++++++++++++++ include/net/cfg80211.h | 20 ++++++++++++++ net/wireless/nl80211.c | 59 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 387e6e220502..8aa7badc1966 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -769,6 +769,8 @@ enum nl80211_commands { * that can be added to a scan request * @NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: maximum length of information * elements that can be added to a scheduled scan request + * @NL80211_ATTR_MAX_MATCH_SETS: maximum number of sets that can be + * used with @NL80211_ATTR_SCHED_SCAN_MATCH, a wiphy attribute. * * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz) * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive @@ -1011,6 +1013,24 @@ enum nl80211_commands { * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan * cycles, in msecs. + + * @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more + * sets of attributes to match during scheduled scans. Only BSSs + * that match any of the sets will be reported. These are + * pass-thru filter rules. + * For a match to succeed, the BSS must match all attributes of a + * set. Since not every hardware supports matching all types of + * attributes, there is no guarantee that the reported BSSs are + * fully complying with the match sets and userspace needs to be + * able to ignore them by itself. + * Thus, the implementation is somewhat hardware-dependent, but + * this is only an optimization and the userspace application + * needs to handle all the non-filtered results anyway. + * If the match attributes don't make sense when combined with + * the values passed in @NL80211_ATTR_SCAN_SSIDS (eg. if an SSID + * is included in the probe request, but the match attributes + * will never let it go through), -EINVAL may be returned. + * If ommited, no filtering is done. * * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported * interface combinations. In each nested item, it contains attributes @@ -1265,6 +1285,9 @@ enum nl80211_attrs { NL80211_ATTR_ROAM_SUPPORT, + NL80211_ATTR_SCHED_SCAN_MATCH, + NL80211_ATTR_MAX_MATCH_SETS, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1723,6 +1746,26 @@ enum nl80211_reg_rule_attr { NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 }; +/** + * enum nl80211_sched_scan_match_attr - scheduled scan match attributes + * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, + * only report BSS with matching SSID. + * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter + * attribute number currently defined + * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use + */ +enum nl80211_sched_scan_match_attr { + __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID, + + NL80211_ATTR_SCHED_SCAN_MATCH_SSID, + + /* keep last */ + __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, + NL80211_SCHED_SCAN_MATCH_ATTR_MAX = + __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 +}; + /** * enum nl80211_reg_rule_flags - regulatory rule flags * diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 01c6bde99a41..09024ab617f9 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -875,6 +875,15 @@ struct cfg80211_scan_request { struct ieee80211_channel *channels[0]; }; +/** + * struct cfg80211_match_set - sets of attributes to match + * + * @ssid: SSID to be matched + */ +struct cfg80211_match_set { + struct cfg80211_ssid ssid; +}; + /** * struct cfg80211_sched_scan_request - scheduled scan request description * @@ -884,6 +893,11 @@ struct cfg80211_scan_request { * @interval: interval between each scheduled scan cycle * @ie: optional information element(s) to add into Probe Request or %NULL * @ie_len: length of ie in octets + * @match_sets: sets of parameters to be matched for a scan result + * entry to be considered valid and to be passed to the host + * (others are filtered out). + * If ommited, all results are passed. + * @n_match_sets: number of match sets * @wiphy: the wiphy this was for * @dev: the interface * @channels: channels to scan @@ -895,6 +909,8 @@ struct cfg80211_sched_scan_request { u32 interval; const u8 *ie; size_t ie_len; + struct cfg80211_match_set *match_sets; + int n_match_sets; /* internal */ struct wiphy *wiphy; @@ -1814,6 +1830,9 @@ struct wiphy_wowlan_support { * any given scan * @max_sched_scan_ssids: maximum number of SSIDs the device can scan * for in any given scheduled scan + * @max_match_sets: maximum number of match sets the device can handle + * when performing a scheduled scan, 0 if filtering is not + * supported. * @max_scan_ie_len: maximum length of user-controlled IEs device can * add to probe request frames transmitted during a scan, must not * include fixed IEs like supported rates @@ -1871,6 +1890,7 @@ struct wiphy { int bss_priv_size; u8 max_scan_ssids; u8 max_sched_scan_ssids; + u8 max_match_sets; u16 max_scan_ie_len; u16 max_sched_scan_ie_len; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0cda46ab35e5..f4cfd3abfbfd 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -190,6 +190,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY, .len = IEEE80211_MAX_DATA_LEN }, [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, + [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, }; /* policy for the key attributes */ @@ -232,6 +233,12 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, }; +static const struct nla_policy +nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { + [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_SSID_LEN }, +}; + /* ifidx get helper */ static int nl80211_get_ifidx(struct netlink_callback *cb) { @@ -715,6 +722,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, dev->wiphy.max_scan_ie_len); NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, dev->wiphy.max_sched_scan_ie_len); + NLA_PUT_U8(msg, NL80211_ATTR_MAX_MATCH_SETS, + dev->wiphy.max_match_sets); if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); @@ -3632,10 +3641,11 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, struct net_device *dev = info->user_ptr[1]; struct nlattr *attr; struct wiphy *wiphy; - int err, tmp, n_ssids = 0, n_channels, i; + int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i; u32 interval; enum ieee80211_band band; size_t ie_len; + struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || !rdev->ops->sched_scan_start) @@ -3674,6 +3684,15 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (n_ssids > wiphy->max_sched_scan_ssids) return -EINVAL; + if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) + nla_for_each_nested(attr, + info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], + tmp) + n_match_sets++; + + if (n_match_sets > wiphy->max_match_sets) + return -EINVAL; + if (info->attrs[NL80211_ATTR_IE]) ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); else @@ -3691,6 +3710,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request = kzalloc(sizeof(*request) + sizeof(*request->ssids) * n_ssids + + sizeof(*request->match_sets) * n_match_sets + sizeof(*request->channels) * n_channels + ie_len, GFP_KERNEL); if (!request) { @@ -3708,6 +3728,18 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->ie = (void *)(request->channels + n_channels); } + if (n_match_sets) { + if (request->ie) + request->match_sets = (void *)(request->ie + ie_len); + else if (request->ssids) + request->match_sets = + (void *)(request->ssids + n_ssids); + else + request->match_sets = + (void *)(request->channels + n_channels); + } + request->n_match_sets = n_match_sets; + i = 0; if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { /* user specified, bail out if channel not found */ @@ -3772,6 +3804,31 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, } } + i = 0; + if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { + nla_for_each_nested(attr, + info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], + tmp) { + struct nlattr *ssid; + + nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, + nla_data(attr), nla_len(attr), + nl80211_match_policy); + ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID]; + if (ssid) { + if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { + err = -EINVAL; + goto out_free; + } + memcpy(request->match_sets[i].ssid.ssid, + nla_data(ssid), nla_len(ssid)); + request->match_sets[i].ssid.ssid_len = + nla_len(ssid); + } + i++; + } + } + if (info->attrs[NL80211_ATTR_IE]) { request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); memcpy((void *)request->ie, From 5126d97ef5a38df8b24abb7611dcba7e5b729021 Mon Sep 17 00:00:00 2001 From: "zero.lin" Date: Wed, 31 Aug 2011 20:43:52 +0200 Subject: [PATCH 093/287] rt2x00: Add new chipset support Signed-off-by: zero.lin Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cabf249aa55b..7586468955da 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1153,6 +1153,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { #endif #ifdef CONFIG_RT2800PCI_RT53XX { PCI_DEVICE(0x1814, 0x5390) }, + { PCI_DEVICE(0x1814, 0x539a) }, { PCI_DEVICE(0x1814, 0x539f) }, #endif { 0, } From 0b4ff45d8e0f0f34e18823bd4e144bc324cae4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 31 Aug 2011 23:36:16 +0200 Subject: [PATCH 094/287] b43: LCN-PHY: minor fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The biggest change is reversing order of reading 32-bit table value. MMIO dumps has shown it's done that way for LCN-PHY. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 2 ++ drivers/net/wireless/b43/main.c | 1 + drivers/net/wireless/b43/tables_phy_lcn.c | 10 ++++------ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 8ff706289b5d..f8615cdf1075 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -110,6 +110,8 @@ #define B43_MMIO_TSF_CFP_START_LOW 0x604 #define B43_MMIO_TSF_CFP_START_HIGH 0x606 #define B43_MMIO_TSF_CFP_PRETBTT 0x612 +#define B43_MMIO_TSF_CLK_FRAC_LOW 0x62E +#define B43_MMIO_TSF_CLK_FRAC_HIGH 0x630 #define B43_MMIO_TSF_0 0x632 /* core rev < 3 only */ #define B43_MMIO_TSF_1 0x634 /* core rev < 3 only */ #define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 172294170df8..6bca727456b6 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2953,6 +2953,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev) case B43_PHYTYPE_N: case B43_PHYTYPE_LP: case B43_PHYTYPE_HT: + case B43_PHYTYPE_LCN: b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1); b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1); b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1); diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index 0a5842808a78..916d3f194f42 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -318,9 +318,8 @@ u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset) break; case B43_LCNTAB_32BIT: b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); - value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI); - value <<= 16; - value |= b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); + value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); + value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16); break; default: B43_WARN_ON(1); @@ -357,10 +356,9 @@ void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset, break; case B43_LCNTAB_32BIT: *((u32 *)data) = b43_phy_read(dev, - B43_PHY_LCN_TABLE_DATAHI); - *((u32 *)data) <<= 16; - *((u32 *)data) |= b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); + *((u32 *)data) |= (b43_phy_read(dev, + B43_PHY_LCN_TABLE_DATAHI) << 16); data += 4; break; default: From b35e6d9a1c35fbb91716ab14551cc0985b443cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 31 Aug 2011 23:36:17 +0200 Subject: [PATCH 095/287] b43: LCN-PHY: put tables functions in correct file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 10 ---------- drivers/net/wireless/b43/tables_phy_lcn.c | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index b617e1f8ca28..9e575774e192 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -137,14 +137,6 @@ static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1); } -static void b43_phy_lcn_clean_0x18_table(struct b43_wldev *dev) -{ - u8 i; - - for (i = 0; i < 0x80; i++) - b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000); -} - static void b43_phy_lcn_clear_0x07_table(struct b43_wldev *dev) { u8 i; @@ -319,8 +311,6 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev) b43_phy_maskset(dev, 0x663, 0xFF00, 0x64); b43_phy_lcn_tables_init(dev); - /* TODO: various tables ops here */ - b43_phy_lcn_clean_0x18_table(dev); b43_phy_lcn_pre_radio_init(dev); b43_phy_lcn_clear_0x07_table(dev); diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index 916d3f194f42..f74c00a34ad5 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -445,7 +445,7 @@ void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset, #define lcntab_upload(dev, offset, data) do { \ b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ } while (0) -void b43_phy_lcn_tables_init(struct b43_wldev *dev) +static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev) { lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02); lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01); @@ -462,3 +462,18 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev) lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00); lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18); } + +static void b43_phy_lcn_clean_0x18_table(struct b43_wldev *dev) +{ + u8 i; + + for (i = 0; i < 0x80; i++) + b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000); +} + +void b43_phy_lcn_tables_init(struct b43_wldev *dev) +{ + b43_phy_lcn_upload_static_tables(dev); + /* TODO: various tables ops here */ + b43_phy_lcn_clean_0x18_table(dev); +} From 095be64ebf112a7427490e360db4505ebd39a212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 31 Aug 2011 23:36:18 +0200 Subject: [PATCH 096/287] b43: LCN-PHY: rewrite 0x7 table at the end of init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is not implemented in brcmsmac, but was noticed in (newer) wl. Can be workaround for some hardware bug. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_phy_lcn.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index f74c00a34ad5..95efea645077 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -463,6 +463,17 @@ static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev) lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18); } +/* Not implemented in brcmsmac, noticed in wl in MMIO dump */ +static void b43_phy_lcn_rewrite_tables(struct b43_wldev *dev) +{ + int i; + u32 tmp; + for (i = 0; i < 128; i++) { + tmp = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x240 + i)); + b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), tmp); + } +} + static void b43_phy_lcn_clean_0x18_table(struct b43_wldev *dev) { u8 i; @@ -475,5 +486,6 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev) { b43_phy_lcn_upload_static_tables(dev); /* TODO: various tables ops here */ + b43_phy_lcn_rewrite_tables(dev); b43_phy_lcn_clean_0x18_table(dev); } From 71c1d1e97f5849078a68992aee97d0bbe128ac63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 31 Aug 2011 23:36:19 +0200 Subject: [PATCH 097/287] b43: LCN-PHY: upload additional 0x7 table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_phy_lcn.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index 95efea645077..fd2b16d9d661 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -295,6 +295,20 @@ static const u32 b43_lcntab_0x18[] = { 0x00080000, 0x00080000, 0x00080000, 0x00080000, }; +const u16 b43_lcntab_0x0f_late[] = { + 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, + 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, + 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, + 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, + 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, + 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, + 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, + 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, + 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, + 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, + 0x0002, 0x0008, 0x0004, 0x0001, +}; + /************************************************** * R/W ops. **************************************************/ @@ -486,6 +500,9 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev) { b43_phy_lcn_upload_static_tables(dev); /* TODO: various tables ops here */ + b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0), + ARRAY_SIZE(b43_lcntab_0x0f_late), b43_lcntab_0x0f_late); + /* TODO: various tables ops here */ b43_phy_lcn_rewrite_tables(dev); b43_phy_lcn_clean_0x18_table(dev); } From bce4dc4a5d6c0ec9b40e353023a4bb30f791dfd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 31 Aug 2011 23:36:20 +0200 Subject: [PATCH 098/287] b43: LCN-PHY: rename functions, get rid of magic names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've compared b43 with brcmsmac and took functions names from the later. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 29 ++++++++++++++++++----- drivers/net/wireless/b43/tables_phy_lcn.c | 10 ++++---- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 9e575774e192..b461278c2442 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -31,6 +31,7 @@ * Radio 2064. **************************************************/ +/* wlc_lcnphy_radio_2064_channel_tune_4313 */ static void b43_radio_2064_channel_setup(struct b43_wldev *dev) { u16 save[2]; @@ -73,6 +74,7 @@ static void b43_radio_2064_channel_setup(struct b43_wldev *dev) b43_radio_write(dev, 0x091, 0x7); } +/* wlc_radio_2064_init */ static void b43_radio_2064_init(struct b43_wldev *dev) { b43_radio_write(dev, 0x09c, 0x0020); @@ -122,6 +124,7 @@ static void b43_radio_2064_init(struct b43_wldev *dev) * Various PHY ops **************************************************/ +/* wlc_lcnphy_toggle_afe_pwdn */ static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev) { u16 afe_ctl2 = b43_phy_read(dev, B43_PHY_LCN_AFE_CTL2); @@ -137,7 +140,8 @@ static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1); } -static void b43_phy_lcn_clear_0x07_table(struct b43_wldev *dev) +/* wlc_lcnphy_clear_tx_power_offsets */ +static void b43_phy_lcn_clear_tx_power_offsets(struct b43_wldev *dev) { u8 i; @@ -154,7 +158,8 @@ static void b43_phy_lcn_clear_0x07_table(struct b43_wldev *dev) } } -static void b43_phy_lcn_pre_radio_init(struct b43_wldev *dev) +/* wlc_lcnphy_rev0_baseband_init */ +static void b43_phy_lcn_rev0_baseband_init(struct b43_wldev *dev) { b43_radio_write(dev, 0x11c, 0); @@ -181,7 +186,11 @@ static void b43_phy_lcn_pre_radio_init(struct b43_wldev *dev) b43_phy_maskset(dev, 0x448, ~0x300, 0x100); b43_phy_maskset(dev, 0x608, ~0xff, 0x17); b43_phy_maskset(dev, 0x604, ~0x7ff, 0x3ea); +} +/* wlc_lcnphy_bu_tweaks */ +static void b43_phy_lcn_bu_tweaks(struct b43_wldev *dev) +{ b43_phy_set(dev, 0x805, 0x1); b43_phy_maskset(dev, 0x42f, ~0x7, 0x3); @@ -203,9 +212,16 @@ static void b43_phy_lcn_pre_radio_init(struct b43_wldev *dev) b43_phy_write(dev, 0x7d6, 0x0902); /* TODO: more ops */ + + if (dev->phy.rev == 1) { + /* TODO: more ops */ + + b43_phy_lcn_clear_tx_power_offsets(dev); + } } -static void b43_phy_lcn_save_configsth_restore(struct b43_wldev *dev) +/* wlc_lcnphy_vbat_temp_sense_setup */ +static void b43_phy_lcn_sense_setup(struct b43_wldev *dev) { u8 i; @@ -297,6 +313,7 @@ static void b43_phy_lcn_op_prepare_structs(struct b43_wldev *dev) memset(phy_lcn, 0, sizeof(*phy_lcn)); } +/* wlc_phy_init_lcnphy */ static int b43_phy_lcn_op_init(struct b43_wldev *dev) { b43_phy_set(dev, 0x44a, 0x80); @@ -312,15 +329,15 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev) b43_phy_lcn_tables_init(dev); - b43_phy_lcn_pre_radio_init(dev); - b43_phy_lcn_clear_0x07_table(dev); + b43_phy_lcn_rev0_baseband_init(dev); + b43_phy_lcn_bu_tweaks(dev); if (dev->phy.radio_ver == 0x2064) b43_radio_2064_init(dev); else B43_WARN_ON(1); - b43_phy_lcn_save_configsth_restore(dev); + b43_phy_lcn_sense_setup(dev); return 0; } diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index fd2b16d9d661..c62a94082bca 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -295,7 +295,7 @@ static const u32 b43_lcntab_0x18[] = { 0x00080000, 0x00080000, 0x00080000, 0x00080000, }; -const u16 b43_lcntab_0x0f_late[] = { +const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = { 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, @@ -488,7 +488,8 @@ static void b43_phy_lcn_rewrite_tables(struct b43_wldev *dev) } } -static void b43_phy_lcn_clean_0x18_table(struct b43_wldev *dev) +/* wlc_lcnphy_clear_papd_comptable */ +static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev) { u8 i; @@ -501,8 +502,9 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev) b43_phy_lcn_upload_static_tables(dev); /* TODO: various tables ops here */ b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0), - ARRAY_SIZE(b43_lcntab_0x0f_late), b43_lcntab_0x0f_late); + ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0), + b43_lcntab_sw_ctl_4313_epa_rev0); /* TODO: various tables ops here */ b43_phy_lcn_rewrite_tables(dev); - b43_phy_lcn_clean_0x18_table(dev); + b43_phy_lcn_clean_papd_comp_table(dev); } From cf577fc242ea5295f676ae3bf9ecb524d78d9e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 31 Aug 2011 23:36:21 +0200 Subject: [PATCH 099/287] b43: LCN-PHY: add conditions for few operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was not possible to guess the conditions from MMIO dumps. Take them from brcmsmac code. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 44 ++++++++++++++++------- drivers/net/wireless/b43/tables_phy_lcn.c | 8 ++++- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index b461278c2442..d0f106ed9f67 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -39,6 +39,7 @@ static void b43_radio_2064_channel_setup(struct b43_wldev *dev) b43_radio_set(dev, 0x09d, 0x4); b43_radio_write(dev, 0x09e, 0xf); + /* Channel specific values in theory, in practice always the same */ b43_radio_write(dev, 0x02a, 0xb); b43_radio_maskset(dev, 0x030, ~0x3, 0xa); b43_radio_maskset(dev, 0x091, ~0x3, 0); @@ -70,22 +71,31 @@ static void b43_radio_2064_channel_setup(struct b43_wldev *dev) b43_radio_write(dev, 0x044, save[0]); b43_radio_write(dev, 0x12b, save[1]); - b43_radio_write(dev, 0x038, 0x0); - b43_radio_write(dev, 0x091, 0x7); + if (dev->phy.rev == 1) { + /* brcmsmac uses outdated 0x3 for 0x038 */ + b43_radio_write(dev, 0x038, 0x0); + b43_radio_write(dev, 0x091, 0x7); + } } /* wlc_radio_2064_init */ static void b43_radio_2064_init(struct b43_wldev *dev) { - b43_radio_write(dev, 0x09c, 0x0020); - b43_radio_write(dev, 0x105, 0x0008); + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + b43_radio_write(dev, 0x09c, 0x0020); + b43_radio_write(dev, 0x105, 0x0008); + } else { + /* TODO */ + } b43_radio_write(dev, 0x032, 0x0062); b43_radio_write(dev, 0x033, 0x0019); b43_radio_write(dev, 0x090, 0x0010); b43_radio_write(dev, 0x010, 0x0000); - b43_radio_write(dev, 0x060, 0x007f); - b43_radio_write(dev, 0x061, 0x0072); - b43_radio_write(dev, 0x062, 0x007f); + if (dev->phy.rev == 1) { + b43_radio_write(dev, 0x060, 0x007f); + b43_radio_write(dev, 0x061, 0x0072); + b43_radio_write(dev, 0x062, 0x007f); + } b43_radio_write(dev, 0x01d, 0x0002); b43_radio_write(dev, 0x01e, 0x0006); @@ -145,10 +155,12 @@ static void b43_phy_lcn_clear_tx_power_offsets(struct b43_wldev *dev) { u8 i; - b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x340); - for (i = 0; i < 30; i++) { - b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, 0); - b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, 0); + if (1) { /* FIXME */ + b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x340); + for (i = 0; i < 30; i++) { + b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, 0); + b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, 0); + } } b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x80); @@ -178,8 +190,13 @@ static void b43_phy_lcn_rev0_baseband_init(struct b43_wldev *dev) b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); + if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM)) + ; /* TODO */ b43_phy_maskset(dev, 0x634, ~0xff, 0xc); - b43_phy_maskset(dev, 0x634, ~0xff, 0xa); + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM) { + b43_phy_maskset(dev, 0x634, ~0xff, 0xa); + b43_phy_write(dev, 0x910, 0x1); + } b43_phy_write(dev, 0x910, 0x1); @@ -207,7 +224,8 @@ static void b43_phy_lcn_bu_tweaks(struct b43_wldev *dev) b43_phy_maskset(dev, 0x434, ~0xff, 0xfd); b43_phy_maskset(dev, 0x420, ~0xff, 0x10); - b43_radio_set(dev, 0x09b, 0xf0); + if (dev->dev->bus_sprom->board_rev >= 0x1204) + b43_radio_set(dev, 0x09b, 0xf0); b43_phy_write(dev, 0x7d6, 0x0902); diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index c62a94082bca..7bf70578b5c2 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -501,9 +501,15 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev) { b43_phy_lcn_upload_static_tables(dev); /* TODO: various tables ops here */ - b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0), + + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM && + !(dev->dev->bus_sprom->boardflags_hi & B43_BFH_FEM_BT)) + b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0), ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0), b43_lcntab_sw_ctl_4313_epa_rev0); + else + b43err(dev->wl, "SW ctl table is unknown for this card\n"); + /* TODO: various tables ops here */ b43_phy_lcn_rewrite_tables(dev); b43_phy_lcn_clean_papd_comp_table(dev); From f84f234c6417e3d60b1cfeaf9d16c3bd1c8fe2a5 Mon Sep 17 00:00:00 2001 From: Bill Jordan Date: Wed, 31 Aug 2011 17:51:00 -0400 Subject: [PATCH 100/287] ath9k: ath9k_hw_set_txpowerlimit sets previous txpower In commit 9c204b46c7af93e334114bea1f5eeaa6fea9ba07 (ath9k_hw: do not limit initial tx power to 20 dbm), setting of txpower was broken. This patch fixes it by initializing reg_pwr from the new power limit, not the previous value. Signed-off-by: Bill Jordan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 16884c416a7e..47d10a4463f1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2451,13 +2451,13 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath9k_channel *chan = ah->curchan; struct ieee80211_channel *channel = chan->chan; - int reg_pwr = min_t(int, MAX_RATE_POWER, regulatory->power_limit); + int reg_pwr = min_t(int, MAX_RATE_POWER, limit); int chan_pwr = channel->max_power * 2; if (test) reg_pwr = chan_pwr = MAX_RATE_POWER; - regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER); + regulatory->power_limit = reg_pwr; ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(regulatory, chan), From 56e6786e59cba2c714091ed53deffa6001a32841 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 1 Sep 2011 11:54:12 -0400 Subject: [PATCH 101/287] cfg80211: print bandwidth in chan_reg_rule_print_dbg() Two spaces and the second "KHz" suggest that the code author meant to print the bandwidth but forgot it. The code appears in commit e702d3cf already with two spaces and "KHz" in place of the bandwidth. Signed-off-by: Pavel Roskin Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 9f3aa5cabdef..a2b09c2df1bf 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -751,9 +751,10 @@ static void chan_reg_rule_print_dbg(struct ieee80211_channel *chan, chan->center_freq, KHZ_TO_MHZ(desired_bw_khz)); - REG_DBG_PRINT("%d KHz - %d KHz @ KHz), (%s mBi, %d mBm)\n", + REG_DBG_PRINT("%d KHz - %d KHz @ %d KHz), (%s mBi, %d mBm)\n", freq_range->start_freq_khz, freq_range->end_freq_khz, + freq_range->max_bandwidth_khz, max_antenna_gain, power_rule->max_eirp); } From c91d06006dd327153d163e5299b8c92f82da86b3 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 25 Aug 2011 18:10:57 +0300 Subject: [PATCH 102/287] wl12xx: print acx id Add id param to the acx debug print (on wl1271_cmd_configure) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 817bc183bc83..9ec2f31b0ecf 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -895,7 +895,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len) struct acx_header *acx = buf; int ret; - wl1271_debug(DEBUG_CMD, "cmd configure"); + wl1271_debug(DEBUG_CMD, "cmd configure (%d)", id); acx->id = cpu_to_le16(id); From 5c472148b0894478c427f5b1b0f69602cb103f88 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 25 Aug 2011 18:10:58 +0300 Subject: [PATCH 103/287] wl12xx: print the seq_num of rx packet Make it easier to match the driver log against a sniffer log. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/rx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 78d8410da1f4..9074625853b2 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -107,6 +107,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, u8 beacon = 0; u8 is_data = 0; u8 reserved = unaligned ? NET_IP_ALIGN : 0; + u16 seq_num; /* * In PLT mode we seem to get frames and mac80211 warns about them, @@ -169,9 +170,11 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); - wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, + seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d", skb, skb->len - desc->pad_len, - beacon ? "beacon" : ""); + beacon ? "beacon" : "", + seq_num); skb_trim(skb, skb->len - desc->pad_len); From 2a5bff091f4c32d07f007d6491453b67b497a3a4 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 25 Aug 2011 18:10:59 +0300 Subject: [PATCH 104/287] wl12xx: add module_param to trigger BUG() on recovery Crashing on recovery is useful for debugging, as a JTAG can be connected in order to investigate the current fw state. (otherwise, a reconfiguration will occur) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index bde84027ab7f..8324d905b431 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -362,6 +362,7 @@ static struct conf_drv_settings default_conf = { }; static char *fwlog_param; +static bool bug_on_recovery; static void __wl1271_op_remove_interface(struct wl1271 *wl, bool reset_tx_queues); @@ -1213,6 +1214,8 @@ static void wl1271_recovery_work(struct work_struct *work) wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); + BUG_ON(bug_on_recovery); + /* * Advance security sequence number to overcome potential progress * in the firmware during recovery. This doens't hurt if the network is @@ -4776,6 +4779,9 @@ module_param_named(fwlog, fwlog_param, charp, 0); MODULE_PARM_DESC(keymap, "FW logger options: continuous, ondemand, dbgpins or disable"); +module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho "); MODULE_AUTHOR("Juuso Oikarinen "); From a0a521560a686ccb06c92919f1047f94acbb8835 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 25 Aug 2011 18:11:00 +0300 Subject: [PATCH 105/287] wl12xx: add beacon_filtering debugfs file Allow enabling/disabling beacon_filtering by debugfs, in order to reduce the log size while debugging (beacon filtering is disabled by default in AP mode, as beacons are needed for ERP configuration). Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index d59354f53702..d227385a8f9c 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -655,6 +655,47 @@ static const struct file_operations rx_streaming_always_ops = { .llseek = default_llseek, }; +static ssize_t beacon_filtering_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + char buf[10]; + size_t len; + unsigned long value; + int ret; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + buf[len] = '\0'; + + ret = kstrtoul(buf, 0, &value); + if (ret < 0) { + wl1271_warning("illegal value for beacon_filtering!"); + return -EINVAL; + } + + mutex_lock(&wl->mutex); + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1271_acx_beacon_filter_opt(wl, !!value); + + wl1271_ps_elp_sleep(wl); +out: + mutex_unlock(&wl->mutex); + return count; +} + +static const struct file_operations beacon_filtering_ops = { + .write = beacon_filtering_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + static int wl1271_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { @@ -767,6 +808,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(driver_state, rootdir); DEBUGFS_ADD(dtim_interval, rootdir); DEBUGFS_ADD(beacon_interval, rootdir); + DEBUGFS_ADD(beacon_filtering, rootdir); streaming = debugfs_create_dir("rx_streaming", rootdir); if (!streaming || IS_ERR(streaming)) From 87579550b2532c23789c89eaa61814d5e71ea521 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 28 Aug 2011 15:11:53 +0300 Subject: [PATCH 106/287] wl12xx: don't disconnect on recovery allow full connection recovery by dropping the beacon_loss notification. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8324d905b431..8aff8d4102d5 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1225,9 +1225,6 @@ static void wl1271_recovery_work(struct work_struct *work) test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) wl->tx_security_seq += WL1271_TX_SQN_POST_RECOVERY_PADDING; - if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) - ieee80211_connection_loss(wl->vif); - /* Prevent spurious TX during FW restart */ ieee80211_stop_queues(wl->hw); From 2ec7da254c5bdb5fe1dc18f8f5bdbe32deb3c466 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 28 Aug 2011 15:11:54 +0300 Subject: [PATCH 107/287] wl12xx: don't use WL1271_SCAN_OPT_PRIORITY_HIGH flag When setting the WL1271_SCAN_OPT_PRIORITY_HIGH flag, the driver requests a scan *now*, and the fw doesn't enter psm before scanning, which in turn might cause packets loss. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/scan.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index af4ad2353f59..b2e2abd40045 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -164,9 +164,6 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, goto out; } - /* We always use high priority scans */ - scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; - /* No SSIDs means that we have a forced passive scan */ if (passive || wl->scan.req->n_ssids == 0) scan_options |= WL1271_SCAN_OPT_PASSIVE; From e0b38265b035a8a2ea05071b67b997f5db181c45 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 28 Aug 2011 15:11:55 +0300 Subject: [PATCH 108/287] wl12xx: check for ROC on scan_complete When scan completes, and we are not associated, we should start the dev role and ROC. however, we might already be in this situation (e.g. if we got disconnected during scan). check for it. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/scan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index b2e2abd40045..4a4d0d03fa1f 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -65,8 +65,9 @@ void wl1271_scan_complete_work(struct work_struct *work) /* return to ROC if needed */ is_sta = (wl->bss_type == BSS_TYPE_STA_BSS); is_ibss = (wl->bss_type == BSS_TYPE_IBSS); - if ((is_sta && !test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) || - (is_ibss && !test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags))) { + if (((is_sta && !test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) || + (is_ibss && !test_bit(WL1271_FLAG_IBSS_JOINED, &wl->flags))) && + !test_bit(wl->dev_role_id, wl->roc_map)) { /* restore remain on channel */ wl12xx_cmd_role_start_dev(wl); wl12xx_roc(wl, wl->dev_role_id); From 9487775c5b785d7c1e8182825c9ff9cf5e88149e Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 28 Aug 2011 15:11:56 +0300 Subject: [PATCH 109/287] wl12xx: add config_hangover command Add wl12xx_acx_config_hangover() and respective conf values. This command configures how long the chip will stay awake after it was configured to enter psm. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/acx.c | 40 ++++++++++++++++++++++++++++++ drivers/net/wireless/wl12xx/acx.h | 18 ++++++++++++++ drivers/net/wireless/wl12xx/conf.h | 23 +++++++++++------ drivers/net/wireless/wl12xx/init.c | 5 ++++ drivers/net/wireless/wl12xx/main.c | 14 ++++++++++- 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index e047594794aa..9809e41f06e2 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1691,3 +1691,43 @@ int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl) kfree(acx); return ret; } + +int wl12xx_acx_config_hangover(struct wl1271 *wl) +{ + struct wl12xx_acx_config_hangover *acx; + struct conf_hangover_settings *conf = &wl->conf.hangover; + int ret; + + wl1271_debug(DEBUG_ACX, "acx config hangover"); + + acx = kzalloc(sizeof(*acx), GFP_KERNEL); + if (!acx) { + ret = -ENOMEM; + goto out; + } + + acx->recover_time = cpu_to_le32(conf->recover_time); + acx->hangover_period = conf->hangover_period; + acx->dynamic_mode = conf->dynamic_mode; + acx->early_termination_mode = conf->early_termination_mode; + acx->max_period = conf->max_period; + acx->min_period = conf->min_period; + acx->increase_delta = conf->increase_delta; + acx->decrease_delta = conf->decrease_delta; + acx->quiet_time = conf->quiet_time; + acx->increase_time = conf->increase_time; + acx->window_size = acx->window_size; + + ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx, + sizeof(*acx)); + + if (ret < 0) { + wl1271_warning("acx config hangover failed: %d", ret); + goto out; + } + +out: + kfree(acx); + return ret; + +} diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 758c596f62f6..556ee4e282d5 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -1144,6 +1144,23 @@ struct wl12xx_acx_set_rate_mgmt_params { u8 padding2[2]; } __packed; +struct wl12xx_acx_config_hangover { + struct acx_header header; + + __le32 recover_time; + u8 hangover_period; + u8 dynamic_mode; + u8 early_termination_mode; + u8 max_period; + u8 min_period; + u8 increase_delta; + u8 decrease_delta; + u8 quiet_time; + u8 increase_time; + u8 window_size; + u8 padding[2]; +} __packed; + enum { ACX_WAKE_UP_CONDITIONS = 0x0002, ACX_MEM_CFG = 0x0003, @@ -1281,5 +1298,6 @@ int wl1271_acx_config_ps(struct wl1271 *wl); int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); int wl1271_acx_fm_coex(struct wl1271 *wl); int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl); +int wl12xx_acx_config_hangover(struct wl1271 *wl); #endif /* __WL1271_ACX_H__ */ diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 82f205c43342..45428a21f9e2 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -915,14 +915,6 @@ struct conf_conn_settings { */ u8 psm_entry_nullfunc_retries; - /* - * Specifies the time to linger in active mode after successfully - * transmitting the PSM entry null-func frame. - * - * Range 0 - 255 TU's - */ - u8 psm_entry_hangover_period; - /* * * Specifies the interval of the connection keep-alive null-func @@ -1236,6 +1228,20 @@ struct conf_rate_policy_settings { u8 rate_retry_policy[ACX_RATE_MGMT_NUM_OF_RATES]; }; +struct conf_hangover_settings { + u32 recover_time; + u8 hangover_period; + u8 dynamic_mode; + u8 early_termination_mode; + u8 max_period; + u8 min_period; + u8 increase_delta; + u8 decrease_delta; + u8 quiet_time; + u8 increase_time; + u8 window_size; +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1254,6 +1260,7 @@ struct conf_drv_settings { struct conf_rx_streaming_settings rx_streaming; struct conf_fwlog fwlog; struct conf_rate_policy_settings rate; + struct conf_hangover_settings hangover; u8 hci_io_ds; }; diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index b13bebea95e0..09515f5e5e1d 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -707,6 +707,11 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; + /* configure hangover */ + ret = wl12xx_acx_config_hangover(wl); + if (ret < 0) + goto out_free_memmap; + return 0; out_free_memmap: diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 8aff8d4102d5..f1fd9916e020 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -239,7 +239,6 @@ static struct conf_drv_settings default_conf = { .psm_entry_retries = 8, .psm_exit_retries = 16, .psm_entry_nullfunc_retries = 3, - .psm_entry_hangover_period = 1, .keep_alive_interval = 55000, .max_listen_interval = 20, }, @@ -359,6 +358,19 @@ static struct conf_drv_settings default_conf = { 0x00, 0x00, 0x00, }, }, + .hangover = { + .recover_time = 0, + .hangover_period = 20, + .dynamic_mode = 1, + .early_termination_mode = 1, + .max_period = 20, + .min_period = 1, + .increase_delta = 1, + .decrease_delta = 2, + .quiet_time = 4, + .increase_time = 1, + .window_size = 16, + }, }; static char *fwlog_param; From 14623787abd1217f4c48f128fd4dc03e238265fe Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 28 Aug 2011 15:11:57 +0300 Subject: [PATCH 110/287] wl12xx: don't queue a new dummy packet if one is already pending The firmware only asks for one dummy packet at a time, but sometimes we are unable to provide it before a FW timer expires. When this happens, the FW will re-request the dummy packet. If a packet is still queued in the driver queues, do nothing in this case. This prevents spurious dummy packets from clogging up the VO AC. Signed-off-by: Arik Nemtsov Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index f1fd9916e020..aeb4cc51bd3b 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1540,7 +1540,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) int wl1271_tx_dummy_packet(struct wl1271 *wl) { unsigned long flags; - int q = wl1271_tx_get_queue(skb_get_queue_mapping(wl->dummy_packet)); + int q; + + /* no need to queue a new dummy packet if one is already pending */ + if (test_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) + return 0; + + q = wl1271_tx_get_queue(skb_get_queue_mapping(wl->dummy_packet)); spin_lock_irqsave(&wl->wl_lock, flags); set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags); From 04907011d59101b508b1c4258f2731fd8f6b6c0a Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 19 May 2011 09:35:00 +0300 Subject: [PATCH 111/287] wl12xx: remove deprecated CONFIG_WL12XX_HT flag The driver now support HT properly, so we can always have HT enabled. Remove the WL12XX_HT configuration. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/Kconfig | 10 ---------- drivers/net/wireless/wl12xx/main.c | 6 ------ drivers/net/wireless/wl12xx/rx.c | 2 -- drivers/net/wireless/wl12xx/tx.c | 2 -- 4 files changed, 20 deletions(-) diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 07bcb1548d8b..3fe388b87c2e 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -19,16 +19,6 @@ config WL12XX If you choose to build a module, it will be called wl12xx. Say N if unsure. -config WL12XX_HT - bool "TI wl12xx 802.11 HT support (EXPERIMENTAL)" - depends on WL12XX && EXPERIMENTAL - default n - ---help--- - This will enable 802.11 HT support in the wl12xx module. - - That configuration is temporary due to the code incomplete and - still in testing process. - config WL12XX_SPI tristate "TI wl12xx SPI support" depends on WL12XX && SPI_MASTER diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index aeb4cc51bd3b..e5b871c5c521 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4084,7 +4084,6 @@ static const u8 wl1271_rate_to_idx_2ghz[] = { /* 11n STA capabilities */ #define HW_RX_HIGHEST_RATE 72 -#ifdef CONFIG_WL12XX_HT #define WL12XX_HT_CAP { \ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \ (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \ @@ -4097,11 +4096,6 @@ static const u8 wl1271_rate_to_idx_2ghz[] = { .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ }, \ } -#else -#define WL12XX_HT_CAP { \ - .ht_supported = false, \ -} -#endif /* can't be const, mac80211 writes to this */ static struct ieee80211_supported_band wl1271_band_2ghz = { diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 9074625853b2..dee4cfe9ccc1 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -66,11 +66,9 @@ static void wl1271_rx_status(struct wl1271 *wl, status->rate_idx = wl1271_rate_to_idx(desc->rate, status->band); -#ifdef CONFIG_WL12XX_HT /* 11n support */ if (desc->rate <= CONF_HW_RXTX_RATE_MCS0) status->flag |= RX_FLAG_HT; -#endif status->signal = desc->rssi; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 08227e69616b..b8dbc6d1ff98 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -453,7 +453,6 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) rate_set >>= 1; } -#ifdef CONFIG_WL12XX_HT /* MCS rates indication are on bits 16 - 23 */ rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates; @@ -462,7 +461,6 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit); rate_set >>= 1; } -#endif return enabled_rates; } From b6883582a8ea6a7a70d4cc9f4c121ed3d8a75681 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Wed, 31 Aug 2011 14:50:13 +0300 Subject: [PATCH 112/287] wl12xx: use kstrtoul_from_user simplify code by calling kstrtoul_from_user() (instead of copy_from_user() + kstrtoul()) Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/debugfs.c | 46 +++------------------------ 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index d227385a8f9c..3999fd528302 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -265,18 +265,10 @@ static ssize_t gpio_power_write(struct file *file, size_t count, loff_t *ppos) { struct wl1271 *wl = file->private_data; - char buf[10]; - size_t len; unsigned long value; int ret; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) { - return -EFAULT; - } - buf[len] = '\0'; - - ret = kstrtoul(buf, 0, &value); + ret = kstrtoul_from_user(user_buf, count, 10, &value); if (ret < 0) { wl1271_warning("illegal value in gpio_power"); return -EINVAL; @@ -427,17 +419,10 @@ static ssize_t dtim_interval_write(struct file *file, size_t count, loff_t *ppos) { struct wl1271 *wl = file->private_data; - char buf[10]; - size_t len; unsigned long value; int ret; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - - ret = kstrtoul(buf, 0, &value); + ret = kstrtoul_from_user(user_buf, count, 10, &value); if (ret < 0) { wl1271_warning("illegal value for dtim_interval"); return -EINVAL; @@ -492,17 +477,10 @@ static ssize_t beacon_interval_write(struct file *file, size_t count, loff_t *ppos) { struct wl1271 *wl = file->private_data; - char buf[10]; - size_t len; unsigned long value; int ret; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - - ret = kstrtoul(buf, 0, &value); + ret = kstrtoul_from_user(user_buf, count, 10, &value); if (ret < 0) { wl1271_warning("illegal value for beacon_interval"); return -EINVAL; @@ -542,17 +520,10 @@ static ssize_t rx_streaming_interval_write(struct file *file, size_t count, loff_t *ppos) { struct wl1271 *wl = file->private_data; - char buf[10]; - size_t len; unsigned long value; int ret; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - - ret = kstrtoul(buf, 0, &value); + ret = kstrtoul_from_user(user_buf, count, 10, &value); if (ret < 0) { wl1271_warning("illegal value in rx_streaming_interval!"); return -EINVAL; @@ -601,17 +572,10 @@ static ssize_t rx_streaming_always_write(struct file *file, size_t count, loff_t *ppos) { struct wl1271 *wl = file->private_data; - char buf[10]; - size_t len; unsigned long value; int ret; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - - ret = kstrtoul(buf, 0, &value); + ret = kstrtoul_from_user(user_buf, count, 10, &value); if (ret < 0) { wl1271_warning("illegal value in rx_streaming_write!"); return -EINVAL; From 1ec23f7f709b7ab5552cb9c34089633c384ec657 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 25 Aug 2011 14:26:54 +0300 Subject: [PATCH 113/287] wl12xx: declare support for WIPHY_FLAG_AP_UAPSD Declare support for uapsd when working as AP, and set psd_type and sp_len whan a station is being added. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/cmd.c | 15 ++++++++++----- drivers/net/wireless/wl12xx/cmd.h | 7 +++++++ drivers/net/wireless/wl12xx/main.c | 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 9ec2f31b0ecf..084262f169b2 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -1413,7 +1413,7 @@ int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid) int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) { struct wl12xx_cmd_add_peer *cmd; - int ret; + int i, ret; u32 sta_rates; wl1271_debug(DEBUG_CMD, "cmd add peer %d", (int)hlid); @@ -1424,15 +1424,19 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) goto out; } - /* currently we don't support UAPSD */ - cmd->sp_len = 0; - memcpy(cmd->addr, sta->addr, ETH_ALEN); cmd->bss_index = WL1271_AP_BSS_INDEX; cmd->aid = sta->aid; cmd->hlid = hlid; + cmd->sp_len = sta->max_sp; cmd->wmm = sta->wme ? 1 : 0; + for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) + if (sta->wme && (sta->uapsd_queues & BIT(i))) + cmd->psd_type[i] = WL1271_PSD_UPSD_TRIGGER; + else + cmd->psd_type[i] = WL1271_PSD_LEGACY; + sta_rates = sta->supp_rates[wl->band]; if (sta->ht_cap.ht_supported) sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET; @@ -1440,7 +1444,8 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates)); - wl1271_debug(DEBUG_CMD, "new peer rates: 0x%x", cmd->supported_rates); + wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x", + cmd->supported_rates, sta->uapsd_queues); ret = wl1271_cmd_send(wl, CMD_ADD_PEER, cmd, sizeof(*cmd), 0); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 22c2f373dd04..8e4d11ec0c55 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -591,6 +591,13 @@ enum wl12xx_ssid_type { WL12XX_SSID_TYPE_ANY = 2, }; +enum wl1271_psd_type { + WL1271_PSD_LEGACY = 0, + WL1271_PSD_UPSD_TRIGGER = 1, + WL1271_PSD_LEGACY_PSPOLL = 2, + WL1271_PSD_SAPSD = 3 +}; + struct wl12xx_cmd_add_peer { struct wl1271_cmd_header header; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e5b871c5c521..501a9e408d7a 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4512,6 +4512,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE - sizeof(struct ieee80211_header); + wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; + /* make sure all our channels fit in the scanned_ch bitmask */ BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) + ARRAY_SIZE(wl1271_channels_5ghz) > From fb55377b2aa9464b773e8688a135d5b4c6aa91fa Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 2 Sep 2011 14:28:21 +0300 Subject: [PATCH 114/287] wl12xx: add support for sched_scan filters Implement support for filtering in scheduled scans. With this commit we now use the match sets passed by cfg80211 to filter on SSIDs. Due to the nature of the wl12xx firmware API, we don't allow SSIDs to be sent in the probe requests if they are not going to match any of the filters. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/scan.c | 107 +++++++++++++++++++---------- 1 file changed, 72 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 4a4d0d03fa1f..488033b2a39b 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -471,34 +471,77 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, cfg->passive[2] || cfg->active[2]; } -/* Returns 0 if no wildcard is used, 1 if wildcard is used or a - * negative value on error */ +/* Returns the scan type to be used or a negative value on error */ static int wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, struct cfg80211_sched_scan_request *req) { struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; - struct cfg80211_ssid *ssid = req->ssids; - int ret, wildcard = 0; + struct cfg80211_match_set *sets = req->match_sets; + struct cfg80211_ssid *ssids = req->ssids; + int ret = 0, type, i, j; wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list"); + /* No filter, no ssids or only bcast ssid */ + if (!req->n_match_sets && + (!req->n_ssids || + (req->n_ssids == 1 && req->ssids[0].ssid_len == 0))) { + type = SCAN_SSID_FILTER_ANY; + goto out; + } + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) - return -ENOMEM; + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + if (!req->n_match_sets) { + /* No filter, with ssids */ + type = SCAN_SSID_FILTER_DISABLED; + + for (i = 0; i < req->n_ssids; i++) { + cmd->ssids[cmd->n_ssids].type = (ssids[i].ssid_len) ? + SCAN_SSID_TYPE_HIDDEN : SCAN_SSID_TYPE_PUBLIC; + cmd->ssids[cmd->n_ssids].len = ssids[i].ssid_len; + memcpy(cmd->ssids[cmd->n_ssids].ssid, ssids[i].ssid, + ssids[i].ssid_len); + cmd->n_ssids++; + } + } else { + type = SCAN_SSID_FILTER_LIST; - while ((cmd->n_ssids < req->n_ssids) && ssid) { - if (ssid->ssid_len == 0) { - wildcard = 1; + /* Add all SSIDs from the filters */ + for (i = 0; i < req->n_match_sets; i++) { cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC; - } else { - cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_HIDDEN; + cmd->ssids[cmd->n_ssids].len = sets[i].ssid.ssid_len; + memcpy(cmd->ssids[cmd->n_ssids].ssid, + sets[i].ssid.ssid, sets[i].ssid.ssid_len); + cmd->n_ssids++; + } + if ((req->n_ssids > 1) || + (req->n_ssids == 1 && req->ssids[0].ssid_len > 0)) { + /* + * Mark all the SSIDs passed in the SSID list as HIDDEN, + * so they're used in probe requests. + */ + for (i = 0; i < req->n_ssids; i++) { + for (j = 0; j < cmd->n_ssids; j++) + if (!memcmp(req->ssids[i].ssid, + cmd->ssids[j].ssid, + req->ssids[i].ssid_len)) { + cmd->ssids[j].type = + SCAN_SSID_TYPE_HIDDEN; + break; + } + /* Fail if SSID isn't present in the filters */ + if (j == req->n_ssids) { + ret = -EINVAL; + goto out_free; + } + } } - cmd->ssids[cmd->n_ssids].len = ssid->ssid_len; - memcpy(cmd->ssids[cmd->n_ssids].ssid, ssid->ssid, - ssid->ssid_len); - ssid++; - cmd->n_ssids++; } wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd)); @@ -507,13 +550,15 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, sizeof(*cmd), 0); if (ret < 0) { wl1271_error("cmd sched scan ssid list failed"); - goto out; + goto out_free; } - ret = wildcard; -out: +out_free: kfree(cmd); - return ret; +out: + if (ret < 0) + return ret; + return type; } int wl1271_scan_sched_scan_config(struct wl1271 *wl, @@ -548,21 +593,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, cfg->intervals[i] = cpu_to_le32(req->interval); cfg->ssid_len = 0; - if (req->n_ssids == 0) { - wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_ANY"); - cfg->filter_type = SCAN_SSID_FILTER_ANY; - } else { - ret = wl12xx_scan_sched_scan_ssid_list(wl, req); - if (ret < 0) - goto out; - if (ret) { - wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_DISABLED"); - cfg->filter_type = SCAN_SSID_FILTER_DISABLED; - } else { - wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_LIST"); - cfg->filter_type = SCAN_SSID_FILTER_LIST; - } - } + ret = wl12xx_scan_sched_scan_ssid_list(wl, req); + if (ret < 0) + goto out; + + cfg->filter_type = ret; + + wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type); if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { wl1271_error("scan channel list is empty"); From 221737d24f884f3f829e7f94d24fc4cc6d0f7b41 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 2 Sep 2011 14:28:22 +0300 Subject: [PATCH 115/287] wl12xx: increase number of allowed SSIDs in sched_scan The latest firmware supports up to 16 SSIDs in the scheduled scan lists. Increase the number we report to cfg80211 and increase the min/max dwell time to 30 and 60 TUs respectively, because otherwise we don't have the time to send the probes for all SSIDs. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 501a9e408d7a..2eb1471ac4ec 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -266,8 +266,8 @@ static struct conf_drv_settings default_conf = { }, .sched_scan = { /* sched_scan requires dwell times in TU instead of TU/1000 */ - .min_dwell_time_active = 8, - .max_dwell_time_active = 30, + .min_dwell_time_active = 30, + .max_dwell_time_active = 60, .dwell_time_passive = 100, .dwell_time_dfs = 150, .num_probe_reqs = 2, @@ -4503,7 +4503,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); wl->hw->wiphy->max_scan_ssids = 1; - wl->hw->wiphy->max_sched_scan_ssids = 8; + wl->hw->wiphy->max_sched_scan_ssids = 16; + wl->hw->wiphy->max_match_sets = 16; /* * Maximum length of elements in scanning probe request templates * should be the maximum length possible for a template, without From 20a33e52edfd75510ee8cc56a013dd55cb0de0aa Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Fri, 2 Sep 2011 14:28:23 +0300 Subject: [PATCH 116/287] wl12xx: ignore sched scan match sets without SSID For now, cfg80211 only support match sets with SSIDs, but in the future more parameters will be added. This patch ignores eventual matches that do not contain SSIDs in preparation for the future. This change also affects the case where broadcast SSIDs are used. Matching a broadcast SSID will match everything, so they can be ignored. Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/scan.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 488033b2a39b..eeccc9f095bb 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -479,12 +479,17 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; struct cfg80211_match_set *sets = req->match_sets; struct cfg80211_ssid *ssids = req->ssids; - int ret = 0, type, i, j; + int ret = 0, type, i, j, n_match_ssids = 0; wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list"); + /* count the match sets that contain SSIDs */ + for (i = 0; i < req->n_match_sets; i++) + if (sets[i].ssid.ssid_len > 0) + n_match_ssids++; + /* No filter, no ssids or only bcast ssid */ - if (!req->n_match_sets && + if (!n_match_ssids && (!req->n_ssids || (req->n_ssids == 1 && req->ssids[0].ssid_len == 0))) { type = SCAN_SSID_FILTER_ANY; @@ -497,7 +502,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, goto out; } - if (!req->n_match_sets) { + if (!n_match_ssids) { /* No filter, with ssids */ type = SCAN_SSID_FILTER_DISABLED; @@ -514,6 +519,10 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, /* Add all SSIDs from the filters */ for (i = 0; i < req->n_match_sets; i++) { + /* ignore sets without SSIDs */ + if (!sets[i].ssid.ssid_len) + continue; + cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC; cmd->ssids[cmd->n_ssids].len = sets[i].ssid.ssid_len; memcpy(cmd->ssids[cmd->n_ssids].ssid, From f8e0af6b8732b47c2531a280753d29a4ca2d114b Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 25 Aug 2011 12:43:12 +0300 Subject: [PATCH 117/287] wl12xx: don't indicate up PS-filtered dummy packets Dummy packets are currently only sent on the system_hlid link. The system_hlid link should never be filtered for PS (as it is not a STA link). Even so, for correctness, don't indicate dummy packets up. The skb does not belong to mac80211 and as such does not contain a correct skb->cb. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/ps.c | 8 ++++++-- drivers/net/wireless/wl12xx/tx.c | 2 +- drivers/net/wireless/wl12xx/tx.h | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 4b720b1b9f65..c15ebf2efd40 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -199,15 +199,19 @@ static void wl1271_ps_filter_frames(struct wl1271 *wl, u8 hlid) unsigned long flags; int filtered[NUM_TX_QUEUES]; - /* filter all frames currently the low level queus for this hlid */ + /* filter all frames currently in the low level queues for this hlid */ for (i = 0; i < NUM_TX_QUEUES; i++) { filtered[i] = 0; while ((skb = skb_dequeue(&wl->links[hlid].tx_queue[i]))) { + filtered[i]++; + + if (WARN_ON(wl12xx_is_dummy_packet(wl, skb))) + continue; + info = IEEE80211_SKB_CB(skb); info->flags |= IEEE80211_TX_STAT_TX_FILTERED; info->status.rates[0].idx = -1; ieee80211_tx_status_ni(wl->hw, skb); - filtered[i]++; } } diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index b8dbc6d1ff98..b6b2d3ac75cf 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -143,7 +143,7 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl, u8 hlid) wl1271_ps_link_start(wl, hlid, true); } -static bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb) +bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb) { return wl->dummy_packet == skb; } diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 6519be4b2c38..5c0fbbe5b42f 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -214,5 +214,6 @@ u32 wl1271_tx_min_rate_get(struct wl1271 *wl); u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb); void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); void wl1271_handle_tx_low_watermark(struct wl1271 *wl); +bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); #endif From 56d4f8f685c073c7ed7203b78c57f5d893d65102 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 25 Aug 2011 12:43:13 +0300 Subject: [PATCH 118/287] wl12xx: AP mode - don't regulate FW blocks for non-active STAs Check a STA is associated before regulating its PS-status in mac80211. Should never happen, so warn as a precaution. [Small cosmetic change wrt Kalle Valo's comment. -- Luca] Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/tx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index b6b2d3ac75cf..b876e9eb4e83 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -30,6 +30,7 @@ #include "reg.h" #include "ps.h" #include "tx.h" +#include "event.h" static int wl1271_set_default_wep_key(struct wl1271 *wl, u8 id) { @@ -132,6 +133,9 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl, u8 hlid) if (hlid < WL1271_AP_STA_HLID_START) return; + if (WARN_ON(!wl1271_is_active_sta(wl, hlid))) + return; + fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); tx_pkts = wl->links[hlid].allocated_pkts; From c47e8229fa5622e4e3f2d6b8e847c4429696a275 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 25 Aug 2011 12:43:14 +0300 Subject: [PATCH 119/287] wl12xx: support up to 8 stations in AP-mode Change the max number of AP stations to 8, up from 5. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/wl12xx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index fb2753c46300..ba1fde9f9b28 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -234,14 +234,14 @@ struct wl1271_stats { #define NUM_TX_QUEUES 4 #define NUM_RX_PKT_DESC 8 -#define AP_MAX_STATIONS 5 +#define AP_MAX_STATIONS 8 /* Broadcast and Global links + system link + links to stations */ /* * TODO: when WL1271_AP_STA_HLID_START is no longer constant, change all * the places that use this. */ -#define AP_MAX_LINKS (AP_MAX_STATIONS + 3) +#define AP_MAX_LINKS (AP_MAX_STATIONS + WL1271_AP_STA_HLID_START) /* FW status registers */ struct wl12xx_fw_status { From da03209eaca9302e110925f84a515e03062aaa9e Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 25 Aug 2011 12:43:15 +0300 Subject: [PATCH 120/287] wl12xx: don't regulate links when a single STA is connected When operating as AP track the number of connected stations. When a single STA is connected don't regulate the PS status of the link. Since this is the only STA connected, there's no point holding space in FW for other links. This will speed up communications with a single connected STA in PSM. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 15 ++++++++++++--- drivers/net/wireless/wl12xx/tx.c | 7 +++++-- drivers/net/wireless/wl12xx/wl12xx.h | 3 +++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 2eb1471ac4ec..1127a3ee36e3 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -770,13 +770,14 @@ static int wl1271_plt_init(struct wl1271 *wl) static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts) { - bool fw_ps; + bool fw_ps, single_sta; /* only regulate station links */ if (hlid < WL1271_AP_STA_HLID_START) return; fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); + single_sta = (wl->active_sta_count == 1); /* * Wake up from high level PS if the STA is asleep with too little @@ -785,8 +786,12 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, u8 hlid, u8 tx_pkts) if (!fw_ps || tx_pkts < WL1271_PS_STA_MAX_PACKETS) wl1271_ps_link_end(wl, hlid); - /* Start high-level PS if the STA is asleep with enough blocks in FW */ - else if (fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) + /* + * Start high-level PS if the STA is asleep with enough blocks in FW. + * Make an exception if this is the only connected station. In this + * case FW-memory congestion is not a problem. + */ + else if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) wl1271_ps_link_start(wl, hlid, true); } @@ -2093,6 +2098,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, memset(wl->roles_map, 0, sizeof(wl->roles_map)); memset(wl->links_map, 0, sizeof(wl->links_map)); memset(wl->roc_map, 0, sizeof(wl->roc_map)); + wl->active_sta_count = 0; /* The system link is always allocated */ __set_bit(WL12XX_SYSTEM_HLID, wl->links_map); @@ -3747,6 +3753,7 @@ static int wl1271_allocate_sta(struct wl1271 *wl, wl_sta->hlid = WL1271_AP_STA_HLID_START + id; *hlid = wl_sta->hlid; memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN); + wl->active_sta_count++; return 0; } @@ -3763,6 +3770,7 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid) wl1271_tx_reset_link_queues(wl, hlid); __clear_bit(hlid, &wl->ap_ps_map); __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); + wl->active_sta_count--; } static int wl1271_op_sta_add(struct ieee80211_hw *hw, @@ -4640,6 +4648,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->session_counter = 0; wl->ap_bcast_hlid = WL12XX_INVALID_LINK_ID; wl->ap_global_hlid = WL12XX_INVALID_LINK_ID; + wl->active_sta_count = 0; setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer, (unsigned long) wl); wl->fwlog_size = 0; diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index b876e9eb4e83..2bf31302b975 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -126,7 +126,7 @@ static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, static void wl1271_tx_regulate_link(struct wl1271 *wl, u8 hlid) { - bool fw_ps; + bool fw_ps, single_sta; u8 tx_pkts; /* only regulate station links */ @@ -138,12 +138,15 @@ static void wl1271_tx_regulate_link(struct wl1271 *wl, u8 hlid) fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); tx_pkts = wl->links[hlid].allocated_pkts; + single_sta = (wl->active_sta_count == 1); /* * if in FW PS and there is enough data in FW we can put the link * into high-level PS and clean out its TX queues. + * Make an exception if this is the only connected station. In this + * case FW-memory congestion is not a problem. */ - if (fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) + if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS) wl1271_ps_link_start(wl, hlid, true); } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index ba1fde9f9b28..b661c2c4f689 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -626,6 +626,9 @@ struct wl1271 { /* number of currently active RX BA sessions */ int ba_rx_session_count; + + /* AP-mode - number of currently connected stations */ + int active_sta_count; }; struct wl1271_station { From f4d3b6ab5e78fbdf3c27123cc29c44ff3d626c59 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 25 Aug 2011 12:43:16 +0300 Subject: [PATCH 121/287] wl12xx: AP mode - enable the BA constraint event from the FW Unblock the RX BA constraint event from firmware in AP mode as well. This allows us to stop RX BA sessions when the FW requests it. In addition refactor the handler for this event to make the flow clearer. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/event.c | 37 ++++++++++++++++++----------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 0bd7b020a420..c73fe4c6b616 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -171,19 +171,26 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl, wl->last_rssi_event = event; } -static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed) +static void wl1271_stop_ba_event(struct wl1271 *wl) { - /* Convert the value to bool */ - wl->ba_allowed = !!ba_allowed; - - /* - * Return in case: - * there are not BA open or the event indication is to allowed BA - */ - if ((!wl->ba_rx_bitmap) || (wl->ba_allowed)) - return; + if (wl->bss_type != BSS_TYPE_AP_BSS) { + if (!wl->ba_rx_bitmap) + return; + ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, + wl->bssid); + } else { + int i; + struct wl1271_link *lnk; + for (i = WL1271_AP_STA_HLID_START; i < WL12XX_MAX_LINKS; i++) { + lnk = &wl->links[i]; + if (!wl1271_is_active_sta(wl, i) || !lnk->ba_bitmap) + continue; - ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid); + ieee80211_stop_rx_ba_session(wl->vif, + lnk->ba_bitmap, + lnk->addr); + } + } } static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, @@ -283,12 +290,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_event_rssi_trigger(wl, mbox); } - if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) && !is_ap) { + if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID)) { wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. " "ba_allowed = 0x%x", mbox->rx_ba_allowed); - if (wl->vif) - wl1271_stop_ba_event(wl, mbox->rx_ba_allowed); + wl->ba_allowed = !!mbox->rx_ba_allowed; + + if (wl->vif && !wl->ba_allowed) + wl1271_stop_ba_event(wl); } if ((vector & DUMMY_PACKET_EVENT_ID)) { From f1acea9a9d48174f982e14a7a488b208d39d825f Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Thu, 25 Aug 2011 12:43:17 +0300 Subject: [PATCH 122/287] wl12xx: AP mode - clean BA and queue state in tx_reset Reset the BA state of all connected stations and explicitly clear the Tx queues. The latter is needed for clearing dummy packets from tx_queue_count. Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 7 +++++-- drivers/net/wireless/wl12xx/tx.c | 7 ++++++- drivers/net/wireless/wl12xx/tx.h | 3 +++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 1127a3ee36e3..45cd10ab3aac 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -3757,11 +3757,14 @@ static int wl1271_allocate_sta(struct wl1271 *wl, return 0; } -static void wl1271_free_sta(struct wl1271 *wl, u8 hlid) +void wl1271_free_sta(struct wl1271 *wl, u8 hlid) { int id = hlid - WL1271_AP_STA_HLID_START; - if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) + if (hlid < WL1271_AP_STA_HLID_START) + return; + + if (!test_bit(id, wl->ap_hlid_map)) return; clear_bit(id, wl->ap_hlid_map); diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 2bf31302b975..9d4157ce0950 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -891,6 +891,7 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) /* TX failure */ if (wl->bss_type == BSS_TYPE_AP_BSS) { for (i = 0; i < AP_MAX_LINKS; i++) { + wl1271_free_sta(wl, i); wl1271_tx_reset_link_queues(wl, i); wl->links[i].allocated_pkts = 0; wl->links[i].prev_freed_pkts = 0; @@ -910,10 +911,14 @@ void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues) ieee80211_tx_status_ni(wl->hw, skb); } } - wl->tx_queue_count[i] = 0; } + + wl->ba_rx_bitmap = 0; } + for (i = 0; i < NUM_TX_QUEUES; i++) + wl->tx_queue_count[i] = 0; + wl->stopped_queues_map = 0; /* diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 5c0fbbe5b42f..d6fdbf904a09 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -216,4 +216,7 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid); void wl1271_handle_tx_low_watermark(struct wl1271 *wl); bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); +/* from main.c */ +void wl1271_free_sta(struct wl1271 *wl, u8 hlid); + #endif From 93f8c8e02597b7d7997c4a0a10173ac90ad378e8 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 30 Aug 2011 09:34:01 +0300 Subject: [PATCH 123/287] wl12xx: set mac80211 flags for A-MPDU aggregation support We set the mac80211 flag for A-MPDU support and also indicate that Tx-agg session setup is performed in HW. This patch depends on "mac80211: add flag to indicate HW only Tx-agg setup support" Signed-off-by: Arik Nemtsov Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 45cd10ab3aac..ade62b3d9a2c 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -4506,7 +4506,9 @@ int wl1271_init_ieee80211(struct wl1271 *wl) IEEE80211_HW_SUPPORTS_CQM_RSSI | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_AP_LINK_PS; + IEEE80211_HW_AP_LINK_PS | + IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_TX_AMPDU_SETUP_IN_HW; wl->hw->wiphy->cipher_suites = cipher_suites; wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); From 045c745f8ccdb584ccc97f068c7c10c1090fbcf9 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 28 Aug 2011 15:23:01 +0300 Subject: [PATCH 124/287] wl12xx: support p2p interfaces Declare support for p2p interfaces, and create p2p_cli/p2p_go roles when being asked for. Indicate we are using a p2p interface by setting the wl->p2p flag. Signed-off-by: Eliad Peller Signed-off-by: Luciano Coelho --- drivers/net/wireless/wl12xx/main.c | 24 +++++++++++++++++++----- drivers/net/wireless/wl12xx/wl12xx.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index ade62b3d9a2c..680f5582618e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1825,10 +1825,16 @@ static u8 wl12xx_get_role_type(struct wl1271 *wl) { switch (wl->bss_type) { case BSS_TYPE_AP_BSS: - return WL1271_ROLE_AP; + if (wl->p2p) + return WL1271_ROLE_P2P_GO; + else + return WL1271_ROLE_AP; case BSS_TYPE_STA_BSS: - return WL1271_ROLE_STA; + if (wl->p2p) + return WL1271_ROLE_P2P_CL; + else + return WL1271_ROLE_STA; case BSS_TYPE_IBSS: return WL1271_ROLE_IBSS; @@ -1850,7 +1856,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, bool booted = false; wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", - vif->type, vif->addr); + ieee80211_vif_type_p2p(vif), vif->addr); mutex_lock(&wl->mutex); if (wl->vif) { @@ -1870,7 +1876,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, goto out; } - switch (vif->type) { + switch (ieee80211_vif_type_p2p(vif)) { + case NL80211_IFTYPE_P2P_CLIENT: + wl->p2p = 1; + /* fall-through */ case NL80211_IFTYPE_STATION: wl->bss_type = BSS_TYPE_STA_BSS; wl->set_bss_type = BSS_TYPE_STA_BSS; @@ -1879,6 +1888,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, wl->bss_type = BSS_TYPE_IBSS; wl->set_bss_type = BSS_TYPE_STA_BSS; break; + case NL80211_IFTYPE_P2P_GO: + wl->p2p = 1; + /* fall-through */ case NL80211_IFTYPE_AP: wl->bss_type = BSS_TYPE_AP_BSS; break; @@ -2074,6 +2086,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, wl->ssid_len = 0; wl->bss_type = MAX_BSS_TYPE; wl->set_bss_type = MAX_BSS_TYPE; + wl->p2p = 0; wl->band = IEEE80211_BAND_2GHZ; wl->rx_counter = 0; @@ -4514,7 +4527,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); + BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO); wl->hw->wiphy->max_scan_ssids = 1; wl->hw->wiphy->max_sched_scan_ssids = 16; wl->hw->wiphy->max_match_sets = 16; diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index b661c2c4f689..3ceb20c170bc 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -402,6 +402,7 @@ struct wl1271 { u8 mac_addr[ETH_ALEN]; u8 bss_type; u8 set_bss_type; + u8 p2p; /* we are using p2p role */ u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; u8 ssid_len; int channel; From eac03e381957a05f3842ceb8de987a1025966ecf Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Tue, 30 Aug 2011 23:38:53 +0200 Subject: [PATCH 125/287] cfg80211: hold reg_mutex when updating regulatory The function wiphy_update_regulatory() uses the static variable last_request and thus needs to be called with reg_mutex held. This is the case for all users in reg.c, but the function was exported for use by wiphy_register(), from where it is called without the lock being held. Fix this by making wiphy_update_regulatory() private and introducing regulatory_update() as a wrapper that acquires and holds the lock. Signed-off-by: Sven Neumann Cc: John W. Linville Cc: Luis R. Rodriguez Cc: Daniel Mack Cc: linux-wireless@vger.kernel.org Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/core.c | 2 +- net/wireless/core.h | 2 -- net/wireless/reg.c | 17 +++++++++++++++-- net/wireless/reg.h | 2 ++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 645437cfc464..44cbebac25e0 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -582,7 +582,7 @@ int wiphy_register(struct wiphy *wiphy) } /* set up regulatory info */ - wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); + regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); list_add_rcu(&rdev->list, &cfg80211_rdev_list); cfg80211_rdev_list_generation++; diff --git a/net/wireless/core.h b/net/wireless/core.h index 8672e028022f..796a4bdf8b0d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -279,8 +279,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, char *newname); void ieee80211_set_bitrate_flags(struct wiphy *wiphy); -void wiphy_update_regulatory(struct wiphy *wiphy, - enum nl80211_reg_initiator setby); void cfg80211_bss_expire(struct cfg80211_registered_device *dev); void cfg80211_bss_age(struct cfg80211_registered_device *dev, diff --git a/net/wireless/reg.c b/net/wireless/reg.c index a2b09c2df1bf..a1f069da79a4 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -101,6 +101,9 @@ struct reg_beacon { struct ieee80211_channel chan; }; +static void wiphy_update_regulatory(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator); + static void reg_todo(struct work_struct *work); static DECLARE_WORK(reg_work, reg_todo); @@ -1118,11 +1121,13 @@ static void reg_process_ht_flags(struct wiphy *wiphy) } -void wiphy_update_regulatory(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) +static void wiphy_update_regulatory(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { enum ieee80211_band band; + assert_reg_lock(); + if (ignore_reg_update(wiphy, initiator)) return; @@ -1137,6 +1142,14 @@ void wiphy_update_regulatory(struct wiphy *wiphy, wiphy->reg_notifier(wiphy, last_request); } +void regulatory_update(struct wiphy *wiphy, + enum nl80211_reg_initiator setby) +{ + mutex_lock(®_mutex); + wiphy_update_regulatory(wiphy, setby); + mutex_unlock(®_mutex); +} + static void handle_channel_custom(struct wiphy *wiphy, enum ieee80211_band band, unsigned int chan_idx, diff --git a/net/wireless/reg.h b/net/wireless/reg.h index b67d1c3a2fb9..4a56799d868d 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h @@ -16,6 +16,8 @@ void regulatory_exit(void); int set_regdom(const struct ieee80211_regdomain *rd); +void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby); + /** * regulatory_hint_found_beacon - hints a beacon was found on a channel * @wiphy: the wireless device where the beacon was found on From d7549cbb9ab0674ef44ea15bd9f9ea1c685adfa6 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Tue, 30 Aug 2011 23:38:54 +0200 Subject: [PATCH 126/287] cfg80211: reorder code to obsolete forward declaration Reorder functions to remove the need for a forward declaration introduced by the last commit. Signed-off-by: Sven Neumann Cc: John W. Linville Cc: Luis R. Rodriguez Cc: Daniel Mack Cc: linux-wireless@vger.kernel.org Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index a1f069da79a4..18fc37b6f2bd 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -101,9 +101,6 @@ struct reg_beacon { struct ieee80211_channel chan; }; -static void wiphy_update_regulatory(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator); - static void reg_todo(struct work_struct *work); static DECLARE_WORK(reg_work, reg_todo); @@ -914,14 +911,6 @@ static bool ignore_reg_update(struct wiphy *wiphy, return false; } -static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) -{ - struct cfg80211_registered_device *rdev; - - list_for_each_entry(rdev, &cfg80211_rdev_list, list) - wiphy_update_regulatory(&rdev->wiphy, initiator); -} - static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, struct reg_beacon *reg_beacon) @@ -1150,6 +1139,14 @@ void regulatory_update(struct wiphy *wiphy, mutex_unlock(®_mutex); } +static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) +{ + struct cfg80211_registered_device *rdev; + + list_for_each_entry(rdev, &cfg80211_rdev_list, list) + wiphy_update_regulatory(&rdev->wiphy, initiator); +} + static void handle_channel_custom(struct wiphy *wiphy, enum ieee80211_band band, unsigned int chan_idx, From 8c771244fbab51661da7dbbabfa5dceffb3e3cce Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 20 Aug 2011 15:53:55 +0200 Subject: [PATCH 127/287] mac80211: make ieee80211_send_bar available for drivers To properly maintain the peer's block ack window, the driver needs to be able to control the new starting sequence number that is sent along with the BlockAckReq frame. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- include/net/mac80211.h | 13 +++++++++++++ net/mac80211/agg-tx.c | 4 +++- net/mac80211/ieee80211_i.h | 1 - net/mac80211/status.c | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 5e5029b22ac7..fc4806c6097f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -3225,6 +3225,19 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw); void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap, const u8 *addr); +/** + * ieee80211_send_bar - send a BlockAckReq frame + * + * can be used to flush pending frames from the peer's aggregation reorder + * buffer. + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @ra: the peer's destination address + * @tid: the TID of the aggregation session + * @ssn: the new starting sequence number for the receiver + */ +void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn); + /* Rate control API */ /** diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 250b9a53f6d9..3cef5a7281cb 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -104,8 +104,9 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, ieee80211_tx_skb(sdata, skb); } -void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn) +void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn) { + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; struct sk_buff *skb; struct ieee80211_bar *bar; @@ -131,6 +132,7 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; ieee80211_tx_skb(sdata, skb); } +EXPORT_SYMBOL(ieee80211_send_bar); void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, struct tid_ampdu_tx *tid_tx) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c204cee1189c..a37da74de023 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1186,7 +1186,6 @@ struct ieee80211_tx_status_rtap_hdr { void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, struct ieee80211_ht_cap *ht_cap_ie, struct ieee80211_sta_ht_cap *ht_cap); -void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid, u16 initiator, u16 reason_code); diff --git a/net/mac80211/status.c b/net/mac80211/status.c index ba405bc4f812..14268465f1d8 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -136,7 +136,7 @@ static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid) return; tid_tx->bar_pending = false; - ieee80211_send_bar(sta->sdata, addr, tid, tid_tx->failed_bar_ssn); + ieee80211_send_bar(&sta->sdata->vif, addr, tid, tid_tx->failed_bar_ssn); } static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) @@ -273,7 +273,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) tid = qc[0] & 0xf; ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) & IEEE80211_SCTL_SEQ); - ieee80211_send_bar(sta->sdata, hdr->addr1, + ieee80211_send_bar(&sta->sdata->vif, hdr->addr1, tid, ssn); } From 2157fdd6ae3f760a95c5c50072a1b4ac656eb9f5 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Thu, 1 Sep 2011 12:32:14 -0700 Subject: [PATCH 128/287] mac80211: check if mesh frame is in RMC after decrypt To check whether a frame is in the RMC, we need access to the mesh header. This header is encrypted in encrypted data frames, so make this check after the frame has been decrypted. Signed-off-by: Thomas Pedersen Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/rx.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index f45fd2fedc24..d479d48e8d18 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -476,7 +476,6 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; - unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); char *dev_addr = rx->sdata->vif.addr; if (ieee80211_is_data(hdr->frame_control)) { @@ -524,14 +523,6 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) } -#define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) - - if (ieee80211_is_data(hdr->frame_control) && - is_multicast_ether_addr(hdr->addr1) && - mesh_rmc_check(hdr->addr3, msh_h_get(hdr, hdrlen), rx->sdata)) - return RX_DROP_MONITOR; -#undef msh_h_get - return RX_CONTINUE; } @@ -1840,6 +1831,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) hdrlen = ieee80211_hdrlen(hdr->frame_control); mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); + /* frame is in RMC, don't forward */ + if (ieee80211_is_data(hdr->frame_control) && + is_multicast_ether_addr(hdr->addr1) && + mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) + return RX_DROP_MONITOR; + if (!ieee80211_is_data(hdr->frame_control)) return RX_CONTINUE; From cfee66b0f9891fc2b79a238e737308a2732365d2 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 6 Sep 2011 13:05:21 -0700 Subject: [PATCH 129/287] mac80211: Stop forwarding mesh traffic when tx queues are full Tx flow control for non-mesh modes of operation only needs to act on the net device queues: when the hardware queues are full we stop accepting traffic from the net device. In mesh, however, we also need to stop forwarding traffic. This patch checks the hardware queues before attempting to forward a mesh frame. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/debugfs_netdev.c | 3 +++ net/mac80211/ieee80211_i.h | 1 + net/mac80211/rx.c | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 6e8eab7919e2..dd0462917518 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -340,6 +340,8 @@ IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC); IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); +IEEE80211_IF_FILE(dropped_frames_congestion, + u.mesh.mshstats.dropped_frames_congestion, DEC); IEEE80211_IF_FILE(dropped_frames_no_route, u.mesh.mshstats.dropped_frames_no_route, DEC); IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); @@ -463,6 +465,7 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) MESHSTATS_ADD(fwded_frames); MESHSTATS_ADD(dropped_frames_ttl); MESHSTATS_ADD(dropped_frames_no_route); + MESHSTATS_ADD(dropped_frames_congestion); MESHSTATS_ADD(estab_plinks); #undef MESHSTATS_ADD } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a37da74de023..5e636bc3551f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -261,6 +261,7 @@ struct mesh_stats { __u32 fwded_frames; /* Mesh total forwarded frames */ __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ __u32 dropped_frames_no_route; /* Not transmitted, no route found */ + __u32 dropped_frames_congestion;/* Not forwarded due to congestion */ atomic_t estab_plinks; }; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d479d48e8d18..811e3ade8c74 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1844,6 +1844,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) /* illegal frame */ return RX_DROP_MONITOR; + if (ieee80211_queue_stopped(&local->hw, skb_get_queue_mapping(skb))) { + IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, + dropped_frames_congestion); + return RX_DROP_MONITOR; + } + if (mesh_hdr->flags & MESH_FLAGS_AE) { struct mesh_path *mppath; char *proxied_addr; From c9c0d9ecdceebe51d1c4e2231f0e691556ec348f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 1 Sep 2011 22:49:57 +0200 Subject: [PATCH 130/287] b43: N-PHY: implement enabling TX power control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 84 +++++++++++++++++++++++++++++--- drivers/net/wireless/b43/phy_n.h | 2 + 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 2eadadf5f4fc..6e9168079b9e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -248,15 +248,25 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) { struct b43_phy_n *nphy = dev->phy.n; u8 i; - u16 tmp; + u16 bmask, val, tmp; + enum ieee80211_band band = b43_current_band(dev->wl); if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 1); nphy->txpwrctrl = enable; if (!enable) { - if (dev->phy.rev >= 3) - ; /* TODO */ + if (dev->phy.rev >= 3 && + (b43_phy_read(dev, B43_NPHY_TXPCTL_CMD) & + (B43_NPHY_TXPCTL_CMD_COEFF | + B43_NPHY_TXPCTL_CMD_HWPCTLEN | + B43_NPHY_TXPCTL_CMD_PCTLEN))) { + /* We disable enabled TX pwr ctl, save it's state */ + nphy->tx_pwr_idx[0] = b43_phy_read(dev, + B43_NPHY_C1_TXPCTL_STAT) & 0x7f; + nphy->tx_pwr_idx[1] = b43_phy_read(dev, + B43_NPHY_C2_TXPCTL_STAT) & 0x7f; + } b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840); for (i = 0; i < 84; i++) @@ -285,10 +295,68 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A); - if (dev->phy.rev < 2 && 0) - ; /* TODO */ + if (dev->phy.rev < 2 && dev->phy.is_40mhz) + b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW); } else { - b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n"); + b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, + nphy->adj_pwr_tbl); + b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, + nphy->adj_pwr_tbl); + + bmask = B43_NPHY_TXPCTL_CMD_COEFF | + B43_NPHY_TXPCTL_CMD_HWPCTLEN; + /* wl does useless check for "enable" param here */ + val = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN; + if (dev->phy.rev >= 3) { + bmask |= B43_NPHY_TXPCTL_CMD_PCTLEN; + if (val) + val |= B43_NPHY_TXPCTL_CMD_PCTLEN; + } + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val); + + if (band == IEEE80211_BAND_5GHZ) { + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, 0x64); + if (dev->phy.rev > 1) + b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT, + ~B43_NPHY_TXPCTL_INIT_PIDXI1, + 0x64); + } + + if (dev->phy.rev >= 3) { + if (nphy->tx_pwr_idx[0] != 128 && + nphy->tx_pwr_idx[1] != 128) { + /* Recover TX pwr ctl state */ + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, + nphy->tx_pwr_idx[0]); + if (dev->phy.rev > 1) + b43_phy_maskset(dev, + B43_NPHY_TXPCTL_INIT, + ~0xff, nphy->tx_pwr_idx[1]); + } + } + + if (dev->phy.rev >= 3) { + b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100); + b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100); + } else { + b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x4000); + } + + if (dev->phy.rev == 2) + b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x3b); + else if (dev->phy.rev < 2) + b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40); + + if (dev->phy.rev < 2 && dev->phy.is_40mhz) + b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW); + + if ((nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) || + (nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ)) { + b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x4); + b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x4); + } } if (nphy->hang_avoid) @@ -3918,6 +3986,10 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev) nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */ nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */ nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */ + /* 128 can mean disabled-by-default state of TX pwr ctl. Max value is + * 0x7f == 127 and we check for 128 when restoring TX pwr ctl. */ + nphy->tx_pwr_idx[0] = 128; + nphy->tx_pwr_idx[1] = 128; } static void b43_nphy_op_free(struct b43_wldev *dev) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index e789a89f1047..cd8498904b90 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -783,6 +783,8 @@ struct b43_phy_n { u16 mphase_txcal_bestcoeffs[11]; bool txpwrctrl; + u8 tx_pwr_idx[2]; + u16 adj_pwr_tbl[84]; u16 txcal_bbmult; u16 txiqlocal_bestc[11]; bool txiqlocal_coeffsvalid; From 693828fe92933ce4fff4c1e51365b2e6ab033b0e Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 2 Sep 2011 13:51:59 +0530 Subject: [PATCH 131/287] mac80211: stop tx before doing hw config and rate update The assumption is that during the hw config, transmission was already stopped by mac80211. Sometimes the AP can be switching b/w the ht modes due to intolerant or etc where STA is in the middle of transmission. In such scenario, buffer overflow was observed at driver side. And also before updating the rate control, the frames are continued to xmited with older rates. This patch ensures that the frames are always xmitted with updated rates and avoid buffer overflow. Signed-off-by: Rajkumar Manoharan Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 1 + net/mac80211/mlme.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 5e636bc3551f..21186e280ceb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -671,6 +671,7 @@ enum queue_stop_reason { IEEE80211_QUEUE_STOP_REASON_AGGREGATION, IEEE80211_QUEUE_STOP_REASON_SUSPEND, IEEE80211_QUEUE_STOP_REASON_SKB_ADD, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE, }; #ifdef CONFIG_MAC80211_LEDS diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fb2f0f986de7..ca97b80b2651 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1918,8 +1918,24 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); + /* + * Whenever the AP announces the HT mode change that can be + * 40MHz intolerant or etc., it would be safer to stop tx + * queues before doing hw config to avoid buffer overflow. + */ + ieee80211_stop_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); + + /* flush out all packets */ + synchronize_net(); + + drv_flush(local, false); + changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, bssid, ap_ht_cap_flags); + + ieee80211_wake_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); } /* Note: country IE parsing is done for us by cfg80211 */ From 82b2d334314c387ebd857b88a3d889c9a2cfec4a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Sep 2011 01:40:23 +0200 Subject: [PATCH 132/287] ath9k: eliminate common->{rx,tx}_chainmask we already have ah->{rx,tx}chainmask for the same purpose Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 3 --- drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 4 ++-- drivers/net/wireless/ath/ath9k/beacon.c | 2 +- drivers/net/wireless/ath/ath9k/debug.c | 20 +++++++++---------- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 7 ++----- drivers/net/wireless/ath/ath9k/htc_drv_main.c | 3 +-- drivers/net/wireless/ath/ath9k/hw.c | 5 ++--- drivers/net/wireless/ath/ath9k/init.c | 9 ++------- drivers/net/wireless/ath/ath9k/main.c | 7 +++---- drivers/net/wireless/ath/ath9k/xmit.c | 8 ++++---- 10 files changed, 27 insertions(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 9891fb605a01..4ed7f248a577 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -140,9 +140,6 @@ struct ath_common { u8 curbssid[ETH_ALEN]; u8 bssidmask[ETH_ALEN]; - u8 tx_chainmask; - u8 rx_chainmask; - u32 rx_bufsize; u32 keymax; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index f80d1d633980..bb2214f425b2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -113,7 +113,7 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah) if (delta > scale) return -1; - switch (get_streams(common->tx_chainmask)) { + switch (get_streams(ah->txchainmask)) { case 1: delta = 6; break; @@ -126,7 +126,7 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah) default: delta = 0; ath_dbg(common, ATH_DBG_CALIBRATE, - "Invalid tx-chainmask: %u\n", common->tx_chainmask); + "Invalid tx-chainmask: %u\n", ah->txchainmask); } power += delta; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 086c9c816bf7..0c757c9f978a 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -107,7 +107,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, series[0].Tries = 1; series[0].Rate = rate; series[0].ChSel = ath_txchainmask_reduction(sc, - common->tx_chainmask, series[0].Rate); + ah->txchainmask, series[0].Rate); series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, series, 4, 0); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 727e8de22fda..19ef559ac78f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -95,11 +95,11 @@ static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; char buf[32]; unsigned int len; - len = sprintf(buf, "0x%08x\n", common->tx_chainmask); + len = sprintf(buf, "0x%08x\n", ah->txchainmask); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -107,7 +107,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; unsigned long mask; char buf[32]; ssize_t len; @@ -120,8 +120,8 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use if (strict_strtoul(buf, 0, &mask)) return -EINVAL; - common->tx_chainmask = mask; - sc->sc_ah->caps.tx_chainmask = mask; + ah->txchainmask = mask; + ah->caps.tx_chainmask = mask; return count; } @@ -138,11 +138,11 @@ static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; char buf[32]; unsigned int len; - len = sprintf(buf, "0x%08x\n", common->rx_chainmask); + len = sprintf(buf, "0x%08x\n", ah->rxchainmask); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -150,7 +150,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; unsigned long mask; char buf[32]; ssize_t len; @@ -163,8 +163,8 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use if (strict_strtoul(buf, 0, &mask)) return -EINVAL; - common->rx_chainmask = mask; - sc->sc_ah->caps.rx_chainmask = mask; + ah->rxchainmask = mask; + ah->caps.rx_chainmask = mask; return count; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 9cf42f6973aa..966661c9e586 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -509,8 +509,8 @@ static void setup_ht_cap(struct ath9k_htc_priv *priv, memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); /* ath9k_htc supports only 1 or 2 stream devices */ - tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2); - rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2); + tx_streams = ath9k_cmn_count_streams(priv->ah->txchainmask, 2); + rx_streams = ath9k_cmn_count_streams(priv->ah->rxchainmask, 2); ath_dbg(common, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n", @@ -601,9 +601,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) { struct ath_common *common = ath9k_hw_common(priv->ah); - common->tx_chainmask = priv->ah->caps.tx_chainmask; - common->rx_chainmask = priv->ah->caps.rx_chainmask; - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); priv->ah->opmode = NL80211_IFTYPE_STATION; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index b9de1511add9..495fdf680a6c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -826,8 +826,7 @@ void ath9k_htc_ani_work(struct work_struct *work) if (longcal || shortcal) common->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan, - common->rx_chainmask, - longcal); + ah->rxchainmask, longcal); ath9k_htc_ps_restore(priv); } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 47d10a4463f1..f2065fce4ec9 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1479,9 +1479,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, u64 tsf = 0; int i, r; - ah->txchainmask = common->tx_chainmask; - ah->rxchainmask = common->rx_chainmask; - if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) return -EIO; @@ -2095,6 +2092,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->tx_chainmask = fixup_chainmask(chip_chainmask, pCap->tx_chainmask); pCap->rx_chainmask = fixup_chainmask(chip_chainmask, pCap->rx_chainmask); + ah->txchainmask = pCap->tx_chainmask; + ah->rxchainmask = pCap->rx_chainmask; ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index dd71a5f77516..50da6421728b 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -270,8 +270,8 @@ static void setup_ht_cap(struct ath_softc *sc, /* set up supported mcs set */ memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); - tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams); - rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams); + tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams); + rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams); ath_dbg(common, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n", @@ -506,9 +506,6 @@ static void ath9k_init_misc(struct ath_softc *sc) sc->sc_flags |= SC_OP_RXAGGR; } - common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; - common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; - ath9k_hw_set_diversity(sc->sc_ah, true); sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); @@ -646,10 +643,8 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) static void ath9k_init_txpower_limits(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath9k_channel *curchan = ah->curchan; - ah->txchainmask = common->tx_chainmask; if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7b7864dfab75..e944eadd677d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -318,7 +318,6 @@ static void ath_paprd_activate(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; struct ath9k_hw_cal_data *caldata = ah->caldata; - struct ath_common *common = ath9k_hw_common(ah); int chain; if (!caldata || !caldata->paprd_done) @@ -327,7 +326,7 @@ static void ath_paprd_activate(struct ath_softc *sc) ath9k_ps_wakeup(sc); ar9003_paprd_enable(ah, false); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(common->tx_chainmask & BIT(chain))) + if (!(ah->txchainmask & BIT(chain))) continue; ar9003_paprd_populate_single_table(ah, caldata, chain); @@ -414,7 +413,7 @@ void ath_paprd_calibrate(struct work_struct *work) memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(common->tx_chainmask & BIT(chain))) + if (!(ah->txchainmask & BIT(chain))) continue; chain_ok = 0; @@ -535,7 +534,7 @@ void ath_ani_calibrate(unsigned long data) if (longcal || shortcal) { common->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan, - common->rx_chainmask, longcal); + ah->rxchainmask, longcal); } ath9k_ps_restore(sc); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 29bcc55a6f9e..0fb8fb57b5c8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1634,7 +1634,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) { - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; struct ath9k_11n_rate_series series[4]; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; @@ -1694,7 +1694,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) /* MCS rates */ series[i].Rate = rix | 0x80; series[i].ChSel = ath_txchainmask_reduction(sc, - common->tx_chainmask, series[i].Rate); + ah->txchainmask, series[i].Rate); series[i].PktDuration = ath_pkt_duration(sc, rix, len, is_40, is_sgi, is_sp); if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) @@ -1719,10 +1719,10 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) } if (bf->bf_state.bfs_paprd) - series[i].ChSel = common->tx_chainmask; + series[i].ChSel = ah->txchainmask; else series[i].ChSel = ath_txchainmask_reduction(sc, - common->tx_chainmask, series[i].Rate); + ah->txchainmask, series[i].Rate); series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, phy, rate->bitrate * 100, len, rix, is_sp); From e8cfe9f8c488f5b345ab557148c7af57af4fbe25 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Sep 2011 01:40:24 +0200 Subject: [PATCH 133/287] ath9k: move a few functions around Helps with making ath_reset static in the next commit Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 137 +++++++++++++------------- 1 file changed, 69 insertions(+), 68 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e944eadd677d..9ff73e007d34 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -596,74 +596,6 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) ath_tx_node_cleanup(sc, an); } -void ath_hw_check(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - unsigned long flags; - int busy; - - ath9k_ps_wakeup(sc); - if (ath9k_hw_check_alive(sc->sc_ah)) - goto out; - - spin_lock_irqsave(&common->cc_lock, flags); - busy = ath_update_survey_stats(sc); - spin_unlock_irqrestore(&common->cc_lock, flags); - - ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " - "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); - if (busy >= 99) { - if (++sc->hw_busy_count >= 3) { - spin_lock_bh(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock_bh(&sc->sc_pcu_lock); - } - } else if (busy >= 0) - sc->hw_busy_count = 0; - -out: - ath9k_ps_restore(sc); -} - -static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) -{ - static int count; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - - if (pll_sqsum >= 0x40000) { - count++; - if (count == 3) { - /* Rx is hung for more than 500ms. Reset it */ - ath_dbg(common, ATH_DBG_RESET, - "Possible RX hang, resetting"); - spin_lock_bh(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock_bh(&sc->sc_pcu_lock); - count = 0; - } - } else - count = 0; -} - -void ath_hw_pll_work(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, - hw_pll_work.work); - u32 pll_sqsum; - - if (AR_SREV_9485(sc->sc_ah)) { - - ath9k_ps_wakeup(sc); - pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); - ath9k_ps_restore(sc); - - ath_hw_pll_rx_hang_check(sc, pll_sqsum); - - ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); - } -} - void ath9k_tasklet(unsigned long data) { @@ -1037,6 +969,75 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) return r; } +void ath_hw_check(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + unsigned long flags; + int busy; + + ath9k_ps_wakeup(sc); + if (ath9k_hw_check_alive(sc->sc_ah)) + goto out; + + spin_lock_irqsave(&common->cc_lock, flags); + busy = ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + + ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " + "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); + if (busy >= 99) { + if (++sc->hw_busy_count >= 3) { + spin_lock_bh(&sc->sc_pcu_lock); + ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); + } + + } else if (busy >= 0) + sc->hw_busy_count = 0; + +out: + ath9k_ps_restore(sc); +} + +static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) +{ + static int count; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + + if (pll_sqsum >= 0x40000) { + count++; + if (count == 3) { + /* Rx is hung for more than 500ms. Reset it */ + ath_dbg(common, ATH_DBG_RESET, + "Possible RX hang, resetting"); + spin_lock_bh(&sc->sc_pcu_lock); + ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); + count = 0; + } + } else + count = 0; +} + +void ath_hw_pll_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, + hw_pll_work.work); + u32 pll_sqsum; + + if (AR_SREV_9485(sc->sc_ah)) { + + ath9k_ps_wakeup(sc); + pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); + ath9k_ps_restore(sc); + + ath_hw_pll_rx_hang_check(sc, pll_sqsum); + + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); + } +} + /**********************/ /* mac80211 callbacks */ /**********************/ From 236de5149b9cbec3e76aef00a4663a8de7feeebe Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Sep 2011 01:40:25 +0200 Subject: [PATCH 134/287] ath9k: always call ath_reset from workqueue context This makes it much easier to add further rework to avoid race conditions between reset and other work items. Move other functions to make ath_reset static. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- drivers/net/wireless/ath/ath9k/beacon.c | 4 +--- drivers/net/wireless/ath/ath9k/init.c | 1 + drivers/net/wireless/ath/ath9k/main.c | 17 +++++++++++++---- drivers/net/wireless/ath/ath9k/xmit.c | 14 +++++++++----- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 5d9a9aabe476..b2992d4097c3 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -425,6 +425,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); #define ATH_PAPRD_TIMEOUT 100 /* msecs */ +void ath_reset_work(struct work_struct *work); void ath_hw_check(struct work_struct *work); void ath_hw_pll_work(struct work_struct *work); void ath_paprd_calibrate(struct work_struct *work); @@ -604,6 +605,7 @@ struct ath_softc { struct mutex mutex; struct work_struct paprd_work; struct work_struct hw_check_work; + struct work_struct hw_reset_work; struct completion paprd_complete; unsigned int hw_busy_count; @@ -650,7 +652,6 @@ struct ath_softc { }; void ath9k_tasklet(unsigned long data); -int ath_reset(struct ath_softc *sc, bool retry_tx); int ath_cabq_update(struct ath_softc *); static inline void ath_read_cachesize(struct ath_common *common, int *csz) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 0c757c9f978a..22e8e2580116 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -386,9 +386,7 @@ void ath_beacon_tasklet(unsigned long data) ath_dbg(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); sc->sc_flags |= SC_OP_TSF_RESET; - spin_lock(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock(&sc->sc_pcu_lock); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); } return; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 50da6421728b..be302fbdc3dc 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -777,6 +777,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, goto error_world; } + INIT_WORK(&sc->hw_reset_work, ath_reset_work); INIT_WORK(&sc->hw_check_work, ath_hw_check); INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9ff73e007d34..9a6db2964b18 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -236,6 +236,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, del_timer_sync(&common->ani.timer); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); + cancel_work_sync(&sc->hw_reset_work); cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); @@ -608,9 +609,7 @@ void ath9k_tasklet(unsigned long data) if ((status & ATH9K_INT_FATAL) || (status & ATH9K_INT_BB_WATCHDOG)) { - spin_lock(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock(&sc->sc_pcu_lock); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); return; } @@ -901,7 +900,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_ps_restore(sc); } -int ath_reset(struct ath_softc *sc, bool retry_tx) +static int ath_reset(struct ath_softc *sc, bool retry_tx) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -969,6 +968,15 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) return r; } +void ath_reset_work(struct work_struct *work) +{ + struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); + + spin_lock_bh(&sc->sc_pcu_lock); + ath_reset(sc, true); + spin_unlock_bh(&sc->sc_pcu_lock); +} + void ath_hw_check(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); @@ -1230,6 +1238,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&sc->hw_pll_work); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); + cancel_work_sync(&sc->hw_reset_work); if (sc->sc_flags & SC_OP_INVALID) { ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0fb8fb57b5c8..cb37047e71d2 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -582,7 +582,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, rcu_read_unlock(); if (needreset) - ath_reset(sc, false); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); } static bool ath_lookup_legacy(struct ath_buf *bf) @@ -1333,7 +1333,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) struct ath_atx_ac *ac, *ac_tmp, *last_ac; struct ath_atx_tid *tid, *last_tid; - if (list_empty(&txq->axq_acq) || + if (work_pending(&sc->hw_reset_work) || list_empty(&txq->axq_acq) || txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) return; @@ -2148,6 +2148,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&txq->axq_lock); for (;;) { + if (work_pending(&sc->hw_reset_work)) + break; + if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; if (sc->sc_flags & SC_OP_TXAGGR) @@ -2235,9 +2238,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work) if (needreset) { ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, "tx hung, resetting the chip\n"); - spin_lock_bh(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock_bh(&sc->sc_pcu_lock); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); } ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, @@ -2270,6 +2271,9 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) int status; for (;;) { + if (work_pending(&sc->hw_reset_work)) + break; + status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts); if (status == -EINPROGRESS) break; From 9adcf440dcc886a950a6049f928ab679912d99f4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Sep 2011 01:40:26 +0200 Subject: [PATCH 135/287] ath9k: merge reset related functions reduces unnecessary code duplication. Also takes the sc_pcu_lock within ath_reset instead of callsites, which makes it possible to always cancel all queued work items before the reset, possibly fixing a few race conditions (work items vs reset) along with it. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 303 +++++++++++--------------- 1 file changed, 127 insertions(+), 176 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9a6db2964b18..19c78be3dc41 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -212,84 +212,58 @@ static int ath_update_survey_stats(struct ath_softc *sc) return ret; } -/* - * Set/change channels. If the channel is really being changed, it's done - * by reseting the chip. To accomplish this we must first cleanup any pending - * DMA, then restart stuff. -*/ -static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, - struct ath9k_channel *hchan) +static void __ath_cancel_work(struct ath_softc *sc) { - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_conf *conf = &common->hw->conf; - bool fastcc = true, stopped; - struct ieee80211_channel *channel = hw->conf.channel; - struct ath9k_hw_cal_data *caldata = NULL; - int r; - - if (sc->sc_flags & SC_OP_INVALID) - return -EIO; - - sc->hw_busy_count = 0; - - del_timer_sync(&common->ani.timer); cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->hw_check_work); - cancel_work_sync(&sc->hw_reset_work); cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); +} - ath9k_ps_wakeup(sc); +static void ath_cancel_work(struct ath_softc *sc) +{ + __ath_cancel_work(sc); + cancel_work_sync(&sc->hw_reset_work); +} - spin_lock_bh(&sc->sc_pcu_lock); +static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + bool ret; - /* - * This is only performed if the channel settings have - * actually changed. - * - * To switch channels clear any pending DMA operations; - * wait long enough for the RX fifo to drain, reset the - * hardware at the new frequency, and then re-enable - * the relevant bits of the h/w. - */ - ath9k_hw_disable_interrupts(ah); - stopped = ath_drain_all_txq(sc, false); + ieee80211_stop_queues(sc->hw); - if (!ath_stoprecv(sc)) - stopped = false; + sc->hw_busy_count = 0; + del_timer_sync(&common->ani.timer); - if (!ath9k_hw_check_alive(ah)) - stopped = false; + ath9k_debug_samp_bb_mac(sc); + ath9k_hw_disable_interrupts(ah); - /* XXX: do not flush receive queue here. We don't want - * to flush data frames already in queue because of - * changing channel. */ + ret = ath_drain_all_txq(sc, retry_tx); - if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL)) - fastcc = false; + if (!ath_stoprecv(sc)) + ret = false; - if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) - caldata = &sc->caldata; + if (!flush) { + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + ath_rx_tasklet(sc, 0, true); + ath_rx_tasklet(sc, 0, false); + } else { + ath_flushrecv(sc); + } - ath_dbg(common, ATH_DBG_CONFIG, - "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", - sc->sc_ah->curchan->channel, - channel->center_freq, conf_is_ht40(conf), - fastcc); + return ret; +} - r = ath9k_hw_reset(ah, hchan, caldata, fastcc); - if (r) { - ath_err(common, - "Unable to reset channel (%u MHz), reset status %d\n", - channel->center_freq, r); - goto ps_restore; - } +static bool ath_complete_reset(struct ath_softc *sc, bool start) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); if (ath_startrecv(sc) != 0) { ath_err(common, "Unable to restart recv logic\n"); - r = -EIO; - goto ps_restore; + return false; } ath9k_cmn_update_txpow(ah, sc->curtxpow, @@ -297,21 +271,93 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath9k_hw_set_interrupts(ah, ah->imask); ath9k_hw_enable_interrupts(ah); - if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { + if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) { if (sc->sc_flags & SC_OP_BEACONS) ath_set_beacon(sc); + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); if (!common->disable_ani) ath_start_ani(common); } - ps_restore: - ieee80211_wake_queues(hw); + ieee80211_wake_queues(sc->hw); + + return true; +} + +static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, + bool retry_tx) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_cal_data *caldata = NULL; + bool fastcc = true; + bool flush = false; + int r; + + __ath_cancel_work(sc); + + spin_lock_bh(&sc->sc_pcu_lock); + if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) { + fastcc = false; + caldata = &sc->caldata; + } + + if (!hchan) { + fastcc = false; + flush = true; + hchan = ah->curchan; + } + + if (fastcc && !ath9k_hw_check_alive(ah)) + fastcc = false; + + if (!ath_prepare_reset(sc, retry_tx, flush)) + fastcc = false; + + ath_dbg(common, ATH_DBG_CONFIG, + "Reset to %u MHz, HT40: %d fastcc: %d\n", + hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | + CHANNEL_HT40PLUS)), + fastcc); + + r = ath9k_hw_reset(ah, hchan, caldata, fastcc); + if (r) { + ath_err(common, + "Unable to reset channel, reset status %d\n", r); + goto out; + } + + if (!ath_complete_reset(sc, true)) + r = -EIO; + +out: spin_unlock_bh(&sc->sc_pcu_lock); + return r; +} + + +/* + * Set/change channels. If the channel is really being changed, it's done + * by reseting the chip. To accomplish this we must first cleanup any pending + * DMA, then restart stuff. +*/ +static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, + struct ath9k_channel *hchan) +{ + int r; + + if (sc->sc_flags & SC_OP_INVALID) + return -EIO; + + ath9k_ps_wakeup(sc); + + r = ath_reset_internal(sc, hchan, false); ath9k_ps_restore(sc); + return r; } @@ -825,28 +871,13 @@ static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) channel->center_freq, r); } - ath9k_cmn_update_txpow(ah, sc->curtxpow, - sc->config.txpowlimit, &sc->curtxpow); - if (ath_startrecv(sc) != 0) { - ath_err(common, "Unable to restart recv logic\n"); - goto out; - } - if (sc->sc_flags & SC_OP_BEACONS) - ath_set_beacon(sc); /* restart beacons */ - - /* Re-Enable interrupts */ - ath9k_hw_set_interrupts(ah, ah->imask); - ath9k_hw_enable_interrupts(ah); + ath_complete_reset(sc, true); /* Enable LED */ ath9k_hw_cfg_output(ah, ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(ah, ah->led_pin, 0); - ieee80211_wake_queues(hw); - ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2); - -out: spin_unlock_bh(&sc->sc_pcu_lock); ath9k_ps_restore(sc); @@ -859,11 +890,10 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) int r; ath9k_ps_wakeup(sc); - cancel_delayed_work_sync(&sc->hw_pll_work); - spin_lock_bh(&sc->sc_pcu_lock); + ath_cancel_work(sc); - ieee80211_stop_queues(hw); + spin_lock_bh(&sc->sc_pcu_lock); /* * Keep the LED on when the radio is disabled @@ -874,13 +904,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ath9k_hw_cfg_gpio_input(ah, ah->led_pin); } - /* Disable interrupts */ - ath9k_hw_disable_interrupts(ah); - - ath_drain_all_txq(sc, false); /* clear pending tx frames */ - - ath_stoprecv(sc); /* turn off frame recv */ - ath_flushrecv(sc); /* flush recv queue */ + ath_prepare_reset(sc, false, true); if (!ah->curchan) ah->curchan = ath9k_cmn_get_curchannel(hw, ah); @@ -902,49 +926,11 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) static int ath_reset(struct ath_softc *sc, bool retry_tx) { - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_hw *hw = sc->hw; int r; - sc->hw_busy_count = 0; - - ath9k_debug_samp_bb_mac(sc); - /* Stop ANI */ - - del_timer_sync(&common->ani.timer); - ath9k_ps_wakeup(sc); - ieee80211_stop_queues(hw); - - ath9k_hw_disable_interrupts(ah); - ath_drain_all_txq(sc, retry_tx); - - ath_stoprecv(sc); - ath_flushrecv(sc); - - r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); - if (r) - ath_err(common, - "Unable to reset hardware; reset status %d\n", r); - - if (ath_startrecv(sc) != 0) - ath_err(common, "Unable to start recv logic\n"); - - /* - * We may be doing a reset in response to a request - * that changes the channel so update any state that - * might change as a result. - */ - ath9k_cmn_update_txpow(ah, sc->curtxpow, - sc->config.txpowlimit, &sc->curtxpow); - - if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) - ath_set_beacon(sc); /* restart beacons */ - - ath9k_hw_set_interrupts(ah, ah->imask); - ath9k_hw_enable_interrupts(ah); + r = ath_reset_internal(sc, NULL, retry_tx); if (retry_tx) { int i; @@ -957,12 +943,6 @@ static int ath_reset(struct ath_softc *sc, bool retry_tx) } } - ieee80211_wake_queues(hw); - - /* Start ANI */ - if (!common->disable_ani) - ath_start_ani(common); - ath9k_ps_restore(sc); return r; @@ -972,9 +952,7 @@ void ath_reset_work(struct work_struct *work) { struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); - spin_lock_bh(&sc->sc_pcu_lock); ath_reset(sc, true); - spin_unlock_bh(&sc->sc_pcu_lock); } void ath_hw_check(struct work_struct *work) @@ -995,11 +973,8 @@ void ath_hw_check(struct work_struct *work) ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); if (busy >= 99) { - if (++sc->hw_busy_count >= 3) { - spin_lock_bh(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock_bh(&sc->sc_pcu_lock); - } + if (++sc->hw_busy_count >= 3) + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); } else if (busy >= 0) sc->hw_busy_count = 0; @@ -1019,9 +994,7 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) /* Rx is hung for more than 500ms. Reset it */ ath_dbg(common, ATH_DBG_RESET, "Possible RX hang, resetting"); - spin_lock_bh(&sc->sc_pcu_lock); - ath_reset(sc, true); - spin_unlock_bh(&sc->sc_pcu_lock); + ieee80211_queue_work(sc->hw, &sc->hw_reset_work); count = 0; } } else @@ -1092,28 +1065,6 @@ static int ath9k_start(struct ieee80211_hw *hw) goto mutex_unlock; } - /* - * This is needed only to setup initial state - * but it's best done after a reset. - */ - ath9k_cmn_update_txpow(ah, sc->curtxpow, - sc->config.txpowlimit, &sc->curtxpow); - - /* - * Setup the hardware after reset: - * The receive engine is set going. - * Frame transmit is handled entirely - * in the frame output path; there's nothing to do - * here except setup the interrupt mask. - */ - if (ath_startrecv(sc) != 0) { - ath_err(common, "Unable to start recv logic\n"); - r = -EIO; - spin_unlock_bh(&sc->sc_pcu_lock); - goto mutex_unlock; - } - spin_unlock_bh(&sc->sc_pcu_lock); - /* Setup our intr mask. */ ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN | ATH9K_INT_FATAL | @@ -1136,12 +1087,14 @@ static int ath9k_start(struct ieee80211_hw *hw) /* Disable BMISS interrupt when we're not associated */ ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); - ath9k_hw_set_interrupts(ah, ah->imask); - ath9k_hw_enable_interrupts(ah); - ieee80211_wake_queues(hw); + if (!ath_complete_reset(sc, false)) { + r = -EIO; + spin_unlock_bh(&sc->sc_pcu_lock); + goto mutex_unlock; + } - ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + spin_unlock_bh(&sc->sc_pcu_lock); if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && !ah->btcoex_hw.enabled) { @@ -1234,11 +1187,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); - cancel_delayed_work_sync(&sc->tx_complete_work); - cancel_delayed_work_sync(&sc->hw_pll_work); - cancel_work_sync(&sc->paprd_work); - cancel_work_sync(&sc->hw_check_work); - cancel_work_sync(&sc->hw_reset_work); + ath_cancel_work(sc); if (sc->sc_flags & SC_OP_INVALID) { ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); @@ -2349,9 +2298,11 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) ath9k_ps_wakeup(sc); spin_lock_bh(&sc->sc_pcu_lock); drain_txq = ath_drain_all_txq(sc, false); + spin_unlock_bh(&sc->sc_pcu_lock); + if (!drain_txq) ath_reset(sc, false); - spin_unlock_bh(&sc->sc_pcu_lock); + ath9k_ps_restore(sc); ieee80211_wake_queues(hw); From 43c3528430bd29f5e52438cad7cf7c0c62bf4583 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 3 Sep 2011 01:40:27 +0200 Subject: [PATCH 136/287] ath9k: implement .get_antenna and .set_antenna On MIMO chips this can be used to enable/disable hardware chains, ensuring that the MCS information is updated accordingly. On non-MIMO chips with rx diversity (e.g. 9285), this configures the rx input antenna. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 + drivers/net/wireless/ath/ath9k/init.c | 32 +++++++++--- drivers/net/wireless/ath/ath9k/main.c | 71 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath9k/recv.c | 2 +- 4 files changed, 99 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b2992d4097c3..0fb4a26f8979 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -649,6 +649,7 @@ struct ath_softc { struct ath_descdma txsdma; struct ath_ant_comb ant_comb; + u8 ant_tx, ant_rx; }; void ath9k_tasklet(unsigned long data); @@ -669,6 +670,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops); void ath9k_deinit_device(struct ath_softc *sc); void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); +void ath9k_reload_chainmask_settings(struct ath_softc *sc); void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); bool ath9k_uses_beacons(int type); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index be302fbdc3dc..9b34c4bab937 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -653,9 +653,22 @@ static void ath9k_init_txpower_limits(struct ath_softc *sc) ah->curchan = curchan; } +void ath9k_reload_chainmask_settings(struct ath_softc *sc) +{ + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)) + return; + + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) + setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) + setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); +} + + void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) { - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | @@ -693,6 +706,16 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vif); + hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; + hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1; + + /* single chain devices with rx diversity */ + if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) + hw->wiphy->available_antennas_rx = BIT(0) | BIT(1); + + sc->ant_rx = hw->wiphy->available_antennas_rx; + sc->ant_tx = hw->wiphy->available_antennas_tx; + #ifdef CONFIG_ATH9K_RATE_CONTROL hw->rate_control_algorithm = "ath9k_rate_control"; #endif @@ -704,12 +727,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &sc->sbands[IEEE80211_BAND_5GHZ]; - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) - setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) - setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); - } + ath9k_reload_chainmask_settings(sc); SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 19c78be3dc41..c8ac2ce61ffe 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -281,6 +281,22 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) ath_start_ani(common); } + if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) { + struct ath_hw_antcomb_conf div_ant_conf; + u8 lna_conf; + + ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); + + if (sc->ant_rx == 1) + lna_conf = ATH_ANT_DIV_COMB_LNA1; + else + lna_conf = ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.main_lna_conf = lna_conf; + div_ant_conf.alt_lna_conf = lna_conf; + + ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); + } + ieee80211_wake_queues(sc->hw); return true; @@ -2379,6 +2395,59 @@ static int ath9k_get_stats(struct ieee80211_hw *hw, return 0; } +static u32 fill_chainmask(u32 cap, u32 new) +{ + u32 filled = 0; + int i; + + for (i = 0; cap && new; i++, cap >>= 1) { + if (!(cap & BIT(0))) + continue; + + if (new & BIT(0)) + filled |= BIT(i); + + new >>= 1; + } + + return filled; +} + +static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) +{ + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; + + if (!rx_ant || !tx_ant) + return -EINVAL; + + sc->ant_rx = rx_ant; + sc->ant_tx = tx_ant; + + if (ah->caps.rx_chainmask == 1) + return 0; + + /* AR9100 runs into calibration issues if not all rx chains are enabled */ + if (AR_SREV_9100(ah)) + ah->rxchainmask = 0x7; + else + ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant); + + ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant); + ath9k_reload_chainmask_settings(sc); + + return 0; +} + +static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) +{ + struct ath_softc *sc = hw->priv; + + *tx_ant = sc->ant_tx; + *rx_ant = sc->ant_rx; + return 0; +} + struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, @@ -2405,4 +2474,6 @@ struct ieee80211_ops ath9k_ops = { .tx_frames_pending = ath9k_tx_frames_pending, .tx_last_beacon = ath9k_tx_last_beacon, .get_stats = ath9k_get_stats, + .set_antenna = ath9k_set_antenna, + .get_antenna = ath9k_get_antenna, }; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 9c7f905f3871..8d3e19dfe7db 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1950,7 +1950,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ath_rx_ps(sc, skb); spin_unlock_irqrestore(&sc->sc_pm_lock, flags); - if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) + if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx == 3) ath_ant_comb_scan(sc, &rs); ieee80211_rx(hw, skb); From 64ed5cf01345da60b5fd9f27e22e5e2e2ffb0a33 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 3 Sep 2011 09:06:20 +0200 Subject: [PATCH 137/287] minstrel_ht: fix Open BA session request floods Minstrel HT tries very hard to establish a BA session with each peer once there's some data on the way. However the stack does not inform minstrel if an aggregation session is already in place, so it keeps trying and wastes good cycles in the tx status path. [ 8149.946393] Open BA session requested for $AP tid 0 [ 8150.048765] Open BA session requested for $AP tid 0 [ 8150.174509] Open BA session requested for $AP tid 0 [ 8150.274376] Open BA session requested for $AP tid 0 ... Signed-off-by: Christian Lamparter Acked-by: Felix Fietkau Signed-off-by: John W. Linville --- net/mac80211/rc80211_minstrel_ht.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 21588386a302..e19249b0f971 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -452,7 +452,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) { minstrel_ht_update_stats(mp, mi); - minstrel_aggr_check(mp, sta, skb); + if (!(info->flags & IEEE80211_TX_CTL_AMPDU)) + minstrel_aggr_check(mp, sta, skb); } } From b0037fab39b52d9b478b2997630a4c0c7e542222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 3 Sep 2011 21:01:01 +0200 Subject: [PATCH 138/287] b43: drop Copyright for not really copyrightable info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As discussed in "Licensing wlc_phy_radio.h and brcm80211" (Message-ID: ) content of that file is not copyrightable, just names and numbers. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/radio_2056.h | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h index d52df6be705a..a7159d8578be 100644 --- a/drivers/net/wireless/b43/radio_2056.h +++ b/drivers/net/wireless/b43/radio_2056.h @@ -1,29 +1,3 @@ -/* - - Broadcom B43 wireless driver - - Copyright (c) 2010 RafaÅ‚ MiÅ‚ecki - - Some parts of the code in this file are derived from the brcm80211 - driver Copyright (c) 2010 Broadcom Corporation - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - #ifndef B43_RADIO_2056_H_ #define B43_RADIO_2056_H_ From 108f4f3c4afff207486f9bc0ba9af2bdd4b19793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 3 Sep 2011 21:01:02 +0200 Subject: [PATCH 139/287] b43: add my copyrights and myself as the module author MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/bus.c | 2 ++ drivers/net/wireless/b43/main.c | 2 ++ drivers/net/wireless/b43/phy_ht.c | 2 ++ drivers/net/wireless/b43/phy_lcn.c | 2 ++ drivers/net/wireless/b43/phy_n.c | 1 + drivers/net/wireless/b43/radio_2055.c | 1 + drivers/net/wireless/b43/radio_2056.c | 2 ++ drivers/net/wireless/b43/radio_2059.c | 2 ++ drivers/net/wireless/b43/tables_nphy.c | 1 + drivers/net/wireless/b43/tables_phy_ht.c | 2 ++ drivers/net/wireless/b43/tables_phy_lcn.c | 2 ++ 11 files changed, 19 insertions(+) diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c index 05f6c7bff6ab..424692df239d 100644 --- a/drivers/net/wireless/b43/bus.c +++ b/drivers/net/wireless/b43/bus.c @@ -3,6 +3,8 @@ Broadcom B43 wireless driver Bus abstraction layer + Copyright (c) 2011 RafaÅ‚ MiÅ‚ecki + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6bca727456b6..24077023d484 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -7,6 +7,7 @@ Copyright (c) 2005-2009 Michael Buesch Copyright (c) 2005 Danny van Dyk Copyright (c) 2005 Andreas Jaggi + Copyright (c) 2010-2011 RafaÅ‚ MiÅ‚ecki SDIO support Copyright (c) 2009 Albert Herranz @@ -64,6 +65,7 @@ MODULE_AUTHOR("Martin Langer"); MODULE_AUTHOR("Stefano Brivio"); MODULE_AUTHOR("Michael Buesch"); MODULE_AUTHOR("Gábor Stefanik"); +MODULE_AUTHOR("RafaÅ‚ MiÅ‚ecki"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE("b43/ucode11.fw"); diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index 4d6345e8ee6b..7416c5e9154d 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c @@ -3,6 +3,8 @@ Broadcom B43 wireless driver IEEE 802.11n HT-PHY support + Copyright (c) 2011 RafaÅ‚ MiÅ‚ecki + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index d0f106ed9f67..d1dfeec7bc28 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -3,6 +3,8 @@ Broadcom B43 wireless driver IEEE 802.11n LCN-PHY support + Copyright (c) 2011 RafaÅ‚ MiÅ‚ecki + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 6e9168079b9e..4951678c366e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -4,6 +4,7 @@ IEEE 802.11n PHY support Copyright (c) 2008 Michael Buesch + Copyright (c) 2010-2011 RafaÅ‚ MiÅ‚ecki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c index 93643f18c2b3..5289a18ddd8c 100644 --- a/drivers/net/wireless/b43/radio_2055.c +++ b/drivers/net/wireless/b43/radio_2055.c @@ -4,6 +4,7 @@ IEEE 802.11n PHY and radio device data tables Copyright (c) 2008 Michael Buesch + Copyright (c) 2010 RafaÅ‚ MiÅ‚ecki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c index 8890df067029..a01f776ca4de 100644 --- a/drivers/net/wireless/b43/radio_2056.c +++ b/drivers/net/wireless/b43/radio_2056.c @@ -3,6 +3,8 @@ Broadcom B43 wireless driver IEEE 802.11n 2056 radio device data tables + Copyright (c) 2010 RafaÅ‚ MiÅ‚ecki + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c index f029f6e1f5d1..d4ce8a12ff9a 100644 --- a/drivers/net/wireless/b43/radio_2059.c +++ b/drivers/net/wireless/b43/radio_2059.c @@ -3,6 +3,8 @@ Broadcom B43 wireless driver IEEE 802.11n 2059 radio device data tables + Copyright (c) 2011 RafaÅ‚ MiÅ‚ecki + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 916f238a71df..7b326f2efdc9 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -4,6 +4,7 @@ IEEE 802.11n PHY data tables Copyright (c) 2008 Michael Buesch + Copyright (c) 2010 RafaÅ‚ MiÅ‚ecki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/drivers/net/wireless/b43/tables_phy_ht.c b/drivers/net/wireless/b43/tables_phy_ht.c index 677d217b5fb3..176c49d74ef4 100644 --- a/drivers/net/wireless/b43/tables_phy_ht.c +++ b/drivers/net/wireless/b43/tables_phy_ht.c @@ -3,6 +3,8 @@ Broadcom B43 wireless driver IEEE 802.11n HT-PHY data tables + Copyright (c) 2011 RafaÅ‚ MiÅ‚ecki + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index 7bf70578b5c2..1682ba0a4107 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -3,6 +3,8 @@ Broadcom B43 wireless driver IEEE 802.11n LCN-PHY data tables + Copyright (c) 2011 RafaÅ‚ MiÅ‚ecki + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or From 28e3181a7717b7e7934391c29e21c5302324479c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 4 Sep 2011 09:11:46 +0200 Subject: [PATCH 140/287] b43: LCN-PHY: load TX gain table on init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/tables_phy_lcn.c | 195 +++++++++++++++++++++- drivers/net/wireless/b43/tables_phy_lcn.h | 2 + 2 files changed, 194 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/tables_phy_lcn.c b/drivers/net/wireless/b43/tables_phy_lcn.c index 1682ba0a4107..9d484e2f79bf 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.c +++ b/drivers/net/wireless/b43/tables_phy_lcn.c @@ -27,6 +27,18 @@ #include "phy_common.h" #include "phy_lcn.h" +struct b43_lcntab_tx_gain_tbl_entry { + u8 gm; + u8 pga; + u8 pad; + u8 dac; + u8 bb_mult; +}; + +/************************************************** + * Static tables. + **************************************************/ + static const u16 b43_lcntab_0x02[] = { 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d, @@ -297,6 +309,146 @@ static const u32 b43_lcntab_0x18[] = { 0x00080000, 0x00080000, 0x00080000, 0x00080000, }; +/************************************************** + * TX gain. + **************************************************/ + +const struct b43_lcntab_tx_gain_tbl_entry + b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = { + { 0x03, 0x00, 0x1f, 0x0, 0x48 }, + { 0x03, 0x00, 0x1f, 0x0, 0x46 }, + { 0x03, 0x00, 0x1f, 0x0, 0x44 }, + { 0x03, 0x00, 0x1e, 0x0, 0x43 }, + { 0x03, 0x00, 0x1d, 0x0, 0x44 }, + { 0x03, 0x00, 0x1c, 0x0, 0x44 }, + { 0x03, 0x00, 0x1b, 0x0, 0x45 }, + { 0x03, 0x00, 0x1a, 0x0, 0x46 }, + { 0x03, 0x00, 0x19, 0x0, 0x46 }, + { 0x03, 0x00, 0x18, 0x0, 0x47 }, + { 0x03, 0x00, 0x17, 0x0, 0x48 }, + { 0x03, 0x00, 0x17, 0x0, 0x46 }, + { 0x03, 0x00, 0x16, 0x0, 0x47 }, + { 0x03, 0x00, 0x15, 0x0, 0x48 }, + { 0x03, 0x00, 0x15, 0x0, 0x46 }, + { 0x03, 0x00, 0x15, 0x0, 0x44 }, + { 0x03, 0x00, 0x15, 0x0, 0x42 }, + { 0x03, 0x00, 0x15, 0x0, 0x40 }, + { 0x03, 0x00, 0x15, 0x0, 0x3f }, + { 0x03, 0x00, 0x14, 0x0, 0x40 }, + { 0x03, 0x00, 0x13, 0x0, 0x41 }, + { 0x03, 0x00, 0x13, 0x0, 0x40 }, + { 0x03, 0x00, 0x12, 0x0, 0x41 }, + { 0x03, 0x00, 0x12, 0x0, 0x40 }, + { 0x03, 0x00, 0x11, 0x0, 0x41 }, + { 0x03, 0x00, 0x11, 0x0, 0x40 }, + { 0x03, 0x00, 0x10, 0x0, 0x41 }, + { 0x03, 0x00, 0x10, 0x0, 0x40 }, + { 0x03, 0x00, 0x10, 0x0, 0x3e }, + { 0x03, 0x00, 0x10, 0x0, 0x3c }, + { 0x03, 0x00, 0x10, 0x0, 0x3a }, + { 0x03, 0x00, 0x0f, 0x0, 0x3d }, + { 0x03, 0x00, 0x0f, 0x0, 0x3b }, + { 0x03, 0x00, 0x0e, 0x0, 0x3d }, + { 0x03, 0x00, 0x0e, 0x0, 0x3c }, + { 0x03, 0x00, 0x0e, 0x0, 0x3a }, + { 0x03, 0x00, 0x0d, 0x0, 0x3c }, + { 0x03, 0x00, 0x0d, 0x0, 0x3b }, + { 0x03, 0x00, 0x0c, 0x0, 0x3e }, + { 0x03, 0x00, 0x0c, 0x0, 0x3c }, + { 0x03, 0x00, 0x0c, 0x0, 0x3a }, + { 0x03, 0x00, 0x0b, 0x0, 0x3e }, + { 0x03, 0x00, 0x0b, 0x0, 0x3c }, + { 0x03, 0x00, 0x0b, 0x0, 0x3b }, + { 0x03, 0x00, 0x0b, 0x0, 0x39 }, + { 0x03, 0x00, 0x0a, 0x0, 0x3d }, + { 0x03, 0x00, 0x0a, 0x0, 0x3b }, + { 0x03, 0x00, 0x0a, 0x0, 0x39 }, + { 0x03, 0x00, 0x09, 0x0, 0x3e }, + { 0x03, 0x00, 0x09, 0x0, 0x3c }, + { 0x03, 0x00, 0x09, 0x0, 0x3a }, + { 0x03, 0x00, 0x09, 0x0, 0x39 }, + { 0x03, 0x00, 0x08, 0x0, 0x3e }, + { 0x03, 0x00, 0x08, 0x0, 0x3c }, + { 0x03, 0x00, 0x08, 0x0, 0x3a }, + { 0x03, 0x00, 0x08, 0x0, 0x39 }, + { 0x03, 0x00, 0x08, 0x0, 0x37 }, + { 0x03, 0x00, 0x07, 0x0, 0x3d }, + { 0x03, 0x00, 0x07, 0x0, 0x3c }, + { 0x03, 0x00, 0x07, 0x0, 0x3a }, + { 0x03, 0x00, 0x07, 0x0, 0x38 }, + { 0x03, 0x00, 0x07, 0x0, 0x37 }, + { 0x03, 0x00, 0x06, 0x0, 0x3e }, + { 0x03, 0x00, 0x06, 0x0, 0x3c }, + { 0x03, 0x00, 0x06, 0x0, 0x3a }, + { 0x03, 0x00, 0x06, 0x0, 0x39 }, + { 0x03, 0x00, 0x06, 0x0, 0x37 }, + { 0x03, 0x00, 0x06, 0x0, 0x36 }, + { 0x03, 0x00, 0x06, 0x0, 0x34 }, + { 0x03, 0x00, 0x05, 0x0, 0x3d }, + { 0x03, 0x00, 0x05, 0x0, 0x3b }, + { 0x03, 0x00, 0x05, 0x0, 0x39 }, + { 0x03, 0x00, 0x05, 0x0, 0x38 }, + { 0x03, 0x00, 0x05, 0x0, 0x36 }, + { 0x03, 0x00, 0x05, 0x0, 0x35 }, + { 0x03, 0x00, 0x05, 0x0, 0x33 }, + { 0x03, 0x00, 0x04, 0x0, 0x3e }, + { 0x03, 0x00, 0x04, 0x0, 0x3c }, + { 0x03, 0x00, 0x04, 0x0, 0x3a }, + { 0x03, 0x00, 0x04, 0x0, 0x39 }, + { 0x03, 0x00, 0x04, 0x0, 0x37 }, + { 0x03, 0x00, 0x04, 0x0, 0x36 }, + { 0x03, 0x00, 0x04, 0x0, 0x34 }, + { 0x03, 0x00, 0x04, 0x0, 0x33 }, + { 0x03, 0x00, 0x04, 0x0, 0x31 }, + { 0x03, 0x00, 0x04, 0x0, 0x30 }, + { 0x03, 0x00, 0x04, 0x0, 0x2e }, + { 0x03, 0x00, 0x03, 0x0, 0x3c }, + { 0x03, 0x00, 0x03, 0x0, 0x3a }, + { 0x03, 0x00, 0x03, 0x0, 0x39 }, + { 0x03, 0x00, 0x03, 0x0, 0x37 }, + { 0x03, 0x00, 0x03, 0x0, 0x36 }, + { 0x03, 0x00, 0x03, 0x0, 0x34 }, + { 0x03, 0x00, 0x03, 0x0, 0x33 }, + { 0x03, 0x00, 0x03, 0x0, 0x31 }, + { 0x03, 0x00, 0x03, 0x0, 0x30 }, + { 0x03, 0x00, 0x03, 0x0, 0x2e }, + { 0x03, 0x00, 0x03, 0x0, 0x2d }, + { 0x03, 0x00, 0x03, 0x0, 0x2c }, + { 0x03, 0x00, 0x03, 0x0, 0x2b }, + { 0x03, 0x00, 0x03, 0x0, 0x29 }, + { 0x03, 0x00, 0x02, 0x0, 0x3d }, + { 0x03, 0x00, 0x02, 0x0, 0x3b }, + { 0x03, 0x00, 0x02, 0x0, 0x39 }, + { 0x03, 0x00, 0x02, 0x0, 0x38 }, + { 0x03, 0x00, 0x02, 0x0, 0x36 }, + { 0x03, 0x00, 0x02, 0x0, 0x35 }, + { 0x03, 0x00, 0x02, 0x0, 0x33 }, + { 0x03, 0x00, 0x02, 0x0, 0x32 }, + { 0x03, 0x00, 0x02, 0x0, 0x30 }, + { 0x03, 0x00, 0x02, 0x0, 0x2f }, + { 0x03, 0x00, 0x02, 0x0, 0x2e }, + { 0x03, 0x00, 0x02, 0x0, 0x2c }, + { 0x03, 0x00, 0x02, 0x0, 0x2b }, + { 0x03, 0x00, 0x02, 0x0, 0x2a }, + { 0x03, 0x00, 0x02, 0x0, 0x29 }, + { 0x03, 0x00, 0x02, 0x0, 0x27 }, + { 0x03, 0x00, 0x02, 0x0, 0x26 }, + { 0x03, 0x00, 0x02, 0x0, 0x25 }, + { 0x03, 0x00, 0x02, 0x0, 0x24 }, + { 0x03, 0x00, 0x02, 0x0, 0x23 }, + { 0x03, 0x00, 0x02, 0x0, 0x22 }, + { 0x03, 0x00, 0x02, 0x0, 0x21 }, + { 0x03, 0x00, 0x02, 0x0, 0x20 }, + { 0x03, 0x00, 0x01, 0x0, 0x3f }, + { 0x03, 0x00, 0x01, 0x0, 0x3d }, + { 0x03, 0x00, 0x01, 0x0, 0x3b }, + { 0x03, 0x00, 0x01, 0x0, 0x39 }, +}; + +/************************************************** + * SW control. + **************************************************/ + const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = { 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001, @@ -479,6 +631,32 @@ static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev) lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18); } +void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev, + const struct b43_lcntab_tx_gain_tbl_entry *gain_table) +{ + u32 i; + u32 val; + + u16 pa_gain = 0x70; + if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM) + pa_gain = 0x10; + + for (i = 0; i < B43_LCNTAB_TX_GAIN_SIZE; i++) { + val = ((pa_gain << 24) | + (gain_table[i].pad << 16) | + (gain_table[i].pga << 8) | + gain_table[i].gm); + b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0xc0 + i), val); + + /* brcmsmac doesn't maskset, we follow newer wl here */ + val = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i)); + val &= 0x000fffff; + val |= ((gain_table[i].dac << 28) | + (gain_table[i].bb_mult << 20)); + b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x140 + i), val); + } +} + /* Not implemented in brcmsmac, noticed in wl in MMIO dump */ static void b43_phy_lcn_rewrite_tables(struct b43_wldev *dev) { @@ -499,13 +677,24 @@ static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev) b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000); } +/* wlc_lcnphy_tbl_init */ void b43_phy_lcn_tables_init(struct b43_wldev *dev) { + struct ssb_sprom *sprom = dev->dev->bus_sprom; + b43_phy_lcn_upload_static_tables(dev); - /* TODO: various tables ops here */ - if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM && - !(dev->dev->bus_sprom->boardflags_hi & B43_BFH_FEM_BT)) + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if (sprom->boardflags_lo & B43_BFL_EXTLNA) + b43_phy_lcn_load_tx_gain_tab(dev, + b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0); + else + b43err(dev->wl, + "TX gain table unknown for this card\n"); + } + + if (sprom->boardflags_lo & B43_BFL_FEM && + !(sprom->boardflags_hi & B43_BFH_FEM_BT)) b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0), ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0), b43_lcntab_sw_ctl_4313_epa_rev0); diff --git a/drivers/net/wireless/b43/tables_phy_lcn.h b/drivers/net/wireless/b43/tables_phy_lcn.h index b6471e89c36f..caff9db6831f 100644 --- a/drivers/net/wireless/b43/tables_phy_lcn.h +++ b/drivers/net/wireless/b43/tables_phy_lcn.h @@ -10,6 +10,8 @@ #define B43_LCNTAB16(table, offset) (((table) << 10) | (offset) | B43_LCNTAB_16BIT) #define B43_LCNTAB32(table, offset) (((table) << 10) | (offset) | B43_LCNTAB_32BIT) +#define B43_LCNTAB_TX_GAIN_SIZE 128 + u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset); void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset, unsigned int nr_elements, void *_data); From 7827493b886c307bc497a669305207f8a5b36eb2 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Sun, 4 Sep 2011 11:11:32 +0300 Subject: [PATCH 141/287] mac80211: add ssid config to bss information in AP-mode Set SSID information from nl80211 beacon parameters. Advertise changes in SSID to low level drivers. Signed-off-by: Arik Nemtsov Signed-off-by: John W. Linville --- include/net/mac80211.h | 8 ++++++++ net/mac80211/cfg.c | 19 ++++++++++++++++++- net/mac80211/util.c | 2 ++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index fc4806c6097f..643e1291a1e8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -164,6 +164,7 @@ struct ieee80211_low_level_stats { * @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note * that it is only ever disabled for station mode. * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. + * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode) */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -181,6 +182,7 @@ enum ieee80211_bss_change { BSS_CHANGED_ARP_FILTER = 1<<12, BSS_CHANGED_QOS = 1<<13, BSS_CHANGED_IDLE = 1<<14, + BSS_CHANGED_SSID = 1<<15, /* when adding here, make sure to change ieee80211_reconfig */ }; @@ -254,6 +256,9 @@ enum ieee80211_rssi_event { * @idle: This interface is idle. There's also a global idle flag in the * hardware config which may be more appropriate depending on what * your driver/device needs to do. + * @ssid: The SSID of the current vif. Only valid in AP-mode. + * @ssid_len: Length of SSID given in @ssid. + * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -280,6 +285,9 @@ struct ieee80211_bss_conf { bool arp_filter_enabled; bool qos; bool idle; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + size_t ssid_len; + bool hidden_ssid; }; /** diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5c0d8fab0e88..b57ddf941e59 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -455,6 +455,20 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, return ret; } +static void ieee80211_config_ap_ssid(struct ieee80211_sub_if_data *sdata, + struct beacon_parameters *params) +{ + struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; + + bss_conf->ssid_len = params->ssid_len; + + if (params->ssid_len) + memcpy(bss_conf->ssid, params->ssid, params->ssid_len); + + bss_conf->hidden_ssid = + (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); +} + /* * This handles both adding a beacon and setting new beacon info */ @@ -548,8 +562,11 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, kfree(old); + ieee80211_config_ap_ssid(sdata, params); + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | - BSS_CHANGED_BEACON); + BSS_CHANGED_BEACON | + BSS_CHANGED_SSID); return 0; } diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1c1080274730..4b1466d5b6a1 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1077,6 +1077,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) changed |= BSS_CHANGED_IBSS; /* fall through */ case NL80211_IFTYPE_AP: + changed |= BSS_CHANGED_SSID; + /* fall through */ case NL80211_IFTYPE_MESH_POINT: changed |= BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED; From c002831a07ddba2a81fe1172c497ec7e673ba720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 4 Sep 2011 23:18:22 +0200 Subject: [PATCH 142/287] b43: N-PHY: use helper for checking IPA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 4951678c366e..40e436e0476e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -89,6 +89,13 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, u16 value, u8 core); +static inline bool b43_nphy_ipa(struct b43_wldev *dev) +{ + enum ieee80211_band band = b43_current_band(dev->wl); + return ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) || + (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); +} + void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) {//TODO } @@ -353,8 +360,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) if (dev->phy.rev < 2 && dev->phy.is_40mhz) b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW); - if ((nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) || - (nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ)) { + if (b43_nphy_ipa(dev)) { b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x4); b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x4); } @@ -650,14 +656,10 @@ static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */ static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev) { - struct b43_phy_n *nphy = dev->phy.n; u16 tmp; - enum ieee80211_band band = b43_current_band(dev->wl); - bool ipa = (nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) || - (nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ); if (dev->phy.rev >= 3) { - if (ipa) { + if (b43_nphy_ipa(dev)) { tmp = 4; b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2, (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp); @@ -2204,7 +2206,6 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) { - struct b43_phy_n *nphy = dev->phy.n; u8 i; u16 reg, val; @@ -2268,10 +2269,7 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) enum ieee80211_band band = b43_current_band(dev->wl); - if ((nphy->ipa2g_on && - band == IEEE80211_BAND_2GHZ) || - (nphy->ipa5g_on && - band == IEEE80211_BAND_5GHZ)) + if (b43_nphy_ipa(dev)) val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; else val = 0x11; @@ -2897,10 +2895,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) enum ieee80211_band band = b43_current_band(dev->wl); - if ((nphy->ipa2g_on && - band == IEEE80211_BAND_2GHZ) || - (nphy->ipa5g_on && - band == IEEE80211_BAND_5GHZ)) { + if (b43_nphy_ipa(dev)) { table = b43_nphy_get_ipa_gain_table(dev); } else { if (band == IEEE80211_BAND_5GHZ) { @@ -3736,8 +3731,7 @@ int b43_phy_initn(struct b43_wldev *dev) } tmp2 = b43_current_band(dev->wl); - if ((nphy->ipa2g_on && tmp2 == IEEE80211_BAND_2GHZ) || - (nphy->ipa5g_on && tmp2 == IEEE80211_BAND_5GHZ)) { + if (b43_nphy_ipa(dev)) { b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1); b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F, nphy->papd_epsilon_offset[0] << 7); From 44f4008b5983f058fbea6d238f8c78908676d092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 4 Sep 2011 23:23:51 +0200 Subject: [PATCH 143/287] b43: N-PHY: replace some hacks with nice tables ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 40e436e0476e..c291ae576b3d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -444,19 +444,14 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) else b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain); - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain); - - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57); - tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); + b43_ntab_write(dev, B43_NTAB16(0x7, 0x110 + i), radio_gain); + tmp = b43_ntab_read(dev, B43_NTAB16(0xF, 0x57)); if (i == 0) tmp = (tmp & 0x00FF) | (bbmult << 8); else tmp = (tmp & 0xFF00) | bbmult; - - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57); - b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp); + b43_ntab_write(dev, B43_NTAB16(0xF, 0x57), tmp); if (0) ; /* TODO */ @@ -970,11 +965,7 @@ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) { u16 array[4]; - int i; - - b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C50); - for (i = 0; i < 4; i++) - array[i] = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); + b43_ntab_read_bulk(dev, B43_NTAB16(0xF, 0x50), 4, array); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW0, array[0]); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW1, array[1]); From 73d07a39ee3eadb9ff6734432151a10c50329804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 4 Sep 2011 23:23:52 +0200 Subject: [PATCH 144/287] b43: N-PHY: split workarounds into per-PHY-ver functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 300 ++++++++++++++++--------------- 1 file changed, 157 insertions(+), 143 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index c291ae576b3d..8647933f9321 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1428,180 +1428,194 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) } } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ -static void b43_nphy_workarounds(struct b43_wldev *dev) +static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) { struct ssb_sprom *sprom = dev->dev->bus_sprom; - struct b43_phy *phy = &dev->phy; - struct b43_phy_n *nphy = phy->n; - - u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; - u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; - - u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; - u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; u16 tmp16; u32 tmp32; - if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) - b43_nphy_classifier(dev, 1, 0); - else - b43_nphy_classifier(dev, 1, 1); + tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); + tmp32 &= 0xffffff; + b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32); - if (nphy->hang_avoid) - b43_nphy_stay_in_carrier_search(dev, 1); + b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125); + b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3); + b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105); + b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E); + b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); + b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); - b43_phy_set(dev, B43_NPHY_IQFLIP, - B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); + b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); + b43_phy_write(dev, 0x2AE, 0x000C); - if (dev->phy.rev >= 3) { - tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); - tmp32 &= 0xffffff; - b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32); + /* TODO */ - b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125); - b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3); - b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105); - b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E); - b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD); - b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020); + tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? + 0x2 : 0x9C40; + b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); - b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); - b43_phy_write(dev, 0x2AE, 0x000C); + b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); - /* TODO */ + b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); + b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); - tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? - 0x2 : 0x9C40; - b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16); + b43_nphy_gain_ctrl_workarounds(dev); - b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700); + b43_ntab_write(dev, B43_NTAB32(8, 0), 2); + b43_ntab_write(dev, B43_NTAB32(8, 16), 2); - b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); - b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); + /* TODO */ - b43_nphy_gain_ctrl_workarounds(dev); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); + b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); + b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); + + /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ + + if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR && + b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || + (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR && + b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) + tmp32 = 0x00088888; + else + tmp32 = 0x88888888; + b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32); + b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32); + b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32); + + if (dev->phy.rev == 4 && + b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC, + 0x70); + b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC, + 0x70); + } - b43_ntab_write(dev, B43_NTAB32(8, 0), 2); - b43_ntab_write(dev, B43_NTAB32(8, 16), 2); + b43_phy_write(dev, 0x224, 0x039C); + b43_phy_write(dev, 0x225, 0x0357); + b43_phy_write(dev, 0x226, 0x0317); + b43_phy_write(dev, 0x227, 0x02D7); + b43_phy_write(dev, 0x228, 0x039C); + b43_phy_write(dev, 0x229, 0x0357); + b43_phy_write(dev, 0x22A, 0x0317); + b43_phy_write(dev, 0x22B, 0x02D7); + b43_phy_write(dev, 0x22C, 0x039C); + b43_phy_write(dev, 0x22D, 0x0357); + b43_phy_write(dev, 0x22E, 0x0317); + b43_phy_write(dev, 0x22F, 0x02D7); +} - /* TODO */ +static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev) +{ + struct ssb_sprom *sprom = dev->dev->bus_sprom; + struct b43_phy *phy = &dev->phy; + struct b43_phy_n *nphy = phy->n; - b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00); - b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00); - b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06); - b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06); - b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07); - b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07); - b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88); - b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); - b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); - b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); - - /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ - - if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR && - b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || - (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR && - b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) - tmp32 = 0x00088888; - else - tmp32 = 0x88888888; - b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32); - b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32); - b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32); - - if (dev->phy.rev == 4 && - b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { - b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC, - 0x70); - b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC, - 0x70); - } + u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; + u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; - b43_phy_write(dev, 0x224, 0x039C); - b43_phy_write(dev, 0x225, 0x0357); - b43_phy_write(dev, 0x226, 0x0317); - b43_phy_write(dev, 0x227, 0x02D7); - b43_phy_write(dev, 0x228, 0x039C); - b43_phy_write(dev, 0x229, 0x0357); - b43_phy_write(dev, 0x22A, 0x0317); - b43_phy_write(dev, 0x22B, 0x02D7); - b43_phy_write(dev, 0x22C, 0x039C); - b43_phy_write(dev, 0x22D, 0x0357); - b43_phy_write(dev, 0x22E, 0x0317); - b43_phy_write(dev, 0x22F, 0x02D7); + u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; + u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; + + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && + nphy->band5g_pwrgain) { + b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); + b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8); } else { - if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && - nphy->band5g_pwrgain) { - b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); - b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8); - } else { - b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); - b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); - } + b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); + b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); + } - b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A); - b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A); - b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); - b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); + b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A); + b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A); + b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); + b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); - if (dev->phy.rev < 2) { - b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000); - b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000); - b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); - b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); - b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800); - b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800); - } + if (dev->phy.rev < 2) { + b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000); + b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000); + b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); + b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); + b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800); + b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800); + } - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); - if (sprom->boardflags2_lo & 0x100 && - dev->dev->board_type == 0x8B) { - delays1[0] = 0x1; - delays1[5] = 0x14; - } - b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); - b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); + if (sprom->boardflags2_lo & 0x100 && + dev->dev->board_type == 0x8B) { + delays1[0] = 0x1; + delays1[5] = 0x14; + } + b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); + b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); - b43_nphy_gain_ctrl_workarounds(dev); + b43_nphy_gain_ctrl_workarounds(dev); - if (dev->phy.rev < 2) { - if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) - b43_hf_write(dev, b43_hf_read(dev) | - B43_HF_MLADVW); - } else if (dev->phy.rev == 2) { - b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); - b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); - } + if (dev->phy.rev < 2) { + if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) + b43_hf_write(dev, b43_hf_read(dev) | + B43_HF_MLADVW); + } else if (dev->phy.rev == 2) { + b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); + b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); + } - if (dev->phy.rev < 2) - b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, - ~B43_NPHY_SCRAM_SIGCTL_SCM); + if (dev->phy.rev < 2) + b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, + ~B43_NPHY_SCRAM_SIGCTL_SCM); + + /* Set phase track alpha and beta */ + b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); + b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); + b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); + b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); + b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); + b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); + + b43_phy_mask(dev, B43_NPHY_PIL_DW1, + ~B43_NPHY_PIL_DW_64QAM & 0xFFFF); + b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); + b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); + b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); + + if (dev->phy.rev == 2) + b43_phy_set(dev, B43_NPHY_FINERX2_CGC, + B43_NPHY_FINERX2_CGC_DECGC); +} - /* Set phase track alpha and beta */ - b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); - b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); - b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); - b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); - b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); - b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ +static void b43_nphy_workarounds(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_n *nphy = phy->n; - b43_phy_mask(dev, B43_NPHY_PIL_DW1, - ~B43_NPHY_PIL_DW_64QAM & 0xFFFF); - b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); - b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); - b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) + b43_nphy_classifier(dev, 1, 0); + else + b43_nphy_classifier(dev, 1, 1); - if (dev->phy.rev == 2) - b43_phy_set(dev, B43_NPHY_FINERX2_CGC, - B43_NPHY_FINERX2_CGC_DECGC); - } + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 1); + + b43_phy_set(dev, B43_NPHY_IQFLIP, + B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); + + if (dev->phy.rev >= 3) + b43_nphy_workarounds_rev3plus(dev); + else + b43_nphy_workarounds_rev1_2(dev); if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 0); From 0eff8fcd290dc7f25d393fb3692e8e673babdeeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 4 Sep 2011 23:23:53 +0200 Subject: [PATCH 145/287] b43: N-PHY: implement few random missing ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 111 ++++++++++++++++++++++++++----- drivers/net/wireless/b43/phy_n.h | 2 + 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 8647933f9321..b17d9b6c33a5 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -78,6 +78,7 @@ enum b43_nphy_rssi_type { B43_NPHY_RSSI_TBD, }; +/* TODO: reorder functions */ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable); static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, @@ -88,6 +89,7 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, u16 value, u8 core, bool off); static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, u16 value, u8 core); +static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev); static inline bool b43_nphy_ipa(struct b43_wldev *dev) { @@ -453,8 +455,14 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) tmp = (tmp & 0xFF00) | bbmult; b43_ntab_write(dev, B43_NTAB16(0xF, 0x57), tmp); - if (0) - ; /* TODO */ + if (b43_nphy_ipa(dev)) { + u32 tmp32; + u16 reg = (i == 0) ? + B43_NPHY_PAPD_EN0 : B43_NPHY_PAPD_EN1; + tmp32 = b43_ntab_read(dev, B43_NTAB32(26 + i, txpi[i])); + b43_phy_maskset(dev, reg, 0xE00F, (u32) tmp32 << 4); + b43_phy_set(dev, reg, 0x4); + } } b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT); @@ -463,6 +471,57 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } +static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + const u32 *table = NULL; +#if 0 + TODO: b43_ntab_papd_pga_gain_delta_ipa_2* + u32 rfpwr_offset; + u8 pga_gain; + int i; +#endif + + if (phy->rev >= 3) { + if (b43_nphy_ipa(dev)) { + table = b43_nphy_get_ipa_gain_table(dev); + } else { + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + if (phy->rev == 3) + table = b43_ntab_tx_gain_rev3_5ghz; + if (phy->rev == 4) + table = b43_ntab_tx_gain_rev4_5ghz; + else + table = b43_ntab_tx_gain_rev5plus_5ghz; + } else { + table = b43_ntab_tx_gain_rev3plus_2ghz; + } + } + } else { + table = b43_ntab_tx_gain_rev0_1_2; + } + b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); + b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table); + + if (phy->rev >= 3) { +#if 0 + nphy->gmval = (table[0] >> 16) & 0x7000; + + for (i = 0; i < 128; i++) { + pga_gain = (table[i] >> 24) & 0xF; + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; + else + rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain]; + b43_ntab_write(dev, B43_NTAB32(26, 576 + i), + rfpwr_offset); + b43_ntab_write(dev, B43_NTAB32(27, 576 + i), + rfpwr_offset); + } +#endif + } +} /* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */ static void b43_radio_2055_setup(struct b43_wldev *dev, @@ -1430,8 +1489,19 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) { + struct b43_phy_n *nphy = dev->phy.n; struct ssb_sprom *sprom = dev->dev->bus_sprom; + /* TX to RX */ + u8 tx2rx_events[9] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F }; + u8 tx2rx_delays[9] = { 8, 4, 2, 2, 4, 4, 6, 1 }; + /* RX to TX */ + u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3, + 0x1F }; + u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; + u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F }; + u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; + u16 tmp16; u32 tmp32; @@ -1449,7 +1519,22 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C); b43_phy_write(dev, 0x2AE, 0x000C); - /* TODO */ + /* TX to RX */ + b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays, 9); + + /* RX to TX */ + if (b43_nphy_ipa(dev)) + b43_nphy_set_rf_sequence(dev, 1, rx2tx_events_ipa, + rx2tx_delays_ipa, 9); + if (nphy->hw_phyrxchain != 3 && + nphy->hw_phyrxchain != nphy->hw_phytxchain) { + if (b43_nphy_ipa(dev)) { + rx2tx_delays[5] = 59; + rx2tx_delays[6] = 1; + rx2tx_events[7] = 0x1F; + } + b43_nphy_set_rf_sequence(dev, 1, rx2tx_events, rx2tx_delays, 9); + } tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0x2 : 0x9C40; @@ -1553,8 +1638,8 @@ static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); - if (sprom->boardflags2_lo & 0x100 && - dev->dev->board_type == 0x8B) { + if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD && + dev->dev->board_type == 0x8B) { delays1[0] = 0x1; delays1[5] = 0x14; } @@ -2649,8 +2734,8 @@ static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { if (dev->phy.rev >= 6) { - /* TODO If the chip is 47162 - return txpwrctrl_tx_gain_ipa_rev5 */ + if (dev->dev->chip_id == 47162) + return txpwrctrl_tx_gain_ipa_rev5; return txpwrctrl_tx_gain_ipa_rev6; } else if (dev->phy.rev >= 5) { return txpwrctrl_tx_gain_ipa_rev5; @@ -3717,7 +3802,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); - if (sprom->boardflags2_lo & 0x100 || + if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD || (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE && dev->dev->board_type == 0x8B)) b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); @@ -3774,15 +3859,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_nphy_tx_power_fix(dev); /* TODO N PHY TX Power Control Idle TSSI */ /* TODO N PHY TX Power Control Setup */ - - if (phy->rev >= 3) { - /* TODO */ - } else { - b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, - b43_ntab_tx_gain_rev0_1_2); - b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, - b43_ntab_tx_gain_rev0_1_2); - } + b43_nphy_tx_gain_table_upload(dev); if (nphy->phyrxchain != 3) b43_nphy_set_rx_core_state(dev, nphy->phyrxchain); diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index cd8498904b90..fbf520285bd1 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -764,6 +764,8 @@ struct b43_phy_n { u8 cal_orig_pwr_idx[2]; u8 measure_hold; u8 phyrxchain; + u8 hw_phyrxchain; + u8 hw_phytxchain; u8 perical; u32 deaf_count; u32 rxcalparams; From cd0b8d89c75233d8468f3c585e4e022f6779ac84 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 6 Sep 2011 14:13:06 +0200 Subject: [PATCH 146/287] mac80211: further optimise buffer expiry timer Juuso optimised the timer to not run all the time in commit 3393a608c4979a94d1887efc05b7. However, after that it will still run once more even if all frames just expired. Fixing that also makes the function return value a little clearer in the process. Also, while at it, change the return value to bool (instead of int). Cc: Juuso Oikarinen Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/sta_info.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 17caba27040b..42c196e86115 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -691,14 +691,13 @@ void sta_info_clear_tim_bit(struct sta_info *sta) spin_unlock_irqrestore(&sta->local->sta_lock, flags); } -static int sta_info_buffer_expired(struct sta_info *sta, - struct sk_buff *skb) +static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) { struct ieee80211_tx_info *info; int timeout; if (!skb) - return 0; + return false; info = IEEE80211_SKB_CB(skb); @@ -718,9 +717,6 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, unsigned long flags; struct sk_buff *skb; - if (skb_queue_empty(&sta->ps_tx_buf)) - return false; - for (;;) { spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); skb = skb_peek(&sta->ps_tx_buf); @@ -745,7 +741,7 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, sta_info_clear_tim_bit(sta); } - return true; + return !skb_queue_empty(&sta->ps_tx_buf); } static int __must_check __sta_info_destroy(struct sta_info *sta) From f7e014dac29b1abe5c8fa8d721d43928633340ab Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 6 Sep 2011 21:00:06 +0530 Subject: [PATCH 147/287] ath9k: Take the samples in unassociated state Currently the samples debugfs which maintains the snapshorts of mac/bb only on associated state. Hence to cover issues on idle state, the samples are taken whenever the driver is ready. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 19ef559ac78f..556032762693 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1373,6 +1373,9 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file) u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; u8 nread; + if (sc->sc_flags & SC_OP_INVALID) + return -EAGAIN; + buf = vmalloc(size); if (!buf) return -ENOMEM; @@ -1381,6 +1384,8 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file) vfree(buf); return -ENOMEM; } + /* Account the current state too */ + ath9k_debug_samp_bb_mac(sc); spin_lock_bh(&sc->debug.samp_lock); memcpy(bb_mac_samp, sc->debug.bb_mac_samp, From 6bc05a9555543d0f8cc56bf2647819aebe39e938 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 6 Sep 2011 21:00:07 +0530 Subject: [PATCH 148/287] ath9k: Move cycle conters under cc_lock This patch protects cycle counters access by cc_lock and also prints current sample index. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 556032762693..7f143872dc83 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -1323,16 +1323,17 @@ void ath9k_debug_samp_bb_mac(struct ath_softc *sc) ath9k_ps_wakeup(sc); + spin_lock_bh(&sc->debug.samp_lock); + spin_lock_irqsave(&common->cc_lock, flags); ath_hw_cycle_counters_update(common); - spin_unlock_irqrestore(&common->cc_lock, flags); - - spin_lock_bh(&sc->debug.samp_lock); ATH_SAMP_DBG(cc.cycles) = common->cc_ani.cycles; ATH_SAMP_DBG(cc.rx_busy) = common->cc_ani.rx_busy; ATH_SAMP_DBG(cc.rx_frame) = common->cc_ani.rx_frame; ATH_SAMP_DBG(cc.tx_frame) = common->cc_ani.tx_frame; + spin_unlock_irqrestore(&common->cc_lock, flags); + ATH_SAMP_DBG(noise) = ah->noise; REG_WRITE_D(ah, AR_MACMISC, @@ -1390,6 +1391,8 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file) spin_lock_bh(&sc->debug.samp_lock); memcpy(bb_mac_samp, sc->debug.bb_mac_samp, sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES); + len += snprintf(buf + len, size - len, + "Current Sample Index: %d\n", sc->debug.sampidx); spin_unlock_bh(&sc->debug.samp_lock); len += snprintf(buf + len, size - len, From e948b99d6f38b726ad1c8f99a2672b792756b549 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 6 Sep 2011 21:59:51 +0530 Subject: [PATCH 149/287] ath9k_hw: Fix magnitude/phase average in TxIQ Calibration The commit "ath9k_hw: Fix Tx IQ Calibration hang issue in AR9003 chips" did not consider more than one potential sample while calculating magnitude/phase average if more than one sample has the same value which could affect post-processing of outlier detection that causes an undesirable Tx IQ correction value will be assigned to tx gain settings where outlier happens. Cc: Kai Shi Reported-by: Paul Stewart Signed-off-by: Rajkumar Manoharan Signed-off-by: Paul Stewart Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index fa35a0235f44..3319a676c0fb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -615,11 +615,10 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, { int mp_max = -64, max_idx = 0; int mp_min = 63, min_idx = 0; - int mp_avg = 0, i, outlier_idx = 0; + int mp_avg = 0, i, outlier_idx = 0, mp_count = 0; /* find min/max mismatch across all calibrated gains */ for (i = 0; i < nmeasurement; i++) { - mp_avg += mp_coeff[i]; if (mp_coeff[i] > mp_max) { mp_max = mp_coeff[i]; max_idx = i; @@ -632,10 +631,20 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, /* find average (exclude max abs value) */ for (i = 0; i < nmeasurement; i++) { if ((abs(mp_coeff[i]) < abs(mp_max)) || - (abs(mp_coeff[i]) < abs(mp_min))) + (abs(mp_coeff[i]) < abs(mp_min))) { mp_avg += mp_coeff[i]; + mp_count++; + } } - mp_avg /= (nmeasurement - 1); + + /* + * finding mean magnitude/phase if possible, otherwise + * just use the last value as the mean + */ + if (mp_count) + mp_avg /= mp_count; + else + mp_avg = mp_coeff[nmeasurement - 1]; /* detect outlier */ if (abs(mp_max - mp_min) > max_delta) { From a944aa9dee00c1f696768bcf4a99e6b1d308351a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 6 Sep 2011 09:31:16 -0700 Subject: [PATCH 150/287] iwlagn: only perform necessary calibration at init time During init time, only the necessary calibration should be performed. This not only save time, also avoid uCode crash because lack of necessary information. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index cb06196e0e80..82bfef4730d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3213,12 +3213,7 @@ enum iwl_ucode_calib_cfg { IWL_CALIB_CFG_LO_IDX | \ IWL_CALIB_CFG_TX_IQ_IDX | \ IWL_CALIB_CFG_RX_IQ_IDX | \ - IWL_CALIB_CFG_NOISE_IDX | \ - IWL_CALIB_CFG_CRYSTAL_IDX | \ - IWL_CALIB_CFG_TEMPERATURE_IDX | \ - IWL_CALIB_CFG_PAPD_IDX | \ - IWL_CALIB_CFG_SENSITIVITY_IDX | \ - IWL_CALIB_CFG_TX_PWR_IDX) + IWL_CALIB_CFG_CRYSTAL_IDX) #define IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK cpu_to_le32(BIT(0)) From 65e291acd806fae8cb6fff73a93def84d0ad327a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 6 Sep 2011 09:31:17 -0700 Subject: [PATCH 151/287] iwlagn: merge iwl_pci_down and iwl_pci_remove The latter was the only place that called the first. The two functions were split when the iwl_pci_probe called iwl_pci_down upon failure in the probe. Since iwl_pci_probe undoes its work by itself, there is no need to split between iwl_pci_down, and iwl_pci_remove. Thanks to Pavel Roskin for pointing that out. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index e41f53e5c307..78a3f8dfe680 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -483,9 +483,13 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return err; } -static void iwl_pci_down(struct iwl_bus *bus) +static void __devexit iwl_pci_remove(struct pci_dev *pdev) { - struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus->bus_specific; + struct iwl_shared *shrd = pci_get_drvdata(pdev); + struct iwl_bus *bus = shrd->bus; + struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); + + iwl_remove(shrd->priv); pci_disable_msi(pci_bus->pci_dev); pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base); @@ -496,16 +500,6 @@ static void iwl_pci_down(struct iwl_bus *bus) kfree(bus); } -static void __devexit iwl_pci_remove(struct pci_dev *pdev) -{ - struct iwl_shared *shrd = pci_get_drvdata(pdev); - struct iwl_bus *bus = shrd->bus; - - iwl_remove(shrd->priv); - - iwl_pci_down(bus); -} - #ifdef CONFIG_PM_SLEEP static int iwl_pci_suspend(struct device *device) From 3e10caeb55b2693b38f1f80c67c79d918fc42e42 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 6 Sep 2011 09:31:18 -0700 Subject: [PATCH 152/287] iwlagn: remove priv dereferences from the transport layer Another round of clean up on the transport layer. Define a wrapper around wiphy_rfkill_set_hw_state to prevent the transport layer from accessing priv->hw. Also move wait_command_queue to the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.c | 7 +++- drivers/net/wireless/iwlwifi/iwl-dev.h | 6 ++-- drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-sta.c | 4 +-- .../net/wireless/iwlwifi/iwl-trans-int-pcie.h | 3 +- .../net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 36 +++++++++---------- .../net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 36 +++++++++---------- drivers/net/wireless/iwlwifi/iwl-trans.c | 18 ++++------ 11 files changed, 59 insertions(+), 60 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index ddb255a575df..8b14d24849b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -114,7 +114,7 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name); - ret = wait_event_interruptible_timeout(priv->wait_command_queue, + ret = wait_event_interruptible_timeout(priv->shrd->wait_command_queue, priv->ucode_write_complete, 5 * HZ); if (ret == -ERESTARTSYS) { IWL_ERR(priv, "Could not load the %s uCode section due " diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8113fbe770a3..484f889a886e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3032,7 +3032,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) { priv->shrd->workqueue = create_singlethread_workqueue(DRV_NAME); - init_waitqueue_head(&priv->wait_command_queue); + init_waitqueue_head(&priv->shrd->wait_command_queue); INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 72b9203c06e2..d9897da7281f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -868,7 +868,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) * commands by clearing the ready bit */ clear_bit(STATUS_READY, &priv->shrd->status); - wake_up_interruptible(&priv->wait_command_queue); + wake_up_interruptible(&priv->shrd->wait_command_queue); if (!ondemand) { /* @@ -1865,3 +1865,8 @@ void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv, ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); } + +void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state) +{ + wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1e54293532b0..8ae79e9cf5f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -102,7 +102,7 @@ struct iwl_cmd_meta { * invoked for SYNC commands, if it were and its result passed * through it would be simpler...) */ - void (*callback)(struct iwl_priv *priv, + void (*callback)(struct iwl_shared *shrd, struct iwl_device_cmd *cmd, struct iwl_rx_packet *pkt); @@ -304,7 +304,7 @@ enum iwl_hcmd_dataflag { struct iwl_host_cmd { const void *data[IWL_MAX_CMD_TFDS]; unsigned long reply_page; - void (*callback)(struct iwl_priv *priv, + void (*callback)(struct iwl_shared *shrd, struct iwl_device_cmd *cmd, struct iwl_rx_packet *pkt); u32 flags; @@ -1142,8 +1142,6 @@ struct iwl_priv { /* Rate scaling data */ u8 retry_rate; - wait_queue_head_t wait_command_queue; - int activity_timer_active; /* counts mgmt, ctl, and data packets */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 8572548dd4a2..ee8fabd0b4f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -563,7 +563,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); else - wake_up_interruptible(&priv->wait_command_queue); + wake_up_interruptible(&priv->shrd->wait_command_queue); } static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 8b8cd54a32e0..9790d7eba39b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -250,6 +250,8 @@ struct iwl_shared { struct ieee80211_hw *hw; struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; + + wait_queue_head_t wait_command_queue; }; /*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ @@ -361,6 +363,7 @@ void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv, void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid); +void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); /***************************************************** * DRIVER STATUS FUNCTIONS diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 26b2bd4db6b4..e24135e7d37d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -123,14 +123,14 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, return ret; } -static void iwl_add_sta_callback(struct iwl_priv *priv, +static void iwl_add_sta_callback(struct iwl_shared *shrd, struct iwl_device_cmd *cmd, struct iwl_rx_packet *pkt) { struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)cmd->cmd.payload; - iwl_process_add_sta_resp(priv, addsta, pkt, false); + iwl_process_add_sta_resp(shrd->priv, addsta, pkt, false); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h index ec4e73737681..f76526e080a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h @@ -195,7 +195,8 @@ int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id, u32 flags, u16 len, const void *data); -void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); +void iwl_tx_cmd_complete(struct iwl_trans *trans, + struct iwl_rx_mem_buffer *rxb); void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_tx_queue *txq, u16 byte_cnt); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c index 2d0ddb8d422d..e22cc6d8c07f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c @@ -453,7 +453,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) * iwl_trans_send_cmd() * as we reclaim the driver command queue */ if (rxb->page) - iwl_tx_cmd_complete(priv(trans), rxb); + iwl_tx_cmd_complete(trans, rxb); else IWL_WARN(trans, "Claim null rxb?\n"); } @@ -646,7 +646,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) */ clear_bit(STATUS_READY, &trans->shrd->status); clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); - wake_up_interruptible(&priv->wait_command_queue); + wake_up_interruptible(&priv->shrd->wait_command_queue); IWL_ERR(trans, "RF is used by WiMAX\n"); return; } @@ -705,18 +705,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, ptr = base + EVENT_START_OFFSET + (start_idx * event_size); /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags); - iwl_grab_nic_access(bus(priv)); + spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags); + iwl_grab_nic_access(bus(trans)); /* Set starting address; reads will auto-increment */ - iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); + iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr); rmb(); /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); + ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); + time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); if (mode == 0) { /* data, ev */ if (bufsz) { @@ -730,7 +730,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, time, ev); } } else { - data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); + data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOGT:%010u:0x%08x:%04u\n", @@ -745,8 +745,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, } /* Allow device to power down */ - iwl_release_nic_access(bus(priv)); - spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); + iwl_release_nic_access(bus(trans)); + spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags); return pos; } @@ -823,10 +823,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, } /* event log header */ - capacity = iwl_read_targ_mem(bus(priv), base); - mode = iwl_read_targ_mem(bus(priv), base + (1 * sizeof(u32))); - num_wraps = iwl_read_targ_mem(bus(priv), base + (2 * sizeof(u32))); - next_entry = iwl_read_targ_mem(bus(priv), base + (3 * sizeof(u32))); + capacity = iwl_read_targ_mem(bus(trans), base); + mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32))); + num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32))); + next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32))); if (capacity > logsize) { IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " @@ -908,8 +908,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) u32 inta_mask; #endif - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct isr_statistics *isr_stats = &trans_pcie->isr_stats; @@ -1003,8 +1002,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) else clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - wiphy_rfkill_set_hw_state(priv(trans)->hw->wiphy, - hw_rf_kill); + iwl_set_hw_rfkill_state(priv(trans), hw_rf_kill); } handled |= CSR_INT_BIT_RF_KILL; @@ -1093,7 +1091,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ priv(trans)->ucode_write_complete = 1; - wake_up_interruptible(&priv(trans)->wait_command_queue); + wake_up_interruptible(&trans->shrd->wait_command_queue); } if (inta & ~handled) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c index ea6a0bc8ca20..32314a60e2ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c @@ -536,7 +536,6 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, struct iwl_tid_data *tid_data; unsigned long flags; int txq_id; - struct iwl_priv *priv = priv(trans); txq_id = iwlagn_txq_ctx_activate_free(trans); if (txq_id == -1) { @@ -560,7 +559,7 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, "queue\n", tid_data->tfds_in_queue); tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_irqrestore(&trans->shrd->sta_lock, flags); return 0; } @@ -856,16 +855,16 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) * need to be reclaimed. As result, some free space forms. If there is * enough free space (> low mark), wake the stack that feeds us. */ -static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx) +static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, + int idx) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans(priv)); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; struct iwl_queue *q = &txq->q; int nfreed = 0; if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { - IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), " + IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " "index %d is out of range [0-%d] %d %d.\n", __func__, txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr); return; @@ -875,9 +874,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx) q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { if (nfreed++ > 0) { - IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx, + IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", idx, q->write_ptr, q->read_ptr); - iwlagn_fw_error(priv, false); + iwlagn_fw_error(priv(trans), false); } } @@ -891,7 +890,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx) * will be executed. The attached skb (if present) will only be freed * if the callback returns 1 */ -void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 sequence = le16_to_cpu(pkt->hdr.sequence); @@ -900,7 +899,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) int cmd_index; struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; - struct iwl_trans *trans = trans(priv); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; unsigned long flags; @@ -913,7 +911,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) txq_id, trans->shrd->cmd_queue, sequence, trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr, trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) { - iwl_print_hex_error(priv, pkt, 32); + iwl_print_hex_error(trans, pkt, 32); return; } @@ -929,17 +927,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) meta->source->reply_page = (unsigned long)rxb_addr(rxb); rxb->page = NULL; } else if (meta->callback) - meta->callback(priv, cmd, pkt); + meta->callback(trans->shrd, cmd, pkt); spin_lock_irqsave(&trans->hcmd_lock, flags); - iwl_hcmd_queue_reclaim(priv, txq_id, index); + iwl_hcmd_queue_reclaim(trans, txq_id, index); if (!(meta->flags & CMD_ASYNC)) { clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->hdr.cmd)); - wake_up_interruptible(&priv->wait_command_queue); + wake_up_interruptible(&trans->shrd->wait_command_queue); } meta->flags = 0; @@ -1031,12 +1029,12 @@ const char *get_cmd_string(u8 cmd) #define HOST_COMPLETE_TIMEOUT (2 * HZ) -static void iwl_generic_cmd_callback(struct iwl_priv *priv, +static void iwl_generic_cmd_callback(struct iwl_shared *shrd, struct iwl_device_cmd *cmd, struct iwl_rx_packet *pkt) { if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from %s (0x%08X)\n", + IWL_ERR(shrd->trans, "Bad return from %s (0x%08X)\n", get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); return; } @@ -1045,11 +1043,11 @@ static void iwl_generic_cmd_callback(struct iwl_priv *priv, switch (cmd->hdr.cmd) { case REPLY_TX_LINK_QUALITY_CMD: case SENSITIVITY_CMD: - IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n", + IWL_DEBUG_HC_DUMP(shrd->trans, "back from %s (0x%08X)\n", get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); break; default: - IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n", + IWL_DEBUG_HC(shrd->trans, "back from %s (0x%08X)\n", get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); } #endif @@ -1107,7 +1105,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return ret; } - ret = wait_event_interruptible_timeout(priv(trans)->wait_command_queue, + ret = wait_event_interruptible_timeout(trans->shrd->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), HOST_COMPLETE_TIMEOUT); if (!ret) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index cec13adb018e..44e2f911f89b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -604,9 +604,8 @@ static int iwl_tx_init(struct iwl_trans *trans) return ret; } -static void iwl_set_pwr_vmain(struct iwl_priv *priv) +static void iwl_set_pwr_vmain(struct iwl_trans *trans) { - struct iwl_trans *trans = trans(priv); /* * (for documentation purposes) * to set power to V_AUX, do: @@ -625,11 +624,10 @@ static void iwl_set_pwr_vmain(struct iwl_priv *priv) static int iwl_nic_init(struct iwl_trans *trans) { unsigned long flags; - struct iwl_priv *priv = priv(trans); /* nic_init */ spin_lock_irqsave(&trans->shrd->lock, flags); - iwl_apm_init(priv); + iwl_apm_init(priv(trans)); /* Set interrupt coalescing calibration timer to default (512 usecs) */ iwl_write8(bus(trans), CSR_INT_COALESCING, @@ -637,9 +635,9 @@ static int iwl_nic_init(struct iwl_trans *trans) spin_unlock_irqrestore(&trans->shrd->lock, flags); - iwl_set_pwr_vmain(priv); + iwl_set_pwr_vmain(trans); - priv->cfg->lib->nic_config(priv); + priv(trans)->cfg->lib->nic_config(priv(trans)); /* Allocate the RX queue, or reset if it is already allocated */ iwl_rx_init(trans); @@ -764,7 +762,6 @@ static const u8 iwlagn_pan_ac_to_queue[] = { static int iwl_trans_pcie_start_device(struct iwl_trans *trans) { int ret; - struct iwl_priv *priv = priv(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -792,7 +789,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); if (iwl_is_rfkill(trans->shrd)) { - wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); + iwl_set_hw_rfkill_state(priv(trans), true); iwl_enable_interrupts(trans); return -ERFKILL; } @@ -1397,7 +1394,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) else clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - wiphy_rfkill_set_hw_state(priv(trans)->hw->wiphy, hw_rfkill); + iwl_set_hw_rfkill_state(priv(trans), hw_rfkill); return 0; } @@ -1674,7 +1671,6 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, { struct iwl_trans *trans = file->private_data; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_priv *priv = priv(trans); struct iwl_tx_queue *txq; struct iwl_queue *q; char *buf; @@ -1684,7 +1680,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num; if (!trans_pcie->txq) { - IWL_ERR(priv, "txq not ready\n"); + IWL_ERR(trans, "txq not ready\n"); return -EAGAIN; } buf = kzalloc(bufsz, GFP_KERNEL); From 522376d206da66cecc90929134ad70c0446e874b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 6 Sep 2011 09:31:19 -0700 Subject: [PATCH 153/287] iwlagn: clean up of transport layer Move a few declarations needed by the transport layer to iwl-shared.h Move iwl_cmd_meta, iwl_tx_queue and friends to the internal transport header file. Move iwl_device_cmd iwl_host_cmd and friends to iwl-trans.h since these structs are used in the API to the transport layer. Move get_cmd_string to the upper layer with a declaration in iwl-shared.h. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.h | 1 - drivers/net/wireless/iwlwifi/iwl-agn.h | 2 - drivers/net/wireless/iwlwifi/iwl-core.c | 4 +- drivers/net/wireless/iwlwifi/iwl-core.h | 22 --- drivers/net/wireless/iwlwifi/iwl-dev.h | 162 ------------------ drivers/net/wireless/iwlwifi/iwl-helpers.h | 23 --- drivers/net/wireless/iwlwifi/iwl-rx.c | 81 +++++++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 43 +++++ drivers/net/wireless/iwlwifi/iwl-sv-open.c | 1 + .../net/wireless/iwlwifi/iwl-trans-int-pcie.h | 92 ++++++++++ .../net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 6 +- .../net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 92 +--------- drivers/net/wireless/iwlwifi/iwl-trans.c | 11 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 66 ++++++- 15 files changed, 299 insertions(+), 309 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 1af276739d87..ea4895a66eb1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -456,7 +456,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) else ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - iwl_print_rx_config_cmd(priv, ctx); + iwl_print_rx_config_cmd(priv, ctx->ctxid); ret = iwl_check_rxon_cmd(priv, ctx); if (ret) { IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h index d118ed29bf3f..7282a23e8f1c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h @@ -117,7 +117,6 @@ struct iwl_tt_mgmt { u8 iwl_tt_current_power_mode(struct iwl_priv *priv); bool iwl_tt_is_low_power_state(struct iwl_priv *priv); bool iwl_ht_enabled(struct iwl_priv *priv); -bool iwl_check_for_ct_kill(struct iwl_priv *priv); enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv); enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv); void iwl_tt_enter_ct_kill(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index a7b4948e43da..4bc1f4669e5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -98,7 +98,6 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, enum iwlagn_ucode_type ucode_type); /* lib */ -int iwlagn_hw_valid_rtc_data_addr(u32 addr); int iwlagn_send_tx_power(struct iwl_priv *priv); void iwlagn_temperature(struct iwl_priv *priv); u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv); @@ -109,7 +108,6 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv); /* rx */ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); void iwl_setup_rx_handlers(struct iwl_priv *priv); -void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /* tx */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d9897da7281f..a600b82e7fcf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -817,9 +817,9 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) } #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) +void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid) { + struct iwl_rxon_context *ctx = &priv->contexts[ctxid]; struct iwl_rxon_cmd *rxon = &ctx->staging; IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2ea8a2e0dfbc..56b554c43fde 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -73,8 +73,6 @@ struct iwl_cmd; #define TIME_UNIT 1024 -#define IWL_CMD(x) case x: return #x - struct iwl_lib_ops { /* set hw dependent parameters */ int (*set_hw_params)(struct iwl_priv *priv); @@ -271,7 +269,6 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_alloc_traffic_mem(struct iwl_priv *priv); void iwl_free_traffic_mem(struct iwl_priv *priv); -void iwl_reset_traffic_log(struct iwl_priv *priv); void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, u16 length, struct ieee80211_hdr *header); void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, @@ -360,26 +357,12 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, * S e n d i n g H o s t C o m m a n d s * *****************************************************/ -const char *get_cmd_string(u8 cmd); void iwl_bg_watchdog(unsigned long data); u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, u32 addon, u32 beacon_interval); -/***************************************************** -* Error Handling Debugging -******************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv, - struct iwl_rxon_context *ctx); -#else -static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ -} -#endif - /***************************************************** * GEOS ******************************************************/ @@ -389,8 +372,6 @@ void iwl_free_geos(struct iwl_priv *priv); extern void iwl_send_bt_config(struct iwl_priv *priv); extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear); -void iwl_apm_stop(struct iwl_priv *priv); -int iwl_apm_init(struct iwl_priv *priv); int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); @@ -408,7 +389,4 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) extern bool bt_siso_mode; - -void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); - #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8ae79e9cf5f1..bbda6725a751 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -32,7 +32,6 @@ #define __iwl_dev_h__ #include -#include /* for struct pci_device_id */ #include #include #include @@ -89,100 +88,6 @@ struct iwl_tx_queue; #define DEFAULT_SHORT_RETRY_LIMIT 7U #define DEFAULT_LONG_RETRY_LIMIT 4U -/* defined below */ -struct iwl_device_cmd; - -struct iwl_cmd_meta { - /* only for SYNC commands, iff the reply skb is wanted */ - struct iwl_host_cmd *source; - /* - * only for ASYNC commands - * (which is somewhat stupid -- look at iwl-sta.c for instance - * which duplicates a bunch of code because the callback isn't - * invoked for SYNC commands, if it were and its result passed - * through it would be simpler...) - */ - void (*callback)(struct iwl_shared *shrd, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt); - - u32 flags; - - DEFINE_DMA_UNMAP_ADDR(mapping); - DEFINE_DMA_UNMAP_LEN(len); -}; - -/* - * Generic queue structure - * - * Contains common data for Rx and Tx queues. - * - * Note the difference between n_bd and n_window: the hardware - * always assumes 256 descriptors, so n_bd is always 256 (unless - * there might be HW changes in the future). For the normal TX - * queues, n_window, which is the size of the software queue data - * is also 256; however, for the command queue, n_window is only - * 32 since we don't need so many commands pending. Since the HW - * still uses 256 BDs for DMA though, n_bd stays 256. As a result, - * the software buffers (in the variables @meta, @txb in struct - * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds - * in the same struct) have 256. - * This means that we end up with the following: - * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | - * SW entries: | 0 | ... | 31 | - * where N is a number between 0 and 7. This means that the SW - * data is a window overlayed over the HW queue. - */ -struct iwl_queue { - int n_bd; /* number of BDs in this queue */ - int write_ptr; /* 1-st empty entry (index) host_w*/ - int read_ptr; /* last used entry (index) host_r*/ - /* use for monitoring and recovering the stuck queue */ - dma_addr_t dma_addr; /* physical addr for BD's */ - int n_window; /* safe queue window */ - u32 id; - int low_mark; /* low watermark, resume queue if free - * space more than this */ - int high_mark; /* high watermark, stop queue if free - * space less than this */ -}; - -/** - * struct iwl_tx_queue - Tx Queue for DMA - * @q: generic Rx/Tx queue descriptor - * @bd: base of circular buffer of TFDs - * @cmd: array of command/TX buffer pointers - * @meta: array of meta data for each command/tx buffer - * @dma_addr_cmd: physical address of cmd/tx buffer array - * @txb: array of per-TFD driver data - * @time_stamp: time (in jiffies) of last read_ptr change - * @need_update: indicates need to update read/write index - * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled - * @sta_id: valid if sched_retry is set - * @tid: valid if sched_retry is set - * - * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame - * descriptors) and required locking structures. - */ -#define TFD_TX_CMD_SLOTS 256 -#define TFD_CMD_SLOTS 32 - -struct iwl_tx_queue { - struct iwl_queue q; - struct iwl_tfd *tfds; - struct iwl_device_cmd **cmd; - struct iwl_cmd_meta *meta; - struct sk_buff **skbs; - unsigned long time_stamp; - u8 need_update; - u8 sched_retry; - u8 active; - u8 swq_id; - - u16 sta_id; - u16 tid; -}; - #define IWL_NUM_SCAN_RATES (2) /* @@ -249,70 +154,6 @@ struct iwl_channel_info { #define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) #define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) - -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) - -enum { - CMD_SYNC = 0, - CMD_ASYNC = BIT(0), - CMD_WANT_SKB = BIT(1), - CMD_ON_DEMAND = BIT(2), -}; - -#define DEF_CMD_PAYLOAD_SIZE 320 - -/** - * struct iwl_device_cmd - * - * For allocation of the command and tx queues, this establishes the overall - * size of the largest command we send to uCode, except for commands that - * aren't fully copied and use other TFD space. - */ -struct iwl_device_cmd { - struct iwl_cmd_header hdr; /* uCode API */ - union { - u32 flags; - u8 val8; - u16 val16; - u32 val32; - struct iwl_tx_cmd tx; - struct iwl6000_channel_switch_cmd chswitch; - u8 payload[DEF_CMD_PAYLOAD_SIZE]; - } __packed cmd; -} __packed; - -#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) - -#define IWL_MAX_CMD_TFDS 2 - -enum iwl_hcmd_dataflag { - IWL_HCMD_DFL_NOCOPY = BIT(0), -}; - -/** - * struct iwl_host_cmd - Host command to the uCode - * @data: array of chunks that composes the data of the host command - * @reply_page: pointer to the page that holds the response to the host command - * @callback: - * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC - * @len: array of the lenths of the chunks in data - * @dataflags: - * @id: id of the host command - */ -struct iwl_host_cmd { - const void *data[IWL_MAX_CMD_TFDS]; - unsigned long reply_page; - void (*callback)(struct iwl_shared *shrd, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt); - u32 flags; - u16 len[IWL_MAX_CMD_TFDS]; - u8 dataflags[IWL_MAX_CMD_TFDS]; - u8 id; -}; - #define SUP_RATE_11A_MAX_NUM_CHANNELS 8 #define SUP_RATE_11B_MAX_NUM_CHANNELS 4 #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 @@ -580,9 +421,6 @@ extern const u8 iwl_bcast_addr[ETH_ALEN]; #define IWL_OPERATION_MODE_MIXED 2 #define IWL_OPERATION_MODE_20MHZ 3 -#define IWL_TX_CRC_SIZE 4 -#define IWL_TX_DELIMITER_SIZE 4 - #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 /* Sensitivity and chain noise calibration */ diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index d3feac9e45b4..968fc66e3506 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -35,35 +35,12 @@ #include "iwl-io.h" -#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) - - static inline struct ieee80211_conf *ieee80211_get_hw_conf( struct ieee80211_hw *hw) { return &hw->conf; } -/** - * iwl_queue_inc_wrap - increment queue index, wrap back to beginning - * @index -- current index - * @n_bd -- total number of entries in queue (must be power of 2) - */ -static inline int iwl_queue_inc_wrap(int index, int n_bd) -{ - return ++index & (n_bd - 1); -} - -/** - * iwl_queue_dec_wrap - decrement queue index, wrap back to end - * @index -- current index - * @n_bd -- total number of entries in queue (must be power of 2) - */ -static inline int iwl_queue_dec_wrap(int index, int n_bd) -{ - return --index & (n_bd - 1); -} - static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) { IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index ee8fabd0b4f3..c7e6a746c3ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -42,6 +42,87 @@ #include "iwl-agn.h" #include "iwl-shared.h" +const char *get_cmd_string(u8 cmd) +{ + switch (cmd) { + IWL_CMD(REPLY_ALIVE); + IWL_CMD(REPLY_ERROR); + IWL_CMD(REPLY_RXON); + IWL_CMD(REPLY_RXON_ASSOC); + IWL_CMD(REPLY_QOS_PARAM); + IWL_CMD(REPLY_RXON_TIMING); + IWL_CMD(REPLY_ADD_STA); + IWL_CMD(REPLY_REMOVE_STA); + IWL_CMD(REPLY_REMOVE_ALL_STA); + IWL_CMD(REPLY_TXFIFO_FLUSH); + IWL_CMD(REPLY_WEPKEY); + IWL_CMD(REPLY_TX); + IWL_CMD(REPLY_LEDS_CMD); + IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); + IWL_CMD(COEX_PRIORITY_TABLE_CMD); + IWL_CMD(COEX_MEDIUM_NOTIFICATION); + IWL_CMD(COEX_EVENT_CMD); + IWL_CMD(REPLY_QUIET_CMD); + IWL_CMD(REPLY_CHANNEL_SWITCH); + IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); + IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD); + IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION); + IWL_CMD(POWER_TABLE_CMD); + IWL_CMD(PM_SLEEP_NOTIFICATION); + IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC); + IWL_CMD(REPLY_SCAN_CMD); + IWL_CMD(REPLY_SCAN_ABORT_CMD); + IWL_CMD(SCAN_START_NOTIFICATION); + IWL_CMD(SCAN_RESULTS_NOTIFICATION); + IWL_CMD(SCAN_COMPLETE_NOTIFICATION); + IWL_CMD(BEACON_NOTIFICATION); + IWL_CMD(REPLY_TX_BEACON); + IWL_CMD(WHO_IS_AWAKE_NOTIFICATION); + IWL_CMD(QUIET_NOTIFICATION); + IWL_CMD(REPLY_TX_PWR_TABLE_CMD); + IWL_CMD(MEASURE_ABORT_NOTIFICATION); + IWL_CMD(REPLY_BT_CONFIG); + IWL_CMD(REPLY_STATISTICS_CMD); + IWL_CMD(STATISTICS_NOTIFICATION); + IWL_CMD(REPLY_CARD_STATE_CMD); + IWL_CMD(CARD_STATE_NOTIFICATION); + IWL_CMD(MISSED_BEACONS_NOTIFICATION); + IWL_CMD(REPLY_CT_KILL_CONFIG_CMD); + IWL_CMD(SENSITIVITY_CMD); + IWL_CMD(REPLY_PHY_CALIBRATION_CMD); + IWL_CMD(REPLY_RX_PHY_CMD); + IWL_CMD(REPLY_RX_MPDU_CMD); + IWL_CMD(REPLY_RX); + IWL_CMD(REPLY_COMPRESSED_BA); + IWL_CMD(CALIBRATION_CFG_CMD); + IWL_CMD(CALIBRATION_RES_NOTIFICATION); + IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); + IWL_CMD(REPLY_TX_POWER_DBM_CMD); + IWL_CMD(TEMPERATURE_NOTIFICATION); + IWL_CMD(TX_ANT_CONFIGURATION_CMD); + IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); + IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); + IWL_CMD(REPLY_BT_COEX_PROT_ENV); + IWL_CMD(REPLY_WIPAN_PARAMS); + IWL_CMD(REPLY_WIPAN_RXON); + IWL_CMD(REPLY_WIPAN_RXON_TIMING); + IWL_CMD(REPLY_WIPAN_RXON_ASSOC); + IWL_CMD(REPLY_WIPAN_QOS_PARAM); + IWL_CMD(REPLY_WIPAN_WEPKEY); + IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); + IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); + IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); + IWL_CMD(REPLY_WOWLAN_PATTERNS); + IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER); + IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS); + IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS); + IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL); + IWL_CMD(REPLY_WOWLAN_GET_STATUS); + default: + return "UNKNOWN"; + + } +} /****************************************************************************** * diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 9790d7eba39b..73ea5e7a1f99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -67,6 +67,7 @@ #include #include #include +#include /* for page_address */ #include #include "iwl-commands.h" @@ -287,6 +288,26 @@ static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page) free_pages(page, shrd->hw_params.rx_page_order); } +/** + * iwl_queue_inc_wrap - increment queue index, wrap back to beginning + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_queue_inc_wrap(int index, int n_bd) +{ + return ++index & (n_bd - 1); +} + +/** + * iwl_queue_dec_wrap - decrement queue index, wrap back to end + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_queue_dec_wrap(int index, int n_bd) +{ + return --index & (n_bd - 1); +} + struct iwl_rx_mem_buffer { dma_addr_t page_dma; struct page *page; @@ -357,6 +378,8 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, struct iwl_cfg *cfg); void __devexit iwl_remove(struct iwl_priv * priv); +void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); +int iwlagn_hw_valid_rtc_data_addr(u32 addr); void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid); @@ -364,6 +387,26 @@ void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid); void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); +void iwl_apm_stop(struct iwl_priv *priv); +int iwl_apm_init(struct iwl_priv *priv); +void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); +const char *get_cmd_string(u8 cmd); +bool iwl_check_for_ct_kill(struct iwl_priv *priv); + +#ifdef CONFIG_IWLWIFI_DEBUGFS +void iwl_reset_traffic_log(struct iwl_priv *priv); +#endif /* CONFIG_IWLWIFI_DEBUGFS */ + +#ifdef CONFIG_IWLWIFI_DEBUG +void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid); +#else +static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid); +{ +} +#endif + +#define IWL_CMD(x) case x: return #x +#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) /***************************************************** * DRIVER STATUS FUNCTIONS diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c index 848fc18befc2..3335d31daf89 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c +++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h index f76526e080a3..c5720cd4f346 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "iwl-fh.h" #include "iwl-csr.h" @@ -114,6 +115,97 @@ struct iwl_dma_ptr { */ #define IWL_IPAN_MCAST_QUEUE 8 +struct iwl_cmd_meta { + /* only for SYNC commands, iff the reply skb is wanted */ + struct iwl_host_cmd *source; + /* + * only for ASYNC commands + * (which is somewhat stupid -- look at iwl-sta.c for instance + * which duplicates a bunch of code because the callback isn't + * invoked for SYNC commands, if it were and its result passed + * through it would be simpler...) + */ + void (*callback)(struct iwl_shared *shrd, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt); + + u32 flags; + + DEFINE_DMA_UNMAP_ADDR(mapping); + DEFINE_DMA_UNMAP_LEN(len); +}; + +/* + * Generic queue structure + * + * Contains common data for Rx and Tx queues. + * + * Note the difference between n_bd and n_window: the hardware + * always assumes 256 descriptors, so n_bd is always 256 (unless + * there might be HW changes in the future). For the normal TX + * queues, n_window, which is the size of the software queue data + * is also 256; however, for the command queue, n_window is only + * 32 since we don't need so many commands pending. Since the HW + * still uses 256 BDs for DMA though, n_bd stays 256. As a result, + * the software buffers (in the variables @meta, @txb in struct + * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds + * in the same struct) have 256. + * This means that we end up with the following: + * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | + * SW entries: | 0 | ... | 31 | + * where N is a number between 0 and 7. This means that the SW + * data is a window overlayed over the HW queue. + */ +struct iwl_queue { + int n_bd; /* number of BDs in this queue */ + int write_ptr; /* 1-st empty entry (index) host_w*/ + int read_ptr; /* last used entry (index) host_r*/ + /* use for monitoring and recovering the stuck queue */ + dma_addr_t dma_addr; /* physical addr for BD's */ + int n_window; /* safe queue window */ + u32 id; + int low_mark; /* low watermark, resume queue if free + * space more than this */ + int high_mark; /* high watermark, stop queue if free + * space less than this */ +}; + +/** + * struct iwl_tx_queue - Tx Queue for DMA + * @q: generic Rx/Tx queue descriptor + * @bd: base of circular buffer of TFDs + * @cmd: array of command/TX buffer pointers + * @meta: array of meta data for each command/tx buffer + * @dma_addr_cmd: physical address of cmd/tx buffer array + * @txb: array of per-TFD driver data + * @time_stamp: time (in jiffies) of last read_ptr change + * @need_update: indicates need to update read/write index + * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled + * @sta_id: valid if sched_retry is set + * @tid: valid if sched_retry is set + * + * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame + * descriptors) and required locking structures. + */ +#define TFD_TX_CMD_SLOTS 256 +#define TFD_CMD_SLOTS 32 + +struct iwl_tx_queue { + struct iwl_queue q; + struct iwl_tfd *tfds; + struct iwl_device_cmd **cmd; + struct iwl_cmd_meta *meta; + struct sk_buff **skbs; + unsigned long time_stamp; + u8 need_update; + u8 sched_retry; + u8 active; + u8 swq_id; + + u16 sta_id; + u16 tid; +}; + /** * struct iwl_trans_pcie - PCIe transport specific data * @rxq: all the RX queue data diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c index e22cc6d8c07f..f7b575022813 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c @@ -30,8 +30,7 @@ #include #include -#include "iwl-dev.h" -#include "iwl-agn.h" +/*TODO: Remove include to iwl-core.h*/ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-helpers.h" @@ -660,8 +659,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) iwl_dump_nic_event_log(trans, false, NULL, false); #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) - iwl_print_rx_config_cmd(priv, - &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_print_rx_config_cmd(priv(trans), IWL_RXON_CTX_BSS); #endif iwlagn_fw_error(priv, false); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c index 32314a60e2ac..ca686dbf5893 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c @@ -30,13 +30,19 @@ #include #include -#include "iwl-agn.h" +/* TODO: remove include to iwl-dev.h */ #include "iwl-dev.h" -#include "iwl-core.h" +#include "iwl-debug.h" +#include "iwl-csr.h" +#include "iwl-prph.h" #include "iwl-io.h" +#include "iwl-agn-hw.h" #include "iwl-helpers.h" #include "iwl-trans-int-pcie.h" +#define IWL_TX_CRC_SIZE 4 +#define IWL_TX_DELIMITER_SIZE 4 + /** * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ @@ -945,88 +951,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) spin_unlock_irqrestore(&trans->hcmd_lock, flags); } -const char *get_cmd_string(u8 cmd) -{ - switch (cmd) { - IWL_CMD(REPLY_ALIVE); - IWL_CMD(REPLY_ERROR); - IWL_CMD(REPLY_RXON); - IWL_CMD(REPLY_RXON_ASSOC); - IWL_CMD(REPLY_QOS_PARAM); - IWL_CMD(REPLY_RXON_TIMING); - IWL_CMD(REPLY_ADD_STA); - IWL_CMD(REPLY_REMOVE_STA); - IWL_CMD(REPLY_REMOVE_ALL_STA); - IWL_CMD(REPLY_TXFIFO_FLUSH); - IWL_CMD(REPLY_WEPKEY); - IWL_CMD(REPLY_TX); - IWL_CMD(REPLY_LEDS_CMD); - IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); - IWL_CMD(COEX_PRIORITY_TABLE_CMD); - IWL_CMD(COEX_MEDIUM_NOTIFICATION); - IWL_CMD(COEX_EVENT_CMD); - IWL_CMD(REPLY_QUIET_CMD); - IWL_CMD(REPLY_CHANNEL_SWITCH); - IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); - IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD); - IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION); - IWL_CMD(POWER_TABLE_CMD); - IWL_CMD(PM_SLEEP_NOTIFICATION); - IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC); - IWL_CMD(REPLY_SCAN_CMD); - IWL_CMD(REPLY_SCAN_ABORT_CMD); - IWL_CMD(SCAN_START_NOTIFICATION); - IWL_CMD(SCAN_RESULTS_NOTIFICATION); - IWL_CMD(SCAN_COMPLETE_NOTIFICATION); - IWL_CMD(BEACON_NOTIFICATION); - IWL_CMD(REPLY_TX_BEACON); - IWL_CMD(WHO_IS_AWAKE_NOTIFICATION); - IWL_CMD(QUIET_NOTIFICATION); - IWL_CMD(REPLY_TX_PWR_TABLE_CMD); - IWL_CMD(MEASURE_ABORT_NOTIFICATION); - IWL_CMD(REPLY_BT_CONFIG); - IWL_CMD(REPLY_STATISTICS_CMD); - IWL_CMD(STATISTICS_NOTIFICATION); - IWL_CMD(REPLY_CARD_STATE_CMD); - IWL_CMD(CARD_STATE_NOTIFICATION); - IWL_CMD(MISSED_BEACONS_NOTIFICATION); - IWL_CMD(REPLY_CT_KILL_CONFIG_CMD); - IWL_CMD(SENSITIVITY_CMD); - IWL_CMD(REPLY_PHY_CALIBRATION_CMD); - IWL_CMD(REPLY_RX_PHY_CMD); - IWL_CMD(REPLY_RX_MPDU_CMD); - IWL_CMD(REPLY_RX); - IWL_CMD(REPLY_COMPRESSED_BA); - IWL_CMD(CALIBRATION_CFG_CMD); - IWL_CMD(CALIBRATION_RES_NOTIFICATION); - IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); - IWL_CMD(REPLY_TX_POWER_DBM_CMD); - IWL_CMD(TEMPERATURE_NOTIFICATION); - IWL_CMD(TX_ANT_CONFIGURATION_CMD); - IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); - IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); - IWL_CMD(REPLY_BT_COEX_PROT_ENV); - IWL_CMD(REPLY_WIPAN_PARAMS); - IWL_CMD(REPLY_WIPAN_RXON); - IWL_CMD(REPLY_WIPAN_RXON_TIMING); - IWL_CMD(REPLY_WIPAN_RXON_ASSOC); - IWL_CMD(REPLY_WIPAN_QOS_PARAM); - IWL_CMD(REPLY_WIPAN_WEPKEY); - IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); - IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); - IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); - IWL_CMD(REPLY_WOWLAN_PATTERNS); - IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER); - IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS); - IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS); - IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL); - IWL_CMD(REPLY_WOWLAN_GET_STATUS); - default: - return "UNKNOWN"; - - } -} - #define HOST_COMPLETE_TIMEOUT (2 * HZ) static void iwl_generic_cmd_callback(struct iwl_shared *shrd, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 44e2f911f89b..3948d317bc19 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -65,14 +65,15 @@ #include #include -#include "iwl-dev.h" #include "iwl-trans.h" -#include "iwl-core.h" -#include "iwl-helpers.h" #include "iwl-trans-int-pcie.h" -/*TODO remove uneeded includes when the transport layer tx_free will be here */ -#include "iwl-agn.h" +#include "iwl-csr.h" +#include "iwl-prph.h" #include "iwl-shared.h" +#include "iwl-eeprom.h" + +/* TODO: the transport layer should not include this */ +#include "iwl-core.h" static int iwl_trans_rx_alloc(struct iwl_trans *trans) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 7a2daa886dfd..71a6fb05356a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -73,10 +73,70 @@ * layer */ struct iwl_priv; -struct iwl_rxon_context; -struct iwl_host_cmd; struct iwl_shared; -struct iwl_device_cmd; + +#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) +#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) + +enum { + CMD_SYNC = 0, + CMD_ASYNC = BIT(0), + CMD_WANT_SKB = BIT(1), + CMD_ON_DEMAND = BIT(2), +}; + +#define DEF_CMD_PAYLOAD_SIZE 320 + +/** + * struct iwl_device_cmd + * + * For allocation of the command and tx queues, this establishes the overall + * size of the largest command we send to uCode, except for commands that + * aren't fully copied and use other TFD space. + */ +struct iwl_device_cmd { + struct iwl_cmd_header hdr; /* uCode API */ + union { + u32 flags; + u8 val8; + u16 val16; + u32 val32; + struct iwl_tx_cmd tx; + struct iwl6000_channel_switch_cmd chswitch; + u8 payload[DEF_CMD_PAYLOAD_SIZE]; + } __packed cmd; +} __packed; + +#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) + +#define IWL_MAX_CMD_TFDS 2 + +enum iwl_hcmd_dataflag { + IWL_HCMD_DFL_NOCOPY = BIT(0), +}; + +/** + * struct iwl_host_cmd - Host command to the uCode + * @data: array of chunks that composes the data of the host command + * @reply_page: pointer to the page that holds the response to the host command + * @callback: + * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC + * @len: array of the lenths of the chunks in data + * @dataflags: + * @id: id of the host command + */ +struct iwl_host_cmd { + const void *data[IWL_MAX_CMD_TFDS]; + unsigned long reply_page; + void (*callback)(struct iwl_shared *shrd, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt); + u32 flags; + u16 len[IWL_MAX_CMD_TFDS]; + u8 dataflags[IWL_MAX_CMD_TFDS]; + u8 id; +}; /** * struct iwl_trans_ops - transport specific operations From 41f5e0475c7c04b17b207736146187636b04eb4c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 6 Sep 2011 09:31:20 -0700 Subject: [PATCH 154/287] iwlagn: move traffic_log back to upper layer The traffic log debugfs handlers were mistakenly moved to the transport layer because they print the pointers of the Tx / Rx queues. The pointers of the queues can be fetched by another debugfs handler. So bring the traffic log back to the upper layer and remove the part that reads the Tx / Rx queues' pointers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 85 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-trans.c | 107 --------------------- 2 files changed, 85 insertions(+), 107 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e320cc10167e..d0c63cfee15c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -804,6 +804,89 @@ DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); DEBUGFS_READ_FILE_OPS(current_sleep_command); +static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + int pos = 0, ofs = 0; + int cnt = 0, entry; + + char *buf; + int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + + (hw_params(priv).max_txq_num * 32 * 8) + 400; + const u8 *ptr; + ssize_t ret; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate buffer\n"); + return -ENOMEM; + } + if (priv->tx_traffic && + (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) { + ptr = priv->tx_traffic; + pos += scnprintf(buf + pos, bufsz - pos, + "Tx Traffic idx: %u\n", priv->tx_traffic_idx); + for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { + for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; + entry++, ofs += 16) { + pos += scnprintf(buf + pos, bufsz - pos, + "0x%.4x ", ofs); + hex_dump_to_buffer(ptr + ofs, 16, 16, 2, + buf + pos, bufsz - pos, 0); + pos += strlen(buf + pos); + if (bufsz - pos > 0) + buf[pos++] = '\n'; + } + } + } + + if (priv->rx_traffic && + (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) { + ptr = priv->rx_traffic; + pos += scnprintf(buf + pos, bufsz - pos, + "Rx Traffic idx: %u\n", priv->rx_traffic_idx); + for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { + for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; + entry++, ofs += 16) { + pos += scnprintf(buf + pos, bufsz - pos, + "0x%.4x ", ofs); + hex_dump_to_buffer(ptr + ofs, 16, 16, 2, + buf + pos, bufsz - pos, 0); + pos += strlen(buf + pos); + if (bufsz - pos > 0) + buf[pos++] = '\n'; + } + } + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_dbgfs_traffic_log_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int traffic_log; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &traffic_log) != 1) + return -EFAULT; + if (traffic_log == 0) + iwl_reset_traffic_log(priv); + + return count; +} + static const char *fmt_value = " %-30s %10u\n"; static const char *fmt_hex = " %-30s 0x%02X\n"; static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; @@ -2340,6 +2423,7 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); +DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); DEBUGFS_READ_FILE_OPS(ucode_rx_stats); DEBUGFS_READ_FILE_OPS(ucode_tx_stats); DEBUGFS_READ_FILE_OPS(ucode_general_stats); @@ -2400,6 +2484,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 3948d317bc19..28fbaa2517a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -1561,111 +1561,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .llseek = generic_file_llseek, \ }; -static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_trans *trans = file->private_data; - struct iwl_priv *priv = priv(trans); - int pos = 0, ofs = 0; - int cnt = 0, entry; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_tx_queue *txq; - struct iwl_queue *q; - struct iwl_rx_queue *rxq = &trans_pcie->rxq; - char *buf; - int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + - (hw_params(trans).max_txq_num * 32 * 8) + 400; - const u8 *ptr; - ssize_t ret; - - if (!trans_pcie->txq) { - IWL_ERR(trans, "txq not ready\n"); - return -EAGAIN; - } - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IWL_ERR(trans, "Can not allocate buffer\n"); - return -ENOMEM; - } - pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n"); - for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { - txq = &trans_pcie->txq[cnt]; - q = &txq->q; - pos += scnprintf(buf + pos, bufsz - pos, - "q[%d]: read_ptr: %u, write_ptr: %u\n", - cnt, q->read_ptr, q->write_ptr); - } - if (priv->tx_traffic && - (iwl_get_debug_level(trans->shrd) & IWL_DL_TX)) { - ptr = priv->tx_traffic; - pos += scnprintf(buf + pos, bufsz - pos, - "Tx Traffic idx: %u\n", priv->tx_traffic_idx); - for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { - for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; - entry++, ofs += 16) { - pos += scnprintf(buf + pos, bufsz - pos, - "0x%.4x ", ofs); - hex_dump_to_buffer(ptr + ofs, 16, 16, 2, - buf + pos, bufsz - pos, 0); - pos += strlen(buf + pos); - if (bufsz - pos > 0) - buf[pos++] = '\n'; - } - } - } - - pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "read: %u, write: %u\n", - rxq->read, rxq->write); - - if (priv->rx_traffic && - (iwl_get_debug_level(trans->shrd) & IWL_DL_RX)) { - ptr = priv->rx_traffic; - pos += scnprintf(buf + pos, bufsz - pos, - "Rx Traffic idx: %u\n", priv->rx_traffic_idx); - for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { - for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; - entry++, ofs += 16) { - pos += scnprintf(buf + pos, bufsz - pos, - "0x%.4x ", ofs); - hex_dump_to_buffer(ptr + ofs, 16, 16, 2, - buf + pos, bufsz - pos, 0); - pos += strlen(buf + pos); - if (bufsz - pos > 0) - buf[pos++] = '\n'; - } - } - } - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -static ssize_t iwl_dbgfs_traffic_log_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_trans *trans = file->private_data; - char buf[8]; - int buf_size; - int traffic_log; - - memset(buf, 0, sizeof(buf)); - buf_size = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - if (sscanf(buf, "%d", &traffic_log) != 1) - return -EFAULT; - if (traffic_log == 0) - iwl_reset_traffic_log(priv(trans)); - - return count; -} - static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -2031,7 +1926,6 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, return ret; } -DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); DEBUGFS_READ_WRITE_FILE_OPS(log_event); DEBUGFS_READ_WRITE_FILE_OPS(interrupt); DEBUGFS_READ_FILE_OPS(fh_reg); @@ -2046,7 +1940,6 @@ DEBUGFS_WRITE_FILE_OPS(csr); static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, struct dentry *dir) { - DEBUGFS_ADD_FILE(traffic_log, dir, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR); DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR); DEBUGFS_ADD_FILE(log_event, dir, S_IWUSR | S_IRUSR); From 7a10e3e4076d09779da5a02b0ab6ce551d964d48 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 6 Sep 2011 09:31:21 -0700 Subject: [PATCH 155/287] iwlagn: iwl-trans.c can't dereference iwl_priv any more This reaches encapsulation for this file. In order to reach this: * move priv->valid_context to iwl_shared * move the last_rejected initialization to the upper layer * define a wrapper iwl_nic_config in the upper layer that calls to cfg->lib->ops->nic_config Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 3 ++ drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 6 +++ drivers/net/wireless/iwlwifi/iwl-csr.h | 18 +++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 38 +------------------ drivers/net/wireless/iwlwifi/iwl-shared.h | 6 +++ .../net/wireless/iwlwifi/iwl-trans-int-pcie.h | 15 ++++++++ drivers/net/wireless/iwlwifi/iwl-trans.c | 12 ++---- 10 files changed, 58 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 7c036b9c2b30..13018872f776 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -659,7 +659,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | IWL_SCD_MGMT_MSK; if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && - (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) + (priv->shrd->valid_contexts != BIT(IWL_RXON_CTX_BSS))) flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index ea4895a66eb1..00e6fc59e459 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -311,7 +311,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) int slot0 = 300, slot1 = 0; int ret; - if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS)) + if (priv->shrd->valid_contexts == BIT(IWL_RXON_CTX_BSS)) return 0; BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 8b14d24849b9..ea31d7674df3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -349,6 +349,7 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) static int iwlagn_alive_notify(struct iwl_priv *priv) { + struct iwl_rxon_context *ctx; int ret; if (!priv->tx_cmd_pool) @@ -361,6 +362,8 @@ static int iwlagn_alive_notify(struct iwl_priv *priv) return -ENOMEM; iwl_trans_tx_start(trans(priv)); + for_each_context(priv, ctx) + ctx->last_tx_rejected = false; ret = iwlagn_send_wimax_coex(priv); if (ret) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 484f889a886e..7f6c58ebbc44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -623,9 +623,9 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) * The default context is always valid, * the PAN context depends on uCode. */ - priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + priv->shrd->valid_contexts = BIT(IWL_RXON_CTX_BSS); if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) - priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); + priv->shrd->valid_contexts |= BIT(IWL_RXON_CTX_PAN); for (i = 0; i < NUM_IWL_RXON_CTX; i++) priv->contexts[i].ctxid = i; @@ -2880,7 +2880,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; int err = 0; - if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) + if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) return -EOPNOTSUPP; if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT))) @@ -2945,7 +2945,7 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; - if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) + if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) return -EOPNOTSUPP; mutex_lock(&priv->shrd->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index a600b82e7fcf..9270f990b2dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1870,3 +1870,9 @@ void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state) { wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); } + +void iwl_nic_config(struct iwl_priv *priv) +{ + priv->cfg->lib->nic_config(priv); + +} diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index d6dbb0423045..b9f3267e720c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -439,4 +439,22 @@ */ #define HBUS_TARG_WRPTR (HBUS_BASE+0x060) +/********************************************************** + * CSR values + **********************************************************/ + /* + * host interrupt timeout value + * used with setting interrupt coalescing timer + * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit + * + * default interrupt coalescing timer is 64 x 32 = 2048 usecs + * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs + */ +#define IWL_HOST_INT_TIMEOUT_MAX (0xFF) +#define IWL_HOST_INT_TIMEOUT_DEF (0x40) +#define IWL_HOST_INT_TIMEOUT_MIN (0x0) +#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF) +#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) +#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) + #endif /* !__iwl_csr_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index bbda6725a751..8438a33e17ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -117,21 +117,6 @@ struct iwl_channel_info { u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ }; -#define IWL_TX_FIFO_BK 0 /* shared */ -#define IWL_TX_FIFO_BE 1 -#define IWL_TX_FIFO_VI 2 /* shared */ -#define IWL_TX_FIFO_VO 3 -#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK -#define IWL_TX_FIFO_BE_IPAN 4 -#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI -#define IWL_TX_FIFO_VO_IPAN 5 -/* re-uses the VO FIFO, uCode will properly flush/schedule */ -#define IWL_TX_FIFO_AUX 5 -#define IWL_TX_FIFO_UNUSED -1 - -/* AUX (TX during scan dwell) queue */ -#define IWL_AUX_QUEUE 10 - /* * Minimum number of queues. MAX_NUM is defined in hw specific files. * Set the minimum to accommodate @@ -544,9 +529,6 @@ struct iwl_chain_noise_data { #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ -#define IWL_TRAFFIC_ENTRIES (256) -#define IWL_TRAFFIC_ENTRY_SIZE (64) - enum { MEASUREMENT_READY = (1 << 0), MEASUREMENT_ACTIVE = (1 << 1), @@ -687,21 +669,6 @@ struct iwl_event_log { int wraps_more_count; }; -/* - * host interrupt timeout value - * used with setting interrupt coalescing timer - * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit - * - * default interrupt coalescing timer is 64 x 32 = 2048 usecs - * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs - */ -#define IWL_HOST_INT_TIMEOUT_MAX (0xFF) -#define IWL_HOST_INT_TIMEOUT_DEF (0x40) -#define IWL_HOST_INT_TIMEOUT_MIN (0x0) -#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF) -#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) -#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) - /* * This is the threshold value of plcp error rate per 100mSecs. It is * used to set and check for the validity of plcp_delta. @@ -933,9 +900,6 @@ struct iwl_priv { /*TODO: remove these pointers - use bus(priv) instead */ struct iwl_bus *bus; /* bus specific data */ - /* microcode/device supports multiple contexts */ - u8 valid_contexts; - /* max number of station keys */ u8 sta_key_max_num; @@ -1163,7 +1127,7 @@ iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) #define for_each_context(priv, ctx) \ for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \ ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ - if (priv->valid_contexts & BIT(ctx->ctxid)) + if (priv->shrd->valid_contexts & BIT(ctx->ctxid)) static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) { diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 73ea5e7a1f99..03f4c6418a66 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -213,6 +213,7 @@ struct iwl_tid_data { * @ucode_owner: IWL_OWNERSHIP_* * @cmd_queue: command queue number * @status: STATUS_* + * @valid_contexts: microcode/device supports multiple contexts * @bus: pointer to the bus layer data * @priv: pointer to the upper layer data * @hw_params: see struct iwl_hw_params @@ -233,6 +234,7 @@ struct iwl_shared { u8 cmd_queue; unsigned long status; bool wowlan; + u8 valid_contexts; struct iwl_bus *bus; struct iwl_priv *priv; @@ -387,6 +389,7 @@ void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid); void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); +void iwl_nic_config(struct iwl_priv *priv); void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); @@ -408,6 +411,9 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid); #define IWL_CMD(x) case x: return #x #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) +#define IWL_TRAFFIC_ENTRIES (256) +#define IWL_TRAFFIC_ENTRY_SIZE (64) + /***************************************************** * DRIVER STATUS FUNCTIONS ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h index c5720cd4f346..8047e955a27b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h @@ -436,4 +436,19 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index) return index & (q->n_window - 1); } +#define IWL_TX_FIFO_BK 0 /* shared */ +#define IWL_TX_FIFO_BE 1 +#define IWL_TX_FIFO_VI 2 /* shared */ +#define IWL_TX_FIFO_VO 3 +#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK +#define IWL_TX_FIFO_BE_IPAN 4 +#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI +#define IWL_TX_FIFO_VO_IPAN 5 +/* re-uses the VO FIFO, uCode will properly flush/schedule */ +#define IWL_TX_FIFO_AUX 5 +#define IWL_TX_FIFO_UNUSED -1 + +/* AUX (TX during scan dwell) queue */ +#define IWL_AUX_QUEUE 10 + #endif /* __iwl_trans_int_pcie_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 28fbaa2517a0..5bf6250612ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -71,9 +71,7 @@ #include "iwl-prph.h" #include "iwl-shared.h" #include "iwl-eeprom.h" - -/* TODO: the transport layer should not include this */ -#include "iwl-core.h" +#include "iwl-agn-hw.h" static int iwl_trans_rx_alloc(struct iwl_trans *trans) { @@ -638,7 +636,7 @@ static int iwl_nic_init(struct iwl_trans *trans) iwl_set_pwr_vmain(trans); - priv(trans)->cfg->lib->nic_config(priv(trans)); + iwl_nic_config(priv(trans)); /* Allocate the RX queue, or reset if it is already allocated */ iwl_rx_init(trans); @@ -831,8 +829,6 @@ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) { const struct queue_to_fifo_ac *queue_to_fifo; - struct iwl_rxon_context *ctx; - struct iwl_priv *priv = priv(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 a; @@ -900,7 +896,7 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); /* map queues to FIFOs */ - if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + if (trans->shrd->valid_contexts != BIT(IWL_RXON_CTX_BSS)) queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo; else queue_to_fifo = iwlagn_default_queue_to_tx_fifo; @@ -912,8 +908,6 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) sizeof(trans_pcie->queue_stopped)); for (i = 0; i < 4; i++) atomic_set(&trans_pcie->queue_stop_count[i], 0); - for_each_context(priv, ctx) - ctx->last_tx_rejected = false; /* reset to 0 to enable all the queue first */ trans_pcie->txq_ctx_active_msk = 0; From 05f8a09faeb4e3a9dd5a877eff747bb898048b5d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 6 Sep 2011 09:31:22 -0700 Subject: [PATCH 156/287] iwlagn: disply queue read/write pointer when stuck When driver detect queue stuck, display current read/write pointer before perform frimware reload. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 5bf6250612ec..c495fc302deb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -1497,6 +1497,8 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) if (time_after(jiffies, timeout)) { IWL_ERR(trans, "Queue %d stuck for %u ms.\n", q->id, hw_params(trans).wd_timeout); + IWL_ERR(trans, "Current read_ptr %d write_ptr %d\n", + q->read_ptr, q->write_ptr); return 1; } From ec8f734f1b1b582f4a5800565b46e9279858bc77 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 6 Sep 2011 09:31:23 -0700 Subject: [PATCH 157/287] iwlagn: enable 11n support for "_d" sku "_d" SKU is 11n enabled device Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-2000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 764d3104e128..913f2a228527 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -285,6 +285,7 @@ struct iwl_cfg iwl2000_2bg_cfg = { struct iwl_cfg iwl2000_2bgn_d_cfg = { .name = "2000D Series 2x2 BGN", IWL_DEVICE_2000, + .ht_params = &iwl2000_ht_params, }; #define IWL_DEVICE_2030 \ From 1ad625ce74f5211045aad6450f7382fd3c599f7e Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 6 Sep 2011 09:31:24 -0700 Subject: [PATCH 158/287] iwlagn: remove lines from the wrong place Few lines for program bt_ch_announce being place in the wrong place. Remove those. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c index f7b575022813..126e5a4cc401 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c @@ -846,9 +846,6 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, return pos; } - /* enable/disable bt channel inhibition */ - priv->bt_ch_announce = iwlagn_mod_params.bt_ch_announce; - #ifdef CONFIG_IWLWIFI_DEBUG if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log) size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) From ff620849110649b5f94989ddfd7a72b2bd43bd42 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 6 Sep 2011 09:31:25 -0700 Subject: [PATCH 159/287] iwlagn: fix compilation when debug flags is unset Trivial fixes to allow compilation without warnings when debug compilation flag isn't set. Also fix the compilation when debugfs flag isn't set. Fix a warning: unused priv pointer on the way. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.c | 260 +++++++++++----------- 3 files changed, 132 insertions(+), 132 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index f8a4bcf0a34b..ba5c514c4a43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -741,7 +741,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); - int cmd_index = SEQ_TO_INDEX(sequence); + int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence); struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; struct ieee80211_hdr *hdr; u32 status = le16_to_cpu(tx_resp->status.status); diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 03f4c6418a66..d987bee5e6ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -403,7 +403,7 @@ void iwl_reset_traffic_log(struct iwl_priv *priv); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid); #else -static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid); +static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid) { } #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index c495fc302deb..b2e89077c684 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -1505,6 +1505,136 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) return 0; } +static const char *get_fh_string(int cmd) +{ + switch (cmd) { + IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); + IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); + IWL_CMD(FH_RSCSR_CHNL0_WPTR); + IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); + IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); + IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); + IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); + IWL_CMD(FH_TSSR_TX_STATUS_REG); + IWL_CMD(FH_TSSR_TX_ERROR_REG); + default: + return "UNKNOWN"; + } +} + +int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) +{ + int i; +#ifdef CONFIG_IWLWIFI_DEBUG + int pos = 0; + size_t bufsz = 0; +#endif + static const u32 fh_tbl[] = { + FH_RSCSR_CHNL0_STTS_WPTR_REG, + FH_RSCSR_CHNL0_RBDCB_BASE_REG, + FH_RSCSR_CHNL0_WPTR, + FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_MEM_RSSR_SHARED_CTRL_REG, + FH_MEM_RSSR_RX_STATUS_REG, + FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, + FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_ERROR_REG + }; +#ifdef CONFIG_IWLWIFI_DEBUG + if (display) { + bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + pos += scnprintf(*buf + pos, bufsz - pos, + "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + pos += scnprintf(*buf + pos, bufsz - pos, + " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(bus(trans), fh_tbl[i])); + } + return pos; + } +#endif + IWL_ERR(trans, "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + IWL_ERR(trans, " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(bus(trans), fh_tbl[i])); + } + return 0; +} + +static const char *get_csr_string(int cmd) +{ + switch (cmd) { + IWL_CMD(CSR_HW_IF_CONFIG_REG); + IWL_CMD(CSR_INT_COALESCING); + IWL_CMD(CSR_INT); + IWL_CMD(CSR_INT_MASK); + IWL_CMD(CSR_FH_INT_STATUS); + IWL_CMD(CSR_GPIO_IN); + IWL_CMD(CSR_RESET); + IWL_CMD(CSR_GP_CNTRL); + IWL_CMD(CSR_HW_REV); + IWL_CMD(CSR_EEPROM_REG); + IWL_CMD(CSR_EEPROM_GP); + IWL_CMD(CSR_OTP_GP_REG); + IWL_CMD(CSR_GIO_REG); + IWL_CMD(CSR_GP_UCODE_REG); + IWL_CMD(CSR_GP_DRIVER_REG); + IWL_CMD(CSR_UCODE_DRV_GP1); + IWL_CMD(CSR_UCODE_DRV_GP2); + IWL_CMD(CSR_LED_REG); + IWL_CMD(CSR_DRAM_INT_TBL_REG); + IWL_CMD(CSR_GIO_CHICKEN_BITS); + IWL_CMD(CSR_ANA_PLL_CFG); + IWL_CMD(CSR_HW_REV_WA_REG); + IWL_CMD(CSR_DBG_HPET_MEM_REG); + default: + return "UNKNOWN"; + } +} + +void iwl_dump_csr(struct iwl_trans *trans) +{ + int i; + static const u32 csr_tbl[] = { + CSR_HW_IF_CONFIG_REG, + CSR_INT_COALESCING, + CSR_INT, + CSR_INT_MASK, + CSR_FH_INT_STATUS, + CSR_GPIO_IN, + CSR_RESET, + CSR_GP_CNTRL, + CSR_HW_REV, + CSR_EEPROM_REG, + CSR_EEPROM_GP, + CSR_OTP_GP_REG, + CSR_GIO_REG, + CSR_GP_UCODE_REG, + CSR_GP_DRIVER_REG, + CSR_UCODE_DRV_GP1, + CSR_UCODE_DRV_GP2, + CSR_LED_REG, + CSR_DRAM_INT_TBL_REG, + CSR_GIO_CHICKEN_BITS, + CSR_ANA_PLL_CFG, + CSR_HW_REV_WA_REG, + CSR_DBG_HPET_MEM_REG + }; + IWL_ERR(trans, "CSR values:\n"); + IWL_ERR(trans, "(2nd byte of CSR_INT_COALESCING is " + "CSR_INT_PERIODIC_REG)\n"); + for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { + IWL_ERR(trans, " %25s: 0X%08x\n", + get_csr_string(csr_tbl[i]), + iwl_read32(bus(trans), csr_tbl[i])); + } +} + #ifdef CONFIG_IWLWIFI_DEBUGFS /* create and remove of files */ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ @@ -1752,75 +1882,6 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file, return count; } -static const char *get_csr_string(int cmd) -{ - switch (cmd) { - IWL_CMD(CSR_HW_IF_CONFIG_REG); - IWL_CMD(CSR_INT_COALESCING); - IWL_CMD(CSR_INT); - IWL_CMD(CSR_INT_MASK); - IWL_CMD(CSR_FH_INT_STATUS); - IWL_CMD(CSR_GPIO_IN); - IWL_CMD(CSR_RESET); - IWL_CMD(CSR_GP_CNTRL); - IWL_CMD(CSR_HW_REV); - IWL_CMD(CSR_EEPROM_REG); - IWL_CMD(CSR_EEPROM_GP); - IWL_CMD(CSR_OTP_GP_REG); - IWL_CMD(CSR_GIO_REG); - IWL_CMD(CSR_GP_UCODE_REG); - IWL_CMD(CSR_GP_DRIVER_REG); - IWL_CMD(CSR_UCODE_DRV_GP1); - IWL_CMD(CSR_UCODE_DRV_GP2); - IWL_CMD(CSR_LED_REG); - IWL_CMD(CSR_DRAM_INT_TBL_REG); - IWL_CMD(CSR_GIO_CHICKEN_BITS); - IWL_CMD(CSR_ANA_PLL_CFG); - IWL_CMD(CSR_HW_REV_WA_REG); - IWL_CMD(CSR_DBG_HPET_MEM_REG); - default: - return "UNKNOWN"; - } -} - -void iwl_dump_csr(struct iwl_trans *trans) -{ - int i; - static const u32 csr_tbl[] = { - CSR_HW_IF_CONFIG_REG, - CSR_INT_COALESCING, - CSR_INT, - CSR_INT_MASK, - CSR_FH_INT_STATUS, - CSR_GPIO_IN, - CSR_RESET, - CSR_GP_CNTRL, - CSR_HW_REV, - CSR_EEPROM_REG, - CSR_EEPROM_GP, - CSR_OTP_GP_REG, - CSR_GIO_REG, - CSR_GP_UCODE_REG, - CSR_GP_DRIVER_REG, - CSR_UCODE_DRV_GP1, - CSR_UCODE_DRV_GP2, - CSR_LED_REG, - CSR_DRAM_INT_TBL_REG, - CSR_GIO_CHICKEN_BITS, - CSR_ANA_PLL_CFG, - CSR_HW_REV_WA_REG, - CSR_DBG_HPET_MEM_REG - }; - IWL_ERR(trans, "CSR values:\n"); - IWL_ERR(trans, "(2nd byte of CSR_INT_COALESCING is " - "CSR_INT_PERIODIC_REG)\n"); - for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { - IWL_ERR(trans, " %25s: 0X%08x\n", - get_csr_string(csr_tbl[i]), - iwl_read32(bus(trans), csr_tbl[i])); - } -} - static ssize_t iwl_dbgfs_csr_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -1842,67 +1903,6 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, return count; } -static const char *get_fh_string(int cmd) -{ - switch (cmd) { - IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); - IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); - IWL_CMD(FH_RSCSR_CHNL0_WPTR); - IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); - IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); - IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); - IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); - IWL_CMD(FH_TSSR_TX_STATUS_REG); - IWL_CMD(FH_TSSR_TX_ERROR_REG); - default: - return "UNKNOWN"; - } -} - -int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) -{ - int i; -#ifdef CONFIG_IWLWIFI_DEBUG - int pos = 0; - size_t bufsz = 0; -#endif - static const u32 fh_tbl[] = { - FH_RSCSR_CHNL0_STTS_WPTR_REG, - FH_RSCSR_CHNL0_RBDCB_BASE_REG, - FH_RSCSR_CHNL0_WPTR, - FH_MEM_RCSR_CHNL0_CONFIG_REG, - FH_MEM_RSSR_SHARED_CTRL_REG, - FH_MEM_RSSR_RX_STATUS_REG, - FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, - FH_TSSR_TX_STATUS_REG, - FH_TSSR_TX_ERROR_REG - }; -#ifdef CONFIG_IWLWIFI_DEBUG - if (display) { - bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; - *buf = kmalloc(bufsz, GFP_KERNEL); - if (!*buf) - return -ENOMEM; - pos += scnprintf(*buf + pos, bufsz - pos, - "FH register values:\n"); - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { - pos += scnprintf(*buf + pos, bufsz - pos, - " %34s: 0X%08x\n", - get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); - } - return pos; - } -#endif - IWL_ERR(trans, "FH register values:\n"); - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { - IWL_ERR(trans, " %34s: 0X%08x\n", - get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); - } - return 0; -} - static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) From 4319e193271dc93241338eb0173fc26dc6c35465 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Sep 2011 11:50:48 +0200 Subject: [PATCH 160/287] cfg80211: verify format of uAPSD information The format is intended to be like the subfields in the QoS Info field, verify that is the case. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f4cfd3abfbfd..11089541bb03 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2627,10 +2627,15 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) if (tb[NL80211_STA_WME_UAPSD_QUEUES]) params.uapsd_queues = nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]); + if (params.uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) + return -EINVAL; if (tb[NL80211_STA_WME_MAX_SP]) params.max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]); + + if (params.max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) + return -EINVAL; } if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && From 31937c423ed3a13613b3aa7459e7405dd428f2d8 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 7 Sep 2011 20:10:02 +0200 Subject: [PATCH 161/287] rt2x00: Minor optimizazion in txdone path We can save an indirect function call + some instructions for fetching the actual function pointer by passing the driver specific txwi pointer directly from rt2800pci/rt2800usb to rt2800lib instead of using the rt2800_drv_get_txwi callback. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 4 +--- drivers/net/wireless/rt2x00/rt2800lib.h | 2 +- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- drivers/net/wireless/rt2x00/rt2800usb.c | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index ef67f6786a84..6a8e92032e90 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -601,7 +601,7 @@ void rt2800_process_rxwi(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); -void rt2800_txdone_entry(struct queue_entry *entry, u32 status) +void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); @@ -609,13 +609,11 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) u32 word; u16 mcs, real_mcs; int aggr, ampdu; - __le32 *txwi; /* * Obtain the status about this packet. */ txdesc.flags = 0; - txwi = rt2800_drv_get_txwi(entry); rt2x00_desc_read(txwi, 0, &word); mcs = rt2x00_get_field32(word, TXWI_W0_MCS); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 69deb3148ae7..bef071cd911f 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -152,7 +152,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, struct txentry_desc *txdesc); void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); -void rt2800_txdone_entry(struct queue_entry *entry, u32 status); +void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32* txwi); void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); void rt2800_clear_beacon(struct queue_entry *entry); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 7586468955da..17abb0675eaf 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -760,7 +760,7 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) } entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - rt2800_txdone_entry(entry, status); + rt2800_txdone_entry(entry, status, rt2800pci_get_txwi(entry)); if (--max_tx_done == 0) break; diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 507559361d87..7917614dbd50 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -534,7 +534,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) if (!entry || rt2x00queue_empty(queue)) break; - rt2800_txdone_entry(entry, reg); + rt2800_txdone_entry(entry, reg, + rt2800usb_get_txwi(entry)); } } From 0f287b74a9cbf4bea155f5b441c9a4aa35c4b119 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 7 Sep 2011 20:10:25 +0200 Subject: [PATCH 162/287] rt2x00: Add LED_CFG register description Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index c69a7d71f4ca..4778620347c4 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -664,6 +664,9 @@ /* * LED_CFG: LED control + * ON_PERIOD: LED active time (ms) during TX (only used for LED mode 1) + * OFF_PERIOD: LED inactive time (ms) during TX (only used for LED mode 1) + * SLOW_BLINK_PERIOD: LED blink interval in seconds (only used for LED mode 2) * color LED's: * 0: off * 1: blinking upon TX2 From 550245b56c4a3746fdcbe051b4a75b60303cb531 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 7 Sep 2011 20:10:45 +0200 Subject: [PATCH 163/287] rt2x00: Remove incorrect led blink rt2800 devices are not capable of configuring arbitrary LED on/off periods. The LED_CFG register fields ON_PERIOD and OFF_PERIOD are only used by the hw when the LED mode is set to "blink upon TX". Hence, remove the blink callback. This will result in software emulation for LED blinking. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 6a8e92032e90..cdb0133afc33 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -897,28 +897,12 @@ static void rt2800_brightness_set(struct led_classdev *led_cdev, } } -static int rt2800_blink_set(struct led_classdev *led_cdev, - unsigned long *delay_on, unsigned long *delay_off) -{ - struct rt2x00_led *led = - container_of(led_cdev, struct rt2x00_led, led_dev); - u32 reg; - - rt2800_register_read(led->rt2x00dev, LED_CFG, ®); - rt2x00_set_field32(®, LED_CFG_ON_PERIOD, *delay_on); - rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, *delay_off); - rt2800_register_write(led->rt2x00dev, LED_CFG, reg); - - return 0; -} - static void rt2800_init_led(struct rt2x00_dev *rt2x00dev, struct rt2x00_led *led, enum led_type type) { led->rt2x00dev = rt2x00dev; led->type = type; led->led_dev.brightness_set = rt2800_brightness_set; - led->led_dev.blink_set = rt2800_blink_set; led->flags = LED_INITIALIZED; } #endif /* CONFIG_RT2X00_LIB_LEDS */ From 5dada06cf156b1b70dcb76de5a63349aa33b135c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 7 Sep 2011 20:11:03 +0200 Subject: [PATCH 164/287] rt2x00: Update some TX descriptor Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index f2100f4ddcff..f22aa8676cee 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -288,8 +288,8 @@ enum txentry_desc_flags { * @signal: PLCP signal. * @service: PLCP service. * @msc: MCS. - * @stbc: STBC. - * @ba_size: BA size. + * @stbc: Use Space Time Block Coding (only available for MCS rates < 8). + * @ba_size: Size of the recepients RX reorder buffer - 1. * @rate_mode: Rate mode (See @enum rate_modulation). * @mpdu_density: MDPU density. * @retry_limit: Max number of retries. From 3de3d966007592693e68a973f62a1e3828565af0 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Wed, 7 Sep 2011 20:11:26 +0200 Subject: [PATCH 165/287] rt2x00: Avoid unnecessary uncached Reading the TX desciptor words from coherent memory is always uncached and potentially slow. Hence, don't read the TX descriptor prior to writing it since we update all fields anyway. Signed-off-by: Helmut Schaa Acked-by: Gertjan van Wingerde Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 17abb0675eaf..a716d1dd0754 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -619,11 +619,11 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, /* * Initialize TX descriptor */ - rt2x00_desc_read(txd, 0, &word); + word = 0; rt2x00_set_field32(&word, TXD_W0_SD_PTR0, skbdesc->skb_dma); rt2x00_desc_write(txd, 0, word); - rt2x00_desc_read(txd, 1, &word); + word = 0; rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len); rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); @@ -634,12 +634,12 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry, rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); rt2x00_desc_write(txd, 1, word); - rt2x00_desc_read(txd, 2, &word); + word = 0; rt2x00_set_field32(&word, TXD_W2_SD_PTR1, skbdesc->skb_dma + TXWI_DESC_SIZE); rt2x00_desc_write(txd, 2, word); - rt2x00_desc_read(txd, 3, &word); + word = 0; rt2x00_set_field32(&word, TXD_W3_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W3_QSEL, 2); From 4777be41638cfab56c78b2a764a5f83beb6cfdd2 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Wed, 7 Sep 2011 17:49:52 -0700 Subject: [PATCH 166/287] mac80211: Start implementing QoS support for mesh interfaces In order to support QoS in mesh, we need to assign queue mapping only after the next hop has been resolved, both for forwarded and locally originated frames. Also, now that this is fixed, remove the XXX comment in ieee80211_select_queue(). Also, V-Shy Ho reported that the queue mapping was not being applied to the forwarded frame (fwd_skb instead of skb). Fixed that as well. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 4 ++++ net/mac80211/rx.c | 10 +++++----- net/mac80211/tx.c | 4 ++++ net/mac80211/wme.c | 6 +----- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 55a206cfb8cc..4fc8c7a5d4dd 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -14,6 +14,7 @@ #include #include #include +#include "wme.h" #include "ieee80211_i.h" #include "mesh.h" @@ -212,6 +213,7 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) struct ieee80211_hdr *hdr; struct sk_buff_head tmpq; unsigned long flags; + struct ieee80211_sub_if_data *sdata = mpath->sdata; rcu_assign_pointer(mpath->next_hop, sta); @@ -222,6 +224,8 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) { hdr = (struct ieee80211_hdr *) skb->data; memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); + skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); + ieee80211_set_qos_hdr(sdata->local, skb); __skb_queue_tail(&tmpq, skb); } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 811e3ade8c74..b1ea4444065e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1905,13 +1905,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) memset(info, 0, sizeof(*info)); info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; info->control.vif = &rx->sdata->vif; - skb_set_queue_mapping(skb, - ieee80211_select_queue(rx->sdata, fwd_skb)); - ieee80211_set_qos_hdr(local, skb); - if (is_multicast_ether_addr(fwd_hdr->addr1)) + if (is_multicast_ether_addr(fwd_hdr->addr1)) { IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, fwded_mcast); - else { + skb_set_queue_mapping(fwd_skb, + ieee80211_select_queue(sdata, fwd_skb)); + ieee80211_set_qos_hdr(local, fwd_skb); + } else { int err; /* * Save TA to addr1 to send TA a path error if a diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2521716aa97b..2a8e437165fb 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1879,6 +1879,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, rcu_read_unlock(); } + /* For mesh, the use of the QoS header is mandatory */ + if (ieee80211_vif_is_mesh(&sdata->vif)) + sta_flags |= WLAN_STA_WME; + /* receiver and we are QoS enabled, use a QoS type frame */ if ((sta_flags & WLAN_STA_WME) && local->hw.queues >= 4) { fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 7a49532f14cb..a9fee2bc6300 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -83,11 +83,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, break; #ifdef CONFIG_MAC80211_MESH case NL80211_IFTYPE_MESH_POINT: - /* - * XXX: This is clearly broken ... but already was before, - * because ieee80211_fill_mesh_addresses() would clear A1 - * except for multicast addresses. - */ + ra = skb->data; break; #endif case NL80211_IFTYPE_STATION: From 2154c81c32fa44364f83218a10d8dbec4e76d4f5 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Wed, 7 Sep 2011 17:49:53 -0700 Subject: [PATCH 167/287] mac80211: Mesh data frames must have the QoS header Per sec 7.1.3.5 of draft 12.0 of 802.11s, mesh frames indicate the presence of the mesh control header in their QoS header. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 2 ++ net/mac80211/mesh.c | 3 +-- net/mac80211/mesh_hwmp.c | 3 +-- net/mac80211/mesh_pathtbl.c | 2 +- net/mac80211/rx.c | 6 +++--- net/mac80211/tx.c | 2 +- net/mac80211/wme.c | 10 ++++++---- net/mac80211/wme.h | 3 ++- 8 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 37f95f2e10f9..72f3933938c0 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -130,6 +130,8 @@ #define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060 /* A-MSDU 802.11n */ #define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080 +/* Mesh Control 802.11s */ +#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100 /* U-APSD queue for WMM IEs sent by AP */ #define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 65acbf5eed2d..a4225ae69681 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -463,8 +463,7 @@ int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, memcpy(hdr->addr3, meshsa, ETH_ALEN); return 24; } else { - *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | - IEEE80211_FCTL_TODS); + *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); /* RA TA DA SA */ memset(hdr->addr1, 0, ETH_ALEN); /* RA is resolved later */ memcpy(hdr->addr2, meshsa, ETH_ALEN); diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 63df0bc3dba4..6df7913d7ca4 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -209,7 +209,6 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { - struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); skb_set_mac_header(skb, 0); @@ -221,7 +220,7 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, skb->priority = 7; info->control.vif = &sdata->vif; - ieee80211_set_qos_hdr(local, skb); + ieee80211_set_qos_hdr(sdata, skb); } /** diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 4fc8c7a5d4dd..332b5ff1e885 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -225,7 +225,7 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) hdr = (struct ieee80211_hdr *) skb->data; memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN); skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); - ieee80211_set_qos_hdr(sdata->local, skb); + ieee80211_set_qos_hdr(sdata, skb); __skb_queue_tail(&tmpq, skb); } diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index b1ea4444065e..db46601e50bf 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1910,7 +1910,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) fwded_mcast); skb_set_queue_mapping(fwd_skb, ieee80211_select_queue(sdata, fwd_skb)); - ieee80211_set_qos_hdr(local, fwd_skb); + ieee80211_set_qos_hdr(sdata, fwd_skb); } else { int err; /* @@ -2572,12 +2572,12 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx) CALL_RXH(ieee80211_rx_h_ps_poll) CALL_RXH(ieee80211_rx_h_michael_mic_verify) /* must be after MMIC verify so header is counted in MPDU mic */ - CALL_RXH(ieee80211_rx_h_remove_qos_control) - CALL_RXH(ieee80211_rx_h_amsdu) #ifdef CONFIG_MAC80211_MESH if (ieee80211_vif_is_mesh(&rx->sdata->vif)) CALL_RXH(ieee80211_rx_h_mesh_fwding); #endif + CALL_RXH(ieee80211_rx_h_remove_qos_control) + CALL_RXH(ieee80211_rx_h_amsdu) CALL_RXH(ieee80211_rx_h_data) CALL_RXH(ieee80211_rx_h_ctrl); CALL_RXH(ieee80211_rx_h_mgmt_check) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2a8e437165fb..7cd6c28968b2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1596,7 +1596,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, return; } - ieee80211_set_qos_hdr(local, skb); + ieee80211_set_qos_hdr(sdata, skb); ieee80211_tx(sdata, skb, false); rcu_read_unlock(); } diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index a9fee2bc6300..971004c9b04f 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -135,7 +135,8 @@ u16 ieee80211_downgrade_queue(struct ieee80211_local *local, return ieee802_1d_to_ac[skb->priority]; } -void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb) +void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) { struct ieee80211_hdr *hdr = (void *)skb->data; @@ -146,10 +147,11 @@ void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb) tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; - if (unlikely(local->wifi_wme_noack_test)) + if (unlikely(sdata->local->wifi_wme_noack_test)) ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; - /* qos header is 2 bytes, second reserved */ + /* qos header is 2 bytes */ *p++ = ack_policy | tid; - *p = 0; + *p = ieee80211_vif_is_mesh(&sdata->vif) ? + (IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8) : 0; } } diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index faead6d02026..34e166fbf4d4 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h @@ -17,7 +17,8 @@ extern const int ieee802_1d_to_ac[8]; u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); -void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb); +void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb); u16 ieee80211_downgrade_queue(struct ieee80211_local *local, struct sk_buff *skb); From 5fbdf4a2dfbc320bb8422c88c0f59b624043add1 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Wed, 7 Sep 2011 17:49:54 -0700 Subject: [PATCH 168/287] mac80211: Mark all mesh stations as QoS capable Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_plink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 1a00d0f701c3..4396906175ae 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -88,7 +88,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, if (!sta) return NULL; - sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH; + sta->flags = WLAN_STA_AUTHORIZED | WLAN_STA_AUTH | WLAN_STA_WME; sta->sta.supp_rates[local->hw.conf.channel->band] = rates; rate_control_rate_init(sta); From 1ea57b1f12c045db5fca5d1299963ca1c70983ea Mon Sep 17 00:00:00 2001 From: Shahar Levi Date: Thu, 8 Sep 2011 08:44:05 +0300 Subject: [PATCH 169/287] mac80211: Update device channel in case of HW channel switch supported The hw.conf.channel value is not updated properly for drivers that support HW channel switch. Since the switch is done entirely by the driver and we don't call ieee80211_hw_config(), this value remains untouched. This patch fixes that by setting the new channel directly in ieee80211_chswitch_work(). Signed-off-by: Shahar Levi Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index ca97b80b2651..2f92ae2f9706 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -390,6 +390,9 @@ static void ieee80211_chswitch_work(struct work_struct *work) /* call "hw_config" only if doing sw channel switch */ ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL); + } else { + /* update the device channel directly */ + sdata->local->hw.conf.channel = sdata->local->oper_channel; } /* XXX: shouldn't really modify cfg80211-owned data! */ From 183255235aadefd5a987021346e7aee2cbe721eb Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:34:22 +0200 Subject: [PATCH 170/287] rt2x00: Move bssidx calculation into its own function This will be used by a later patch. No functional changes. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 6 ++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 16 ++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00mac.c | 10 +--------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index f82bfeb79ebb..d454ec8f5c6f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1225,6 +1225,12 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, } #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ +/* + * Utility functions. + */ +u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif); + /* * Interrupt context handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 92ff6a72a2bb..634b084a6527 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -32,6 +32,22 @@ #include "rt2x00.h" #include "rt2x00lib.h" +/* + * Utility functions. + */ +u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif) +{ + /* + * When in STA mode, bssidx is always 0 otherwise local_address[5] + * contains the bss number, see BSS_ID_MASK comments for details. + */ + if (rt2x00dev->intf_sta_count) + return 0; + return vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1); +} +EXPORT_SYMBOL_GPL(rt2x00lib_get_bssidx); + /* * Radio control handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 4ccf23805973..9db9378820bf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -504,15 +504,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memset(&crypto, 0, sizeof(crypto)); - /* - * When in STA mode, bssidx is always 0 otherwise local_address[5] - * contains the bss number, see BSS_ID_MASK comments for details. - */ - if (rt2x00dev->intf_sta_count) - crypto.bssidx = 0; - else - crypto.bssidx = vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1); - + crypto.bssidx = rt2x00lib_get_bssidx(rt2x00dev, vif); crypto.cipher = rt2x00crypto_key_to_cipher(key); if (crypto.cipher == CIPHER_NONE) return -EOPNOTSUPP; From b4943d8113500ee783072ba2ba7506ad76df3726 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:36:04 +0200 Subject: [PATCH 171/287] rt2x00: Introduce sta_add/remove callbacks This implements a basic sta_add and sta_remove callback. Introduce a new structure rt2x00_sta and ask mac80211 to allocate it as private part of its ieee80211_sta. rt2x00_sta only contains the WCID for now. The sta_add callback allows the driver to assign a WCID to a station that is currently being added. The same wcid is also passed to the sta_remove callback one mac80211 removes this STA. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 22 +++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 5 ++++ drivers/net/wireless/rt2x00/rt2x00mac.c | 33 +++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index d454ec8f5c6f..3b71d792bbf5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -511,6 +511,19 @@ struct rt2x00intf_conf { __le32 bssid[2]; }; +/* + * Private structure for storing STA details + * wcid: Wireless Client ID + */ +struct rt2x00_sta { + int wcid; +}; + +static inline struct rt2x00_sta* sta_to_rt2x00_sta(struct ieee80211_sta *sta) +{ + return (struct rt2x00_sta *)sta->drv_priv; +} + /* * rt2x00lib callback functions. */ @@ -620,6 +633,11 @@ struct rt2x00lib_ops { void (*config) (struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf, const unsigned int changed_flags); + int (*sta_add) (struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + int (*sta_remove) (struct rt2x00_dev *rt2x00dev, + int wcid); }; /* @@ -1267,6 +1285,10 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, #else #define rt2x00mac_set_key NULL #endif /* CONFIG_RT2X00_LIB_CRYPTO */ +int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw); void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw); int rt2x00mac_get_stats(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 634b084a6527..e1fb2a8569be 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -930,6 +930,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; + /* + * Tell mac80211 about the size of our private STA structure. + */ + rt2x00dev->hw->sta_data_size = sizeof(struct rt2x00_sta); + /* * Allocate tx status FIFO for driver use. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 9db9378820bf..6a03f93e92ac 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -552,6 +552,39 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, EXPORT_SYMBOL_GPL(rt2x00mac_set_key); #endif /* CONFIG_RT2X00_LIB_CRYPTO */ +int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); + + /* + * If there's no space left in the device table store + * -1 as wcid but tell mac80211 everything went ok. + */ + if (rt2x00dev->ops->lib->sta_add(rt2x00dev, vif, sta)) + sta_priv->wcid = -1; + + return 0; +} +EXPORT_SYMBOL_GPL(rt2x00mac_sta_add); + +int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); + + /* + * If we never sent the STA to the device no need to clean it up. + */ + if (sta_priv->wcid < 0) + return 0; + + return rt2x00dev->ops->lib->sta_remove(rt2x00dev, sta_priv->wcid); +} +EXPORT_SYMBOL_GPL(rt2x00mac_sta_remove); + void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) { struct rt2x00_dev *rt2x00dev = hw->priv; From f03fcfc110739be5bae4f0edf33998b019ff7436 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:36:45 +0200 Subject: [PATCH 172/287] rt2x00: Add WCID to crypto struct When a WCID was already assigned to a STA the key configuration functions need to use the same WCID for configuring the keys. Hence, add the WCID to the crypo configuration structure. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 2 ++ drivers/net/wireless/rt2x00/rt2x00mac.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 3b71d792bbf5..cbf8eb334e96 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -478,6 +478,8 @@ struct rt2x00lib_crypto { u8 key[16]; u8 tx_mic[8]; u8 rx_mic[8]; + + int wcid; }; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 6a03f93e92ac..cef1c878c37e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -494,6 +494,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct rt2x00lib_crypto crypto; static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; + struct rt2x00_sta *sta_priv = NULL; if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; @@ -511,9 +512,11 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, crypto.cmd = cmd; - if (sta) + if (sta) { crypto.address = sta->addr; - else + sta_priv = sta_to_rt2x00_sta(sta); + crypto.wcid = sta_priv->wcid; + } else crypto.address = bcast_addr; if (crypto.cipher == CIPHER_TKIP) From ead2bb64a38c471ad0a769f61921f330f062dd50 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:37:19 +0200 Subject: [PATCH 173/287] rt2x00: Add WCID to HT TX descriptor When sending an unencrypted frame to a STA the driver might want to pass a suitable WCID since we don't have a key index to allow tx status reports to get properly assigned to the correct STA. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00queue.c | 7 ++++++- drivers/net/wireless/rt2x00/rt2x00queue.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 29edb9fbe6f1..5adfb3eab9cd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -310,11 +310,16 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0]; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct rt2x00_sta *sta_priv = NULL; - if (tx_info->control.sta) + if (tx_info->control.sta) { txdesc->u.ht.mpdu_density = tx_info->control.sta->ht_cap.ampdu_density; + sta_priv = sta_to_rt2x00_sta(tx_info->control.sta); + txdesc->u.ht.wcid = sta_priv->wcid; + } + txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */ /* diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index f22aa8676cee..349008d1fb28 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -321,6 +321,7 @@ struct txentry_desc { u8 ba_size; u8 mpdu_density; enum txop txop; + int wcid; } ht; } u; From a2b1328a23c57fbb9c51e6660a11049c35d151f9 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:38:01 +0200 Subject: [PATCH 174/287] rt2x00: Make use of sta_add/remove callbacks in rt2800 This allows us to assign a WCID to each STA even for STAs without crypto key. To achieve this search for an unused WCID in the HW WCID table and assign it to the according STA. When configuring a pairwise key for this STA we don't need to write the MAC address and BSSIDX anymore but just update the crypto related fields in the WCID_ATTR table. This has two advantages: 1) Setting a new key for an already available STA (PTK rekeying) is slightly less expensive and should improve performance in situations where a lot of rekeying happens (e.g. a huge number of stations and/or a small rekeying interval) 2) The TXWI now gets a WCID assigned for unencrypted frames which will be reflected in the corresponding tx status report. This should make tx status reports in unencrypted AP mode more reliable as we can distinguish between multiple key-less STAs. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 153 +++++++++++++++++++----- drivers/net/wireless/rt2x00/rt2800lib.h | 3 + drivers/net/wireless/rt2x00/rt2800pci.c | 4 + drivers/net/wireless/rt2x00/rt2800usb.c | 4 + 4 files changed, 134 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index cdb0133afc33..0e21aaf53bb4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -493,7 +493,7 @@ void rt2800_write_tx_data(struct queue_entry *entry, rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->u.ht.ba_size); rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? - txdesc->key_idx : 0xff); + txdesc->key_idx : txdesc->u.ht.wcid); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, txdesc->length); rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid); @@ -910,11 +910,51 @@ static void rt2800_init_led(struct rt2x00_dev *rt2x00dev, /* * Configuration handlers. */ -static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_crypto *crypto, - struct ieee80211_key_conf *key) +static void rt2800_config_wcid(struct rt2x00_dev *rt2x00dev, + const u8 *address, + int wcid) { struct mac_wcid_entry wcid_entry; + u32 offset; + + offset = MAC_WCID_ENTRY(wcid); + + memset(&wcid_entry, 0xff, sizeof(wcid_entry)); + if (address) + memcpy(wcid_entry.mac, address, ETH_ALEN); + + rt2800_register_multiwrite(rt2x00dev, offset, + &wcid_entry, sizeof(wcid_entry)); +} + +static void rt2800_delete_wcid_attr(struct rt2x00_dev *rt2x00dev, int wcid) +{ + u32 offset; + offset = MAC_WCID_ATTR_ENTRY(wcid); + rt2800_register_write(rt2x00dev, offset, 0); +} + +static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev, + int wcid, u32 bssidx) +{ + u32 offset = MAC_WCID_ATTR_ENTRY(wcid); + u32 reg; + + /* + * The BSS Idx numbers is split in a main value of 3 bits, + * and a extended field for adding one additional bit to the value. + */ + rt2800_register_read(rt2x00dev, offset, ®); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7)); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT, + (bssidx & 0x8) >> 3); + rt2800_register_write(rt2x00dev, offset, reg); +} + +static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev, + struct rt2x00lib_crypto *crypto, + struct ieee80211_key_conf *key) +{ struct mac_iveiv_entry iveiv_entry; u32 offset; u32 reg; @@ -934,14 +974,16 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev, (crypto->cipher & 0x7)); rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER_EXT, (crypto->cipher & 0x8) >> 3); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, - (crypto->bssidx & 0x7)); - rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT, - (crypto->bssidx & 0x8) >> 3); rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher); rt2800_register_write(rt2x00dev, offset, reg); } else { - rt2800_register_write(rt2x00dev, offset, 0); + /* Delete the cipher without touching the bssidx */ + rt2800_register_read(rt2x00dev, offset, ®); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, 0); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER, 0); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER_EXT, 0); + rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0); + rt2800_register_write(rt2x00dev, offset, reg); } offset = MAC_IVEIV_ENTRY(key->hw_key_idx); @@ -954,14 +996,6 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev, iveiv_entry.iv[3] |= key->keyidx << 6; rt2800_register_multiwrite(rt2x00dev, offset, &iveiv_entry, sizeof(iveiv_entry)); - - offset = MAC_WCID_ENTRY(key->hw_key_idx); - - memset(&wcid_entry, 0, sizeof(wcid_entry)); - if (crypto->cmd == SET_KEY) - memcpy(wcid_entry.mac, crypto->address, ETH_ALEN); - rt2800_register_multiwrite(rt2x00dev, offset, - &wcid_entry, sizeof(wcid_entry)); } int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, @@ -1008,20 +1042,24 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, /* * Update WCID information */ - rt2800_config_wcid_attr(rt2x00dev, crypto, key); + rt2800_config_wcid(rt2x00dev, crypto->address, key->hw_key_idx); + rt2800_config_wcid_attr_bssidx(rt2x00dev, key->hw_key_idx, + crypto->bssidx); + rt2800_config_wcid_attr_cipher(rt2x00dev, crypto, key); return 0; } EXPORT_SYMBOL_GPL(rt2800_config_shared_key); -static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev) +static inline int rt2800_find_wcid(struct rt2x00_dev *rt2x00dev) { + struct mac_wcid_entry wcid_entry; int idx; - u32 offset, reg; + u32 offset; /* - * Search for the first free pairwise key entry and return the - * corresponding index. + * Search for the first free WCID entry and return the corresponding + * index. * * Make sure the WCID starts _after_ the last possible shared key * entry (>32). @@ -1031,11 +1069,17 @@ static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev) * first 222 entries. */ for (idx = 33; idx <= 222; idx++) { - offset = MAC_WCID_ATTR_ENTRY(idx); - rt2800_register_read(rt2x00dev, offset, ®); - if (!reg) + offset = MAC_WCID_ENTRY(idx); + rt2800_register_multiread(rt2x00dev, offset, &wcid_entry, + sizeof(wcid_entry)); + if (is_broadcast_ether_addr(wcid_entry.mac)) return idx; } + + /* + * Use -1 to indicate that we don't have any more space in the WCID + * table. + */ return -1; } @@ -1045,13 +1089,15 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, { struct hw_key_entry key_entry; u32 offset; - int idx; if (crypto->cmd == SET_KEY) { - idx = rt2800_find_pairwise_keyslot(rt2x00dev); - if (idx < 0) + /* + * Allow key configuration only for STAs that are + * known by the hw. + */ + if (crypto->wcid < 0) return -ENOSPC; - key->hw_key_idx = idx; + key->hw_key_idx = crypto->wcid; memcpy(key_entry.key, crypto->key, sizeof(key_entry.key)); @@ -1068,12 +1114,59 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, /* * Update WCID information */ - rt2800_config_wcid_attr(rt2x00dev, crypto, key); + rt2800_config_wcid_attr_cipher(rt2x00dev, crypto, key); return 0; } EXPORT_SYMBOL_GPL(rt2800_config_pairwise_key); +int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + int wcid; + struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); + + /* + * Find next free WCID. + */ + wcid = rt2800_find_wcid(rt2x00dev); + + /* + * Store selected wcid even if it is invalid so that we can + * later decide if the STA is uploaded into the hw. + */ + sta_priv->wcid = wcid; + + /* + * No space left in the device, however, we can still communicate + * with the STA -> No error. + */ + if (wcid < 0) + return 0; + + /* + * Clean up WCID attributes and write STA address to the device. + */ + rt2800_delete_wcid_attr(rt2x00dev, wcid); + rt2800_config_wcid(rt2x00dev, sta->addr, wcid); + rt2800_config_wcid_attr_bssidx(rt2x00dev, wcid, + rt2x00lib_get_bssidx(rt2x00dev, vif)); + return 0; +} +EXPORT_SYMBOL_GPL(rt2800_sta_add); + +int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid) +{ + /* + * Remove WCID entry, no need to clean the attributes as they will + * get renewed when the WCID is reused. + */ + rt2800_config_wcid(rt2x00dev, NULL, wcid); + + return 0; +} +EXPORT_SYMBOL_GPL(rt2800_sta_remove); + void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, const unsigned int filter_flags) { diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index bef071cd911f..7a2511f6785c 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -166,6 +166,9 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_crypto *crypto, struct ieee80211_key_conf *key); +int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid); void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, const unsigned int filter_flags); void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index a716d1dd0754..da48c8ac27bd 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1015,6 +1015,8 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = { .get_stats = rt2x00mac_get_stats, .get_tkip_seq = rt2800_get_tkip_seq, .set_rts_threshold = rt2800_set_rts_threshold, + .sta_add = rt2x00mac_sta_add, + .sta_remove = rt2x00mac_sta_remove, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2800_conf_tx, .get_tsf = rt2800_get_tsf, @@ -1076,6 +1078,8 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .config_erp = rt2800_config_erp, .config_ant = rt2800_config_ant, .config = rt2800_config, + .sta_add = rt2800_sta_add, + .sta_remove = rt2800_sta_remove, }; static const struct data_queue_desc rt2800pci_queue_rx = { diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 7917614dbd50..4b907a53f97c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -750,6 +750,8 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = { .get_stats = rt2x00mac_get_stats, .get_tkip_seq = rt2800_get_tkip_seq, .set_rts_threshold = rt2800_set_rts_threshold, + .sta_add = rt2x00mac_sta_add, + .sta_remove = rt2x00mac_sta_remove, .bss_info_changed = rt2x00mac_bss_info_changed, .conf_tx = rt2800_conf_tx, .get_tsf = rt2800_get_tsf, @@ -807,6 +809,8 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .config_erp = rt2800_config_erp, .config_ant = rt2800_config_ant, .config = rt2800_config, + .sta_add = rt2800_sta_add, + .sta_remove = rt2800_sta_remove, }; static const struct data_queue_desc rt2800usb_queue_rx = { From af35323db6a177514ef6c77b961bf9db31648cd9 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:38:36 +0200 Subject: [PATCH 175/287] rt2x00: Forbid aggregation for STAs not programmed into the hw If a STA is not known by the hw (i.e. has no WCID assigned) don't allow aggregation since this might mess up tx status reports and we won't be able to distinguish the reports of multiple WCID-less STAs. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 0e21aaf53bb4..9ff58231abcd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4484,8 +4484,19 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { + struct rt2x00_sta *sta_priv = (struct rt2x00_sta *)sta->drv_priv; int ret = 0; + /* + * Don't allow aggregation for stations the hardware isn't aware + * of because tx status reports for frames to an unknown station + * always contain wcid=255 and thus we can't distinguish between + * multiple stations which leads to unwanted situations when the + * hw reorders frames due to aggregation. + */ + if (sta_priv->wcid < 0) + return 1; + switch (action) { case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_STOP: From d7d259d3a5e5975b8d0b67759f2632fbd0d508d2 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:39:04 +0200 Subject: [PATCH 176/287] rt2x00: Use the available helper functions to initialize the WCID table Use rt2800_config_wcid and rt2800_delete_wcid_attr to initialize the WCID table instead of writing to the registers directly. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 9ff58231abcd..a5ddb39ca4a0 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2846,11 +2846,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) SHARED_KEY_MODE_ENTRY(i), 0); for (i = 0; i < 256; i++) { - static const u32 wcid[2] = { 0xffffffff, 0x00ffffff }; - rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), - wcid, sizeof(wcid)); - - rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 0); + rt2800_config_wcid(rt2x00dev, NULL, i); + rt2800_delete_wcid_attr(rt2x00dev, i); rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); } From fd235913f9d86fde954f7e1215bd0921ee70cb19 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 8 Sep 2011 10:16:50 -0700 Subject: [PATCH 177/287] wireless: fix kernel-doc warning in net/cfg80211.h Fix kernel-doc warning in net/cfg80211.h: Warning(include/net/cfg80211.h:1884): No description found for parameter 'registered' Signed-off-by: Randy Dunlap Signed-off-by: John W. Linville --- include/net/cfg80211.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 09024ab617f9..95980317d983 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1810,6 +1810,8 @@ struct wiphy_wowlan_support { * by default for perm_addr. In this case, the mask should be set to * all-zeroes. In this case it is assumed that the device can handle * the same number of arbitrary MAC addresses. + * @registered: protects ->resume and ->suspend sysfs callbacks against + * unregister hardware * @debugfsdir: debugfs directory used for this wiphy, will be renamed * automatically on wiphy renames * @dev: (virtual) struct device for this wiphy From 55768fa6d9462c18c1ce3c862db3bf55bac3b1c7 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Thu, 8 Sep 2011 17:35:17 -0700 Subject: [PATCH 178/287] libertas: prioritize usb8388_olpc.bin firmware on OLPC machines Normally, the v9 firmware will be loaded if it's available. However, on OLPC XO-1 machines, the olpc-specific firmware supports extra functionality. This makes the libertas driver attempt to load the custom firmware first if the machine is an OLPC machine; if that fails (or it's not an OLPC machine), fall back to attempting to load the other firmwares. usb8388_olpc.bin is currently found in the linux-firmware repository. Signed-off-by: Andres Salomon Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_usb.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 0c846f5a646a..8147f1e2a0b0 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -973,6 +973,23 @@ static const struct { { MODEL_8682, "libertas/usb8682.bin" } }; +#ifdef CONFIG_OLPC + +static int try_olpc_fw(struct if_usb_card *cardp) +{ + int retval = -ENOENT; + + /* try the OLPC firmware first; fall back to fw_table list */ + if (machine_is_olpc() && cardp->model == MODEL_8388) + retval = request_firmware(&cardp->fw, + "libertas/usb8388_olpc.bin", &cardp->udev->dev); + return retval; +} + +#else +static int try_olpc_fw(struct if_usb_card *cardp) { return -ENOENT; } +#endif /* !CONFIG_OLPC */ + static int get_fw(struct if_usb_card *cardp, const char *fwname) { int i; @@ -981,6 +998,10 @@ static int get_fw(struct if_usb_card *cardp, const char *fwname) if (fwname) return request_firmware(&cardp->fw, fwname, &cardp->udev->dev); + /* Handle OLPC firmware */ + if (try_olpc_fw(cardp) == 0) + return 0; + /* Otherwise search for firmware to use */ for (i = 0; i < ARRAY_SIZE(fw_table); i++) { if (fw_table[i].model != cardp->model) From 2d20a26a92f72e3bb658fe8ce99c3663756e9e7a Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 30 Aug 2011 15:52:18 +0200 Subject: [PATCH 179/287] Bluetooth: Fix timeout on scanning for the second time The checks for HCI_INQUIRY and HCI_MGMT were in the wrong order, so that second scans always failed. Signed-off-by: Oliver Neukum Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_event.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a40170e022e8..7ef4eb4435fb 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -58,8 +58,8 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) if (status) return; - if (test_bit(HCI_MGMT, &hdev->flags) && - test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) + if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && + test_bit(HCI_MGMT, &hdev->flags)) mgmt_discovering(hdev->id, 0); hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status); @@ -76,8 +76,8 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) if (status) return; - if (test_bit(HCI_MGMT, &hdev->flags) && - test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) + if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && + test_bit(HCI_MGMT, &hdev->flags)) mgmt_discovering(hdev->id, 0); hci_conn_check_pending(hdev); @@ -959,9 +959,8 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) return; } - if (test_bit(HCI_MGMT, &hdev->flags) && - !test_and_set_bit(HCI_INQUIRY, - &hdev->flags)) + if (!test_and_set_bit(HCI_INQUIRY, &hdev->flags) && + test_bit(HCI_MGMT, &hdev->flags)) mgmt_discovering(hdev->id, 1); } @@ -1340,8 +1339,8 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff BT_DBG("%s status %d", hdev->name, status); - if (test_bit(HCI_MGMT, &hdev->flags) && - test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) + if (test_and_clear_bit(HCI_INQUIRY, &hdev->flags) && + test_bit(HCI_MGMT, &hdev->flags)) mgmt_discovering(hdev->id, 0); hci_req_complete(hdev, HCI_OP_INQUIRY, status); From aa3d7eef398dd4f29045e9889b817d5161afe03e Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 14 Sep 2011 14:28:17 +0530 Subject: [PATCH 180/287] wireless: Reset beacon_found while updating regulatory During the association, the regulatory is updated by country IE that reaps the previously found beacons. The impact is that after a STA disconnects *or* when for any reason a regulatory domain change happens the beacon hint flag is not cleared therefore preventing future beacon hints to be learned. This is important as a regulatory domain change or a restore of regulatory settings would set back the passive scan and no-ibss flags on the channel. This is the right place to do this given that it covers any regulatory domain change. Cc: stable@kernel.org Reviewed-by: Luis R. Rodriguez Signed-off-by: Rajkumar Manoharan Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 02751dbc5a97..68a471ba193f 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -852,6 +852,7 @@ static void handle_channel(struct wiphy *wiphy, return; } + chan->beacon_found = false; chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags); chan->max_antenna_gain = min(chan->orig_mag, (int) MBI_TO_DBI(power_rule->max_antenna_gain)); From 7cabafcea793c003503a118da58da358b0692930 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 14 Sep 2011 16:47:50 +0200 Subject: [PATCH 181/287] ipw2x00: fix rtnl mutex deadlock This fix regression introduced by: commit: ecb4433550f0620f3d1471ae7099037ede30a91e Author: Stanislaw Gruszka Date: Fri Aug 12 14:00:59 2011 +0200 mac80211: fix suspend/resume races with unregister hw Above commit add rtnl_lock() into wiphy_register(), what cause deadlock when initializing ipw2x00 driver, which itself call wiphy_register() from register_netdev() internal callback with rtnl mutex taken. To fix move wiphy_register() outside register_netdev(). This solution have side effect of not creating /sys/class/net/wlanX/phy80211 link, but that's a minor issue we can live with. Bisected-by: Witold Baryluk Bisected-by: Michael Witten Tested-by: Witold Baryluk Tested-by: Michael Witten Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/ipw2x00/ipw2100.c | 21 +++++++++----- drivers/net/wireless/ipw2x00/ipw2200.c | 39 +++++++++++++++++--------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 3774dd034746..ef9ad79d1bfd 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1901,17 +1901,19 @@ static void ipw2100_down(struct ipw2100_priv *priv) /* Called by register_netdev() */ static int ipw2100_net_init(struct net_device *dev) +{ + struct ipw2100_priv *priv = libipw_priv(dev); + + return ipw2100_up(priv, 1); +} + +static int ipw2100_wdev_init(struct net_device *dev) { struct ipw2100_priv *priv = libipw_priv(dev); const struct libipw_geo *geo = libipw_get_geo(priv->ieee); struct wireless_dev *wdev = &priv->ieee->wdev; - int ret; int i; - ret = ipw2100_up(priv, 1); - if (ret) - return ret; - memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); /* fill-out priv->ieee->bg_band */ @@ -6350,9 +6352,13 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, "Error calling register_netdev.\n"); goto fail; } + registered = 1; + + err = ipw2100_wdev_init(dev); + if (err) + goto fail; mutex_lock(&priv->action_mutex); - registered = 1; IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev)); @@ -6389,7 +6395,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, fail_unlock: mutex_unlock(&priv->action_mutex); - + wiphy_unregister(priv->ieee->wdev.wiphy); + kfree(priv->ieee->bg_band.channels); fail: if (dev) { if (registered) diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 87813c33bdc2..4ffebede5e03 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11424,17 +11424,24 @@ static void ipw_bg_down(struct work_struct *work) /* Called by register_netdev() */ static int ipw_net_init(struct net_device *dev) +{ + int rc = 0; + struct ipw_priv *priv = libipw_priv(dev); + + mutex_lock(&priv->mutex); + if (ipw_up(priv)) + rc = -EIO; + mutex_unlock(&priv->mutex); + + return rc; +} + +static int ipw_wdev_init(struct net_device *dev) { int i, rc = 0; struct ipw_priv *priv = libipw_priv(dev); const struct libipw_geo *geo = libipw_get_geo(priv->ieee); struct wireless_dev *wdev = &priv->ieee->wdev; - mutex_lock(&priv->mutex); - - if (ipw_up(priv)) { - rc = -EIO; - goto out; - } memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); @@ -11519,13 +11526,9 @@ static int ipw_net_init(struct net_device *dev) set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); /* With that information in place, we can now register the wiphy... */ - if (wiphy_register(wdev->wiphy)) { + if (wiphy_register(wdev->wiphy)) rc = -EIO; - goto out; - } - out: - mutex_unlock(&priv->mutex); return rc; } @@ -11832,14 +11835,22 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, goto out_remove_sysfs; } + err = ipw_wdev_init(net_dev); + if (err) { + IPW_ERROR("failed to register wireless device\n"); + goto out_unregister_netdev; + } + #ifdef CONFIG_IPW2200_PROMISCUOUS if (rtap_iface) { err = ipw_prom_alloc(priv); if (err) { IPW_ERROR("Failed to register promiscuous network " "device (error %d).\n", err); - unregister_netdev(priv->net_dev); - goto out_remove_sysfs; + wiphy_unregister(priv->ieee->wdev.wiphy); + kfree(priv->ieee->a_band.channels); + kfree(priv->ieee->bg_band.channels); + goto out_unregister_netdev; } } #endif @@ -11851,6 +11862,8 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, return 0; + out_unregister_netdev: + unregister_netdev(priv->net_dev); out_remove_sysfs: sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); out_release_irq: From d331eb51e4d4190b2178c30fcafea54a94a577e8 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 14 Sep 2011 16:50:22 -0500 Subject: [PATCH 182/287] rt2800pci: Fix compiler error on PowerPC Using gcc 4.4.5 on a Powerbook G4 with a PPC cpu, a complicated if statement results in incorrect flow, whereas the equivalent switch statement works correctly. Signed-off-by: Larry Finger Cc: stable Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 30 ++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index ef67f6786a84..23568af4941d 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3870,19 +3870,23 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) return -ENODEV; } - if (!rt2x00_rf(rt2x00dev, RF2820) && - !rt2x00_rf(rt2x00dev, RF2850) && - !rt2x00_rf(rt2x00dev, RF2720) && - !rt2x00_rf(rt2x00dev, RF2750) && - !rt2x00_rf(rt2x00dev, RF3020) && - !rt2x00_rf(rt2x00dev, RF2020) && - !rt2x00_rf(rt2x00dev, RF3021) && - !rt2x00_rf(rt2x00dev, RF3022) && - !rt2x00_rf(rt2x00dev, RF3052) && - !rt2x00_rf(rt2x00dev, RF3320) && - !rt2x00_rf(rt2x00dev, RF5370) && - !rt2x00_rf(rt2x00dev, RF5390)) { - ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); + switch (rt2x00dev->chip.rf) { + case RF2820: + case RF2850: + case RF2720: + case RF2750: + case RF3020: + case RF2020: + case RF3021: + case RF3022: + case RF3052: + case RF3320: + case RF5370: + case RF5390: + break; + default: + ERROR(rt2x00dev, "Invalid RF chipset 0x%x detected.\n", + rt2x00dev->chip.rf); return -ENODEV; } From daabead1c32f331edcfb255fd973411c667977e8 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 14 Sep 2011 16:50:23 -0500 Subject: [PATCH 183/287] rtl2800usb: Fix incorrect storage of MAC address on big-endian platforms The eeprom data is stored in little-endian order in the rt2x00 library. As it was converted to cpu order in the read routines, the data need to be converted to LE on a big-endian platform. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 23568af4941d..0019dfd8fb01 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -3697,14 +3697,15 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®); /* Apparently the data is read from end to start */ - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, - (u32 *)&rt2x00dev->eeprom[i]); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, - (u32 *)&rt2x00dev->eeprom[i + 2]); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, - (u32 *)&rt2x00dev->eeprom[i + 4]); - rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, - (u32 *)&rt2x00dev->eeprom[i + 6]); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); + /* The returned value is in CPU order, but eeprom is le */ + rt2x00dev->eeprom[i] = cpu_to_le32(reg); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); + *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); + *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, ®); + *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg); mutex_unlock(&rt2x00dev->csr_mutex); } From 3965ac00204e0ccd89e1e73ead4d2098dc8f7bd1 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 15 Sep 2011 15:12:29 +0530 Subject: [PATCH 184/287] wireless: Fix rate mask for scan request The scan request received from cfg80211_connect do not have proper rate mast. So the probe request sent on each channel do not have proper the supported rates ie. Cc: stable@kernel.org Reviewed-by: Johannes Berg Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- net/wireless/sme.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index b7b6ff8be553..dec0fa28372e 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -118,6 +118,8 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) i++, j++) request->channels[i] = &wdev->wiphy->bands[band]->channels[j]; + request->rates[band] = + (1 << wdev->wiphy->bands[band]->n_bitrates) - 1; } } request->n_channels = n_channels; From 2249b011432ca3dcce112f0f71e0f531b4bb9347 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Thu, 15 Sep 2011 08:36:22 -0700 Subject: [PATCH 185/287] iwlagn: workaround bug crashing some APs This patch reverts commit 9b7688328422b88a7a15dc0dc123ad9ab1a6e22d which was introduced in 2.6.38-rc1. It works around a problem where the iwlagn driver stimulates a bug crashing (requiring power cycle to recover) some APs under heavy traffic. CC: stable@kernel.org #2.6.39, #3.0.0 #3.1.0 Signed-off-by: Don Fry SIgned-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b0ae4de7f083..f9c3cd95d614 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2140,7 +2140,12 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_REPORTS_TX_ACK_STATUS; + /* + * Including the following line will crash some AP's. This + * workaround removes the stimulus which causes the crash until + * the AP software can be fixed. hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + */ hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; From 910868db3f114df32387a9c51a729b2645febe4d Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 11 Sep 2011 09:46:55 +0300 Subject: [PATCH 186/287] nl80211/cfg80211/mac80211: fix wme docs Add/fix some missing docs. Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- include/linux/nl80211.h | 6 ++++-- include/net/cfg80211.h | 4 ++++ include/net/mac80211.h | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 8aa7badc1966..f17307590e61 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -2541,8 +2541,10 @@ enum nl80211_hidden_ssid { /** * enum nl80211_sta_wme_attr - station WME attributes * @__NL80211_STA_WME_INVALID: invalid number for nested attribute - * @NL80211_STA_WME_QUEUES: bitmap of uapsd queues. - * @NL80211_STA_WME_MAX_SP: max service period. + * @NL80211_STA_WME_UAPSD_QUEUES: bitmap of uapsd queues. the format + * is the same as the AC bitmap in the QoS info field. + * @NL80211_STA_WME_MAX_SP: max service period. the format is the same + * as the MAX_SP field in the QoS info field (but already shifted down). * @__NL80211_STA_WME_AFTER_LAST: internal * @NL80211_STA_WME_MAX: highest station WME attribute */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 95980317d983..b42136a61f3a 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -441,6 +441,10 @@ enum plink_actions { * @plink_action: plink action to take * @plink_state: set the peer link state for a station * @ht_capa: HT capabilities of station + * @uapsd_queues: bitmap of queues configured for uapsd. same format + * as the AC bitmap in the QoS info field + * @max_sp: max Service Period. same format as the MAX_SP in the + * QoS info field (but already shifted down) */ struct station_parameters { u8 *supported_rates; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 643e1291a1e8..9edba09547e4 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -955,6 +955,9 @@ enum set_key_cmd { * @wme: indicates whether the STA supports WME. Only valid during AP-mode. * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *), size is determined in hw information. + * @uapsd_queues: bitmap of queues configured for uapsd. Only valid + * if wme is supported. + * @max_sp: max Service Period. Only valid if wme is supported. */ struct ieee80211_sta { u32 supp_rates[IEEE80211_NUM_BANDS]; From ce407afc1008a67969ae05717e86dcee9ce5de76 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 13 Sep 2011 22:38:16 +0530 Subject: [PATCH 187/287] ath9k_hw: Add initvals and register definitions for AR946/8x chipsets. Add initvals and register modifications required to support AR946/8x chipsets. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 75 +- .../wireless/ath/ath9k/ar9480_1p0_initvals.h | 1833 ++++++++++++++++ .../wireless/ath/ath9k/ar9480_2p0_initvals.h | 1928 +++++++++++++++++ drivers/net/wireless/ath/ath9k/hw.h | 4 + drivers/net/wireless/ath/ath9k/mac.h | 1 + drivers/net/wireless/ath/ath9k/reg.h | 60 +- 6 files changed, 3883 insertions(+), 18 deletions(-) create mode 100644 drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h create mode 100644 drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 3aca9fa2d27b..05f6538416ce 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -581,6 +581,9 @@ #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \ (AR_SREV_9485(ah) ? \ 0x3d0 : 0x450) + ((_i) << 2)) +#define AR_PHY_RTT_CTRL (AR_SM_BASE + 0x380) +#define AR_PHY_RTT_TABLE_SW_INTF_B (AR_SM_BASE + 0x384) +#define AR_PHY_RTT_TABLE_SW_INTF_1_B0 (AR_SM_BASE + 0x388) #define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0) #define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4) @@ -600,6 +603,17 @@ #define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00 #define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8 +/* AIC Registers */ +#define AR_PHY_AIC_CTRL_0_B0 (AR_SM_BASE + 0x4b0) +#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4) +#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8) +#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc) +#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \ + 0x4c0 : 0x4c4)) +#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \ + 0x4c4 : 0x4c8)) +#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) +#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) #define AR_PHY_65NM_CH0_SYNTH4 0x1608c #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 @@ -609,7 +623,10 @@ #define AR_PHY_65NM_CH0_BIAS2 0x160c4 #define AR_PHY_65NM_CH0_BIAS4 0x160cc #define AR_PHY_65NM_CH0_RXTX4 0x1610c -#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : 0x1628c) + + +#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ + (AR_SREV_9485(ah) ? 0x1628c : 0x16294)) #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 @@ -625,21 +642,23 @@ #define AR_PHY_65NM_CH2_RXTX1 0x16900 #define AR_PHY_65NM_CH2_RXTX2 0x16904 -#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : 0x16284) +#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ + (AR_SREV_9485(ah) ? 0x16284 : 0x16290)) #define AR_CH0_TOP2_XPABIASLVL 0xf000 #define AR_CH0_TOP2_XPABIASLVL_S 12 -#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : 0x16290) +#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ + (AR_SREV_9485(ah) ? 0x16290 : 0x16298)) #define AR_CH0_XTAL_CAPINDAC 0x7f000000 #define AR_CH0_XTAL_CAPINDAC_S 24 #define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 #define AR_CH0_XTAL_CAPOUTDAC_S 17 -#define AR_PHY_PMU1 0x16c40 +#define AR_PHY_PMU1 (AR_SREV_9480(ah) ? 0x16340 : 0x16c40) #define AR_PHY_PMU1_PWD 0x1 #define AR_PHY_PMU1_PWD_S 0 -#define AR_PHY_PMU2 0x16c44 +#define AR_PHY_PMU2 (AR_SREV_9480(ah) ? 0x16344 : 0x16c44) #define AR_PHY_PMU2_PGM 0x00200000 #define AR_PHY_PMU2_PGM_S 21 @@ -839,19 +858,38 @@ */ #define AR_SM1_BASE 0xb200 -#define AR_PHY_SWITCH_CHAIN_1 (AR_SM1_BASE + 0x84) -#define AR_PHY_FCAL_2_1 (AR_SM1_BASE + 0xd0) -#define AR_PHY_DFT_TONE_CTL_1 (AR_SM1_BASE + 0xd4) -#define AR_PHY_CL_TAB_1 (AR_SM1_BASE + 0x100) -#define AR_PHY_CHAN_INFO_GAIN_1 (AR_SM1_BASE + 0x180) -#define AR_PHY_TPC_4_B1 (AR_SM1_BASE + 0x204) -#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) -#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) -#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) -#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) +#define AR_PHY_SWITCH_CHAIN_1 (AR_SM1_BASE + 0x84) +#define AR_PHY_FCAL_2_1 (AR_SM1_BASE + 0xd0) +#define AR_PHY_DFT_TONE_CTL_1 (AR_SM1_BASE + 0xd4) +#define AR_PHY_CL_TAB_1 (AR_SM1_BASE + 0x100) +#define AR_PHY_CHAN_INFO_GAIN_1 (AR_SM1_BASE + 0x180) +#define AR_PHY_TPC_4_B1 (AR_SM1_BASE + 0x204) +#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) +#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) +#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) +#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9300(ah) ? \ + 0x240 : 0x280)) +#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240) +#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff +#define AR_PHY_TPC_19_B1_ALPHA_THERM_S 0 #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) #define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) +/* SM 1 AIC Registers */ + +#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0) +#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4) +#define AR_PHY_AIC_CTRL_2_B1 (AR_SM1_BASE + 0x4b8) +#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \ + 0x4c0 : 0x4c4)) +#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \ + 0x4c4 : 0x4c8)) +#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0) +#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc) + +#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0) +#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4) + /* * Channel 2 Register Map */ @@ -914,6 +952,13 @@ #define AR_PHY_RSSI_3 (AR_AGC3_BASE + 0x180) +/* GLB Registers */ +#define AR_GLB_BASE 0x20000 +#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44) +#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \ + (AR_SREV_9480_20(_ah) ? 0x4c : 0x50)) +#define AR_GLB_STATUS (AR_GLB_BASE + 0x48) + /* * Misc helper defines */ diff --git a/drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h new file mode 100644 index 000000000000..4071bd2bd03f --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h @@ -0,0 +1,1833 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INITVALS_9480_1P0_H +#define INITVALS_9480_1P0_H + +/* AR9480 1.0 */ + +static const u32 ar9480_1p0_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00060085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00001810, 0x0f000003}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00080000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008050, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c20}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00005}, + {0x000080d8, 0x00400002}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486e00}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x99c00010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x0000001f}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0xffff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xaa48105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; + +static const u32 ar9480_1p0_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; + +static const u32 ar9480_1p0_sys3ant[][2] = { + /* Addr allmodes */ + {0x00063280, 0x00040807}, + {0x00063284, 0x104ccccc}, +}; + +static const u32 ar9480_pcie_phy_clkreq_enable_L1_1p0[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10053e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000580c}, +}; + +static const u32 ar9480_1p0_mac_core_emulation[][2] = { + /* Addr allmodes */ + {0x00000030, 0x00060085}, + {0x00000044, 0x00000008}, + {0x0000805c, 0xffffc7ff}, + {0x00008344, 0xaa4a105b}, +}; + +static const u32 ar9480_common_rx_gain_table_ar9280_2p0_1p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x02000101}, + {0x0000a004, 0x02000102}, + {0x0000a008, 0x02000103}, + {0x0000a00c, 0x02000104}, + {0x0000a010, 0x02000200}, + {0x0000a014, 0x02000201}, + {0x0000a018, 0x02000202}, + {0x0000a01c, 0x02000203}, + {0x0000a020, 0x02000204}, + {0x0000a024, 0x02000205}, + {0x0000a028, 0x02000208}, + {0x0000a02c, 0x02000302}, + {0x0000a030, 0x02000303}, + {0x0000a034, 0x02000304}, + {0x0000a038, 0x02000400}, + {0x0000a03c, 0x02010300}, + {0x0000a040, 0x02010301}, + {0x0000a044, 0x02010302}, + {0x0000a048, 0x02000500}, + {0x0000a04c, 0x02010400}, + {0x0000a050, 0x02020300}, + {0x0000a054, 0x02020301}, + {0x0000a058, 0x02020302}, + {0x0000a05c, 0x02020303}, + {0x0000a060, 0x02020400}, + {0x0000a064, 0x02030300}, + {0x0000a068, 0x02030301}, + {0x0000a06c, 0x02030302}, + {0x0000a070, 0x02030303}, + {0x0000a074, 0x02030400}, + {0x0000a078, 0x02040300}, + {0x0000a07c, 0x02040301}, + {0x0000a080, 0x02040302}, + {0x0000a084, 0x02040303}, + {0x0000a088, 0x02030500}, + {0x0000a08c, 0x02040400}, + {0x0000a090, 0x02050203}, + {0x0000a094, 0x02050204}, + {0x0000a098, 0x02050205}, + {0x0000a09c, 0x02040500}, + {0x0000a0a0, 0x02050301}, + {0x0000a0a4, 0x02050302}, + {0x0000a0a8, 0x02050303}, + {0x0000a0ac, 0x02050400}, + {0x0000a0b0, 0x02050401}, + {0x0000a0b4, 0x02050402}, + {0x0000a0b8, 0x02050403}, + {0x0000a0bc, 0x02050500}, + {0x0000a0c0, 0x02050501}, + {0x0000a0c4, 0x02050502}, + {0x0000a0c8, 0x02050503}, + {0x0000a0cc, 0x02050504}, + {0x0000a0d0, 0x02050600}, + {0x0000a0d4, 0x02050601}, + {0x0000a0d8, 0x02050602}, + {0x0000a0dc, 0x02050603}, + {0x0000a0e0, 0x02050604}, + {0x0000a0e4, 0x02050700}, + {0x0000a0e8, 0x02050701}, + {0x0000a0ec, 0x02050702}, + {0x0000a0f0, 0x02050703}, + {0x0000a0f4, 0x02050704}, + {0x0000a0f8, 0x02050705}, + {0x0000a0fc, 0x02050708}, + {0x0000a100, 0x02050709}, + {0x0000a104, 0x0205070a}, + {0x0000a108, 0x0205070b}, + {0x0000a10c, 0x0205070c}, + {0x0000a110, 0x0205070d}, + {0x0000a114, 0x02050710}, + {0x0000a118, 0x02050711}, + {0x0000a11c, 0x02050712}, + {0x0000a120, 0x02050713}, + {0x0000a124, 0x02050714}, + {0x0000a128, 0x02050715}, + {0x0000a12c, 0x02050730}, + {0x0000a130, 0x02050731}, + {0x0000a134, 0x02050732}, + {0x0000a138, 0x02050733}, + {0x0000a13c, 0x02050734}, + {0x0000a140, 0x02050735}, + {0x0000a144, 0x02050750}, + {0x0000a148, 0x02050751}, + {0x0000a14c, 0x02050752}, + {0x0000a150, 0x02050753}, + {0x0000a154, 0x02050754}, + {0x0000a158, 0x02050755}, + {0x0000a15c, 0x02050770}, + {0x0000a160, 0x02050771}, + {0x0000a164, 0x02050772}, + {0x0000a168, 0x02050773}, + {0x0000a16c, 0x02050774}, + {0x0000a170, 0x02050775}, + {0x0000a174, 0x00000776}, + {0x0000a178, 0x00000776}, + {0x0000a17c, 0x00000776}, + {0x0000a180, 0x00000776}, + {0x0000a184, 0x00000776}, + {0x0000a188, 0x00000776}, + {0x0000a18c, 0x00000776}, + {0x0000a190, 0x00000776}, + {0x0000a194, 0x00000776}, + {0x0000a198, 0x00000776}, + {0x0000a19c, 0x00000776}, + {0x0000a1a0, 0x00000776}, + {0x0000a1a4, 0x00000776}, + {0x0000a1a8, 0x00000776}, + {0x0000a1ac, 0x00000776}, + {0x0000a1b0, 0x00000776}, + {0x0000a1b4, 0x00000776}, + {0x0000a1b8, 0x00000776}, + {0x0000a1bc, 0x00000776}, + {0x0000a1c0, 0x00000776}, + {0x0000a1c4, 0x00000776}, + {0x0000a1c8, 0x00000776}, + {0x0000a1cc, 0x00000776}, + {0x0000a1d0, 0x00000776}, + {0x0000a1d4, 0x00000776}, + {0x0000a1d8, 0x00000776}, + {0x0000a1dc, 0x00000776}, + {0x0000a1e0, 0x00000776}, + {0x0000a1e4, 0x00000776}, + {0x0000a1e8, 0x00000776}, + {0x0000a1ec, 0x00000776}, + {0x0000a1f0, 0x00000776}, + {0x0000a1f4, 0x00000776}, + {0x0000a1f8, 0x00000776}, + {0x0000a1fc, 0x00000776}, + {0x0000b000, 0x02000101}, + {0x0000b004, 0x02000102}, + {0x0000b008, 0x02000103}, + {0x0000b00c, 0x02000104}, + {0x0000b010, 0x02000200}, + {0x0000b014, 0x02000201}, + {0x0000b018, 0x02000202}, + {0x0000b01c, 0x02000203}, + {0x0000b020, 0x02000204}, + {0x0000b024, 0x02000205}, + {0x0000b028, 0x02000208}, + {0x0000b02c, 0x02000302}, + {0x0000b030, 0x02000303}, + {0x0000b034, 0x02000304}, + {0x0000b038, 0x02000400}, + {0x0000b03c, 0x02010300}, + {0x0000b040, 0x02010301}, + {0x0000b044, 0x02010302}, + {0x0000b048, 0x02000500}, + {0x0000b04c, 0x02010400}, + {0x0000b050, 0x02020300}, + {0x0000b054, 0x02020301}, + {0x0000b058, 0x02020302}, + {0x0000b05c, 0x02020303}, + {0x0000b060, 0x02020400}, + {0x0000b064, 0x02030300}, + {0x0000b068, 0x02030301}, + {0x0000b06c, 0x02030302}, + {0x0000b070, 0x02030303}, + {0x0000b074, 0x02030400}, + {0x0000b078, 0x02040300}, + {0x0000b07c, 0x02040301}, + {0x0000b080, 0x02040302}, + {0x0000b084, 0x02040303}, + {0x0000b088, 0x02030500}, + {0x0000b08c, 0x02040400}, + {0x0000b090, 0x02050203}, + {0x0000b094, 0x02050204}, + {0x0000b098, 0x02050205}, + {0x0000b09c, 0x02040500}, + {0x0000b0a0, 0x02050301}, + {0x0000b0a4, 0x02050302}, + {0x0000b0a8, 0x02050303}, + {0x0000b0ac, 0x02050400}, + {0x0000b0b0, 0x02050401}, + {0x0000b0b4, 0x02050402}, + {0x0000b0b8, 0x02050403}, + {0x0000b0bc, 0x02050500}, + {0x0000b0c0, 0x02050501}, + {0x0000b0c4, 0x02050502}, + {0x0000b0c8, 0x02050503}, + {0x0000b0cc, 0x02050504}, + {0x0000b0d0, 0x02050600}, + {0x0000b0d4, 0x02050601}, + {0x0000b0d8, 0x02050602}, + {0x0000b0dc, 0x02050603}, + {0x0000b0e0, 0x02050604}, + {0x0000b0e4, 0x02050700}, + {0x0000b0e8, 0x02050701}, + {0x0000b0ec, 0x02050702}, + {0x0000b0f0, 0x02050703}, + {0x0000b0f4, 0x02050704}, + {0x0000b0f8, 0x02050705}, + {0x0000b0fc, 0x02050708}, + {0x0000b100, 0x02050709}, + {0x0000b104, 0x0205070a}, + {0x0000b108, 0x0205070b}, + {0x0000b10c, 0x0205070c}, + {0x0000b110, 0x0205070d}, + {0x0000b114, 0x02050710}, + {0x0000b118, 0x02050711}, + {0x0000b11c, 0x02050712}, + {0x0000b120, 0x02050713}, + {0x0000b124, 0x02050714}, + {0x0000b128, 0x02050715}, + {0x0000b12c, 0x02050730}, + {0x0000b130, 0x02050731}, + {0x0000b134, 0x02050732}, + {0x0000b138, 0x02050733}, + {0x0000b13c, 0x02050734}, + {0x0000b140, 0x02050735}, + {0x0000b144, 0x02050750}, + {0x0000b148, 0x02050751}, + {0x0000b14c, 0x02050752}, + {0x0000b150, 0x02050753}, + {0x0000b154, 0x02050754}, + {0x0000b158, 0x02050755}, + {0x0000b15c, 0x02050770}, + {0x0000b160, 0x02050771}, + {0x0000b164, 0x02050772}, + {0x0000b168, 0x02050773}, + {0x0000b16c, 0x02050774}, + {0x0000b170, 0x02050775}, + {0x0000b174, 0x00000776}, + {0x0000b178, 0x00000776}, + {0x0000b17c, 0x00000776}, + {0x0000b180, 0x00000776}, + {0x0000b184, 0x00000776}, + {0x0000b188, 0x00000776}, + {0x0000b18c, 0x00000776}, + {0x0000b190, 0x00000776}, + {0x0000b194, 0x00000776}, + {0x0000b198, 0x00000776}, + {0x0000b19c, 0x00000776}, + {0x0000b1a0, 0x00000776}, + {0x0000b1a4, 0x00000776}, + {0x0000b1a8, 0x00000776}, + {0x0000b1ac, 0x00000776}, + {0x0000b1b0, 0x00000776}, + {0x0000b1b4, 0x00000776}, + {0x0000b1b8, 0x00000776}, + {0x0000b1bc, 0x00000776}, + {0x0000b1c0, 0x00000776}, + {0x0000b1c4, 0x00000776}, + {0x0000b1c8, 0x00000776}, + {0x0000b1cc, 0x00000776}, + {0x0000b1d0, 0x00000776}, + {0x0000b1d4, 0x00000776}, + {0x0000b1d8, 0x00000776}, + {0x0000b1dc, 0x00000776}, + {0x0000b1e0, 0x00000776}, + {0x0000b1e4, 0x00000776}, + {0x0000b1e8, 0x00000776}, + {0x0000b1ec, 0x00000776}, + {0x0000b1f0, 0x00000776}, + {0x0000b1f4, 0x00000776}, + {0x0000b1f8, 0x00000776}, + {0x0000b1fc, 0x00000776}, +}; + +static const u32 ar9200_ar9280_2p0_radio_core_1p0[][2] = { + /* Addr allmodes */ + {0x00007800, 0x00040000}, + {0x00007804, 0xdb005012}, + {0x00007808, 0x04924914}, + {0x0000780c, 0x21084210}, + {0x00007810, 0x6d801300}, + {0x00007814, 0x0019beff}, + {0x00007818, 0x07e41000}, + {0x0000781c, 0x00392000}, + {0x00007820, 0x92592480}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb005012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x6d801300}, + {0x00007838, 0x0019beff}, + {0x0000783c, 0x07e40000}, + {0x00007840, 0x00392000}, + {0x00007844, 0x92592480}, + {0x00007848, 0x00100000}, + {0x0000784c, 0x773f0567}, + {0x00007850, 0x54214514}, + {0x00007854, 0x12035828}, + {0x00007858, 0x92592692}, + {0x0000785c, 0x00000000}, + {0x00007860, 0x56400000}, + {0x00007864, 0x0a8e370e}, + {0x00007868, 0xc0102850}, + {0x0000786c, 0x812d4000}, + {0x00007870, 0x807ec400}, + {0x00007874, 0x001b6db0}, + {0x00007878, 0x00376b63}, + {0x0000787c, 0x06db6db6}, + {0x00007880, 0x006d8000}, + {0x00007884, 0xffeffffe}, + {0x00007888, 0xffeffffe}, + {0x0000788c, 0x00010000}, + {0x00007890, 0x02060aeb}, + {0x00007894, 0x5a108000}, +}; + +static const u32 ar9480_1p0_baseband_postamble_emulation[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221}, + {0x00009e44, 0x005c0000, 0x005c0000, 0x005c0000, 0x005c0000}, + {0x0000a258, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x0000a25c, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a28c, 0x00011111, 0x00011111, 0x00011111, 0x00011111}, + {0x0000a2c4, 0x00148d18, 0x00148d18, 0x00148d20, 0x00148d20}, + {0x0000a2d8, 0xf999a800, 0xf999a800, 0xf999a80c, 0xf999a80c}, + {0x0000a50c, 0x0000c00a, 0x0000c00a, 0x0000c00a, 0x0000c00a}, + {0x0000a538, 0x00038e8c, 0x00038e8c, 0x00038e8c, 0x00038e8c}, + {0x0000a53c, 0x0003cecc, 0x0003cecc, 0x0003cecc, 0x0003cecc}, + {0x0000a540, 0x00040ed4, 0x00040ed4, 0x00040ed4, 0x00040ed4}, + {0x0000a544, 0x00044edc, 0x00044edc, 0x00044edc, 0x00044edc}, + {0x0000a548, 0x00048ede, 0x00048ede, 0x00048ede, 0x00048ede}, + {0x0000a54c, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, + {0x0000a550, 0x00050f5e, 0x00050f5e, 0x00050f5e, 0x00050f5e}, + {0x0000a554, 0x00054f9e, 0x00054f9e, 0x00054f9e, 0x00054f9e}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9480_pcie_phy_pll_on_clkreq_disable_L1_1p0[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10012e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000580c}, +}; + +static const u32 ar9480_common_rx_gain_table_1p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x01910190}, + {0x0000a030, 0x01930192}, + {0x0000a034, 0x01950194}, + {0x0000a038, 0x038a0196}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x22222229}, + {0x0000a084, 0x1d1d1d1d}, + {0x0000a088, 0x1d1d1d1d}, + {0x0000a08c, 0x1d1d1d1d}, + {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x2a2d2f32}, + {0x0000b084, 0x21232328}, + {0x0000b088, 0x19191c1e}, + {0x0000b08c, 0x12141417}, + {0x0000b090, 0x07070e0e}, + {0x0000b094, 0x03030305}, + {0x0000b098, 0x00000003}, + {0x0000b09c, 0x00000000}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9480_modes_high_ob_db_tx_gain_table_1p0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, + {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, + {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, + {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, + {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, + {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, + {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, + {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, + {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, + {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, + {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, + {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, +}; + +static const u32 ar9480_common_wo_xlna_rx_gain_table_1p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9480_1p0_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; + +static const u32 ar9480_1p0_mac_postamble_emulation[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8}, + {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017}, +}; + +static const u32 ar9480_1p0_tx_gain_table_baseband_postamble_emulation[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x00004002, 0x00004002, 0x00004002, 0x00004002}, + {0x0000a508, 0x00008004, 0x00008004, 0x00008004, 0x00008004}, + {0x0000a510, 0x0001000c, 0x0001000c, 0x0001000c, 0x0001000c}, + {0x0000a514, 0x0001420b, 0x0001420b, 0x0001420b, 0x0001420b}, + {0x0000a518, 0x0001824a, 0x0001824a, 0x0001824a, 0x0001824a}, + {0x0000a51c, 0x0001c44a, 0x0001c44a, 0x0001c44a, 0x0001c44a}, + {0x0000a520, 0x0002064a, 0x0002064a, 0x0002064a, 0x0002064a}, + {0x0000a524, 0x0002484a, 0x0002484a, 0x0002484a, 0x0002484a}, + {0x0000a528, 0x00028a4a, 0x00028a4a, 0x00028a4a, 0x00028a4a}, + {0x0000a52c, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, + {0x0000a530, 0x00030e4a, 0x00030e4a, 0x00030e4a, 0x00030e4a}, + {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a}, +}; + +static const u32 ar9480_1p0_radio_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, + {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24646c08, 0x24646c08}, + {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, + {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, + {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, + {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, + {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, +}; + +static const u32 ar9480_1p0_soc_postamble_emulation[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00001133, 0x00001133, 0x00001133, 0x00001133}, +}; + +static const u32 ar9480_1p0_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a9f6b}, + {0x0000980c, 0x04900000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x6400a290}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x0d000600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x32840bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098e4, 0x01ffffff}, + {0x000098e8, 0x01ffffff}, + {0x000098ec, 0x01ffffff}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0xff55ff55}, + {0x00009c08, 0x0320ff55}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x9883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c0040b}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038230c}, + {0x00009e24, 0x990bb514}, + {0x00009e28, 0x0c6f0000}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009e54, 0x64c355c7}, + {0x00009e58, 0xfd897735}, + {0x00009e5c, 0xe9198724}, + {0x00009fc0, 0x803e4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x00009fd0, 0x01193b93}, + {0x0000a20c, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0c9bd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739ce}, + {0x0000a418, 0x2d001dce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00100000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x05000080}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a458, 0x00000000}, + {0x0000a644, 0xbfad9d74}, + {0x0000a648, 0x0048060a}, + {0x0000a64c, 0x00003c37}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, + {0x0000a67c, 0x13121110}, + {0x0000a680, 0x31301514}, + {0x0000a684, 0x35343332}, + {0x0000a688, 0x00000036}, + {0x0000a690, 0x00000838}, + {0x0000a6b0, 0x0000000a}, + {0x0000a6b4, 0x28f12c01}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, + {0x0000a8d0, 0x004b6a8e}, + {0x0000a8d4, 0x00000820}, + {0x0000a8dc, 0x00000000}, + {0x0000a8f0, 0x00000000}, + {0x0000a8f4, 0x00000000}, + {0x0000b2d0, 0x00000080}, + {0x0000b2d4, 0x00000000}, + {0x0000b2ec, 0x00000000}, + {0x0000b2f0, 0x00000000}, + {0x0000b2f4, 0x00000000}, + {0x0000b2f8, 0x00000000}, + {0x0000b408, 0x0e79e5c0}, + {0x0000b40c, 0x00820820}, + {0x0000b420, 0x00000000}, + {0x0000b6b0, 0x0000000a}, + {0x0000b6b4, 0x00c00001}, +}; + +static const u32 ar9480_1p0_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, + {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, + {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, + {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c782}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x0131b7c0, 0x0131b7c4, 0x0131b7c4, 0x0131b7c0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f}, + {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, + {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, + {0x0000a288, 0x00000110, 0x00000110, 0x00100110, 0x00100110}, + {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, + {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, + {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, +}; + +static const u32 ar9480_modes_fast_clock_1p0[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, + {0x000010b0, 0x00000fd0, 0x00001fa0}, + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, + {0x00009e00, 0x0372131c, 0x0372131c}, + {0x0000a230, 0x0000400b, 0x00004016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9480_modes_low_ob_db_tx_gain_table_1p0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, + {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, + {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, + {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, + {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, + {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, + {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060}, + {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, + {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000}, +}; + +static const u32 ar9480_1p0_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, +}; + +static const u32 ar9480_common_mixed_rx_gain_table_1p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x2a2d2f32}, + {0x0000b084, 0x21232328}, + {0x0000b088, 0x19191c1e}, + {0x0000b08c, 0x12141417}, + {0x0000b090, 0x07070e0e}, + {0x0000b094, 0x03030305}, + {0x0000b098, 0x00000003}, + {0x0000b09c, 0x00000000}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9480_pcie_phy_clkreq_disable_L1_1p0[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x10013e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000580c}, +}; + +static const u32 ar9480_1p0_baseband_core_emulation[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafa68e30}, + {0x00009884, 0x00002842}, + {0x00009c04, 0xff55ff55}, + {0x00009c08, 0x0320ff55}, + {0x00009e50, 0x00000000}, + {0x00009fcc, 0x00000014}, + {0x0000a344, 0x00000010}, + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x71733d01}, + {0x0000a3a0, 0xd0ad5c12}, + {0x0000a3c0, 0x22222220}, + {0x0000a3c4, 0x22222222}, + {0x0000a404, 0x00418a11}, + {0x0000a418, 0x050001ce}, + {0x0000a438, 0x00001800}, + {0x0000a458, 0x01444452}, + {0x0000a644, 0x3fad9d74}, + {0x0000a690, 0x00000038}, +}; + +static const u32 ar9480_1p0_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73f00000}, + {0x0001600c, 0x00000000}, + {0x00016010, 0x6d820001}, + {0x00016040, 0x7f80fff8}, + {0x0001604c, 0x2699e04f}, + {0x00016050, 0x6db6db6c}, + {0x00016054, 0x6db60000}, + {0x00016058, 0x6c200000}, + {0x00016080, 0x00040000}, + {0x00016084, 0x9a68048c}, + {0x00016088, 0x54214514}, + {0x0001608c, 0x12030409}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd2888888}, + {0x000160a0, 0x0a108ffe}, + {0x000160a4, 0x812fc490}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92000000}, + {0x000160b8, 0x0285dddc}, + {0x000160bc, 0x02908888}, + {0x000160c0, 0x00adb6d0}, + {0x000160c4, 0x6db6db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x0de6c1b0}, + {0x00016100, 0x3fffbe04}, + {0x00016104, 0xfff80000}, + {0x00016108, 0x00200400}, + {0x00016110, 0x00000000}, + {0x00016144, 0x02084080}, + {0x00016148, 0x000080c0}, + {0x00016280, 0x050a0001}, + {0x00016284, 0x3d841400}, + {0x00016288, 0x00000000}, + {0x0001628c, 0xe3000000}, + {0x00016290, 0xa1005080}, + {0x00016294, 0x00000020}, + {0x00016298, 0x50a02900}, + {0x00016340, 0x121e4276}, + {0x00016344, 0x00300000}, + {0x00016400, 0x36db6db6}, + {0x00016404, 0x6db6db40}, + {0x00016408, 0x73f00000}, + {0x0001640c, 0x00000000}, + {0x00016410, 0x6c800001}, + {0x00016440, 0x7f80fff8}, + {0x0001644c, 0x4699e04f}, + {0x00016450, 0x6db6db6c}, + {0x00016454, 0x6db60000}, + {0x00016500, 0x3fffbe04}, + {0x00016504, 0xfff80000}, + {0x00016508, 0x00200400}, + {0x00016510, 0x00000000}, + {0x00016544, 0x02084080}, + {0x00016548, 0x000080c0}, +}; + +static const u32 ar9480_1p0_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, +}; + +static const u32 ar9480_1p0_sys2ant[][2] = { + /* Addr allmodes */ + {0x00063120, 0x00801980}, +}; + +#endif /* INITVALS_9480_1P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h new file mode 100644 index 000000000000..d54163d8d69f --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h @@ -0,0 +1,1928 @@ +/* + * Copyright (c) 2010 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INITVALS_9480_2P0_H +#define INITVALS_9480_2P0_H + +/* AR9480 2.0 */ + +static const u32 ar9480_modes_fast_clock_2p0[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, + {0x000010b0, 0x00000fd0, 0x00001fa0}, + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, + {0x00009e00, 0x0372131c, 0x0372131c}, + {0x0000a230, 0x0000400b, 0x00004016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9480_pciephy_clkreq_enable_L1_2p0[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18253ede}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0003580c}, +}; + +static const u32 ar9480_2p0_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, + {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, + {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, + {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3039605e, 0x33795d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c782}, + {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x013187c0, 0x013187c4, 0x013187c4, 0x013187c0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f}, + {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, + {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, + {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, + {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, + {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, + {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, + {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, +}; + +static const u32 ar9480_2p0_mac_core_emulation[][2] = { + /* Addr allmodes */ + {0x00000030, 0x000e0085}, + {0x00000044, 0x00000008}, + {0x0000805c, 0xffffc7ff}, + {0x00008344, 0xaa4a105b}, +}; + +static const u32 ar9480_common_rx_gain_table_2p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x01910190}, + {0x0000a030, 0x01930192}, + {0x0000a034, 0x01950194}, + {0x0000a038, 0x038a0196}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x22222229}, + {0x0000a084, 0x1d1d1d1d}, + {0x0000a088, 0x1d1d1d1d}, + {0x0000a08c, 0x1d1d1d1d}, + {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x2a2d2f32}, + {0x0000b084, 0x21232328}, + {0x0000b088, 0x19191c1e}, + {0x0000b08c, 0x12141417}, + {0x0000b090, 0x07070e0e}, + {0x0000b094, 0x03030305}, + {0x0000b098, 0x00000003}, + {0x0000b09c, 0x00000000}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9480_pciephy_clkreq_disable_L1_2p0[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18213ede}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0003580c}, +}; + +static const u32 ar9480_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18212ede}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0003580c}, +}; + +static const u32 ar9480_2p0_sys3ant[][2] = { + /* Addr allmodes */ + {0x00063280, 0x00040807}, + {0x00063284, 0x104ccccc}, +}; + +static const u32 ar9480_common_rx_gain_table_ar9280_2p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x02000101}, + {0x0000a004, 0x02000102}, + {0x0000a008, 0x02000103}, + {0x0000a00c, 0x02000104}, + {0x0000a010, 0x02000200}, + {0x0000a014, 0x02000201}, + {0x0000a018, 0x02000202}, + {0x0000a01c, 0x02000203}, + {0x0000a020, 0x02000204}, + {0x0000a024, 0x02000205}, + {0x0000a028, 0x02000208}, + {0x0000a02c, 0x02000302}, + {0x0000a030, 0x02000303}, + {0x0000a034, 0x02000304}, + {0x0000a038, 0x02000400}, + {0x0000a03c, 0x02010300}, + {0x0000a040, 0x02010301}, + {0x0000a044, 0x02010302}, + {0x0000a048, 0x02000500}, + {0x0000a04c, 0x02010400}, + {0x0000a050, 0x02020300}, + {0x0000a054, 0x02020301}, + {0x0000a058, 0x02020302}, + {0x0000a05c, 0x02020303}, + {0x0000a060, 0x02020400}, + {0x0000a064, 0x02030300}, + {0x0000a068, 0x02030301}, + {0x0000a06c, 0x02030302}, + {0x0000a070, 0x02030303}, + {0x0000a074, 0x02030400}, + {0x0000a078, 0x02040300}, + {0x0000a07c, 0x02040301}, + {0x0000a080, 0x02040302}, + {0x0000a084, 0x02040303}, + {0x0000a088, 0x02030500}, + {0x0000a08c, 0x02040400}, + {0x0000a090, 0x02050203}, + {0x0000a094, 0x02050204}, + {0x0000a098, 0x02050205}, + {0x0000a09c, 0x02040500}, + {0x0000a0a0, 0x02050301}, + {0x0000a0a4, 0x02050302}, + {0x0000a0a8, 0x02050303}, + {0x0000a0ac, 0x02050400}, + {0x0000a0b0, 0x02050401}, + {0x0000a0b4, 0x02050402}, + {0x0000a0b8, 0x02050403}, + {0x0000a0bc, 0x02050500}, + {0x0000a0c0, 0x02050501}, + {0x0000a0c4, 0x02050502}, + {0x0000a0c8, 0x02050503}, + {0x0000a0cc, 0x02050504}, + {0x0000a0d0, 0x02050600}, + {0x0000a0d4, 0x02050601}, + {0x0000a0d8, 0x02050602}, + {0x0000a0dc, 0x02050603}, + {0x0000a0e0, 0x02050604}, + {0x0000a0e4, 0x02050700}, + {0x0000a0e8, 0x02050701}, + {0x0000a0ec, 0x02050702}, + {0x0000a0f0, 0x02050703}, + {0x0000a0f4, 0x02050704}, + {0x0000a0f8, 0x02050705}, + {0x0000a0fc, 0x02050708}, + {0x0000a100, 0x02050709}, + {0x0000a104, 0x0205070a}, + {0x0000a108, 0x0205070b}, + {0x0000a10c, 0x0205070c}, + {0x0000a110, 0x0205070d}, + {0x0000a114, 0x02050710}, + {0x0000a118, 0x02050711}, + {0x0000a11c, 0x02050712}, + {0x0000a120, 0x02050713}, + {0x0000a124, 0x02050714}, + {0x0000a128, 0x02050715}, + {0x0000a12c, 0x02050730}, + {0x0000a130, 0x02050731}, + {0x0000a134, 0x02050732}, + {0x0000a138, 0x02050733}, + {0x0000a13c, 0x02050734}, + {0x0000a140, 0x02050735}, + {0x0000a144, 0x02050750}, + {0x0000a148, 0x02050751}, + {0x0000a14c, 0x02050752}, + {0x0000a150, 0x02050753}, + {0x0000a154, 0x02050754}, + {0x0000a158, 0x02050755}, + {0x0000a15c, 0x02050770}, + {0x0000a160, 0x02050771}, + {0x0000a164, 0x02050772}, + {0x0000a168, 0x02050773}, + {0x0000a16c, 0x02050774}, + {0x0000a170, 0x02050775}, + {0x0000a174, 0x00000776}, + {0x0000a178, 0x00000776}, + {0x0000a17c, 0x00000776}, + {0x0000a180, 0x00000776}, + {0x0000a184, 0x00000776}, + {0x0000a188, 0x00000776}, + {0x0000a18c, 0x00000776}, + {0x0000a190, 0x00000776}, + {0x0000a194, 0x00000776}, + {0x0000a198, 0x00000776}, + {0x0000a19c, 0x00000776}, + {0x0000a1a0, 0x00000776}, + {0x0000a1a4, 0x00000776}, + {0x0000a1a8, 0x00000776}, + {0x0000a1ac, 0x00000776}, + {0x0000a1b0, 0x00000776}, + {0x0000a1b4, 0x00000776}, + {0x0000a1b8, 0x00000776}, + {0x0000a1bc, 0x00000776}, + {0x0000a1c0, 0x00000776}, + {0x0000a1c4, 0x00000776}, + {0x0000a1c8, 0x00000776}, + {0x0000a1cc, 0x00000776}, + {0x0000a1d0, 0x00000776}, + {0x0000a1d4, 0x00000776}, + {0x0000a1d8, 0x00000776}, + {0x0000a1dc, 0x00000776}, + {0x0000a1e0, 0x00000776}, + {0x0000a1e4, 0x00000776}, + {0x0000a1e8, 0x00000776}, + {0x0000a1ec, 0x00000776}, + {0x0000a1f0, 0x00000776}, + {0x0000a1f4, 0x00000776}, + {0x0000a1f8, 0x00000776}, + {0x0000a1fc, 0x00000776}, + {0x0000b000, 0x02000101}, + {0x0000b004, 0x02000102}, + {0x0000b008, 0x02000103}, + {0x0000b00c, 0x02000104}, + {0x0000b010, 0x02000200}, + {0x0000b014, 0x02000201}, + {0x0000b018, 0x02000202}, + {0x0000b01c, 0x02000203}, + {0x0000b020, 0x02000204}, + {0x0000b024, 0x02000205}, + {0x0000b028, 0x02000208}, + {0x0000b02c, 0x02000302}, + {0x0000b030, 0x02000303}, + {0x0000b034, 0x02000304}, + {0x0000b038, 0x02000400}, + {0x0000b03c, 0x02010300}, + {0x0000b040, 0x02010301}, + {0x0000b044, 0x02010302}, + {0x0000b048, 0x02000500}, + {0x0000b04c, 0x02010400}, + {0x0000b050, 0x02020300}, + {0x0000b054, 0x02020301}, + {0x0000b058, 0x02020302}, + {0x0000b05c, 0x02020303}, + {0x0000b060, 0x02020400}, + {0x0000b064, 0x02030300}, + {0x0000b068, 0x02030301}, + {0x0000b06c, 0x02030302}, + {0x0000b070, 0x02030303}, + {0x0000b074, 0x02030400}, + {0x0000b078, 0x02040300}, + {0x0000b07c, 0x02040301}, + {0x0000b080, 0x02040302}, + {0x0000b084, 0x02040303}, + {0x0000b088, 0x02030500}, + {0x0000b08c, 0x02040400}, + {0x0000b090, 0x02050203}, + {0x0000b094, 0x02050204}, + {0x0000b098, 0x02050205}, + {0x0000b09c, 0x02040500}, + {0x0000b0a0, 0x02050301}, + {0x0000b0a4, 0x02050302}, + {0x0000b0a8, 0x02050303}, + {0x0000b0ac, 0x02050400}, + {0x0000b0b0, 0x02050401}, + {0x0000b0b4, 0x02050402}, + {0x0000b0b8, 0x02050403}, + {0x0000b0bc, 0x02050500}, + {0x0000b0c0, 0x02050501}, + {0x0000b0c4, 0x02050502}, + {0x0000b0c8, 0x02050503}, + {0x0000b0cc, 0x02050504}, + {0x0000b0d0, 0x02050600}, + {0x0000b0d4, 0x02050601}, + {0x0000b0d8, 0x02050602}, + {0x0000b0dc, 0x02050603}, + {0x0000b0e0, 0x02050604}, + {0x0000b0e4, 0x02050700}, + {0x0000b0e8, 0x02050701}, + {0x0000b0ec, 0x02050702}, + {0x0000b0f0, 0x02050703}, + {0x0000b0f4, 0x02050704}, + {0x0000b0f8, 0x02050705}, + {0x0000b0fc, 0x02050708}, + {0x0000b100, 0x02050709}, + {0x0000b104, 0x0205070a}, + {0x0000b108, 0x0205070b}, + {0x0000b10c, 0x0205070c}, + {0x0000b110, 0x0205070d}, + {0x0000b114, 0x02050710}, + {0x0000b118, 0x02050711}, + {0x0000b11c, 0x02050712}, + {0x0000b120, 0x02050713}, + {0x0000b124, 0x02050714}, + {0x0000b128, 0x02050715}, + {0x0000b12c, 0x02050730}, + {0x0000b130, 0x02050731}, + {0x0000b134, 0x02050732}, + {0x0000b138, 0x02050733}, + {0x0000b13c, 0x02050734}, + {0x0000b140, 0x02050735}, + {0x0000b144, 0x02050750}, + {0x0000b148, 0x02050751}, + {0x0000b14c, 0x02050752}, + {0x0000b150, 0x02050753}, + {0x0000b154, 0x02050754}, + {0x0000b158, 0x02050755}, + {0x0000b15c, 0x02050770}, + {0x0000b160, 0x02050771}, + {0x0000b164, 0x02050772}, + {0x0000b168, 0x02050773}, + {0x0000b16c, 0x02050774}, + {0x0000b170, 0x02050775}, + {0x0000b174, 0x00000776}, + {0x0000b178, 0x00000776}, + {0x0000b17c, 0x00000776}, + {0x0000b180, 0x00000776}, + {0x0000b184, 0x00000776}, + {0x0000b188, 0x00000776}, + {0x0000b18c, 0x00000776}, + {0x0000b190, 0x00000776}, + {0x0000b194, 0x00000776}, + {0x0000b198, 0x00000776}, + {0x0000b19c, 0x00000776}, + {0x0000b1a0, 0x00000776}, + {0x0000b1a4, 0x00000776}, + {0x0000b1a8, 0x00000776}, + {0x0000b1ac, 0x00000776}, + {0x0000b1b0, 0x00000776}, + {0x0000b1b4, 0x00000776}, + {0x0000b1b8, 0x00000776}, + {0x0000b1bc, 0x00000776}, + {0x0000b1c0, 0x00000776}, + {0x0000b1c4, 0x00000776}, + {0x0000b1c8, 0x00000776}, + {0x0000b1cc, 0x00000776}, + {0x0000b1d0, 0x00000776}, + {0x0000b1d4, 0x00000776}, + {0x0000b1d8, 0x00000776}, + {0x0000b1dc, 0x00000776}, + {0x0000b1e0, 0x00000776}, + {0x0000b1e4, 0x00000776}, + {0x0000b1e8, 0x00000776}, + {0x0000b1ec, 0x00000776}, + {0x0000b1f0, 0x00000776}, + {0x0000b1f4, 0x00000776}, + {0x0000b1f8, 0x00000776}, + {0x0000b1fc, 0x00000776}, +}; + +static const u32 ar9200_ar9280_2p0_radio_core[][2] = { + /* Addr allmodes */ + {0x00007800, 0x00040000}, + {0x00007804, 0xdb005012}, + {0x00007808, 0x04924914}, + {0x0000780c, 0x21084210}, + {0x00007810, 0x6d801300}, + {0x00007814, 0x0019beff}, + {0x00007818, 0x07e41000}, + {0x0000781c, 0x00392000}, + {0x00007820, 0x92592480}, + {0x00007824, 0x00040000}, + {0x00007828, 0xdb005012}, + {0x0000782c, 0x04924914}, + {0x00007830, 0x21084210}, + {0x00007834, 0x6d801300}, + {0x00007838, 0x0019beff}, + {0x0000783c, 0x07e40000}, + {0x00007840, 0x00392000}, + {0x00007844, 0x92592480}, + {0x00007848, 0x00100000}, + {0x0000784c, 0x773f0567}, + {0x00007850, 0x54214514}, + {0x00007854, 0x12035828}, + {0x00007858, 0x92592692}, + {0x0000785c, 0x00000000}, + {0x00007860, 0x56400000}, + {0x00007864, 0x0a8e370e}, + {0x00007868, 0xc0102850}, + {0x0000786c, 0x812d4000}, + {0x00007870, 0x807ec400}, + {0x00007874, 0x001b6db0}, + {0x00007878, 0x00376b63}, + {0x0000787c, 0x06db6db6}, + {0x00007880, 0x006d8000}, + {0x00007884, 0xffeffffe}, + {0x00007888, 0xffeffffe}, + {0x0000788c, 0x00010000}, + {0x00007890, 0x02060aeb}, + {0x00007894, 0x5a108000}, +}; + +static const u32 ar9480_2p0_mac_postamble_emulation[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8}, + {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017}, +}; + +static const u32 ar9480_2p0_radio_postamble_sys3ant[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, + {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, + {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, +}; + +static const u32 ar9480_2p0_baseband_postamble_emulation[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221}, + {0x00009e44, 0xfc5c0000, 0xfc5c0000, 0xfc5c0000, 0xfc5c0000}, + {0x0000a258, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, + {0x0000a25c, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a28c, 0x00011111, 0x00011111, 0x00011111, 0x00011111}, + {0x0000a2c4, 0x00148d18, 0x00148d18, 0x00148d20, 0x00148d20}, + {0x0000a2d8, 0xf999a800, 0xf999a800, 0xf999a80c, 0xf999a80c}, + {0x0000a50c, 0x0000c00a, 0x0000c00a, 0x0000c00a, 0x0000c00a}, + {0x0000a538, 0x00038e8c, 0x00038e8c, 0x00038e8c, 0x00038e8c}, + {0x0000a53c, 0x0003cecc, 0x0003cecc, 0x0003cecc, 0x0003cecc}, + {0x0000a540, 0x00040ed4, 0x00040ed4, 0x00040ed4, 0x00040ed4}, + {0x0000a544, 0x00044edc, 0x00044edc, 0x00044edc, 0x00044edc}, + {0x0000a548, 0x00048ede, 0x00048ede, 0x00048ede, 0x00048ede}, + {0x0000a54c, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, + {0x0000a550, 0x00050f5e, 0x00050f5e, 0x00050f5e, 0x00050f5e}, + {0x0000a554, 0x00054f9e, 0x00054f9e, 0x00054f9e, 0x00054f9e}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9480_2p0_radio_postamble_sys2ant[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, + {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, + {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, +}; + +static const u32 ar9480_common_wo_xlna_rx_gain_table_2p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9480_2p0_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; + +static const u32 ar9480_modes_low_ob_db_tx_gain_table_2p0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, + {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, + {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, + {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, + {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, + {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, + {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060}, + {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, + {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, + {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000}, + {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, +}; + +static const u32 ar9480_2p0_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, +}; + +static const u32 ar9480_2p0_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a9f6b}, + {0x0000980c, 0x04900000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x6400a290}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x0d000600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x32440bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098e4, 0x01ffffff}, + {0x000098e8, 0x01ffffff}, + {0x000098ec, 0x01ffffff}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009bf0, 0x80000000}, + {0x00009c04, 0xff55ff55}, + {0x00009c08, 0x0320ff55}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x9883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c0040b}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038230c}, + {0x00009e24, 0x990bb515}, + {0x00009e28, 0x0c6f0000}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009e54, 0xe4c355c7}, + {0x00009e58, 0xfd897735}, + {0x00009e5c, 0xe9198724}, + {0x00009fc0, 0x803e4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x00009fd0, 0x01193b93}, + {0x0000a20c, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0c9bd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739ce}, + {0x0000a418, 0x2d001dce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00100000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x05000080}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a454, 0x07000000}, + {0x0000a644, 0xbfad9d74}, + {0x0000a648, 0x0048060a}, + {0x0000a64c, 0x00002037}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, + {0x0000a67c, 0x13121110}, + {0x0000a680, 0x31301514}, + {0x0000a684, 0x35343332}, + {0x0000a688, 0x00000036}, + {0x0000a690, 0x00000838}, + {0x0000a6b0, 0x0000000a}, + {0x0000a6b4, 0x00512c01}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, + {0x0000a7f0, 0x80000000}, + {0x0000a8d0, 0x004b6a8e}, + {0x0000a8d4, 0x00000820}, + {0x0000a8dc, 0x00000000}, + {0x0000a8f0, 0x00000000}, + {0x0000a8f4, 0x00000000}, + {0x0000abf0, 0x80000000}, + {0x0000b2d0, 0x00000080}, + {0x0000b2d4, 0x00000000}, + {0x0000b2ec, 0x00000000}, + {0x0000b2f0, 0x00000000}, + {0x0000b2f4, 0x00000000}, + {0x0000b2f8, 0x00000000}, + {0x0000b408, 0x0e79e5c0}, + {0x0000b40c, 0x00820820}, + {0x0000b420, 0x00000000}, + {0x0000b6b0, 0x0000000a}, + {0x0000b6b4, 0x00000001}, +}; + +static const u32 ar9480_2p0_radio_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, + {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, + {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, + {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, +}; + +static const u32 ar9480_modes_high_ob_db_tx_gain_table_2p0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, + {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, + {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, + {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, + {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, + {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, + {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, + {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, + {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, + {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, + {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, + {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, + {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, + {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, +}; + +static const u32 ar9480_2p0_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73f00000}, + {0x0001600c, 0x00000000}, + {0x00016010, 0x6d820001}, + {0x00016040, 0x7f80fff8}, + {0x0001604c, 0x2699e04f}, + {0x00016050, 0x6db6db6c}, + {0x00016058, 0x6c200000}, + {0x00016080, 0x00040000}, + {0x00016084, 0x9a68048c}, + {0x00016088, 0x54214514}, + {0x0001608c, 0x1203040b}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd2888888}, + {0x000160a0, 0x0a108ffe}, + {0x000160a4, 0x812fc491}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92000000}, + {0x000160b8, 0x0285dddc}, + {0x000160bc, 0x02908888}, + {0x000160c0, 0x00adb6d0}, + {0x000160c4, 0x6db6db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x0de6c1b0}, + {0x00016100, 0x3fffbe04}, + {0x00016104, 0xfff80000}, + {0x00016108, 0x00200400}, + {0x00016110, 0x00000000}, + {0x00016144, 0x02084080}, + {0x00016148, 0x000080c0}, + {0x00016280, 0x050a0001}, + {0x00016284, 0x3d841400}, + {0x00016288, 0x00000000}, + {0x0001628c, 0xe3000000}, + {0x00016290, 0xa1005080}, + {0x00016294, 0x00000020}, + {0x00016298, 0x54a82900}, + {0x00016340, 0x121e4276}, + {0x00016344, 0x00300000}, + {0x00016400, 0x36db6db6}, + {0x00016404, 0x6db6db40}, + {0x00016408, 0x73f00000}, + {0x0001640c, 0x00000000}, + {0x00016410, 0x6c800001}, + {0x00016440, 0x7f80fff8}, + {0x0001644c, 0x4699e04f}, + {0x00016450, 0x6db6db6c}, + {0x00016500, 0x3fffbe04}, + {0x00016504, 0xfff80000}, + {0x00016508, 0x00200400}, + {0x00016510, 0x00000000}, + {0x00016544, 0x02084080}, + {0x00016548, 0x000080c0}, +}; + +static const u32 ar9480_2p0_tx_gain_table_baseband_postamble_emulation[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x00004002, 0x00004002, 0x00004002, 0x00004002}, + {0x0000a508, 0x00008004, 0x00008004, 0x00008004, 0x00008004}, + {0x0000a510, 0x0001000c, 0x0001000c, 0x0001000c, 0x0001000c}, + {0x0000a514, 0x0001420b, 0x0001420b, 0x0001420b, 0x0001420b}, + {0x0000a518, 0x0001824a, 0x0001824a, 0x0001824a, 0x0001824a}, + {0x0000a51c, 0x0001c44a, 0x0001c44a, 0x0001c44a, 0x0001c44a}, + {0x0000a520, 0x0002064a, 0x0002064a, 0x0002064a, 0x0002064a}, + {0x0000a524, 0x0002484a, 0x0002484a, 0x0002484a, 0x0002484a}, + {0x0000a528, 0x00028a4a, 0x00028a4a, 0x00028a4a, 0x00028a4a}, + {0x0000a52c, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, + {0x0000a530, 0x00030e4a, 0x00030e4a, 0x00030e4a, 0x00030e4a}, + {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a}, +}; + +static const u32 ar9480_2p0_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, +}; + +static const u32 ar9480_2p0_sys2ant[][2] = { + /* Addr allmodes */ + {0x00063120, 0x00801980}, +}; + +static const u32 ar9480_2p0_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x000e0085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00001810, 0x0f000003}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00080000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008050, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c20}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00b00005}, + {0x000080d8, 0x00400002}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486e00}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x99c00010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x0000001f}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0xffff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xaa48105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; + +static const u32 ar9480_2p0_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; + +static const u32 ar9480_common_mixed_rx_gain_table_2p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x2a2d2f32}, + {0x0000b084, 0x21232328}, + {0x0000b088, 0x19191c1e}, + {0x0000b08c, 0x12141417}, + {0x0000b090, 0x07070e0e}, + {0x0000b094, 0x03030305}, + {0x0000b098, 0x00000003}, + {0x0000b09c, 0x00000000}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; + +static const u32 ar9480_modes_green_ob_db_tx_gain_table_2p0[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, + {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, + {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, + {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, + {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, + {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, + {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, + {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, + {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, + {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, + {0x00016054, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180}, + {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, + {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, + {0x00016454, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180}, +}; + +static const u32 ar9480_2p0_BTCOEX_MAX_TXPWR_table[][2] = { + /* Addr allmodes */ + {0x000018c0, 0x10101010}, + {0x000018c4, 0x10101010}, + {0x000018c8, 0x10101010}, + {0x000018cc, 0x10101010}, + {0x000018d0, 0x10101010}, + {0x000018d4, 0x10101010}, + {0x000018d8, 0x10101010}, + {0x000018dc, 0x10101010}, +}; + +static const u32 ar9480_2p0_baseband_core_emulation[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafa68e30}, + {0x00009884, 0x00002842}, + {0x00009c04, 0xff55ff55}, + {0x00009c08, 0x0320ff55}, + {0x00009e50, 0x00000000}, + {0x00009fcc, 0x00000014}, + {0x0000a344, 0x00000010}, + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x71733d01}, + {0x0000a3a0, 0xd0ad5c12}, + {0x0000a3c0, 0x22222220}, + {0x0000a3c4, 0x22222222}, + {0x0000a404, 0x00418a11}, + {0x0000a418, 0x050001ce}, + {0x0000a438, 0x00001800}, + {0x0000a458, 0x01444452}, + {0x0000a644, 0x3fad9d74}, + {0x0000a690, 0x00000038}, +}; + +#endif /* INITVALS_9480_2P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c8af86c795e5..780cd0268ae1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -46,6 +46,7 @@ #define AR9300_DEVID_AR9340 0x0031 #define AR9300_DEVID_AR9485_PCIE 0x0032 #define AR9300_DEVID_AR9580 0x0033 +#define AR9300_DEVID_AR9480 0x0034 #define AR9300_DEVID_AR9330 0x0035 #define AR5416_AR9100_DEVID 0x000b @@ -827,11 +828,14 @@ struct ath_hw { struct ar5416IniArray iniModes_9271_1_0_only; struct ar5416IniArray iniCckfirNormal; struct ar5416IniArray iniCckfirJapan2484; + struct ar5416IniArray ini_japan2484; struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271; struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271; struct ar5416IniArray iniModes_9271_ANI_reg; struct ar5416IniArray iniModes_high_power_tx_gain_9271; struct ar5416IniArray iniModes_normal_power_tx_gain_9271; + struct ar5416IniArray ini_radio_post_sys2ant; + struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT]; struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT]; diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index acb83bfd05a0..2a523709ca9c 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -644,6 +644,7 @@ enum ath9k_rx_filter { ATH9K_RX_FILTER_PSPOLL = 0x00004000, ATH9K_RX_FILTER_PHYRADAR = 0x00002000, ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, + ATH9K_RX_FILTER_CONTROL_WRAPPER = 0x00080000, }; #define ATH9K_RATESERIES_RTS_CTS 0x0001 diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 5d34381c44c3..0846654b57ef 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -796,6 +796,9 @@ #define AR_SREV_VERSION_9340 0x300 #define AR_SREV_VERSION_9580 0x1C0 #define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ +#define AR_SREV_VERSION_9480 0x280 +#define AR_SREV_REVISION_9480_10 0 +#define AR_SREV_REVISION_9480_20 2 #define AR_SREV_5416(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ @@ -896,6 +899,21 @@ (AR_SREV_9285_12_OR_LATER(_ah) && \ ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) +#define AR_SREV_9480(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480)) + +#define AR_SREV_9480_10(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_10)) + +#define AR_SREV_9480_20(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_20)) + +#define AR_SREV_9480_20_OR_LATER(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \ + ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9480_20)) + #define AR_SREV_9580(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9580_10)) @@ -1779,6 +1797,7 @@ enum { #define AR_TXOP_12_15 0x81fc #define AR_NEXT_NDP2_TIMER 0x8180 +#define AR_GEN_TIMER_BANK_1_LEN 8 #define AR_FIRST_NDP_TIMER 7 #define AR_NDP2_PERIOD 0x81a0 #define AR_NDP2_TIMER_MODE 0x81c0 @@ -1867,9 +1886,10 @@ enum { #define AR_PCU_MISC_MODE2_HWWAR2 0x02000000 #define AR_PCU_MISC_MODE2_RESERVED2 0xFFFE0000 -#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358 -#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400 -#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000 +#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358 +#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400 +#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000 +#define AR_MAC_PCU_GEN_TIMER_TSF_SEL 0x83d8 #define AR_AES_MUTE_MASK0 0x805c @@ -1920,4 +1940,38 @@ enum { #define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0 #define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6 +/* MCI Registers */ +#define AR_MCI_INTERRUPT_RX_MSG_EN 0x183c +#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET 0x00000001 +#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET_S 0 +#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL 0x00000002 +#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL_S 1 +#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK 0x00000004 +#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK_S 2 +#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO 0x00000008 +#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO_S 3 +#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST 0x00000010 +#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST_S 4 +#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO 0x00000020 +#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO_S 5 +#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT 0x00000040 +#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT_S 6 +#define AR_MCI_INTERRUPT_RX_MSG_GPM 0x00000100 +#define AR_MCI_INTERRUPT_RX_MSG_GPM_S 8 +#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO 0x00000200 +#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO_S 9 +#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING 0x00000400 +#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING_S 10 +#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING 0x00000800 +#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING_S 11 +#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE 0x00001000 +#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE_S 12 +#define AR_MCI_INTERRUPT_RX_HW_MSG_MASK (AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO | \ + AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL| \ + AR_MCI_INTERRUPT_RX_MSG_LNA_INFO | \ + AR_MCI_INTERRUPT_RX_MSG_CONT_NACK | \ + AR_MCI_INTERRUPT_RX_MSG_CONT_INFO | \ + AR_MCI_INTERRUPT_RX_MSG_CONT_RST) + + #endif From 4d0707e66d82f46998d49be98adea0e705647be1 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 13 Sep 2011 22:38:17 +0530 Subject: [PATCH 188/287] ath9k_hw: Split tx/rx gain table initval handling Split tx/rx gain table initval hanlding part so readability is better and easy to manage the code. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 390 +++++++++++---------- 1 file changed, 210 insertions(+), 180 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index b6839e695270..6b54700eff5b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -374,208 +374,238 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) } } +static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) +{ + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_lowest_ob_db_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_lowest_ob_db_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9340Modes_lowest_ob_db_tx_gain_table_1p0, + ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), + 5); + else if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485_modes_lowest_ob_db_tx_gain_1_1, + ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), + 5); + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9580_1p0_lowest_ob_db_tx_gain_table, + ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), + 5); +} + +static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) +{ + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_ob_db_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_ob_db_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9340Modes_lowest_ob_db_tx_gain_table_1p0, + ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), + 5); + else if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_high_ob_db_tx_gain_1_1, + ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), + 5); + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9580_1p0_high_ob_db_tx_gain_table, + ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), + 5); +} + +static void ar9003_tx_gain_table_mode2(struct ath_hw *ah) +{ + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_low_ob_db_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_low_ob_db_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9340Modes_lowest_ob_db_tx_gain_table_1p0, + ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), + 5); + else if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_low_ob_db_tx_gain_1_1, + ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), + 5); + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9580_1p0_low_ob_db_tx_gain_table, + ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_low_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), + 5); +} + +static void ar9003_tx_gain_table_mode3(struct ath_hw *ah) +{ + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_power_tx_gain_1p2, + ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2), + 5); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9331_modes_high_power_tx_gain_1p1, + ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1), + 5); + else if (AR_SREV_9340(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9340Modes_lowest_ob_db_tx_gain_table_1p0, + ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), + 5); + else if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9485Modes_high_power_tx_gain_1_1, + ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), + 5); + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9580_1p0_high_power_tx_gain_table, + ARRAY_SIZE(ar9580_1p0_high_power_tx_gain_table), + 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_power_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2), + 5); +} + static void ar9003_tx_gain_table_apply(struct ath_hw *ah) { switch (ar9003_hw_get_tx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9330_12(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_lowest_ob_db_tx_gain_1p2, - ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), - 5); - else if (AR_SREV_9330_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_lowest_ob_db_tx_gain_1p1, - ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), - 5); - else if (AR_SREV_9340(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9340Modes_lowest_ob_db_tx_gain_table_1p0, - ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), - 5); - else if (AR_SREV_9485_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9485_modes_lowest_ob_db_tx_gain_1_1, - ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), - 5); - else if (AR_SREV_9580(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9580_1p0_lowest_ob_db_tx_gain_table, - ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), - 5); + ar9003_tx_gain_table_mode0(ah); break; case 1: - if (AR_SREV_9330_12(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_high_ob_db_tx_gain_1p2, - ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2), - 5); - else if (AR_SREV_9330_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_high_ob_db_tx_gain_1p1, - ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1), - 5); - else if (AR_SREV_9340(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9340Modes_lowest_ob_db_tx_gain_table_1p0, - ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), - 5); - else if (AR_SREV_9485_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9485Modes_high_ob_db_tx_gain_1_1, - ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), - 5); - else if (AR_SREV_9580(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9580_1p0_high_ob_db_tx_gain_table, - ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), - 5); + ar9003_tx_gain_table_mode1(ah); break; case 2: - if (AR_SREV_9330_12(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_low_ob_db_tx_gain_1p2, - ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2), - 5); - else if (AR_SREV_9330_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_low_ob_db_tx_gain_1p1, - ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1), - 5); - else if (AR_SREV_9340(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9340Modes_lowest_ob_db_tx_gain_table_1p0, - ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), - 5); - else if (AR_SREV_9485_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9485Modes_low_ob_db_tx_gain_1_1, - ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), - 5); - else if (AR_SREV_9580(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9580_1p0_low_ob_db_tx_gain_table, - ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_low_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), - 5); + ar9003_tx_gain_table_mode2(ah); break; case 3: - if (AR_SREV_9330_12(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_high_power_tx_gain_1p2, - ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2), - 5); - else if (AR_SREV_9330_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9331_modes_high_power_tx_gain_1p1, - ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1), - 5); - else if (AR_SREV_9340(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9340Modes_lowest_ob_db_tx_gain_table_1p0, - ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), - 5); - else if (AR_SREV_9485_11(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9485Modes_high_power_tx_gain_1_1, - ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), - 5); - else if (AR_SREV_9580(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9580_1p0_high_power_tx_gain_table, - ARRAY_SIZE(ar9580_1p0_high_power_tx_gain_table), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_power_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2), - 5); + ar9003_tx_gain_table_mode3(ah); break; } } +static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) +{ + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_rx_gain_1p2, + ARRAY_SIZE(ar9331_common_rx_gain_1p2), + 2); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_rx_gain_1p1, + ARRAY_SIZE(ar9331_common_rx_gain_1p1), + 2); + else if (AR_SREV_9340(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9340Common_rx_gain_table_1p0, + ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), + 2); + else if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485Common_wo_xlna_rx_gain_1_1, + ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), + 2); + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9580_1p0_rx_gain_table, + ARRAY_SIZE(ar9580_1p0_rx_gain_table), + 2); + else + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), + 2); +} + +static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) +{ + if (AR_SREV_9330_12(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_wo_xlna_rx_gain_1p2, + ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2), + 2); + else if (AR_SREV_9330_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9331_common_wo_xlna_rx_gain_1p1, + ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1), + 2); + else if (AR_SREV_9340(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9340Common_wo_xlna_rx_gain_table_1p0, + ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), + 2); + else if (AR_SREV_9485_11(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9485Common_wo_xlna_rx_gain_1_1, + ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), + 2); + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9580_1p0_wo_xlna_rx_gain_table, + ARRAY_SIZE(ar9580_1p0_wo_xlna_rx_gain_table), + 2); + else + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_wo_xlna_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), + 2); +} + static void ar9003_rx_gain_table_apply(struct ath_hw *ah) { switch (ar9003_hw_get_rx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9330_12(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9331_common_rx_gain_1p2, - ARRAY_SIZE(ar9331_common_rx_gain_1p2), - 2); - else if (AR_SREV_9330_11(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9331_common_rx_gain_1p1, - ARRAY_SIZE(ar9331_common_rx_gain_1p1), - 2); - else if (AR_SREV_9340(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9340Common_rx_gain_table_1p0, - ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), - 2); - else if (AR_SREV_9485_11(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9485Common_wo_xlna_rx_gain_1_1, - ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), - 2); - else if (AR_SREV_9580(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9580_1p0_rx_gain_table, - ARRAY_SIZE(ar9580_1p0_rx_gain_table), - 2); - else - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), - 2); + ar9003_rx_gain_table_mode0(ah); break; case 1: - if (AR_SREV_9330_12(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9331_common_wo_xlna_rx_gain_1p2, - ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2), - 2); - else if (AR_SREV_9330_11(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9331_common_wo_xlna_rx_gain_1p1, - ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1), - 2); - else if (AR_SREV_9340(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9340Common_wo_xlna_rx_gain_table_1p0, - ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), - 2); - else if (AR_SREV_9485_11(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9485Common_wo_xlna_rx_gain_1_1, - ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), - 2); - else if (AR_SREV_9580(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9580_1p0_wo_xlna_rx_gain_table, - ARRAY_SIZE(ar9580_1p0_wo_xlna_rx_gain_table), - 2); - else - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_wo_xlna_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), - 2); + ar9003_rx_gain_table_mode1(ah); break; } } From 2577c6e8f2320f1d2f09be122efef5b9118efee4 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 13 Sep 2011 22:38:18 +0530 Subject: [PATCH 189/287] ath9k_hw: Add support for AR946/8x chipsets. This patch adds support for AR946/8x chipets. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 109 +++++++--- .../net/wireless/ath/ath9k/ar9003_eeprom.h | 3 +- drivers/net/wireless/ath/ath9k/ar9003_hw.c | 191 ++++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 11 +- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 10 + drivers/net/wireless/ath/ath9k/hw.c | 73 ++++++- drivers/net/wireless/ath/ath9k/pci.c | 1 + 7 files changed, 362 insertions(+), 36 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index cb4c32eaef61..0fc0595c59e1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -22,11 +22,13 @@ #define COMP_HDR_LEN 4 #define COMP_CKSUM_LEN 2 -#define AR_CH0_TOP (0x00016288) +#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ + ((AR_SREV_9480(ah) ? 0x1628c : 0x16280))) #define AR_CH0_TOP_XPABIASLVL (0x300) #define AR_CH0_TOP_XPABIASLVL_S (8) -#define AR_CH0_THERM (0x00016290) +#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : \ + ((AR_SREV_9485(ah) ? 0x1628c : 0x16294))) #define AR_CH0_THERM_XPABIASLVL_MSB 0x3 #define AR_CH0_THERM_XPABIASLVL_MSB_S 0 #define AR_CH0_THERM_XPASHORT2GND 0x4 @@ -34,6 +36,11 @@ #define AR_SWITCH_TABLE_COM_ALL (0xffff) #define AR_SWITCH_TABLE_COM_ALL_S (0) +#define AR_SWITCH_TABLE_COM_AR9480_ALL (0xffffff) +#define AR_SWITCH_TABLE_COM_AR9480_ALL_S (0) +#define AR_SWITCH_TABLE_COM_SPDT (0x00f00000) +#define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0) +#define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4) #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) #define AR_SWITCH_TABLE_COM2_ALL_S (0) @@ -158,7 +165,7 @@ static const struct ar9300_eeprom ar9300_default = { .papdRateMaskHt20 = LE32(0x0cf0e0e0), .papdRateMaskHt40 = LE32(0x6cf0e0e0), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext1 = { @@ -360,7 +367,7 @@ static const struct ar9300_eeprom ar9300_default = { .papdRateMaskHt20 = LE32(0x0c80c080), .papdRateMaskHt40 = LE32(0x0080c080), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext2 = { @@ -735,7 +742,7 @@ static const struct ar9300_eeprom ar9300_x113 = { .papdRateMaskHt20 = LE32(0x0c80c080), .papdRateMaskHt40 = LE32(0x0080c080), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext1 = { @@ -937,7 +944,7 @@ static const struct ar9300_eeprom ar9300_x113 = { .papdRateMaskHt20 = LE32(0x0cf0e0e0), .papdRateMaskHt40 = LE32(0x6cf0e0e0), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext2 = { @@ -1313,7 +1320,7 @@ static const struct ar9300_eeprom ar9300_h112 = { .papdRateMaskHt20 = LE32(0x80c080), .papdRateMaskHt40 = LE32(0x80c080), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext1 = { @@ -1515,7 +1522,7 @@ static const struct ar9300_eeprom ar9300_h112 = { .papdRateMaskHt20 = LE32(0x0cf0e0e0), .papdRateMaskHt40 = LE32(0x6cf0e0e0), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext2 = { @@ -1891,7 +1898,7 @@ static const struct ar9300_eeprom ar9300_x112 = { .papdRateMaskHt20 = LE32(0x0c80c080), .papdRateMaskHt40 = LE32(0x0080c080), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext1 = { @@ -2093,7 +2100,7 @@ static const struct ar9300_eeprom ar9300_x112 = { .papdRateMaskHt20 = LE32(0x0cf0e0e0), .papdRateMaskHt40 = LE32(0x6cf0e0e0), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext2 = { @@ -2468,7 +2475,7 @@ static const struct ar9300_eeprom ar9300_h116 = { .papdRateMaskHt20 = LE32(0x0c80C080), .papdRateMaskHt40 = LE32(0x0080C080), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext1 = { @@ -2670,7 +2677,7 @@ static const struct ar9300_eeprom ar9300_h116 = { .papdRateMaskHt20 = LE32(0x0cf0e0e0), .papdRateMaskHt40 = LE32(0x6cf0e0e0), .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, }, .base_ext2 = { @@ -3573,6 +3580,8 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); + else if (AR_SREV_9480(ah)) + REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); else { REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); REG_RMW_FIELD(ah, AR_CH0_THERM, @@ -3583,6 +3592,19 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) } } +static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz) +{ + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + __le32 val; + + if (is_2ghz) + val = eep->modalHeader2G.switchcomspdt; + else + val = eep->modalHeader5G.switchcomspdt; + return le32_to_cpu(val); +} + + static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) { struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; @@ -3637,7 +3659,36 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); - REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); + if (AR_SREV_9480(ah)) { + if (AR_SREV_9480_10(ah)) { + value &= ~AR_SWITCH_TABLE_COM_SPDT; + value |= 0x00100000; + } + REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, + AR_SWITCH_TABLE_COM_AR9480_ALL, value); + } else + REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, + AR_SWITCH_TABLE_COM_ALL, value); + + + /* + * AR9480 defines new switch table for BT/WLAN, + * here's new field name in XXX.ref for both 2G and 5G. + * Register: [GLB_CONTROL] GLB_CONTROL (@0x20044) + * 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX + * SWITCH_TABLE_COM_SPDT_WLAN_RX + * + * 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX + * SWITCH_TABLE_COM_SPDT_WLAN_TX + * + * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE + * SWITCH_TABLE_COM_SPDT_WLAN_IDLE + */ + if (AR_SREV_9480_20_OR_LATER(ah)) { + value = ar9003_switch_com_spdt_get(ah, is2ghz); + REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, + AR_SWITCH_TABLE_COM_SPDT_ALL, value); + } value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); @@ -3837,6 +3888,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) { int internal_regulator = ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); + u32 reg_val; if (internal_regulator) { if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { @@ -3881,13 +3933,16 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set); if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) return; + } else if (AR_SREV_9480(ah)) { + reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); + REG_WRITE(ah, AR_PHY_PMU1, reg_val); } else { /* Internal regulator is ON. Write swreg register. */ - int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); + reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); REG_WRITE(ah, AR_RTC_REG_CONTROL1, REG_READ(ah, AR_RTC_REG_CONTROL1) & (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); - REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg); + REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val); /* Set REG_CONTROL1.SWREG_PROGRAM */ REG_WRITE(ah, AR_RTC_REG_CONTROL1, REG_READ(ah, @@ -3898,22 +3953,24 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0); while (REG_READ_FIELD(ah, AR_PHY_PMU2, - AR_PHY_PMU2_PGM)) + AR_PHY_PMU2_PGM)) udelay(10); REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1); while (!REG_READ_FIELD(ah, AR_PHY_PMU1, - AR_PHY_PMU1_PWD)) + AR_PHY_PMU1_PWD)) udelay(10); REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1); while (!REG_READ_FIELD(ah, AR_PHY_PMU2, - AR_PHY_PMU2_PGM)) + AR_PHY_PMU2_PGM)) udelay(10); - } else - REG_WRITE(ah, AR_RTC_SLEEP_CLK, - (REG_READ(ah, - AR_RTC_SLEEP_CLK) | - AR_RTC_FORCE_SWREG_PRD)); + } else if (AR_SREV_9480(ah)) + REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1); + else { + reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) | + AR_RTC_FORCE_SWREG_PRD; + REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val); + } } } @@ -4493,6 +4550,12 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, tempSlope = eep->modalHeader5G.tempSlope; REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); + + if (AR_SREV_9480_20(ah)) + REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, + AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope); + + REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, temperature[0]); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index ab21a4915981..6335a867527e 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -233,7 +233,8 @@ struct ar9300_modal_eep_header { u8 thresh62; __le32 papdRateMaskHt20; __le32 papdRateMaskHt40; - u8 futureModal[10]; + __le16 switchcomspdt; + u8 futureModal[8]; } __packed; struct ar9300_cal_data_per_freq_op_loop { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 6b54700eff5b..901f417bb036 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -22,6 +22,8 @@ #include "ar9330_1p1_initvals.h" #include "ar9330_1p2_initvals.h" #include "ar9580_1p0_initvals.h" +#include "ar9480_1p0_initvals.h" +#include "ar9480_2p0_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -32,6 +34,14 @@ */ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { +#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \ + ar9480_pciephy_pll_on_clkreq_disable_L1_2p0 + +#define AR9480_BB_CTX_COEFJ(x) \ + ar9480_##x##_baseband_core_txfir_coeff_japan_2484 + +#define AR9480_BBC_TXIFR_COEFFJ \ + ar9480_2p0_baseband_core_txfir_coeff_japan_2484 if (AR_SREV_9330_11(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -254,6 +264,132 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ar9485_1_1_pcie_phy_clkreq_disable_L1, ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 2); + } else if (AR_SREV_9480_10(ah)) { + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_1p0_mac_core, + ARRAY_SIZE(ar9480_1p0_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9480_1p0_mac_postamble, + ARRAY_SIZE(ar9480_1p0_mac_postamble), + 5); + + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9480_1p0_baseband_core, + ARRAY_SIZE(ar9480_1p0_baseband_core), + 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9480_1p0_baseband_postamble, + ARRAY_SIZE(ar9480_1p0_baseband_postamble), 5); + + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9480_1p0_radio_core, + ARRAY_SIZE(ar9480_1p0_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], + ar9480_1p0_radio_postamble, + ARRAY_SIZE(ar9480_1p0_radio_postamble), 5); + + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9480_1p0_soc_preamble, + ARRAY_SIZE(ar9480_1p0_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], + ar9480_1p0_soc_postamble, + ARRAY_SIZE(ar9480_1p0_soc_postamble), 5); + + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_rx_gain_table_1p0, + ARRAY_SIZE(ar9480_common_rx_gain_table_1p0), 2); + + /* Awake -> Sleep Setting */ + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9480_pcie_phy_clkreq_disable_L1_1p0, + ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0), + 2); + + /* Sleep -> Awake Setting */ + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + ar9480_pcie_phy_clkreq_disable_L1_1p0, + ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0), + 2); + + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9480_modes_fast_clock_1p0, + ARRAY_SIZE(ar9480_modes_fast_clock_1p0), 3); + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, + AR9480_BB_CTX_COEFJ(1p0), + ARRAY_SIZE(AR9480_BB_CTX_COEFJ(1p0)), 2); + + } else if (AR_SREV_9480_20(ah)) { + + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_2p0_mac_core, + ARRAY_SIZE(ar9480_2p0_mac_core), 2); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9480_2p0_mac_postamble, + ARRAY_SIZE(ar9480_2p0_mac_postamble), 5); + + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9480_2p0_baseband_core, + ARRAY_SIZE(ar9480_2p0_baseband_core), 2); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9480_2p0_baseband_postamble, + ARRAY_SIZE(ar9480_2p0_baseband_postamble), 5); + + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9480_2p0_radio_core, + ARRAY_SIZE(ar9480_2p0_radio_core), 2); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], + ar9480_2p0_radio_postamble, + ARRAY_SIZE(ar9480_2p0_radio_postamble), 5); + INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant, + ar9480_2p0_radio_postamble_sys2ant, + ARRAY_SIZE(ar9480_2p0_radio_postamble_sys2ant), + 5); + + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9480_2p0_soc_preamble, + ARRAY_SIZE(ar9480_2p0_soc_preamble), 2); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], + ar9480_2p0_soc_postamble, + ARRAY_SIZE(ar9480_2p0_soc_postamble), 5); + + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_rx_gain_table_2p0, + ARRAY_SIZE(ar9480_common_rx_gain_table_2p0), 2); + + INIT_INI_ARRAY(&ah->ini_BTCOEX_MAX_TXPWR, + ar9480_2p0_BTCOEX_MAX_TXPWR_table, + ARRAY_SIZE(ar9480_2p0_BTCOEX_MAX_TXPWR_table), + 2); + + /* Awake -> Sleep Setting */ + INIT_INI_ARRAY(&ah->iniPcieSerdes, + PCIE_PLL_ON_CREQ_DIS_L1_2P0, + ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0), + 2); + /* Sleep -> Awake Setting */ + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + PCIE_PLL_ON_CREQ_DIS_L1_2P0, + ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0), + 2); + + /* Fast clock modal settings */ + INIT_INI_ARRAY(&ah->iniModesAdditional, + ar9480_modes_fast_clock_2p0, + ARRAY_SIZE(ar9480_modes_fast_clock_2p0), 3); + + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, + AR9480_BB_CTX_COEFJ(2p0), + ARRAY_SIZE(AR9480_BB_CTX_COEFJ(2p0)), 2); + + INIT_INI_ARRAY(&ah->ini_japan2484, AR9480_BBC_TXIFR_COEFFJ, + ARRAY_SIZE(AR9480_BBC_TXIFR_COEFFJ), 2); + } else if (AR_SREV_9580(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -401,6 +537,16 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) ar9580_1p0_lowest_ob_db_tx_gain_table, ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table), 5); + else if (AR_SREV_9480_10(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9480_modes_low_ob_db_tx_gain_table_1p0, + ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_1p0), + 5); + else if (AR_SREV_9480_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9480_modes_low_ob_db_tx_gain_table_2p0, + ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_2p0), + 5); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_lowest_ob_db_tx_gain_table_2p2, @@ -435,6 +581,16 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) ar9580_1p0_high_ob_db_tx_gain_table, ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table), 5); + else if (AR_SREV_9480_10(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9480_modes_high_ob_db_tx_gain_table_1p0, + ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_1p0), + 5); + else if (AR_SREV_9480_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9480_modes_high_ob_db_tx_gain_table_2p0, + ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_2p0), + 5); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_high_ob_db_tx_gain_table_2p2, @@ -556,6 +712,16 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) ar9580_1p0_rx_gain_table, ARRAY_SIZE(ar9580_1p0_rx_gain_table), 2); + else if (AR_SREV_9480_10(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_rx_gain_table_1p0, + ARRAY_SIZE(ar9480_common_rx_gain_table_1p0), + 2); + else if (AR_SREV_9480_20(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_rx_gain_table_2p0, + ARRAY_SIZE(ar9480_common_rx_gain_table_2p0), + 2); else INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p2, @@ -585,6 +751,16 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) ar9485Common_wo_xlna_rx_gain_1_1, ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2); + else if (AR_SREV_9480_10(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_wo_xlna_rx_gain_table_1p0, + ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_1p0), + 2); + else if (AR_SREV_9480_20(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_wo_xlna_rx_gain_table_2p0, + ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_2p0), + 2); else if (AR_SREV_9580(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9580_1p0_wo_xlna_rx_gain_table, @@ -597,6 +773,18 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) 2); } +static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) +{ + if (AR_SREV_9480_10(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_mixed_rx_gain_table_1p0, + ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_1p0), 2); + else if (AR_SREV_9480_20(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9480_common_mixed_rx_gain_table_2p0, + ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_2p0), 2); +} + static void ar9003_rx_gain_table_apply(struct ath_hw *ah) { switch (ar9003_hw_get_rx_gain_idx(ah)) { @@ -607,6 +795,9 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) case 1: ar9003_rx_gain_table_mode1(ah); break; + case 2: + ar9003_rx_gain_table_mode2(ah); + break; } } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index bb2214f425b2..609acb2b504f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -147,7 +147,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) AR_PHY_PAPRD_CTRL1_B2 }; int training_power; - int i; + int i, val; if (IS_CHAN_2GHZ(ah->curchan)) training_power = ar9003_get_training_power_2g(ah); @@ -207,8 +207,9 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1); + val = AR_SREV_9480(ah) ? 0x91 : 147; REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2, - AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147); + AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, @@ -217,7 +218,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); - if (AR_SREV_9485(ah)) + if (AR_SREV_9485(ah) || AR_SREV_9480(ah)) REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -3); @@ -225,9 +226,10 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6); + val = AR_SREV_9480(ah) ? -10 : -15; REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, - -15); + val); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1); REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, @@ -757,6 +759,7 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah, training_power); if (ah->caps.tx_chainmask & BIT(2)) + /* val AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL correct? */ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2, AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, training_power); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 33edb5653ca6..95147948794d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -559,6 +559,9 @@ static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); + else if (AR_SREV_9480(ah)) + /* xxx only when MCI support is enabled */ + REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); else REG_WRITE(ah, AR_SELFGEN_MASK, tx); @@ -658,6 +661,10 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); + if (i == ATH_INI_POST && AR_SREV_9480_20(ah)) + ar9003_hw_prog_ini(ah, + &ah->ini_radio_post_sys2ant, + modesIndex); } REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); @@ -677,6 +684,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); + if (AR_SREV_9480(ah)) + ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); + ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f2065fce4ec9..4ace66c9d59d 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -580,6 +580,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) case AR_SREV_VERSION_9330: case AR_SREV_VERSION_9485: case AR_SREV_VERSION_9340: + case AR_SREV_VERSION_9480: break; default: ath_err(common, @@ -664,6 +665,7 @@ int ath9k_hw_init(struct ath_hw *ah) case AR9300_DEVID_AR9330: case AR9300_DEVID_AR9340: case AR9300_DEVID_AR9580: + case AR9300_DEVID_AR9480: break; default: if (common->bus_ops->ath_bus_type == ATH_USB) @@ -1340,6 +1342,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) { + if (AR_SREV_9300_20_OR_LATER(ah)) { REG_WRITE(ah, AR_WA, ah->WARegVal); udelay(10); @@ -1743,25 +1746,41 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) { REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); if (setChip) { + if (AR_SREV_9480(ah)) { + REG_WRITE(ah, AR_TIMER_MODE, + REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); + REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah, + AR_NDP2_TIMER_MODE) & 0xFFFFFF00); + REG_WRITE(ah, AR_SLP32_INC, + REG_READ(ah, AR_SLP32_INC) & 0xFFF00000); + /* xxx Required for WLAN only case ? */ + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); + udelay(100); + } + /* * Clear the RTC force wake bit to allow the * mac to go to sleep. */ - REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, - AR_RTC_FORCE_WAKE_EN); + REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); + + if (AR_SREV_9480(ah)) + udelay(100); + if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); /* Shutdown chip. Active low */ - if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) - REG_CLR_BIT(ah, (AR_RTC_RESET), - AR_RTC_RESET_EN); + if (!AR_SREV_5416(ah) && + !AR_SREV_9271(ah) && !AR_SREV_9480_10(ah)) { + REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); + udelay(2); + } } /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ - if (AR_SREV_9300_20_OR_LATER(ah)) - REG_WRITE(ah, AR_WA, - ah->WARegVal & ~AR_WA_D3_L1_DISABLE); + if (!AR_SREV_9480(ah)) + REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); } /* @@ -1771,6 +1790,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) */ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) { + u32 val; + REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); if (setChip) { struct ath9k_hw_capabilities *pCap = &ah->caps; @@ -1780,12 +1801,30 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); } else { + + /* When chip goes into network sleep, it could be waken + * up by MCI_INT interrupt caused by BT's HW messages + * (LNA_xxx, CONT_xxx) which chould be in a very fast + * rate (~100us). This will cause chip to leave and + * re-enter network sleep mode frequently, which in + * consequence will have WLAN MCI HW to generate lots of + * SYS_WAKING and SYS_SLEEPING messages which will make + * BT CPU to busy to process. + */ + if (AR_SREV_9480(ah)) { + val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & + ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK; + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val); + } /* * Clear the RTC force wake bit to allow the * mac to go to sleep. */ REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); + + if (AR_SREV_9480(ah)) + udelay(30); } } @@ -2404,6 +2443,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) ENABLE_REGWRITE_BUFFER(ah); + if (AR_SREV_9480(ah)) + bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER; + REG_WRITE(ah, AR_RX_FILTER, bits); phybits = 0; @@ -2660,6 +2702,20 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr, gen_tmr_configuration[timer->index].mode_mask); + if (AR_SREV_9480(ah)) { + /* + * Starting from AR9480, each generic timer can select which tsf + * to use. But we still follow the old rule, 0 - 7 use tsf and + * 8 - 15 use tsf2. + */ + if ((timer->index < AR_GEN_TIMER_BANK_1_LEN)) + REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, + (1 << timer->index)); + else + REG_SET_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, + (1 << timer->index)); + } + /* Enable both trigger and thresh interrupt masks */ REG_SET_BIT(ah, AR_IMR_S5, (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | @@ -2765,6 +2821,7 @@ static struct { { AR_SREV_VERSION_9330, "9330" }, { AR_SREV_VERSION_9340, "9340" }, { AR_SREV_VERSION_9485, "9485" }, + { AR_SREV_VERSION_9480, "9480" }, }; /* For devices with external radios */ diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 891661a61513..bda2233126d0 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -33,6 +33,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ + { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9480 */ { 0 } }; From b54af8af49cd93c1ac33e3a8f0bb2f5acc8c7d0e Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 13 Sep 2011 22:38:19 +0530 Subject: [PATCH 190/287] ath9k_hw: move register definitions to header files Move the register macros to appropriate header files to be in sync with other register definitions and also a single place to refer everything. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 26 ------------------- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 25 ++++++++++++++++++ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 0fc0595c59e1..98e4caef7850 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -22,32 +22,6 @@ #define COMP_HDR_LEN 4 #define COMP_CKSUM_LEN 2 -#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ - ((AR_SREV_9480(ah) ? 0x1628c : 0x16280))) -#define AR_CH0_TOP_XPABIASLVL (0x300) -#define AR_CH0_TOP_XPABIASLVL_S (8) - -#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : \ - ((AR_SREV_9485(ah) ? 0x1628c : 0x16294))) -#define AR_CH0_THERM_XPABIASLVL_MSB 0x3 -#define AR_CH0_THERM_XPABIASLVL_MSB_S 0 -#define AR_CH0_THERM_XPASHORT2GND 0x4 -#define AR_CH0_THERM_XPASHORT2GND_S 2 - -#define AR_SWITCH_TABLE_COM_ALL (0xffff) -#define AR_SWITCH_TABLE_COM_ALL_S (0) -#define AR_SWITCH_TABLE_COM_AR9480_ALL (0xffffff) -#define AR_SWITCH_TABLE_COM_AR9480_ALL_S (0) -#define AR_SWITCH_TABLE_COM_SPDT (0x00f00000) -#define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0) -#define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4) - -#define AR_SWITCH_TABLE_COM2_ALL (0xffffff) -#define AR_SWITCH_TABLE_COM2_ALL_S (0) - -#define AR_SWITCH_TABLE_ALL (0xfff) -#define AR_SWITCH_TABLE_ALL_S (0) - #define LE16(x) __constant_cpu_to_le16(x) #define LE32(x) __constant_cpu_to_le32(x) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 05f6538416ce..f1be87454308 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -624,6 +624,31 @@ #define AR_PHY_65NM_CH0_BIAS4 0x160cc #define AR_PHY_65NM_CH0_RXTX4 0x1610c +#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ + ((AR_SREV_9480(ah) ? 0x1628c : 0x16280))) +#define AR_CH0_TOP_XPABIASLVL (0x300) +#define AR_CH0_TOP_XPABIASLVL_S (8) + +#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : \ + ((AR_SREV_9485(ah) ? 0x1628c : 0x16294))) +#define AR_CH0_THERM_XPABIASLVL_MSB 0x3 +#define AR_CH0_THERM_XPABIASLVL_MSB_S 0 +#define AR_CH0_THERM_XPASHORT2GND 0x4 +#define AR_CH0_THERM_XPASHORT2GND_S 2 + +#define AR_SWITCH_TABLE_COM_ALL (0xffff) +#define AR_SWITCH_TABLE_COM_ALL_S (0) +#define AR_SWITCH_TABLE_COM_AR9480_ALL (0xffffff) +#define AR_SWITCH_TABLE_COM_AR9480_ALL_S (0) +#define AR_SWITCH_TABLE_COM_SPDT (0x00f00000) +#define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0) +#define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4) + +#define AR_SWITCH_TABLE_COM2_ALL (0xffffff) +#define AR_SWITCH_TABLE_COM2_ALL_S (0) + +#define AR_SWITCH_TABLE_ALL (0xfff) +#define AR_SWITCH_TABLE_ALL_S (0) #define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ (AR_SREV_9485(ah) ? 0x1628c : 0x16294)) From 7db062ac4bafac040afb28faf355fc2acb426413 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 14 Sep 2011 14:20:30 +0530 Subject: [PATCH 191/287] ath9k_hw: Do full chip reset on 11A channels for AR9003 AR9003 seems to have issues sometimes with fast channel change in 5GHz and this case is handled specifically for AR9280 by doing a full reset. Let's do a full reset for 5GHz channles of AR9380 & for all channels of AR9280 pci chips. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 4ace66c9d59d..f2de7ee047ce 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1499,14 +1499,16 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } ah->noise = ath9k_hw_getchan_noise(ah, chan); + if ((AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) || + (AR_SREV_9300_20_OR_LATER(ah) && IS_CHAN_5GHZ(chan))) + bChannelChange = false; + if (bChannelChange && (ah->chip_fullsleep != true) && (ah->curchan != NULL) && (chan->channel != ah->curchan->channel) && ((chan->channelFlags & CHANNEL_ALL) == - (ah->curchan->channelFlags & CHANNEL_ALL)) && - (!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) { - + (ah->curchan->channelFlags & CHANNEL_ALL))) { if (ath9k_hw_channel_change(ah, chan)) { ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_start_nfcal(ah, true); From 79ac9b3033eef5dd1144da035cf18b00e35ddf48 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 14 Sep 2011 15:09:13 +0530 Subject: [PATCH 192/287] ath9k: enable LED pin for AR946/8x chipsets now the LED starts working for AR946/8x chipsets Cc: "Balasubramanian, senthilkumar" Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/gpio.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 0fb4a26f8979..45be0a3fe5c1 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -461,6 +461,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); #define ATH_LED_PIN_9287 8 #define ATH_LED_PIN_9300 10 #define ATH_LED_PIN_9485 6 +#define ATH_LED_PIN_9480 0 #ifdef CONFIG_MAC80211_LEDS void ath_init_leds(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 5113dd80c99f..afbf5400a52a 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -48,6 +48,8 @@ void ath_init_leds(struct ath_softc *sc) sc->sc_ah->led_pin = ATH_LED_PIN_9485; else if (AR_SREV_9300(sc->sc_ah)) sc->sc_ah->led_pin = ATH_LED_PIN_9300; + else if (AR_SREV_9480(sc->sc_ah)) + sc->sc_ah->led_pin = ATH_LED_PIN_9480; else sc->sc_ah->led_pin = ATH_LED_PIN_DEF; } From c5d2593bad0d3440ce3b464d9e3c514d364820f8 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Wed, 14 Sep 2011 15:09:40 +0530 Subject: [PATCH 193/287] ath9k: Fix PS wrappers and enabling LED in ath_pci_resume it seems we are not enabling LED properly, in addition we have a PS wrapper fix for this Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index bda2233126d0..d67d6eee3954 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -333,16 +333,16 @@ static int ath_pci_resume(struct device *device) if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + ath9k_ps_wakeup(sc); /* Enable LED */ ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); + ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0); /* * Reset key cache to sane defaults (all entries cleared) instead of * semi-random values after suspend/resume. */ - ath9k_ps_wakeup(sc); ath9k_cmn_init_crypto(sc->sc_ah); ath9k_ps_restore(sc); From e392700741a4a5f061f3fcc9f5f2ceb0e0b0953e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:23:01 +0200 Subject: [PATCH 194/287] ath9k: fix enabling interrupts after a hardware error interrupt The interrupt handler increases the interrupt disable refcount, so the tasklet needs to always call ath9k_hw_enable_interrupts. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c8ac2ce61ffe..03b402bb9c4e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -669,15 +669,15 @@ void ath9k_tasklet(unsigned long data) u32 status = sc->intrstatus; u32 rxmask; + ath9k_ps_wakeup(sc); + spin_lock(&sc->sc_pcu_lock); + if ((status & ATH9K_INT_FATAL) || (status & ATH9K_INT_BB_WATCHDOG)) { ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - return; + goto out; } - ath9k_ps_wakeup(sc); - spin_lock(&sc->sc_pcu_lock); - /* * Only run the baseband hang check if beacons stop working in AP or * IBSS mode, because it has a high false positive rate. For station @@ -725,6 +725,7 @@ void ath9k_tasklet(unsigned long data) if (status & ATH9K_INT_GENTIMER) ath_gen_timer_isr(sc->sc_ah); +out: /* re-enable hardware interrupt */ ath9k_hw_enable_interrupts(ah); From c31c8261bf7b817e323d29ba66c031f6b0982680 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:23:02 +0200 Subject: [PATCH 195/287] ath9k: make beacon timer initialization more reliable When starting the AP beacon timer, it assumes that the TSF has recently been cleared. Set the SC_OP_TSF_RESET flag to ensure that this is always the case. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 22e8e2580116..6d7088b02611 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -517,6 +517,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc, /* Set the computed AP beacon timers */ ath9k_hw_disable_interrupts(ah); + sc->sc_flags |= SC_OP_TSF_RESET; ath9k_beacon_init(sc, nexttbtt, intval); sc->beacon.bmisscnt = 0; ath9k_hw_set_interrupts(ah, ah->imask); From 3483288caf3d979e6b032d62f75f57893adf0d53 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:23:03 +0200 Subject: [PATCH 196/287] ath9k: ensure that rx is not enabled during a reset During a reset, rx buffers are flushed after rx has been disabled. To avoid race conditions, rx needs to stay disabled during the reset, so avoid any calls to ath9k_hw_rxena in that case. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 ++-- drivers/net/wireless/ath/ath9k/recv.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 03b402bb9c4e..8149511e8f7e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -247,8 +247,8 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) if (!flush) { if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) - ath_rx_tasklet(sc, 0, true); - ath_rx_tasklet(sc, 0, false); + ath_rx_tasklet(sc, 1, true); + ath_rx_tasklet(sc, 1, false); } else { ath_flushrecv(sc); } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 8d3e19dfe7db..bcc0b222ec18 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1839,7 +1839,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) * If we're asked to flush receive queue, directly * chain it back at the queue without processing it. */ - if (flush) + if (sc->sc_flags & SC_OP_RXFLUSH) goto requeue_drop_frag; retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, @@ -1967,7 +1967,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) } else { list_move_tail(&bf->list, &sc->rx.rxbuf); ath_rx_buf_link(sc, bf); - ath9k_hw_rxena(ah); + if (!flush) + ath9k_hw_rxena(ah); } } while (1); From 55797b1ae5bfc33f1c0f978cdc7cd89a8d9460fc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:16 +0200 Subject: [PATCH 197/287] ath9k: remove ATH_TX_XRETRY and BUF_XRETRY flags Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 6 +----- drivers/net/wireless/ath/ath9k/debug.c | 7 ++++--- drivers/net/wireless/ath/ath9k/debug.h | 6 ++++-- drivers/net/wireless/ath/ath9k/xmit.c | 23 ++++------------------- 4 files changed, 13 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 45be0a3fe5c1..c016a7ae056e 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -87,17 +87,14 @@ struct ath_config { * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX) * @BUF_AGGR: Indicates whether the buffer can be aggregated * (used in aggregation scheduling) - * @BUF_XRETRY: To denote excessive retries of the buffer */ enum buffer_type { BUF_AMPDU = BIT(0), BUF_AGGR = BIT(1), - BUF_XRETRY = BIT(2), }; #define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU) #define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR) -#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) #define ATH_TXSTATUS_RING_SIZE 64 @@ -277,8 +274,7 @@ struct ath_tx_control { }; #define ATH_TX_ERROR 0x01 -#define ATH_TX_XRETRY 0x02 -#define ATH_TX_BAR 0x04 +#define ATH_TX_BAR 0x02 /** * @txq_map: Index is mac80211 queue number. This is diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 7f143872dc83..179da2099270 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -826,7 +826,8 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, } void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts, struct ath_txq *txq) + struct ath_tx_status *ts, struct ath_txq *txq, + unsigned int flags) { #define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\ [sc->debug.tsidx].c) @@ -836,12 +837,12 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; if (bf_isampdu(bf)) { - if (bf_isxretried(bf)) + if (flags & ATH_TX_BAR) TX_STAT_INC(qnum, a_xretries); else TX_STAT_INC(qnum, a_completed); } else { - if (bf_isxretried(bf)) + if (ts->ts_status & ATH9K_TXERR_XRETRY) TX_STAT_INC(qnum, xretries); else TX_STAT_INC(qnum, completed); diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 95f85bdc8db7..39f89bc9abcd 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -230,7 +230,8 @@ int ath9k_init_debug(struct ath_hw *ah); void ath9k_debug_samp_bb_mac(struct ath_softc *sc); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, - struct ath_tx_status *ts, struct ath_txq *txq); + struct ath_tx_status *ts, struct ath_txq *txq, + unsigned int flags); void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); #else @@ -252,7 +253,8 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc, static inline void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, - struct ath_txq *txq) + struct ath_txq *txq, + unsigned int flags) { } diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index cb37047e71d2..54049824bf69 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -390,7 +390,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, while (bf) { bf_next = bf->bf_next; - bf->bf_state.bf_type |= BUF_XRETRY; if (!bf->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); @@ -470,7 +469,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, clear_filter = true; txpending = 1; } else { - bf->bf_state.bf_type |= BUF_XRETRY; txfail = 1; sendbar = 1; txfail_cnt++; @@ -523,13 +521,11 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, ath_tx_update_baw(sc, tid, seqno); spin_unlock_bh(&txq->axq_lock); - bf->bf_state.bf_type |= - BUF_XRETRY; ath_tx_rc_status(sc, bf, ts, nframes, nbad, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, - ts, 0, 0); + ts, 0, 1); break; } @@ -1953,10 +1949,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, if (tx_flags & ATH_TX_BAR) tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { + if (!(tx_flags & ATH_TX_ERROR)) /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; - } padpos = ath9k_cmn_padpos(hdr->frame_control); padsize = padpos & 3; @@ -2006,13 +2001,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, if (sendbar) tx_flags = ATH_TX_BAR; - if (!txok) { + if (!txok) tx_flags |= ATH_TX_ERROR; - if (bf_isxretried(bf)) - tx_flags |= ATH_TX_XRETRY; - } - dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); bf->bf_buf_addr = 0; @@ -2024,7 +2015,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, else complete(&sc->paprd_complete); } else { - ath_debug_stat_tx(sc, bf, ts, txq); + ath_debug_stat_tx(sc, bf, ts, txq, tx_flags); ath_tx_complete(sc, skb, tx_flags, txq); } /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't @@ -2115,12 +2106,6 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, spin_unlock_bh(&txq->axq_lock); if (!bf_isampdu(bf)) { - /* - * This frame is sent out as a single frame. - * Use hardware retry status for this frame. - */ - if (ts->ts_status & ATH9K_TXERR_XRETRY) - bf->bf_state.bf_type |= BUF_XRETRY; ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true); ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0); } else From 399c64895d206b16c704827d0a71b7467e441c94 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:17 +0200 Subject: [PATCH 198/287] ath9k: reduce the number of functions that access the tx descriptor Makes it easier to clean up the ath9k_hw descriptor API Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/xmit.c | 91 ++++++++++++++++---------- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c016a7ae056e..4eba9577386b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -213,6 +213,7 @@ struct ath_frame_info { struct ath_buf_state { u8 bf_type; u8 bfs_paprd; + u8 ndelim; u16 seqno; unsigned long bfs_paprd_timestamp; }; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 54049824bf69..48ac9ff01ac0 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -774,7 +774,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, if (!bf) continue; - bf->bf_state.bf_type |= BUF_AMPDU; + bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; seqno = bf->bf_state.seqno; if (!bf_first) bf_first = bf; @@ -824,20 +824,17 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, nframes++; bf->bf_next = NULL; - ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); /* link buffers of this frame to the aggregate */ if (!fi->retries) ath_tx_addto_baw(sc, tid, seqno); - ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim); + bf->bf_state.ndelim = ndelim; __skb_unlink(skb, &tid->buf_q); list_add_tail(&bf->list, bf_q); - if (bf_prev) { + if (bf_prev) bf_prev->bf_next = bf; - ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc, - bf->bf_daddr); - } + bf_prev = bf; } while (!skb_queue_empty(&tid->buf_q)); @@ -848,12 +845,50 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, #undef PADBYTES } +static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, int len) +{ + struct ath_hw *ah = sc->sc_ah; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); + struct ath_buf *bf_first = bf; + + bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR); + bool clrdmask = !!(tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT); + + u32 ds_next; + + ath_buf_set_rate(sc, bf, len); + + while (bf) { + if (bf->bf_next) + ds_next = bf->bf_next->bf_daddr; + else + ds_next = 0; + + ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, clrdmask); + if (!aggr) + ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); + else if (!bf->bf_next) + ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_desc); + else { + if (bf == bf_first) + ath9k_hw_set11n_aggr_first(sc->sc_ah, + bf->bf_desc, len); + + ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, + bf->bf_state.ndelim); + } + + ath9k_hw_set_desc_link(ah, bf->bf_desc, ds_next); + bf = bf->bf_next; + } +} + static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, struct ath_atx_tid *tid) { struct ath_buf *bf; enum ATH_AGGR_STATUS status; - struct ath_frame_info *fi; + struct ieee80211_tx_info *tx_info; struct list_head bf_q; int aggr_len; @@ -874,34 +909,25 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, bf = list_first_entry(&bf_q, struct ath_buf, list); bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list); + tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); if (tid->ac->clear_ps_filter) { tid->ac->clear_ps_filter = false; - ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); + tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; + } else { + tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; } /* if only one frame, send as non-aggregate */ if (bf == bf->bf_lastbf) { - fi = get_frame_info(bf->bf_mpdu); - - bf->bf_state.bf_type &= ~BUF_AGGR; - ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); - ath_buf_set_rate(sc, bf, fi->framelen); - ath_tx_txqaddbuf(sc, txq, &bf_q, false); - continue; + aggr_len = get_frame_info(bf->bf_mpdu)->framelen; + bf->bf_state.bf_type = BUF_AMPDU; + } else { + TX_STAT_INC(txq->axq_qnum, a_aggr); } - /* setup first desc of aggregate */ - bf->bf_state.bf_type |= BUF_AGGR; - ath_buf_set_rate(sc, bf, aggr_len); - ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len); - - /* anchor last desc of aggregate */ - ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); - + ath_tx_fill_desc(sc, bf, aggr_len); ath_tx_txqaddbuf(sc, txq, &bf_q, false); - TX_STAT_INC(txq->axq_qnum, a_aggr); - } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && status != ATH_AGGR_BAW_CLOSED); } @@ -1479,7 +1505,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, if (!bf) return; - bf->bf_state.bf_type |= BUF_AMPDU; + bf->bf_state.bf_type = BUF_AMPDU; INIT_LIST_HEAD(&bf_head); list_add(&bf->list, &bf_head); @@ -1489,7 +1515,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, /* Queue to h/w without aggregation */ TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf, fi->framelen); + ath_tx_fill_desc(sc, bf, fi->framelen); ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); } @@ -1509,14 +1535,14 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, INIT_LIST_HEAD(&bf_head); list_add_tail(&bf->list, &bf_head); - bf->bf_state.bf_type &= ~BUF_AMPDU; + bf->bf_state.bf_type = 0; /* update starting sequence number for subsequent ADDBA request */ if (tid) INCR(tid->seq_start, IEEE80211_SEQ_MAX); bf->bf_lastbf = bf; - ath_buf_set_rate(sc, bf, fi->framelen); + ath_tx_fill_desc(sc, bf, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); TX_STAT_INC(txq->axq_qnum, queued); } @@ -1790,8 +1816,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, frm_type = get_hw_packet_type(skb); ds = bf->bf_desc; - ath9k_hw_set_desc_link(ah, ds, 0); - ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, fi->keyix, fi->keytype, bf->bf_flags); @@ -1852,9 +1876,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, if (txctl->paprd) bf->bf_state.bfs_paprd_timestamp = jiffies; - if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) - ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true); - ath_tx_send_normal(sc, txctl->txq, tid, skb); } From 38dad7ba60475618d873fe703e7ef564a963fd1f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:18 +0200 Subject: [PATCH 199/287] ath9k: move ath_buf_set_rate to remove a forward declaration Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 283 +++++++++++++------------- 1 file changed, 141 insertions(+), 142 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 48ac9ff01ac0..485c0a3a9ce1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -56,7 +56,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int txok, int sendbar); static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, struct list_head *head, bool internal); -static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int nframes, int nbad, int txok, bool update_rc); @@ -845,6 +844,147 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, #undef PADBYTES } +/* + * rix - rate index + * pktlen - total bytes (delims + data + fcs + pads + pad delims) + * width - 0 for 20 MHz, 1 for 40 MHz + * half_gi - to use 4us v/s 3.6 us for symbol time + */ +static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, + int width, int half_gi, bool shortPreamble) +{ + u32 nbits, nsymbits, duration, nsymbols; + int streams; + + /* find number of symbols: PLCP + data */ + streams = HT_RC_2_STREAMS(rix); + nbits = (pktlen << 3) + OFDM_PLCP_BITS; + nsymbits = bits_per_symbol[rix % 8][width] * streams; + nsymbols = (nbits + nsymbits - 1) / nsymbits; + + if (!half_gi) + duration = SYMBOL_TIME(nsymbols); + else + duration = SYMBOL_TIME_HALFGI(nsymbols); + + /* addup duration for legacy/ht training and signal fields */ + duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); + + return duration; +} + +static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_11n_rate_series series[4]; + struct sk_buff *skb; + struct ieee80211_tx_info *tx_info; + struct ieee80211_tx_rate *rates; + const struct ieee80211_rate *rate; + struct ieee80211_hdr *hdr; + int i, flags = 0; + u8 rix = 0, ctsrate = 0; + bool is_pspoll; + + memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); + + skb = bf->bf_mpdu; + tx_info = IEEE80211_SKB_CB(skb); + rates = tx_info->control.rates; + hdr = (struct ieee80211_hdr *)skb->data; + is_pspoll = ieee80211_is_pspoll(hdr->frame_control); + + /* + * We check if Short Preamble is needed for the CTS rate by + * checking the BSS's global flag. + * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. + */ + rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); + ctsrate = rate->hw_value; + if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) + ctsrate |= rate->hw_value_short; + + for (i = 0; i < 4; i++) { + bool is_40, is_sgi, is_sp; + int phy; + + if (!rates[i].count || (rates[i].idx < 0)) + continue; + + rix = rates[i].idx; + series[i].Tries = rates[i].count; + + if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { + series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; + flags |= ATH9K_TXDESC_RTSENA; + } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; + flags |= ATH9K_TXDESC_CTSENA; + } + + if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + series[i].RateFlags |= ATH9K_RATESERIES_2040; + if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) + series[i].RateFlags |= ATH9K_RATESERIES_HALFGI; + + is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI); + is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH); + is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE); + + if (rates[i].flags & IEEE80211_TX_RC_MCS) { + /* MCS rates */ + series[i].Rate = rix | 0x80; + series[i].ChSel = ath_txchainmask_reduction(sc, + ah->txchainmask, series[i].Rate); + series[i].PktDuration = ath_pkt_duration(sc, rix, len, + is_40, is_sgi, is_sp); + if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) + series[i].RateFlags |= ATH9K_RATESERIES_STBC; + continue; + } + + /* legacy rates */ + if ((tx_info->band == IEEE80211_BAND_2GHZ) && + !(rate->flags & IEEE80211_RATE_ERP_G)) + phy = WLAN_RC_PHY_CCK; + else + phy = WLAN_RC_PHY_OFDM; + + rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; + series[i].Rate = rate->hw_value; + if (rate->hw_value_short) { + if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + series[i].Rate |= rate->hw_value_short; + } else { + is_sp = false; + } + + if (bf->bf_state.bfs_paprd) + series[i].ChSel = ah->txchainmask; + else + series[i].ChSel = ath_txchainmask_reduction(sc, + ah->txchainmask, series[i].Rate); + + series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, + phy, rate->bitrate * 100, len, rix, is_sp); + } + + /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ + if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) + flags &= ~ATH9K_TXDESC_RTSENA; + + /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ + if (flags & ATH9K_TXDESC_RTSENA) + flags &= ~ATH9K_TXDESC_CTSENA; + + /* set dur_update_en for l-sig computation except for PS-Poll frames */ + ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, + bf->bf_lastbf->bf_desc, + !is_pspoll, ctsrate, + 0, series, 4, flags); + +} + static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, int len) { struct ath_hw *ah = sc->sc_ah; @@ -1613,35 +1753,6 @@ static int setup_tx_flags(struct sk_buff *skb) return flags; } -/* - * rix - rate index - * pktlen - total bytes (delims + data + fcs + pads + pad delims) - * width - 0 for 20 MHz, 1 for 40 MHz - * half_gi - to use 4us v/s 3.6 us for symbol time - */ -static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, - int width, int half_gi, bool shortPreamble) -{ - u32 nbits, nsymbits, duration, nsymbols; - int streams; - - /* find number of symbols: PLCP + data */ - streams = HT_RC_2_STREAMS(rix); - nbits = (pktlen << 3) + OFDM_PLCP_BITS; - nsymbits = bits_per_symbol[rix % 8][width] * streams; - nsymbols = (nbits + nsymbits - 1) / nsymbits; - - if (!half_gi) - duration = SYMBOL_TIME(nsymbols); - else - duration = SYMBOL_TIME_HALFGI(nsymbols); - - /* addup duration for legacy/ht training and signal fields */ - duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); - - return duration; -} - u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) { struct ath_hw *ah = sc->sc_ah; @@ -1654,118 +1765,6 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) return chainmask; } -static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath9k_11n_rate_series series[4]; - struct sk_buff *skb; - struct ieee80211_tx_info *tx_info; - struct ieee80211_tx_rate *rates; - const struct ieee80211_rate *rate; - struct ieee80211_hdr *hdr; - int i, flags = 0; - u8 rix = 0, ctsrate = 0; - bool is_pspoll; - - memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); - - skb = bf->bf_mpdu; - tx_info = IEEE80211_SKB_CB(skb); - rates = tx_info->control.rates; - hdr = (struct ieee80211_hdr *)skb->data; - is_pspoll = ieee80211_is_pspoll(hdr->frame_control); - - /* - * We check if Short Preamble is needed for the CTS rate by - * checking the BSS's global flag. - * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. - */ - rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); - ctsrate = rate->hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) - ctsrate |= rate->hw_value_short; - - for (i = 0; i < 4; i++) { - bool is_40, is_sgi, is_sp; - int phy; - - if (!rates[i].count || (rates[i].idx < 0)) - continue; - - rix = rates[i].idx; - series[i].Tries = rates[i].count; - - if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { - series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; - flags |= ATH9K_TXDESC_RTSENA; - } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; - flags |= ATH9K_TXDESC_CTSENA; - } - - if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - series[i].RateFlags |= ATH9K_RATESERIES_2040; - if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) - series[i].RateFlags |= ATH9K_RATESERIES_HALFGI; - - is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI); - is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH); - is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE); - - if (rates[i].flags & IEEE80211_TX_RC_MCS) { - /* MCS rates */ - series[i].Rate = rix | 0x80; - series[i].ChSel = ath_txchainmask_reduction(sc, - ah->txchainmask, series[i].Rate); - series[i].PktDuration = ath_pkt_duration(sc, rix, len, - is_40, is_sgi, is_sp); - if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) - series[i].RateFlags |= ATH9K_RATESERIES_STBC; - continue; - } - - /* legacy rates */ - if ((tx_info->band == IEEE80211_BAND_2GHZ) && - !(rate->flags & IEEE80211_RATE_ERP_G)) - phy = WLAN_RC_PHY_CCK; - else - phy = WLAN_RC_PHY_OFDM; - - rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; - series[i].Rate = rate->hw_value; - if (rate->hw_value_short) { - if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - series[i].Rate |= rate->hw_value_short; - } else { - is_sp = false; - } - - if (bf->bf_state.bfs_paprd) - series[i].ChSel = ah->txchainmask; - else - series[i].ChSel = ath_txchainmask_reduction(sc, - ah->txchainmask, series[i].Rate); - - series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, - phy, rate->bitrate * 100, len, rix, is_sp); - } - - /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ - if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) - flags &= ~ATH9K_TXDESC_RTSENA; - - /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ - if (flags & ATH9K_TXDESC_RTSENA) - flags &= ~ATH9K_TXDESC_CTSENA; - - /* set dur_update_en for l-sig computation except for PS-Poll frames */ - ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, - bf->bf_lastbf->bf_desc, - !is_pspoll, ctsrate, - 0, series, 4, flags); - -} - /* * Assign a descriptor (and sequence number if necessary, * and map buffer for DMA. Frees skb on error From 7a2721a3233d32c958a474f78c20e25c9efa221c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:19 +0200 Subject: [PATCH 200/287] ath9k: call ath9k_hw_set_desc_link for beacon descriptors This ensures that only ath9k_hw_set_desc_link needs to recalculate the tx descriptor checksum on AR9380+ Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/beacon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 6d7088b02611..b97d01d2eece 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -111,6 +111,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, series, 4, 0); + ath9k_hw_set_desc_link(ah, ds, 0); } static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) From 60f8cc60fa41b8c44662a3a4d99862e3b81cfa6f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:20 +0200 Subject: [PATCH 201/287] ath9k_hw: do not recalculate the descriptor checksum in ar9003_hw_fill_txdesc Reduces the number of accesses to uncached descriptor memory. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index d08ab930e430..c3179d9bdc38 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -207,8 +207,7 @@ static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, ads->ctl3 &= AR_BufLen; /* Fill in pointer checksum and descriptor id */ - ads->ctl10 = ar9003_calc_ptr_chksum(ads); - ads->ctl10 |= (descid << AR_TxDescId_S); + ads->ctl10 = (descid << AR_TxDescId_S); if (is_firstseg) { ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore); From 2b63a41d14245345d6c498506c5634613afa80c0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:21 +0200 Subject: [PATCH 202/287] ath9k_hw: add a new API for setting tx descriptors Instead of using lots of different functions with long argument lists, pull all the necessary information from one struct. This makes the code easier to read and eliminates the need for copying data between multiple linked descriptors. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 101 ++++++++++++++++ drivers/net/wireless/ath/ath9k/ar9003_mac.c | 127 ++++++++++++++++++++ drivers/net/wireless/ath/ath9k/hw-ops.h | 6 + drivers/net/wireless/ath/ath9k/hw.h | 2 + drivers/net/wireless/ath/ath9k/mac.h | 40 +++++- 5 files changed, 275 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 33deb0d574b0..cb86c9577085 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -170,6 +170,106 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) return true; } +static void +ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) +{ + struct ar5416_desc *ads = AR5416DESC(ds); + u32 ctl1, ctl6; + + ads->ds_txstatus0 = ads->ds_txstatus1 = 0; + ads->ds_txstatus2 = ads->ds_txstatus3 = 0; + ads->ds_txstatus4 = ads->ds_txstatus5 = 0; + ads->ds_txstatus6 = ads->ds_txstatus7 = 0; + ads->ds_txstatus8 = ads->ds_txstatus9 = 0; + + ACCESS_ONCE(ads->ds_link) = i->link; + ACCESS_ONCE(ads->ds_data) = i->buf_addr[0]; + + ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore); + ctl6 = SM(i->keytype, AR_EncrType); + + if (AR_SREV_9285(ah)) { + ads->ds_ctl8 = 0; + ads->ds_ctl9 = 0; + ads->ds_ctl10 = 0; + ads->ds_ctl11 = 0; + } + + if ((i->is_first || i->is_last) && + i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) { + ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0) + | set11nTries(i->rates, 1) + | set11nTries(i->rates, 2) + | set11nTries(i->rates, 3) + | (i->dur_update ? AR_DurUpdateEna : 0) + | SM(0, AR_BurstDur); + + ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0) + | set11nRate(i->rates, 1) + | set11nRate(i->rates, 2) + | set11nRate(i->rates, 3); + } else { + ACCESS_ONCE(ads->ds_ctl2) = 0; + ACCESS_ONCE(ads->ds_ctl3) = 0; + } + + if (!i->is_first) { + ACCESS_ONCE(ads->ds_ctl0) = 0; + ACCESS_ONCE(ads->ds_ctl1) = ctl1; + ACCESS_ONCE(ads->ds_ctl6) = ctl6; + return; + } + + ctl1 |= (i->keyix != ATH9K_TXKEYIX_INVALID ? SM(i->keyix, AR_DestIdx) : 0) + | SM(i->type, AR_FrameType) + | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) + | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) + | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); + + switch (i->aggr) { + case AGGR_BUF_FIRST: + ctl6 |= SM(i->aggr_len, AR_AggrLen); + /* fall through */ + case AGGR_BUF_MIDDLE: + ctl1 |= AR_IsAggr | AR_MoreAggr; + ctl6 |= SM(i->ndelim, AR_PadDelim); + break; + case AGGR_BUF_LAST: + ctl1 |= AR_IsAggr; + break; + case AGGR_BUF_NONE: + break; + } + + ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen) + | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) + | SM(i->txpower, AR_XmitPower) + | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) + | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) + | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) + | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) + | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable : + (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)); + + ACCESS_ONCE(ads->ds_ctl1) = ctl1; + ACCESS_ONCE(ads->ds_ctl6) = ctl6; + + if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST) + return; + + ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0) + | set11nPktDurRTSCTS(i->rates, 1); + + ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2) + | set11nPktDurRTSCTS(i->rates, 3); + + ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0) + | set11nRateFlags(i->rates, 1) + | set11nRateFlags(i->rates, 2) + | set11nRateFlags(i->rates, 3) + | SM(i->rtscts_rate, AR_RTSCTSRate); +} + static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, bool is_firstseg, bool is_lastseg, const void *ds0, dma_addr_t buf_addr, @@ -433,6 +533,7 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) ops->rx_enable = ar9002_hw_rx_enable; ops->set_desc_link = ar9002_hw_set_desc_link; ops->get_isr = ar9002_hw_get_isr; + ops->set_txdesc = ar9002_set_txdesc; ops->fill_txdesc = ar9002_hw_fill_txdesc; ops->proc_txdesc = ar9002_hw_proc_txdesc; ops->set11n_txdesc = ar9002_hw_set11n_txdesc; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index c3179d9bdc38..e3382d5013c5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -21,6 +21,132 @@ static void ar9003_hw_rx_enable(struct ath_hw *hw) REG_WRITE(hw, AR_CR, 0); } +static void +ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) +{ + struct ar9003_txc *ads = ds; + int checksum = 0; + u32 val, ctl12, ctl17; + + val = (ATHEROS_VENDOR_ID << AR_DescId_S) | + (1 << AR_TxRxDesc_S) | + (1 << AR_CtrlStat_S) | + (i->qcu << AR_TxQcuNum_S) | 0x17; + + checksum += val; + ACCESS_ONCE(ads->info) = val; + + checksum += i->link; + ACCESS_ONCE(ads->link) = i->link; + + checksum += i->buf_addr[0]; + ACCESS_ONCE(ads->data0) = i->buf_addr[0]; + checksum += i->buf_addr[1]; + ACCESS_ONCE(ads->data1) = i->buf_addr[1]; + checksum += i->buf_addr[2]; + ACCESS_ONCE(ads->data2) = i->buf_addr[2]; + checksum += i->buf_addr[3]; + ACCESS_ONCE(ads->data3) = i->buf_addr[3]; + + checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen); + ACCESS_ONCE(ads->ctl3) = val; + checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen); + ACCESS_ONCE(ads->ctl5) = val; + checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen); + ACCESS_ONCE(ads->ctl7) = val; + checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen); + ACCESS_ONCE(ads->ctl9) = val; + + checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff); + ACCESS_ONCE(ads->ctl10) = checksum; + + if (i->is_first || i->is_last) { + ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0) + | set11nTries(i->rates, 1) + | set11nTries(i->rates, 2) + | set11nTries(i->rates, 3) + | (i->dur_update ? AR_DurUpdateEna : 0) + | SM(0, AR_BurstDur); + + ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0) + | set11nRate(i->rates, 1) + | set11nRate(i->rates, 2) + | set11nRate(i->rates, 3); + } else { + ACCESS_ONCE(ads->ctl13) = 0; + ACCESS_ONCE(ads->ctl14) = 0; + } + + ads->ctl20 = 0; + ads->ctl21 = 0; + ads->ctl22 = 0; + + ctl17 = SM(i->keytype, AR_EncrType); + if (!i->is_first) { + ACCESS_ONCE(ads->ctl11) = 0; + ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore; + ACCESS_ONCE(ads->ctl15) = 0; + ACCESS_ONCE(ads->ctl16) = 0; + ACCESS_ONCE(ads->ctl17) = ctl17; + ACCESS_ONCE(ads->ctl18) = 0; + ACCESS_ONCE(ads->ctl19) = 0; + return; + } + + ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen) + | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) + | SM(i->txpower, AR_XmitPower) + | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) + | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) + | (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0) + | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) + | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable : + (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)); + + ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ? + SM(i->keyix, AR_DestIdx) : 0) + | SM(i->type, AR_FrameType) + | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) + | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) + | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); + + ctl17 |= (i->flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0); + switch (i->aggr) { + case AGGR_BUF_FIRST: + ctl17 |= SM(i->aggr_len, AR_AggrLen); + /* fall through */ + case AGGR_BUF_MIDDLE: + ctl12 |= AR_IsAggr | AR_MoreAggr; + ctl17 |= SM(i->ndelim, AR_PadDelim); + break; + case AGGR_BUF_LAST: + ctl12 |= AR_IsAggr; + break; + case AGGR_BUF_NONE: + break; + } + + val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S; + ctl12 |= SM(val, AR_PAPRDChainMask); + + ACCESS_ONCE(ads->ctl12) = ctl12; + ACCESS_ONCE(ads->ctl17) = ctl17; + + ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0) + | set11nPktDurRTSCTS(i->rates, 1); + + ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2) + | set11nPktDurRTSCTS(i->rates, 3); + + ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0) + | set11nRateFlags(i->rates, 1) + | set11nRateFlags(i->rates, 2) + | set11nRateFlags(i->rates, 3) + | SM(i->rtscts_rate, AR_RTSCTSRate); + + ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding; +} + static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads) { int checksum; @@ -471,6 +597,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) ops->rx_enable = ar9003_hw_rx_enable; ops->set_desc_link = ar9003_hw_set_desc_link; ops->get_isr = ar9003_hw_get_isr; + ops->set_txdesc = ar9003_set_txdesc; ops->fill_txdesc = ar9003_hw_fill_txdesc; ops->proc_txdesc = ar9003_hw_proc_txdesc; ops->set11n_txdesc = ar9003_hw_set11n_txdesc; diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index dd9003ee123b..5310f9616506 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -54,6 +54,12 @@ static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) return ath9k_hw_ops(ah)->get_isr(ah, masked); } +static inline void ath9k_hw_set_txdesc(struct ath_hw *ah, void *ds, + struct ath_tx_info *i) +{ + return ath9k_hw_ops(ah)->set_txdesc(ah, ds, i); +} + static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen, bool is_firstseg, bool is_lastseg, const void *ds0, dma_addr_t buf_addr, diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 780cd0268ae1..0efe0134ff4a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -616,6 +616,8 @@ struct ath_hw_ops { u8 rxchainmask, bool longcal); bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked); + void (*set_txdesc)(struct ath_hw *ah, void *ds, + struct ath_tx_info *i); void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen, bool is_firstseg, bool is_is_lastseg, const void *ds0, dma_addr_t buf_addr, diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 2a523709ca9c..ca71bb4ae916 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -263,7 +263,11 @@ struct ath_desc { #define ATH9K_TXDESC_VMF 0x0100 #define ATH9K_TXDESC_FRAG_IS_ON 0x0200 #define ATH9K_TXDESC_LOWRXCHAIN 0x0400 -#define ATH9K_TXDESC_LDPC 0x00010000 +#define ATH9K_TXDESC_LDPC 0x0800 +#define ATH9K_TXDESC_CLRDMASK 0x1000 + +#define ATH9K_TXDESC_PAPRD 0x70000 +#define ATH9K_TXDESC_PAPRD_S 16 #define ATH9K_RXDESC_INTREQ 0x0020 @@ -660,6 +664,13 @@ struct ath9k_11n_rate_series { u32 RateFlags; }; +enum aggr_type { + AGGR_BUF_NONE, + AGGR_BUF_FIRST, + AGGR_BUF_MIDDLE, + AGGR_BUF_LAST, +}; + enum ath9k_key_type { ATH9K_KEY_TYPE_CLEAR, ATH9K_KEY_TYPE_WEP, @@ -667,6 +678,33 @@ enum ath9k_key_type { ATH9K_KEY_TYPE_TKIP, }; +struct ath_tx_info { + u8 qcu; + + bool is_first; + bool is_last; + + enum aggr_type aggr; + u8 ndelim; + u16 aggr_len; + + dma_addr_t link; + int pkt_len; + u32 flags; + + dma_addr_t buf_addr[4]; + int buf_len[4]; + + struct ath9k_11n_rate_series rates[4]; + u8 rtscts_rate; + bool dur_update; + + enum ath9k_pkt_type type; + enum ath9k_key_type keytype; + u8 keyix; + u8 txpower; +}; + struct ath_hw; struct ath9k_channel; enum ath9k_int; From 493cf04fd37bf265dc3c9aad357e3e34654c86e3 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:22 +0200 Subject: [PATCH 203/287] ath9k: use the new API for setting tx descriptors With the new API, tx descriptors can be written in one single pass instead of having to re-read and rewrite fields from multiple places. This makes the code easier to read and also slightly improves performance on embedded MIPS hardware. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 - drivers/net/wireless/ath/ath9k/beacon.c | 52 +++--- drivers/net/wireless/ath/ath9k/xmit.c | 229 ++++++++++-------------- 3 files changed, 122 insertions(+), 160 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4eba9577386b..94d887b65e69 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -228,7 +228,6 @@ struct ath_buf { dma_addr_t bf_daddr; /* physical addr of desc */ dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ bool bf_stale; - u16 bf_flags; struct ath_buf_state bf_state; }; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b97d01d2eece..9cdeaebc844f 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -73,45 +73,39 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, struct sk_buff *skb = bf->bf_mpdu; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - struct ath_desc *ds; - struct ath9k_11n_rate_series series[4]; - int flags, ctsrate = 0, ctsduration = 0; + struct ath_tx_info info; struct ieee80211_supported_band *sband; + u8 chainmask = ah->txchainmask; u8 rate = 0; ath9k_reset_beacon_status(sc); - ds = bf->bf_desc; - flags = ATH9K_TXDESC_NOACK; - - ds->ds_link = 0; - sband = &sc->sbands[common->hw->conf.channel->band]; rate = sband->bitrates[rateidx].hw_value; if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) rate |= sband->bitrates[rateidx].hw_value_short; - ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN, - ATH9K_PKT_TYPE_BEACON, - MAX_RATE_POWER, - ATH9K_TXKEYIX_INVALID, - ATH9K_KEY_TYPE_CLEAR, - flags); - - /* NB: beacon's BufLen must be a multiple of 4 bytes */ - ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), - true, true, ds, bf->bf_buf_addr, - sc->beacon.beaconq); - - memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); - series[0].Tries = 1; - series[0].Rate = rate; - series[0].ChSel = ath_txchainmask_reduction(sc, - ah->txchainmask, series[0].Rate); - series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0; - ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration, - series, 4, 0); - ath9k_hw_set_desc_link(ah, ds, 0); + memset(&info, 0, sizeof(info)); + info.pkt_len = skb->len + FCS_LEN; + info.type = ATH9K_PKT_TYPE_BEACON; + info.txpower = MAX_RATE_POWER; + info.keyix = ATH9K_TXKEYIX_INVALID; + info.keytype = ATH9K_KEY_TYPE_CLEAR; + info.flags = ATH9K_TXDESC_NOACK; + + info.buf_addr[0] = bf->bf_buf_addr; + info.buf_len[0] = roundup(skb->len, 4); + + info.is_first = true; + info.is_last = true; + + info.qcu = sc->beacon.beaconq; + + info.rates[0].Tries = 1; + info.rates[0].Rate = rate; + info.rates[0].ChSel = ath_txchainmask_reduction(sc, chainmask, rate); + + ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); } static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 485c0a3a9ce1..7f8191eddebe 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -504,7 +504,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, !txfail, sendbar); } else { /* retry the un-acked ones */ - ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false); if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { if (bf->bf_next == NULL && bf_last->bf_stale) { struct ath_buf *tbf; @@ -528,16 +527,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, break; } - ath9k_hw_cleartxdesc(sc->sc_ah, - tbf->bf_desc); fi->bf = tbf; - } else { - /* - * Clear descriptor status words for - * software retry - */ - ath9k_hw_cleartxdesc(sc->sc_ah, - bf->bf_desc); } } @@ -873,26 +863,25 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, return duration; } -static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) +static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, + struct ath_tx_info *info, int len) { struct ath_hw *ah = sc->sc_ah; - struct ath9k_11n_rate_series series[4]; struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *rates; const struct ieee80211_rate *rate; struct ieee80211_hdr *hdr; - int i, flags = 0; - u8 rix = 0, ctsrate = 0; - bool is_pspoll; - - memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); + int i; + u8 rix = 0; skb = bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); rates = tx_info->control.rates; hdr = (struct ieee80211_hdr *)skb->data; - is_pspoll = ieee80211_is_pspoll(hdr->frame_control); + + /* set dur_update_en for l-sig computation except for PS-Poll frames */ + info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); /* * We check if Short Preamble is needed for the CTS rate by @@ -900,9 +889,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. */ rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); - ctsrate = rate->hw_value; + info->rtscts_rate = rate->hw_value; if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) - ctsrate |= rate->hw_value_short; + info->rtscts_rate |= rate->hw_value_short; for (i = 0; i < 4; i++) { bool is_40, is_sgi, is_sp; @@ -912,20 +901,20 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) continue; rix = rates[i].idx; - series[i].Tries = rates[i].count; + info->rates[i].Tries = rates[i].count; if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) { - series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; - flags |= ATH9K_TXDESC_RTSENA; + info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; + info->flags |= ATH9K_TXDESC_RTSENA; } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; - flags |= ATH9K_TXDESC_CTSENA; + info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; + info->flags |= ATH9K_TXDESC_CTSENA; } if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - series[i].RateFlags |= ATH9K_RATESERIES_2040; + info->rates[i].RateFlags |= ATH9K_RATESERIES_2040; if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) - series[i].RateFlags |= ATH9K_RATESERIES_HALFGI; + info->rates[i].RateFlags |= ATH9K_RATESERIES_HALFGI; is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI); is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH); @@ -933,13 +922,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) if (rates[i].flags & IEEE80211_TX_RC_MCS) { /* MCS rates */ - series[i].Rate = rix | 0x80; - series[i].ChSel = ath_txchainmask_reduction(sc, - ah->txchainmask, series[i].Rate); - series[i].PktDuration = ath_pkt_duration(sc, rix, len, + info->rates[i].Rate = rix | 0x80; + info->rates[i].ChSel = ath_txchainmask_reduction(sc, + ah->txchainmask, info->rates[i].Rate); + info->rates[i].PktDuration = ath_pkt_duration(sc, rix, len, is_40, is_sgi, is_sp); if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) - series[i].RateFlags |= ATH9K_RATESERIES_STBC; + info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; continue; } @@ -951,74 +940,115 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len) phy = WLAN_RC_PHY_OFDM; rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; - series[i].Rate = rate->hw_value; + info->rates[i].Rate = rate->hw_value; if (rate->hw_value_short) { if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) - series[i].Rate |= rate->hw_value_short; + info->rates[i].Rate |= rate->hw_value_short; } else { is_sp = false; } if (bf->bf_state.bfs_paprd) - series[i].ChSel = ah->txchainmask; + info->rates[i].ChSel = ah->txchainmask; else - series[i].ChSel = ath_txchainmask_reduction(sc, - ah->txchainmask, series[i].Rate); + info->rates[i].ChSel = ath_txchainmask_reduction(sc, + ah->txchainmask, info->rates[i].Rate); - series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, + info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, phy, rate->bitrate * 100, len, rix, is_sp); } /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit)) - flags &= ~ATH9K_TXDESC_RTSENA; + info->flags &= ~ATH9K_TXDESC_RTSENA; /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ - if (flags & ATH9K_TXDESC_RTSENA) - flags &= ~ATH9K_TXDESC_CTSENA; + if (info->flags & ATH9K_TXDESC_RTSENA) + info->flags &= ~ATH9K_TXDESC_CTSENA; +} - /* set dur_update_en for l-sig computation except for PS-Poll frames */ - ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, - bf->bf_lastbf->bf_desc, - !is_pspoll, ctsrate, - 0, series, 4, flags); +static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + enum ath9k_pkt_type htype; + __le16 fc; + + hdr = (struct ieee80211_hdr *)skb->data; + fc = hdr->frame_control; + + if (ieee80211_is_beacon(fc)) + htype = ATH9K_PKT_TYPE_BEACON; + else if (ieee80211_is_probe_resp(fc)) + htype = ATH9K_PKT_TYPE_PROBE_RESP; + else if (ieee80211_is_atim(fc)) + htype = ATH9K_PKT_TYPE_ATIM; + else if (ieee80211_is_pspoll(fc)) + htype = ATH9K_PKT_TYPE_PSPOLL; + else + htype = ATH9K_PKT_TYPE_NORMAL; + return htype; } -static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, int len) +static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, + struct ath_txq *txq, int len) { struct ath_hw *ah = sc->sc_ah; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); struct ath_buf *bf_first = bf; - + struct ath_tx_info info; bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR); - bool clrdmask = !!(tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT); - u32 ds_next; + memset(&info, 0, sizeof(info)); + info.is_first = true; + info.is_last = true; + info.txpower = MAX_RATE_POWER; + info.qcu = txq->axq_qnum; + + info.flags = ATH9K_TXDESC_INTREQ; + if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) + info.flags |= ATH9K_TXDESC_NOACK; + if (tx_info->flags & IEEE80211_TX_CTL_LDPC) + info.flags |= ATH9K_TXDESC_LDPC; + + ath_buf_set_rate(sc, bf, &info, len); + + if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) + info.flags |= ATH9K_TXDESC_CLRDMASK; + + if (bf->bf_state.bfs_paprd) + info.flags |= (u32) bf->bf_state.bfs_paprd << ATH9K_TXDESC_PAPRD_S; - ath_buf_set_rate(sc, bf, len); while (bf) { + struct sk_buff *skb = bf->bf_mpdu; + struct ath_frame_info *fi = get_frame_info(skb); + + info.type = get_hw_packet_type(skb); if (bf->bf_next) - ds_next = bf->bf_next->bf_daddr; + info.link = bf->bf_next->bf_daddr; else - ds_next = 0; - - ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, clrdmask); - if (!aggr) - ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); - else if (!bf->bf_next) - ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_desc); - else { + info.link = 0; + + info.buf_addr[0] = bf->bf_buf_addr; + info.buf_len[0] = skb->len; + info.pkt_len = fi->framelen; + info.keyix = fi->keyix; + info.keytype = fi->keytype; + + if (aggr) { if (bf == bf_first) - ath9k_hw_set11n_aggr_first(sc->sc_ah, - bf->bf_desc, len); + info.aggr = AGGR_BUF_FIRST; + else if (!bf->bf_next) + info.aggr = AGGR_BUF_LAST; + else + info.aggr = AGGR_BUF_MIDDLE; - ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, - bf->bf_state.ndelim); + info.ndelim = bf->bf_state.ndelim; + info.aggr_len = len; } - ath9k_hw_set_desc_link(ah, bf->bf_desc, ds_next); + ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); bf = bf->bf_next; } } @@ -1066,7 +1096,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, TX_STAT_INC(txq->axq_qnum, a_aggr); } - ath_tx_fill_desc(sc, bf, aggr_len); + ath_tx_fill_desc(sc, bf, txq, aggr_len); ath_tx_txqaddbuf(sc, txq, &bf_q, false); } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && status != ATH_AGGR_BAW_CLOSED); @@ -1655,7 +1685,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, /* Queue to h/w without aggregation */ TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); bf->bf_lastbf = bf; - ath_tx_fill_desc(sc, bf, fi->framelen); + ath_tx_fill_desc(sc, bf, txctl->txq, fi->framelen); ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); } @@ -1682,34 +1712,11 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, INCR(tid->seq_start, IEEE80211_SEQ_MAX); bf->bf_lastbf = bf; - ath_tx_fill_desc(sc, bf, fi->framelen); + ath_tx_fill_desc(sc, bf, txq, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); TX_STAT_INC(txq->axq_qnum, queued); } -static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - enum ath9k_pkt_type htype; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - if (ieee80211_is_beacon(fc)) - htype = ATH9K_PKT_TYPE_BEACON; - else if (ieee80211_is_probe_resp(fc)) - htype = ATH9K_PKT_TYPE_PROBE_RESP; - else if (ieee80211_is_atim(fc)) - htype = ATH9K_PKT_TYPE_ATIM; - else if (ieee80211_is_pspoll(fc)) - htype = ATH9K_PKT_TYPE_PSPOLL; - else - htype = ATH9K_PKT_TYPE_NORMAL; - - return htype; -} - static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, int framelen) { @@ -1737,22 +1744,6 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, fi->framelen = framelen; } -static int setup_tx_flags(struct sk_buff *skb) -{ - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - int flags = 0; - - flags |= ATH9K_TXDESC_INTREQ; - - if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) - flags |= ATH9K_TXDESC_NOACK; - - if (tx_info->flags & IEEE80211_TX_CTL_LDPC) - flags |= ATH9K_TXDESC_LDPC; - - return flags; -} - u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) { struct ath_hw *ah = sc->sc_ah; @@ -1774,13 +1765,10 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_atx_tid *tid, struct sk_buff *skb) { - struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_frame_info *fi = get_frame_info(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath_buf *bf; - struct ath_desc *ds; - int frm_type; u16 seqno; bf = ath_tx_get_buffer(sc); @@ -1798,7 +1786,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, bf->bf_state.seqno = seqno; } - bf->bf_flags = setup_tx_flags(skb); bf->bf_mpdu = skb; bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, @@ -1812,20 +1799,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, goto error; } - frm_type = get_hw_packet_type(skb); - - ds = bf->bf_desc; - ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER, - fi->keyix, fi->keytype, bf->bf_flags); - - ath9k_hw_filltxdesc(ah, ds, - skb->len, /* segment length */ - true, /* first segment */ - true, /* last segment */ - ds, /* first descriptor */ - bf->bf_buf_addr, - txq->axq_qnum); - fi->bf = bf; return bf; @@ -1868,10 +1841,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, bf->bf_state.bfs_paprd = txctl->paprd; - if (bf->bf_state.bfs_paprd) - ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, - bf->bf_state.bfs_paprd); - if (txctl->paprd) bf->bf_state.bfs_paprd_timestamp = jiffies; @@ -2080,7 +2049,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, } if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && - (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { + (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0 && update_rc) { /* * If an underrun error is seen assume it as an excessive * retry only if max frame trigger level has been reached From 66ac69c8c3bd176b49c19e52c37449dec24c9588 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:23 +0200 Subject: [PATCH 204/287] ath9k_hw: remove the old tx descriptor API Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_mac.c | 176 ----------------- drivers/net/wireless/ath/ath9k/ar9003_mac.c | 203 -------------------- drivers/net/wireless/ath/ath9k/hw-ops.h | 58 ------ drivers/net/wireless/ath/ath9k/hw.h | 22 --- drivers/net/wireless/ath/ath9k/mac.c | 12 -- drivers/net/wireless/ath/ath9k/mac.h | 1 - 6 files changed, 472 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index cb86c9577085..f7d8e516a2a9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -270,35 +270,6 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) | SM(i->rtscts_rate, AR_RTSCTSRate); } -static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, - bool is_firstseg, bool is_lastseg, - const void *ds0, dma_addr_t buf_addr, - unsigned int qcu) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - ads->ds_data = buf_addr; - - if (is_firstseg) { - ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore); - } else if (is_lastseg) { - ads->ds_ctl0 = 0; - ads->ds_ctl1 = seglen; - ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; - ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; - } else { - ads->ds_ctl0 = 0; - ads->ds_ctl1 = seglen | AR_TxMore; - ads->ds_ctl2 = 0; - ads->ds_ctl3 = 0; - } - ads->ds_txstatus0 = ads->ds_txstatus1 = 0; - ads->ds_txstatus2 = ads->ds_txstatus3 = 0; - ads->ds_txstatus4 = ads->ds_txstatus5 = 0; - ads->ds_txstatus6 = ads->ds_txstatus7 = 0; - ads->ds_txstatus8 = ads->ds_txstatus9 = 0; -} - static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { @@ -371,145 +342,6 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, return 0; } -static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, - u32 pktLen, enum ath9k_pkt_type type, - u32 txPower, u8 keyIx, - enum ath9k_key_type keyType, u32 flags) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - if (txPower > 63) - txPower = 63; - - ads->ds_ctl0 = (pktLen & AR_FrameLen) - | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) - | SM(txPower, AR_XmitPower) - | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) - | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) - | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); - - ads->ds_ctl1 = - (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) - | SM(type, AR_FrameType) - | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) - | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) - | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); - - ads->ds_ctl6 = SM(keyType, AR_EncrType); - - if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { - ads->ds_ctl8 = 0; - ads->ds_ctl9 = 0; - ads->ds_ctl10 = 0; - ads->ds_ctl11 = 0; - } -} - -static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - if (val) - ads->ds_ctl0 |= AR_ClrDestMask; - else - ads->ds_ctl0 &= ~AR_ClrDestMask; -} - -static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, - void *lastds, - u32 durUpdateEn, u32 rtsctsRate, - u32 rtsctsDuration, - struct ath9k_11n_rate_series series[], - u32 nseries, u32 flags) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - struct ar5416_desc *last_ads = AR5416DESC(lastds); - u32 ds_ctl0; - - if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { - ds_ctl0 = ads->ds_ctl0; - - if (flags & ATH9K_TXDESC_RTSENA) { - ds_ctl0 &= ~AR_CTSEnable; - ds_ctl0 |= AR_RTSEnable; - } else { - ds_ctl0 &= ~AR_RTSEnable; - ds_ctl0 |= AR_CTSEnable; - } - - ads->ds_ctl0 = ds_ctl0; - } else { - ads->ds_ctl0 = - (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); - } - - ads->ds_ctl2 = set11nTries(series, 0) - | set11nTries(series, 1) - | set11nTries(series, 2) - | set11nTries(series, 3) - | (durUpdateEn ? AR_DurUpdateEna : 0) - | SM(0, AR_BurstDur); - - ads->ds_ctl3 = set11nRate(series, 0) - | set11nRate(series, 1) - | set11nRate(series, 2) - | set11nRate(series, 3); - - ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) - | set11nPktDurRTSCTS(series, 1); - - ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) - | set11nPktDurRTSCTS(series, 3); - - ads->ds_ctl7 = set11nRateFlags(series, 0) - | set11nRateFlags(series, 1) - | set11nRateFlags(series, 2) - | set11nRateFlags(series, 3) - | SM(rtsctsRate, AR_RTSCTSRate); - last_ads->ds_ctl2 = ads->ds_ctl2; - last_ads->ds_ctl3 = ads->ds_ctl3; -} - -static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, - u32 aggrLen) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); - ads->ds_ctl6 &= ~AR_AggrLen; - ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); -} - -static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, - u32 numDelims) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - unsigned int ctl6; - - ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); - - ctl6 = ads->ds_ctl6; - ctl6 &= ~AR_PadDelim; - ctl6 |= SM(numDelims, AR_PadDelim); - ads->ds_ctl6 = ctl6; -} - -static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - ads->ds_ctl1 |= AR_IsAggr; - ads->ds_ctl1 &= ~AR_MoreAggr; - ads->ds_ctl6 &= ~AR_PadDelim; -} - -static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); -} - void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags) { @@ -534,13 +366,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) ops->set_desc_link = ar9002_hw_set_desc_link; ops->get_isr = ar9002_hw_get_isr; ops->set_txdesc = ar9002_set_txdesc; - ops->fill_txdesc = ar9002_hw_fill_txdesc; ops->proc_txdesc = ar9002_hw_proc_txdesc; - ops->set11n_txdesc = ar9002_hw_set11n_txdesc; - ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario; - ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first; - ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle; - ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; - ops->clr11n_aggr = ar9002_hw_clr11n_aggr; - ops->set_clrdmask = ar9002_hw_set_clrdmask; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index e3382d5013c5..6cabc85bf61b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -311,46 +311,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) return true; } -static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, - bool is_firstseg, bool is_lastseg, - const void *ds0, dma_addr_t buf_addr, - unsigned int qcu) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - unsigned int descid = 0; - - ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) | - (1 << AR_TxRxDesc_S) | - (1 << AR_CtrlStat_S) | - (qcu << AR_TxQcuNum_S) | 0x17; - - ads->data0 = buf_addr; - ads->data1 = 0; - ads->data2 = 0; - ads->data3 = 0; - - ads->ctl3 = (seglen << AR_BufLen_S); - ads->ctl3 &= AR_BufLen; - - /* Fill in pointer checksum and descriptor id */ - ads->ctl10 = (descid << AR_TxDescId_S); - - if (is_firstseg) { - ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore); - } else if (is_lastseg) { - ads->ctl11 = 0; - ads->ctl12 = 0; - ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13; - ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14; - } else { - /* XXX Intermediate descriptor in a multi-descriptor frame.*/ - ads->ctl11 = 0; - ads->ctl12 = AR_TxMore; - ads->ctl13 = 0; - ads->ctl14 = 0; - } -} - static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { @@ -435,161 +395,6 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, return 0; } -static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, - u32 pktlen, enum ath9k_pkt_type type, u32 txpower, - u8 keyIx, enum ath9k_key_type keyType, u32 flags) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - - if (txpower > ah->txpower_limit) - txpower = ah->txpower_limit; - - if (txpower > 63) - txpower = 63; - - ads->ctl11 = (pktlen & AR_FrameLen) - | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) - | SM(txpower, AR_XmitPower) - | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) - | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) - | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); - - ads->ctl12 = - (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) - | SM(type, AR_FrameType) - | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) - | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) - | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); - - ads->ctl17 = SM(keyType, AR_EncrType) | - (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0); - ads->ctl18 = 0; - ads->ctl19 = AR_Not_Sounding; - - ads->ctl20 = 0; - ads->ctl21 = 0; - ads->ctl22 = 0; -} - -static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - - if (val) - ads->ctl11 |= AR_ClrDestMask; - else - ads->ctl11 &= ~AR_ClrDestMask; -} - -static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, - void *lastds, - u32 durUpdateEn, u32 rtsctsRate, - u32 rtsctsDuration, - struct ath9k_11n_rate_series series[], - u32 nseries, u32 flags) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds; - u_int32_t ctl11; - - if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { - ctl11 = ads->ctl11; - - if (flags & ATH9K_TXDESC_RTSENA) { - ctl11 &= ~AR_CTSEnable; - ctl11 |= AR_RTSEnable; - } else { - ctl11 &= ~AR_RTSEnable; - ctl11 |= AR_CTSEnable; - } - - ads->ctl11 = ctl11; - } else { - ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable)); - } - - ads->ctl13 = set11nTries(series, 0) - | set11nTries(series, 1) - | set11nTries(series, 2) - | set11nTries(series, 3) - | (durUpdateEn ? AR_DurUpdateEna : 0) - | SM(0, AR_BurstDur); - - ads->ctl14 = set11nRate(series, 0) - | set11nRate(series, 1) - | set11nRate(series, 2) - | set11nRate(series, 3); - - ads->ctl15 = set11nPktDurRTSCTS(series, 0) - | set11nPktDurRTSCTS(series, 1); - - ads->ctl16 = set11nPktDurRTSCTS(series, 2) - | set11nPktDurRTSCTS(series, 3); - - ads->ctl18 = set11nRateFlags(series, 0) - | set11nRateFlags(series, 1) - | set11nRateFlags(series, 2) - | set11nRateFlags(series, 3) - | SM(rtsctsRate, AR_RTSCTSRate); - ads->ctl19 = AR_Not_Sounding; - - last_ads->ctl13 = ads->ctl13; - last_ads->ctl14 = ads->ctl14; -} - -static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, - u32 aggrLen) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - - ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); - - ads->ctl17 &= ~AR_AggrLen; - ads->ctl17 |= SM(aggrLen, AR_AggrLen); -} - -static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, - u32 numDelims) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - unsigned int ctl17; - - ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); - - /* - * We use a stack variable to manipulate ctl6 to reduce uncached - * read modify, modfiy, write. - */ - ctl17 = ads->ctl17; - ctl17 &= ~AR_PadDelim; - ctl17 |= SM(numDelims, AR_PadDelim); - ads->ctl17 = ctl17; -} - -static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - - ads->ctl12 |= AR_IsAggr; - ads->ctl12 &= ~AR_MoreAggr; - ads->ctl17 &= ~AR_PadDelim; -} - -static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds) -{ - struct ar9003_txc *ads = (struct ar9003_txc *) ds; - - ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr); -} - -void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) -{ - struct ar9003_txc *ads = ds; - - ads->ctl12 |= SM(chains, AR_PAPRDChainMask); -} -EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc); - void ar9003_hw_attach_mac_ops(struct ath_hw *hw) { struct ath_hw_ops *ops = ath9k_hw_ops(hw); @@ -598,15 +403,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) ops->set_desc_link = ar9003_hw_set_desc_link; ops->get_isr = ar9003_hw_get_isr; ops->set_txdesc = ar9003_set_txdesc; - ops->fill_txdesc = ar9003_hw_fill_txdesc; ops->proc_txdesc = ar9003_hw_proc_txdesc; - ops->set11n_txdesc = ar9003_hw_set11n_txdesc; - ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario; - ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first; - ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle; - ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; - ops->clr11n_aggr = ar9003_hw_clr11n_aggr; - ops->set_clrdmask = ar9003_hw_set_clrdmask; } void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 5310f9616506..41f4bf363d3d 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -60,70 +60,12 @@ static inline void ath9k_hw_set_txdesc(struct ath_hw *ah, void *ds, return ath9k_hw_ops(ah)->set_txdesc(ah, ds, i); } -static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen, - bool is_firstseg, bool is_lastseg, - const void *ds0, dma_addr_t buf_addr, - unsigned int qcu) -{ - ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg, - ds0, buf_addr, qcu); -} - static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts); } -static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds, - u32 pktLen, enum ath9k_pkt_type type, - u32 txPower, u32 keyIx, - enum ath9k_key_type keyType, - u32 flags) -{ - ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx, - keyType, flags); -} - -static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, - void *lastds, - u32 durUpdateEn, u32 rtsctsRate, - u32 rtsctsDuration, - struct ath9k_11n_rate_series series[], - u32 nseries, u32 flags) -{ - ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn, - rtsctsRate, rtsctsDuration, series, - nseries, flags); -} - -static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, - u32 aggrLen) -{ - ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen); -} - -static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, - u32 numDelims) -{ - ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims); -} - -static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) -{ - ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds); -} - -static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds) -{ - ath9k_hw_ops(ah)->clr11n_aggr(ah, ds); -} - -static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) -{ - ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); -} - static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, struct ath_hw_antcomb_conf *antconf) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 0efe0134ff4a..bf38e2fc8f78 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -618,30 +618,8 @@ struct ath_hw_ops { bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked); void (*set_txdesc)(struct ath_hw *ah, void *ds, struct ath_tx_info *i); - void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen, - bool is_firstseg, bool is_is_lastseg, - const void *ds0, dma_addr_t buf_addr, - unsigned int qcu); int (*proc_txdesc)(struct ath_hw *ah, void *ds, struct ath_tx_status *ts); - void (*set11n_txdesc)(struct ath_hw *ah, void *ds, - u32 pktLen, enum ath9k_pkt_type type, - u32 txPower, u8 keyIx, - enum ath9k_key_type keyType, - u32 flags); - void (*set11n_ratescenario)(struct ath_hw *ah, void *ds, - void *lastds, - u32 durUpdateEn, u32 rtsctsRate, - u32 rtsctsDuration, - struct ath9k_11n_rate_series series[], - u32 nseries, u32 flags); - void (*set11n_aggr_first)(struct ath_hw *ah, void *ds, - u32 aggrLen); - void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds, - u32 numDelims); - void (*set11n_aggr_last)(struct ath_hw *ah, void *ds); - void (*clr11n_aggr)(struct ath_hw *ah, void *ds); - void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); void (*antdiv_comb_conf_get)(struct ath_hw *ah, struct ath_hw_antcomb_conf *antconf); void (*antdiv_comb_conf_set)(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 7ce9b320f0d9..786587ac40a7 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -62,18 +62,6 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q) } EXPORT_SYMBOL(ath9k_hw_txstart); -void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds) -{ - struct ar5416_desc *ads = AR5416DESC(ds); - - ads->ds_txstatus0 = ads->ds_txstatus1 = 0; - ads->ds_txstatus2 = ads->ds_txstatus3 = 0; - ads->ds_txstatus4 = ads->ds_txstatus5 = 0; - ads->ds_txstatus6 = ads->ds_txstatus7 = 0; - ads->ds_txstatus8 = ads->ds_txstatus9 = 0; -} -EXPORT_SYMBOL(ath9k_hw_cleartxdesc); - u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) { u32 npend; diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index ca71bb4ae916..ac5a1d265d39 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -712,7 +712,6 @@ enum ath9k_int; u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); void ath9k_hw_txstart(struct ath_hw *ah, u32 q); -void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds); u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); From c6c539f023423a7a730f5759be1b3b45c2d1d1ca Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:24 +0200 Subject: [PATCH 205/287] ath9k: optimize ath9k_ps_restore ath_hw_cycle_counters_update only needs to be called if the power state changes. Most of the time this does not happen, even when ps_usecount goes down to 0. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8149511e8f7e..7910165cf0e6 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -111,24 +111,29 @@ void ath9k_ps_wakeup(struct ath_softc *sc) void ath9k_ps_restore(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); + enum ath9k_power_mode mode; unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (--sc->ps_usecount != 0) goto unlock; - spin_lock(&common->cc_lock); - ath_hw_cycle_counters_update(common); - spin_unlock(&common->cc_lock); - if (sc->ps_idle) - ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); + mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA | PS_WAIT_FOR_TX_ACK))) - ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); + mode = ATH9K_PM_NETWORK_SLEEP; + else + goto unlock; + + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + spin_unlock(&common->cc_lock); + + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); unlock: spin_unlock_irqrestore(&sc->sc_pm_lock, flags); From bdf2dbfb084f421dc6dc2f2234194ddb6ec2ea8d Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:25 +0200 Subject: [PATCH 206/287] ath9k: remove a redundant check in ath_tx_form_aggr ath_lookup_legacy now checks all the tx rate flags for MCS vs legacy Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 7f8191eddebe..634a29a946d3 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -790,8 +790,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, } tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); - if (nframes && ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || - !(tx_info->control.rates[0].flags & IEEE80211_TX_RC_MCS))) + if (nframes && (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) break; /* do not exceed subframe limit */ From 3afd21e7c5b3b6312193fbee628b000dce82ecf5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:26 +0200 Subject: [PATCH 207/287] ath9k: optimize ath_tx_rc_status usage The only flag that needs to be set when ath_tx_rc_status is called with rc_update == false is the IEEE80211_TX_STAT_TX_FILTERED flag. All other data is ignored in that case. This flag can be set from ath_tx_complete_buf instead, so that we can drop a few redundant calls to ath_tx_rc_status and remove the rc_update function parameter Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 29 ++++++++++++--------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 634a29a946d3..a0cd51f28596 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -58,7 +58,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, struct list_head *head, bool internal); static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int nframes, int nbad, - int txok, bool update_rc); + int txok); static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, int seqno); static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, @@ -392,7 +392,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (!bf->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); - ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0, 0); @@ -494,10 +493,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { memcpy(tx_info->control.rates, rates, sizeof(rates)); - ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, true); + ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok); rc_update = false; - } else { - ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, false); } ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, @@ -519,8 +516,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, ath_tx_update_baw(sc, tid, seqno); spin_unlock_bh(&txq->axq_lock); - ath_tx_rc_status(sc, bf, ts, nframes, - nbad, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0, 1); @@ -1983,6 +1978,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int txok, int sendbar) { struct sk_buff *skb = bf->bf_mpdu; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); unsigned long flags; int tx_flags = 0; @@ -1992,6 +1988,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, if (!txok) tx_flags |= ATH_TX_ERROR; + if (ts->ts_status & ATH9K_TXERR_FILT) + tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); bf->bf_buf_addr = 0; @@ -2021,7 +2020,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int nframes, int nbad, - int txok, bool update_rc) + int txok) { struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -2036,9 +2035,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, tx_rateindex = ts->ts_rateindex; WARN_ON(tx_rateindex >= hw->max_rates); - if (ts->ts_status & ATH9K_TXERR_FILT) - tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { tx_info->flags |= IEEE80211_TX_STAT_AMPDU; BUG_ON(nbad > nframes); @@ -2048,7 +2045,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, } if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && - (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0 && update_rc) { + (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) { /* * If an underrun error is seen assume it as an excessive * retry only if max frame trigger level has been reached @@ -2061,9 +2058,9 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, * successfully by eventually preferring slower rates. * This itself should also alleviate congestion on the bus. */ - if (ieee80211_is_data(hdr->frame_control) && - (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | - ATH9K_TX_DELIM_UNDERRUN)) && + if (unlikely(ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN | + ATH9K_TX_DELIM_UNDERRUN)) && + ieee80211_is_data(hdr->frame_control) && ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level) tx_info->status.rates[tx_rateindex].count = hw->max_rate_tries; @@ -2094,7 +2091,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, spin_unlock_bh(&txq->axq_lock); if (!bf_isampdu(bf)) { - ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true); + ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0); } else ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); From 4245d31347bdc99a608dc1d1cfe64e44aa3d1771 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Sep 2011 21:24:27 +0200 Subject: [PATCH 208/287] ath9k: do not insert padding into tx buffers on AR9380+ With the new EDMA descriptor format, a single descriptor can contain up to four buffer pointers. By splitting the buffer into two parts, we can let the hardware add the padding internally instead of using memmove on the skb data. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 56 ++++++++++++++++++--------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a0cd51f28596..2c6aefad3728 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1017,6 +1017,8 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, while (bf) { struct sk_buff *skb = bf->bf_mpdu; struct ath_frame_info *fi = get_frame_info(skb); + struct ieee80211_hdr *hdr; + int padpos, padsize; info.type = get_hw_packet_type(skb); if (bf->bf_next) @@ -1024,8 +1026,20 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, else info.link = 0; - info.buf_addr[0] = bf->bf_buf_addr; - info.buf_len[0] = skb->len; + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + hdr = (struct ieee80211_hdr *)skb->data; + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + + info.buf_addr[0] = bf->bf_buf_addr; + info.buf_len[0] = padpos + padsize; + info.buf_addr[1] = info.buf_addr[0] + padpos; + info.buf_len[1] = skb->len - padpos; + } else { + info.buf_addr[0] = bf->bf_buf_addr; + info.buf_len[0] = skb->len; + } + info.pkt_len = fi->framelen; info.keyix = fi->keyix; info.keytype = fi->keytype; @@ -1878,15 +1892,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } - /* Add the padding after the header if this is not already done */ - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - if (padsize && skb->len > padpos) { - if (skb_headroom(skb) < padsize) - return -ENOMEM; + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { + /* Add the padding after the header if this is not already done */ + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len > padpos) { + if (skb_headroom(skb) < padsize) + return -ENOMEM; - skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, padpos); + skb_push(skb, padsize); + memmove(skb->data, skb->data + padsize, padpos); + } } if ((vif && vif->type != NL80211_IFTYPE_AP && @@ -1936,15 +1952,17 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - if (padsize && skb->len>padpos+padsize) { - /* - * Remove MAC header padding before giving the frame back to - * mac80211. - */ - memmove(skb->data + padsize, skb->data, padpos); - skb_pull(skb, padsize); + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len>padpos+padsize) { + /* + * Remove MAC header padding before giving the frame back to + * mac80211. + */ + memmove(skb->data + padsize, skb->data, padpos); + skb_pull(skb, padsize); + } } if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { From 7107676a3a46415c27186bc7d5ce988498897c66 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 15 Sep 2011 09:37:46 +0200 Subject: [PATCH 209/287] mac80211: fix endian issues and comments for BAR failure handling Signed-off-by: Felix Fietkau Cc: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/status.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 14268465f1d8..d50358c45ab0 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -278,17 +278,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) } if (!acked && ieee80211_is_back_req(fc)) { + u16 control; + /* - * BAR failed, let's tear down the BA session as a - * last resort as some STAs (Intel 5100 on Windows) - * can get stuck when the BA window isn't flushed - * correctly. + * BAR failed, store the last SSN and retry sending + * the BAR when the next unicast transmission on the + * same TID succeeds. */ bar = (struct ieee80211_bar *) skb->data; - if (!(bar->control & IEEE80211_BAR_CTRL_MULTI_TID)) { + control = le16_to_cpu(bar->control); + if (!(control & IEEE80211_BAR_CTRL_MULTI_TID)) { u16 ssn = le16_to_cpu(bar->start_seq_num); - tid = (bar->control & + tid = (control & IEEE80211_BAR_CTRL_TID_INFO_MASK) >> IEEE80211_BAR_CTRL_TID_INFO_SHIFT; From 12e62d6f7ec475e546b40bece2045da15d6c21ef Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 13 Sep 2011 10:21:25 +0300 Subject: [PATCH 210/287] MAINTAINERS: update ath6kl It's not in staging anymore and I'm the current maintainer. Cc: Luis R. Rodriguez Cc: Naveen Singh Signed-off-by: Kalle Valo Signed-off-by: John W. Linville --- MAINTAINERS | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index c66c093978d7..ce0e60c7b07a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1246,6 +1246,14 @@ W: http://wireless.kernel.org/en/users/Drivers/ath5k S: Maintained F: drivers/net/wireless/ath/ath5k/ +ATHEROS ATH6KL WIRELESS DRIVER +M: Kalle Valo +L: linux-wireless@vger.kernel.org +W: http://wireless.kernel.org/en/users/Drivers/ath6kl +T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath6kl.git +S: Supported +F: drivers/net/wireless/ath/ath6kl/ + ATHEROS ATH9K WIRELESS DRIVER M: "Luis R. Rodriguez" M: Jouni Malinen @@ -6122,12 +6130,6 @@ M: Jakub Schmidtke S: Odd Fixes F: drivers/staging/asus_oled/ -STAGING - ATHEROS ATH6KL WIRELESS DRIVER -M: Luis R. Rodriguez -M: Naveen Singh -S: Odd Fixes -F: drivers/staging/ath6kl/ - STAGING - COMEDI M: Ian Abbott M: Mori Hess From 8be964d2364e8fbe302850f60d9d514c3e134510 Mon Sep 17 00:00:00 2001 From: Chen Ganir Date: Tue, 30 Aug 2011 13:58:28 +0300 Subject: [PATCH 211/287] Bluetooth: Fixed BT ST Channel reg order Reordered the BT ST channel registration, to make sure that the event channel is registered before all others. This prevents a situation where incoming events may cause kernel panic in the ST driver if the event channel is not yet registered to handle incoming events.In addition, the deregistration of the channels was also modified, to be in the reversed order of the registration, to allow the event channel to be the last one unregistered. Signed-off-by: Chen Ganir Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btwilink.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c index 65d27aff553a..04d353f58d71 100644 --- a/drivers/bluetooth/btwilink.c +++ b/drivers/bluetooth/btwilink.c @@ -124,6 +124,13 @@ static long st_receive(void *priv_data, struct sk_buff *skb) /* ------- Interfaces to HCI layer ------ */ /* protocol structure registered with shared transport */ static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { + { + .chnl_id = HCI_EVENT_PKT, /* HCI Events */ + .hdr_len = sizeof(struct hci_event_hdr), + .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen), + .len_size = 1, /* sizeof(plen) in struct hci_event_hdr */ + .reserve = 8, + }, { .chnl_id = HCI_ACLDATA_PKT, /* ACL */ .hdr_len = sizeof(struct hci_acl_hdr), @@ -138,13 +145,6 @@ static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { .len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */ .reserve = 8, }, - { - .chnl_id = HCI_EVENT_PKT, /* HCI Events */ - .hdr_len = sizeof(struct hci_event_hdr), - .offset_len_in_hdr = offsetof(struct hci_event_hdr, plen), - .len_size = 1, /* sizeof(plen) in struct hci_event_hdr */ - .reserve = 8, - }, }; /* Called from HCI core to initialize the device */ @@ -240,7 +240,7 @@ static int ti_st_close(struct hci_dev *hdev) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; - for (i = 0; i < MAX_BT_CHNL_IDS; i++) { + for (i = MAX_BT_CHNL_IDS-1; i >= 0; i--) { err = st_unregister(&ti_st_proto[i]); if (err) BT_ERR("st_unregister(%d) failed with error %d", From a63b723d02531f7add0b2b8a0e6a77ee176f1626 Mon Sep 17 00:00:00 2001 From: Pieter-Augustijn Van Malleghem Date: Wed, 7 Sep 2011 02:28:10 -0400 Subject: [PATCH 212/287] Bluetooth: Add MacBookAir4,1 support This patch against current git adds the hardware ID for the Apple MacBookAir4,1, released in July 2011. The device features a BCM2046 USB chip. The patch was inspired by the previous modifications adding support for the MacBookAir3,x. Signed-off-by: Pieter-Augustijn Van Malleghem Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3ef476070baf..60c748a32ed5 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -72,6 +72,9 @@ static struct usb_device_id btusb_table[] = { /* Apple MacBookAir3,1, MacBookAir3,2 */ { USB_DEVICE(0x05ac, 0x821b) }, + /* Apple MacBookAir4,1 */ + { USB_DEVICE(0x05ac, 0x821f) }, + /* Apple MacBookPro8,2 */ { USB_DEVICE(0x05ac, 0x821a) }, From f78b68261e80899f81a21dfdf91e2a1456ea8175 Mon Sep 17 00:00:00 2001 From: Jurgen Kramer Date: Sun, 4 Sep 2011 18:01:42 +0200 Subject: [PATCH 213/287] Bluetooth: add support for 2011 mac mini Today I noticed that the usb bluetooth adapter (BCM2046B1) on my 2011 mac mini was not working. I've created a patch to get it going. Signed-off-by: Jurgen Kramer Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 60c748a32ed5..9cbac6b445e1 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -78,6 +78,9 @@ static struct usb_device_id btusb_table[] = { /* Apple MacBookPro8,2 */ { USB_DEVICE(0x05ac, 0x821a) }, + /* Apple MacMini5,1 */ + { USB_DEVICE(0x05ac, 0x8281) }, + /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, From 8c23516fbb209ccf8f8c36268311c721faff29ee Mon Sep 17 00:00:00 2001 From: Manual Munz Date: Sun, 18 Sep 2011 18:24:03 -0500 Subject: [PATCH 214/287] b43: Fix beacon problem in ad-hoc mode In ad-hoc mode, driver b43 does not issue beacons. Signed-off-by: Manual Munz Tested-by: Larry Finger Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 26f1ab840cc7..e293a7921bf0 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1632,7 +1632,8 @@ static void handle_irq_beacon(struct b43_wldev *dev) u32 cmd, beacon0_valid, beacon1_valid; if (!b43_is_mode(wl, NL80211_IFTYPE_AP) && - !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) + !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) && + !b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) return; /* This is the bottom half of the asynchronous beacon update. */ From 42cecc3465578e442b794851fd8802dcb85a192c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 19 Sep 2011 15:42:31 -0400 Subject: [PATCH 215/287] Revert "ath9k: do not insert padding into tx buffers on AR9380+" This reverts commit 4245d31347bdc99a608dc1d1cfe64e44aa3d1771. --- drivers/net/wireless/ath/ath9k/xmit.c | 56 +++++++++------------------ 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2c6aefad3728..a0cd51f28596 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1017,8 +1017,6 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, while (bf) { struct sk_buff *skb = bf->bf_mpdu; struct ath_frame_info *fi = get_frame_info(skb); - struct ieee80211_hdr *hdr; - int padpos, padsize; info.type = get_hw_packet_type(skb); if (bf->bf_next) @@ -1026,20 +1024,8 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, else info.link = 0; - if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - hdr = (struct ieee80211_hdr *)skb->data; - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - - info.buf_addr[0] = bf->bf_buf_addr; - info.buf_len[0] = padpos + padsize; - info.buf_addr[1] = info.buf_addr[0] + padpos; - info.buf_len[1] = skb->len - padpos; - } else { - info.buf_addr[0] = bf->bf_buf_addr; - info.buf_len[0] = skb->len; - } - + info.buf_addr[0] = bf->bf_buf_addr; + info.buf_len[0] = skb->len; info.pkt_len = fi->framelen; info.keyix = fi->keyix; info.keytype = fi->keytype; @@ -1892,17 +1878,15 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { - /* Add the padding after the header if this is not already done */ - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - if (padsize && skb->len > padpos) { - if (skb_headroom(skb) < padsize) - return -ENOMEM; + /* Add the padding after the header if this is not already done */ + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len > padpos) { + if (skb_headroom(skb) < padsize) + return -ENOMEM; - skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, padpos); - } + skb_push(skb, padsize); + memmove(skb->data, skb->data + padsize, padpos); } if ((vif && vif->type != NL80211_IFTYPE_AP && @@ -1952,17 +1936,15 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { - padpos = ath9k_cmn_padpos(hdr->frame_control); - padsize = padpos & 3; - if (padsize && skb->len>padpos+padsize) { - /* - * Remove MAC header padding before giving the frame back to - * mac80211. - */ - memmove(skb->data + padsize, skb->data, padpos); - skb_pull(skb, padsize); - } + padpos = ath9k_cmn_padpos(hdr->frame_control); + padsize = padpos & 3; + if (padsize && skb->len>padpos+padsize) { + /* + * Remove MAC header padding before giving the frame back to + * mac80211. + */ + memmove(skb->data + padsize, skb->data, padpos); + skb_pull(skb, padsize); } if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) { From 6e82bc4a5bf3a1ce597324c8667baa6a2ed12604 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 15 Sep 2011 10:03:12 +0200 Subject: [PATCH 216/287] ath9k: fix setting the IEEE80211_TX_CTL_CLEAR_PS_FILT flag When the driver inserts padding between the 802.11 header and data, it needs to set the hdr variable to the new header location. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a0cd51f28596..82718ee1386d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1887,6 +1887,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, skb_push(skb, padsize); memmove(skb->data, skb->data + padsize, padpos); + hdr = (struct ieee80211_hdr *) skb->data; } if ((vif && vif->type != NL80211_IFTYPE_AP && From 0c28ec587a2f061b93a98ac02a53b4152cbe48f4 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 15 Sep 2011 11:53:01 +0300 Subject: [PATCH 217/287] cfg80211: add cfg80211_find_vendor_ie() function Add function to find vendor-specific ie (along with vendor-specific ie struct definition and P2P OUI values) Signed-off-by: Eliad Peller Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 10 ++++++++++ include/net/cfg80211.h | 18 ++++++++++++++++++ net/wireless/scan.c | 27 +++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 72f3933938c0..b5e0a5c344fd 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -777,6 +777,13 @@ struct ieee80211_mmie { u8 mic[8]; } __attribute__ ((packed)); +struct ieee80211_vendor_ie { + u8 element_id; + u8 len; + u8 oui[3]; + u8 oui_type; +} __packed; + /* Control frames */ struct ieee80211_rts { __le16 frame_control; @@ -1470,6 +1477,9 @@ enum ieee80211_sa_query_action { #define WLAN_PMKID_LEN 16 +#define WLAN_OUI_WFA 0x506f9a +#define WLAN_OUI_TYPE_WFA_P2P 9 + /* * WMM/802.11e Tspec Element */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b42136a61f3a..9518b5cfb822 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2458,6 +2458,24 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb); */ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len); +/** + * cfg80211_find_vendor_ie - find vendor specific information element in data + * + * @oui: vendor OUI + * @oui_type: vendor-specific OUI type + * @ies: data consisting of IEs + * @len: length of data + * + * This function will return %NULL if the vendor specific element ID + * could not be found or if the element is invalid (claims to be + * longer than the given data), or a pointer to the first byte + * of the requested element, that is the byte containing the + * element ID. There are no checks on the element length + * other than having to fit into the given data. + */ +const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, + const u8 *ies, int len); + /** * DOC: Regulatory enforcement infrastructure * diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b0f003966953..0fb142410404 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -228,6 +228,33 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) } EXPORT_SYMBOL(cfg80211_find_ie); +const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, + const u8 *ies, int len) +{ + struct ieee80211_vendor_ie *ie; + const u8 *pos = ies, *end = ies + len; + int ie_oui; + + while (pos < end) { + pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, + end - pos); + if (!pos) + return NULL; + + if (end - pos < sizeof(*ie)) + return NULL; + + ie = (struct ieee80211_vendor_ie *)pos; + ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; + if (ie_oui == oui && ie->oui_type == oui_type) + return pos; + + pos += 2 + ie->len; + } + return NULL; +} +EXPORT_SYMBOL(cfg80211_find_vendor_ie); + static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) { const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); From f11cc949fd9fed7040eba39eab11e7bee274b527 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 15 Sep 2011 12:59:49 +0200 Subject: [PATCH 218/287] ath9k: sync the dma buffer after changing the retry flag Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 82718ee1386d..fa3dcfdf7174 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -262,6 +262,7 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, struct sk_buff *skb) { struct ath_frame_info *fi = get_frame_info(skb); + struct ath_buf *bf = fi->bf; struct ieee80211_hdr *hdr; TX_STAT_INC(txq->axq_qnum, a_retries); @@ -270,6 +271,8 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, hdr = (struct ieee80211_hdr *)skb->data; hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); + dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, + sizeof(*hdr), DMA_TO_DEVICE); } static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) From 1b8714f7dcd8b41cd2843c42a6cc16ba2d4c899f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 15 Sep 2011 14:25:35 +0200 Subject: [PATCH 219/287] ath9k_hw: clean up hardware revision checks - AR_SREV_5416_20_OR_LATER is always true, remove it - AR_SREV_9280_20_OR_LATER is always true within eeprom_4k.c and eeprom_9287.c - (AR_SREV_9271 || AR_SREV_9285) is always true in eeprom_4k.c Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 3 +- drivers/net/wireless/ath/ath9k/eeprom.c | 7 +- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 85 +++++++++----------- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 6 +- drivers/net/wireless/ath/ath9k/eeprom_def.c | 46 +++++------ drivers/net/wireless/ath/ath9k/mac.c | 2 +- drivers/net/wireless/ath/ath9k/mac.h | 4 - drivers/net/wireless/ath/ath9k/reg.h | 4 - 8 files changed, 63 insertions(+), 94 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index fac2c6da6ca4..b130c26d3dd0 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -704,8 +704,7 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, REG_WRITE(ah, AR_PCU_MISC_MODE2, val); } - if (!AR_SREV_5416_20_OR_LATER(ah) || - AR_SREV_9280_20_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) return; /* * Disable BB clock gating diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index e61404dda8c5..e46f751ab508 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -456,12 +456,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah, pPdGainBoundaries[i] = min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]); - if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) { - minDelta = pPdGainBoundaries[0] - 23; - pPdGainBoundaries[0] = 23; - } else { - minDelta = 0; - } + minDelta = 0; if (i == 0) { if (AR_SREV_9280_20_OR_LATER(ah)) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index ea658e794cbd..99f7a08c57e2 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -405,12 +405,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0); for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { - if (AR_SREV_5416_20_OR_LATER(ah) && - (ah->rxchainmask == 5 || ah->txchainmask == 5) && - (i != 0)) { - regChainOffset = (i == 1) ? 0x2000 : 0x1000; - } else - regChainOffset = i * 0x1000; + regChainOffset = i * 0x1000; if (pEepData->baseEepHeader.txMask & (1 << i)) { pRawDataset = pEepData->calPierData2G[i]; @@ -423,19 +418,17 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, ENABLE_REGWRITE_BUFFER(ah); - if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { - REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, - SM(pdGainOverlap_t2, - AR_PHY_TPCRG5_PD_GAIN_OVERLAP) - | SM(gainBoundaries[0], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) - | SM(gainBoundaries[1], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) - | SM(gainBoundaries[2], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) - | SM(gainBoundaries[3], - AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); - } + REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, + SM(pdGainOverlap_t2, + AR_PHY_TPCRG5_PD_GAIN_OVERLAP) + | SM(gainBoundaries[0], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) + | SM(gainBoundaries[1], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) + | SM(gainBoundaries[2], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) + | SM(gainBoundaries[3], + AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; for (j = 0; j < 32; j++) { @@ -715,10 +708,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, if (test) return; - if (AR_SREV_9280_20_OR_LATER(ah)) { - for (i = 0; i < Ar5416RateSize; i++) - ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; - } + for (i = 0; i < Ar5416RateSize; i++) + ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; ENABLE_REGWRITE_BUFFER(ah); @@ -877,6 +868,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, u8 txRxAttenLocal; u8 ob[5], db1[5], db2[5]; u8 ant_div_control1, ant_div_control2; + u8 bb_desired_scale; u32 regVal; pModal = &eep->modalHeader; @@ -1096,30 +1088,29 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40); } - if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) { - u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna & - EEP_4K_BB_DESIRED_SCALE_MASK); - if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { - u32 pwrctrl, mask, clr; - - mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); - pwrctrl = mask * bb_desired_scale; - clr = mask * 0x1f; - REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); - REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); - REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); - - mask = BIT(0)|BIT(5)|BIT(15); - pwrctrl = mask * bb_desired_scale; - clr = mask * 0x1f; - REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); - - mask = BIT(0)|BIT(5); - pwrctrl = mask * bb_desired_scale; - clr = mask * 0x1f; - REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); - REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); - } + + bb_desired_scale = (pModal->bb_scale_smrt_antenna & + EEP_4K_BB_DESIRED_SCALE_MASK); + if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { + u32 pwrctrl, mask, clr; + + mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); + REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); + + mask = BIT(0)|BIT(5)|BIT(15); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr); + + mask = BIT(0)|BIT(5); + pwrctrl = mask * bb_desired_scale; + clr = mask * 0x1f; + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); + REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); } } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 21f180db2381..ebf97bae6c27 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -851,10 +851,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, if (test) return; - if (AR_SREV_9280_20_OR_LATER(ah)) { - for (i = 0; i < Ar5416RateSize; i++) - ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; - } + for (i = 0; i < Ar5416RateSize; i++) + ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; ENABLE_REGWRITE_BUFFER(ah); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index e7e84be8beed..eda681fc7ba6 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -547,8 +547,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, break; } - if (AR_SREV_5416_20_OR_LATER(ah) && - (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) + if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) regChainOffset = (i == 1) ? 0x2000 : 0x1000; else regChainOffset = i * 0x1000; @@ -565,9 +564,8 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF)); - if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) - ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, - regChainOffset, i); + ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal, + regChainOffset, i); } if (AR_SREV_9280_20_OR_LATER(ah)) { @@ -893,8 +891,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, xpdGainValues[2]); for (i = 0; i < AR5416_MAX_CHAINS; i++) { - if (AR_SREV_5416_20_OR_LATER(ah) && - (ah->rxchainmask == 5 || ah->txchainmask == 5) && + if ((ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0)) { regChainOffset = (i == 1) ? 0x2000 : 0x1000; } else @@ -935,27 +932,24 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, ENABLE_REGWRITE_BUFFER(ah); - if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { - if (OLC_FOR_AR9280_20_LATER) { - REG_WRITE(ah, - AR_PHY_TPCRG5 + regChainOffset, - SM(0x6, - AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | - SM_PD_GAIN(1) | SM_PD_GAIN(2) | - SM_PD_GAIN(3) | SM_PD_GAIN(4)); - } else { - REG_WRITE(ah, - AR_PHY_TPCRG5 + regChainOffset, - SM(pdGainOverlap_t2, - AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| - SM_PDGAIN_B(0, 1) | - SM_PDGAIN_B(1, 2) | - SM_PDGAIN_B(2, 3) | - SM_PDGAIN_B(3, 4)); - } + if (OLC_FOR_AR9280_20_LATER) { + REG_WRITE(ah, + AR_PHY_TPCRG5 + regChainOffset, + SM(0x6, + AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | + SM_PD_GAIN(1) | SM_PD_GAIN(2) | + SM_PD_GAIN(3) | SM_PD_GAIN(4)); + } else { + REG_WRITE(ah, + AR_PHY_TPCRG5 + regChainOffset, + SM(pdGainOverlap_t2, + AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| + SM_PDGAIN_B(0, 1) | + SM_PDGAIN_B(1, 2) | + SM_PDGAIN_B(2, 3) | + SM_PDGAIN_B(3, 4)); } - ath9k_adjust_pdadc_values(ah, pwr_table_offset, diff, pdadcValues); diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 786587ac40a7..22f23eafe8ba 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -584,7 +584,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, else rs->rs_keyix = ATH9K_RXKEYIX_INVALID; - rs->rs_rate = RXSTATUS_RATE(ah, (&ads)); + rs->rs_rate = MS(ads.ds_rxstatus0, AR_RxRate); rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index ac5a1d265d39..91c96546c0cd 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -17,10 +17,6 @@ #ifndef MAC_H #define MAC_H -#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ? \ - MS(ads->ds_rxstatus0, AR_RxRate) : \ - (ads->ds_rxstatus3 >> 2) & 0xFF) - #define set11nTries(_series, _index) \ (SM((_series)[_index].Tries, AR_XmitDataTries##_index)) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 0846654b57ef..b76c49d9c503 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -803,10 +803,6 @@ #define AR_SREV_5416(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)) -#define AR_SREV_5416_20_OR_LATER(_ah) \ - (((AR_SREV_5416(_ah)) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \ - ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100)) #define AR_SREV_5416_22_OR_LATER(_ah) \ (((AR_SREV_5416(_ah)) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \ From d7084da0ceeddb9caf84de20cf687bb4a9b842b1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 15 Sep 2011 14:25:36 +0200 Subject: [PATCH 220/287] ath9k_hw: remove dead code in the eeprom ops The eeprom .set_addac function is only necessary for AR9160, remove it from eeprom_4k.c and remove the dummy function from eeprom_9287.c Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 3 ++- drivers/net/wireless/ath/ath9k/eeprom_4k.c | 23 -------------------- drivers/net/wireless/ath/ath9k/eeprom_9287.c | 6 ----- 3 files changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index b130c26d3dd0..1381a39a1da4 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -801,7 +801,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, /* Write ADDAC shifts */ REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); - ah->eep_ops->set_addac(ah, chan); + if (ah->eep_ops->set_addac) + ah->eep_ops->set_addac(ah, chan); if (AR_SREV_5416_22_OR_LATER(ah)) { REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 99f7a08c57e2..303560e49ac8 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -779,28 +779,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, REGWRITE_BUFFER_FLUSH(ah); } -static void ath9k_hw_4k_set_addac(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - struct modal_eep_4k_header *pModal; - struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; - u8 biaslevel; - - if (ah->hw_version.macVersion != AR_SREV_VERSION_9160) - return; - - if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7) - return; - - pModal = &eep->modalHeader; - - if (pModal->xpaBiasLvl != 0xff) { - biaslevel = pModal->xpaBiasLvl; - INI_RA(&ah->iniAddac, 7, 1) = - (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3; - } -} - static void ath9k_hw_4k_set_gain(struct ath_hw *ah, struct modal_eep_4k_header *pModal, struct ar5416_eeprom_4k *eep, @@ -1152,7 +1130,6 @@ const struct eeprom_ops eep_4k_ops = { .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver, .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev, .set_board_values = ath9k_hw_4k_set_board_values, - .set_addac = ath9k_hw_4k_set_addac, .set_txpower = ath9k_hw_4k_set_txpower, .get_spur_channel = ath9k_hw_4k_get_spur_channel }; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index ebf97bae6c27..6698b722b604 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -942,11 +942,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, REGWRITE_BUFFER_FLUSH(ah); } -static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah, - struct ath9k_channel *chan) -{ -} - static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -1098,7 +1093,6 @@ const struct eeprom_ops eep_ar9287_ops = { .get_eeprom_ver = ath9k_hw_ar9287_get_eeprom_ver, .get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev, .set_board_values = ath9k_hw_ar9287_set_board_values, - .set_addac = ath9k_hw_ar9287_set_addac, .set_txpower = ath9k_hw_ar9287_set_txpower, .get_spur_channel = ath9k_hw_ar9287_get_spur_channel }; From bf3f204b92c48c4afa3e827dfe98353560d9aa7f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 15 Sep 2011 14:25:37 +0200 Subject: [PATCH 221/287] ath9k_hw: fix setting the hardware diversity flag ath9k_hw_set_diversity is only called from init.c where it cannot affect the hardware setting because it's cleared on the next reset. Instead of using a PHY op for something that's supposed to be initialized statically, set the register value directly in the INI override function. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 14 +++----------- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 14 +++----------- drivers/net/wireless/ath/ath9k/hw-ops.h | 5 ----- drivers/net/wireless/ath/ath9k/hw.h | 1 - drivers/net/wireless/ath/ath9k/init.c | 1 - 5 files changed, 6 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 1381a39a1da4..794a2d96a8ef 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -704,6 +704,9 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, REG_WRITE(ah, AR_PCU_MISC_MODE2, val); } + REG_SET_BIT(ah, AR_PHY_CCK_DETECT, + AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); + if (AR_SREV_9280_20_OR_LATER(ah)) return; /* @@ -1007,16 +1010,6 @@ static void ar5008_restore_chainmask(struct ath_hw *ah) } } -static void ar5008_set_diversity(struct ath_hw *ah, bool value) -{ - u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); - if (value) - v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; - else - v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; - REG_WRITE(ah, AR_PHY_CCK_DETECT, v); -} - static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -1654,7 +1647,6 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->rfbus_req = ar5008_hw_rfbus_req; priv_ops->rfbus_done = ar5008_hw_rfbus_done; priv_ops->restore_chainmask = ar5008_restore_chainmask; - priv_ops->set_diversity = ar5008_set_diversity; priv_ops->do_getnf = ar5008_hw_do_getnf; priv_ops->set_radar_params = ar5008_hw_set_radar_params; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 95147948794d..9874248240e8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -595,6 +595,9 @@ static void ar9003_hw_override_ini(struct ath_hw *ah) val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE); REG_WRITE(ah, AR_PCU_MISC_MODE2, val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE); + + REG_SET_BIT(ah, AR_PHY_CCK_DETECT, + AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); } static void ar9003_hw_prog_ini(struct ath_hw *ah, @@ -795,16 +798,6 @@ static void ar9003_hw_rfbus_done(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); } -static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) -{ - u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); - if (value) - v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; - else - v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; - REG_WRITE(ah, AR_PHY_CCK_DETECT, v); -} - static bool ar9003_hw_ani_control(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { @@ -1287,7 +1280,6 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; priv_ops->rfbus_req = ar9003_hw_rfbus_req; priv_ops->rfbus_done = ar9003_hw_rfbus_done; - priv_ops->set_diversity = ar9003_hw_set_diversity; priv_ops->ani_control = ar9003_hw_ani_control; priv_ops->do_getnf = ar9003_hw_do_getnf; priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 41f4bf363d3d..e9782d164962 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -181,11 +181,6 @@ static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah) return ath9k_hw_private_ops(ah)->restore_chainmask(ah); } -static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value) -{ - return ath9k_hw_private_ops(ah)->set_diversity(ah, value); -} - static inline bool ath9k_hw_ani_control(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index bf38e2fc8f78..24889f78a053 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -584,7 +584,6 @@ struct ath_hw_private_ops { bool (*rfbus_req)(struct ath_hw *ah); void (*rfbus_done)(struct ath_hw *ah); void (*restore_chainmask)(struct ath_hw *ah); - void (*set_diversity)(struct ath_hw *ah, bool value); u32 (*compute_pll_control)(struct ath_hw *ah, struct ath9k_channel *chan); bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd, diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 9b34c4bab937..39514de044ef 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -506,7 +506,6 @@ static void ath9k_init_misc(struct ath_softc *sc) sc->sc_flags |= SC_OP_RXAGGR; } - ath9k_hw_set_diversity(sc->sc_ah, true); sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); From 491b209d06192a8b93d226b4e5d7399747bf01ef Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 15 Sep 2011 14:25:38 +0200 Subject: [PATCH 222/287] ath9k_hw: remove ar9100_hw_compute_pll_control AR913x uses the same PLL register layout as AR9160 and later. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar5008_phy.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 794a2d96a8ef..0a749c8fa634 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -1010,14 +1010,6 @@ static void ar5008_restore_chainmask(struct ath_hw *ah) } } -static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - if (chan && IS_CHAN_5GHZ(chan)) - return 0x1450; - return 0x1458; -} - static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -1656,9 +1648,7 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) } else priv_ops->ani_control = ar5008_hw_ani_control_old; - if (AR_SREV_9100(ah)) - priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; - else if (AR_SREV_9160_10_OR_LATER(ah)) + if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) priv_ops->compute_pll_control = ar9160_hw_compute_pll_control; else priv_ops->compute_pll_control = ar5008_hw_compute_pll_control; From e9c10469cf3c71bc1c6b0f01319161e277d6ac9b Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 15 Sep 2011 19:02:25 +0530 Subject: [PATCH 223/287] ath9k_hw: Fix magnitude/phase coeff correction Do the magnitude/phase coeff correction only if the outlier is detected. Updating wrong magnitude/phase coeff factor impacts not only tx gain setting but also leads to poor performance in congested networks. In the clear environment the impact is very minimal because the outlier happens very rarely according to the past experiment. It occured less than once every 1000 calibrations. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 3319a676c0fb..695d9d38d482 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -652,8 +652,9 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, outlier_idx = max_idx; else outlier_idx = min_idx; + + mp_coeff[outlier_idx] = mp_avg; } - mp_coeff[outlier_idx] = mp_avg; } static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, From 05bfe3d2a5794cc9e9b8119f36d1d7848ecd8967 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 15 Sep 2011 19:02:53 +0530 Subject: [PATCH 224/287] ath9k: load noise floor from history after the full chip reset Currently during the full reset, the nf calibration is always restarted from the defaults. The noise floor history buffers are never be used again after the scan and ath reset. This patch ensures that nf histories are always be used that helps to improve the signal quality on congested environment Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9002_calib.c | 1 + drivers/net/wireless/ath/ath9k/ar9003_calib.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index 2d4c0910295b..c527af84b371 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -868,6 +868,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) ar9002_hw_pa_cal(ah, true); /* Do NF Calibration after DC offset and other calibrations */ + ath9k_hw_loadnf(ah, chan); ath9k_hw_start_nfcal(ah, true); if (ah->caldata) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 695d9d38d482..e4b1a8300854 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -885,6 +885,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, if (txiqcal_done) ar9003_hw_tx_iq_cal_post_proc(ah); + ath9k_hw_loadnf(ah, chan); ath9k_hw_start_nfcal(ah, true); /* Initialize list pointers */ From d2c71c20789189cd01978efcbdd61231f5929eaf Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 15 Sep 2011 19:02:54 +0530 Subject: [PATCH 225/287] ath9k: Reset caldata on radio enable Not doing so, the caldata continues to retain older history values learned on that channel. It is always safer to start noise floor calibration from the defaults after the assoication. So this patch resets the nf history buffer when none of the STA vifs are associated. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 7910165cf0e6..6dcd8def5530 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2021,6 +2021,7 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) /* Stop ANI */ sc->sc_flags &= ~SC_OP_ANI_RUN; del_timer_sync(&common->ani.timer); + memset(&sc->caldata, 0, sizeof(sc->caldata)); } } From 17a68dd7bc25b3671d54b3b371df9b5baf985b20 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:28 -0700 Subject: [PATCH 226/287] iwlagn: warn about buggy fw that doesn't set SEQ_RX_FRAME The way we check if there is host command that should be reclaimed is way too complicated. We should have a clear indication from the fw. The fw is expected to set the SEQ_RX_FRAME bit if the frame was originated by the fw which indicates to the driver that there is no host command to free. Somehow, there seem to have been buggy fw out there, hence the very old comment. This code checks if we have still buggy fw out there. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c index 126e5a4cc401..2308177232c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c @@ -398,6 +398,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) while (i != r) { int len; + u16 txq_id, sequence; rxb = rxq->queue[i]; @@ -437,6 +438,17 @@ static void iwl_rx_handle(struct iwl_trans *trans) (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && (pkt->hdr.cmd != REPLY_TX); + sequence = le16_to_cpu(pkt->hdr.sequence); + txq_id = SEQ_TO_QUEUE(le16_to_cpu(pkt->hdr.sequence)); + + /* warn if this is cmd response / notification and the uCode + * didn't set the SEQ_RX_FRAME for a frame that is + * uCode-originated*/ + WARN(txq_id == trans->shrd->cmd_queue && reclaim == false && + (!(pkt->hdr.sequence & SEQ_RX_FRAME)), + "reclaim is false, SEQ_RX_FRAME unset: %s\n", + get_cmd_string(pkt->hdr.cmd)); + iwl_rx_dispatch(priv(trans), rxb); /* From 39644e9ac5329dc92d9547976c8f30f18da90097 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:29 -0700 Subject: [PATCH 227/287] iwlagn: unmap cmd queue's tfds as BIDI If the driver is unloaded while there is still a host command in flight, its tfd will be freed by iwl_tx_queue_free. This function is called for both types of queues: Tx queues and cmd queue. This didn't take in count the fact that in Tx queues, tfds are mapped as TO_DEVICE (besides the first TB), whereas in cmd queue, all TBs are mapped as BIDI. Hence, tx_queue_free unmapped the second (and higher) TB of each tfd in the cmd queue as TO_DEVICE, whereas they must be freed as BIDI. This means that if a multi TFD is in flight while we unload the driver (which is quite unlikely but can happen), we will get the warning below. This patch fixes this. [ 445.234060] ------------[ cut here ]------------ [ 445.236273] WARNING: at lib/dma-debug.c:861 check_unmap+0x337/0x780() [ 445.236654] iwlagn 0000:02:00.0: DMA-API: device driver frees DMA memory with different direction [device address=0x0000000126950540] [size=8 bytes] [mapped with DMA_BIDIRECTIONAL] [unmapped with DMA_TO_DEVICE] [ 445.236654] Modules linked in: ... [ 445.236654] Pid: 1415, comm: modprobe Not tainted 3.1.0-rc4-wl-65912-g5215ff1-dirty #79 [ 445.236654] Call Trace: [ 445.236654] [] warn_slowpath_common+0x71/0xa0 [ 445.236654] [] warn_slowpath_fmt+0x47/0x50 [ 445.236654] [] check_unmap+0x337/0x780 [ 445.236654] [] ? free_one_page+0x156/0x320 [ 445.236654] [] debug_dma_unmap_page+0x5a/0x60 [ 445.236654] [] iwlagn_unmap_tfd.isra.11+0x121/0x1c0 [iwlagn] [ 445.236654] [] iwlagn_txq_free_tfd+0x42/0x70 [iwlagn] [ 445.236654] [] iwl_tx_queue_unmap+0x4e/0x70 [iwlagn] [ 445.236654] [] iwl_trans_pcie_tx_free+0x10d/0x440 [iwlagn] [ 445.236654] [] ? destroy_workqueue+0xb9/0x1e0 [ 445.236654] [] iwl_trans_pcie_free+0x2a/0x2c0 [iwlagn] [ 445.236654] [] iwl_remove+0x149/0x17e [iwlagn] [ 445.236654] [] iwl_pci_remove+0x1f/0x65 [iwlagn] [ 445.236654] [] pci_device_remove+0x47/0x120 [ 445.236654] [] __device_release_driver+0x7c/0xe0 [ 445.236654] [] driver_detach+0xc8/0xd0 [ 445.236654] [] bus_remove_driver+0x88/0xe0 [ 445.236654] [] driver_unregister+0x62/0xa0 [ 445.236654] [] pci_unregister_driver+0x44/0xc0 [ 445.236654] [] iwl_pci_unregister_driver+0x15/0x20 [iwlagn] [ 445.236654] [] iwl_exit+0x9/0xa74 [iwlagn] [ 445.236654] [] sys_delete_module+0x184/0x240 [ 445.236654] [] ? retint_swapgs+0xe/0x13 [ 445.236654] [] ? trace_hardirqs_on_thunk+0x3a/0x3f [ 445.236654] [] system_call_fastpath+0x16/0x1b [ 445.236654] ---[ end trace 1fbc362b7dbe5d74 ]--- [ 445.236654] Mapped at: [ 445.236654] [] debug_dma_map_page+0x8b/0x150 [ 445.236654] [] iwl_enqueue_hcmd+0x837/0xa40 [iwlagn] [ 445.236654] [] iwl_trans_pcie_send_cmd+0x8d/0x580 [iwlagn] [ 445.236654] [] iwl_send_calib_results+0x75/0xd0 [iwlagn] [ 445.236654] [] iwlagn_alive_notify+0x196/0x1f0 [iwlagn] [ 445.386500] iwlagn 0000:02:00.0: PCI INT A disabled Reported-by: Johannes Berg Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 12 ++++++++---- drivers/net/wireless/iwlwifi/iwl-trans.c | 12 +++++++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h index 8047e955a27b..fc3375473541 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h @@ -307,7 +307,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, enum iwl_rxon_context_id ctx, int sta_id, int tid, int frame_limit); void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - int index); + int index, enum dma_data_direction dma_dir); int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, struct sk_buff_head *skbs); int iwl_queue_space(const struct iwl_queue *q); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c index ca686dbf5893..c7ddb2204a6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c @@ -207,17 +207,17 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, * @trans - transport private data * @txq - tx queue * @index - the index of the TFD to be freed + *@dma_dir - the direction of the DMA mapping * * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, - int index) + int index, enum dma_data_direction dma_dir) { struct iwl_tfd *tfd_tmp = txq->tfds; - iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], - DMA_TO_DEVICE); + iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir); /* free SKB */ if (txq->skbs) { @@ -1119,6 +1119,10 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, int last_to_free; int freed = 0; + /* This function is not meant to release cmd queue*/ + if (WARN_ON(txq_id == trans->shrd->cmd_queue)) + return 0; + /*Since we free until index _not_ inclusive, the one before index is * the last we will free. This one must be used */ last_to_free = iwl_queue_dec_wrap(index, q->n_bd); @@ -1151,7 +1155,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, iwlagn_txq_inval_byte_cnt_tbl(trans, txq); - iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr); + iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); freed++; } return freed; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index b2e89077c684..228c861848cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -411,13 +411,23 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; struct iwl_queue *q = &txq->q; + enum dma_data_direction dma_dir; if (!q->n_bd) return; + /* In the command queue, all the TBs are mapped as BIDI + * so unmap them as such. + */ + if (txq_id == trans->shrd->cmd_queue) + dma_dir = DMA_BIDIRECTIONAL; + else + dma_dir = DMA_TO_DEVICE; + while (q->write_ptr != q->read_ptr) { /* The read_ptr needs to bound by q->n_window */ - iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr)); + iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), + dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } } From 909e9b23e4b1d4a783e8d2e5e2c865b7ebdb0675 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:30 -0700 Subject: [PATCH 228/287] iwlagn: free the Tx cmd when a non empty Tx queue is freed When a non-empty Tx queueis freed, the buffer it contains must be freed too. Since the Tx cmd are now allocated from a pool, the Tx cmd must be freed too. This patch avoids to destroy a non-empty pool of Tx cmd. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 9 +++++++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 1 + drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 7 +++++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7f6c58ebbc44..1142d85ea881 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1522,6 +1522,8 @@ static void __iwl_down(struct iwl_priv *priv) if (priv->shrd->mac80211_registered) ieee80211_stop_queues(priv->hw); + iwl_trans_stop_device(trans(priv)); + /* Clear out all status bits but a few that are stable across reset */ priv->shrd->status &= test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) << @@ -1533,8 +1535,6 @@ static void __iwl_down(struct iwl_priv *priv) test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) << STATUS_EXIT_PENDING; - iwl_trans_stop_device(trans(priv)); - dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = NULL; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 9270f990b2dd..5e490dbe0d07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1876,3 +1876,12 @@ void iwl_nic_config(struct iwl_priv *priv) priv->cfg->lib->nic_config(priv); } + +void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info; + + info = IEEE80211_SKB_CB(skb); + kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); + dev_kfree_skb_any(skb); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index d987bee5e6ce..bdfbc6058ba1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -390,6 +390,7 @@ void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv, u8 sta_id, u8 tid); void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); void iwl_nic_config(struct iwl_priv *priv); +void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c index c7ddb2204a6e..15cb0ff2ff18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c @@ -225,9 +225,12 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, skb = txq->skbs[index]; - /* can be called from irqs-disabled context */ + /* Can be called from irqs-disabled context + * If skb is not NULL, it means that the whole queue is being + * freed and that the queue is not empty - free the skb + */ if (skb) { - dev_kfree_skb_any(skb); + iwl_free_skb(priv(trans), skb); txq->skbs[index] = NULL; } } From 859cfb0a99369cf51dc2125ebc3476382a15c322 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:31 -0700 Subject: [PATCH 229/287] iwlagn: move iwl_stop / wake_queue to the upper layer Add a wrapper in the upper layer to call the mac80211's function. This allows not to have the transport layer call mac80211 directly. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn.c | 9 ++++----- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-shared.h | 9 +++------ drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h | 10 ++-------- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 92ba8cd0ecd5..495f93664741 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -209,7 +209,7 @@ static void iwl_perform_ct_kill_task(struct iwl_priv *priv, { if (stop) { IWL_DEBUG_TEMP(priv, "Stop all queues\n"); - if (priv->shrd->mac80211_registered) + if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); IWL_DEBUG_TEMP(priv, "Schedule 5 seconds CT_KILL Timer\n"); @@ -217,7 +217,7 @@ static void iwl_perform_ct_kill_task(struct iwl_priv *priv, jiffies + CT_KILL_EXIT_DURATION * HZ); } else { IWL_DEBUG_TEMP(priv, "Wake all queues\n"); - if (priv->shrd->mac80211_registered) + if (priv->mac80211_registered) ieee80211_wake_queues(priv->hw); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1142d85ea881..61f8ea6413c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1519,7 +1519,7 @@ static void __iwl_down(struct iwl_priv *priv) if (!exit_pending) clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); - if (priv->shrd->mac80211_registered) + if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); iwl_trans_stop_device(trans(priv)); @@ -1863,7 +1863,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, IWL_ERR(priv, "Failed to register hw (error %d)\n", ret); return ret; } - priv->shrd->mac80211_registered = 1; + priv->mac80211_registered = 1; return 0; } @@ -3311,7 +3311,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, priv->shrd = &priv->_shrd; priv->shrd->bus = bus; priv->shrd->priv = priv; - priv->shrd->hw = hw; bus_set_drv_data(priv->bus, priv->shrd); priv->shrd->trans = trans_ops->alloc(priv->shrd); @@ -3487,9 +3486,9 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_testmode_cleanup(priv); iwl_leds_exit(priv); - if (priv->shrd->mac80211_registered) { + if (priv->mac80211_registered) { ieee80211_unregister_hw(priv->hw); - priv->shrd->mac80211_registered = 0; + priv->mac80211_registered = 0; } iwl_tt_exit(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5e490dbe0d07..208ca218d6b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1885,3 +1885,13 @@ void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb) kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); dev_kfree_skb_any(skb); } + +void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac) +{ + ieee80211_stop_queue(priv->hw, ac); +} + +void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac) +{ + ieee80211_wake_queue(priv->hw, ac); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 8438a33e17ee..f69e556bd3c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -958,6 +958,8 @@ struct iwl_priv { struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; unsigned long ucode_key_table; + u8 mac80211_registered; + /* Indication if ieee80211_ops->open has been called */ u8 is_open; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index bdfbc6058ba1..0f15d588303f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -246,12 +246,6 @@ struct iwl_shared { spinlock_t sta_lock; struct mutex mutex; - /*these 2 shouldn't really be here, but they are needed for - * iwl_queue_stop, which is called from the upper layer too - */ - u8 mac80211_registered; - struct ieee80211_hw *hw; - struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; wait_queue_head_t wait_command_queue; @@ -397,6 +391,9 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); const char *get_cmd_string(u8 cmd); bool iwl_check_for_ct_kill(struct iwl_priv *priv); +void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac); +void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac); + #ifdef CONFIG_IWLWIFI_DEBUGFS void iwl_reset_traffic_log(struct iwl_priv *priv); #endif /* CONFIG_IWLWIFI_DEBUGFS */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h index fc3375473541..49cd5a768280 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h @@ -375,12 +375,9 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (unlikely(!trans->shrd->mac80211_registered)) - return; - if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) - ieee80211_wake_queue(trans->shrd->hw, ac); + iwl_wake_sw_queue(priv(trans), ac); } static inline void iwl_stop_queue(struct iwl_trans *trans, @@ -392,12 +389,9 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (unlikely(!trans->shrd->mac80211_registered)) - return; - if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) - ieee80211_stop_queue(trans->shrd->hw, ac); + iwl_stop_sw_queue(priv(trans), ac); } #ifdef ieee80211_stop_queue From 14991a9d8469ccac12c5d243e975d3ab78c8238a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:32 -0700 Subject: [PATCH 230/287] iwlagn: use enum iwl_rxon_context_id instead of u8 enum iwl_rxon_context_id is the right type to use when we need a rxon_context_id. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-shared.h | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-trans.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-trans.h | 12 ++++++++---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 208ca218d6b1..90ab27e50e7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -817,7 +817,8 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) } #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid) +void iwl_print_rx_config_cmd(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid) { struct iwl_rxon_context *ctx = &priv->contexts[ctxid]; struct iwl_rxon_cmd *rxon = &ctx->staging; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 0f15d588303f..36872f0c3352 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -399,9 +399,11 @@ void iwl_reset_traffic_log(struct iwl_priv *priv); #endif /* CONFIG_IWLWIFI_DEBUGFS */ #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid); +void iwl_print_rx_config_cmd(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid); #else -static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid) +static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid) { } #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 228c861848cf..209dd7e16e92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -1041,7 +1041,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) } static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, u8 ctx, u8 sta_id) + struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, + u8 sta_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; @@ -1413,7 +1414,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) #endif /* CONFIG_PM */ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, - u8 ctx) + enum iwl_rxon_context_id ctx) { u8 ac, txq_id; struct iwl_trans_pcie *trans_pcie = diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 71a6fb05356a..f067408356fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -178,14 +178,16 @@ struct iwl_trans_ops { void (*stop_device)(struct iwl_trans *trans); void (*tx_start)(struct iwl_trans *trans); - void (*wake_any_queue)(struct iwl_trans *trans, u8 ctx); + void (*wake_any_queue)(struct iwl_trans *trans, + enum iwl_rxon_context_id ctx); int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); int (*send_cmd_pdu)(struct iwl_trans *trans, u8 id, u32 flags, u16 len, const void *data); int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, u8 ctx, u8 sta_id); + struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, + u8 sta_id); void (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, int txq_id, int ssn, u32 status, struct sk_buff_head *skbs); @@ -255,7 +257,8 @@ static inline void iwl_trans_tx_start(struct iwl_trans *trans) trans->ops->tx_start(trans); } -static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, u8 ctx) +static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, + enum iwl_rxon_context_id ctx) { trans->ops->wake_any_queue(trans, ctx); } @@ -274,7 +277,8 @@ static inline int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, } static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, u8 ctx, u8 sta_id) + struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, + u8 sta_id) { return trans->ops->tx(trans, skb, dev_cmd, ctx, sta_id); } From eeb7f8cb93966250e5768ea9f8fec8830567c02a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:33 -0700 Subject: [PATCH 231/287] iwlagn: document the bus layer API Add documentation to the bus layer API - iwl-bus.h Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-bus.h | 62 +++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 83aed46673e1..98535dfd29e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -63,18 +63,65 @@ #ifndef __iwl_bus_h__ #define __iwl_bus_h__ -/*This file includes the declaration that are exported from the bus layer */ - #include #include +/** + * DOC: Bus layer - role and goal + * + * iwl-bus.h defines the API to the bus layer of the iwlwifi driver. + * The bus layer is responsible for doing very basic bus operations that are + * listed in the iwl_bus_ops structure. + * The bus layer registers to the bus driver, advertises the supported HW and + * gets notifications about enumeration, suspend, resume. + * For the moment, the bus layer is not a linux kernel module as itself, and + * the module_init function of the driver must call the bus specific + * registration functions. These functions are listed at the end of this file. + * For the moment, there is only one implementation of this interface: PCI-e. + * This implementation is iwl-pci.c + */ + +/** + * DOC: encapsulation and type safety + * + * The iwl_bus describes the data that is shared amongst all the bus layer + * implementations. This data is visible to other layers. Data in the bus + * specific area is not visible outside the bus specific implementation. + * iwl_bus holds a pointer to iwl_shared which holds pointer to all the other + * layers of the driver (iwl_priv, iwl_trans). In fact, this is the way to go + * when the transport layer needs to call a function of another layer. + * + * In order to achieve encapsulation, iwl_priv cannot be dereferenced from the + * bus layer. Type safety is still kept since functions that gets iwl_priv gets + * a typed pointer (as opposed to void *). + */ + +/** + * DOC: probe flow + * + * The module_init calls the bus specific registration function. The + * registration to the bus layer will trigger an enumeration of the bus which + * will call the bus specific probe function. + * The first thing this function must do is to allocate the memory needed by + * iwl_bus + the bus_specific data. + * Once the bus specific probe function has configured the hardware, it + * chooses the appropriate transport layer and calls iwl_probe that will run + * the bus independent probe flow. + * + * Note: The bus specific code must set the following data in iwl_bus before it + * calls iwl_probe: + * * bus->dev + * * bus->irq + * * bus->ops + */ + struct iwl_shared; struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations * @get_pm_support: must returns true if the bus can go to sleep - * @apm_config: will be called during the config of the APM configuration + * @apm_config: will be called during the config of the APM * @set_drv_data: set the shared data pointer to the bus layer * @get_hw_id: prints the hw_id in the provided buffer * @write8: write a byte to register at offset ofs @@ -93,14 +140,16 @@ struct iwl_bus_ops { /** * struct iwl_bus - bus common data - * @dev - pointer to struct device * that represent the device + * + * This data is common to all bus layer implementations. + * + * @dev - pointer to struct device * that represents the device * @ops - pointer to iwl_bus_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer * @irq - the irq number for the device * @reg_lock - protect hw register access */ struct iwl_bus { - /* Common data to all buses */ struct device *dev; const struct iwl_bus_ops *ops; struct iwl_shared *shrd; @@ -149,6 +198,9 @@ static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs) return bus->ops->read32(bus, ofs); } +/***************************************************** +* Bus layer registration functions +******************************************************/ int __must_check iwl_pci_register_driver(void); void iwl_pci_unregister_driver(void); From 21023e2696679bea2a42aa963de74ce37c049b13 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:34 -0700 Subject: [PATCH 232/287] iwlagn: add documentation to the transport layer and do a few clean up fixes on the way Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 117 ++++++++++++++++------ drivers/net/wireless/iwlwifi/iwl-trans.c | 4 +- 3 files changed, 91 insertions(+), 32 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index ba5c514c4a43..459b82b8a2a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -901,7 +901,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, ba_resp->scd_ssn); /* Mark that the expected block-ack response arrived */ - agg->wait_for_ba = 0; + agg->wait_for_ba = false; /* Sanity check values reported by uCode */ if (ba_resp->txed_2_done > ba_resp->txed) { diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 36872f0c3352..810b3e112077 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -72,8 +72,27 @@ #include "iwl-commands.h" -/*This files includes all the types / functions that are exported by the - * upper layer to the bus and transport layer */ +/** + * DOC: shared area - role and goal + * + * The shared area contains all the data exported by the upper layer to the + * other layers. Since the bus and transport layer shouldn't dereference + * iwl_priv, all the data needed by the upper layer and the transport / bus + * layer must be here. + * The shared area also holds pointer to all the other layers. This allows a + * layer to call a function from another layer. + * + * NOTE: All the layers hold a pointer to the shared area which must be shrd. + * A few macros assume that (_m)->shrd points to the shared area no matter + * what _m is. + * + * gets notifications about enumeration, suspend, resume. + * For the moment, the bus layer is not a linux kernel module as itself, and + * the module_init function of the driver must call the bus specific + * registration functions. These functions are listed at the end of this file. + * For the moment, there is only one implementation of this interface: PCI-e. + * This implementation is iwl-pci.c + */ struct iwl_cfg; struct iwl_bus; @@ -90,6 +109,9 @@ extern struct iwl_mod_params iwlagn_mod_params; /** * struct iwl_mod_params + * + * Holds the module parameters + * * @sw_crypto: using hardware encryption, default = 0 * @num_of_queues: number of tx queue, HW dependent * @disable_11n: 11n capabilities enabled, default = 0 @@ -134,20 +156,25 @@ struct iwl_mod_params { /** * struct iwl_hw_params + * + * Holds the module parameters + * * @max_txq_num: Max # Tx queues supported * @num_ampdu_queues: num of ampdu queues - * @tx/rx_chains_num: Number of TX/RX chains - * @valid_tx/rx_ant: usable antennas - * @max_stations: - * @ht40_channel: is 40MHz width possible in band 2.4 + * @tx_chains_num: Number of TX chains + * @rx_chains_num: Number of RX chains + * @valid_tx_ant: usable antennas for TX + * @valid_rx_ant: usable antennas for RX + * @max_stations: the maximal number of stations + * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) * @beacon_time_tsf_bits: number of valid tsf bits for beacon time - * @sku: + * @sku: sku read from EEPROM * @rx_page_order: Rx buffer page order - * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR - * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ) - * @sw_crypto: 0 for hw, 1 for sw - * @max_xxx_size: for ucode uses - * @ct_kill_threshold: temperature threshold + * @max_inst_size: for ucode use + * @max_data_size: for ucode use + * @ct_kill_threshold: temperature threshold - in hw dependent unit + * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit + * relevant for 1000, 6000 and up * @wd_timeout: TX queues watchdog timeout * @calib_init_cfg: setup initial calibrations for the hw * @calib_rt_cfg: setup runtime calibrations for the hw @@ -168,9 +195,8 @@ struct iwl_hw_params { u32 rx_page_order; u32 max_inst_size; u32 max_data_size; - u32 ct_kill_threshold; /* value in hw-dependent units */ - u32 ct_kill_exit_threshold; /* value in hw-dependent units */ - /* for 1000, 6000 series and up */ + u32 ct_kill_threshold; + u32 ct_kill_exit_threshold; unsigned int wd_timeout; u32 calib_init_cfg; @@ -179,28 +205,59 @@ struct iwl_hw_params { }; /** - * struct iwl_ht_agg - aggregation status while waiting for block-ack - * @txq_id: Tx queue used for Tx attempt - * @wait_for_ba: Expect block-ack before next Tx reply - * @rate_n_flags: Rate at which Tx was attempted + * enum iwl_agg_state + * + * The state machine of the BA agreement establishment / tear down. + * These states relate to a specific RA / TID. * - * If REPLY_TX indicates that aggregation was attempted, driver must wait - * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info - * until block ack arrives. + * @IWL_AGG_OFF: aggregation is not used + * @IWL_AGG_ON: aggregation session is up + * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the + * HW queue to be empty from packets for this RA /TID. + * @IWL_EMPTYING_HW_QUEUE_DELBA: tearing down a BA session - waiting for the + * HW queue to be empty from packets for this RA /TID. + */ +enum iwl_agg_state { + IWL_AGG_OFF = 0, + IWL_AGG_ON, + IWL_EMPTYING_HW_QUEUE_ADDBA, + IWL_EMPTYING_HW_QUEUE_DELBA, +}; + +/** + * struct iwl_ht_agg - aggregation state machine + + * This structs holds the states for the BA agreement establishment and tear + * down. It also holds the state during the BA session itself. This struct is + * duplicated for each RA / TID. + + * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the + * Tx response (REPLY_TX), and the block ack notification + * (REPLY_COMPRESSED_BA). + * @state: state of the BA agreement establishment / tear down. + * @txq_id: Tx queue used by the BA session - used by the transport layer. + * Needed by the upper layer for debugfs only. + * @wait_for_ba: Expect block-ack before next Tx reply */ struct iwl_ht_agg { - u16 txq_id; - u16 wait_for_ba; u32 rate_n_flags; -#define IWL_AGG_OFF 0 -#define IWL_AGG_ON 1 -#define IWL_EMPTYING_HW_QUEUE_ADDBA 2 -#define IWL_EMPTYING_HW_QUEUE_DELBA 3 - u8 state; + enum iwl_agg_state state; + u16 txq_id; + bool wait_for_ba; }; +/** + * struct iwl_tid_data - one for each RA / TID + + * This structs holds the states for each RA / TID. + + * @seq_number: the next WiFi sequence number to use + * @tfds_in_queue: number of packets sent to the HW queues. + * Exported for debugfs only + * @agg: aggregation state machine + */ struct iwl_tid_data { - u16 seq_number; /* agn only */ + u16 seq_number; u16 tfds_in_queue; struct iwl_ht_agg agg; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 209dd7e16e92..d4f628160565 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -1300,6 +1300,8 @@ static int iwlagn_txq_check_empty(struct iwl_trans *trans, sta_id, tid); } break; + default: + break; } return 0; @@ -1326,10 +1328,10 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; + enum iwl_agg_state agg_state; /* n_bd is usually 256 => n_bd - 1 = 0xff */ int tfd_num = ssn & (txq->q.n_bd - 1); int freed = 0; - u8 agg_state; bool cond; txq->time_stamp = jiffies; From 9845ad22fdac09109d230bd4070311c98b119ebe Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 15 Sep 2011 12:47:26 -0700 Subject: [PATCH 233/287] iwlagn: Convert kzalloc to kcalloc Convert kzalloc to kcalloc, coalesce multiple lines too. Signed-off-by: Joe Perches Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index d4f628160565..a49fb26bdf5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -308,10 +308,8 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, txq->q.n_window = slots_num; - txq->meta = kzalloc(sizeof(txq->meta[0]) * slots_num, - GFP_KERNEL); - txq->cmd = kzalloc(sizeof(txq->cmd[0]) * slots_num, - GFP_KERNEL); + txq->meta = kcalloc(slots_num, sizeof(txq->meta[0]), GFP_KERNEL); + txq->cmd = kcalloc(slots_num, sizeof(txq->cmd[0]), GFP_KERNEL); if (!txq->meta || !txq->cmd) goto error; From ff647af65656b731f81d2216e01d3d1dcb2130bf Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 15 Sep 2011 11:46:36 -0700 Subject: [PATCH 234/287] iwlagn: New SKU for 6005 SFF Adding another SKU for 6005 series devices. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 78a3f8dfe680..1be0bc47ef9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -260,6 +260,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, /* 6x30 Series */ {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, From 5092e47afcbe6c470094c32095794b16083dfac2 Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Thu, 15 Sep 2011 11:46:37 -0700 Subject: [PATCH 235/287] iwlagn: fix modinfo display for 135 ucode. The modinfo report for 135 ucode is iwlwifi-135-IWL135_UCODE_API_MAX.ucode Change to show the value of the define: iwlwifi-135-6.ucode Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 913f2a228527..057939803d68 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -75,7 +75,7 @@ #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" #define IWL135_FW_PRE "iwlwifi-135-" -#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE #api ".ucode" +#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode" static void iwl2000_set_ct_threshold(struct iwl_priv *priv) { From b8c2b05e14fbe1ba3fffa31931a1a9ef8da933f9 Mon Sep 17 00:00:00 2001 From: "Fry, Donald H" Date: Thu, 15 Sep 2011 11:46:38 -0700 Subject: [PATCH 236/287] iwlagn: simplify chain_noise_num_beacons indirection chain_noise_num_beacons is set and never changes. Use the #define rather than 3 levels of indirection. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 - drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 1 - drivers/net/wireless/iwlwifi/iwl-6000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 21 +++++++------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 6 files changed, 7 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 4766c3a1a2f6..5eba5d9fdd85 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -191,7 +191,6 @@ static struct iwl_base_params iwl1000_base_params = { .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 057939803d68..ba138a572e80 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -211,7 +211,6 @@ static struct iwl_base_params iwl2000_base_params = { .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, @@ -231,7 +230,6 @@ static struct iwl_base_params iwl2030_base_params = { .max_ll_items = OTP_MAX_LL_ITEMS_2x00, .shadow_ram_support = true, .led_compensation = 57, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 7cb4d69e0c37..327ebf6b7063 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -353,7 +353,6 @@ static struct iwl_base_params iwl5000_base_params = { .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 2a98e65ca84c..d44378527380 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -305,7 +305,6 @@ static struct iwl_base_params iwl6000_base_params = { .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, @@ -323,7 +322,6 @@ static struct iwl_base_params iwl6050_base_params = { .max_ll_items = OTP_MAX_LL_ITEMS_6x50, .shadow_ram_support = true, .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, @@ -340,7 +338,6 @@ static struct iwl_base_params iwl6000_g2_base_params = { .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 57, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index b725f6970dee..03bac48558b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -766,12 +766,9 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, u8 first_chain; u16 i = 0; - average_sig[0] = data->chain_signal_a / - priv->cfg->base_params->chain_noise_num_beacons; - average_sig[1] = data->chain_signal_b / - priv->cfg->base_params->chain_noise_num_beacons; - average_sig[2] = data->chain_signal_c / - priv->cfg->base_params->chain_noise_num_beacons; + average_sig[0] = data->chain_signal_a / IWL_CAL_NUM_BEACONS; + average_sig[1] = data->chain_signal_b / IWL_CAL_NUM_BEACONS; + average_sig[2] = data->chain_signal_c / IWL_CAL_NUM_BEACONS; if (average_sig[0] >= average_sig[1]) { max_average_sig = average_sig[0]; @@ -1038,8 +1035,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) /* If this is the "chain_noise_num_beacons", determine: * 1) Disconnected antennas (using signal strengths) * 2) Differential gain (using silence noise) to balance receivers */ - if (data->beacon_count != - priv->cfg->base_params->chain_noise_num_beacons) + if (data->beacon_count != IWL_CAL_NUM_BEACONS) return; /* Analyze signal for disconnected antenna */ @@ -1055,12 +1051,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) iwl_find_disconn_antenna(priv, average_sig, data); /* Analyze noise for rx balance */ - average_noise[0] = data->chain_noise_a / - priv->cfg->base_params->chain_noise_num_beacons; - average_noise[1] = data->chain_noise_b / - priv->cfg->base_params->chain_noise_num_beacons; - average_noise[2] = data->chain_noise_c / - priv->cfg->base_params->chain_noise_num_beacons; + average_noise[0] = data->chain_noise_a / IWL_CAL_NUM_BEACONS; + average_noise[1] = data->chain_noise_b / IWL_CAL_NUM_BEACONS; + average_noise[2] = data->chain_noise_c / IWL_CAL_NUM_BEACONS; for (i = 0; i < NUM_RX_CHAINS; i++) { if (!(data->disconn_array[i]) && diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 56b554c43fde..549dc46d3903 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -124,7 +124,6 @@ struct iwl_base_params { const u16 max_ll_items; const bool shadow_ram_support; u16 led_compensation; - int chain_noise_num_beacons; bool adv_thermal_throttle; bool support_ct_kill_exit; const bool support_wimax_coexist; From 403ba56aedf2b3092e12219188e5c248f04c5acc Mon Sep 17 00:00:00 2001 From: Don Fry Date: Thu, 15 Sep 2011 11:46:39 -0700 Subject: [PATCH 237/287] iwlagn: replace beacon_time_fsf_bits variable with #define All devices use the same value for beacon_time_tsf_bits. Use the #define Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-core.c | 21 ++++++++++----------- drivers/net/wireless/iwlwifi/iwl-shared.h | 2 -- 6 files changed, 10 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 5eba5d9fdd85..dacbe3ad5c18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -161,8 +161,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) if (priv->cfg->need_dc_calib) hw_params(priv).calib_init_cfg |= BIT(IWL_CALIB_DC); - hw_params(priv).beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; - return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index ba138a572e80..82719b7ec349 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -159,8 +159,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) if (priv->cfg->need_temp_offset_calib) hw_params(priv).calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET); - hw_params(priv).beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; - return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 327ebf6b7063..de7f7f2b3d9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -184,8 +184,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) BIT(IWL_CALIB_TX_IQ_PERD) | BIT(IWL_CALIB_BASE_BAND); - hw_params(priv).beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; - return 0; } @@ -223,8 +221,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) if (priv->cfg->need_dc_calib) hw_params(priv).calib_init_cfg |= BIT(IWL_CALIB_DC); - hw_params(priv).beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; - return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index d44378527380..5c1a8b8584a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -180,8 +180,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) if (priv->cfg->need_temp_offset_calib) hw_params(priv).calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET); - hw_params(priv).beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; - return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 90ab27e50e7c..0a426cbcbfc4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1803,13 +1803,12 @@ u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval) return 0; quot = (usec / interval) & - (iwl_beacon_time_mask_high(priv, - hw_params(priv).beacon_time_tsf_bits) >> - hw_params(priv).beacon_time_tsf_bits); + (iwl_beacon_time_mask_high(priv, IWLAGN_EXT_BEACON_TIME_POS) >> + IWLAGN_EXT_BEACON_TIME_POS); rem = (usec % interval) & iwl_beacon_time_mask_low(priv, - hw_params(priv).beacon_time_tsf_bits); + IWLAGN_EXT_BEACON_TIME_POS); - return (quot << hw_params(priv).beacon_time_tsf_bits) + rem; + return (quot << IWLAGN_EXT_BEACON_TIME_POS) + rem; } /* base is usually what we get from ucode with each received frame, @@ -1819,22 +1818,22 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, u32 addon, u32 beacon_interval) { u32 base_low = base & iwl_beacon_time_mask_low(priv, - hw_params(priv).beacon_time_tsf_bits); + IWLAGN_EXT_BEACON_TIME_POS); u32 addon_low = addon & iwl_beacon_time_mask_low(priv, - hw_params(priv).beacon_time_tsf_bits); + IWLAGN_EXT_BEACON_TIME_POS); u32 interval = beacon_interval * TIME_UNIT; u32 res = (base & iwl_beacon_time_mask_high(priv, - hw_params(priv).beacon_time_tsf_bits)) + + IWLAGN_EXT_BEACON_TIME_POS)) + (addon & iwl_beacon_time_mask_high(priv, - hw_params(priv).beacon_time_tsf_bits)); + IWLAGN_EXT_BEACON_TIME_POS)); if (base_low > addon_low) res += base_low - addon_low; else if (base_low < addon_low) { res += interval + base_low - addon_low; - res += (1 << hw_params(priv).beacon_time_tsf_bits); + res += (1 << IWLAGN_EXT_BEACON_TIME_POS); } else - res += (1 << hw_params(priv).beacon_time_tsf_bits); + res += (1 << IWLAGN_EXT_BEACON_TIME_POS); return cpu_to_le32(res); } diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 810b3e112077..8272a9489ab1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -167,7 +167,6 @@ struct iwl_mod_params { * @valid_rx_ant: usable antennas for RX * @max_stations: the maximal number of stations * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) - * @beacon_time_tsf_bits: number of valid tsf bits for beacon time * @sku: sku read from EEPROM * @rx_page_order: Rx buffer page order * @max_inst_size: for ucode use @@ -190,7 +189,6 @@ struct iwl_hw_params { u8 max_stations; u8 ht40_channel; bool shadow_reg_enable; - u16 beacon_time_tsf_bits; u16 sku; u32 rx_page_order; u32 max_inst_size; From 1dd9124e2911b34744672c91ad865f39711f5542 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 15 Sep 2011 11:46:40 -0700 Subject: [PATCH 238/287] iwlagn: provide data after WARN_ON From time to time, we hit a WARN_ON in iwl_mac_remove_interface. This basically means that we got out of sync with mac80211: the vif we hold differs from the vif 80211 passes as parameter. Try to get some data that will help to debug this. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 0a426cbcbfc4..ce8a015c7205 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1328,7 +1328,13 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, mutex_lock(&priv->shrd->mutex); - WARN_ON(ctx->vif != vif); + if (WARN_ON(ctx->vif != vif)) { + struct iwl_rxon_context *tmp; + IWL_ERR(priv, "ctx->vif = %p, vif = %p\n", ctx->vif, vif); + for_each_context(priv, tmp) + IWL_ERR(priv, "\tID = %d:\tctx = %p\tctx->vif = %p\n", + tmp->ctxid, tmp, tmp->vif); + } ctx->vif = NULL; iwl_teardown_interface(priv, vif, false); From 701cb0997f42196a42c3566da1d35451b4b899e2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 15 Sep 2011 11:46:41 -0700 Subject: [PATCH 239/287] iwlagn: merge eeprom access into single file After driver split and no need to support legacy devices, there is no reason we need to separate the NVM access into different files, merge those. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | 299 ------------------ drivers/net/wireless/iwlwifi/iwl-eeprom.c | 239 +++++++++++++- 3 files changed, 235 insertions(+), 305 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 48ab9142af38..ae1d816cc4ee 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o -iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o +iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-power.o iwlagn-objs += iwl-rx.o iwl-sta.o diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c deleted file mode 100644 index c62ddc2a31bd..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ /dev/null @@ -1,299 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - *****************************************************************************/ - - -#include -#include -#include -#include - -#include - -#include "iwl-commands.h" -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-debug.h" -#include "iwl-agn.h" -#include "iwl-io.h" - -/****************************************************************************** - * - * EEPROM related functions - * -******************************************************************************/ - -int iwl_eeprom_check_version(struct iwl_priv *priv) -{ - u16 eeprom_ver; - u16 calib_ver; - - eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); - calib_ver = iwlagn_eeprom_calib_version(priv); - - if (eeprom_ver < priv->cfg->eeprom_ver || - calib_ver < priv->cfg->eeprom_calib_ver) - goto err; - - IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", - eeprom_ver, calib_ver); - - return 0; -err: - IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " - "CALIB=0x%x < 0x%x\n", - eeprom_ver, priv->cfg->eeprom_ver, - calib_ver, priv->cfg->eeprom_calib_ver); - return -EINVAL; - -} - -int iwl_eeprom_check_sku(struct iwl_priv *priv) -{ - u16 radio_cfg; - - if (!priv->cfg->sku) { - /* not using sku overwrite */ - priv->cfg->sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); - if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE && - !priv->cfg->ht_params) { - IWL_ERR(priv, "Invalid 11n configuration\n"); - return -EINVAL; - } - } - if (!priv->cfg->sku) { - IWL_ERR(priv, "Invalid device sku\n"); - return -EINVAL; - } - - IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku); - - if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) { - /* not using .cfg overwrite */ - radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); - priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); - priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); - if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) { - IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n", - priv->cfg->valid_tx_ant, - priv->cfg->valid_rx_ant); - return -EINVAL; - } - IWL_INFO(priv, "Valid Tx ant: 0X%x, Valid Rx ant: 0X%x\n", - priv->cfg->valid_tx_ant, priv->cfg->valid_rx_ant); - } - /* - * for some special cases, - * EEPROM did not reflect the correct antenna setting - * so overwrite the valid tx/rx antenna from .cfg - */ - return 0; -} - -void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) -{ - const u8 *addr = iwl_eeprom_query_addr(priv, - EEPROM_MAC_ADDRESS); - memcpy(mac, addr, ETH_ALEN); -} - -/** - * iwl_get_max_txpower_avg - get the highest tx power from all chains. - * find the highest tx power from all chains for the channel - */ -static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int element, s8 *max_txpower_in_half_dbm) -{ - s8 max_txpower_avg = 0; /* (dBm) */ - - /* Take the highest tx power from any valid chains */ - if ((priv->cfg->valid_tx_ant & ANT_A) && - (enhanced_txpower[element].chain_a_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_a_max; - if ((priv->cfg->valid_tx_ant & ANT_B) && - (enhanced_txpower[element].chain_b_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_b_max; - if ((priv->cfg->valid_tx_ant & ANT_C) && - (enhanced_txpower[element].chain_c_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_c_max; - if (((priv->cfg->valid_tx_ant == ANT_AB) | - (priv->cfg->valid_tx_ant == ANT_BC) | - (priv->cfg->valid_tx_ant == ANT_AC)) && - (enhanced_txpower[element].mimo2_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo2_max; - if ((priv->cfg->valid_tx_ant == ANT_ABC) && - (enhanced_txpower[element].mimo3_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo3_max; - - /* - * max. tx power in EEPROM is in 1/2 dBm format - * convert from 1/2 dBm to dBm (round-up convert) - * but we also do not want to loss 1/2 dBm resolution which - * will impact performance - */ - *max_txpower_in_half_dbm = max_txpower_avg; - return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); -} - -static void -iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *txp, - s8 max_txpower_avg) -{ - int ch_idx; - bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; - enum ieee80211_band band; - - band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? - IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; - - for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { - struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; - - /* update matching channel or from common data only */ - if (txp->channel != 0 && ch_info->channel != txp->channel) - continue; - - /* update matching band only */ - if (band != ch_info->band) - continue; - - if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { - ch_info->max_power_avg = max_txpower_avg; - ch_info->curr_txpow = max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - - if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) - ch_info->ht40_max_power_avg = max_txpower_avg; - } -} - -#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) -#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) -#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) - -#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ - ? # x " " : "") - -void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) -{ - struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; - int idx, entries; - __le16 *txp_len; - s8 max_txp_avg, max_txp_avg_halfdbm; - - BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); - - /* the length is in 16-bit words, but we want entries */ - txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); - entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; - - txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS); - - for (idx = 0; idx < entries; idx++) { - txp = &txp_array[idx]; - /* skip invalid entries */ - if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) - continue; - - IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", - (txp->channel && (txp->flags & - IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? - "Common " : (txp->channel) ? - "Channel" : "Common", - (txp->channel), - TXP_CHECK_AND_PRINT(VALID), - TXP_CHECK_AND_PRINT(BAND_52G), - TXP_CHECK_AND_PRINT(OFDM), - TXP_CHECK_AND_PRINT(40MHZ), - TXP_CHECK_AND_PRINT(HT_AP), - TXP_CHECK_AND_PRINT(RES1), - TXP_CHECK_AND_PRINT(RES2), - TXP_CHECK_AND_PRINT(COMMON_TYPE), - txp->flags); - IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x " - "chain_B: 0X%02x chain_C: 0X%02x\n", - txp->chain_a_max, txp->chain_b_max, - txp->chain_c_max); - IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x " - "MIMO3: 0x%02x High 20_on_40: 0x%02x " - "Low 20_on_40: 0x%02x\n", - txp->mimo2_max, txp->mimo3_max, - ((txp->delta_20_in_40 & 0xf0) >> 4), - (txp->delta_20_in_40 & 0x0f)); - - max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, - &max_txp_avg_halfdbm); - - /* - * Update the user limit values values to the highest - * power supported by any channel - */ - if (max_txp_avg > priv->tx_power_user_lmt) - priv->tx_power_user_lmt = max_txp_avg; - if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) - priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; - - iwl_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); - } -} diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 80ee65be9cd1..0b669417b0a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -72,6 +72,7 @@ #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-debug.h" +#include "iwl-agn.h" #include "iwl-eeprom.h" #include "iwl-io.h" @@ -138,7 +139,7 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ /****************************************************************************** * - * EEPROM related functions + * generic NVM functions * ******************************************************************************/ @@ -214,6 +215,93 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv) return ret; } +u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) +{ + if (!priv->eeprom) + return 0; + return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); +} + +int iwl_eeprom_check_version(struct iwl_priv *priv) +{ + u16 eeprom_ver; + u16 calib_ver; + + eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); + calib_ver = iwlagn_eeprom_calib_version(priv); + + if (eeprom_ver < priv->cfg->eeprom_ver || + calib_ver < priv->cfg->eeprom_calib_ver) + goto err; + + IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", + eeprom_ver, calib_ver); + + return 0; +err: + IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " + "CALIB=0x%x < 0x%x\n", + eeprom_ver, priv->cfg->eeprom_ver, + calib_ver, priv->cfg->eeprom_calib_ver); + return -EINVAL; + +} + +int iwl_eeprom_check_sku(struct iwl_priv *priv) +{ + u16 radio_cfg; + + if (!priv->cfg->sku) { + /* not using sku overwrite */ + priv->cfg->sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); + if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE && + !priv->cfg->ht_params) { + IWL_ERR(priv, "Invalid 11n configuration\n"); + return -EINVAL; + } + } + if (!priv->cfg->sku) { + IWL_ERR(priv, "Invalid device sku\n"); + return -EINVAL; + } + + IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku); + + if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) { + /* not using .cfg overwrite */ + radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); + priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); + priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); + if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) { + IWL_ERR(priv, "Invalid chain (0X%x, 0X%x)\n", + priv->cfg->valid_tx_ant, + priv->cfg->valid_rx_ant); + return -EINVAL; + } + IWL_INFO(priv, "Valid Tx ant: 0X%x, Valid Rx ant: 0X%x\n", + priv->cfg->valid_tx_ant, priv->cfg->valid_rx_ant); + } + /* + * for some special cases, + * EEPROM did not reflect the correct antenna setting + * so overwrite the valid tx/rx antenna from .cfg + */ + return 0; +} + +void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) +{ + const u8 *addr = iwl_eeprom_query_addr(priv, + EEPROM_MAC_ADDRESS); + memcpy(mac, addr, ETH_ALEN); +} + +/****************************************************************************** + * + * OTP related functions + * +******************************************************************************/ + static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) { iwl_read32(bus(priv), CSR_OTP_GP_REG); @@ -407,11 +495,152 @@ static int iwl_find_otp_image(struct iwl_priv *priv, return -EINVAL; } -u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) +/****************************************************************************** + * + * Tx Power related functions + * +******************************************************************************/ +/** + * iwl_get_max_txpower_avg - get the highest tx power from all chains. + * find the highest tx power from all chains for the channel + */ +static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, + int element, s8 *max_txpower_in_half_dbm) { - if (!priv->eeprom) - return 0; - return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); + s8 max_txpower_avg = 0; /* (dBm) */ + + /* Take the highest tx power from any valid chains */ + if ((priv->cfg->valid_tx_ant & ANT_A) && + (enhanced_txpower[element].chain_a_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_a_max; + if ((priv->cfg->valid_tx_ant & ANT_B) && + (enhanced_txpower[element].chain_b_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_b_max; + if ((priv->cfg->valid_tx_ant & ANT_C) && + (enhanced_txpower[element].chain_c_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_c_max; + if (((priv->cfg->valid_tx_ant == ANT_AB) | + (priv->cfg->valid_tx_ant == ANT_BC) | + (priv->cfg->valid_tx_ant == ANT_AC)) && + (enhanced_txpower[element].mimo2_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].mimo2_max; + if ((priv->cfg->valid_tx_ant == ANT_ABC) && + (enhanced_txpower[element].mimo3_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].mimo3_max; + + /* + * max. tx power in EEPROM is in 1/2 dBm format + * convert from 1/2 dBm to dBm (round-up convert) + * but we also do not want to loss 1/2 dBm resolution which + * will impact performance + */ + *max_txpower_in_half_dbm = max_txpower_avg; + return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); +} + +static void +iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *txp, + s8 max_txpower_avg) +{ + int ch_idx; + bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; + enum ieee80211_band band; + + band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? + IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; + + for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { + struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; + + /* update matching channel or from common data only */ + if (txp->channel != 0 && ch_info->channel != txp->channel) + continue; + + /* update matching band only */ + if (band != ch_info->band) + continue; + + if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { + ch_info->max_power_avg = max_txpower_avg; + ch_info->curr_txpow = max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + + if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) + ch_info->ht40_max_power_avg = max_txpower_avg; + } +} + +#define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) +#define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) +#define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) + +#define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ + ? # x " " : "") + +void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) +{ + struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; + int idx, entries; + __le16 *txp_len; + s8 max_txp_avg, max_txp_avg_halfdbm; + + BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); + + /* the length is in 16-bit words, but we want entries */ + txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); + entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; + + txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS); + + for (idx = 0; idx < entries; idx++) { + txp = &txp_array[idx]; + /* skip invalid entries */ + if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) + continue; + + IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", + (txp->channel && (txp->flags & + IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? + "Common " : (txp->channel) ? + "Channel" : "Common", + (txp->channel), + TXP_CHECK_AND_PRINT(VALID), + TXP_CHECK_AND_PRINT(BAND_52G), + TXP_CHECK_AND_PRINT(OFDM), + TXP_CHECK_AND_PRINT(40MHZ), + TXP_CHECK_AND_PRINT(HT_AP), + TXP_CHECK_AND_PRINT(RES1), + TXP_CHECK_AND_PRINT(RES2), + TXP_CHECK_AND_PRINT(COMMON_TYPE), + txp->flags); + IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x " + "chain_B: 0X%02x chain_C: 0X%02x\n", + txp->chain_a_max, txp->chain_b_max, + txp->chain_c_max); + IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x " + "MIMO3: 0x%02x High 20_on_40: 0x%02x " + "Low 20_on_40: 0x%02x\n", + txp->mimo2_max, txp->mimo3_max, + ((txp->delta_20_in_40 & 0xf0) >> 4), + (txp->delta_20_in_40 & 0x0f)); + + max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, + &max_txp_avg_halfdbm); + + /* + * Update the user limit values values to the highest + * power supported by any channel + */ + if (max_txp_avg > priv->tx_power_user_lmt) + priv->tx_power_user_lmt = max_txp_avg; + if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) + priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; + + iwl_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); + } } /** From c17d0681b8a4d93217464d8026361c7b44b3ca99 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:42 -0700 Subject: [PATCH 240/287] iwlagn: move PCI-E transport files Move all the PCI-E specific transport files to be iwl-trans-pcie*; specifically iwl-trans.c which is really iwl-trans-pcie.c. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 2 +- .../{iwl-trans-int-pcie.h => iwl-trans-pcie-int.h} | 0 .../{iwl-trans-rx-pcie.c => iwl-trans-pcie-rx.c} | 2 +- .../{iwl-trans-tx-pcie.c => iwl-trans-pcie-tx.c} | 4 ++-- .../iwlwifi/{iwl-trans.c => iwl-trans-pcie.c} | 11 ++++------- 5 files changed, 8 insertions(+), 11 deletions(-) rename drivers/net/wireless/iwlwifi/{iwl-trans-int-pcie.h => iwl-trans-pcie-int.h} (100%) rename drivers/net/wireless/iwlwifi/{iwl-trans-rx-pcie.c => iwl-trans-pcie-rx.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-trans-tx-pcie.c => iwl-trans-pcie-tx.c} (99%) rename drivers/net/wireless/iwlwifi/{iwl-trans.c => iwl-trans-pcie.c} (99%) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index ae1d816cc4ee..6104f1950390 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -14,7 +14,7 @@ iwlagn-objs += iwl-6000.o iwlagn-objs += iwl-1000.o iwlagn-objs += iwl-2000.o iwlagn-objs += iwl-pci.o -iwlagn-objs += iwl-trans.o iwl-trans-rx-pcie.o iwl-trans-tx-pcie.o +iwlagn-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h similarity index 100% rename from drivers/net/wireless/iwlwifi/iwl-trans-int-pcie.h rename to drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c rename to drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2308177232c0..458a6fbc2e39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -34,7 +34,7 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-helpers.h" -#include "iwl-trans-int-pcie.h" +#include "iwl-trans-pcie-int.h" /****************************************************************************** * diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c rename to drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 15cb0ff2ff18..5332aa3961b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -38,7 +38,7 @@ #include "iwl-io.h" #include "iwl-agn-hw.h" #include "iwl-helpers.h" -#include "iwl-trans-int-pcie.h" +#include "iwl-trans-pcie-int.h" #define IWL_TX_CRC_SIZE 4 #define IWL_TX_DELIMITER_SIZE 4 @@ -544,7 +544,7 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tid_data *tid_data; unsigned long flags; - int txq_id; + u16 txq_id; txq_id = iwlagn_txq_ctx_activate_free(trans); if (txq_id == -1) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c similarity index 99% rename from drivers/net/wireless/iwlwifi/iwl-trans.c rename to drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index a49fb26bdf5c..f0115b242c41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -66,7 +66,7 @@ #include #include "iwl-trans.h" -#include "iwl-trans-int-pcie.h" +#include "iwl-trans-pcie-int.h" #include "iwl-csr.h" #include "iwl-prph.h" #include "iwl-shared.h" @@ -142,9 +142,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, { u32 rb_size; const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ - u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ - - rb_timeout = RX_RB_TIMEOUT; + u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */ if (iwlagn_mod_params.amsdu_size_8K) rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; @@ -308,8 +306,8 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, txq->q.n_window = slots_num; - txq->meta = kcalloc(slots_num, sizeof(txq->meta[0]), GFP_KERNEL); - txq->cmd = kcalloc(slots_num, sizeof(txq->cmd[0]), GFP_KERNEL); + txq->meta = kzalloc(sizeof(txq->meta[0]) * slots_num, GFP_KERNEL); + txq->cmd = kzalloc(sizeof(txq->cmd[0]) * slots_num, GFP_KERNEL); if (!txq->meta || !txq->cmd) goto error; @@ -1995,4 +1993,3 @@ const struct iwl_trans_ops trans_ops_pcie = { .suspend = iwl_trans_pcie_suspend, .resume = iwl_trans_pcie_resume, }; - From 370ad313be78473bfdb066397e38abf1b0dd5b5c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:43 -0700 Subject: [PATCH 241/287] iwlagn: generically provide iwl_trans_send_cmd_pdu There's no need to have the transport layer have a callback for iwl_trans_send_cmd_pdu() since it is just a generic wrapper around iwl_trans_send_cmd(). Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 1 + .../net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 13 ---- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 - drivers/net/wireless/iwlwifi/iwl-trans.c | 77 +++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-trans.h | 10 +-- 5 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-trans.c diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 6104f1950390..a7e954b146d3 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -14,6 +14,7 @@ iwlagn-objs += iwl-6000.o iwlagn-objs += iwl-1000.o iwlagn-objs += iwl-2000.o iwlagn-objs += iwl-pci.o +iwlagn-objs += iwl-trans.o iwlagn-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 5332aa3961b0..93d22c470e2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -1099,19 +1099,6 @@ int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return iwl_send_cmd_sync(trans, cmd); } -int iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id, u32 flags, - u16 len, const void *data) -{ - struct iwl_host_cmd cmd = { - .id = id, - .len = { len, }, - .data = { data, }, - .flags = flags, - }; - - return iwl_trans_pcie_send_cmd(trans, &cmd); -} - /* Frees buffers until index _not_ inclusive */ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, struct sk_buff_head *skbs) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index f0115b242c41..de081194e300 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1971,7 +1971,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .wake_any_queue = iwl_trans_pcie_wake_any_queue, .send_cmd = iwl_trans_pcie_send_cmd, - .send_cmd_pdu = iwl_trans_pcie_send_cmd_pdu, .tx = iwl_trans_pcie_tx, .reclaim = iwl_trans_pcie_reclaim, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c new file mode 100644 index 000000000000..1b20c4fb791b --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -0,0 +1,77 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include "iwl-trans.h" + +int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, + u32 flags, u16 len, const void *data) +{ + struct iwl_host_cmd cmd = { + .id = id, + .len = { len, }, + .data = { data, }, + .flags = flags, + }; + + return iwl_trans_send_cmd(trans, &cmd); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index f067408356fc..8fba5162e2dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -151,7 +151,6 @@ struct iwl_host_cmd { * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) * @send_cmd:send a host command - * @send_cmd_pdu:send a host command: flags can be CMD_* * @tx: send an skb * @reclaim: free packet until ssn. Returns a list of freed packets. * @tx_agg_alloc: allocate resources for a TX BA session @@ -183,8 +182,6 @@ struct iwl_trans_ops { int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); - int (*send_cmd_pdu)(struct iwl_trans *trans, u8 id, u32 flags, u16 len, - const void *data); int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, u8 sta_id); @@ -270,11 +267,8 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, return trans->ops->send_cmd(trans, cmd); } -static inline int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, - u32 flags, u16 len, const void *data) -{ - return trans->ops->send_cmd_pdu(trans, id, flags, len, data); -} +int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, + u32 flags, u16 len, const void *data); static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, From 72afb108ad679f0694d3232ffdd34b0e906773ef Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:44 -0700 Subject: [PATCH 242/287] iwlagn: Makefile whitespace cleanup Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index a7e954b146d3..8fa59cdb3b49 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -5,17 +5,17 @@ iwlagn-objs += iwl-agn-ucode.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o -iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-power.o -iwlagn-objs += iwl-rx.o iwl-sta.o -iwlagn-objs += iwl-scan.o iwl-led.o -iwlagn-objs += iwl-agn-rxon.o -iwlagn-objs += iwl-5000.o -iwlagn-objs += iwl-6000.o -iwlagn-objs += iwl-1000.o -iwlagn-objs += iwl-2000.o -iwlagn-objs += iwl-pci.o +iwlagn-objs += iwl-core.o iwl-eeprom.o iwl-power.o +iwlagn-objs += iwl-rx.o iwl-sta.o +iwlagn-objs += iwl-scan.o iwl-led.o +iwlagn-objs += iwl-agn-rxon.o +iwlagn-objs += iwl-5000.o +iwlagn-objs += iwl-6000.o +iwlagn-objs += iwl-1000.o +iwlagn-objs += iwl-2000.o +iwlagn-objs += iwl-pci.o iwlagn-objs += iwl-trans.o -iwlagn-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o +iwlagn-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o From c01a404756ef7dd4089b3d5d2010cba99732e385 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:45 -0700 Subject: [PATCH 243/287] iwlagn: clean up PM code The transport callbacks might as well be undefined when CONFIG_PM_SLEEP is not set, so ifdef all of it out and make everything available for PM_SLEEP only. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 14 ++++---------- drivers/net/wireless/iwlwifi/iwl-trans.h | 5 ++++- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 61f8ea6413c0..5c85133219e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1919,7 +1919,7 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int iwlagn_send_patterns(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) { @@ -1994,7 +1994,7 @@ struct wowlan_key_data { bool error, use_rsc_tsc, use_tkip; }; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static void iwlagn_convert_p1k(u16 *p1k, __le16 *out) { int i; @@ -3203,7 +3203,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .tx = iwlagn_mac_tx, .start = iwlagn_mac_start, .stop = iwlagn_mac_stop, -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .suspend = iwlagn_mac_suspend, .resume = iwlagn_mac_resume, #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index de081194e300..ca13eebbdb4f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1363,8 +1363,7 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) kfree(trans); } -#ifdef CONFIG_PM - +#ifdef CONFIG_PM_SLEEP static int iwl_trans_pcie_suspend(struct iwl_trans *trans) { /* @@ -1402,14 +1401,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) return 0; } -#else /* CONFIG_PM */ -static int iwl_trans_pcie_suspend(struct iwl_trans *trans) -{ return 0; } - -static int iwl_trans_pcie_resume(struct iwl_trans *trans) -{ return 0; } - -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, enum iwl_rxon_context_id ctx) @@ -1989,6 +1981,8 @@ const struct iwl_trans_ops trans_ops_pcie = { .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, .check_stuck_queue = iwl_trans_pcie_check_stuck_queue, +#ifdef CONFIG_PM_SLEEP .suspend = iwl_trans_pcie_suspend, .resume = iwl_trans_pcie_resume, +#endif }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 8fba5162e2dc..5b6e6842d5fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -208,9 +208,10 @@ struct iwl_trans_ops { int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); int (*check_stuck_queue)(struct iwl_trans *trans, int q); int (*wait_tx_queue_empty)(struct iwl_trans *trans); - +#ifdef CONFIG_PM_SLEEP int (*suspend)(struct iwl_trans *trans); int (*resume)(struct iwl_trans *trans); +#endif }; /** @@ -337,6 +338,7 @@ static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, return trans->ops->dbgfs_register(trans, dir); } +#ifdef CONFIG_PM_SLEEP static inline int iwl_trans_suspend(struct iwl_trans *trans) { return trans->ops->suspend(trans); @@ -346,6 +348,7 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) { return trans->ops->resume(trans); } +#endif /***************************************************** * Transport layers implementations From cebcbd752a2e8b3a4da1d554cc570fc5310af057 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:46 -0700 Subject: [PATCH 244/287] iwlagn: rename iwl-pci.h to iwl-cfg.h There's nothing PCI(E) specific in this file. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/{iwl-pci.h => iwl-cfg.h} | 5 ++--- drivers/net/wireless/iwlwifi/iwl-pci.c | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) rename drivers/net/wireless/iwlwifi/{iwl-pci.h => iwl-cfg.h} (97%) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index dacbe3ad5c18..887f9ac434c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -44,7 +44,7 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-shared.h" -#include "iwl-pci.h" +#include "iwl-cfg.h" /* Highest firmware API version supported */ #define IWL1000_UCODE_API_MAX 6 diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 82719b7ec349..5a870104398f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -45,7 +45,7 @@ #include "iwl-agn-hw.h" #include "iwl-6000-hw.h" #include "iwl-shared.h" -#include "iwl-pci.h" +#include "iwl-cfg.h" /* Highest firmware API version supported */ #define IWL2030_UCODE_API_MAX 6 diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index de7f7f2b3d9d..290701620f03 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -47,7 +47,7 @@ #include "iwl-5000-hw.h" #include "iwl-trans.h" #include "iwl-shared.h" -#include "iwl-pci.h" +#include "iwl-cfg.h" /* Highest firmware API version supported */ #define IWL5000_UCODE_API_MAX 5 diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 5c1a8b8584a5..37837f7b6990 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -46,7 +46,7 @@ #include "iwl-6000-hw.h" #include "iwl-trans.h" #include "iwl-shared.h" -#include "iwl-pci.h" +#include "iwl-cfg.h" /* Highest firmware API version supported */ #define IWL6000_UCODE_API_MAX 4 diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h similarity index 97% rename from drivers/net/wireless/iwlwifi/iwl-pci.h rename to drivers/net/wireless/iwlwifi/iwl-cfg.h index c0aea9e092cb..d4f317cfe8b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h @@ -64,11 +64,10 @@ #define __iwl_pci_h__ -/* This file includes the declaration that are internal to the PCI - * implementation of the bus layer +/* + * This file declares the config structures for all devices. */ -/* configuration for the _agn devices */ extern struct iwl_cfg iwl5300_agn_cfg; extern struct iwl_cfg iwl5100_agn_cfg; extern struct iwl_cfg iwl5350_agn_cfg; diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 1be0bc47ef9d..849b5ef71c35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -68,7 +68,7 @@ #include "iwl-shared.h" #include "iwl-trans.h" #include "iwl-csr.h" -#include "iwl-pci.h" +#include "iwl-cfg.h" /* PCI registers */ #define PCI_CFG_RETRY_TIMEOUT 0x041 From fd90b3c1bab995f9225d8048d6d60e39dedac7ed Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:47 -0700 Subject: [PATCH 245/287] iwlagn: remove unused function declarations iwl_suspend and iwl_resume don't exist. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-shared.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 8272a9489ab1..40186a61f20a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -420,11 +420,6 @@ enum iwl_rxon_context_id { NUM_IWL_RXON_CTX }; -#ifdef CONFIG_PM -int iwl_suspend(struct iwl_priv *priv); -int iwl_resume(struct iwl_priv *priv); -#endif /* !CONFIG_PM */ - int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, struct iwl_cfg *cfg); void __devexit iwl_remove(struct iwl_priv * priv); From ca934b6715c134573da5acea01e9258eb0bf7c27 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:48 -0700 Subject: [PATCH 246/287] iwlagn: move sysfs files to debugfs The debug_level and temperature files should be in debugfs, the txpower file is completely unneeded since TX power can be set with iw/iwconfig. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 125 --------------------- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 72 ++++++++++-- 2 files changed, 64 insertions(+), 133 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5c85133219e6..84ba4282c455 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -453,122 +453,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); } -/***************************************************************************** - * - * sysfs attributes - * - *****************************************************************************/ - -#ifdef CONFIG_IWLWIFI_DEBUG - -/* - * The following adds a new attribute to the sysfs representation - * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/) - * used for controlling the debug level. - * - * See the level definitions in iwl for details. - * - * The debug_level being managed using sysfs below is a per device debug - * level that is used instead of the global debug level if it (the per - * device debug level) is set. - */ -static ssize_t show_debug_level(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_shared *shrd = dev_get_drvdata(d); - return sprintf(buf, "0x%08X\n", iwl_get_debug_level(shrd)); -} -static ssize_t store_debug_level(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_shared *shrd = dev_get_drvdata(d); - struct iwl_priv *priv = shrd->priv; - unsigned long val; - int ret; - - ret = strict_strtoul(buf, 0, &val); - if (ret) - IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); - else { - shrd->dbg_level_dev = val; - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(shrd->priv, - "Not enough memory to generate traffic log\n"); - } - return strnlen(buf, count); -} - -static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, - show_debug_level, store_debug_level); - - -#endif /* CONFIG_IWLWIFI_DEBUG */ - - -static ssize_t show_temperature(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_shared *shrd = dev_get_drvdata(d); - struct iwl_priv *priv = shrd->priv; - - if (!iwl_is_alive(priv->shrd)) - return -EAGAIN; - - return sprintf(buf, "%d\n", priv->temperature); -} - -static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); - -static ssize_t show_tx_power(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - - if (!iwl_is_ready_rf(priv->shrd)) - return sprintf(buf, "off\n"); - else - return sprintf(buf, "%d\n", priv->tx_power_user_lmt); -} - -static ssize_t store_tx_power(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct iwl_priv *priv = dev_get_drvdata(d); - unsigned long val; - int ret; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - IWL_INFO(priv, "%s is not in decimal form.\n", buf); - else { - ret = iwl_set_tx_power(priv, val, false); - if (ret) - IWL_ERR(priv, "failed setting tx power (0x%d).\n", - ret); - else - ret = count; - } - return ret; -} - -static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); - -static struct attribute *iwl_sysfs_entries[] = { - &dev_attr_temperature.attr, - &dev_attr_tx_power.attr, -#ifdef CONFIG_IWLWIFI_DEBUG - &dev_attr_debug_level.attr, -#endif - NULL -}; - -static struct attribute_group iwl_attribute_group = { - .name = NULL, /* put in device directory */ - .attrs = iwl_sysfs_entries, -}; - /****************************************************************************** * * uCode download functions @@ -1259,13 +1143,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (err) IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - err = sysfs_create_group(&(priv->bus->dev->kobj), - &iwl_attribute_group); - if (err) { - IWL_ERR(priv, "failed to create sysfs device attributes\n"); - goto out_unbind; - } - /* We have our copies now, allow OS release its copies */ release_firmware(ucode_raw); complete(&priv->firmware_loading_complete); @@ -3474,8 +3351,6 @@ void __devexit iwl_remove(struct iwl_priv * priv) IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); iwl_dbgfs_unregister(priv); - sysfs_remove_group(&priv->bus->dev->kobj, - &iwl_attribute_group); /* ieee80211_unregister_hw call wil cause iwl_mac_stop to * to be called and iwl_down since we are removing the device diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index d0c63cfee15c..bf2a678970a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -64,6 +64,14 @@ goto err; \ } while (0) +#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \ + struct dentry *__tmp; \ + __tmp = debugfs_create_u32(#name, mode, \ + parent, ptr); \ + if (IS_ERR(__tmp) || !__tmp) \ + goto err; \ +} while (0) + /* file operation */ #define DEBUGFS_READ_FUNC(name) \ static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ @@ -2229,8 +2237,8 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, static ssize_t iwl_dbgfs_force_reset_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) { - + size_t count, loff_t *ppos) +{ struct iwl_priv *priv = file->private_data; int i, pos = 0; char buf[300]; @@ -2309,8 +2317,8 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) { - + size_t count, loff_t *ppos) +{ struct iwl_priv *priv = file->private_data; char buf[8]; int buf_size; @@ -2445,6 +2453,52 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); +#ifdef CONFIG_IWLWIFI_DEBUG +static ssize_t iwl_dbgfs_debug_level_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + struct iwl_shared *shrd = priv->shrd; + char buf[11]; + int len; + + len = scnprintf(buf, sizeof(buf), "0x%.8x", + iwl_get_debug_level(shrd)); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t iwl_dbgfs_debug_level_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + struct iwl_shared *shrd = priv->shrd; + char buf[11]; + unsigned long val; + int ret; + + if (count > sizeof(buf)) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + if (copy_from_user(buf, user_buf, count)) + return -EFAULT; + + ret = strict_strtoul(buf, 0, &val); + if (ret) + return ret; + + shrd->dbg_level_dev = val; + if (iwl_alloc_traffic_mem(priv)) + IWL_ERR(priv, "Not enough memory to generate traffic log\n"); + + return count; +} +DEBUGFS_READ_WRITE_FILE_OPS(debug_level); +#endif /* CONFIG_IWLWIFI_DEBUG */ + /* * Create the debugfs files and directories * @@ -2482,6 +2536,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_U32(temperature, dir_data, &priv->temperature, S_IRUSR); + DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); @@ -2496,7 +2552,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); @@ -2507,6 +2562,10 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); +#ifdef CONFIG_IWLWIFI_DEBUG + DEBUGFS_ADD_FILE(debug_level, dir_debug, S_IRUSR | S_IWUSR); +#endif + DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, @@ -2534,6 +2593,3 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) debugfs_remove_recursive(priv->debugfs_dir); priv->debugfs_dir = NULL; } - - - From 18d0077f0c4a3b88a04bf164db39671edafc30b8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:49 -0700 Subject: [PATCH 247/287] iwlagn: remove drvdata support from bus layer Since the removal of the sysfs files, it is no longer necessary to have upper layers control the drvdata, so let the PCI driver have it for itself completely. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-bus.h | 10 ++-------- drivers/net/wireless/iwlwifi/iwl-pci.c | 19 ++++++++----------- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 84ba4282c455..1d53eb84acbb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3186,9 +3186,9 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, priv = hw->priv; priv->bus = bus; priv->shrd = &priv->_shrd; + bus->shrd = priv->shrd; priv->shrd->bus = bus; priv->shrd->priv = priv; - bus_set_drv_data(priv->bus, priv->shrd); priv->shrd->trans = trans_ops->alloc(priv->shrd); if (priv->shrd->trans == NULL) { @@ -3387,8 +3387,6 @@ void __devexit iwl_remove(struct iwl_priv * priv) iwl_trans_free(trans(priv)); - bus_set_drv_data(priv->bus, NULL); - iwl_uninit_drv(priv); dev_kfree_skb(priv->beacon_skb); diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 98535dfd29e7..08b97594e305 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -122,7 +122,6 @@ struct iwl_bus; * struct iwl_bus_ops - bus specific operations * @get_pm_support: must returns true if the bus can go to sleep * @apm_config: will be called during the config of the APM - * @set_drv_data: set the shared data pointer to the bus layer * @get_hw_id: prints the hw_id in the provided buffer * @write8: write a byte to register at offset ofs * @write32: write a dword to register at offset ofs @@ -131,7 +130,6 @@ struct iwl_bus; struct iwl_bus_ops { bool (*get_pm_support)(struct iwl_bus *bus); void (*apm_config)(struct iwl_bus *bus); - void (*set_drv_data)(struct iwl_bus *bus, struct iwl_shared *shrd); void (*get_hw_id)(struct iwl_bus *bus, char buf[], int buf_len); void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); @@ -146,6 +144,8 @@ struct iwl_bus_ops { * @dev - pointer to struct device * that represents the device * @ops - pointer to iwl_bus_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer + * NB: for the time being this needs to be set by the upper layer since + * it allocates the shared data * @irq - the irq number for the device * @reg_lock - protect hw register access */ @@ -172,12 +172,6 @@ static inline void bus_apm_config(struct iwl_bus *bus) bus->ops->apm_config(bus); } -static inline void bus_set_drv_data(struct iwl_bus *bus, - struct iwl_shared *shrd) -{ - bus->ops->set_drv_data(bus, shrd); -} - static inline void bus_get_hw_id(struct iwl_bus *bus, char buf[], int buf_len) { bus->ops->get_hw_id(bus, buf, buf_len); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 849b5ef71c35..23b5f78207ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -134,12 +134,6 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) } } -static void iwl_pci_set_drv_data(struct iwl_bus *bus, struct iwl_shared *shrd) -{ - bus->shrd = shrd; - pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), shrd); -} - static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], int buf_len) { @@ -168,7 +162,6 @@ static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) static const struct iwl_bus_ops bus_ops_pci = { .get_pm_support = iwl_pci_is_pm_supported, .apm_config = iwl_pci_apm_config, - .set_drv_data = iwl_pci_set_drv_data, .get_hw_id = iwl_pci_get_hw_id, .write8 = iwl_pci_write8, .write32 = iwl_pci_write32, @@ -393,6 +386,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_bus = IWL_BUS_GET_PCI_BUS(bus); pci_bus->pci_dev = pdev; + pci_set_drvdata(pdev, bus); + /* W/A - seems to solve weird behavior. We need to remove this if we * don't want to stay in L1 all the time. This wastes a lot of power */ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | @@ -486,9 +481,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static void __devexit iwl_pci_remove(struct pci_dev *pdev) { - struct iwl_shared *shrd = pci_get_drvdata(pdev); - struct iwl_bus *bus = shrd->bus; + struct iwl_bus *bus = pci_get_drvdata(pdev); struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); + struct iwl_shared *shrd = bus->shrd; iwl_remove(shrd->priv); @@ -506,7 +501,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) static int iwl_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_shared *shrd = pci_get_drvdata(pdev); + struct iwl_bus *bus = pci_get_drvdata(pdev); + struct iwl_shared *shrd = bus->shrd; /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if @@ -519,7 +515,8 @@ static int iwl_pci_suspend(struct device *device) static int iwl_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_shared *shrd = pci_get_drvdata(pdev); + struct iwl_bus *bus = pci_get_drvdata(pdev); + struct iwl_shared *shrd = bus->shrd; /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if From c6f30347a79502cc81e8ec55248b569b3a90ba2a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 15 Sep 2011 11:46:50 -0700 Subject: [PATCH 248/287] iwlagn: add support for v2 of temperature offset calibration For 2000 series of NICs, version 2 of temperature offset calibration should be used. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-2000.c | 4 ++ drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 4 +- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 45 ++++++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 8 ++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl-eeprom.h | 5 ++- 6 files changed, 62 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 5a870104398f..db889581c0e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -264,6 +264,7 @@ static struct iwl_bt_params iwl2030_bt_params = { .base_params = &iwl2000_base_params, \ .need_dc_calib = true, \ .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE, \ .iq_invert = true \ @@ -296,6 +297,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = { .bt_params = &iwl2030_bt_params, \ .need_dc_calib = true, \ .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE, \ .adv_pm = true, \ .iq_invert = true \ @@ -322,6 +324,7 @@ struct iwl_cfg iwl2030_2bg_cfg = { .base_params = &iwl2000_base_params, \ .need_dc_calib = true, \ .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE, \ .adv_pm = true, \ .rx_with_siso_diversity = true, \ @@ -350,6 +353,7 @@ struct iwl_cfg iwl105_bgn_cfg = { .bt_params = &iwl2030_bt_params, \ .need_dc_calib = true, \ .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ .led_mode = IWL_LED_RF_STATE, \ .adv_pm = true, \ .rx_with_siso_diversity = true, \ diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index f9630a3c79fe..c0135988e777 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -74,8 +74,8 @@ static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) { u16 temperature, voltage; - __le16 *temp_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); + __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv, + EEPROM_KELVIN_TEMPERATURE); temperature = le16_to_cpu(temp_calib[0]); voltage = le16_to_cpu(temp_calib[1]); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index ea31d7674df3..564d1fcbcec7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -164,7 +164,7 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_cmd cmd; __le16 *offset_calib = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_TEMPERATURE); + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); @@ -178,6 +178,41 @@ static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) (u8 *)&cmd, sizeof(cmd)); } +static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv) +{ + struct iwl_calib_temperature_offset_v2_cmd cmd; + __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv, + EEPROM_KELVIN_TEMPERATURE); + __le16 *offset_calib_low = + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); + __le16 *voltage_reading = + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_VOLTAGE_READING); + + memset(&cmd, 0, sizeof(cmd)); + iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); + memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, + sizeof(offset_calib_high)); + memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, + sizeof(offset_calib_low)); + if (!(cmd.radio_sensor_offset_low)) { + IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); + cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; + cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; + } + memcpy(&cmd.burntVoltageRef, voltage_reading, + sizeof(voltage_reading)); + + IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", + le16_to_cpu(cmd.radio_sensor_offset_high)); + IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", + le16_to_cpu(cmd.radio_sensor_offset_low)); + IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", + le16_to_cpu(cmd.burntVoltageRef)); + + return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET], + (u8 *)&cmd, sizeof(cmd)); +} + static int iwlagn_send_calib_cfg(struct iwl_priv *priv) { struct iwl_calib_cfg_cmd calib_cfg_cmd; @@ -263,8 +298,12 @@ int iwlagn_init_alive_start(struct iwl_priv *priv) * temperature offset calibration is only needed for runtime ucode, * so prepare the value now. */ - if (priv->cfg->need_temp_offset_calib) - return iwlagn_set_temperature_offset_calib(priv); + if (priv->cfg->need_temp_offset_calib) { + if (priv->cfg->temp_offset_v2) + return iwlagn_set_temperature_offset_calib_v2(priv); + else + return iwlagn_set_temperature_offset_calib(priv); + } return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 82bfef4730d5..64593aa03ad6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3263,6 +3263,14 @@ struct iwl_calib_temperature_offset_cmd { __le16 reserved; } __packed; +struct iwl_calib_temperature_offset_v2_cmd { + struct iwl_calib_hdr hdr; + __le16 radio_sensor_offset_high; + __le16 radio_sensor_offset_low; + __le16 burntVoltageRef; + __le16 reserved; +} __packed; + /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ struct iwl_calib_chain_noise_reset_cmd { struct iwl_calib_hdr hdr; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 549dc46d3903..6d7ad45c6d6f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -193,6 +193,7 @@ struct iwl_ht_params { * @rx_with_siso_diversity: 1x1 device with rx antenna diversity * @internal_wimax_coex: internal wifi/wimax combo device * @iq_invert: I/Q inversion + * @temp_offset_v2: support v2 of temperature offset calibration * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -230,6 +231,7 @@ struct iwl_cfg { const bool rx_with_siso_diversity; const bool internal_wimax_coex; const bool iq_invert; + const bool temp_offset_v2; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index e2b5e0ea5d9c..325753e1a65c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -167,7 +167,10 @@ struct iwl_eeprom_enhanced_txpwr { #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) /* temperature */ -#define EEPROM_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) +#define EEPROM_VOLTAGE_READING ((2*0x1) | EEPROM_CALIB_ALL) +#define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) +#define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) + /* agn links */ #define EEPROM_LINK_HOST (2*0x64) From 7d8f2d50b5082385ad0e0ab5f7dc2a6f1c19819c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 15 Sep 2011 11:46:51 -0700 Subject: [PATCH 249/287] iwlagn: use iwl_eeprom_calib_hdr structure For retrieve calibration hdr related information, instead of using structure in one place and #define in other place, unify the method to use data structure. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 6 +----- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 9 +++++---- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 7 ++++++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 13018872f776..e8b324c84da8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -96,11 +96,7 @@ void iwlagn_temperature(struct iwl_priv *priv) u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv) { - struct iwl_eeprom_calib_hdr { - u8 version; - u8 pa_type; - u16 voltage; - } *hdr; + struct iwl_eeprom_calib_hdr *hdr; hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, EEPROM_CALIB_ALL); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 564d1fcbcec7..5f8d7b61db4a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -185,11 +185,12 @@ static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv) EEPROM_KELVIN_TEMPERATURE); __le16 *offset_calib_low = (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); - __le16 *voltage_reading = - (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_VOLTAGE_READING); + struct iwl_eeprom_calib_hdr *hdr; memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); + hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, + EEPROM_CALIB_ALL); memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, sizeof(offset_calib_high)); memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, @@ -199,8 +200,8 @@ static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv) cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; } - memcpy(&cmd.burntVoltageRef, voltage_reading, - sizeof(voltage_reading)); + memcpy(&cmd.burntVoltageRef, &hdr->voltage, + sizeof(hdr->voltage)); IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", le16_to_cpu(cmd.radio_sensor_offset_high)); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 325753e1a65c..c94747e7299e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -163,11 +163,16 @@ struct iwl_eeprom_enhanced_txpwr { } __packed; /* calibration */ +struct iwl_eeprom_calib_hdr { + u8 version; + u8 pa_type; + __le16 voltage; +} __packed; + #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) /* temperature */ -#define EEPROM_VOLTAGE_READING ((2*0x1) | EEPROM_CALIB_ALL) #define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) #define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) From effd4d9aece9184f526e6556786a94d335e38b71 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 15 Sep 2011 11:46:52 -0700 Subject: [PATCH 250/287] iwlagn: do not use interruptible waits Since the dawn of its time, iwlwifi has used interruptible waits to wait for synchronous commands and firmware loading. This leads to "interesting" bugs, because it can't actually handle the interruptions; for example when a command sending is interrupted it will assume the command completed fully, and then leave it pending, which leads to all kinds of trouble when the command finishes later. Since there's no easy way to gracefully deal with interruptions, fix the driver to not use interruptible waits. This at least fixes the error iwlagn 0000:02:00.0: Error: Response NULL in 'REPLY_SCAN_ABORT_CMD' I have seen in P2P testing, but it is likely that there are other errors caused by this. Cc: Stanislaw Gruszka Cc: stable@kernel.org [2.6.24+] Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 9 ++------- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 4 ++-- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 5f8d7b61db4a..b5bae38eff83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -114,13 +114,8 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name); - ret = wait_event_interruptible_timeout(priv->shrd->wait_command_queue, - priv->ucode_write_complete, 5 * HZ); - if (ret == -ERESTARTSYS) { - IWL_ERR(priv, "Could not load the %s uCode section due " - "to interrupt\n", name); - return ret; - } + ret = wait_event_timeout(priv->shrd->wait_command_queue, + priv->ucode_write_complete, 5 * HZ); if (!ret) { IWL_ERR(priv, "Could not load the %s uCode section\n", name); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index ce8a015c7205..cea6520fafdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -869,7 +869,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) * commands by clearing the ready bit */ clear_bit(STATUS_READY, &priv->shrd->status); - wake_up_interruptible(&priv->shrd->wait_command_queue); + wake_up(&priv->shrd->wait_command_queue); if (!ondemand) { /* diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index c7e6a746c3ea..2ee61031e207 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -644,7 +644,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); else - wake_up_interruptible(&priv->shrd->wait_command_queue); + wake_up(&priv->shrd->wait_command_queue); } static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 458a6fbc2e39..6f3f07dd817d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -657,7 +657,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) */ clear_bit(STATUS_READY, &trans->shrd->status); clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); - wake_up_interruptible(&priv->shrd->wait_command_queue); + wake_up(&priv->shrd->wait_command_queue); IWL_ERR(trans, "RF is used by WiMAX\n"); return; } @@ -1098,7 +1098,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ priv(trans)->ucode_write_complete = 1; - wake_up_interruptible(&trans->shrd->wait_command_queue); + wake_up(&trans->shrd->wait_command_queue); } if (inta & ~handled) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 93d22c470e2f..62c00523b3bf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -946,7 +946,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->hdr.cmd)); - wake_up_interruptible(&trans->shrd->wait_command_queue); + wake_up(&trans->shrd->wait_command_queue); } meta->flags = 0; @@ -1032,7 +1032,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return ret; } - ret = wait_event_interruptible_timeout(trans->shrd->wait_command_queue, + ret = wait_event_timeout(trans->shrd->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), HOST_COMPLETE_TIMEOUT); if (!ret) { From 000850065c3b8ee6c9e8125496be3ee9773903cc Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 15 Sep 2011 11:46:53 -0700 Subject: [PATCH 251/287] iwlagn: fix stack corruption for temperature offset v2 Same stack corruption problem as temperature offset Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index b5bae38eff83..3e40429fa5ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -187,9 +187,9 @@ static int iwlagn_set_temperature_offset_calib_v2(struct iwl_priv *priv) hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, EEPROM_CALIB_ALL); memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, - sizeof(offset_calib_high)); + sizeof(*offset_calib_high)); memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, - sizeof(offset_calib_low)); + sizeof(*offset_calib_low)); if (!(cmd.radio_sensor_offset_low)) { IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; From 143bb15de5ea904195d8e52cca7e2edbf5b31159 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 15 Sep 2011 11:46:54 -0700 Subject: [PATCH 252/287] iwlagn: signedness bug re-apply the unsigned shorts bug fixed by Dan Carpenter but get lost after the file move. Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 62c00523b3bf..c8e56858fa10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -544,7 +544,7 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tid_data *tid_data; unsigned long flags; - u16 txq_id; + int txq_id; txq_id = iwlagn_txq_ctx_activate_free(trans); if (txq_id == -1) { From 7cc44ed48d0ec0937c1f098642540b6c9ca38de5 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 16 Sep 2011 15:32:34 +0530 Subject: [PATCH 253/287] mac80211: Fix regression on queue stop during 2040 bss change The commit "mac80211: stop tx before doing hw config and rate update" stops the tx queue and call drv_flush so frequently whenever a beacon got received with 11n htcap. This leads to massive "Failed to stop TX DMA" logspam on embedded hw. So the queue stop and flush should be called if and only if there is a change in the channel type. Reported-by: Felix Fietkau Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2f92ae2f9706..1a59fb6630d4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -160,7 +160,8 @@ static int ecw2cw(int ecw) */ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, struct ieee80211_ht_info *hti, - const u8 *bssid, u16 ap_ht_cap_flags) + const u8 *bssid, u16 ap_ht_cap_flags, + bool beacon_htcap_ie) { struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; @@ -232,6 +233,21 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); } + if (beacon_htcap_ie && (prev_chantype != channel_type)) { + /* + * Whenever the AP announces the HT mode change that can be + * 40MHz intolerant or etc., it would be safer to stop tx + * queues before doing hw config to avoid buffer overflow. + */ + ieee80211_stop_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); + + /* flush out all packets */ + synchronize_net(); + + drv_flush(local, false); + } + /* channel_type change automatically detected */ ieee80211_hw_config(local, 0); @@ -243,6 +259,10 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, IEEE80211_RC_HT_CHANGED, channel_type); rcu_read_unlock(); + + if (beacon_htcap_ie) + ieee80211_wake_queues_by_reason(&sdata->local->hw, + IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); } ht_opmode = le16_to_cpu(hti->operation_mode); @@ -1588,7 +1608,8 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, (sdata->local->hw.queues >= 4) && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, - cbss->bssid, ap_ht_cap_flags); + cbss->bssid, ap_ht_cap_flags, + false); /* set AID and assoc capability, * ieee80211_set_associated() will tell the driver */ @@ -1921,24 +1942,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, rcu_read_unlock(); - /* - * Whenever the AP announces the HT mode change that can be - * 40MHz intolerant or etc., it would be safer to stop tx - * queues before doing hw config to avoid buffer overflow. - */ - ieee80211_stop_queues_by_reason(&sdata->local->hw, - IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); - - /* flush out all packets */ - synchronize_net(); - - drv_flush(local, false); - changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, - bssid, ap_ht_cap_flags); - - ieee80211_wake_queues_by_reason(&sdata->local->hw, - IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); + bssid, ap_ht_cap_flags, true); } /* Note: country IE parsing is done for us by cfg80211 */ From 3861b2c5d90b219ee772b5a1d1a32ee630564121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Sep 2011 12:33:58 +0200 Subject: [PATCH 254/287] bcma: cc: export more control functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/driver_chipcommon_pmu.c | 38 ++++++++++++++++----- include/linux/bcma/bcma_driver_chipcommon.h | 9 +++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index 4bc10aa57bd4..2968d809d49f 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -18,20 +18,40 @@ static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); } -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, - u32 offset, u32 mask, u32 set) +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { - u32 value; + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); + bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); +} +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write); - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, + u32 set) +{ + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); + bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set); +} +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset); + +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, + u32 offset, u32 mask, u32 set) +{ bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset); bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); - value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA); - value &= mask; - value |= set; - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value); - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA); + bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set); +} +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset); + +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, + u32 set) +{ + bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset); + bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR); + bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set); } +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) { diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index a7ae33d06f24..1526d965ed06 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -378,4 +378,13 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value); /* PMU support */ extern void bcma_pmu_init(struct bcma_drv_cc *cc); +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, + u32 value); +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, + u32 mask, u32 set); +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, + u32 offset, u32 mask, u32 set); +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, + u32 offset, u32 mask, u32 set); + #endif /* LINUX_BCMA_DRIVER_CC_H_ */ From b534706a0692912e72d4be78f45be57c5b231ed5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Sep 2011 12:33:59 +0200 Subject: [PATCH 255/287] b43: LCN-PHY: tweaks for channel switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They have been taken from brcmsmac, add Broadcom's copyright. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 67 ++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index d1dfeec7bc28..06d8efc2f29f 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -20,6 +20,14 @@ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. + This file incorporates work covered by the following copyright and + permission notice: + + Copyright (c) 2010 Broadcom Corporation + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. */ #include @@ -278,14 +286,50 @@ static void b43_phy_lcn_sense_setup(struct b43_wldev *dev) * Channel switching ops. **************************************************/ -static int b43_phy_lcn_set_channel(struct b43_wldev *dev, - struct ieee80211_channel *channel, - enum nl80211_channel_type channel_type) +/* wlc_lcnphy_set_chanspec_tweaks */ +static void b43_phy_lcn_set_channel_tweaks(struct b43_wldev *dev, int channel) { - /* TODO: PLL and PHY ops */ + struct bcma_drv_cc *cc = &dev->dev->bdev->bus->drv_cc; + + b43_phy_maskset(dev, 0x448, ~0x300, (channel == 14) ? 0x200 : 0x100); + + if (channel == 1 || channel == 2 || channel == 3 || channel == 4 || + channel == 9 || channel == 10 || channel == 11 || channel == 12) { + bcma_chipco_pll_write(cc, 0x2, 0x03000c04); + bcma_chipco_pll_maskset(cc, 0x3, 0x00ffffff, 0x0); + bcma_chipco_pll_write(cc, 0x4, 0x200005c0); + + bcma_cc_set32(cc, BCMA_CC_PMU_CTL, 0x400); + + b43_phy_write(dev, 0x942, 0); + + /* b43_phy_lcn_txrx_spur_avoidance_mode(dev, false); */ + b43_phy_maskset(dev, 0x424, (u16) ~0xff00, 0x1b00); + b43_phy_write(dev, 0x425, 0x5907); + } else { + bcma_chipco_pll_write(cc, 0x2, 0x03140c04); + bcma_chipco_pll_maskset(cc, 0x3, 0x00ffffff, 0x333333); + bcma_chipco_pll_write(cc, 0x4, 0x202c2820); + + bcma_cc_set32(cc, BCMA_CC_PMU_CTL, 0x400); + + b43_phy_write(dev, 0x942, 0); + + /* b43_phy_lcn_txrx_spur_avoidance_mode(dev, true); */ + b43_phy_maskset(dev, 0x424, (u16) ~0xff00, 0x1f00); + b43_phy_write(dev, 0x425, 0x590a); + } b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); +} + +/* wlc_phy_chanspec_set_lcnphy */ +static int b43_phy_lcn_set_channel(struct b43_wldev *dev, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type) +{ + b43_phy_lcn_set_channel_tweaks(dev, channel->hw_value); b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); @@ -336,6 +380,8 @@ static void b43_phy_lcn_op_prepare_structs(struct b43_wldev *dev) /* wlc_phy_init_lcnphy */ static int b43_phy_lcn_op_init(struct b43_wldev *dev) { + struct bcma_drv_cc *cc = &dev->dev->bdev->bus->drv_cc; + b43_phy_set(dev, 0x44a, 0x80); b43_phy_mask(dev, 0x44a, 0x7f); b43_phy_set(dev, 0x6d1, 0x80); @@ -359,6 +405,19 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev) b43_phy_lcn_sense_setup(dev); + b43_switch_channel(dev, dev->phy.channel); + + bcma_chipco_regctl_maskset(cc, 0, 0xf, 0x9); + bcma_chipco_chipctl_maskset(cc, 0, 0, 0x03cddddd); + + /* TODO */ + + b43_phy_set(dev, 0x448, 0x4000); + udelay(100); + b43_phy_mask(dev, 0x448, ~0x4000); + + /* TODO */ + return 0; } From 0c5644b98b54dd4d156aba098689adb2054205cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Sep 2011 12:34:00 +0200 Subject: [PATCH 256/287] b43: LCN-PHY: set TX filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 107 ++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 06d8efc2f29f..765036461204 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -37,6 +37,11 @@ #include "tables_phy_lcn.h" #include "main.h" +struct lcn_tx_iir_filter { + u8 type; + u16 values[16]; +}; + /************************************************** * Radio 2064. **************************************************/ @@ -282,6 +287,86 @@ static void b43_phy_lcn_sense_setup(struct b43_wldev *dev) b43_radio_write(dev, 0x4a4, save_radio_4a4); } +static bool b43_phy_lcn_load_tx_iir_cck_filter(struct b43_wldev *dev, + u8 filter_type) +{ + int i, j; + u16 phy_regs[] = { 0x910, 0x91e, 0x91f, 0x924, 0x925, 0x926, 0x920, + 0x921, 0x927, 0x928, 0x929, 0x922, 0x923, 0x930, + 0x931, 0x932 }; + /* Table is from brcmsmac, values for type 25 were outdated, probably + * others need updating too */ + struct lcn_tx_iir_filter tx_iir_filters_cck[] = { + { 0, { 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, + 1582, 64, 128, 64 } }, + { 1, { 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, + 1863, 93, 167, 93 } }, + { 2, { 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, + 778, 1582, 64, 128, 64 } }, + { 3, { 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, + 754, 1760, 170, 340, 170 } }, + { 20, { 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, + 767, 1760, 256, 185, 256 } }, + { 21, { 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, + 767, 1760, 256, 273, 256 } }, + { 22, { 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, + 767, 1760, 256, 352, 256 } }, + { 23, { 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, + 767, 1760, 128, 233, 128 } }, + { 24, { 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, + 1760, 256, 1881, 256 } }, + { 25, { 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, + 1760, 262, 1878, 262 } }, + /* brcmsmac version { 25, { 1, 299, 1884, 51, 64, 51, 736, 1720, + * 256, 471, 256, 765, 1760, 256, 1881, 256 } }, */ + { 26, { 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, + 1864, 128, 384, 288 } }, + { 27, { 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, + 613, 1864, 128, 384, 288 } }, + { 30, { 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, + 754, 1760, 170, 340, 170 } }, + }; + + for (i = 0; i < ARRAY_SIZE(tx_iir_filters_cck); i++) { + if (tx_iir_filters_cck[i].type == filter_type) { + for (j = 0; j < 16; j++) + b43_phy_write(dev, phy_regs[j], + tx_iir_filters_cck[i].values[j]); + return true; + } + } + + return false; +} + +static bool b43_phy_lcn_load_tx_iir_ofdm_filter(struct b43_wldev *dev, + u8 filter_type) +{ + int i, j; + u16 phy_regs[] = { 0x90f, 0x900, 0x901, 0x906, 0x907, 0x908, 0x902, + 0x903, 0x909, 0x90a, 0x90b, 0x904, 0x905, 0x90c, + 0x90d, 0x90e }; + struct lcn_tx_iir_filter tx_iir_filters_ofdm[] = { + { 0, { 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, + 0x0, 0x278, 0xfea0, 0x80, 0x100, 0x80 } }, + { 1, { 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50, 750, + 0xFE2B, 212, 0xFFCE, 212 } }, + { 2, { 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748, + 0xFEF2, 128, 0xFFE2, 128 } }, + }; + + for (i = 0; i < ARRAY_SIZE(tx_iir_filters_ofdm); i++) { + if (tx_iir_filters_ofdm[i].type == filter_type) { + for (j = 0; j < 16; j++) + b43_phy_write(dev, phy_regs[j], + tx_iir_filters_ofdm[i].values[j]); + return true; + } + } + + return false; +} + /************************************************** * Channel switching ops. **************************************************/ @@ -329,6 +414,12 @@ static int b43_phy_lcn_set_channel(struct b43_wldev *dev, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type) { + static const u16 sfo_cfg[14][2] = { + {965, 1087}, {967, 1085}, {969, 1082}, {971, 1080}, {973, 1078}, + {975, 1076}, {977, 1073}, {979, 1071}, {981, 1069}, {983, 1067}, + {985, 1065}, {987, 1063}, {989, 1060}, {994, 1055}, + }; + b43_phy_lcn_set_channel_tweaks(dev, channel->hw_value); b43_phy_set(dev, 0x44a, 0x44); @@ -339,7 +430,21 @@ static int b43_phy_lcn_set_channel(struct b43_wldev *dev, b43_phy_lcn_afe_set_unset(dev); - /* TODO */ + b43_phy_write(dev, 0x657, sfo_cfg[channel->hw_value - 1][0]); + b43_phy_write(dev, 0x658, sfo_cfg[channel->hw_value - 1][1]); + + if (channel->hw_value == 14) { + b43_phy_maskset(dev, 0x448, ~(0x3 << 8), (2) << 8); + b43_phy_lcn_load_tx_iir_cck_filter(dev, 3); + } else { + b43_phy_maskset(dev, 0x448, ~(0x3 << 8), (1) << 8); + /* brcmsmac uses filter_type 2, we follow wl with 25 */ + b43_phy_lcn_load_tx_iir_cck_filter(dev, 25); + } + /* brcmsmac uses filter_type 2, we follow wl with 0 */ + b43_phy_lcn_load_tx_iir_ofdm_filter(dev, 0); + + b43_phy_maskset(dev, 0x4eb, ~(0x7 << 3), 0x1 << 3); return 0; } From ac78a52f49e3645c49e2c13a239b570d2e590bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Sep 2011 12:34:01 +0200 Subject: [PATCH 257/287] b43: LCN-PHY: implement SPUR avoidance mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 58 ++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 765036461204..895164783c3b 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -42,6 +42,39 @@ struct lcn_tx_iir_filter { u16 values[16]; }; +/* In theory it's PHY common function, move if needed */ +/* brcms_b_switch_macfreq */ +static void b43_phy_switch_macfreq(struct b43_wldev *dev, u8 spurmode) +{ + if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) { + switch (spurmode) { + case 2: /* 126 Mhz */ + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082); + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8); + break; + case 1: /* 123 Mhz */ + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341); + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8); + break; + default: /* 120 Mhz */ + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889); + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8); + break; + } + } else if (dev->phy.type == B43_PHYTYPE_LCN) { + switch (spurmode) { + case 1: /* 82 Mhz */ + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0); + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC); + break; + default: /* 80 Mhz */ + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD); + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC); + break; + } + } +} + /************************************************** * Radio 2064. **************************************************/ @@ -367,6 +400,27 @@ static bool b43_phy_lcn_load_tx_iir_ofdm_filter(struct b43_wldev *dev, return false; } +/* wlc_lcnphy_txrx_spur_avoidance_mode */ +static void b43_phy_lcn_txrx_spur_avoidance_mode(struct b43_wldev *dev, + bool enable) +{ + if (enable) { + b43_phy_write(dev, 0x942, 0x7); + b43_phy_write(dev, 0x93b, ((1 << 13) + 23)); + b43_phy_write(dev, 0x93c, ((1 << 13) + 1989)); + + b43_phy_write(dev, 0x44a, 0x084); + b43_phy_write(dev, 0x44a, 0x080); + b43_phy_write(dev, 0x6d3, 0x2222); + b43_phy_write(dev, 0x6d3, 0x2220); + } else { + b43_phy_write(dev, 0x942, 0x0); + b43_phy_write(dev, 0x93b, ((0 << 13) + 23)); + b43_phy_write(dev, 0x93c, ((0 << 13) + 1989)); + } + b43_phy_switch_macfreq(dev, enable); +} + /************************************************** * Channel switching ops. **************************************************/ @@ -388,7 +442,7 @@ static void b43_phy_lcn_set_channel_tweaks(struct b43_wldev *dev, int channel) b43_phy_write(dev, 0x942, 0); - /* b43_phy_lcn_txrx_spur_avoidance_mode(dev, false); */ + b43_phy_lcn_txrx_spur_avoidance_mode(dev, false); b43_phy_maskset(dev, 0x424, (u16) ~0xff00, 0x1b00); b43_phy_write(dev, 0x425, 0x5907); } else { @@ -400,7 +454,7 @@ static void b43_phy_lcn_set_channel_tweaks(struct b43_wldev *dev, int channel) b43_phy_write(dev, 0x942, 0); - /* b43_phy_lcn_txrx_spur_avoidance_mode(dev, true); */ + b43_phy_lcn_txrx_spur_avoidance_mode(dev, true); b43_phy_maskset(dev, 0x424, (u16) ~0xff00, 0x1f00); b43_phy_write(dev, 0x425, 0x590a); } From 1b0a69c1ff445c265b173cc82c3f41a01dd90bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Sep 2011 12:34:02 +0200 Subject: [PATCH 258/287] b43: LCN-PHY: init TX power control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 92 +++++++++++++++++++++++++++++- drivers/net/wireless/b43/phy_lcn.h | 2 + 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 895164783c3b..8810bc99d28c 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -37,6 +37,13 @@ #include "tables_phy_lcn.h" #include "main.h" +struct lcn_tx_gains { + u16 gm_gain; + u16 pga_gain; + u16 pad_gain; + u16 dac_gain; +}; + struct lcn_tx_iir_filter { u8 type; u16 values[16]; @@ -198,6 +205,29 @@ static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1); } +/* wlc_lcnphy_get_pa_gain */ +static u16 b43_phy_lcn_get_pa_gain(struct b43_wldev *dev) +{ + return (b43_phy_read(dev, 0x4fb) & 0x7f00) >> 8; +} + +/* wlc_lcnphy_set_dac_gain */ +static void b43_phy_lcn_set_dac_gain(struct b43_wldev *dev, u16 dac_gain) +{ + u16 dac_ctrl; + + dac_ctrl = b43_phy_read(dev, 0x439); + dac_ctrl = dac_ctrl & 0xc7f; + dac_ctrl = dac_ctrl | (dac_gain << 7); + b43_phy_maskset(dev, 0x439, ~0xfff, dac_ctrl); +} + +/* wlc_lcnphy_set_bbmult */ +static void b43_phy_lcn_set_bbmult(struct b43_wldev *dev, u8 m0) +{ + b43_lcntab_write(dev, B43_LCNTAB16(0x00, 0x57), m0 << 8); +} + /* wlc_lcnphy_clear_tx_power_offsets */ static void b43_phy_lcn_clear_tx_power_offsets(struct b43_wldev *dev) { @@ -400,6 +430,65 @@ static bool b43_phy_lcn_load_tx_iir_ofdm_filter(struct b43_wldev *dev, return false; } +/* wlc_lcnphy_set_tx_gain_override */ +static void b43_phy_lcn_set_tx_gain_override(struct b43_wldev *dev, bool enable) +{ + b43_phy_maskset(dev, 0x4b0, ~(0x1 << 7), enable << 7); + b43_phy_maskset(dev, 0x4b0, ~(0x1 << 14), enable << 14); + b43_phy_maskset(dev, 0x43b, ~(0x1 << 6), enable << 6); +} + +/* wlc_lcnphy_set_tx_gain */ +static void b43_phy_lcn_set_tx_gain(struct b43_wldev *dev, + struct lcn_tx_gains *target_gains) +{ + u16 pa_gain = b43_phy_lcn_get_pa_gain(dev); + + b43_phy_write(dev, 0x4b5, + (target_gains->gm_gain | (target_gains->pga_gain << 8))); + b43_phy_maskset(dev, 0x4fb, ~0x7fff, + (target_gains->pad_gain | (pa_gain << 8))); + b43_phy_write(dev, 0x4fc, + (target_gains->gm_gain | (target_gains->pga_gain << 8))); + b43_phy_maskset(dev, 0x4fd, ~0x7fff, + (target_gains->pad_gain | (pa_gain << 8))); + + b43_phy_lcn_set_dac_gain(dev, target_gains->dac_gain); + b43_phy_lcn_set_tx_gain_override(dev, true); +} + +/* wlc_lcnphy_tx_pwr_ctrl_init */ +static void b43_phy_lcn_tx_pwr_ctl_init(struct b43_wldev *dev) +{ + struct lcn_tx_gains tx_gains; + u8 bbmult; + + b43_mac_suspend(dev); + + if (!dev->phy.lcn->hw_pwr_ctl_capable) { + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + tx_gains.gm_gain = 4; + tx_gains.pga_gain = 12; + tx_gains.pad_gain = 12; + tx_gains.dac_gain = 0; + bbmult = 150; + } else { + tx_gains.gm_gain = 7; + tx_gains.pga_gain = 15; + tx_gains.pad_gain = 14; + tx_gains.dac_gain = 0; + bbmult = 150; + } + b43_phy_lcn_set_tx_gain(dev, &tx_gains); + b43_phy_lcn_set_bbmult(dev, bbmult); + b43_phy_lcn_sense_setup(dev); /* TODO: TEMPSENSE as arg */ + } else { + b43err(dev->wl, "TX power control not supported for this HW\n"); + } + + b43_mac_enable(dev); +} + /* wlc_lcnphy_txrx_spur_avoidance_mode */ static void b43_phy_lcn_txrx_spur_avoidance_mode(struct b43_wldev *dev, bool enable) @@ -562,7 +651,8 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev) else B43_WARN_ON(1); - b43_phy_lcn_sense_setup(dev); + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + b43_phy_lcn_tx_pwr_ctl_init(dev); b43_switch_channel(dev, dev->phy.channel); diff --git a/drivers/net/wireless/b43/phy_lcn.h b/drivers/net/wireless/b43/phy_lcn.h index 25f06e8d4531..2a386d07fc23 100644 --- a/drivers/net/wireless/b43/phy_lcn.h +++ b/drivers/net/wireless/b43/phy_lcn.h @@ -19,6 +19,8 @@ struct b43_phy_lcn { + bool hw_pwr_ctl; + bool hw_pwr_ctl_capable; }; From bbb5574224168ef62c8549535c0d0a99e989ecf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Sep 2011 12:34:03 +0200 Subject: [PATCH 259/287] b43: LCN-PHY: add more init tweaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 8810bc99d28c..3ac235770863 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -307,12 +307,30 @@ static void b43_phy_lcn_bu_tweaks(struct b43_wldev *dev) b43_phy_write(dev, 0x7d6, 0x0902); - /* TODO: more ops */ + b43_phy_maskset(dev, 0x429, ~0xf, 0x9); + b43_phy_maskset(dev, 0x429, ~(0x3f << 4), 0xe << 4); if (dev->phy.rev == 1) { - /* TODO: more ops */ + b43_phy_maskset(dev, 0x423, ~0xff, 0x46); + b43_phy_maskset(dev, 0x411, ~0xff, 1); + b43_phy_set(dev, 0x434, 0xff); /* FIXME: update to wl */ + + /* TODO: wl operates on PHY 0x416, brcmsmac is outdated here */ + + b43_phy_maskset(dev, 0x656, ~0xf, 2); + b43_phy_set(dev, 0x44d, 4); + + b43_radio_set(dev, 0x0f7, 0x4); + b43_radio_mask(dev, 0x0f1, ~0x3); + b43_radio_maskset(dev, 0x0f2, ~0xf8, 0x90); + b43_radio_maskset(dev, 0x0f3, ~0x3, 0x2); + b43_radio_maskset(dev, 0x0f3, ~0xf0, 0xa0); + + b43_radio_set(dev, 0x11f, 0x2); b43_phy_lcn_clear_tx_power_offsets(dev); + + /* TODO: something more? */ } } From 39193498913f82dd7e484aa908843ca4114c3b0c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Sep 2011 13:45:25 +0200 Subject: [PATCH 260/287] cfg80211: validate IBSS BSSID The IBSS BSSID is never validated, so an invalid one might end up being used. Fix this by rejecting invalid configuration. Reported-by: Marek Lindner Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 11089541bb03..430b432bc3f0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4527,8 +4527,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) wiphy = &rdev->wiphy; - if (info->attrs[NL80211_ATTR_MAC]) + if (info->attrs[NL80211_ATTR_MAC]) { ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); + + if (!is_valid_ether_addr(ibss.bssid)) + return -EINVAL; + } ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); From 6be19ccd698abf9c4f0b7bba5a704f94e7ccdf54 Mon Sep 17 00:00:00 2001 From: Mohammed Shafi Shajakhan Date: Fri, 16 Sep 2011 19:03:40 +0530 Subject: [PATCH 261/287] rfkill: properly assign a boolean type Signed-off-by: Mohammed Shafi Shajakhan Signed-off-by: John W. Linville --- net/rfkill/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rfkill/core.c b/net/rfkill/core.c index be90640a2774..5be19575c340 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -235,7 +235,7 @@ static bool __rfkill_set_hw_state(struct rfkill *rfkill, else rfkill->state &= ~RFKILL_BLOCK_HW; *change = prev != blocked; - any = rfkill->state & RFKILL_BLOCK_ANY; + any = !!(rfkill->state & RFKILL_BLOCK_ANY); spin_unlock_irqrestore(&rfkill->lock, flags); rfkill_led_trigger_event(rfkill); From 2981808269941490f209b2db88ae021d7007b39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 16 Sep 2011 16:36:32 +0200 Subject: [PATCH 262/287] b43: LCN-PHY: finish sense setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_lcn.c | 90 +++++++++++++++++++++++++++++- drivers/net/wireless/b43/phy_lcn.h | 1 + 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 3ac235770863..bffeb44b4a40 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c @@ -49,6 +49,11 @@ struct lcn_tx_iir_filter { u16 values[16]; }; +enum lcn_sense_type { + B43_SENSE_TEMP, + B43_SENSE_VBAT, +}; + /* In theory it's PHY common function, move if needed */ /* brcms_b_switch_macfreq */ static void b43_phy_switch_macfreq(struct b43_wldev *dev, u8 spurmode) @@ -335,8 +340,12 @@ static void b43_phy_lcn_bu_tweaks(struct b43_wldev *dev) } /* wlc_lcnphy_vbat_temp_sense_setup */ -static void b43_phy_lcn_sense_setup(struct b43_wldev *dev) +static void b43_phy_lcn_sense_setup(struct b43_wldev *dev, + enum lcn_sense_type sense_type) { + u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain; + u16 auxpga_vmid; + u8 tx_pwr_idx; u8 i; u16 save_radio_regs[6][2] = { @@ -351,21 +360,96 @@ static void b43_phy_lcn_sense_setup(struct b43_wldev *dev) }; u16 save_radio_4a4; + msleep(1); + + /* Save */ for (i = 0; i < 6; i++) save_radio_regs[i][1] = b43_radio_read(dev, save_radio_regs[i][0]); for (i = 0; i < 14; i++) save_phy_regs[i][1] = b43_phy_read(dev, save_phy_regs[i][0]); + b43_mac_suspend(dev); save_radio_4a4 = b43_radio_read(dev, 0x4a4); + /* wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); */ + tx_pwr_idx = dev->phy.lcn->tx_pwr_curr_idx; + + /* Setup */ + /* TODO: wlc_lcnphy_set_tx_pwr_by_index(pi, 127); */ + b43_radio_set(dev, 0x007, 0x1); + b43_radio_set(dev, 0x0ff, 0x10); + b43_radio_set(dev, 0x11f, 0x4); + + b43_phy_mask(dev, 0x503, ~0x1); + b43_phy_mask(dev, 0x503, ~0x4); + b43_phy_mask(dev, 0x4a4, ~0x4000); + b43_phy_mask(dev, 0x4a4, (u16) ~0x8000); + b43_phy_mask(dev, 0x4d0, ~0x20); + b43_phy_set(dev, 0x4a5, 0xff); + b43_phy_maskset(dev, 0x4a5, ~0x7000, 0x5000); + b43_phy_mask(dev, 0x4a5, ~0x700); + b43_phy_maskset(dev, 0x40d, ~0xff, 64); + b43_phy_maskset(dev, 0x40d, ~0x700, 0x600); + b43_phy_maskset(dev, 0x4a2, ~0xff, 64); + b43_phy_maskset(dev, 0x4a2, ~0x700, 0x600); + b43_phy_maskset(dev, 0x4d9, ~0x70, 0x20); + b43_phy_maskset(dev, 0x4d9, ~0x700, 0x300); + b43_phy_maskset(dev, 0x4d9, ~0x7000, 0x1000); + b43_phy_mask(dev, 0x4da, ~0x1000); + b43_phy_set(dev, 0x4da, 0x2000); + b43_phy_set(dev, 0x4a6, 0x8000); + + b43_radio_write(dev, 0x025, 0xc); + b43_radio_set(dev, 0x005, 0x8); + b43_phy_set(dev, 0x938, 0x4); + b43_phy_set(dev, 0x939, 0x4); + b43_phy_set(dev, 0x4a4, 0x1000); + + /* FIXME: don't hardcode */ + b43_lcntab_write(dev, B43_LCNTAB16(0x8, 0x6), 0x640); + + switch (sense_type) { + case B43_SENSE_TEMP: + b43_phy_set(dev, 0x4d7, 0x8); + b43_phy_maskset(dev, 0x4d7, ~0x7000, 0x1000); + auxpga_vmidcourse = 8; + auxpga_vmidfine = 0x4; + auxpga_gain = 2; + b43_radio_set(dev, 0x082, 0x20); + break; + case B43_SENSE_VBAT: + b43_phy_set(dev, 0x4d7, 0x8); + b43_phy_maskset(dev, 0x4d7, ~0x7000, 0x3000); + auxpga_vmidcourse = 7; + auxpga_vmidfine = 0xa; + auxpga_gain = 2; + break; + } + auxpga_vmid = (0x200 | (auxpga_vmidcourse << 4) | auxpga_vmidfine); - /* TODO: config sth */ + b43_phy_set(dev, 0x4d8, 0x1); + b43_phy_maskset(dev, 0x4d8, ~(0x3ff << 2), auxpga_vmid << 2); + b43_phy_set(dev, 0x4d8, 0x2); + b43_phy_maskset(dev, 0x4d8, ~(0x7 << 12), auxpga_gain << 12); + b43_phy_set(dev, 0x4d0, 0x20); + b43_radio_write(dev, 0x112, 0x6); + /* TODO: dummy transmission? */ + /* Wait if not done */ + if (!(b43_phy_read(dev, 0x476) & 0x8000)) + udelay(10); + + /* Restore */ for (i = 0; i < 6; i++) b43_radio_write(dev, save_radio_regs[i][0], save_radio_regs[i][1]); for (i = 0; i < 14; i++) b43_phy_write(dev, save_phy_regs[i][0], save_phy_regs[i][1]); + /* TODO: wlc_lcnphy_set_tx_pwr_by_index(tx_pwr_idx) */ b43_radio_write(dev, 0x4a4, save_radio_4a4); + + b43_mac_enable(dev); + + msleep(1); } static bool b43_phy_lcn_load_tx_iir_cck_filter(struct b43_wldev *dev, @@ -499,7 +583,7 @@ static void b43_phy_lcn_tx_pwr_ctl_init(struct b43_wldev *dev) } b43_phy_lcn_set_tx_gain(dev, &tx_gains); b43_phy_lcn_set_bbmult(dev, bbmult); - b43_phy_lcn_sense_setup(dev); /* TODO: TEMPSENSE as arg */ + b43_phy_lcn_sense_setup(dev, B43_SENSE_TEMP); } else { b43err(dev->wl, "TX power control not supported for this HW\n"); } diff --git a/drivers/net/wireless/b43/phy_lcn.h b/drivers/net/wireless/b43/phy_lcn.h index 2a386d07fc23..6a7092e13fff 100644 --- a/drivers/net/wireless/b43/phy_lcn.h +++ b/drivers/net/wireless/b43/phy_lcn.h @@ -21,6 +21,7 @@ struct b43_phy_lcn { bool hw_pwr_ctl; bool hw_pwr_ctl_capable; + u8 tx_pwr_curr_idx; }; From c9df56b48e4ff003eaebd680ec7a45342dcd03ea Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 16 Sep 2011 18:56:23 +0300 Subject: [PATCH 263/287] cfg80211/nl80211: Add PMKSA caching candidate event When the driver (or most likely firmware) decides which AP to use for roaming based on internal scan result processing, user space needs to be notified of PMKSA caching candidates to allow RSN pre-authentication to be used. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 33 +++++++++++++++++++++++++++++ include/net/cfg80211.h | 11 ++++++++++ net/wireless/mlme.c | 11 ++++++++++ net/wireless/nl80211.c | 46 +++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 4 ++++ 5 files changed, 105 insertions(+) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index f17307590e61..460b12a8ef66 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -499,6 +499,9 @@ * this command may also be sent by the driver as an MLME event to * inform userspace of the new replay counter. * + * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace + * of PMKSA caching dandidates. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -623,6 +626,8 @@ enum nl80211_commands { NL80211_CMD_SET_REKEY_OFFLOAD, + NL80211_CMD_PMKSA_CANDIDATE, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -1070,6 +1075,9 @@ enum nl80211_commands { * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of * roaming to another AP in the same ESS if the signal lever is low. * + * @NL80211_ATTR_PMKSA_CANDIDATE: Nested attribute containing the PMKSA caching + * candidate information, see &enum nl80211_pmksa_candidate_attr. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -1288,6 +1296,8 @@ enum nl80211_attrs { NL80211_ATTR_SCHED_SCAN_MATCH, NL80211_ATTR_MAX_MATCH_SETS, + NL80211_ATTR_PMKSA_CANDIDATE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -2558,4 +2568,27 @@ enum nl80211_sta_wme_attr { NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1 }; +/** + * enum nl80211_pmksa_candidate_attr - attributes for PMKSA caching candidates + * @__NL80211_PMKSA_CANDIDATE_INVALID: invalid number for nested attributes + * @NL80211_PMKSA_CANDIDATE_INDEX: candidate index (u32; the smaller, the higher + * priority) + * @NL80211_PMKSA_CANDIDATE_BSSID: candidate BSSID (6 octets) + * @NL80211_PMKSA_CANDIDATE_PREAUTH: RSN pre-authentication supported (flag) + * @NUM_NL80211_PMKSA_CANDIDATE: number of PMKSA caching candidate attributes + * (internal) + * @MAX_NL80211_PMKSA_CANDIDATE: highest PMKSA caching candidate attribute + * (internal) + */ +enum nl80211_pmksa_candidate_attr { + __NL80211_PMKSA_CANDIDATE_INVALID, + NL80211_PMKSA_CANDIDATE_INDEX, + NL80211_PMKSA_CANDIDATE_BSSID, + NL80211_PMKSA_CANDIDATE_PREAUTH, + + /* keep last */ + NUM_NL80211_PMKSA_CANDIDATE, + MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1 +}; + #endif /* __LINUX_NL80211_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 9518b5cfb822..6ac4bddeeeca 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3136,6 +3136,17 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, const u8 *replay_ctr, gfp_t gfp); +/** + * cfg80211_pmksa_candidate_notify - notify about PMKSA caching candidate + * @dev: network device + * @index: candidate index (the smaller the index, the higher the priority) + * @bssid: BSSID of AP + * @preauth: Whether AP advertises support for RSN pre-authentication + * @gfp: allocation flags + */ +void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, + const u8 *bssid, bool preauth, gfp_t gfp); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 832f6574e4ed..61adea540e02 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -1095,3 +1095,14 @@ void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp); } EXPORT_SYMBOL(cfg80211_gtk_rekey_notify); + +void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, + const u8 *bssid, bool preauth, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + + nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp); +} +EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 430b432bc3f0..3c6427abdf34 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7270,6 +7270,52 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } +void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, + struct net_device *netdev, int index, + const u8 *bssid, bool preauth, gfp_t gfp) +{ + struct sk_buff *msg; + struct nlattr *attr; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + + attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); + if (!attr) + goto nla_put_failure; + + NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index); + NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid); + if (preauth) + NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH); + + nla_nest_end(msg, attr); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, + nl80211_mlme_mcgrp.id, gfp); + return; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + void nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *peer, diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 5d69c56400ae..f24a1fbeaf19 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -113,4 +113,8 @@ void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *bssid, const u8 *replay_ctr, gfp_t gfp); +void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, + struct net_device *netdev, int index, + const u8 *bssid, bool preauth, gfp_t gfp); + #endif /* __NET_WIRELESS_NL80211_H */ From e30815016bbd0b5c3dcdc29f53e054b57938f1aa Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Thu, 15 Sep 2011 17:40:50 +0530 Subject: [PATCH 264/287] wireless: Do not allow disabled channel in scan request cfg80211_conn_scan allows disabled channels at scan request. Hence probe request was seen at the disabled one. This patch ensures that disabled channel never be added into the scan request's channel list. Acked-by: Johannes Berg Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- net/wireless/sme.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index dec0fa28372e..6e86d5acf145 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -110,17 +110,22 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) else { int i = 0, j; enum ieee80211_band band; + struct ieee80211_supported_band *bands; + struct ieee80211_channel *channel; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!wdev->wiphy->bands[band]) + bands = wdev->wiphy->bands[band]; + if (!bands) continue; - for (j = 0; j < wdev->wiphy->bands[band]->n_channels; - i++, j++) - request->channels[i] = - &wdev->wiphy->bands[band]->channels[j]; - request->rates[band] = - (1 << wdev->wiphy->bands[band]->n_bitrates) - 1; + for (j = 0; j < bands->n_channels; j++) { + channel = &bands->channels[j]; + if (channel->flags & IEEE80211_CHAN_DISABLED) + continue; + request->channels[i++] = channel; + } + request->rates[band] = (1 << bands->n_bitrates) - 1; } + n_channels = i; } request->n_channels = n_channels; request->ssids = (void *)&request->channels[n_channels]; From a7ce1c9446a7f7513211e4698d07357d20452909 Mon Sep 17 00:00:00 2001 From: Alexander Simon Date: Sun, 18 Sep 2011 00:16:45 +0200 Subject: [PATCH 265/287] mac80211: fix indentation Signed-off-by: Alexander Simon Signed-off-by: John W. Linville --- include/net/mac80211.h | 2 +- net/mac80211/ibss.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9edba09547e4..c0f63fd0c52b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -171,7 +171,7 @@ enum ieee80211_bss_change { BSS_CHANGED_ERP_CTS_PROT = 1<<1, BSS_CHANGED_ERP_PREAMBLE = 1<<2, BSS_CHANGED_ERP_SLOT = 1<<3, - BSS_CHANGED_HT = 1<<4, + BSS_CHANGED_HT = 1<<4, BSS_CHANGED_BASIC_RATES = 1<<5, BSS_CHANGED_BEACON_INT = 1<<6, BSS_CHANGED_BSSID = 1<<7, diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 56c24cabf26d..836b2752ecd6 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -417,7 +417,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, * must be callable in atomic context. */ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, - u8 *bssid,u8 *addr, u32 supp_rates, + u8 *bssid, u8 *addr, u32 supp_rates, gfp_t gfp) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; From 8b3fe7b591b3c50061a8701f8eda14033420577b Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Sun, 18 Sep 2011 11:19:33 +0300 Subject: [PATCH 266/287] NFC: Add dev_up and dev_down control operations Add 2 new nfc control operations: dev_up to turn on the nfc device dev_down to turn off the nfc device Signed-off-by: Ilan Elias Signed-off-by: John W. Linville --- drivers/nfc/pn533.c | 2 ++ include/linux/nfc.h | 6 ++++ include/net/nfc.h | 4 +++ net/nfc/core.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ net/nfc/netlink.c | 56 +++++++++++++++++++++++++++++++++ net/nfc/nfc.h | 4 +++ 6 files changed, 149 insertions(+) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index f81a93e5b59d..c78eb6afd0cb 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1432,6 +1432,8 @@ static int pn533_set_configuration(struct pn533 *dev, u8 cfgitem, u8 *cfgdata, } struct nfc_ops pn533_nfc_ops = { + .dev_up = NULL, + .dev_down = NULL, .start_poll = pn533_start_poll, .stop_poll = pn533_stop_poll, .activate_target = pn533_activate_target, diff --git a/include/linux/nfc.h b/include/linux/nfc.h index c525e0b5876b..36cb955b05cc 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h @@ -39,6 +39,10 @@ * * @NFC_CMD_GET_DEVICE: request information about a device (requires * %NFC_ATTR_DEVICE_INDEX) or dump request to get a list of all nfc devices + * @NFC_CMD_DEV_UP: turn on the nfc device + * (requires %NFC_ATTR_DEVICE_INDEX) + * @NFC_CMD_DEV_DOWN: turn off the nfc device + * (requires %NFC_ATTR_DEVICE_INDEX) * @NFC_CMD_START_POLL: start polling for targets using the given protocols * (requires %NFC_ATTR_DEVICE_INDEX and %NFC_ATTR_PROTOCOLS) * @NFC_CMD_STOP_POLL: stop polling for targets (requires @@ -56,6 +60,8 @@ enum nfc_commands { NFC_CMD_UNSPEC, NFC_CMD_GET_DEVICE, + NFC_CMD_DEV_UP, + NFC_CMD_DEV_DOWN, NFC_CMD_START_POLL, NFC_CMD_STOP_POLL, NFC_CMD_GET_TARGET, diff --git a/include/net/nfc.h b/include/net/nfc.h index 87b51fe15b70..6a7f602aa841 100644 --- a/include/net/nfc.h +++ b/include/net/nfc.h @@ -48,6 +48,8 @@ typedef void (*data_exchange_cb_t)(void *context, struct sk_buff *skb, int err); struct nfc_ops { + int (*dev_up)(struct nfc_dev *dev); + int (*dev_down)(struct nfc_dev *dev); int (*start_poll)(struct nfc_dev *dev, u32 protocols); void (*stop_poll)(struct nfc_dev *dev); int (*activate_target)(struct nfc_dev *dev, u32 target_idx, @@ -78,7 +80,9 @@ struct nfc_dev { int targets_generation; spinlock_t targets_lock; struct device dev; + bool dev_up; bool polling; + bool remote_activated; struct nfc_genl_data genl_data; u32 supported_protocols; diff --git a/net/nfc/core.c b/net/nfc/core.c index 284e2f6a14ff..47e02c1b8c02 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -52,6 +52,80 @@ int nfc_printk(const char *level, const char *format, ...) } EXPORT_SYMBOL(nfc_printk); +/** + * nfc_dev_up - turn on the NFC device + * + * @dev: The nfc device to be turned on + * + * The device remains up until the nfc_dev_down function is called. + */ +int nfc_dev_up(struct nfc_dev *dev) +{ + int rc = 0; + + nfc_dbg("dev_name=%s", dev_name(&dev->dev)); + + device_lock(&dev->dev); + + if (!device_is_registered(&dev->dev)) { + rc = -ENODEV; + goto error; + } + + if (dev->dev_up) { + rc = -EALREADY; + goto error; + } + + if (dev->ops->dev_up) + rc = dev->ops->dev_up(dev); + + if (!rc) + dev->dev_up = true; + +error: + device_unlock(&dev->dev); + return rc; +} + +/** + * nfc_dev_down - turn off the NFC device + * + * @dev: The nfc device to be turned off + */ +int nfc_dev_down(struct nfc_dev *dev) +{ + int rc = 0; + + nfc_dbg("dev_name=%s", dev_name(&dev->dev)); + + device_lock(&dev->dev); + + if (!device_is_registered(&dev->dev)) { + rc = -ENODEV; + goto error; + } + + if (!dev->dev_up) { + rc = -EALREADY; + goto error; + } + + if (dev->polling || dev->remote_activated) { + rc = -EBUSY; + goto error; + } + + if (dev->ops->dev_down) + dev->ops->dev_down(dev); + + dev->dev_up = false; + +error: + device_unlock(&dev->dev); + return rc; +} + /** * nfc_start_poll - start polling for nfc targets * @@ -144,6 +218,8 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol) } rc = dev->ops->activate_target(dev, target_idx, protocol); + if (!rc) + dev->remote_activated = true; error: device_unlock(&dev->dev); @@ -170,6 +246,7 @@ int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx) } dev->ops->deactivate_target(dev, target_idx); + dev->remote_activated = false; error: device_unlock(&dev->dev); diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index ccdff7953f7d..03f8818e1f16 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -367,6 +367,52 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info) return rc; } +static int nfc_genl_dev_up(struct sk_buff *skb, struct genl_info *info) +{ + struct nfc_dev *dev; + int rc; + u32 idx; + + nfc_dbg("entry"); + + if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) + return -EINVAL; + + idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); + + dev = nfc_get_device(idx); + if (!dev) + return -ENODEV; + + rc = nfc_dev_up(dev); + + nfc_put_device(dev); + return rc; +} + +static int nfc_genl_dev_down(struct sk_buff *skb, struct genl_info *info) +{ + struct nfc_dev *dev; + int rc; + u32 idx; + + nfc_dbg("entry"); + + if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) + return -EINVAL; + + idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); + + dev = nfc_get_device(idx); + if (!dev) + return -ENODEV; + + rc = nfc_dev_down(dev); + + nfc_put_device(dev); + return rc; +} + static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info) { struct nfc_dev *dev; @@ -440,6 +486,16 @@ static struct genl_ops nfc_genl_ops[] = { .done = nfc_genl_dump_devices_done, .policy = nfc_genl_policy, }, + { + .cmd = NFC_CMD_DEV_UP, + .doit = nfc_genl_dev_up, + .policy = nfc_genl_policy, + }, + { + .cmd = NFC_CMD_DEV_DOWN, + .doit = nfc_genl_dev_down, + .policy = nfc_genl_policy, + }, { .cmd = NFC_CMD_START_POLL, .doit = nfc_genl_start_poll, diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index aaf9832298f3..1a877de8e230 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -101,6 +101,10 @@ static inline void nfc_device_iter_exit(struct class_dev_iter *iter) class_dev_iter_exit(iter); } +int nfc_dev_up(struct nfc_dev *dev); + +int nfc_dev_down(struct nfc_dev *dev); + int nfc_start_poll(struct nfc_dev *dev, u32 protocols); int nfc_stop_poll(struct nfc_dev *dev); From 55eb94f9e923cba376cdf48ea5ab28d81116bead Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Sun, 18 Sep 2011 11:19:34 +0300 Subject: [PATCH 267/287] NFC: move nfc.h from include/net to include/net/nfc The file nfc.h was moved from include/net to include/net/nfc, since new NFC header files will be added to include/net/nfc. Signed-off-by: Ilan Elias Signed-off-by: John W. Linville --- MAINTAINERS | 2 +- drivers/nfc/pn533.c | 2 +- include/net/{ => nfc}/nfc.h | 0 net/nfc/nfc.h | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename include/net/{ => nfc}/nfc.h (100%) diff --git a/MAINTAINERS b/MAINTAINERS index ce0e60c7b07a..1789ce22ea8c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4508,7 +4508,7 @@ L: linux-wireless@vger.kernel.org S: Maintained F: net/nfc/ F: include/linux/nfc.h -F: include/net/nfc.h +F: include/net/nfc/ F: drivers/nfc/ NFS, SUNRPC, AND LOCKD CLIENTS diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index c78eb6afd0cb..7bcb1febef0d 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #define VERSION "0.1" diff --git a/include/net/nfc.h b/include/net/nfc/nfc.h similarity index 100% rename from include/net/nfc.h rename to include/net/nfc/nfc.h diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 1a877de8e230..b6753f45624e 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h @@ -24,7 +24,7 @@ #ifndef __LOCAL_NFC_H #define __LOCAL_NFC_H -#include +#include #include __attribute__((format (printf, 2, 3))) From 6a2968aaf50c7a22fced77a5e24aa636281efca8 Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Sun, 18 Sep 2011 11:19:35 +0300 Subject: [PATCH 268/287] NFC: basic NCI protocol implementation The NFC Controller Interface (NCI) is a standard communication protocol between an NFC Controller (NFCC) and a Device Host (DH), defined by the NFC Forum. Signed-off-by: Ilan Elias Signed-off-by: John W. Linville --- include/net/nfc/nci.h | 313 +++++++++++++++ include/net/nfc/nci_core.h | 183 +++++++++ net/nfc/Kconfig | 2 + net/nfc/Makefile | 1 + net/nfc/nci/Kconfig | 10 + net/nfc/nci/Makefile | 7 + net/nfc/nci/core.c | 790 +++++++++++++++++++++++++++++++++++++ net/nfc/nci/data.c | 245 ++++++++++++ net/nfc/nci/lib.c | 94 +++++ net/nfc/nci/ntf.c | 258 ++++++++++++ net/nfc/nci/rsp.c | 226 +++++++++++ 11 files changed, 2129 insertions(+) create mode 100644 include/net/nfc/nci.h create mode 100644 include/net/nfc/nci_core.h create mode 100644 net/nfc/nci/Kconfig create mode 100644 net/nfc/nci/Makefile create mode 100644 net/nfc/nci/core.c create mode 100644 net/nfc/nci/data.c create mode 100644 net/nfc/nci/lib.c create mode 100644 net/nfc/nci/ntf.c create mode 100644 net/nfc/nci/rsp.c diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h new file mode 100644 index 000000000000..39b85bc0804f --- /dev/null +++ b/include/net/nfc/nci.h @@ -0,0 +1,313 @@ +/* + * The NFC Controller Interface is the communication protocol between an + * NFC Controller (NFCC) and a Device Host (DH). + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * Acknowledgements: + * This file is based on hci.h, which was written + * by Maxim Krasnyansky. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __NCI_H +#define __NCI_H + +/* NCI constants */ +#define NCI_MAX_NUM_MAPPING_CONFIGS 10 +#define NCI_MAX_NUM_RF_CONFIGS 10 +#define NCI_MAX_NUM_CONN 10 + +/* NCI Status Codes */ +#define NCI_STATUS_OK 0x00 +#define NCI_STATUS_REJECTED 0x01 +#define NCI_STATUS_MESSAGE_CORRUPTED 0x02 +#define NCI_STATUS_BUFFER_FULL 0x03 +#define NCI_STATUS_FAILED 0x04 +#define NCI_STATUS_NOT_INITIALIZED 0x05 +#define NCI_STATUS_SYNTAX_ERROR 0x06 +#define NCI_STATUS_SEMANTIC_ERROR 0x07 +#define NCI_STATUS_UNKNOWN_GID 0x08 +#define NCI_STATUS_UNKNOWN_OID 0x09 +#define NCI_STATUS_INVALID_PARAM 0x0a +#define NCI_STATUS_MESSAGE_SIZE_EXCEEDED 0x0b +/* Discovery Specific Status Codes */ +#define NCI_STATUS_DISCOVERY_ALREADY_STARTED 0xa0 +#define NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED 0xa1 +/* RF Interface Specific Status Codes */ +#define NCI_STATUS_RF_TRANSMISSION_ERROR 0xb0 +#define NCI_STATUS_RF_PROTOCOL_ERROR 0xb1 +#define NCI_STATUS_RF_TIMEOUT_ERROR 0xb2 +#define NCI_STATUS_RF_LINK_LOSS_ERROR 0xb3 +/* NFCEE Interface Specific Status Codes */ +#define NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED 0xc0 +#define NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED 0xc1 +#define NCI_STATUS_NFCEE_TRANSMISSION_ERROR 0xc2 +#define NCI_STATUS_NFCEE_PROTOCOL_ERROR 0xc3 +#define NCI_STATUS_NFCEE_TIMEOUT_ERROR 0xc4 + +/* NCI RF Technology and Mode */ +#define NCI_NFC_A_PASSIVE_POLL_MODE 0x00 +#define NCI_NFC_B_PASSIVE_POLL_MODE 0x01 +#define NCI_NFC_F_PASSIVE_POLL_MODE 0x02 +#define NCI_NFC_A_ACTIVE_POLL_MODE 0x03 +#define NCI_NFC_F_ACTIVE_POLL_MODE 0x05 +#define NCI_NFC_A_PASSIVE_LISTEN_MODE 0x80 +#define NCI_NFC_B_PASSIVE_LISTEN_MODE 0x81 +#define NCI_NFC_F_PASSIVE_LISTEN_MODE 0x82 +#define NCI_NFC_A_ACTIVE_LISTEN_MODE 0x83 +#define NCI_NFC_F_ACTIVE_LISTEN_MODE 0x85 + +/* NCI RF Protocols */ +#define NCI_RF_PROTOCOL_UNKNOWN 0x00 +#define NCI_RF_PROTOCOL_T1T 0x01 +#define NCI_RF_PROTOCOL_T2T 0x02 +#define NCI_RF_PROTOCOL_T3T 0x03 +#define NCI_RF_PROTOCOL_ISO_DEP 0x04 +#define NCI_RF_PROTOCOL_NFC_DEP 0x05 + +/* NCI RF Interfaces */ +#define NCI_RF_INTERFACE_RFU 0x00 +#define NCI_RF_INTERFACE_FRAME 0x01 +#define NCI_RF_INTERFACE_ISO_DEP 0x02 +#define NCI_RF_INTERFACE_NFC_DEP 0x03 + +/* NCI RF_DISCOVER_MAP_CMD modes */ +#define NCI_DISC_MAP_MODE_POLL 0x01 +#define NCI_DISC_MAP_MODE_LISTEN 0x02 +#define NCI_DISC_MAP_MODE_BOTH 0x03 + +/* NCI Discovery Types */ +#define NCI_DISCOVERY_TYPE_POLL_A_PASSIVE 0x00 +#define NCI_DISCOVERY_TYPE_POLL_B_PASSIVE 0x01 +#define NCI_DISCOVERY_TYPE_POLL_F_PASSIVE 0x02 +#define NCI_DISCOVERY_TYPE_POLL_A_ACTIVE 0x03 +#define NCI_DISCOVERY_TYPE_POLL_F_ACTIVE 0x05 +#define NCI_DISCOVERY_TYPE_WAKEUP_A_PASSIVE 0x06 +#define NCI_DISCOVERY_TYPE_WAKEUP_B_PASSIVE 0x07 +#define NCI_DISCOVERY_TYPE_WAKEUP_A_ACTIVE 0x09 +#define NCI_DISCOVERY_TYPE_LISTEN_A_PASSIVE 0x80 +#define NCI_DISCOVERY_TYPE_LISTEN_B_PASSIVE 0x81 +#define NCI_DISCOVERY_TYPE_LISTEN_F_PASSIVE 0x82 +#define NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE 0x83 +#define NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE 0x85 + +/* NCI Deactivation Type */ +#define NCI_DEACTIVATE_TYPE_IDLE_MODE 0x00 +#define NCI_DEACTIVATE_TYPE_SLEEP_MODE 0x01 +#define NCI_DEACTIVATE_TYPE_SLEEP_AF_MODE 0x02 +#define NCI_DEACTIVATE_TYPE_RF_LINK_LOSS 0x03 +#define NCI_DEACTIVATE_TYPE_DISCOVERY_ERROR 0x04 + +/* Message Type (MT) */ +#define NCI_MT_DATA_PKT 0x00 +#define NCI_MT_CMD_PKT 0x01 +#define NCI_MT_RSP_PKT 0x02 +#define NCI_MT_NTF_PKT 0x03 + +#define nci_mt(hdr) (((hdr)[0]>>5)&0x07) +#define nci_mt_set(hdr, mt) ((hdr)[0] |= (__u8)(((mt)&0x07)<<5)) + +/* Packet Boundary Flag (PBF) */ +#define NCI_PBF_LAST 0x00 +#define NCI_PBF_CONT 0x01 + +#define nci_pbf(hdr) (__u8)(((hdr)[0]>>4)&0x01) +#define nci_pbf_set(hdr, pbf) ((hdr)[0] |= (__u8)(((pbf)&0x01)<<4)) + +/* Control Opcode manipulation */ +#define nci_opcode_pack(gid, oid) (__u16)((((__u16)((gid)&0x0f))<<8)|\ + ((__u16)((oid)&0x3f))) +#define nci_opcode(hdr) nci_opcode_pack(hdr[0], hdr[1]) +#define nci_opcode_gid(op) (__u8)(((op)&0x0f00)>>8) +#define nci_opcode_oid(op) (__u8)((op)&0x003f) + +/* Payload Length */ +#define nci_plen(hdr) (__u8)((hdr)[2]) + +/* Connection ID */ +#define nci_conn_id(hdr) (__u8)(((hdr)[0])&0x0f) + +/* GID values */ +#define NCI_GID_CORE 0x0 +#define NCI_GID_RF_MGMT 0x1 +#define NCI_GID_NFCEE_MGMT 0x2 +#define NCI_GID_PROPRIETARY 0xf + +/* ---- NCI Packet structures ---- */ +#define NCI_CTRL_HDR_SIZE 3 +#define NCI_DATA_HDR_SIZE 3 + +struct nci_ctrl_hdr { + __u8 gid; /* MT & PBF & GID */ + __u8 oid; + __u8 plen; +} __packed; + +struct nci_data_hdr { + __u8 conn_id; /* MT & PBF & ConnID */ + __u8 rfu; + __u8 plen; +} __packed; + +/* ------------------------ */ +/* ----- NCI Commands ---- */ +/* ------------------------ */ +#define NCI_OP_CORE_RESET_CMD nci_opcode_pack(NCI_GID_CORE, 0x00) + +#define NCI_OP_CORE_INIT_CMD nci_opcode_pack(NCI_GID_CORE, 0x01) + +#define NCI_OP_CORE_SET_CONFIG_CMD nci_opcode_pack(NCI_GID_CORE, 0x02) + +#define NCI_OP_CORE_CONN_CREATE_CMD nci_opcode_pack(NCI_GID_CORE, 0x04) +struct nci_core_conn_create_cmd { + __u8 target_handle; + __u8 num_target_specific_params; +} __packed; + +#define NCI_OP_CORE_CONN_CLOSE_CMD nci_opcode_pack(NCI_GID_CORE, 0x06) + +#define NCI_OP_RF_DISCOVER_MAP_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x00) +struct disc_map_config { + __u8 rf_protocol; + __u8 mode; + __u8 rf_interface_type; +} __packed; + +struct nci_rf_disc_map_cmd { + __u8 num_mapping_configs; + struct disc_map_config mapping_configs + [NCI_MAX_NUM_MAPPING_CONFIGS]; +} __packed; + +#define NCI_OP_RF_DISCOVER_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x03) +struct disc_config { + __u8 type; + __u8 frequency; +} __packed; + +struct nci_rf_disc_cmd { + __u8 num_disc_configs; + struct disc_config disc_configs[NCI_MAX_NUM_RF_CONFIGS]; +} __packed; + +#define NCI_OP_RF_DEACTIVATE_CMD nci_opcode_pack(NCI_GID_RF_MGMT, 0x06) +struct nci_rf_deactivate_cmd { + __u8 type; +} __packed; + +/* ----------------------- */ +/* ---- NCI Responses ---- */ +/* ----------------------- */ +#define NCI_OP_CORE_RESET_RSP nci_opcode_pack(NCI_GID_CORE, 0x00) +struct nci_core_reset_rsp { + __u8 status; + __u8 nci_ver; +} __packed; + +#define NCI_OP_CORE_INIT_RSP nci_opcode_pack(NCI_GID_CORE, 0x01) +struct nci_core_init_rsp_1 { + __u8 status; + __le32 nfcc_features; + __u8 num_supported_rf_interfaces; + __u8 supported_rf_interfaces[0]; /* variable size array */ + /* continuted in nci_core_init_rsp_2 */ +} __packed; + +struct nci_core_init_rsp_2 { + __u8 max_logical_connections; + __le16 max_routing_table_size; + __u8 max_control_packet_payload_length; + __le16 rf_sending_buffer_size; + __le16 rf_receiving_buffer_size; + __le16 manufacturer_id; +} __packed; + +#define NCI_OP_CORE_SET_CONFIG_RSP nci_opcode_pack(NCI_GID_CORE, 0x02) + +#define NCI_OP_CORE_CONN_CREATE_RSP nci_opcode_pack(NCI_GID_CORE, 0x04) +struct nci_core_conn_create_rsp { + __u8 status; + __u8 max_pkt_payload_size; + __u8 initial_num_credits; + __u8 conn_id; +} __packed; + +#define NCI_OP_CORE_CONN_CLOSE_RSP nci_opcode_pack(NCI_GID_CORE, 0x06) + +#define NCI_OP_RF_DISCOVER_MAP_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x00) + +#define NCI_OP_RF_DISCOVER_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x03) + +#define NCI_OP_RF_DEACTIVATE_RSP nci_opcode_pack(NCI_GID_RF_MGMT, 0x06) + +/* --------------------------- */ +/* ---- NCI Notifications ---- */ +/* --------------------------- */ +#define NCI_OP_CORE_CONN_CREDITS_NTF nci_opcode_pack(NCI_GID_CORE, 0x07) +struct conn_credit_entry { + __u8 conn_id; + __u8 credits; +} __packed; + +struct nci_core_conn_credit_ntf { + __u8 num_entries; + struct conn_credit_entry conn_entries[NCI_MAX_NUM_CONN]; +} __packed; + +#define NCI_OP_RF_FIELD_INFO_NTF nci_opcode_pack(NCI_GID_CORE, 0x08) +struct nci_rf_field_info_ntf { + __u8 rf_field_status; +} __packed; + +#define NCI_OP_RF_ACTIVATE_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x05) +struct rf_tech_specific_params_nfca_poll { + __u16 sens_res; + __u8 nfcid1_len; /* 0, 4, 7, or 10 Bytes */ + __u8 nfcid1[10]; + __u8 sel_res_len; /* 0 or 1 Bytes */ + __u8 sel_res; +} __packed; + +struct activation_params_nfca_poll_iso_dep { + __u8 rats_res_len; + __u8 rats_res[20]; +}; + +struct nci_rf_activate_ntf { + __u8 target_handle; + __u8 rf_protocol; + __u8 rf_tech_and_mode; + __u8 rf_tech_specific_params_len; + + union { + struct rf_tech_specific_params_nfca_poll nfca_poll; + } rf_tech_specific_params; + + __u8 rf_interface_type; + __u8 activation_params_len; + + union { + struct activation_params_nfca_poll_iso_dep nfca_poll_iso_dep; + } activation_params; + +} __packed; + +#define NCI_OP_RF_DEACTIVATE_NTF nci_opcode_pack(NCI_GID_RF_MGMT, 0x06) + +#endif /* __NCI_H */ diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h new file mode 100644 index 000000000000..2563f3a95e67 --- /dev/null +++ b/include/net/nfc/nci_core.h @@ -0,0 +1,183 @@ +/* + * The NFC Controller Interface is the communication protocol between an + * NFC Controller (NFCC) and a Device Host (DH). + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * Acknowledgements: + * This file is based on hci_core.h, which was written + * by Maxim Krasnyansky. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __NCI_CORE_H +#define __NCI_CORE_H + +#include +#include + +#include +#include + +/* NCI device state */ +enum { + NCI_INIT, + NCI_UP, + NCI_DISCOVERY, + NCI_POLL_ACTIVE, +}; + +/* NCI timeouts */ +#define NCI_RESET_TIMEOUT 5000 +#define NCI_INIT_TIMEOUT 5000 +#define NCI_RF_DISC_TIMEOUT 5000 +#define NCI_RF_DEACTIVATE_TIMEOUT 5000 +#define NCI_CMD_TIMEOUT 5000 + +struct nci_dev; + +struct nci_ops { + int (*open)(struct nci_dev *ndev); + int (*close)(struct nci_dev *ndev); + int (*send)(struct sk_buff *skb); +}; + +#define NCI_MAX_SUPPORTED_RF_INTERFACES 4 + +/* NCI Core structures */ +struct nci_dev { + struct nfc_dev *nfc_dev; + struct nci_ops *ops; + + int tx_headroom; + int tx_tailroom; + + unsigned long flags; + + atomic_t cmd_cnt; + atomic_t credits_cnt; + + struct timer_list cmd_timer; + + struct workqueue_struct *cmd_wq; + struct work_struct cmd_work; + + struct workqueue_struct *rx_wq; + struct work_struct rx_work; + + struct workqueue_struct *tx_wq; + struct work_struct tx_work; + + struct sk_buff_head cmd_q; + struct sk_buff_head rx_q; + struct sk_buff_head tx_q; + + struct mutex req_lock; + struct completion req_completion; + __u32 req_status; + __u32 req_result; + + void *driver_data; + + __u32 poll_prots; + __u32 target_available_prots; + __u32 target_active_prot; + + /* received during NCI_OP_CORE_RESET_RSP */ + __u8 nci_ver; + + /* received during NCI_OP_CORE_INIT_RSP */ + __u32 nfcc_features; + __u8 num_supported_rf_interfaces; + __u8 supported_rf_interfaces + [NCI_MAX_SUPPORTED_RF_INTERFACES]; + __u8 max_logical_connections; + __u16 max_routing_table_size; + __u8 max_control_packet_payload_length; + __u16 rf_sending_buffer_size; + __u16 rf_receiving_buffer_size; + __u16 manufacturer_id; + + /* received during NCI_OP_CORE_CONN_CREATE_RSP for static conn 0 */ + __u8 max_pkt_payload_size; + __u8 initial_num_credits; + __u8 conn_id; + + /* stored during nci_data_exchange */ + data_exchange_cb_t data_exchange_cb; + void *data_exchange_cb_context; + struct sk_buff *rx_data_reassembly; +}; + +/* ----- NCI Devices ----- */ +struct nci_dev *nci_allocate_device(struct nci_ops *ops, + __u32 supported_protocols, + int tx_headroom, + int tx_tailroom); +void nci_free_device(struct nci_dev *ndev); +int nci_register_device(struct nci_dev *ndev); +void nci_unregister_device(struct nci_dev *ndev); +int nci_recv_frame(struct sk_buff *skb); + +static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, + unsigned int len, + gfp_t how) +{ + struct sk_buff *skb; + + skb = alloc_skb(len + ndev->tx_headroom + ndev->tx_tailroom, how); + if (skb) + skb_reserve(skb, ndev->tx_headroom); + + return skb; +} + +static inline void nci_set_parent_dev(struct nci_dev *ndev, struct device *dev) +{ + nfc_set_parent_dev(ndev->nfc_dev, dev); +} + +static inline void nci_set_drvdata(struct nci_dev *ndev, void *data) +{ + ndev->driver_data = data; +} + +static inline void *nci_get_drvdata(struct nci_dev *ndev) +{ + return ndev->driver_data; +} + +void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb); +void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb); +void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb); +int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload); +int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); +void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, + int err); + +/* ----- NCI requests ----- */ +#define NCI_REQ_DONE 0 +#define NCI_REQ_PEND 1 +#define NCI_REQ_CANCELED 2 + +void nci_req_complete(struct nci_dev *ndev, int result); + +/* ----- NCI status code ----- */ +int nci_to_errno(__u8 code); + +#endif /* __NCI_CORE_H */ diff --git a/net/nfc/Kconfig b/net/nfc/Kconfig index 33e095b124b3..58cddadf8e8e 100644 --- a/net/nfc/Kconfig +++ b/net/nfc/Kconfig @@ -13,4 +13,6 @@ menuconfig NFC To compile this support as a module, choose M here: the module will be called nfc. +source "net/nfc/nci/Kconfig" + source "drivers/nfc/Kconfig" diff --git a/net/nfc/Makefile b/net/nfc/Makefile index 16250c353851..fbb550f2377b 100644 --- a/net/nfc/Makefile +++ b/net/nfc/Makefile @@ -3,5 +3,6 @@ # obj-$(CONFIG_NFC) += nfc.o +obj-$(CONFIG_NFC_NCI) += nci/ nfc-objs := core.o netlink.o af_nfc.o rawsock.o diff --git a/net/nfc/nci/Kconfig b/net/nfc/nci/Kconfig new file mode 100644 index 000000000000..decdc49b26d8 --- /dev/null +++ b/net/nfc/nci/Kconfig @@ -0,0 +1,10 @@ +config NFC_NCI + depends on NFC && EXPERIMENTAL + tristate "NCI protocol support (EXPERIMENTAL)" + default n + help + NCI (NFC Controller Interface) is a communication protocol between + an NFC Controller (NFCC) and a Device Host (DH). + + Say Y here to compile NCI support into the kernel or say M to + compile it as module (nci). diff --git a/net/nfc/nci/Makefile b/net/nfc/nci/Makefile new file mode 100644 index 000000000000..cdb3a2e44471 --- /dev/null +++ b/net/nfc/nci/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the Linux NFC NCI layer. +# + +obj-$(CONFIG_NFC_NCI) += nci.o + +nci-objs := core.o data.o lib.o ntf.o rsp.o \ No newline at end of file diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c new file mode 100644 index 000000000000..895e5fdf464a --- /dev/null +++ b/net/nfc/nci/core.c @@ -0,0 +1,790 @@ +/* + * The NFC Controller Interface is the communication protocol between an + * NFC Controller (NFCC) and a Device Host (DH). + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * Acknowledgements: + * This file is based on hci_core.c, which was written + * by Maxim Krasnyansky. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#include "../nfc.h" +#include +#include +#include + +static void nci_cmd_work(struct work_struct *work); +static void nci_rx_work(struct work_struct *work); +static void nci_tx_work(struct work_struct *work); + +/* ---- NCI requests ---- */ + +void nci_req_complete(struct nci_dev *ndev, int result) +{ + if (ndev->req_status == NCI_REQ_PEND) { + ndev->req_result = result; + ndev->req_status = NCI_REQ_DONE; + complete(&ndev->req_completion); + } +} + +static void nci_req_cancel(struct nci_dev *ndev, int err) +{ + if (ndev->req_status == NCI_REQ_PEND) { + ndev->req_result = err; + ndev->req_status = NCI_REQ_CANCELED; + complete(&ndev->req_completion); + } +} + +/* Execute request and wait for completion. */ +static int __nci_request(struct nci_dev *ndev, + void (*req)(struct nci_dev *ndev, unsigned long opt), + unsigned long opt, + __u32 timeout) +{ + int rc = 0; + unsigned long completion_rc; + + ndev->req_status = NCI_REQ_PEND; + + init_completion(&ndev->req_completion); + req(ndev, opt); + completion_rc = wait_for_completion_interruptible_timeout( + &ndev->req_completion, + timeout); + + nfc_dbg("wait_for_completion return %ld", completion_rc); + + if (completion_rc > 0) { + switch (ndev->req_status) { + case NCI_REQ_DONE: + rc = nci_to_errno(ndev->req_result); + break; + + case NCI_REQ_CANCELED: + rc = -ndev->req_result; + break; + + default: + rc = -ETIMEDOUT; + break; + } + } else { + nfc_err("wait_for_completion_interruptible_timeout failed %ld", + completion_rc); + + rc = ((completion_rc == 0) ? (-ETIMEDOUT) : (completion_rc)); + } + + ndev->req_status = ndev->req_result = 0; + + return rc; +} + +static inline int nci_request(struct nci_dev *ndev, + void (*req)(struct nci_dev *ndev, unsigned long opt), + unsigned long opt, __u32 timeout) +{ + int rc; + + if (!test_bit(NCI_UP, &ndev->flags)) + return -ENETDOWN; + + /* Serialize all requests */ + mutex_lock(&ndev->req_lock); + rc = __nci_request(ndev, req, opt, timeout); + mutex_unlock(&ndev->req_lock); + + return rc; +} + +static void nci_reset_req(struct nci_dev *ndev, unsigned long opt) +{ + nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 0, NULL); +} + +static void nci_init_req(struct nci_dev *ndev, unsigned long opt) +{ + nci_send_cmd(ndev, NCI_OP_CORE_INIT_CMD, 0, NULL); +} + +static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt) +{ + struct nci_rf_disc_map_cmd cmd; + struct nci_core_conn_create_cmd conn_cmd; + int i; + + /* create static rf connection */ + conn_cmd.target_handle = 0; + conn_cmd.num_target_specific_params = 0; + nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd); + + /* set rf mapping configurations */ + cmd.num_mapping_configs = 0; + + /* by default mapping is set to NCI_RF_INTERFACE_FRAME */ + for (i = 0; i < ndev->num_supported_rf_interfaces; i++) { + if (ndev->supported_rf_interfaces[i] == + NCI_RF_INTERFACE_ISO_DEP) { + cmd.mapping_configs[cmd.num_mapping_configs] + .rf_protocol = NCI_RF_PROTOCOL_ISO_DEP; + cmd.mapping_configs[cmd.num_mapping_configs] + .mode = NCI_DISC_MAP_MODE_BOTH; + cmd.mapping_configs[cmd.num_mapping_configs] + .rf_interface_type = NCI_RF_INTERFACE_ISO_DEP; + cmd.num_mapping_configs++; + } else if (ndev->supported_rf_interfaces[i] == + NCI_RF_INTERFACE_NFC_DEP) { + cmd.mapping_configs[cmd.num_mapping_configs] + .rf_protocol = NCI_RF_PROTOCOL_NFC_DEP; + cmd.mapping_configs[cmd.num_mapping_configs] + .mode = NCI_DISC_MAP_MODE_BOTH; + cmd.mapping_configs[cmd.num_mapping_configs] + .rf_interface_type = NCI_RF_INTERFACE_NFC_DEP; + cmd.num_mapping_configs++; + } + + if (cmd.num_mapping_configs == NCI_MAX_NUM_MAPPING_CONFIGS) + break; + } + + nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_MAP_CMD, + (1 + (cmd.num_mapping_configs*sizeof(struct disc_map_config))), + &cmd); +} + +static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) +{ + struct nci_rf_disc_cmd cmd; + __u32 protocols = opt; + + cmd.num_disc_configs = 0; + + if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && + (protocols & NFC_PROTO_JEWEL_MASK + || protocols & NFC_PROTO_MIFARE_MASK + || protocols & NFC_PROTO_ISO14443_MASK + || protocols & NFC_PROTO_NFC_DEP_MASK)) { + cmd.disc_configs[cmd.num_disc_configs].type = + NCI_DISCOVERY_TYPE_POLL_A_PASSIVE; + cmd.disc_configs[cmd.num_disc_configs].frequency = 1; + cmd.num_disc_configs++; + } + + if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && + (protocols & NFC_PROTO_ISO14443_MASK)) { + cmd.disc_configs[cmd.num_disc_configs].type = + NCI_DISCOVERY_TYPE_POLL_B_PASSIVE; + cmd.disc_configs[cmd.num_disc_configs].frequency = 1; + cmd.num_disc_configs++; + } + + if ((cmd.num_disc_configs < NCI_MAX_NUM_RF_CONFIGS) && + (protocols & NFC_PROTO_FELICA_MASK + || protocols & NFC_PROTO_NFC_DEP_MASK)) { + cmd.disc_configs[cmd.num_disc_configs].type = + NCI_DISCOVERY_TYPE_POLL_F_PASSIVE; + cmd.disc_configs[cmd.num_disc_configs].frequency = 1; + cmd.num_disc_configs++; + } + + nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_CMD, + (1 + (cmd.num_disc_configs*sizeof(struct disc_config))), + &cmd); +} + +static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt) +{ + struct nci_rf_deactivate_cmd cmd; + + cmd.type = NCI_DEACTIVATE_TYPE_IDLE_MODE; + + nci_send_cmd(ndev, NCI_OP_RF_DEACTIVATE_CMD, + sizeof(struct nci_rf_deactivate_cmd), + &cmd); +} + +static int nci_open_device(struct nci_dev *ndev) +{ + int rc = 0; + + mutex_lock(&ndev->req_lock); + + if (test_bit(NCI_UP, &ndev->flags)) { + rc = -EALREADY; + goto done; + } + + if (ndev->ops->open(ndev)) { + rc = -EIO; + goto done; + } + + atomic_set(&ndev->cmd_cnt, 1); + + set_bit(NCI_INIT, &ndev->flags); + + rc = __nci_request(ndev, nci_reset_req, 0, + msecs_to_jiffies(NCI_RESET_TIMEOUT)); + + if (!rc) { + rc = __nci_request(ndev, nci_init_req, 0, + msecs_to_jiffies(NCI_INIT_TIMEOUT)); + } + + if (!rc) { + rc = __nci_request(ndev, nci_init_complete_req, 0, + msecs_to_jiffies(NCI_INIT_TIMEOUT)); + } + + clear_bit(NCI_INIT, &ndev->flags); + + if (!rc) { + set_bit(NCI_UP, &ndev->flags); + } else { + /* Init failed, cleanup */ + skb_queue_purge(&ndev->cmd_q); + skb_queue_purge(&ndev->rx_q); + skb_queue_purge(&ndev->tx_q); + + ndev->ops->close(ndev); + ndev->flags = 0; + } + +done: + mutex_unlock(&ndev->req_lock); + return rc; +} + +static int nci_close_device(struct nci_dev *ndev) +{ + nci_req_cancel(ndev, ENODEV); + mutex_lock(&ndev->req_lock); + + if (!test_and_clear_bit(NCI_UP, &ndev->flags)) { + del_timer_sync(&ndev->cmd_timer); + mutex_unlock(&ndev->req_lock); + return 0; + } + + /* Drop RX and TX queues */ + skb_queue_purge(&ndev->rx_q); + skb_queue_purge(&ndev->tx_q); + + /* Flush RX and TX wq */ + flush_workqueue(ndev->rx_wq); + flush_workqueue(ndev->tx_wq); + + /* Reset device */ + skb_queue_purge(&ndev->cmd_q); + atomic_set(&ndev->cmd_cnt, 1); + + set_bit(NCI_INIT, &ndev->flags); + __nci_request(ndev, nci_reset_req, 0, + msecs_to_jiffies(NCI_RESET_TIMEOUT)); + clear_bit(NCI_INIT, &ndev->flags); + + /* Flush cmd wq */ + flush_workqueue(ndev->cmd_wq); + + /* After this point our queues are empty + * and no works are scheduled. */ + ndev->ops->close(ndev); + + /* Clear flags */ + ndev->flags = 0; + + mutex_unlock(&ndev->req_lock); + + return 0; +} + +/* NCI command timer function */ +static void nci_cmd_timer(unsigned long arg) +{ + struct nci_dev *ndev = (void *) arg; + + nfc_dbg("entry"); + + atomic_set(&ndev->cmd_cnt, 1); + queue_work(ndev->cmd_wq, &ndev->cmd_work); +} + +static int nci_dev_up(struct nfc_dev *nfc_dev) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + + nfc_dbg("entry"); + + return nci_open_device(ndev); +} + +static int nci_dev_down(struct nfc_dev *nfc_dev) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + + nfc_dbg("entry"); + + return nci_close_device(ndev); +} + +static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + int rc; + + nfc_dbg("entry"); + + if (test_bit(NCI_DISCOVERY, &ndev->flags)) { + nfc_err("unable to start poll, since poll is already active"); + return -EBUSY; + } + + if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) { + nfc_dbg("target already active, first deactivate..."); + + rc = nci_request(ndev, nci_rf_deactivate_req, 0, + msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); + if (rc) + return -EBUSY; + } + + rc = nci_request(ndev, nci_rf_discover_req, protocols, + msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); + + if (!rc) + ndev->poll_prots = protocols; + + return rc; +} + +static void nci_stop_poll(struct nfc_dev *nfc_dev) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + + nfc_dbg("entry"); + + if (!test_bit(NCI_DISCOVERY, &ndev->flags)) { + nfc_err("unable to stop poll, since poll is not active"); + return; + } + + nci_request(ndev, nci_rf_deactivate_req, 0, + msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); +} + +static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx, + __u32 protocol) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + + nfc_dbg("entry, target_idx %d, protocol 0x%x", target_idx, protocol); + + if (!test_bit(NCI_POLL_ACTIVE, &ndev->flags)) { + nfc_err("there is no available target to activate"); + return -EINVAL; + } + + if (ndev->target_active_prot) { + nfc_err("there is already an active target"); + return -EBUSY; + } + + if (!(ndev->target_available_prots & (1 << protocol))) { + nfc_err("target does not support the requested protocol 0x%x", + protocol); + return -EINVAL; + } + + ndev->target_active_prot = protocol; + ndev->target_available_prots = 0; + + return 0; +} + +static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + + nfc_dbg("entry, target_idx %d", target_idx); + + if (!ndev->target_active_prot) { + nfc_err("unable to deactivate target, no active target"); + return; + } + + ndev->target_active_prot = 0; + + if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) { + nci_request(ndev, nci_rf_deactivate_req, 0, + msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT)); + } +} + +static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, + struct sk_buff *skb, + data_exchange_cb_t cb, + void *cb_context) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + + nfc_dbg("entry, target_idx %d, len %d", target_idx, skb->len); + + if (!ndev->target_active_prot) { + nfc_err("unable to exchange data, no active target"); + return -EINVAL; + } + + /* store cb and context to be used on receiving data */ + ndev->data_exchange_cb = cb; + ndev->data_exchange_cb_context = cb_context; + + return nci_send_data(ndev, ndev->conn_id, skb); +} + +static struct nfc_ops nci_nfc_ops = { + .dev_up = nci_dev_up, + .dev_down = nci_dev_down, + .start_poll = nci_start_poll, + .stop_poll = nci_stop_poll, + .activate_target = nci_activate_target, + .deactivate_target = nci_deactivate_target, + .data_exchange = nci_data_exchange, +}; + +/* ---- Interface to NCI drivers ---- */ + +/** + * nci_allocate_device - allocate a new nci device + * + * @ops: device operations + * @supported_protocols: NFC protocols supported by the device + */ +struct nci_dev *nci_allocate_device(struct nci_ops *ops, + __u32 supported_protocols, + int tx_headroom, + int tx_tailroom) +{ + struct nci_dev *ndev = NULL; + + nfc_dbg("entry, supported_protocols 0x%x", supported_protocols); + + if (!ops->open || !ops->close || !ops->send) + goto exit; + + if (!supported_protocols) + goto exit; + + ndev = kzalloc(sizeof(struct nci_dev), GFP_KERNEL); + if (!ndev) + goto exit; + + ndev->ops = ops; + ndev->tx_headroom = tx_headroom; + ndev->tx_tailroom = tx_tailroom; + + ndev->nfc_dev = nfc_allocate_device(&nci_nfc_ops, + supported_protocols, + tx_headroom + NCI_DATA_HDR_SIZE, + tx_tailroom); + if (!ndev->nfc_dev) + goto free_exit; + + nfc_set_drvdata(ndev->nfc_dev, ndev); + + goto exit; + +free_exit: + kfree(ndev); + +exit: + return ndev; +} +EXPORT_SYMBOL(nci_allocate_device); + +/** + * nci_free_device - deallocate nci device + * + * @ndev: The nci device to deallocate + */ +void nci_free_device(struct nci_dev *ndev) +{ + nfc_dbg("entry"); + + nfc_free_device(ndev->nfc_dev); + kfree(ndev); +} +EXPORT_SYMBOL(nci_free_device); + +/** + * nci_register_device - register a nci device in the nfc subsystem + * + * @dev: The nci device to register + */ +int nci_register_device(struct nci_dev *ndev) +{ + int rc; + struct device *dev = &ndev->nfc_dev->dev; + char name[32]; + + nfc_dbg("entry"); + + rc = nfc_register_device(ndev->nfc_dev); + if (rc) + goto exit; + + ndev->flags = 0; + + INIT_WORK(&ndev->cmd_work, nci_cmd_work); + snprintf(name, sizeof(name), "%s_nci_cmd_wq", dev_name(dev)); + ndev->cmd_wq = create_singlethread_workqueue(name); + if (!ndev->cmd_wq) { + rc = -ENOMEM; + goto unreg_exit; + } + + INIT_WORK(&ndev->rx_work, nci_rx_work); + snprintf(name, sizeof(name), "%s_nci_rx_wq", dev_name(dev)); + ndev->rx_wq = create_singlethread_workqueue(name); + if (!ndev->rx_wq) { + rc = -ENOMEM; + goto destroy_cmd_wq_exit; + } + + INIT_WORK(&ndev->tx_work, nci_tx_work); + snprintf(name, sizeof(name), "%s_nci_tx_wq", dev_name(dev)); + ndev->tx_wq = create_singlethread_workqueue(name); + if (!ndev->tx_wq) { + rc = -ENOMEM; + goto destroy_rx_wq_exit; + } + + skb_queue_head_init(&ndev->cmd_q); + skb_queue_head_init(&ndev->rx_q); + skb_queue_head_init(&ndev->tx_q); + + setup_timer(&ndev->cmd_timer, nci_cmd_timer, + (unsigned long) ndev); + + mutex_init(&ndev->req_lock); + + goto exit; + +destroy_rx_wq_exit: + destroy_workqueue(ndev->rx_wq); + +destroy_cmd_wq_exit: + destroy_workqueue(ndev->cmd_wq); + +unreg_exit: + nfc_unregister_device(ndev->nfc_dev); + +exit: + return rc; +} +EXPORT_SYMBOL(nci_register_device); + +/** + * nci_unregister_device - unregister a nci device in the nfc subsystem + * + * @dev: The nci device to unregister + */ +void nci_unregister_device(struct nci_dev *ndev) +{ + nfc_dbg("entry"); + + nci_close_device(ndev); + + destroy_workqueue(ndev->cmd_wq); + destroy_workqueue(ndev->rx_wq); + destroy_workqueue(ndev->tx_wq); + + nfc_unregister_device(ndev->nfc_dev); +} +EXPORT_SYMBOL(nci_unregister_device); + +/** + * nci_recv_frame - receive frame from NCI drivers + * + * @skb: The sk_buff to receive + */ +int nci_recv_frame(struct sk_buff *skb) +{ + struct nci_dev *ndev = (struct nci_dev *) skb->dev; + + nfc_dbg("entry, len %d", skb->len); + + if (!ndev || (!test_bit(NCI_UP, &ndev->flags) + && !test_bit(NCI_INIT, &ndev->flags))) { + kfree_skb(skb); + return -ENXIO; + } + + /* Queue frame for rx worker thread */ + skb_queue_tail(&ndev->rx_q, skb); + queue_work(ndev->rx_wq, &ndev->rx_work); + + return 0; +} +EXPORT_SYMBOL(nci_recv_frame); + +static int nci_send_frame(struct sk_buff *skb) +{ + struct nci_dev *ndev = (struct nci_dev *) skb->dev; + + nfc_dbg("entry, len %d", skb->len); + + if (!ndev) { + kfree_skb(skb); + return -ENODEV; + } + + /* Get rid of skb owner, prior to sending to the driver. */ + skb_orphan(skb); + + return ndev->ops->send(skb); +} + +/* Send NCI command */ +int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload) +{ + struct nci_ctrl_hdr *hdr; + struct sk_buff *skb; + + nfc_dbg("entry, opcode 0x%x, plen %d", opcode, plen); + + skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL); + if (!skb) { + nfc_err("no memory for command"); + return -ENOMEM; + } + + hdr = (struct nci_ctrl_hdr *) skb_put(skb, NCI_CTRL_HDR_SIZE); + hdr->gid = nci_opcode_gid(opcode); + hdr->oid = nci_opcode_oid(opcode); + hdr->plen = plen; + + nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT); + nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST); + + if (plen) + memcpy(skb_put(skb, plen), payload, plen); + + skb->dev = (void *) ndev; + + skb_queue_tail(&ndev->cmd_q, skb); + queue_work(ndev->cmd_wq, &ndev->cmd_work); + + return 0; +} + +/* ---- NCI TX Data worker thread ---- */ + +static void nci_tx_work(struct work_struct *work) +{ + struct nci_dev *ndev = container_of(work, struct nci_dev, tx_work); + struct sk_buff *skb; + + nfc_dbg("entry, credits_cnt %d", atomic_read(&ndev->credits_cnt)); + + /* Send queued tx data */ + while (atomic_read(&ndev->credits_cnt)) { + skb = skb_dequeue(&ndev->tx_q); + if (!skb) + return; + + atomic_dec(&ndev->credits_cnt); + + nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d", + nci_pbf(skb->data), + nci_conn_id(skb->data), + nci_plen(skb->data)); + + nci_send_frame(skb); + } +} + +/* ----- NCI RX worker thread (data & control) ----- */ + +static void nci_rx_work(struct work_struct *work) +{ + struct nci_dev *ndev = container_of(work, struct nci_dev, rx_work); + struct sk_buff *skb; + + while ((skb = skb_dequeue(&ndev->rx_q))) { + /* Process frame */ + switch (nci_mt(skb->data)) { + case NCI_MT_RSP_PKT: + nci_rsp_packet(ndev, skb); + break; + + case NCI_MT_NTF_PKT: + nci_ntf_packet(ndev, skb); + break; + + case NCI_MT_DATA_PKT: + nci_rx_data_packet(ndev, skb); + break; + + default: + nfc_err("unknown MT 0x%x", nci_mt(skb->data)); + kfree_skb(skb); + break; + } + } +} + +/* ----- NCI TX CMD worker thread ----- */ + +static void nci_cmd_work(struct work_struct *work) +{ + struct nci_dev *ndev = container_of(work, struct nci_dev, cmd_work); + struct sk_buff *skb; + + nfc_dbg("entry, cmd_cnt %d", atomic_read(&ndev->cmd_cnt)); + + /* Send queued command */ + if (atomic_read(&ndev->cmd_cnt)) { + skb = skb_dequeue(&ndev->cmd_q); + if (!skb) + return; + + atomic_dec(&ndev->cmd_cnt); + + nfc_dbg("NCI TX: MT=cmd, PBF=%d, GID=0x%x, OID=0x%x, plen=%d", + nci_pbf(skb->data), + nci_opcode_gid(nci_opcode(skb->data)), + nci_opcode_oid(nci_opcode(skb->data)), + nci_plen(skb->data)); + + nci_send_frame(skb); + + mod_timer(&ndev->cmd_timer, + jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT)); + } +} diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c new file mode 100644 index 000000000000..141790ada4aa --- /dev/null +++ b/net/nfc/nci/data.c @@ -0,0 +1,245 @@ +/* + * The NFC Controller Interface is the communication protocol between an + * NFC Controller (NFCC) and a Device Host (DH). + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include + +#include "../nfc.h" +#include +#include +#include + +/* Complete data exchange transaction and forward skb to nfc core */ +void nci_data_exchange_complete(struct nci_dev *ndev, + struct sk_buff *skb, + int err) +{ + data_exchange_cb_t cb = ndev->data_exchange_cb; + void *cb_context = ndev->data_exchange_cb_context; + + nfc_dbg("entry, len %d, err %d", ((skb) ? (skb->len) : (0)), err); + + if (cb) { + ndev->data_exchange_cb = NULL; + ndev->data_exchange_cb_context = 0; + + /* forward skb to nfc core */ + cb(cb_context, skb, err); + } else if (skb) { + nfc_err("no rx callback, dropping rx data..."); + + /* no waiting callback, free skb */ + kfree_skb(skb); + } +} + +/* ----------------- NCI TX Data ----------------- */ + +static inline void nci_push_data_hdr(struct nci_dev *ndev, + __u8 conn_id, + struct sk_buff *skb, + __u8 pbf) +{ + struct nci_data_hdr *hdr; + int plen = skb->len; + + hdr = (struct nci_data_hdr *) skb_push(skb, NCI_DATA_HDR_SIZE); + hdr->conn_id = conn_id; + hdr->rfu = 0; + hdr->plen = plen; + + nci_mt_set((__u8 *)hdr, NCI_MT_DATA_PKT); + nci_pbf_set((__u8 *)hdr, pbf); + + skb->dev = (void *) ndev; +} + +static int nci_queue_tx_data_frags(struct nci_dev *ndev, + __u8 conn_id, + struct sk_buff *skb) { + int total_len = skb->len; + unsigned char *data = skb->data; + unsigned long flags; + struct sk_buff_head frags_q; + struct sk_buff *skb_frag; + int frag_len; + int rc = 0; + + nfc_dbg("entry, conn_id 0x%x, total_len %d", conn_id, total_len); + + __skb_queue_head_init(&frags_q); + + while (total_len) { + frag_len = min_t(int, total_len, ndev->max_pkt_payload_size); + + skb_frag = nci_skb_alloc(ndev, + (NCI_DATA_HDR_SIZE + frag_len), + GFP_KERNEL); + if (skb_frag == NULL) { + rc = -ENOMEM; + goto free_exit; + } + skb_reserve(skb_frag, NCI_DATA_HDR_SIZE); + + /* first, copy the data */ + memcpy(skb_put(skb_frag, frag_len), data, frag_len); + + /* second, set the header */ + nci_push_data_hdr(ndev, conn_id, skb_frag, + ((total_len == frag_len) ? (NCI_PBF_LAST) : (NCI_PBF_CONT))); + + __skb_queue_tail(&frags_q, skb_frag); + + data += frag_len; + total_len -= frag_len; + + nfc_dbg("frag_len %d, remaining total_len %d", + frag_len, total_len); + } + + /* queue all fragments atomically */ + spin_lock_irqsave(&ndev->tx_q.lock, flags); + + while ((skb_frag = __skb_dequeue(&frags_q)) != NULL) + __skb_queue_tail(&ndev->tx_q, skb_frag); + + spin_unlock_irqrestore(&ndev->tx_q.lock, flags); + + /* free the original skb */ + kfree_skb(skb); + + goto exit; + +free_exit: + while ((skb_frag = __skb_dequeue(&frags_q)) != NULL) + kfree_skb(skb_frag); + +exit: + return rc; +} + +/* Send NCI data */ +int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb) +{ + int rc = 0; + + nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len); + + /* check if the packet need to be fragmented */ + if (skb->len <= ndev->max_pkt_payload_size) { + /* no need to fragment packet */ + nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST); + + skb_queue_tail(&ndev->tx_q, skb); + } else { + /* fragment packet and queue the fragments */ + rc = nci_queue_tx_data_frags(ndev, conn_id, skb); + if (rc) { + nfc_err("failed to fragment tx data packet"); + goto free_exit; + } + } + + queue_work(ndev->tx_wq, &ndev->tx_work); + + goto exit; + +free_exit: + kfree_skb(skb); + +exit: + return rc; +} + +/* ----------------- NCI RX Data ----------------- */ + +static void nci_add_rx_data_frag(struct nci_dev *ndev, + struct sk_buff *skb, + __u8 pbf) +{ + int reassembly_len; + int err = 0; + + if (ndev->rx_data_reassembly) { + reassembly_len = ndev->rx_data_reassembly->len; + + /* first, make enough room for the already accumulated data */ + if (skb_cow_head(skb, reassembly_len)) { + nfc_err("error adding room for accumulated rx data"); + + kfree_skb(skb); + skb = 0; + + kfree_skb(ndev->rx_data_reassembly); + ndev->rx_data_reassembly = 0; + + err = -ENOMEM; + goto exit; + } + + /* second, combine the two fragments */ + memcpy(skb_push(skb, reassembly_len), + ndev->rx_data_reassembly->data, + reassembly_len); + + /* third, free old reassembly */ + kfree_skb(ndev->rx_data_reassembly); + ndev->rx_data_reassembly = 0; + } + + if (pbf == NCI_PBF_CONT) { + /* need to wait for next fragment, store skb and exit */ + ndev->rx_data_reassembly = skb; + return; + } + +exit: + nci_data_exchange_complete(ndev, skb, err); +} + +/* Rx Data packet */ +void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) +{ + __u8 pbf = nci_pbf(skb->data); + + nfc_dbg("entry, len %d", skb->len); + + nfc_dbg("NCI RX: MT=data, PBF=%d, conn_id=%d, plen=%d", + nci_pbf(skb->data), + nci_conn_id(skb->data), + nci_plen(skb->data)); + + /* strip the nci data header */ + skb_pull(skb, NCI_DATA_HDR_SIZE); + + if (ndev->target_active_prot == NFC_PROTO_MIFARE) { + /* frame I/F => remove the status byte */ + nfc_dbg("NFC_PROTO_MIFARE => remove the status byte"); + skb_trim(skb, (skb->len - 1)); + } + + nci_add_rx_data_frag(ndev, skb, pbf); +} diff --git a/net/nfc/nci/lib.c b/net/nfc/nci/lib.c new file mode 100644 index 000000000000..b19dc2fa90e1 --- /dev/null +++ b/net/nfc/nci/lib.c @@ -0,0 +1,94 @@ +/* + * The NFC Controller Interface is the communication protocol between an + * NFC Controller (NFCC) and a Device Host (DH). + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * Acknowledgements: + * This file is based on lib.c, which was written + * by Maxim Krasnyansky. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +#include + +/* NCI status codes to Unix errno mapping */ +int nci_to_errno(__u8 code) +{ + switch (code) { + case NCI_STATUS_OK: + return 0; + + case NCI_STATUS_REJECTED: + return -EBUSY; + + case NCI_STATUS_MESSAGE_CORRUPTED: + return -EBADMSG; + + case NCI_STATUS_BUFFER_FULL: + return -ENOBUFS; + + case NCI_STATUS_NOT_INITIALIZED: + return -EHOSTDOWN; + + case NCI_STATUS_SYNTAX_ERROR: + case NCI_STATUS_SEMANTIC_ERROR: + case NCI_STATUS_INVALID_PARAM: + case NCI_STATUS_RF_PROTOCOL_ERROR: + case NCI_STATUS_NFCEE_PROTOCOL_ERROR: + return -EPROTO; + + case NCI_STATUS_UNKNOWN_GID: + case NCI_STATUS_UNKNOWN_OID: + return -EBADRQC; + + case NCI_STATUS_MESSAGE_SIZE_EXCEEDED: + return -EMSGSIZE; + + case NCI_STATUS_DISCOVERY_ALREADY_STARTED: + return -EALREADY; + + case NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED: + case NCI_STATUS_NFCEE_INTERFACE_ACTIVATION_FAILED: + return -ECONNREFUSED; + + case NCI_STATUS_RF_TRANSMISSION_ERROR: + case NCI_STATUS_NFCEE_TRANSMISSION_ERROR: + return -ECOMM; + + case NCI_STATUS_RF_TIMEOUT_ERROR: + case NCI_STATUS_NFCEE_TIMEOUT_ERROR: + return -ETIMEDOUT; + + case NCI_STATUS_RF_LINK_LOSS_ERROR: + return -ENOLINK; + + case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED: + return -EDQUOT; + + case NCI_STATUS_FAILED: + default: + return -ENOSYS; + } +} +EXPORT_SYMBOL(nci_to_errno); diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c new file mode 100644 index 000000000000..8dd75352ab6c --- /dev/null +++ b/net/nfc/nci/ntf.c @@ -0,0 +1,258 @@ +/* + * The NFC Controller Interface is the communication protocol between an + * NFC Controller (NFCC) and a Device Host (DH). + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * Acknowledgements: + * This file is based on hci_event.c, which was written + * by Maxim Krasnyansky. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +#include "../nfc.h" +#include +#include +#include + +/* Handle NCI Notification packets */ + +static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + struct nci_core_conn_credit_ntf *ntf = (void *) skb->data; + int i; + + nfc_dbg("entry, num_entries %d", ntf->num_entries); + + if (ntf->num_entries > NCI_MAX_NUM_CONN) + ntf->num_entries = NCI_MAX_NUM_CONN; + + /* update the credits */ + for (i = 0; i < ntf->num_entries; i++) { + nfc_dbg("entry[%d]: conn_id %d, credits %d", i, + ntf->conn_entries[i].conn_id, + ntf->conn_entries[i].credits); + + if (ntf->conn_entries[i].conn_id == ndev->conn_id) { + /* found static rf connection */ + atomic_add(ntf->conn_entries[i].credits, + &ndev->credits_cnt); + } + } + + /* trigger the next tx */ + if (!skb_queue_empty(&ndev->tx_q)) + queue_work(ndev->tx_wq, &ndev->tx_work); +} + +static void nci_rf_field_info_ntf_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + struct nci_rf_field_info_ntf *ntf = (void *) skb->data; + + nfc_dbg("entry, rf_field_status %d", ntf->rf_field_status); +} + +static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, + struct nci_rf_activate_ntf *ntf, __u8 *data) +{ + struct rf_tech_specific_params_nfca_poll *nfca_poll; + struct activation_params_nfca_poll_iso_dep *nfca_poll_iso_dep; + + nfca_poll = &ntf->rf_tech_specific_params.nfca_poll; + nfca_poll_iso_dep = &ntf->activation_params.nfca_poll_iso_dep; + + nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); + data += 2; + + nfca_poll->nfcid1_len = *data++; + + nfc_dbg("sens_res 0x%x, nfcid1_len %d", + nfca_poll->sens_res, + nfca_poll->nfcid1_len); + + memcpy(nfca_poll->nfcid1, data, nfca_poll->nfcid1_len); + data += nfca_poll->nfcid1_len; + + nfca_poll->sel_res_len = *data++; + + if (nfca_poll->sel_res_len != 0) + nfca_poll->sel_res = *data++; + + ntf->rf_interface_type = *data++; + ntf->activation_params_len = *data++; + + nfc_dbg("sel_res_len %d, sel_res 0x%x, rf_interface_type %d, activation_params_len %d", + nfca_poll->sel_res_len, + nfca_poll->sel_res, + ntf->rf_interface_type, + ntf->activation_params_len); + + switch (ntf->rf_interface_type) { + case NCI_RF_INTERFACE_ISO_DEP: + nfca_poll_iso_dep->rats_res_len = *data++; + if (nfca_poll_iso_dep->rats_res_len > 0) { + memcpy(nfca_poll_iso_dep->rats_res, + data, + nfca_poll_iso_dep->rats_res_len); + } + break; + + case NCI_RF_INTERFACE_FRAME: + /* no activation params */ + break; + + default: + nfc_err("unsupported rf_interface_type 0x%x", + ntf->rf_interface_type); + return -EPROTO; + } + + return 0; +} + +static void nci_target_found(struct nci_dev *ndev, + struct nci_rf_activate_ntf *ntf) +{ + struct nfc_target nfc_tgt; + + if (ntf->rf_protocol == NCI_RF_PROTOCOL_T2T) /* T2T MifareUL */ + nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; + else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */ + nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; + + nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res; + nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res; + + if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) { + nfc_dbg("the target found does not have the desired protocol"); + return; + } + + nfc_dbg("new target found, supported_protocols 0x%x", + nfc_tgt.supported_protocols); + + ndev->target_available_prots = nfc_tgt.supported_protocols; + + nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1); +} + +static void nci_rf_activate_ntf_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + struct nci_rf_activate_ntf ntf; + __u8 *data = skb->data; + int rc = -1; + + clear_bit(NCI_DISCOVERY, &ndev->flags); + set_bit(NCI_POLL_ACTIVE, &ndev->flags); + + ntf.target_handle = *data++; + ntf.rf_protocol = *data++; + ntf.rf_tech_and_mode = *data++; + ntf.rf_tech_specific_params_len = *data++; + + nfc_dbg("target_handle %d, rf_protocol 0x%x, rf_tech_and_mode 0x%x, rf_tech_specific_params_len %d", + ntf.target_handle, + ntf.rf_protocol, + ntf.rf_tech_and_mode, + ntf.rf_tech_specific_params_len); + + switch (ntf.rf_tech_and_mode) { + case NCI_NFC_A_PASSIVE_POLL_MODE: + rc = nci_rf_activate_nfca_passive_poll(ndev, &ntf, + data); + break; + + default: + nfc_err("unsupported rf_tech_and_mode 0x%x", + ntf.rf_tech_and_mode); + return; + } + + if (!rc) + nci_target_found(ndev, &ntf); +} + +static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + __u8 type = skb->data[0]; + + nfc_dbg("entry, type 0x%x", type); + + clear_bit(NCI_POLL_ACTIVE, &ndev->flags); + ndev->target_active_prot = 0; + + /* drop tx data queue */ + skb_queue_purge(&ndev->tx_q); + + /* drop partial rx data packet */ + if (ndev->rx_data_reassembly) { + kfree_skb(ndev->rx_data_reassembly); + ndev->rx_data_reassembly = 0; + } + + /* complete the data exchange transaction, if exists */ + if (ndev->data_exchange_cb) + nci_data_exchange_complete(ndev, NULL, -EIO); +} + +void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb) +{ + __u16 ntf_opcode = nci_opcode(skb->data); + + nfc_dbg("NCI RX: MT=ntf, PBF=%d, GID=0x%x, OID=0x%x, plen=%d", + nci_pbf(skb->data), + nci_opcode_gid(ntf_opcode), + nci_opcode_oid(ntf_opcode), + nci_plen(skb->data)); + + /* strip the nci control header */ + skb_pull(skb, NCI_CTRL_HDR_SIZE); + + switch (ntf_opcode) { + case NCI_OP_CORE_CONN_CREDITS_NTF: + nci_core_conn_credits_ntf_packet(ndev, skb); + break; + + case NCI_OP_RF_FIELD_INFO_NTF: + nci_rf_field_info_ntf_packet(ndev, skb); + break; + + case NCI_OP_RF_ACTIVATE_NTF: + nci_rf_activate_ntf_packet(ndev, skb); + break; + + case NCI_OP_RF_DEACTIVATE_NTF: + nci_rf_deactivate_ntf_packet(ndev, skb); + break; + + default: + nfc_err("unknown ntf opcode 0x%x", ntf_opcode); + break; + } + + kfree_skb(skb); +} diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c new file mode 100644 index 000000000000..0403d4cd0917 --- /dev/null +++ b/net/nfc/nci/rsp.c @@ -0,0 +1,226 @@ +/* + * The NFC Controller Interface is the communication protocol between an + * NFC Controller (NFCC) and a Device Host (DH). + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * Acknowledgements: + * This file is based on hci_event.c, which was written + * by Maxim Krasnyansky. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +#include "../nfc.h" +#include +#include + +/* Handle NCI Response packets */ + +static void nci_core_reset_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) +{ + struct nci_core_reset_rsp *rsp = (void *) skb->data; + + nfc_dbg("entry, status 0x%x", rsp->status); + + if (rsp->status == NCI_STATUS_OK) + ndev->nci_ver = rsp->nci_ver; + + nfc_dbg("nci_ver 0x%x", ndev->nci_ver); + + nci_req_complete(ndev, rsp->status); +} + +static void nci_core_init_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) +{ + struct nci_core_init_rsp_1 *rsp_1 = (void *) skb->data; + struct nci_core_init_rsp_2 *rsp_2; + + nfc_dbg("entry, status 0x%x", rsp_1->status); + + if (rsp_1->status != NCI_STATUS_OK) + return; + + ndev->nfcc_features = __le32_to_cpu(rsp_1->nfcc_features); + ndev->num_supported_rf_interfaces = rsp_1->num_supported_rf_interfaces; + + if (ndev->num_supported_rf_interfaces > + NCI_MAX_SUPPORTED_RF_INTERFACES) { + ndev->num_supported_rf_interfaces = + NCI_MAX_SUPPORTED_RF_INTERFACES; + } + + memcpy(ndev->supported_rf_interfaces, + rsp_1->supported_rf_interfaces, + ndev->num_supported_rf_interfaces); + + rsp_2 = (void *) (skb->data + 6 + ndev->num_supported_rf_interfaces); + + ndev->max_logical_connections = + rsp_2->max_logical_connections; + ndev->max_routing_table_size = + __le16_to_cpu(rsp_2->max_routing_table_size); + ndev->max_control_packet_payload_length = + rsp_2->max_control_packet_payload_length; + ndev->rf_sending_buffer_size = + __le16_to_cpu(rsp_2->rf_sending_buffer_size); + ndev->rf_receiving_buffer_size = + __le16_to_cpu(rsp_2->rf_receiving_buffer_size); + ndev->manufacturer_id = + __le16_to_cpu(rsp_2->manufacturer_id); + + nfc_dbg("nfcc_features 0x%x", + ndev->nfcc_features); + nfc_dbg("num_supported_rf_interfaces %d", + ndev->num_supported_rf_interfaces); + nfc_dbg("supported_rf_interfaces[0] 0x%x", + ndev->supported_rf_interfaces[0]); + nfc_dbg("supported_rf_interfaces[1] 0x%x", + ndev->supported_rf_interfaces[1]); + nfc_dbg("supported_rf_interfaces[2] 0x%x", + ndev->supported_rf_interfaces[2]); + nfc_dbg("supported_rf_interfaces[3] 0x%x", + ndev->supported_rf_interfaces[3]); + nfc_dbg("max_logical_connections %d", + ndev->max_logical_connections); + nfc_dbg("max_routing_table_size %d", + ndev->max_routing_table_size); + nfc_dbg("max_control_packet_payload_length %d", + ndev->max_control_packet_payload_length); + nfc_dbg("rf_sending_buffer_size %d", + ndev->rf_sending_buffer_size); + nfc_dbg("rf_receiving_buffer_size %d", + ndev->rf_receiving_buffer_size); + nfc_dbg("manufacturer_id 0x%x", + ndev->manufacturer_id); + + nci_req_complete(ndev, rsp_1->status); +} + +static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + struct nci_core_conn_create_rsp *rsp = (void *) skb->data; + + nfc_dbg("entry, status 0x%x", rsp->status); + + if (rsp->status != NCI_STATUS_OK) + return; + + ndev->max_pkt_payload_size = rsp->max_pkt_payload_size; + ndev->initial_num_credits = rsp->initial_num_credits; + ndev->conn_id = rsp->conn_id; + + atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); + + nfc_dbg("max_pkt_payload_size %d", ndev->max_pkt_payload_size); + nfc_dbg("initial_num_credits %d", ndev->initial_num_credits); + nfc_dbg("conn_id %d", ndev->conn_id); +} + +static void nci_rf_disc_map_rsp_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + __u8 status = skb->data[0]; + + nfc_dbg("entry, status 0x%x", status); + + nci_req_complete(ndev, status); +} + +static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) +{ + __u8 status = skb->data[0]; + + nfc_dbg("entry, status 0x%x", status); + + if (status == NCI_STATUS_OK) + set_bit(NCI_DISCOVERY, &ndev->flags); + + nci_req_complete(ndev, status); +} + +static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev, + struct sk_buff *skb) +{ + __u8 status = skb->data[0]; + + nfc_dbg("entry, status 0x%x", status); + + clear_bit(NCI_DISCOVERY, &ndev->flags); + + nci_req_complete(ndev, status); +} + +void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb) +{ + __u16 rsp_opcode = nci_opcode(skb->data); + + /* we got a rsp, stop the cmd timer */ + del_timer(&ndev->cmd_timer); + + nfc_dbg("NCI RX: MT=rsp, PBF=%d, GID=0x%x, OID=0x%x, plen=%d", + nci_pbf(skb->data), + nci_opcode_gid(rsp_opcode), + nci_opcode_oid(rsp_opcode), + nci_plen(skb->data)); + + /* strip the nci control header */ + skb_pull(skb, NCI_CTRL_HDR_SIZE); + + switch (rsp_opcode) { + case NCI_OP_CORE_RESET_RSP: + nci_core_reset_rsp_packet(ndev, skb); + break; + + case NCI_OP_CORE_INIT_RSP: + nci_core_init_rsp_packet(ndev, skb); + break; + + case NCI_OP_CORE_CONN_CREATE_RSP: + nci_core_conn_create_rsp_packet(ndev, skb); + break; + + case NCI_OP_RF_DISCOVER_MAP_RSP: + nci_rf_disc_map_rsp_packet(ndev, skb); + break; + + case NCI_OP_RF_DISCOVER_RSP: + nci_rf_disc_rsp_packet(ndev, skb); + break; + + case NCI_OP_RF_DEACTIVATE_RSP: + nci_rf_deactivate_rsp_packet(ndev, skb); + break; + + default: + nfc_err("unknown rsp opcode 0x%x", rsp_opcode); + break; + } + + kfree_skb(skb); + + /* trigger the next cmd */ + atomic_set(&ndev->cmd_cnt, 1); + if (!skb_queue_empty(&ndev->cmd_q)) + queue_work(ndev->cmd_wq, &ndev->cmd_work); +} From 93aead46428d38729f430f395a8403795a019e54 Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Sun, 18 Sep 2011 11:19:36 +0300 Subject: [PATCH 269/287] NFC: driver for TI shared transport Signed-off-by: Ilan Elias Signed-off-by: John W. Linville --- drivers/nfc/Kconfig | 11 ++ drivers/nfc/Makefile | 1 + drivers/nfc/nfcwilink.c | 342 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 354 insertions(+) create mode 100644 drivers/nfc/nfcwilink.c diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 2acff4307ca4..8a56fd3da989 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -27,4 +27,15 @@ config NFC_PN533 Say Y here to compile support for PN533 devices into the kernel or say M to compile it as module (pn533). +config NFC_WILINK + tristate "Texas Instruments NFC WiLink driver" + depends on TI_ST + help + This enables the NFC driver for Texas Instrument's BT/FM/GPS/NFC + combo devices. This makes use of shared transport line discipline + core driver to communicate with the NFC core of the combo chip. + + Say Y here to compile support for Texas Instrument's NFC WiLink driver + into the kernel or say M to compile it as module. + endmenu diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile index 8ef446d2c1bd..ab99e8572f02 100644 --- a/drivers/nfc/Makefile +++ b/drivers/nfc/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_PN544_NFC) += pn544.o obj-$(CONFIG_NFC_PN533) += pn533.o +obj-$(CONFIG_NFC_WILINK) += nfcwilink.o ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c new file mode 100644 index 000000000000..5b0f1ff80361 --- /dev/null +++ b/drivers/nfc/nfcwilink.c @@ -0,0 +1,342 @@ +/* + * Texas Instrument's NFC Driver For Shared Transport. + * + * NFC Driver acts as interface between NCI core and + * TI Shared Transport Layer. + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * Written by Ilan Elias + * + * Acknowledgements: + * This file is based on btwilink.c, which was written + * by Raja Mani and Pavan Savoy. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include +#include +#include + +#define NFCWILINK_CHNL 12 +#define NFCWILINK_OPCODE 7 +#define NFCWILINK_MAX_FRAME_SIZE 300 +#define NFCWILINK_HDR_LEN 4 +#define NFCWILINK_OFFSET_LEN_IN_HDR 1 +#define NFCWILINK_LEN_SIZE 2 +#define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */ + +struct nfcwilink_hdr { + u8 chnl; + u8 opcode; + u16 len; +} __packed; + +struct nfcwilink { + struct platform_device *pdev; + struct nci_dev *ndev; + unsigned long flags; + + char st_register_cb_status; + long (*st_write) (struct sk_buff *); + struct completion st_register_completed; +}; + +/* NFCWILINK driver flags */ +enum { + NFCWILINK_RUNNING, +}; + +/* Called by ST when registration is complete */ +static void nfcwilink_register_complete(void *priv_data, char data) +{ + struct nfcwilink *drv = priv_data; + + nfc_dev_dbg(&drv->pdev->dev, "register_complete entry"); + + /* store ST registration status */ + drv->st_register_cb_status = data; + + /* complete the wait in nfc_st_open() */ + complete(&drv->st_register_completed); +} + +/* Called by ST when receive data is available */ +static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) +{ + struct nfcwilink *drv = priv_data; + int rc; + + nfc_dev_dbg(&drv->pdev->dev, "receive entry, len %d", skb->len); + + if (!skb) + return -EFAULT; + + if (!drv) { + kfree_skb(skb); + return -EFAULT; + } + + /* strip the ST header + (apart for the chnl byte, which is not received in the hdr) */ + skb_pull(skb, (NFCWILINK_HDR_LEN-1)); + + skb->dev = (void *) drv->ndev; + + /* Forward skb to NCI core layer */ + rc = nci_recv_frame(skb); + if (rc < 0) { + nfc_dev_err(&drv->pdev->dev, "nci_recv_frame failed %d", rc); + return rc; + } + + return 0; +} + +/* protocol structure registered with ST */ +static struct st_proto_s nfcwilink_proto = { + .chnl_id = NFCWILINK_CHNL, + .max_frame_size = NFCWILINK_MAX_FRAME_SIZE, + .hdr_len = (NFCWILINK_HDR_LEN-1), /* not including chnl byte */ + .offset_len_in_hdr = NFCWILINK_OFFSET_LEN_IN_HDR, + .len_size = NFCWILINK_LEN_SIZE, + .reserve = 0, + .recv = nfcwilink_receive, + .reg_complete_cb = nfcwilink_register_complete, + .write = NULL, +}; + +static int nfcwilink_open(struct nci_dev *ndev) +{ + struct nfcwilink *drv = nci_get_drvdata(ndev); + unsigned long comp_ret; + int rc; + + nfc_dev_dbg(&drv->pdev->dev, "open entry"); + + if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) { + rc = -EBUSY; + goto exit; + } + + nfcwilink_proto.priv_data = drv; + + init_completion(&drv->st_register_completed); + drv->st_register_cb_status = -EINPROGRESS; + + rc = st_register(&nfcwilink_proto); + if (rc < 0) { + if (rc == -EINPROGRESS) { + comp_ret = wait_for_completion_timeout( + &drv->st_register_completed, + msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT)); + + nfc_dev_dbg(&drv->pdev->dev, + "wait_for_completion_timeout returned %ld", + comp_ret); + + if (comp_ret == 0) { + /* timeout */ + rc = -ETIMEDOUT; + goto clear_exit; + } else if (drv->st_register_cb_status != 0) { + rc = drv->st_register_cb_status; + nfc_dev_err(&drv->pdev->dev, + "st_register_cb failed %d", rc); + goto clear_exit; + } + } else { + nfc_dev_err(&drv->pdev->dev, + "st_register failed %d", rc); + goto clear_exit; + } + } + + /* st_register MUST fill the write callback */ + BUG_ON(nfcwilink_proto.write == NULL); + drv->st_write = nfcwilink_proto.write; + + goto exit; + +clear_exit: + clear_bit(NFCWILINK_RUNNING, &drv->flags); + +exit: + return rc; +} + +static int nfcwilink_close(struct nci_dev *ndev) +{ + struct nfcwilink *drv = nci_get_drvdata(ndev); + int rc; + + nfc_dev_dbg(&drv->pdev->dev, "close entry"); + + if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags)) + return 0; + + rc = st_unregister(&nfcwilink_proto); + if (rc) + nfc_dev_err(&drv->pdev->dev, "st_unregister failed %d", rc); + + drv->st_write = NULL; + + return rc; +} + +static int nfcwilink_send(struct sk_buff *skb) +{ + struct nci_dev *ndev = (struct nci_dev *)skb->dev; + struct nfcwilink *drv = nci_get_drvdata(ndev); + struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000}; + long len; + + nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len); + + if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) + return -EBUSY; + + /* add the ST hdr to the start of the buffer */ + hdr.len = skb->len; + memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN); + + /* Insert skb to shared transport layer's transmit queue. + * Freeing skb memory is taken care in shared transport layer, + * so don't free skb memory here. + */ + len = drv->st_write(skb); + if (len < 0) { + kfree_skb(skb); + nfc_dev_err(&drv->pdev->dev, "st_write failed %ld", len); + return -EFAULT; + } + + return 0; +} + +static struct nci_ops nfcwilink_ops = { + .open = nfcwilink_open, + .close = nfcwilink_close, + .send = nfcwilink_send, +}; + +static int nfcwilink_probe(struct platform_device *pdev) +{ + static struct nfcwilink *drv; + int rc; + u32 protocols; + + nfc_dev_dbg(&pdev->dev, "probe entry"); + + drv = kzalloc(sizeof(struct nfcwilink), GFP_KERNEL); + if (!drv) { + rc = -ENOMEM; + goto exit; + } + + drv->pdev = pdev; + + protocols = NFC_PROTO_JEWEL_MASK + | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK + | NFC_PROTO_ISO14443_MASK + | NFC_PROTO_NFC_DEP_MASK; + + drv->ndev = nci_allocate_device(&nfcwilink_ops, + protocols, + NFCWILINK_HDR_LEN, + 0); + if (!drv->ndev) { + nfc_dev_err(&pdev->dev, "nci_allocate_device failed"); + rc = -ENOMEM; + goto free_exit; + } + + nci_set_parent_dev(drv->ndev, &pdev->dev); + nci_set_drvdata(drv->ndev, drv); + + rc = nci_register_device(drv->ndev); + if (rc < 0) { + nfc_dev_err(&pdev->dev, "nci_register_device failed %d", rc); + goto free_dev_exit; + } + + dev_set_drvdata(&pdev->dev, drv); + + goto exit; + +free_dev_exit: + nci_free_device(drv->ndev); + +free_exit: + kfree(drv); + +exit: + return rc; +} + +static int nfcwilink_remove(struct platform_device *pdev) +{ + struct nfcwilink *drv = dev_get_drvdata(&pdev->dev); + struct nci_dev *ndev; + + nfc_dev_dbg(&pdev->dev, "remove entry"); + + if (!drv) + return -EFAULT; + + ndev = drv->ndev; + + nci_unregister_device(ndev); + nci_free_device(ndev); + + kfree(drv); + + dev_set_drvdata(&pdev->dev, NULL); + + return 0; +} + +static struct platform_driver nfcwilink_driver = { + .probe = nfcwilink_probe, + .remove = nfcwilink_remove, + .driver = { + .name = "nfcwilink", + .owner = THIS_MODULE, + }, +}; + +/* ------- Module Init/Exit interfaces ------ */ +static int __init nfcwilink_init(void) +{ + printk(KERN_INFO "NFC Driver for TI WiLink"); + + return platform_driver_register(&nfcwilink_driver); +} + +static void __exit nfcwilink_exit(void) +{ + platform_driver_unregister(&nfcwilink_driver); +} + +module_init(nfcwilink_init); +module_exit(nfcwilink_exit); + +/* ------ Module Info ------ */ + +MODULE_AUTHOR("Ilan Elias "); +MODULE_DESCRIPTION("NFC Driver for TI Shared Transport"); +MODULE_LICENSE("GPL"); From f36369afce40a20b6328590c1f9a777d0810f815 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Mon, 19 Sep 2011 20:15:48 +0530 Subject: [PATCH 270/287] ath9k: Store noise immunity values across scanning CCK/OFDM noise immunilty values are always reset to defaults during bgscan. This could affect the link quality and performance when the STA is associated in a noisy channel. So do not override the learned values across the scanning. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ani.c | 10 ++++++++-- drivers/net/wireless/ath/ath9k/ani.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index d969a11e3425..01240d63896e 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -273,7 +273,8 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) immunityLevel, aniState->noiseFloor, aniState->rssiThrLow, aniState->rssiThrHigh); - aniState->ofdmNoiseImmunityLevel = immunityLevel; + if (aniState->update_ani) + aniState->ofdmNoiseImmunityLevel = immunityLevel; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; @@ -346,7 +347,8 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; - aniState->cckNoiseImmunityLevel = immunityLevel; + if (aniState->update_ani) + aniState->cckNoiseImmunityLevel = immunityLevel; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; @@ -593,6 +595,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); + aniState->update_ani = false; ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL); ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL); } @@ -609,6 +612,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); + aniState->update_ani = true; ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel); ath9k_hw_set_cck_nil(ah, @@ -892,6 +896,8 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ani->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; + ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; + ani->update_ani = false; } /* diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index a547005572e7..83029d6c7b22 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -122,6 +122,7 @@ struct ar5416AniState { u8 firstepLevel; u8 ofdmWeakSigDetectOff; u8 cckWeakSigThreshold; + bool update_ani; u32 listenTime; int32_t rssiThrLow; int32_t rssiThrHigh; From eed72316586a3ad401eff054b7c7a3ea56869541 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 19 Sep 2011 14:34:07 -0500 Subject: [PATCH 271/287] rtlwifi: rtl8192ce: Change modinfo messages The various modparam messages are difficult to understand. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 4c34c4c1ae56..b7ecb9e44aa9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -133,6 +133,10 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + if (!rtlpriv->psc.inactiveps) + pr_info("rtl8192ce: Power Save off (module option)\n"); + if (!rtlpriv->psc.fwctrl_lps) + pr_info("rtl8192ce: FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through @@ -356,10 +360,10 @@ module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444); -MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); -MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); -MODULE_PARM_DESC(fwlps, "using linked fw control power save " - "(default 1 is open)\n"); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); static struct pci_driver rtl92ce_driver = { .name = KBUILD_MODNAME, From 7664beeb2fb2d7ed13b2609dab8b84724263f135 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 19 Sep 2011 14:34:08 -0500 Subject: [PATCH 272/287] rtlwifi: rtl8192se: Change modinfo messages The various modparam messages are difficult to understand. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 0055a1c845a2..24bd331a5484 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -164,6 +164,10 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + if (!rtlpriv->psc.inactiveps) + pr_info("rtl8192ce: Power Save off (module option)\n"); + if (!rtlpriv->psc.fwctrl_lps) + pr_info("rtl8192ce: FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through @@ -378,6 +382,7 @@ MODULE_DEVICE_TABLE(pci, rtl92se_pci_ids); MODULE_AUTHOR("lizhaoming "); MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin"); @@ -386,11 +391,10 @@ module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444); module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444); -MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); -MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); -MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1 is " - "open)\n"); - +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); static struct pci_driver rtl92se_driver = { .name = KBUILD_MODNAME, From 87b6d09225506236c58bf407f9b750591a3b3a7b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 19 Sep 2011 14:34:09 -0500 Subject: [PATCH 273/287] rtlwifi: rtl8192de: Change modinfo messages The various modparam messages are difficult to understand. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index f6419b7ed2f4..c681597c7f20 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -150,6 +150,10 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + if (!rtlpriv->psc.inactiveps) + pr_info("rtl8192ce: Power Save off (module option)\n"); + if (!rtlpriv->psc.fwctrl_lps) + pr_info("rtl8192ce: FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through @@ -376,10 +380,10 @@ module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444); module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444); -MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); -MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); -MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1" - " is open)\n"); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); static struct pci_driver rtl92de_driver = { .name = KBUILD_MODNAME, From da3ba88a9996cd64c6768bed5727e02da81e2c8d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 19 Sep 2011 14:34:10 -0500 Subject: [PATCH 274/287] rtlwifi: Combine instances of RTL_HAL_IS_CCK_RATE macros. Three drivers, rtl8192ce, rtl8192cu and rtl8192de, use the same macro to check if a particular rate is in the CCK set. This common code is relocated to a common header file. A distinct macro used by rtl8192se with the same name is renamed. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 6 ------ drivers/net/wireless/rtlwifi/rtl8192cu/mac.h | 6 ------ drivers/net/wireless/rtlwifi/rtl8192de/trx.h | 6 ------ drivers/net/wireless/rtlwifi/rtl8192se/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 +- drivers/net/wireless/rtlwifi/wifi.h | 6 ++++++ 6 files changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index 81ae64234f80..c8977a50ca36 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -537,12 +537,6 @@ do { \ memset(__pdesc, 0, _size); \ } while (0); -#define RX_HAL_IS_CCK_RATE(_pdesc)\ - (_pdesc->rxmcs == DESC92_RATE1M || \ - _pdesc->rxmcs == DESC92_RATE2M || \ - _pdesc->rxmcs == DESC92_RATE5_5M || \ - _pdesc->rxmcs == DESC92_RATE11M) - struct rx_fwinfo_92c { u8 gain_trsw[4]; u8 pwdb_all; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h index 35529f701fc0..626d88e88e26 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h @@ -87,12 +87,6 @@ void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter); u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw); -#define RX_HAL_IS_CCK_RATE(_pdesc)\ - (GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE1M ||\ - GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE2M ||\ - GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE5_5M ||\ - GET_RX_DESC_RX_MCS(_pdesc) == DESC92_RATE11M) - struct rx_fwinfo_92c { u8 gain_trsw[4]; u8 pwdb_all; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h index 6c2236868c9a..4d55d0b6816d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h @@ -537,12 +537,6 @@ do { \ memset((void *)__pdesc, 0, _size); \ } while (0); -#define RX_HAL_IS_CCK_RATE(_pdesc)\ - (_pdesc->rxmcs == DESC92_RATE1M || \ - _pdesc->rxmcs == DESC92_RATE2M || \ - _pdesc->rxmcs == DESC92_RATE5_5M || \ - _pdesc->rxmcs == DESC92_RATE11M) - /* For 92D early mode */ #define SET_EARLYMODE_PKTNUM(__paddr, __value) \ SET_BITS_OFFSET_LE(__paddr, 0, 3, __value) diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h index 68204ea175dd..c6c044816d39 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h @@ -459,7 +459,7 @@ do { \ #define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val) \ SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val) -#define RX_HAL_IS_CCK_RATE(_pdesc)\ +#define SE_RX_HAL_IS_CCK_RATE(_pdesc)\ (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE1M || \ GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE2M || \ GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE5_5M ||\ diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index d9aeae7f8bdb..ba137da082b5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -126,7 +126,7 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, bool in_powersavemode = false; bool is_cck_rate; - is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); + is_cck_rate = SE_RX_HAL_IS_CCK_RATE(pdesc); pstats->packet_matchbssid = packet_match_bssid; pstats->packet_toself = packet_toself; pstats->is_cck = is_cck_rate; diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 8a9091968f31..615f6b4463e6 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -165,6 +165,12 @@ enum hardware_type { #define IS_HARDWARE_TYPE_8723U(rtlhal) \ (rtlhal->hw_type == HARDWARE_TYPE_RTL8723U) +#define RX_HAL_IS_CCK_RATE(_pdesc)\ + (_pdesc->rxmcs == DESC92_RATE1M || \ + _pdesc->rxmcs == DESC92_RATE2M || \ + _pdesc->rxmcs == DESC92_RATE5_5M || \ + _pdesc->rxmcs == DESC92_RATE11M) + enum scan_operation_backup_opt { SCAN_OPT_BACKUP = 0, SCAN_OPT_RESTORE, From 6f2d93353a48af4d5b6ea2a79994d7c9a94b356a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 20 Sep 2011 17:40:51 +0200 Subject: [PATCH 275/287] mac80211: fix AP/VLAN PS buffer race When an AP interface is removed without the AP/VLAN interfaces having been removed before already, the AP-VLAN interface might still have sleeping stations and buffer multicast frames which will happen on the AP interface. Thus, we need to remove AP/VLAN interfaces before purging buffered broadcast frames. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/iface.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index eaa80a3d412b..4116a7542b6b 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -460,17 +460,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, synchronize_rcu(); kfree(old_beacon); - /* free all potentially still buffered bcast frames */ - while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { - local->total_ps_buffered--; - dev_kfree_skb(skb); - } - /* down all dependent devices, that is VLANs */ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, u.vlan.list) dev_close(vlan->dev); WARN_ON(!list_empty(&sdata->u.ap.vlans)); + + /* free all potentially still buffered bcast frames */ + local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf); + skb_queue_purge(&sdata->u.ap.ps_bc_buf); } if (going_down) From ba4a14e1024fd783f0e56d96538a959a44651897 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Tue, 20 Sep 2011 13:43:32 -0700 Subject: [PATCH 276/287] mac80211: notify peer when shutting down peer link Send a Mesh Peering Close frame when we deactivate a mesh peer link. Signed-off-by: Thomas Pedersen Signed-off-by: John W. Linville --- net/mac80211/mesh_plink.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 4396906175ae..1213a23ff0fa 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -43,6 +43,10 @@ enum plink_event { CLS_IGNR }; +static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, + enum ieee80211_self_protected_actioncode action, + u8 *da, __le16 llid, __le16 plid, __le16 reason); + static inline void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) { @@ -133,6 +137,10 @@ void mesh_plink_deactivate(struct sta_info *sta) spin_lock_bh(&sta->lock); deactivated = __mesh_plink_deactivate(sta); + sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); + mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, + sta->sta.addr, sta->llid, sta->plid, + sta->reason); spin_unlock_bh(&sta->lock); if (deactivated) From 6e809a16d98efa8b1483a25ab8886dd2aa200d0f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 20 Sep 2011 15:37:20 -0700 Subject: [PATCH 277/287] iwlagn: move scan code to scan file Since the driver split there's no longer a need to have the scan code scattered across multiple files, so move it all back to iwl-scan.c Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 427 -------------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 - drivers/net/wireless/iwlwifi/iwl-core.h | 6 - drivers/net/wireless/iwlwifi/iwl-scan.c | 439 ++++++++++++++++++++- 4 files changed, 433 insertions(+), 440 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index e8b324c84da8..0a1f331cb572 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -190,433 +190,6 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) return -1; } -static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, - struct ieee80211_vif *vif, - enum ieee80211_band band, - struct iwl_scan_channel *scan_ch) -{ - const struct ieee80211_supported_band *sband; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added = 0; - u16 channel = 0; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) { - IWL_ERR(priv, "invalid band\n"); - return added; - } - - active_dwell = iwl_get_active_dwell_time(priv, band, 0); - passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - channel = iwl_get_single_channel_number(priv, band); - if (channel) { - scan_ch->channel = cpu_to_le16(channel); - scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* Set txpower levels to defaults */ - scan_ch->dsp_atten = 110; - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tx_gain = ((1 << 5) | (5 << 3)); - added++; - } else - IWL_ERR(priv, "no valid channel found\n"); - return added; -} - -static int iwl_get_channels_for_scan(struct iwl_priv *priv, - struct ieee80211_vif *vif, - enum ieee80211_band band, - u8 is_active, u8 n_probes, - struct iwl_scan_channel *scan_ch) -{ - struct ieee80211_channel *chan; - const struct ieee80211_supported_band *sband; - const struct iwl_channel_info *ch_info; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added, i; - u16 channel; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) - return 0; - - active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); - passive_dwell = iwl_get_passive_dwell_time(priv, band, vif); - - if (passive_dwell <= active_dwell) - passive_dwell = active_dwell + 1; - - for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) { - chan = priv->scan_request->channels[i]; - - if (chan->band != band) - continue; - - channel = chan->hw_value; - scan_ch->channel = cpu_to_le16(channel); - - ch_info = iwl_get_channel_info(priv, band, channel); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n", - channel); - continue; - } - - if (!is_active || is_channel_passive(ch_info) || - (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) - scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; - else - scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; - - if (n_probes) - scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); - - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - - /* Set txpower levels to defaults */ - scan_ch->dsp_atten = 110; - - /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level: - * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; - */ - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tx_gain = ((1 << 5) | (5 << 3)); - - IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n", - channel, le32_to_cpu(scan_ch->type), - (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? - "ACTIVE" : "PASSIVE", - (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? - active_dwell : passive_dwell); - - scan_ch++; - added++; - } - - IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added); - return added; -} - -int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_SCAN_CMD, - .len = { sizeof(struct iwl_scan_cmd), }, - .flags = CMD_SYNC, - }; - struct iwl_scan_cmd *scan; - struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - u32 rate_flags = 0; - u16 cmd_len; - u16 rx_chain = 0; - enum ieee80211_band band; - u8 n_probes = 0; - u8 rx_ant = hw_params(priv).valid_rx_ant; - u8 rate; - bool is_active = false; - int chan_mod; - u8 active_chains; - u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; - int ret; - - lockdep_assert_held(&priv->shrd->mutex); - - if (vif) - ctx = iwl_rxon_ctx_from_vif(vif); - - if (!priv->scan_cmd) { - priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + - IWL_MAX_SCAN_SIZE, GFP_KERNEL); - if (!priv->scan_cmd) { - IWL_DEBUG_SCAN(priv, - "fail to allocate memory for scan\n"); - return -ENOMEM; - } - } - scan = priv->scan_cmd; - memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); - - scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; - scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - - if (priv->scan_type != IWL_SCAN_ROC && - iwl_is_any_associated(priv)) { - u16 interval = 0; - u32 extra; - u32 suspend_time = 100; - u32 scan_suspend_time = 100; - - IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - switch (priv->scan_type) { - case IWL_SCAN_ROC: - WARN_ON(1); - break; - case IWL_SCAN_RADIO_RESET: - interval = 0; - break; - case IWL_SCAN_NORMAL: - interval = vif->bss_conf.beacon_int; - break; - } - - scan->suspend_time = 0; - scan->max_out_time = cpu_to_le32(200 * 1024); - if (!interval) - interval = suspend_time; - - extra = (suspend_time / interval) << 22; - scan_suspend_time = (extra | - ((suspend_time % interval) * 1024)); - scan->suspend_time = cpu_to_le32(scan_suspend_time); - IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", - scan_suspend_time, interval); - } else if (priv->scan_type == IWL_SCAN_ROC) { - scan->suspend_time = 0; - scan->max_out_time = 0; - scan->quiet_time = 0; - scan->quiet_plcp_th = 0; - } - - switch (priv->scan_type) { - case IWL_SCAN_RADIO_RESET: - IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); - break; - case IWL_SCAN_NORMAL: - if (priv->scan_request->n_ssids) { - int i, p = 0; - IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); - for (i = 0; i < priv->scan_request->n_ssids; i++) { - /* always does wildcard anyway */ - if (!priv->scan_request->ssids[i].ssid_len) - continue; - scan->direct_scan[p].id = WLAN_EID_SSID; - scan->direct_scan[p].len = - priv->scan_request->ssids[i].ssid_len; - memcpy(scan->direct_scan[p].ssid, - priv->scan_request->ssids[i].ssid, - priv->scan_request->ssids[i].ssid_len); - n_probes++; - p++; - } - is_active = true; - } else - IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); - break; - case IWL_SCAN_ROC: - IWL_DEBUG_SCAN(priv, "Start ROC scan.\n"); - break; - } - - scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = ctx->bcast_sta_id; - scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - - switch (priv->scan_band) { - case IEEE80211_BAND_2GHZ: - scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; - chan_mod = le32_to_cpu( - priv->contexts[IWL_RXON_CTX_BSS].active.flags & - RXON_FLG_CHANNEL_MODE_MSK) - >> RXON_FLG_CHANNEL_MODE_POS; - if (chan_mod == CHANNEL_MODE_PURE_40) { - rate = IWL_RATE_6M_PLCP; - } else { - rate = IWL_RATE_1M_PLCP; - rate_flags = RATE_MCS_CCK_MSK; - } - /* - * Internal scans are passive, so we can indiscriminately set - * the BT ignore flag on 2.4 GHz since it applies to TX only. - */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) - scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; - break; - case IEEE80211_BAND_5GHZ: - rate = IWL_RATE_6M_PLCP; - break; - default: - IWL_WARN(priv, "Invalid scan band\n"); - return -EIO; - } - - /* - * If active scanning is requested but a certain channel is - * marked passive, we can do active scanning if we detect - * transmissions. - * - * There is an issue with some firmware versions that triggers - * a sysassert on a "good CRC threshold" of zero (== disabled), - * on a radar channel even though this means that we should NOT - * send probes. - * - * The "good CRC threshold" is the number of frames that we - * need to receive during our dwell time on a channel before - * sending out probes -- setting this to a huge value will - * mean we never reach it, but at the same time work around - * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER - * here instead of IWL_GOOD_CRC_TH_DISABLED. - * - * This was fixed in later versions along with some other - * scan changes, and the threshold behaves as a flag in those - * versions. - */ - if (priv->new_scan_threshold_behaviour) - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_DISABLED; - else - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_NEVER; - - band = priv->scan_band; - - if (priv->cfg->scan_rx_antennas[band]) - rx_ant = priv->cfg->scan_rx_antennas[band]; - - if (band == IEEE80211_BAND_2GHZ && - priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { - /* transmit 2.4 GHz probes only on first antenna */ - scan_tx_antennas = first_antenna(scan_tx_antennas); - } - - priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], - scan_tx_antennas); - rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); - scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); - - /* In power save mode use one chain, otherwise use all chains */ - if (test_bit(STATUS_POWER_PMI, &priv->shrd->status)) { - /* rx_ant has been set to all valid chains previously */ - active_chains = rx_ant & - ((u8)(priv->chain_noise_data.active_chains)); - if (!active_chains) - active_chains = rx_ant; - - IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n", - priv->chain_noise_data.active_chains); - - rx_ant = first_antenna(active_chains); - } - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && - priv->bt_full_concurrent) { - /* operated as 1x1 in full concurrency mode */ - rx_ant = first_antenna(rx_ant); - } - - /* MIMO is not used here, but value is required */ - rx_chain |= - hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS; - rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; - rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; - rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; - scan->rx_chain = cpu_to_le16(rx_chain); - switch (priv->scan_type) { - case IWL_SCAN_NORMAL: - cmd_len = iwl_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - vif->addr, - priv->scan_request->ie, - priv->scan_request->ie_len, - IWL_MAX_SCAN_SIZE - sizeof(*scan)); - break; - case IWL_SCAN_RADIO_RESET: - case IWL_SCAN_ROC: - /* use bcast addr, will not be transmitted but must be valid */ - cmd_len = iwl_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - iwl_bcast_addr, NULL, 0, - IWL_MAX_SCAN_SIZE - sizeof(*scan)); - break; - default: - BUG(); - } - scan->tx_cmd.len = cpu_to_le16(cmd_len); - - scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | - RXON_FILTER_BCON_AWARE_MSK); - - switch (priv->scan_type) { - case IWL_SCAN_RADIO_RESET: - scan->channel_count = - iwl_get_single_channel_for_scan(priv, vif, band, - (void *)&scan->data[cmd_len]); - break; - case IWL_SCAN_NORMAL: - scan->channel_count = - iwl_get_channels_for_scan(priv, vif, band, - is_active, n_probes, - (void *)&scan->data[cmd_len]); - break; - case IWL_SCAN_ROC: { - struct iwl_scan_channel *scan_ch; - - scan->channel_count = 1; - - scan_ch = (void *)&scan->data[cmd_len]; - scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; - scan_ch->channel = - cpu_to_le16(priv->hw_roc_channel->hw_value); - scan_ch->active_dwell = - scan_ch->passive_dwell = - cpu_to_le16(priv->hw_roc_duration); - - /* Set txpower levels to defaults */ - scan_ch->dsp_atten = 110; - - /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level: - * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; - */ - if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ) - scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tx_gain = ((1 << 5) | (5 << 3)); - } - break; - } - - if (scan->channel_count == 0) { - IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); - return -EIO; - } - - cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) + - scan->channel_count * sizeof(struct iwl_scan_channel); - cmd.data[0] = scan; - cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - scan->len = cpu_to_le16(cmd.len[0]); - - /* set scan bit here for PAN params */ - set_bit(STATUS_SCAN_HW, &priv->shrd->status); - - ret = iwlagn_set_pan_params(priv); - if (ret) - return ret; - - ret = iwl_trans_send_cmd(trans(priv), &cmd); - if (ret) { - clear_bit(STATUS_SCAN_HW, &priv->shrd->status); - iwlagn_set_pan_params(priv); - } - - return ret; -} - int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add) { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 4bc1f4669e5a..5c4f8c72ee60 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -146,7 +146,6 @@ static inline bool iwl_is_tx_success(u32 status) u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); /* scan */ -int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); void iwlagn_post_scan(struct iwl_priv *priv); void iwlagn_disable_roc(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6d7ad45c6d6f..74d4cff09fae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -330,12 +330,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, const u8 *ta, const u8 *ie, int ie_len, int left); void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); -u16 iwl_get_active_dwell_time(struct iwl_priv *priv, - enum ieee80211_band band, - u8 n_probes); -u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, - enum ieee80211_band band, - struct ieee80211_vif *vif); void iwl_setup_scan_deferred_work(struct iwl_priv *priv); void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); int __must_check iwl_scan_initiate(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index fc5af3475392..8ac6b05c6c78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -299,9 +299,8 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) iwl_rx_scan_complete_notif; } -inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, - enum ieee80211_band band, - u8 n_probes) +static u16 iwl_get_active_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band, u8 n_probes) { if (band == IEEE80211_BAND_5GHZ) return IWL_ACTIVE_DWELL_TIME_52 + @@ -311,9 +310,8 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); } -u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, - enum ieee80211_band band, - struct ieee80211_vif *vif) +static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band) { struct iwl_rxon_context *ctx; u16 passive = (band == IEEE80211_BAND_2GHZ) ? @@ -342,6 +340,435 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, return passive; } +static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + struct iwl_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added = 0; + u16 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_get_passive_dwell_time(priv, band); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + channel = iwl_get_single_channel_number(priv, band); + if (channel) { + scan_ch->channel = cpu_to_le16(channel); + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + +static int iwl_get_channels_for_scan(struct iwl_priv *priv, + struct ieee80211_vif *vif, + enum ieee80211_band band, + u8 is_active, u8 n_probes, + struct iwl_scan_channel *scan_ch) +{ + struct ieee80211_channel *chan; + const struct ieee80211_supported_band *sband; + const struct iwl_channel_info *ch_info; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added, i; + u16 channel; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) + return 0; + + active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); + passive_dwell = iwl_get_passive_dwell_time(priv, band); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) { + chan = priv->scan_request->channels[i]; + + if (chan->band != band) + continue; + + channel = chan->hw_value; + scan_ch->channel = cpu_to_le16(channel); + + ch_info = iwl_get_channel_info(priv, band, channel); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_SCAN(priv, + "Channel %d is INVALID for this band.\n", + channel); + continue; + } + + if (!is_active || is_channel_passive(ch_info) || + (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + else + scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; + + if (n_probes) + scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); + + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + + IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n", + channel, le32_to_cpu(scan_ch->type), + (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? + "ACTIVE" : "PASSIVE", + (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ? + active_dwell : passive_dwell); + + scan_ch++; + added++; + } + + IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added); + return added; +} + +static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_CMD, + .len = { sizeof(struct iwl_scan_cmd), }, + .flags = CMD_SYNC, + }; + struct iwl_scan_cmd *scan; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + u32 rate_flags = 0; + u16 cmd_len; + u16 rx_chain = 0; + enum ieee80211_band band; + u8 n_probes = 0; + u8 rx_ant = hw_params(priv).valid_rx_ant; + u8 rate; + bool is_active = false; + int chan_mod; + u8 active_chains; + u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; + int ret; + + lockdep_assert_held(&priv->shrd->mutex); + + if (vif) + ctx = iwl_rxon_ctx_from_vif(vif); + + if (!priv->scan_cmd) { + priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + + IWL_MAX_SCAN_SIZE, GFP_KERNEL); + if (!priv->scan_cmd) { + IWL_DEBUG_SCAN(priv, + "fail to allocate memory for scan\n"); + return -ENOMEM; + } + } + scan = priv->scan_cmd; + memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); + + scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; + scan->quiet_time = IWL_ACTIVE_QUIET_TIME; + + if (priv->scan_type != IWL_SCAN_ROC && + iwl_is_any_associated(priv)) { + u16 interval = 0; + u32 extra; + u32 suspend_time = 100; + u32 scan_suspend_time = 100; + + IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); + switch (priv->scan_type) { + case IWL_SCAN_ROC: + WARN_ON(1); + break; + case IWL_SCAN_RADIO_RESET: + interval = 0; + break; + case IWL_SCAN_NORMAL: + interval = vif->bss_conf.beacon_int; + break; + } + + scan->suspend_time = 0; + scan->max_out_time = cpu_to_le32(200 * 1024); + if (!interval) + interval = suspend_time; + + extra = (suspend_time / interval) << 22; + scan_suspend_time = (extra | + ((suspend_time % interval) * 1024)); + scan->suspend_time = cpu_to_le32(scan_suspend_time); + IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", + scan_suspend_time, interval); + } else if (priv->scan_type == IWL_SCAN_ROC) { + scan->suspend_time = 0; + scan->max_out_time = 0; + scan->quiet_time = 0; + scan->quiet_plcp_th = 0; + } + + switch (priv->scan_type) { + case IWL_SCAN_RADIO_RESET: + IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + break; + case IWL_SCAN_NORMAL: + if (priv->scan_request->n_ssids) { + int i, p = 0; + IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; + } + is_active = true; + } else + IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); + break; + case IWL_SCAN_ROC: + IWL_DEBUG_SCAN(priv, "Start ROC scan.\n"); + break; + } + + scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; + scan->tx_cmd.sta_id = ctx->bcast_sta_id; + scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + + switch (priv->scan_band) { + case IEEE80211_BAND_2GHZ: + scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; + chan_mod = le32_to_cpu( + priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_CHANNEL_MODE_MSK) + >> RXON_FLG_CHANNEL_MODE_POS; + if (chan_mod == CHANNEL_MODE_PURE_40) { + rate = IWL_RATE_6M_PLCP; + } else { + rate = IWL_RATE_1M_PLCP; + rate_flags = RATE_MCS_CCK_MSK; + } + /* + * Internal scans are passive, so we can indiscriminately set + * the BT ignore flag on 2.4 GHz since it applies to TX only. + */ + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) + scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; + break; + case IEEE80211_BAND_5GHZ: + rate = IWL_RATE_6M_PLCP; + break; + default: + IWL_WARN(priv, "Invalid scan band\n"); + return -EIO; + } + + /* + * If active scanning is requested but a certain channel is + * marked passive, we can do active scanning if we detect + * transmissions. + * + * There is an issue with some firmware versions that triggers + * a sysassert on a "good CRC threshold" of zero (== disabled), + * on a radar channel even though this means that we should NOT + * send probes. + * + * The "good CRC threshold" is the number of frames that we + * need to receive during our dwell time on a channel before + * sending out probes -- setting this to a huge value will + * mean we never reach it, but at the same time work around + * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER + * here instead of IWL_GOOD_CRC_TH_DISABLED. + * + * This was fixed in later versions along with some other + * scan changes, and the threshold behaves as a flag in those + * versions. + */ + if (priv->new_scan_threshold_behaviour) + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_DISABLED; + else + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_NEVER; + + band = priv->scan_band; + + if (priv->cfg->scan_rx_antennas[band]) + rx_ant = priv->cfg->scan_rx_antennas[band]; + + if (band == IEEE80211_BAND_2GHZ && + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + /* transmit 2.4 GHz probes only on first antenna */ + scan_tx_antennas = first_antenna(scan_tx_antennas); + } + + priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, + priv->scan_tx_ant[band], + scan_tx_antennas); + rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); + scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); + + /* In power save mode use one chain, otherwise use all chains */ + if (test_bit(STATUS_POWER_PMI, &priv->shrd->status)) { + /* rx_ant has been set to all valid chains previously */ + active_chains = rx_ant & + ((u8)(priv->chain_noise_data.active_chains)); + if (!active_chains) + active_chains = rx_ant; + + IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n", + priv->chain_noise_data.active_chains); + + rx_ant = first_antenna(active_chains); + } + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + rx_ant = first_antenna(rx_ant); + } + + /* MIMO is not used here, but value is required */ + rx_chain |= + hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS; + rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; + rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; + rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; + scan->rx_chain = cpu_to_le16(rx_chain); + switch (priv->scan_type) { + case IWL_SCAN_NORMAL: + cmd_len = iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + vif->addr, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + break; + case IWL_SCAN_RADIO_RESET: + case IWL_SCAN_ROC: + /* use bcast addr, will not be transmitted but must be valid */ + cmd_len = iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + iwl_bcast_addr, NULL, 0, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + break; + default: + BUG(); + } + scan->tx_cmd.len = cpu_to_le16(cmd_len); + + scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | + RXON_FILTER_BCON_AWARE_MSK); + + switch (priv->scan_type) { + case IWL_SCAN_RADIO_RESET: + scan->channel_count = + iwl_get_single_channel_for_scan(priv, vif, band, + (void *)&scan->data[cmd_len]); + break; + case IWL_SCAN_NORMAL: + scan->channel_count = + iwl_get_channels_for_scan(priv, vif, band, + is_active, n_probes, + (void *)&scan->data[cmd_len]); + break; + case IWL_SCAN_ROC: { + struct iwl_scan_channel *scan_ch; + + scan->channel_count = 1; + + scan_ch = (void *)&scan->data[cmd_len]; + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + scan_ch->channel = + cpu_to_le16(priv->hw_roc_channel->hw_value); + scan_ch->active_dwell = + scan_ch->passive_dwell = + cpu_to_le16(priv->hw_roc_duration); + + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + } + break; + } + + if (scan->channel_count == 0) { + IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); + return -EIO; + } + + cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) + + scan->channel_count * sizeof(struct iwl_scan_channel); + cmd.data[0] = scan; + cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; + scan->len = cpu_to_le16(cmd.len[0]); + + /* set scan bit here for PAN params */ + set_bit(STATUS_SCAN_HW, &priv->shrd->status); + + ret = iwlagn_set_pan_params(priv); + if (ret) + return ret; + + ret = iwl_trans_send_cmd(trans(priv), &cmd); + if (ret) { + clear_bit(STATUS_SCAN_HW, &priv->shrd->status); + iwlagn_set_pan_params(priv); + } + + return ret; +} + void iwl_init_scan_params(struct iwl_priv *priv) { u8 ant_idx = fls(hw_params(priv).valid_tx_ant) - 1; From c68929060181eb088bef252c5f493a66a44e77b1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 20 Sep 2011 15:37:21 -0700 Subject: [PATCH 278/287] iwlagn: remove common station priv Since the driver split there's no more need for shared/non-shared private station data so remove struct iwl_station_priv_common entirely. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 16 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 8 ++------ drivers/net/wireless/iwlwifi/iwl-sta.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-sta.h | 2 +- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index ffee15ba06a8..c14f8d6fd7d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -346,7 +346,7 @@ static void rs_program_fix_rate(struct iwl_priv *priv, { struct iwl_station_priv *sta_priv = container_of(lq_sta, struct iwl_station_priv, lq_sta); - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + struct iwl_rxon_context *ctx = sta_priv->ctx; lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ @@ -710,7 +710,7 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, static bool rs_use_green(struct ieee80211_sta *sta) { struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + struct iwl_rxon_context *ctx = sta_priv->ctx; return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && !(ctx->ht.non_gf_sta_present); @@ -917,7 +917,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, struct iwl_scale_tbl_info tbl_type; struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + struct iwl_rxon_context *ctx = sta_priv->ctx; IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); @@ -1283,7 +1283,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, s32 rate; s8 is_green = lq_sta->is_green; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + struct iwl_rxon_context *ctx = sta_priv->ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1339,7 +1339,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, s32 rate; s8 is_green = lq_sta->is_green; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + struct iwl_rxon_context *ctx = sta_priv->ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1396,7 +1396,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, u8 is_green = lq_sta->is_green; s32 rate; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + struct iwl_rxon_context *ctx = sta_priv->ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -2263,7 +2263,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, u8 tid = IWL_MAX_TID_COUNT; struct iwl_tid_data *tid_data; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - struct iwl_rxon_context *ctx = sta_priv->common.ctx; + struct iwl_rxon_context *ctx = sta_priv->ctx; IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n"); @@ -2706,7 +2706,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, return; sta_priv = (void *)sta->drv_priv; - ctx = sta_priv->common.ctx; + ctx = sta_priv->ctx; i = lq_sta->last_txrate_idx; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6def1c272775..fcfb410aca90 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2513,7 +2513,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, mutex_lock(&priv->shrd->mutex); IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", sta->addr); - sta_priv->common.sta_id = IWL_INVALID_STATION; + sta_priv->sta_id = IWL_INVALID_STATION; atomic_set(&sta_priv->pending_frames, 0); if (vif->type == NL80211_IFTYPE_AP) @@ -2529,7 +2529,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, return ret; } - sta_priv->common.sta_id = sta_id; + sta_priv->sta_id = sta_id; /* Initialize rate scaling */ IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f69e556bd3c2..fabfc8bf4971 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -202,11 +202,6 @@ struct iwl_station_entry { struct iwl_link_quality_cmd *lq; }; -struct iwl_station_priv_common { - struct iwl_rxon_context *ctx; - u8 sta_id; -}; - /* * iwl_station_priv: Driver's private station information * @@ -215,12 +210,13 @@ struct iwl_station_priv_common { * space. */ struct iwl_station_priv { - struct iwl_station_priv_common common; + struct iwl_rxon_context *ctx; struct iwl_lq_sta lq_sta; atomic_t pending_frames; bool client; bool asleep; u8 max_agg_bufsize; + u8 sta_id; }; /** diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index e24135e7d37d..f35cfa2fe5c5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -305,7 +305,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, station->ctxid = ctx->ctxid; if (sta) { - struct iwl_station_priv_common *sta_priv; + struct iwl_station_priv *sta_priv; sta_priv = (void *)sta->drv_priv; sta_priv->ctx = ctx; @@ -821,7 +821,7 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_sta *sta) { struct iwl_priv *priv = hw->priv; - struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; int ret; IWL_DEBUG_INFO(priv, "received request to remove station %pM\n", @@ -829,7 +829,7 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, mutex_lock(&priv->shrd->mutex); IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr); - ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr); + ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); if (ret) IWL_ERR(priv, "Error removing station %pM\n", sta->addr); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 9641eb6b1d0a..02491b930423 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -102,7 +102,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) if (WARN_ON(!sta)) return IWL_INVALID_STATION; - return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id; + return ((struct iwl_station_priv *)sta->drv_priv)->sta_id; } /** From 390808db4ab5c658dc1eb8078d82027ce7d0ea78 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 20 Sep 2011 15:37:22 -0700 Subject: [PATCH 279/287] iwlagn: split remain-on-channel If we're associated and want to do P2P at the same time, the scan for remain-on-channel is currently limited to 80ms because of the way the device will behave in that case. Instead of doing that, split up the dwell times into little pieces. It will not actually be a single big dwell time then, but will be close enough. This improves robustness of P2P in such scenarios. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +-- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 99 +++++++++++++++---------- 3 files changed, 62 insertions(+), 49 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index fcfb410aca90..baaf48616cc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2770,15 +2770,6 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, mutex_lock(&priv->shrd->mutex); - /* - * TODO: Remove this hack! Firmware needs to be updated - * to allow longer off-channel periods in scanning for - * this use case, based on a flag (and we'll need an API - * flag in the firmware when it has that). - */ - if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && duration > 80) - duration = 80; - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { err = -EBUSY; goto out; @@ -2787,6 +2778,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, priv->hw_roc_channel = channel; priv->hw_roc_chantype = channel_type; priv->hw_roc_duration = duration; + priv->hw_roc_start_notified = false; cancel_delayed_work(&priv->hw_roc_disable_work); if (!ctx->is_active) { diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index fabfc8bf4971..7f534c45d1fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1029,7 +1029,7 @@ struct iwl_priv { struct delayed_work hw_roc_disable_work; enum nl80211_channel_type hw_roc_chantype; int hw_roc_duration; - bool hw_roc_setup; + bool hw_roc_setup, hw_roc_start_notified; /* bt coex */ u8 bt_enable_flag; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 8ac6b05c6c78..8386a86e2ca2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -218,8 +218,11 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv, le32_to_cpu(notif->tsf_low), notif->status, notif->beacon_timer); - if (priv->scan_type == IWL_SCAN_ROC) + if (priv->scan_type == IWL_SCAN_ROC && + !priv->hw_roc_start_notified) { ieee80211_ready_on_channel(priv->hw); + priv->hw_roc_start_notified = true; + } } /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ @@ -310,34 +313,38 @@ static u16 iwl_get_active_dwell_time(struct iwl_priv *priv, IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); } +static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) +{ + struct iwl_rxon_context *ctx; + + /* + * If we're associated, we clamp the dwell time 98% + * of the smallest beacon interval (minus 2 * channel + * tune time) + */ + for_each_context(priv, ctx) { + u16 value; + + if (!iwl_is_associated_ctx(ctx)) + continue; + value = ctx->beacon_int; + if (!value) + value = IWL_PASSIVE_DWELL_BASE; + value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + dwell_time = min(value, dwell_time); + } + + return dwell_time; +} + static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band) { - struct iwl_rxon_context *ctx; u16 passive = (band == IEEE80211_BAND_2GHZ) ? IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; - if (iwl_is_any_associated(priv)) { - /* - * If we're associated, we clamp the maximum passive - * dwell time to be 98% of the smallest beacon interval - * (minus 2 * channel tune time) - */ - for_each_context(priv, ctx) { - u16 value; - - if (!iwl_is_associated_ctx(ctx)) - continue; - value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0; - if ((value > IWL_PASSIVE_DWELL_BASE) || !value) - value = IWL_PASSIVE_DWELL_BASE; - value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; - passive = min(value, passive); - } - } - - return passive; + return iwl_limit_dwell(priv, passive); } static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, @@ -716,29 +723,43 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) break; case IWL_SCAN_ROC: { struct iwl_scan_channel *scan_ch; + int n_chan, i; + u16 dwell; + + dwell = iwl_limit_dwell(priv, priv->hw_roc_duration); + n_chan = DIV_ROUND_UP(priv->hw_roc_duration, dwell); - scan->channel_count = 1; + scan->channel_count = n_chan; scan_ch = (void *)&scan->data[cmd_len]; - scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; - scan_ch->channel = - cpu_to_le16(priv->hw_roc_channel->hw_value); - scan_ch->active_dwell = - scan_ch->passive_dwell = - cpu_to_le16(priv->hw_roc_duration); - /* Set txpower levels to defaults */ - scan_ch->dsp_atten = 110; + for (i = 0; i < n_chan; i++) { + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + scan_ch->channel = + cpu_to_le16(priv->hw_roc_channel->hw_value); - /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level: - * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; - */ - if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ) - scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; - else - scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + if (i == n_chan - 1) + dwell = priv->hw_roc_duration - i * dwell; + + scan_ch->active_dwell = + scan_ch->passive_dwell = cpu_to_le16(dwell); + + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + + scan_ch++; } + } + break; } From 247c61d625154e18a105d663281c52376a882762 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 20 Sep 2011 15:37:23 -0700 Subject: [PATCH 280/287] iwlagn: remove the callback in host commands Before this patch, the upper layer could register a callback for each host command. This mechanism allowed the upper layer to have different callbacks for the same command ID. In fact, it wasn't used and the rx_handlers is enough: same callback for all the command with a specific command ID. The iwl_send_add_station needs the access the command that was sent while handling the response (regardless if the command was sent in SYNC or ASYNC mode). So now, all the handlers receive the host command that was sent. This implies a change in the handler signature. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 16 ++-- drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 18 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 5 +- drivers/net/wireless/iwlwifi/iwl-led.c | 1 - drivers/net/wireless/iwlwifi/iwl-rx.c | 95 ++++++++++++------- drivers/net/wireless/iwlwifi/iwl-scan.c | 25 +++-- drivers/net/wireless/iwlwifi/iwl-shared.h | 5 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 29 +++--- drivers/net/wireless/iwlwifi/iwl-sta.h | 3 + .../net/wireless/iwlwifi/iwl-trans-pcie-int.h | 12 +-- .../net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 17 +++- .../net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 42 ++------ drivers/net/wireless/iwlwifi/iwl-trans.h | 7 +- 15 files changed, 157 insertions(+), 134 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 0a1f331cb572..d30714be515b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -705,8 +705,9 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv, } } -void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { unsigned long flags; struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -715,7 +716,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { /* bt coex disabled */ - return; + return 0; } IWL_DEBUG_COEX(priv, "BT Coex notification:\n"); @@ -757,6 +758,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, spin_lock_irqsave(&priv->shrd->lock, flags); priv->bt_ci_compliance = coex->bt_ci_compliance; spin_unlock_irqrestore(&priv->shrd->lock, flags); + return 0; } void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 459b82b8a2a7..4aa414a63d6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -736,7 +736,8 @@ static void iwl_check_abort_status(struct iwl_priv *priv, } } -void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 sequence = le16_to_cpu(pkt->hdr.sequence); @@ -824,6 +825,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) iwl_check_abort_status(priv, tx_resp->frame_count, status); spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + return 0; } /** @@ -832,8 +834,9 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) * Handles block-acknowledge notification from device, which reports success * of frames sent via aggregation. */ -void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; @@ -857,7 +860,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, if (scd_flow >= hw_params(priv).max_txq_num) { IWL_ERR(priv, "BUG_ON scd_flow is bigger than number of queues\n"); - return; + return 0; } sta_id = ba_resp->sta_id; @@ -877,14 +880,14 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, "BA scd_flow %d does not match txq_id %d\n", scd_flow, agg->txq_id); spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); - return; + return 0; } if (unlikely(!agg->wait_for_ba)) { if (unlikely(ba_resp->bitmap)) IWL_ERR(priv, "Received BA when not expected\n"); spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); - return; + return 0; } IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " @@ -955,4 +958,5 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, } spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 634f18f6125a..b4e1e7c4c314 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -228,8 +228,9 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv) return iwl_trans_send_cmd(trans(priv), &cmd); } -void iwlagn_rx_calib_result(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +int iwlagn_rx_calib_result(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; @@ -262,9 +263,10 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv, default: IWL_ERR(priv, "Unknown calibration notification %d\n", hdr->op_code); - return; + return -1; } iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); + return 0; } int iwlagn_init_alive_start(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5c4f8c72ee60..2a297d1e6bc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -88,8 +88,9 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, u32 changes); /* uCode */ -void iwlagn_rx_calib_result(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); +int iwlagn_rx_calib_result(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); void iwlagn_send_prio_tbl(struct iwl_priv *priv); int iwlagn_run_init_ucode(struct iwl_priv *priv); @@ -116,9 +117,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 *ssn); int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); -void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); +int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); +int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); static inline u32 iwl_tx_status_to_mac80211(u32 status) { @@ -155,8 +158,9 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, /* bt coex */ void iwlagn_send_advance_bt_config(struct iwl_priv *priv); -void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); +int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 7f534c45d1fd..4ddaf2c63f50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -841,8 +841,9 @@ struct iwl_priv { void (*pre_rx_handler)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); - void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); + int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 7dffed186f0a..f149165e8010 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -104,7 +104,6 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) .len = { sizeof(struct iwl_led_cmd), }, .data = { led_cmd, }, .flags = CMD_ASYNC, - .callback = NULL, }; u32 reg; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 2ee61031e207..bcd7f64683aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -130,8 +130,9 @@ const char *get_cmd_string(u8 cmd) * ******************************************************************************/ -static void iwl_rx_reply_error(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_reply_error(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -142,9 +143,11 @@ static void iwl_rx_reply_error(struct iwl_priv *priv, pkt->u.err_resp.cmd_id, le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), le32_to_cpu(pkt->u.err_resp.error_info)); + return 0; } -static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_csa_notification *csa = &(pkt->u.csa_notif); @@ -156,7 +159,7 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) struct iwl_rxon_cmd *rxon = (void *)&ctx->active; if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) - return; + return 0; if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { rxon->channel = csa->channel; @@ -169,11 +172,13 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) le16_to_cpu(csa->channel)); iwl_chswitch_done(priv, false); } + return 0; } -static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); @@ -181,15 +186,17 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, if (!report->state) { IWL_DEBUG_11H(priv, "Spectrum Measure Notification: Start\n"); - return; + return 0; } memcpy(&priv->measure_report, report, sizeof(*report)); priv->measurement_status |= MEASUREMENT_READY; + return 0; } -static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_pm_sleep_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -197,10 +204,12 @@ static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif + return 0; } -static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u32 __maybe_unused len = @@ -209,10 +218,12 @@ static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, "notification for %s:\n", len, get_cmd_string(pkt->hdr.cmd)); iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); + return 0; } -static void iwl_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; @@ -233,6 +244,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) queue_work(priv->shrd->workqueue, &priv->beacon_update); + return 0; } /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ @@ -475,8 +487,9 @@ iwl_accumulative_statistics(struct iwl_priv *priv, } #endif -static void iwl_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { unsigned long stamp = jiffies; const int reg_recalib_period = 60; @@ -530,7 +543,7 @@ static void iwl_rx_statistics(struct iwl_priv *priv, WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", len, sizeof(struct iwl_bt_notif_statistics), sizeof(struct iwl_notif_statistics)); - return; + return 0; } change = common->temperature != priv->statistics.common.temperature || @@ -573,10 +586,12 @@ static void iwl_rx_statistics(struct iwl_priv *priv, } if (priv->cfg->lib->temperature && change) priv->cfg->lib->temperature(priv); + return 0; } -static void iwl_rx_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_reply_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -591,13 +606,15 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv, #endif IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); } - iwl_rx_statistics(priv, rxb); + iwl_rx_statistics(priv, rxb, cmd); + return 0; } /* Handle notification from uCode that card's power state is changing * due to software, hardware, or critical temperature RFKILL */ -static void iwl_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_card_state_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); @@ -645,10 +662,12 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); else wake_up(&priv->shrd->wait_command_queue); + return 0; } -static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_missed_beacon_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -666,18 +685,21 @@ static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) iwl_init_sensitivity(priv); } + return 0; } /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ -static void iwl_rx_reply_rx_phy(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_reply_rx_phy(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); priv->last_phy_res_valid = true; memcpy(&priv->last_phy_res, pkt->u.raw, sizeof(struct iwl_rx_phy_res)); + return 0; } /* @@ -892,8 +914,9 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, /* Called for REPLY_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ -static void iwl_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_reply_rx(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct ieee80211_hdr *header; struct ieee80211_rx_status rx_status; @@ -926,7 +949,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv, } else { if (!priv->last_phy_res_valid) { IWL_ERR(priv, "MPDU frame without cached PHY data\n"); - return; + return 0; } phy_res = &priv->last_phy_res; amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; @@ -940,14 +963,14 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv, if ((unlikely(phy_res->cfg_phy_cnt > 20))) { IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n", phy_res->cfg_phy_cnt); - return; + return 0; } if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) || !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) { IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", le32_to_cpu(rx_pkt_status)); - return; + return 0; } /* This will be used in several places later */ @@ -1008,6 +1031,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv, iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status, rxb, &rx_status); + return 0; } /** @@ -1018,7 +1042,8 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv, */ void iwl_setup_rx_handlers(struct iwl_priv *priv) { - void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); + int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); handlers = priv->rx_handlers; @@ -1028,6 +1053,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; + handlers[REPLY_ADD_STA] = iwl_add_sta_callback; /* * The same handler is used for both the REPLY to a discrete @@ -1065,9 +1091,11 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) } -void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); + int err = 0; /* * Do the notification wait before RX handlers so @@ -1102,11 +1130,12 @@ void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) * rx_handlers table. See iwl_setup_rx_handlers() */ if (priv->rx_handlers[pkt->hdr.cmd]) { priv->rx_handlers_stats[pkt->hdr.cmd]++; - priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); + err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); } else { /* No handling needed */ IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); } + return err; } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 8386a86e2ca2..2b6db24daf70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -189,8 +189,9 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) } /* Service response to REPLY_SCAN_CMD (0x80) */ -static void iwl_rx_reply_scan(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_reply_scan(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -199,11 +200,13 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv, IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); #endif + return 0; } /* Service SCAN_START_NOTIFICATION (0x82) */ -static void iwl_rx_scan_start_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_scan_start_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_scanstart_notification *notif = @@ -223,11 +226,14 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv, ieee80211_ready_on_channel(priv->hw); priv->hw_roc_start_notified = true; } + + return 0; } /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ -static void iwl_rx_scan_results_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_scan_results_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -245,11 +251,13 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, le32_to_cpu(notif->statistics[0]), le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf); #endif + return 0; } /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ -static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; @@ -289,6 +297,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, queue_work(priv->shrd->workqueue, &priv->bt_traffic_change_work); } + return 0; } void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 40186a61f20a..7abafe16de9a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -423,8 +423,11 @@ enum iwl_rxon_context_id { int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, struct iwl_cfg *cfg); void __devexit iwl_remove(struct iwl_priv * priv); +struct iwl_device_cmd; +int __must_check iwl_rx_dispatch(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); -void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); int iwlagn_hw_valid_rtc_data_addr(u32 addr); void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv, enum iwl_rxon_context_id ctx, diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index f35cfa2fe5c5..7028f907e600 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -59,8 +59,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) static int iwl_process_add_sta_resp(struct iwl_priv *priv, struct iwl_addsta_cmd *addsta, - struct iwl_rx_packet *pkt, - bool sync) + struct iwl_rx_packet *pkt) { u8 sta_id = addsta->sta.sta_id; unsigned long flags; @@ -123,15 +122,14 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, return ret; } -static void iwl_add_sta_callback(struct iwl_shared *shrd, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt) +int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd) { + struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)cmd->cmd.payload; - iwl_process_add_sta_resp(shrd->priv, addsta, pkt, false); - + return iwl_process_add_sta_resp(priv, addsta, pkt); } static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) @@ -147,7 +145,6 @@ static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags) { - struct iwl_rx_packet *pkt = NULL; int ret = 0; u8 data[sizeof(*sta)]; struct iwl_host_cmd cmd = { @@ -160,9 +157,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n", sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); - if (flags & CMD_ASYNC) - cmd.callback = iwl_add_sta_callback; - else { + if (!(flags & CMD_ASYNC)) { cmd.flags |= CMD_WANT_SKB; might_sleep(); } @@ -172,14 +167,16 @@ int iwl_send_add_sta(struct iwl_priv *priv, if (ret || (flags & CMD_ASYNC)) return ret; + /*else the command was successfully sent in SYNC mode, need to free + * the reply page */ - if (ret == 0) { - pkt = (struct iwl_rx_packet *)cmd.reply_page; - ret = iwl_process_add_sta_resp(priv, sta, pkt, true); - } iwl_free_pages(priv->shrd, cmd.reply_page); - return ret; + if (cmd.handler_status) + IWL_ERR(priv, "%s - error in the CMD response %d", __func__, + cmd.handler_status); + + return cmd.handler_status; } static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 02491b930423..1bca0dabde8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -61,6 +61,9 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + struct iwl_device_cmd *cmd); + /** * iwl_clear_driver_stations - clear knowledge of all stations from driver diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 49cd5a768280..0e7d915b547f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -118,16 +118,6 @@ struct iwl_dma_ptr { struct iwl_cmd_meta { /* only for SYNC commands, iff the reply skb is wanted */ struct iwl_host_cmd *source; - /* - * only for ASYNC commands - * (which is somewhat stupid -- look at iwl-sta.c for instance - * which duplicates a bunch of code because the callback isn't - * invoked for SYNC commands, if it were and its result passed - * through it would be simpler...) - */ - void (*callback)(struct iwl_shared *shrd, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt); u32 flags; @@ -288,7 +278,7 @@ int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id, u32 flags, u16 len, const void *data); void iwl_tx_cmd_complete(struct iwl_trans *trans, - struct iwl_rx_mem_buffer *rxb); + struct iwl_rx_mem_buffer *rxb, int handler_status); void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_tx_queue *txq, u16 byte_cnt); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 6f3f07dd817d..3ef9eac02ff4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -372,12 +372,15 @@ static void iwl_rx_handle(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; + struct iwl_device_cmd *cmd; u32 r, i; int reclaim; unsigned long flags; u8 fill_rx = 0; u32 count = 8; int total_empty; + int index, cmd_index; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ @@ -397,7 +400,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) fill_rx = 1; while (i != r) { - int len; + int len, err; u16 txq_id, sequence; rxb = rxq->queue[i]; @@ -439,7 +442,13 @@ static void iwl_rx_handle(struct iwl_trans *trans) (pkt->hdr.cmd != REPLY_TX); sequence = le16_to_cpu(pkt->hdr.sequence); - txq_id = SEQ_TO_QUEUE(le16_to_cpu(pkt->hdr.sequence)); + index = SEQ_TO_INDEX(sequence); + cmd_index = get_cmd_index(&txq->q, index); + + if (reclaim) + cmd = txq->cmd[cmd_index]; + else + cmd = NULL; /* warn if this is cmd response / notification and the uCode * didn't set the SEQ_RX_FRAME for a frame that is @@ -449,7 +458,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) "reclaim is false, SEQ_RX_FRAME unset: %s\n", get_cmd_string(pkt->hdr.cmd)); - iwl_rx_dispatch(priv(trans), rxb); + err = iwl_rx_dispatch(priv(trans), rxb, cmd); /* * XXX: After here, we should always check rxb->page @@ -464,7 +473,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) * iwl_trans_send_cmd() * as we reclaim the driver command queue */ if (rxb->page) - iwl_tx_cmd_complete(trans, rxb); + iwl_tx_cmd_complete(trans, rxb, err); else IWL_WARN(trans, "Claim null rxb?\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 031a291a13dc..48ef6c25d5bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -762,8 +762,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ if (cmd->flags & CMD_WANT_SKB) out_meta->source = cmd; - if (cmd->flags & CMD_ASYNC) - out_meta->callback = cmd->callback; /* set up the header */ @@ -894,12 +892,15 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, /** * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them * @rxb: Rx buffer to reclaim + * @handler_status: return value of the handler of the command + * (put in setup_rx_handlers) * * If an Rx buffer has an async callback associated with it the callback * will be executed. The attached skb (if present) will only be freed * if the callback returns 1 */ -void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) +void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, + int handler_status) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 sequence = le16_to_cpu(pkt->hdr.sequence); @@ -936,9 +937,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { meta->source->reply_page = (unsigned long)rxb_addr(rxb); + meta->source->handler_status = handler_status; rxb->page = NULL; - } else if (meta->callback) - meta->callback(trans->shrd, cmd, pkt); + } spin_lock_irqsave(&trans->hcmd_lock, flags); @@ -958,30 +959,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) #define HOST_COMPLETE_TIMEOUT (2 * HZ) -static void iwl_generic_cmd_callback(struct iwl_shared *shrd, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt) -{ - if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(shrd->trans, "Bad return from %s (0x%08X)\n", - get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); - return; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - switch (cmd->hdr.cmd) { - case REPLY_TX_LINK_QUALITY_CMD: - case SENSITIVITY_CMD: - IWL_DEBUG_HC_DUMP(shrd->trans, "back from %s (0x%08X)\n", - get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); - break; - default: - IWL_DEBUG_HC(shrd->trans, "back from %s (0x%08X)\n", - get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); - } -#endif -} - static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { int ret; @@ -990,9 +967,6 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (WARN_ON(cmd->flags & CMD_WANT_SKB)) return -EINVAL; - /* Assign a generic callback if one is not provided */ - if (!cmd->callback) - cmd->callback = iwl_generic_cmd_callback; if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) return -EBUSY; @@ -1014,10 +988,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) lockdep_assert_held(&trans->shrd->mutex); - /* A synchronous command can not have a callback set. */ - if (WARN_ON(cmd->callback)) - return -EINVAL; - IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 5b6e6842d5fc..ddb7741bed66 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -120,6 +120,8 @@ enum iwl_hcmd_dataflag { * struct iwl_host_cmd - Host command to the uCode * @data: array of chunks that composes the data of the host command * @reply_page: pointer to the page that holds the response to the host command + * @handler_status: return value of the handler of the command + * (put in setup_rx_handlers) - valid for SYNC mode only * @callback: * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC * @len: array of the lenths of the chunks in data @@ -129,9 +131,8 @@ enum iwl_hcmd_dataflag { struct iwl_host_cmd { const void *data[IWL_MAX_CMD_TFDS]; unsigned long reply_page; - void (*callback)(struct iwl_shared *shrd, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt); + int handler_status; + u32 flags; u16 len[IWL_MAX_CMD_TFDS]; u8 dataflags[IWL_MAX_CMD_TFDS]; From 132f98c2dc702940ed2bb58e7aa48432c2c62f7b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 20 Sep 2011 15:37:24 -0700 Subject: [PATCH 281/287] iwlagn: simplify the iwl_device_cmd layout This simplifies both the transport layer and the upper layer. Kill the union in the device command, which avoids the funny syntax we had: cmd->cmd.payload. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 12 ++++++++---- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 10 +--------- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 4aa414a63d6b..abb702da700d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -322,7 +322,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) goto drop_unlock_sta; memset(dev_cmd, 0, sizeof(*dev_cmd)); - tx_cmd = &dev_cmd->cmd.tx; + tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; /* Copy MAC header from skb into command buffer */ memcpy(tx_cmd->hdr, hdr, hdr_len); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7028f907e600..580a4d702ff3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -127,7 +127,7 @@ int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_addsta_cmd *addsta = - (struct iwl_addsta_cmd *)cmd->cmd.payload; + (struct iwl_addsta_cmd *) cmd->payload; return iwl_process_add_sta_resp(priv, addsta, pkt); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 48ef6c25d5bc..ee7059dcbbcb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -59,13 +59,15 @@ void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, u8 sta_id = 0; u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; __le16 bc_ent; + struct iwl_tx_cmd *tx_cmd = + (struct iwl_tx_cmd *) txq->cmd[txq->q.write_ptr]->payload; scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); - sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id; - sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl; + sta_id = tx_cmd->sta_id; + sec_ctl = tx_cmd->sec_ctl; switch (sec_ctl & TX_CMD_SEC_MSK) { case TX_CMD_SEC_CCM: @@ -353,11 +355,13 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, int read_ptr = txq->q.read_ptr; u8 sta_id = 0; __le16 bc_ent; + struct iwl_tx_cmd *tx_cmd = + (struct iwl_tx_cmd *) txq->cmd[txq->q.read_ptr]->payload; WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); if (txq_id != trans->shrd->cmd_queue) - sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; + sta_id = tx_cmd->sta_id; bc_ent = cpu_to_le16(1 | (sta_id << 12)); scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; @@ -773,7 +777,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) /* and copy the data that needs to be copied */ - cmd_dest = &out_cmd->cmd.payload[0]; + cmd_dest = out_cmd->payload; for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ca13eebbdb4f..dbb7eb3715c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1043,7 +1043,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct iwl_tx_cmd *tx_cmd = &dev_cmd->cmd.tx; + struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; struct iwl_cmd_meta *out_meta; struct iwl_tx_queue *txq; struct iwl_queue *q; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index ddb7741bed66..c5923125c3f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -97,15 +97,7 @@ enum { */ struct iwl_device_cmd { struct iwl_cmd_header hdr; /* uCode API */ - union { - u32 flags; - u8 val8; - u16 val16; - u32 val32; - struct iwl_tx_cmd tx; - struct iwl6000_channel_switch_cmd chswitch; - u8 payload[DEF_CMD_PAYLOAD_SIZE]; - } __packed cmd; + u8 payload[DEF_CMD_PAYLOAD_SIZE]; } __packed; #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) From edb5c2f38d3eef3a45457846a76732586f6bcf5c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 20 Sep 2011 15:37:25 -0700 Subject: [PATCH 282/287] iwlagn: remove uneeded declaration This has been removed but the declaration hasn't. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 0e7d915b547f..2b6756e8b8f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -275,8 +275,6 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, dma_addr_t addr, u16 len, u8 reset); int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); -int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id, - u32 flags, u16 len, const void *data); void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, int handler_status); void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, From 08ecf10441c79ebebe5ce6b6ff9a06c586f5895c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 20 Sep 2011 15:37:26 -0700 Subject: [PATCH 283/287] iwlagn: pending frames musn't be incremented if agg is on During my works on the transport layer I removed code that updated a local variable (is_agg) that is needed to keep the pending_frames count up to date. Fix this. Also, there should be no way to have a packet with TX_CTL_AMPDU set while the internal aggregation state machine is not in AGG_ON state. Add a WARN_ON to ensure that. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 3 +++ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index abb702da700d..8c0f07f56149 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -313,6 +313,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); } + if (info->flags & IEEE80211_TX_CTL_AMPDU) + is_agg = true; + /* irqs already disabled/saved above when locking priv->shrd->lock */ spin_lock(&priv->shrd->sta_lock); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index dbb7eb3715c4..3e69e877e72c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1096,8 +1096,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, hdr->seq_ctrl |= cpu_to_le16(seq_number); seq_number += 0x10; /* aggregation is on for this */ - if (info->flags & IEEE80211_TX_CTL_AMPDU && - tid_data->agg.state == IWL_AGG_ON) { + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + WARN_ON(tid_data->agg.state != IWL_AGG_ON); txq_id = tid_data->agg.txq_id; is_agg = true; } From 5adcb81037558aa545676f78dea2b2ce6c3b5819 Mon Sep 17 00:00:00 2001 From: Amit Beka Date: Tue, 20 Sep 2011 15:37:27 -0700 Subject: [PATCH 284/287] iwlagn: remove duplicate list init iwl_trans_rx_alloc is only called from iwl_rx_init, so no need to init the lists twice. Signed-off-by: Amit Beka Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 3e69e877e72c..b78ac65b2779 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -83,8 +83,6 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans) memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); spin_lock_init(&rxq->lock); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); if (WARN_ON(rxq->bd || rxq->rb_stts)) return -EINVAL; From aef0ba54ecb961ae559106540f37ab734b64410d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 21 Sep 2011 10:13:29 +0300 Subject: [PATCH 285/287] mwifiex: add a kfree() to an error path We're not likely to hit this small memory leak, but lets fix it anyway to keep the static checkers happy. Signed-off-by: Dan Carpenter Acked-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_ioctl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index eb569fa9adba..215c65ae23ee 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -203,6 +203,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, beacon_ie = kmemdup(bss->information_elements, bss->len_beacon_ies, GFP_KERNEL); if (!beacon_ie) { + kfree(bss_desc); dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); return -ENOMEM; } From 49753128d8fc976576c497c81962cf1ae57174aa Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 21 Sep 2011 10:13:56 +0300 Subject: [PATCH 286/287] mwifiex: remove unneeded NULL check We dereference "rate" on the lines before so the checks here are too late to help. This function is only called from mwifiex_dump_station_info() and "rate" is always a non-NULL pointer so the check can be removed. Signed-off-by: Dan Carpenter Acked-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 215c65ae23ee..1df5ef6b4953 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -868,10 +868,10 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, ret = mwifiex_rate_ioctl_cfg(priv, rate); if (!ret) { - if (rate && rate->is_rate_auto) + if (rate->is_rate_auto) rate->rate = mwifiex_index_to_data_rate(priv->tx_rate, priv->tx_htinfo); - else if (rate) + else rate->rate = priv->data_rate; } else { ret = -1; From ed46fdfc54d2d4523fdd727708fe0b9e2be993cc Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 21 Sep 2011 11:02:37 -0700 Subject: [PATCH 287/287] nfc: NFC_WILINK depends on NFC_NCI nwcwilink.c uses nci_*() interfaces, so it should depend on NFC_NCI. Fixes these build errors: ERROR: "nci_register_device" [drivers/nfc/nfcwilink.ko] undefined! ERROR: "nci_allocate_device" [drivers/nfc/nfcwilink.ko] undefined! ERROR: "nci_recv_frame" [drivers/nfc/nfcwilink.ko] undefined! ERROR: "nci_free_device" [drivers/nfc/nfcwilink.ko] undefined! ERROR: "nci_unregister_device" [drivers/nfc/nfcwilink.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: John W. Linville --- drivers/nfc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig index 8a56fd3da989..5af959274d4e 100644 --- a/drivers/nfc/Kconfig +++ b/drivers/nfc/Kconfig @@ -29,7 +29,7 @@ config NFC_PN533 config NFC_WILINK tristate "Texas Instruments NFC WiLink driver" - depends on TI_ST + depends on TI_ST && NFC_NCI help This enables the NFC driver for Texas Instrument's BT/FM/GPS/NFC combo devices. This makes use of shared transport line discipline