Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next

This commit is contained in:
David S. Miller 2012-03-05 16:39:02 -05:00
commit 7c1e51a34a
191 changed files with 8784 additions and 8878 deletions

View File

@ -1568,7 +1568,6 @@ F: drivers/net/ethernet/broadcom/tg3.*
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
M: Brett Rudley <brudley@broadcom.com> M: Brett Rudley <brudley@broadcom.com>
M: Henry Ptasinski <henryp@broadcom.com>
M: Roland Vossen <rvossen@broadcom.com> M: Roland Vossen <rvossen@broadcom.com>
M: Arend van Spriel <arend@broadcom.com> M: Arend van Spriel <arend@broadcom.com>
M: Franky (Zhenhui) Lin <frankyl@broadcom.com> M: Franky (Zhenhui) Lin <frankyl@broadcom.com>

View File

@ -140,23 +140,23 @@ static int ath_ahb_probe(struct platform_device *pdev)
if (bcfg->devid >= AR5K_SREV_AR2315_R6) { if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
/* Enable WMAC AHB arbitration */ /* Enable WMAC AHB arbitration */
reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN; reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
__raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
/* Enable global WMAC swapping */ /* Enable global WMAC swapping */
reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP); reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
reg |= AR5K_AR2315_BYTESWAP_WMAC; reg |= AR5K_AR2315_BYTESWAP_WMAC;
__raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
} else { } else {
/* Enable WMAC DMA access (assuming 5312 or 231x*/ /* Enable WMAC DMA access (assuming 5312 or 231x*/
/* TODO: check other platforms */ /* TODO: check other platforms */
reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE); reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
if (to_platform_device(ah->dev)->id == 0) if (to_platform_device(ah->dev)->id == 0)
reg |= AR5K_AR5312_ENABLE_WLAN0; reg |= AR5K_AR5312_ENABLE_WLAN0;
else else
reg |= AR5K_AR5312_ENABLE_WLAN1; reg |= AR5K_AR5312_ENABLE_WLAN1;
__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
/* /*
* On a dual-band AR5312, the multiband radio is only * On a dual-band AR5312, the multiband radio is only
@ -203,17 +203,17 @@ static int ath_ahb_remove(struct platform_device *pdev)
if (bcfg->devid >= AR5K_SREV_AR2315_R6) { if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
/* Disable WMAC AHB arbitration */ /* Disable WMAC AHB arbitration */
reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN; reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
__raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
} else { } else {
/*Stop DMA access */ /*Stop DMA access */
reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE); reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
if (to_platform_device(ah->dev)->id == 0) if (to_platform_device(ah->dev)->id == 0)
reg &= ~AR5K_AR5312_ENABLE_WLAN0; reg &= ~AR5K_AR5312_ENABLE_WLAN0;
else else
reg &= ~AR5K_AR5312_ENABLE_WLAN1; reg &= ~AR5K_AR5312_ENABLE_WLAN1;
__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
} }
ath5k_deinit_ah(ah); ath5k_deinit_ah(ah);

View File

@ -1656,12 +1656,12 @@ static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
{ {
return __raw_readl(ath5k_ahb_reg(ah, reg)); return ioread32(ath5k_ahb_reg(ah, reg));
} }
static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
{ {
__raw_writel(val, ath5k_ahb_reg(ah, reg)); iowrite32(val, ath5k_ahb_reg(ah, reg));
} }
#else #else

View File

@ -473,14 +473,14 @@ ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
} }
/* Put BB/MAC into reset */ /* Put BB/MAC into reset */
regval = __raw_readl(reg); regval = ioread32(reg);
__raw_writel(regval | val, reg); iowrite32(regval | val, reg);
regval = __raw_readl(reg); regval = ioread32(reg);
usleep_range(100, 150); usleep_range(100, 150);
/* Bring BB/MAC out of reset */ /* Bring BB/MAC out of reset */
__raw_writel(regval & ~val, reg); iowrite32(regval & ~val, reg);
regval = __raw_readl(reg); regval = ioread32(reg);
/* /*
* Reset configuration register (for hw byte-swap). Note that this * Reset configuration register (for hw byte-swap). Note that this

View File

@ -2269,8 +2269,42 @@ static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
return ret; return ret;
} }
static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, static int ath6kl_set_ies(struct ath6kl_vif *vif,
struct beacon_parameters *info, bool add) struct cfg80211_beacon_data *info)
{
struct ath6kl *ar = vif->ar;
int res;
if (info->beacon_ies) {
res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
WMI_FRAME_BEACON,
info->beacon_ies,
info->beacon_ies_len);
if (res)
return res;
}
if (info->proberesp_ies) {
res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
info->proberesp_ies_len);
if (res)
return res;
}
if (info->assocresp_ies) {
res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
WMI_FRAME_ASSOC_RESP,
info->assocresp_ies,
info->assocresp_ies_len);
if (res)
return res;
}
return 0;
}
static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ap_settings *info)
{ {
struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev);
@ -2281,7 +2315,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
int res; int res;
int i, ret; int i, ret;
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
if (!ath6kl_cfg80211_ready(vif)) if (!ath6kl_cfg80211_ready(vif))
return -EIO; return -EIO;
@ -2289,31 +2323,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
if (vif->next_mode != AP_NETWORK) if (vif->next_mode != AP_NETWORK)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (info->beacon_ies) { res = ath6kl_set_ies(vif, &info->beacon);
res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
WMI_FRAME_BEACON,
info->beacon_ies,
info->beacon_ies_len);
if (res)
return res;
}
if (info->proberesp_ies) {
res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
info->proberesp_ies_len);
if (res)
return res;
}
if (info->assocresp_ies) {
res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
WMI_FRAME_ASSOC_RESP,
info->assocresp_ies,
info->assocresp_ies_len);
if (res)
return res;
}
if (!add)
return 0;
ar->ap_mode_bkey.valid = false; ar->ap_mode_bkey.valid = false;
@ -2322,13 +2332,13 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
* info->dtim_period * info->dtim_period
*/ */
if (info->head == NULL) if (info->beacon.head == NULL)
return -EINVAL; return -EINVAL;
mgmt = (struct ieee80211_mgmt *) info->head; mgmt = (struct ieee80211_mgmt *) info->beacon.head;
ies = mgmt->u.beacon.variable; ies = mgmt->u.beacon.variable;
if (ies > info->head + info->head_len) if (ies > info->beacon.head + info->beacon.head_len)
return -EINVAL; return -EINVAL;
ies_len = info->head + info->head_len - ies; ies_len = info->beacon.head + info->beacon.head_len - ies;
if (info->ssid == NULL) if (info->ssid == NULL)
return -EINVAL; return -EINVAL;
@ -2436,19 +2446,21 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
return 0; return 0;
} }
static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev, static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
struct beacon_parameters *info) struct cfg80211_beacon_data *beacon)
{ {
return ath6kl_ap_beacon(wiphy, dev, info, true); struct ath6kl_vif *vif = netdev_priv(dev);
if (!ath6kl_cfg80211_ready(vif))
return -EIO;
if (vif->next_mode != AP_NETWORK)
return -EOPNOTSUPP;
return ath6kl_set_ies(vif, beacon);
} }
static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev, static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
struct beacon_parameters *info)
{
return ath6kl_ap_beacon(wiphy, dev, info, false);
}
static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
{ {
struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev);
@ -2783,9 +2795,9 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
.resume = __ath6kl_cfg80211_resume, .resume = __ath6kl_cfg80211_resume,
#endif #endif
.set_channel = ath6kl_set_channel, .set_channel = ath6kl_set_channel,
.add_beacon = ath6kl_add_beacon, .start_ap = ath6kl_start_ap,
.set_beacon = ath6kl_set_beacon, .change_beacon = ath6kl_change_beacon,
.del_beacon = ath6kl_del_beacon, .stop_ap = ath6kl_stop_ap,
.del_station = ath6kl_del_station, .del_station = ath6kl_del_station,
.change_station = ath6kl_change_station, .change_station = ath6kl_change_station,
.remain_on_channel = ath6kl_remain_on_channel, .remain_on_channel = ath6kl_remain_on_channel,

View File

@ -6,6 +6,14 @@ config ATH9K_DFS_DEBUGFS
def_bool y def_bool y
depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
config ATH9K_BTCOEX_SUPPORT
bool "Atheros bluetooth coexistence support"
depends on (ATH9K || ATH9K_HTC)
default y
---help---
Say Y, if you want to use the ath9k/ath9k_htc radios together with
Bluetooth modules in the same system.
config ATH9K config ATH9K
tristate "Atheros 802.11n wireless cards support" tristate "Atheros 802.11n wireless cards support"
depends on MAC80211 depends on MAC80211
@ -81,14 +89,6 @@ config ATH9K_RATE_CONTROL
Say Y, if you want to use the ath9k specific rate control Say Y, if you want to use the ath9k specific rate control
module instead of minstrel_ht. module instead of minstrel_ht.
config ATH9K_BTCOEX_SUPPORT
bool "Atheros ath9k bluetooth coexistence support"
depends on ATH9K
default y
---help---
Say Y, if you want to use the ath9k radios together with
Bluetooth modules in the same system.
config ATH9K_HTC config ATH9K_HTC
tristate "Atheros HTC based wireless cards support" tristate "Atheros HTC based wireless cards support"
depends on USB && MAC80211 depends on USB && MAC80211

View File

@ -3,9 +3,9 @@ ath9k-y += beacon.o \
init.o \ init.o \
main.o \ main.o \
recv.o \ recv.o \
xmit.o \ xmit.o
mci.o \
ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
ath9k-$(CONFIG_ATH9K_PCI) += pci.o ath9k-$(CONFIG_ATH9K_PCI) += pci.o
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
@ -31,14 +31,14 @@ ath9k_hw-y:= \
eeprom_4k.o \ eeprom_4k.o \
eeprom_9287.o \ eeprom_9287.o \
ani.o \ ani.o \
btcoex.o \
mac.o \ mac.o \
ar9002_mac.o \ ar9002_mac.o \
ar9003_mac.o \ ar9003_mac.o \
ar9003_eeprom.o \ ar9003_eeprom.o \
ar9003_paprd.o \ ar9003_paprd.o
ar9003_mci.o
ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
ar9003_mci.o
obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o

View File

@ -459,97 +459,6 @@ static const u32 ar5416Common_9100[][2] = {
{0x0000a3e0, 0x000001ce}, {0x0000a3e0, 0x000001ce},
}; };
static const u32 ar5416Bank0_9100[][2] = {
/* Addr allmodes */
{0x000098b0, 0x1e5795e5},
{0x000098e0, 0x02008020},
};
static const u32 ar5416BB_RfGain_9100[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{0x00009a00, 0x00000000, 0x00000000},
{0x00009a04, 0x00000040, 0x00000040},
{0x00009a08, 0x00000080, 0x00000080},
{0x00009a0c, 0x000001a1, 0x00000141},
{0x00009a10, 0x000001e1, 0x00000181},
{0x00009a14, 0x00000021, 0x000001c1},
{0x00009a18, 0x00000061, 0x00000001},
{0x00009a1c, 0x00000168, 0x00000041},
{0x00009a20, 0x000001a8, 0x000001a8},
{0x00009a24, 0x000001e8, 0x000001e8},
{0x00009a28, 0x00000028, 0x00000028},
{0x00009a2c, 0x00000068, 0x00000068},
{0x00009a30, 0x00000189, 0x000000a8},
{0x00009a34, 0x000001c9, 0x00000169},
{0x00009a38, 0x00000009, 0x000001a9},
{0x00009a3c, 0x00000049, 0x000001e9},
{0x00009a40, 0x00000089, 0x00000029},
{0x00009a44, 0x00000170, 0x00000069},
{0x00009a48, 0x000001b0, 0x00000190},
{0x00009a4c, 0x000001f0, 0x000001d0},
{0x00009a50, 0x00000030, 0x00000010},
{0x00009a54, 0x00000070, 0x00000050},
{0x00009a58, 0x00000191, 0x00000090},
{0x00009a5c, 0x000001d1, 0x00000151},
{0x00009a60, 0x00000011, 0x00000191},
{0x00009a64, 0x00000051, 0x000001d1},
{0x00009a68, 0x00000091, 0x00000011},
{0x00009a6c, 0x000001b8, 0x00000051},
{0x00009a70, 0x000001f8, 0x00000198},
{0x00009a74, 0x00000038, 0x000001d8},
{0x00009a78, 0x00000078, 0x00000018},
{0x00009a7c, 0x00000199, 0x00000058},
{0x00009a80, 0x000001d9, 0x00000098},
{0x00009a84, 0x00000019, 0x00000159},
{0x00009a88, 0x00000059, 0x00000199},
{0x00009a8c, 0x00000099, 0x000001d9},
{0x00009a90, 0x000000d9, 0x00000019},
{0x00009a94, 0x000000f9, 0x00000059},
{0x00009a98, 0x000000f9, 0x00000099},
{0x00009a9c, 0x000000f9, 0x000000d9},
{0x00009aa0, 0x000000f9, 0x000000f9},
{0x00009aa4, 0x000000f9, 0x000000f9},
{0x00009aa8, 0x000000f9, 0x000000f9},
{0x00009aac, 0x000000f9, 0x000000f9},
{0x00009ab0, 0x000000f9, 0x000000f9},
{0x00009ab4, 0x000000f9, 0x000000f9},
{0x00009ab8, 0x000000f9, 0x000000f9},
{0x00009abc, 0x000000f9, 0x000000f9},
{0x00009ac0, 0x000000f9, 0x000000f9},
{0x00009ac4, 0x000000f9, 0x000000f9},
{0x00009ac8, 0x000000f9, 0x000000f9},
{0x00009acc, 0x000000f9, 0x000000f9},
{0x00009ad0, 0x000000f9, 0x000000f9},
{0x00009ad4, 0x000000f9, 0x000000f9},
{0x00009ad8, 0x000000f9, 0x000000f9},
{0x00009adc, 0x000000f9, 0x000000f9},
{0x00009ae0, 0x000000f9, 0x000000f9},
{0x00009ae4, 0x000000f9, 0x000000f9},
{0x00009ae8, 0x000000f9, 0x000000f9},
{0x00009aec, 0x000000f9, 0x000000f9},
{0x00009af0, 0x000000f9, 0x000000f9},
{0x00009af4, 0x000000f9, 0x000000f9},
{0x00009af8, 0x000000f9, 0x000000f9},
{0x00009afc, 0x000000f9, 0x000000f9},
};
static const u32 ar5416Bank1_9100[][2] = {
/* Addr allmodes */
{0x000098b0, 0x02108421},
{0x000098ec, 0x00000008},
};
static const u32 ar5416Bank2_9100[][2] = {
/* Addr allmodes */
{0x000098b0, 0x0e73ff17},
{0x000098e0, 0x00000420},
};
static const u32 ar5416Bank3_9100[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{0x000098f0, 0x01400018, 0x01c00018},
};
static const u32 ar5416Bank6_9100[][3] = { static const u32 ar5416Bank6_9100[][3] = {
/* Addr 5G_HT20 5G_HT40 */ /* Addr 5G_HT20 5G_HT40 */
{0x0000989c, 0x00000000, 0x00000000}, {0x0000989c, 0x00000000, 0x00000000},
@ -624,13 +533,6 @@ static const u32 ar5416Bank6TPC_9100[][3] = {
{0x000098d0, 0x0000000f, 0x0010000f}, {0x000098d0, 0x0000000f, 0x0010000f},
}; };
static const u32 ar5416Bank7_9100[][2] = {
/* Addr allmodes */
{0x0000989c, 0x00000500},
{0x0000989c, 0x00000800},
{0x000098cc, 0x0000000e},
};
static const u32 ar5416Addac_9100[][2] = { static const u32 ar5416Addac_9100[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x0000989c, 0x00000000}, {0x0000989c, 0x00000000},
@ -1113,178 +1015,6 @@ static const u32 ar5416Common_9160[][2] = {
{0x0000a3e0, 0x000001ce}, {0x0000a3e0, 0x000001ce},
}; };
static const u32 ar5416Bank0_9160[][2] = {
/* Addr allmodes */
{0x000098b0, 0x1e5795e5},
{0x000098e0, 0x02008020},
};
static const u32 ar5416BB_RfGain_9160[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{0x00009a00, 0x00000000, 0x00000000},
{0x00009a04, 0x00000040, 0x00000040},
{0x00009a08, 0x00000080, 0x00000080},
{0x00009a0c, 0x000001a1, 0x00000141},
{0x00009a10, 0x000001e1, 0x00000181},
{0x00009a14, 0x00000021, 0x000001c1},
{0x00009a18, 0x00000061, 0x00000001},
{0x00009a1c, 0x00000168, 0x00000041},
{0x00009a20, 0x000001a8, 0x000001a8},
{0x00009a24, 0x000001e8, 0x000001e8},
{0x00009a28, 0x00000028, 0x00000028},
{0x00009a2c, 0x00000068, 0x00000068},
{0x00009a30, 0x00000189, 0x000000a8},
{0x00009a34, 0x000001c9, 0x00000169},
{0x00009a38, 0x00000009, 0x000001a9},
{0x00009a3c, 0x00000049, 0x000001e9},
{0x00009a40, 0x00000089, 0x00000029},
{0x00009a44, 0x00000170, 0x00000069},
{0x00009a48, 0x000001b0, 0x00000190},
{0x00009a4c, 0x000001f0, 0x000001d0},
{0x00009a50, 0x00000030, 0x00000010},
{0x00009a54, 0x00000070, 0x00000050},
{0x00009a58, 0x00000191, 0x00000090},
{0x00009a5c, 0x000001d1, 0x00000151},
{0x00009a60, 0x00000011, 0x00000191},
{0x00009a64, 0x00000051, 0x000001d1},
{0x00009a68, 0x00000091, 0x00000011},
{0x00009a6c, 0x000001b8, 0x00000051},
{0x00009a70, 0x000001f8, 0x00000198},
{0x00009a74, 0x00000038, 0x000001d8},
{0x00009a78, 0x00000078, 0x00000018},
{0x00009a7c, 0x00000199, 0x00000058},
{0x00009a80, 0x000001d9, 0x00000098},
{0x00009a84, 0x00000019, 0x00000159},
{0x00009a88, 0x00000059, 0x00000199},
{0x00009a8c, 0x00000099, 0x000001d9},
{0x00009a90, 0x000000d9, 0x00000019},
{0x00009a94, 0x000000f9, 0x00000059},
{0x00009a98, 0x000000f9, 0x00000099},
{0x00009a9c, 0x000000f9, 0x000000d9},
{0x00009aa0, 0x000000f9, 0x000000f9},
{0x00009aa4, 0x000000f9, 0x000000f9},
{0x00009aa8, 0x000000f9, 0x000000f9},
{0x00009aac, 0x000000f9, 0x000000f9},
{0x00009ab0, 0x000000f9, 0x000000f9},
{0x00009ab4, 0x000000f9, 0x000000f9},
{0x00009ab8, 0x000000f9, 0x000000f9},
{0x00009abc, 0x000000f9, 0x000000f9},
{0x00009ac0, 0x000000f9, 0x000000f9},
{0x00009ac4, 0x000000f9, 0x000000f9},
{0x00009ac8, 0x000000f9, 0x000000f9},
{0x00009acc, 0x000000f9, 0x000000f9},
{0x00009ad0, 0x000000f9, 0x000000f9},
{0x00009ad4, 0x000000f9, 0x000000f9},
{0x00009ad8, 0x000000f9, 0x000000f9},
{0x00009adc, 0x000000f9, 0x000000f9},
{0x00009ae0, 0x000000f9, 0x000000f9},
{0x00009ae4, 0x000000f9, 0x000000f9},
{0x00009ae8, 0x000000f9, 0x000000f9},
{0x00009aec, 0x000000f9, 0x000000f9},
{0x00009af0, 0x000000f9, 0x000000f9},
{0x00009af4, 0x000000f9, 0x000000f9},
{0x00009af8, 0x000000f9, 0x000000f9},
{0x00009afc, 0x000000f9, 0x000000f9},
};
static const u32 ar5416Bank1_9160[][2] = {
/* Addr allmodes */
{0x000098b0, 0x02108421},
{0x000098ec, 0x00000008},
};
static const u32 ar5416Bank2_9160[][2] = {
/* Addr allmodes */
{0x000098b0, 0x0e73ff17},
{0x000098e0, 0x00000420},
};
static const u32 ar5416Bank3_9160[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{0x000098f0, 0x01400018, 0x01c00018},
};
static const u32 ar5416Bank6_9160[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{0x0000989c, 0x00000000, 0x00000000},
{0x0000989c, 0x00000000, 0x00000000},
{0x0000989c, 0x00000000, 0x00000000},
{0x0000989c, 0x00e00000, 0x00e00000},
{0x0000989c, 0x005e0000, 0x005e0000},
{0x0000989c, 0x00120000, 0x00120000},
{0x0000989c, 0x00620000, 0x00620000},
{0x0000989c, 0x00020000, 0x00020000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x40ff0000, 0x40ff0000},
{0x0000989c, 0x005f0000, 0x005f0000},
{0x0000989c, 0x00870000, 0x00870000},
{0x0000989c, 0x00f90000, 0x00f90000},
{0x0000989c, 0x007b0000, 0x007b0000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x00f50000, 0x00f50000},
{0x0000989c, 0x00dc0000, 0x00dc0000},
{0x0000989c, 0x00110000, 0x00110000},
{0x0000989c, 0x006100a8, 0x006100a8},
{0x0000989c, 0x004210a2, 0x004210a2},
{0x0000989c, 0x0014008f, 0x0014008f},
{0x0000989c, 0x00c40003, 0x00c40003},
{0x0000989c, 0x003000f2, 0x003000f2},
{0x0000989c, 0x00440016, 0x00440016},
{0x0000989c, 0x00410040, 0x00410040},
{0x0000989c, 0x0001805e, 0x0001805e},
{0x0000989c, 0x0000c0ab, 0x0000c0ab},
{0x0000989c, 0x000000f1, 0x000000f1},
{0x0000989c, 0x00002081, 0x00002081},
{0x0000989c, 0x000000d4, 0x000000d4},
{0x000098d0, 0x0000000f, 0x0010000f},
};
static const u32 ar5416Bank6TPC_9160[][3] = {
/* Addr 5G_HT20 5G_HT40 */
{0x0000989c, 0x00000000, 0x00000000},
{0x0000989c, 0x00000000, 0x00000000},
{0x0000989c, 0x00000000, 0x00000000},
{0x0000989c, 0x00e00000, 0x00e00000},
{0x0000989c, 0x005e0000, 0x005e0000},
{0x0000989c, 0x00120000, 0x00120000},
{0x0000989c, 0x00620000, 0x00620000},
{0x0000989c, 0x00020000, 0x00020000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x40ff0000, 0x40ff0000},
{0x0000989c, 0x005f0000, 0x005f0000},
{0x0000989c, 0x00870000, 0x00870000},
{0x0000989c, 0x00f90000, 0x00f90000},
{0x0000989c, 0x007b0000, 0x007b0000},
{0x0000989c, 0x00ff0000, 0x00ff0000},
{0x0000989c, 0x00f50000, 0x00f50000},
{0x0000989c, 0x00dc0000, 0x00dc0000},
{0x0000989c, 0x00110000, 0x00110000},
{0x0000989c, 0x006100a8, 0x006100a8},
{0x0000989c, 0x00423022, 0x00423022},
{0x0000989c, 0x2014008f, 0x2014008f},
{0x0000989c, 0x00c40002, 0x00c40002},
{0x0000989c, 0x003000f2, 0x003000f2},
{0x0000989c, 0x00440016, 0x00440016},
{0x0000989c, 0x00410040, 0x00410040},
{0x0000989c, 0x0001805e, 0x0001805e},
{0x0000989c, 0x0000c0ab, 0x0000c0ab},
{0x0000989c, 0x000000e1, 0x000000e1},
{0x0000989c, 0x00007080, 0x00007080},
{0x0000989c, 0x000000d4, 0x000000d4},
{0x000098d0, 0x0000000f, 0x0010000f},
};
static const u32 ar5416Bank7_9160[][2] = {
/* Addr allmodes */
{0x0000989c, 0x00000500},
{0x0000989c, 0x00000800},
{0x000098cc, 0x0000000e},
};
static const u32 ar5416Addac_9160[][2] = { static const u32 ar5416Addac_9160[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x0000989c, 0x00000000}, {0x0000989c, 0x00000000},

View File

@ -35,11 +35,11 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
ARRAY_SIZE(ar9271Common_9271), 2); ARRAY_SIZE(ar9271Common_9271), 2);
INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271, INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
ar9271Common_normal_cck_fir_coeff_9271, ar9287Common_normal_cck_fir_coeff_9287_1_1,
ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2); ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2);
INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271, INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
ar9271Common_japan_2484_cck_fir_coeff_9271, ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2); ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2);
INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
ar9271Modes_9271_1_0_only, ar9271Modes_9271_1_0_only,
ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5);
@ -54,53 +54,31 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
return; return;
} }
if (ah->config.pcie_clock_req)
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_off_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
else
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_always_on_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
if (AR_SREV_9287_11_OR_LATER(ah)) { if (AR_SREV_9287_11_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
ARRAY_SIZE(ar9287Modes_9287_1_1), 5); ARRAY_SIZE(ar9287Modes_9287_1_1), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1, INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
ARRAY_SIZE(ar9287Common_9287_1_1), 2); ARRAY_SIZE(ar9287Common_9287_1_1), 2);
if (ah->config.pcie_clock_req)
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9287PciePhy_clkreq_off_L1_9287_1_1,
ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
else
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
2);
} else if (AR_SREV_9285_12_OR_LATER(ah)) { } else if (AR_SREV_9285_12_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
ARRAY_SIZE(ar9285Modes_9285_1_2), 5); ARRAY_SIZE(ar9285Modes_9285_1_2), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
ARRAY_SIZE(ar9285Common_9285_1_2), 2); ARRAY_SIZE(ar9285Common_9285_1_2), 2);
if (ah->config.pcie_clock_req) {
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_off_L1_9285_1_2,
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
} else {
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
2);
}
} else if (AR_SREV_9280_20_OR_LATER(ah)) { } else if (AR_SREV_9280_20_OR_LATER(ah)) {
INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
ARRAY_SIZE(ar9280Modes_9280_2), 5); ARRAY_SIZE(ar9280Modes_9280_2), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
ARRAY_SIZE(ar9280Common_9280_2), 2); ARRAY_SIZE(ar9280Common_9280_2), 2);
if (ah->config.pcie_clock_req) {
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_off_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
} else {
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_always_on_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
}
INIT_INI_ARRAY(&ah->iniModesAdditional, INIT_INI_ARRAY(&ah->iniModesAdditional,
ar9280Modes_fast_clock_9280_2, ar9280Modes_fast_clock_9280_2,
ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
@ -109,22 +87,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
ARRAY_SIZE(ar5416Modes_9160), 5); ARRAY_SIZE(ar5416Modes_9160), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
ARRAY_SIZE(ar5416Common_9160), 2); ARRAY_SIZE(ar5416Common_9160), 2);
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
ARRAY_SIZE(ar5416Bank0_9160), 2);
INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
ARRAY_SIZE(ar5416Bank1_9160), 2);
INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
ARRAY_SIZE(ar5416Bank2_9160), 2);
INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
ARRAY_SIZE(ar5416Bank3_9160), 3);
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
ARRAY_SIZE(ar5416Bank6_9160), 3);
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
ARRAY_SIZE(ar5416Bank7_9160), 2);
if (AR_SREV_9160_11(ah)) { if (AR_SREV_9160_11(ah)) {
INIT_INI_ARRAY(&ah->iniAddac, INIT_INI_ARRAY(&ah->iniAddac,
ar5416Addac_9160_1_1, ar5416Addac_9160_1_1,
@ -138,22 +100,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
ARRAY_SIZE(ar5416Modes_9100), 5); ARRAY_SIZE(ar5416Modes_9100), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
ARRAY_SIZE(ar5416Common_9100), 2); ARRAY_SIZE(ar5416Common_9100), 2);
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
ARRAY_SIZE(ar5416Bank0_9100), 2);
INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
ARRAY_SIZE(ar5416Bank1_9100), 2);
INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
ARRAY_SIZE(ar5416Bank2_9100), 2);
INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
ARRAY_SIZE(ar5416Bank3_9100), 3);
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100, INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
ARRAY_SIZE(ar5416Bank6_9100), 3); ARRAY_SIZE(ar5416Bank6_9100), 3);
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
ARRAY_SIZE(ar5416Bank7_9100), 2);
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100, INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
ARRAY_SIZE(ar5416Addac_9100), 2); ARRAY_SIZE(ar5416Addac_9100), 2);
} else { } else {
@ -161,24 +109,37 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
ARRAY_SIZE(ar5416Modes), 5); ARRAY_SIZE(ar5416Modes), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
ARRAY_SIZE(ar5416Common), 2); ARRAY_SIZE(ar5416Common), 2);
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
ARRAY_SIZE(ar5416Bank0), 2); ARRAY_SIZE(ar5416Bank6TPC), 3);
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
ARRAY_SIZE(ar5416Addac), 2);
}
if (!AR_SREV_9280_20_OR_LATER(ah)) {
/* Common for AR5416, AR913x, AR9160 */
INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain, INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
ARRAY_SIZE(ar5416BB_RfGain), 3); ARRAY_SIZE(ar5416BB_RfGain), 3);
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
ARRAY_SIZE(ar5416Bank0), 2);
INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1, INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
ARRAY_SIZE(ar5416Bank1), 2); ARRAY_SIZE(ar5416Bank1), 2);
INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2, INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
ARRAY_SIZE(ar5416Bank2), 2); ARRAY_SIZE(ar5416Bank2), 2);
INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3, INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
ARRAY_SIZE(ar5416Bank3), 3); ARRAY_SIZE(ar5416Bank3), 3);
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
ARRAY_SIZE(ar5416Bank6), 3);
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
ARRAY_SIZE(ar5416Bank6TPC), 3);
INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7, INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
ARRAY_SIZE(ar5416Bank7), 2); ARRAY_SIZE(ar5416Bank7), 2);
INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
ARRAY_SIZE(ar5416Addac), 2); /* Common for AR5416, AR9160 */
if (!AR_SREV_9100(ah))
INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
ARRAY_SIZE(ar5416Bank6), 3);
/* Common for AR913x, AR9160 */
if (!AR_SREV_5416(ah))
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
} }
/* iniAddac needs to be modified for these chips */ /* iniAddac needs to be modified for these chips */

View File

@ -925,34 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
{0x00004044, 0x00000000}, {0x00004044, 0x00000000},
}; };
static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
/* Addr allmodes */
{0x00004040, 0x9248fd00},
{0x00004040, 0x24924924},
{0x00004040, 0xa8000019},
{0x00004040, 0x13160820},
{0x00004040, 0xe5980560},
{0x00004040, 0xc01dcffd},
{0x00004040, 0x1aaabe41},
{0x00004040, 0xbe105554},
{0x00004040, 0x00043007},
{0x00004044, 0x00000000},
};
static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = {
/* Addr allmodes */
{0x00004040, 0x9248fd00},
{0x00004040, 0x24924924},
{0x00004040, 0xa8000019},
{0x00004040, 0x13160820},
{0x00004040, 0xe5980560},
{0x00004040, 0xc01dcffc},
{0x00004040, 0x1aaabe41},
{0x00004040, 0xbe105554},
{0x00004040, 0x00043007},
{0x00004044, 0x00000000},
};
static const u32 ar9285Modes_9285_1_2[][5] = { static const u32 ar9285Modes_9285_1_2[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
@ -1743,34 +1715,6 @@ static const u32 ar9285Modes_XE2_0_high_power[][5] = {
{0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7},
}; };
static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
/* Addr allmodes */
{0x00004040, 0x9248fd00},
{0x00004040, 0x24924924},
{0x00004040, 0xa8000019},
{0x00004040, 0x13160820},
{0x00004040, 0xe5980560},
{0x00004040, 0xc01dcffd},
{0x00004040, 0x1aaabe41},
{0x00004040, 0xbe105554},
{0x00004040, 0x00043007},
{0x00004044, 0x00000000},
};
static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
/* Addr allmodes */
{0x00004040, 0x9248fd00},
{0x00004040, 0x24924924},
{0x00004040, 0xa8000019},
{0x00004040, 0x13160820},
{0x00004040, 0xe5980560},
{0x00004040, 0xc01dcffc},
{0x00004040, 0x1aaabe41},
{0x00004040, 0xbe105554},
{0x00004040, 0x00043007},
{0x00004044, 0x00000000},
};
static const u32 ar9287Modes_9287_1_1[][5] = { static const u32 ar9287Modes_9287_1_1[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160}, {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160},
@ -2512,34 +2456,6 @@ static const u32 ar9287Modes_rx_gain_9287_1_1[][5] = {
{0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067}, {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067},
}; };
static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
/* Addr allmodes */
{0x00004040, 0x9248fd00},
{0x00004040, 0x24924924},
{0x00004040, 0xa8000019},
{0x00004040, 0x13160820},
{0x00004040, 0xe5980560},
{0x00004040, 0xc01dcffd},
{0x00004040, 0x1aaabe41},
{0x00004040, 0xbe105554},
{0x00004040, 0x00043007},
{0x00004044, 0x00000000},
};
static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
/* Addr allmodes */
{0x00004040, 0x9248fd00},
{0x00004040, 0x24924924},
{0x00004040, 0xa8000019},
{0x00004040, 0x13160820},
{0x00004040, 0xe5980560},
{0x00004040, 0xc01dcffc},
{0x00004040, 0x1aaabe41},
{0x00004040, 0xbe105554},
{0x00004040, 0x00043007},
{0x00004044, 0x00000000},
};
static const u32 ar9271Modes_9271[][5] = { static const u32 ar9271Modes_9271[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
@ -3176,20 +3092,6 @@ static const u32 ar9271Common_9271[][2] = {
{0x0000d384, 0xf3307ff0}, {0x0000d384, 0xf3307ff0},
}; };
static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = {
/* Addr allmodes */
{0x0000a1f4, 0x00fffeff},
{0x0000a1f8, 0x00f5f9ff},
{0x0000a1fc, 0xb79f6427},
};
static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
/* Addr allmodes */
{0x0000a1f4, 0x00000000},
{0x0000a1f8, 0xefff0301},
{0x0000a1fc, 0xca9228ee},
};
static const u32 ar9271Modes_9271_1_0_only[][5] = { static const u32 ar9271Modes_9271_1_0_only[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311},

View File

@ -925,7 +925,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_cal_data *caldata = ah->caldata; struct ath9k_hw_cal_data *caldata = ah->caldata;
struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
bool txiqcal_done = false, txclcal_done = false; bool txiqcal_done = false, txclcal_done = false;
bool is_reusable = true, status = true; bool is_reusable = true, status = true;
bool run_rtt_cal = false, run_agc_cal; bool run_rtt_cal = false, run_agc_cal;
@ -998,30 +997,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
} else if (caldata && !caldata->done_txiqcal_once) } else if (caldata && !caldata->done_txiqcal_once)
run_agc_cal = true; run_agc_cal = true;
if (mci && IS_CHAN_2GHZ(chan) && if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
(mci_hw->bt_state == MCI_BT_AWAKE) && ar9003_mci_init_cal_req(ah, &is_reusable);
run_agc_cal &&
!(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) {
u32 pld[4] = {0, 0, 0, 0};
/* send CAL_REQ only when BT is AWAKE. */
ath_dbg(common, MCI, "MCI send WLAN_CAL_REQ 0x%x\n",
mci_hw->wlan_cal_seq);
MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ);
pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++;
ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
/* Wait BT_CAL_GRANT for 50ms */
ath_dbg(common, MCI, "MCI wait for BT_CAL_GRANT\n");
if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
ath_dbg(common, MCI, "MCI got BT_CAL_GRANT\n");
else {
is_reusable = false;
ath_dbg(common, MCI, "\nMCI BT is not responding\n");
}
}
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
@ -1041,19 +1018,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
0, AH_WAIT_TIMEOUT); 0, AH_WAIT_TIMEOUT);
} }
if (mci && IS_CHAN_2GHZ(chan) && if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
(mci_hw->bt_state == MCI_BT_AWAKE) && ar9003_mci_init_cal_done(ah);
run_agc_cal &&
!(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) {
u32 pld[4] = {0, 0, 0, 0};
ath_dbg(common, MCI, "MCI Send WLAN_CAL_DONE 0x%x\n",
mci_hw->wlan_cal_done);
MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE);
pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++;
ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
}
if (rtt && !run_rtt_cal) { if (rtt && !run_rtt_cal) {
agc_ctrl |= agc_supp_cals; agc_ctrl |= agc_supp_cals;

View File

@ -3603,10 +3603,6 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
if (AR_SREV_9462(ah)) { if (AR_SREV_9462(ah)) {
if (AR_SREV_9462_10(ah)) {
value &= ~AR_SWITCH_TABLE_COM_SPDT;
value |= 0x00100000;
}
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
AR_SWITCH_TABLE_COM_AR9462_ALL, value); AR_SWITCH_TABLE_COM_AR9462_ALL, value);
} else } else

View File

@ -22,7 +22,6 @@
#include "ar9330_1p1_initvals.h" #include "ar9330_1p1_initvals.h"
#include "ar9330_1p2_initvals.h" #include "ar9330_1p2_initvals.h"
#include "ar9580_1p0_initvals.h" #include "ar9580_1p0_initvals.h"
#include "ar9462_1p0_initvals.h"
#include "ar9462_2p0_initvals.h" #include "ar9462_2p0_initvals.h"
/* General hardware code for the AR9003 hadware family */ /* General hardware code for the AR9003 hadware family */
@ -264,63 +263,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
ar9485_1_1_pcie_phy_clkreq_disable_L1, ar9485_1_1_pcie_phy_clkreq_disable_L1,
ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
2); 2);
} else if (AR_SREV_9462_10(ah)) {
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_1p0_mac_core,
ARRAY_SIZE(ar9462_1p0_mac_core), 2);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
ar9462_1p0_mac_postamble,
ARRAY_SIZE(ar9462_1p0_mac_postamble),
5);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
ar9462_1p0_baseband_core,
ARRAY_SIZE(ar9462_1p0_baseband_core),
2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
ar9462_1p0_baseband_postamble,
ARRAY_SIZE(ar9462_1p0_baseband_postamble), 5);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
ar9462_1p0_radio_core,
ARRAY_SIZE(ar9462_1p0_radio_core), 2);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
ar9462_1p0_radio_postamble,
ARRAY_SIZE(ar9462_1p0_radio_postamble), 5);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
ar9462_1p0_soc_preamble,
ARRAY_SIZE(ar9462_1p0_soc_preamble), 2);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
ar9462_1p0_soc_postamble,
ARRAY_SIZE(ar9462_1p0_soc_postamble), 5);
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_rx_gain_table_1p0,
ARRAY_SIZE(ar9462_common_rx_gain_table_1p0), 2);
/* Awake -> Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9462_pcie_phy_clkreq_disable_L1_1p0,
ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
2);
/* Sleep -> Awake Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
ar9462_pcie_phy_clkreq_disable_L1_1p0,
ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
2);
INIT_INI_ARRAY(&ah->iniModesAdditional,
ar9462_modes_fast_clock_1p0,
ARRAY_SIZE(ar9462_modes_fast_clock_1p0), 3);
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
AR9462_BB_CTX_COEFJ(1p0),
ARRAY_SIZE(AR9462_BB_CTX_COEFJ(1p0)), 2);
} else if (AR_SREV_9462_20(ah)) { } else if (AR_SREV_9462_20(ah)) {
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
@ -537,11 +479,6 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
ar9580_1p0_lowest_ob_db_tx_gain_table, ar9580_1p0_lowest_ob_db_tx_gain_table,
ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table), ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
5); 5);
else if (AR_SREV_9462_10(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9462_modes_low_ob_db_tx_gain_table_1p0,
ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_1p0),
5);
else if (AR_SREV_9462_20(ah)) else if (AR_SREV_9462_20(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9462_modes_low_ob_db_tx_gain_table_2p0, ar9462_modes_low_ob_db_tx_gain_table_2p0,
@ -581,11 +518,6 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
ar9580_1p0_high_ob_db_tx_gain_table, ar9580_1p0_high_ob_db_tx_gain_table,
ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table), ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
5); 5);
else if (AR_SREV_9462_10(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9462_modes_high_ob_db_tx_gain_table_1p0,
ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_1p0),
5);
else if (AR_SREV_9462_20(ah)) else if (AR_SREV_9462_20(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9462_modes_high_ob_db_tx_gain_table_2p0, ar9462_modes_high_ob_db_tx_gain_table_2p0,
@ -712,11 +644,6 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
ar9580_1p0_rx_gain_table, ar9580_1p0_rx_gain_table,
ARRAY_SIZE(ar9580_1p0_rx_gain_table), ARRAY_SIZE(ar9580_1p0_rx_gain_table),
2); 2);
else if (AR_SREV_9462_10(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_rx_gain_table_1p0,
ARRAY_SIZE(ar9462_common_rx_gain_table_1p0),
2);
else if (AR_SREV_9462_20(ah)) else if (AR_SREV_9462_20(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain, INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_rx_gain_table_2p0, ar9462_common_rx_gain_table_2p0,
@ -751,11 +678,6 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
ar9485Common_wo_xlna_rx_gain_1_1, ar9485Common_wo_xlna_rx_gain_1_1,
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
2); 2);
else if (AR_SREV_9462_10(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_wo_xlna_rx_gain_table_1p0,
ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_1p0),
2);
else if (AR_SREV_9462_20(ah)) else if (AR_SREV_9462_20(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain, INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_wo_xlna_rx_gain_table_2p0, ar9462_common_wo_xlna_rx_gain_table_2p0,
@ -775,11 +697,7 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
{ {
if (AR_SREV_9462_10(ah)) if (AR_SREV_9462_20(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_mixed_rx_gain_table_1p0,
ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_1p0), 2);
else if (AR_SREV_9462_20(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain, INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_mixed_rx_gain_table_2p0, ar9462_common_mixed_rx_gain_table_2p0,
ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2); ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);

View File

@ -16,6 +16,7 @@
#include <linux/export.h> #include <linux/export.h>
#include "hw.h" #include "hw.h"
#include "ar9003_mac.h" #include "ar9003_mac.h"
#include "ar9003_mci.h"
static void ar9003_hw_rx_enable(struct ath_hw *hw) static void ar9003_hw_rx_enable(struct ath_hw *hw)
{ {
@ -28,11 +29,14 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
struct ar9003_txc *ads = ds; struct ar9003_txc *ads = ds;
int checksum = 0; int checksum = 0;
u32 val, ctl12, ctl17; u32 val, ctl12, ctl17;
u8 desc_len;
desc_len = (AR_SREV_9462(ah) ? 0x18 : 0x17);
val = (ATHEROS_VENDOR_ID << AR_DescId_S) | val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
(1 << AR_TxRxDesc_S) | (1 << AR_TxRxDesc_S) |
(1 << AR_CtrlStat_S) | (1 << AR_CtrlStat_S) |
(i->qcu << AR_TxQcuNum_S) | 0x17; (i->qcu << AR_TxQcuNum_S) | desc_len;
checksum += val; checksum += val;
ACCESS_ONCE(ads->info) = val; ACCESS_ONCE(ads->info) = val;
@ -81,6 +85,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
ads->ctl20 = 0; ads->ctl20 = 0;
ads->ctl21 = 0; ads->ctl21 = 0;
ads->ctl22 = 0; ads->ctl22 = 0;
ads->ctl23 = 0;
ctl17 = SM(i->keytype, AR_EncrType); ctl17 = SM(i->keytype, AR_EncrType);
if (!i->is_first) { if (!i->is_first) {
@ -176,7 +181,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
u32 mask2 = 0; u32 mask2 = 0;
struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
u32 sync_cause = 0, async_cause; u32 sync_cause = 0, async_cause;
async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE); async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
@ -298,32 +302,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
ar9003_hw_bb_watchdog_read(ah); ar9003_hw_bb_watchdog_read(ah);
} }
if (async_cause & AR_INTR_ASYNC_MASK_MCI) { if (async_cause & AR_INTR_ASYNC_MASK_MCI)
u32 raw_intr, rx_msg_intr; ar9003_mci_get_isr(ah, masked);
rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);
if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef))
ath_dbg(common, MCI,
"MCI gets 0xdeadbeef during MCI int processing new raw_intr=0x%08x, new rx_msg_raw=0x%08x, raw_intr=0x%08x, rx_msg_raw=0x%08x\n",
raw_intr, rx_msg_intr, mci->raw_intr,
mci->rx_msg_intr);
else {
mci->rx_msg_intr |= rx_msg_intr;
mci->raw_intr |= raw_intr;
*masked |= ATH9K_INT_MCI;
if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
mci->cont_status =
REG_READ(ah, AR_MCI_CONT_STATUS);
REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
ath_dbg(common, MCI, "AR_INTR_SYNC_MCI\n");
}
}
if (sync_cause) { if (sync_cause) {
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
@ -530,7 +510,11 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
*/ */
if (rxsp->status11 & AR_CRCErr) if (rxsp->status11 & AR_CRCErr)
rxs->rs_status |= ATH9K_RXERR_CRC; rxs->rs_status |= ATH9K_RXERR_CRC;
else if (rxsp->status11 & AR_PHYErr) { else if (rxsp->status11 & AR_DecryptCRCErr)
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
else if (rxsp->status11 & AR_MichaelErr)
rxs->rs_status |= ATH9K_RXERR_MIC;
if (rxsp->status11 & AR_PHYErr) {
phyerr = MS(rxsp->status11, AR_PHYErrCode); phyerr = MS(rxsp->status11, AR_PHYErrCode);
/* /*
* If we reach a point here where AR_PostDelimCRCErr is * If we reach a point here where AR_PostDelimCRCErr is
@ -552,11 +536,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
rxs->rs_status |= ATH9K_RXERR_PHY; rxs->rs_status |= ATH9K_RXERR_PHY;
rxs->rs_phyerr = phyerr; rxs->rs_phyerr = phyerr;
} }
};
} else if (rxsp->status11 & AR_DecryptCRCErr)
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
else if (rxsp->status11 & AR_MichaelErr)
rxs->rs_status |= ATH9K_RXERR_MIC;
} }
if (rxsp->status11 & AR_KeyMiss) if (rxsp->status11 & AR_KeyMiss)

View File

@ -92,7 +92,8 @@ struct ar9003_txc {
u32 ctl20; /* DMA control 20 */ u32 ctl20; /* DMA control 20 */
u32 ctl21; /* DMA control 21 */ u32 ctl21; /* DMA control 21 */
u32 ctl22; /* DMA control 22 */ u32 ctl22; /* DMA control 22 */
u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */ u32 ctl23; /* DMA control 23 */
u32 pad[8]; /* pad to cache line (128 bytes/32 dwords) */
} __packed __aligned(4); } __packed __aligned(4);
struct ar9003_txs { struct ar9003_txs {

File diff suppressed because it is too large Load Diff

View File

@ -99,4 +99,237 @@ enum mci_gpm_coex_bt_update_flags_op {
ATH_MCI_CONFIG_MCI_OBS_BT) ATH_MCI_CONFIG_MCI_OBS_BT)
#define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F #define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F
enum mci_message_header { /* length of payload */
MCI_LNA_CTRL = 0x10, /* len = 0 */
MCI_CONT_NACK = 0x20, /* len = 0 */
MCI_CONT_INFO = 0x30, /* len = 4 */
MCI_CONT_RST = 0x40, /* len = 0 */
MCI_SCHD_INFO = 0x50, /* len = 16 */
MCI_CPU_INT = 0x60, /* len = 4 */
MCI_SYS_WAKING = 0x70, /* len = 0 */
MCI_GPM = 0x80, /* len = 16 */
MCI_LNA_INFO = 0x90, /* len = 1 */
MCI_LNA_STATE = 0x94,
MCI_LNA_TAKE = 0x98,
MCI_LNA_TRANS = 0x9c,
MCI_SYS_SLEEPING = 0xa0, /* len = 0 */
MCI_REQ_WAKE = 0xc0, /* len = 0 */
MCI_DEBUG_16 = 0xfe, /* len = 2 */
MCI_REMOTE_RESET = 0xff /* len = 16 */
};
enum ath_mci_gpm_coex_profile_type {
MCI_GPM_COEX_PROFILE_UNKNOWN,
MCI_GPM_COEX_PROFILE_RFCOMM,
MCI_GPM_COEX_PROFILE_A2DP,
MCI_GPM_COEX_PROFILE_HID,
MCI_GPM_COEX_PROFILE_BNEP,
MCI_GPM_COEX_PROFILE_VOICE,
MCI_GPM_COEX_PROFILE_MAX
};
/* MCI GPM/Coex opcode/type definitions */
enum {
MCI_GPM_COEX_W_GPM_PAYLOAD = 1,
MCI_GPM_COEX_B_GPM_TYPE = 4,
MCI_GPM_COEX_B_GPM_OPCODE = 5,
/* MCI_GPM_WLAN_CAL_REQ, MCI_GPM_WLAN_CAL_DONE */
MCI_GPM_WLAN_CAL_W_SEQUENCE = 2,
/* MCI_GPM_COEX_VERSION_QUERY */
/* MCI_GPM_COEX_VERSION_RESPONSE */
MCI_GPM_COEX_B_MAJOR_VERSION = 6,
MCI_GPM_COEX_B_MINOR_VERSION = 7,
/* MCI_GPM_COEX_STATUS_QUERY */
MCI_GPM_COEX_B_BT_BITMAP = 6,
MCI_GPM_COEX_B_WLAN_BITMAP = 7,
/* MCI_GPM_COEX_HALT_BT_GPM */
MCI_GPM_COEX_B_HALT_STATE = 6,
/* MCI_GPM_COEX_WLAN_CHANNELS */
MCI_GPM_COEX_B_CHANNEL_MAP = 6,
/* MCI_GPM_COEX_BT_PROFILE_INFO */
MCI_GPM_COEX_B_PROFILE_TYPE = 6,
MCI_GPM_COEX_B_PROFILE_LINKID = 7,
MCI_GPM_COEX_B_PROFILE_STATE = 8,
MCI_GPM_COEX_B_PROFILE_ROLE = 9,
MCI_GPM_COEX_B_PROFILE_RATE = 10,
MCI_GPM_COEX_B_PROFILE_VOTYPE = 11,
MCI_GPM_COEX_H_PROFILE_T = 12,
MCI_GPM_COEX_B_PROFILE_W = 14,
MCI_GPM_COEX_B_PROFILE_A = 15,
/* MCI_GPM_COEX_BT_STATUS_UPDATE */
MCI_GPM_COEX_B_STATUS_TYPE = 6,
MCI_GPM_COEX_B_STATUS_LINKID = 7,
MCI_GPM_COEX_B_STATUS_STATE = 8,
/* MCI_GPM_COEX_BT_UPDATE_FLAGS */
MCI_GPM_COEX_W_BT_FLAGS = 6,
MCI_GPM_COEX_B_BT_FLAGS_OP = 10
};
enum mci_gpm_subtype {
MCI_GPM_BT_CAL_REQ = 0,
MCI_GPM_BT_CAL_GRANT = 1,
MCI_GPM_BT_CAL_DONE = 2,
MCI_GPM_WLAN_CAL_REQ = 3,
MCI_GPM_WLAN_CAL_GRANT = 4,
MCI_GPM_WLAN_CAL_DONE = 5,
MCI_GPM_COEX_AGENT = 0x0c,
MCI_GPM_RSVD_PATTERN = 0xfe,
MCI_GPM_RSVD_PATTERN32 = 0xfefefefe,
MCI_GPM_BT_DEBUG = 0xff
};
enum mci_bt_state {
MCI_BT_SLEEP,
MCI_BT_AWAKE,
MCI_BT_CAL_START,
MCI_BT_CAL
};
/* Type of state query */
enum mci_state_type {
MCI_STATE_ENABLE,
MCI_STATE_INIT_GPM_OFFSET,
MCI_STATE_NEXT_GPM_OFFSET,
MCI_STATE_LAST_GPM_OFFSET,
MCI_STATE_BT,
MCI_STATE_SET_BT_SLEEP,
MCI_STATE_SET_BT_AWAKE,
MCI_STATE_SET_BT_CAL_START,
MCI_STATE_SET_BT_CAL,
MCI_STATE_LAST_SCHD_MSG_OFFSET,
MCI_STATE_REMOTE_SLEEP,
MCI_STATE_CONT_RSSI_POWER,
MCI_STATE_CONT_PRIORITY,
MCI_STATE_CONT_TXRX,
MCI_STATE_RESET_REQ_WAKE,
MCI_STATE_SEND_WLAN_COEX_VERSION,
MCI_STATE_SET_BT_COEX_VERSION,
MCI_STATE_SEND_WLAN_CHANNELS,
MCI_STATE_SEND_VERSION_QUERY,
MCI_STATE_SEND_STATUS_QUERY,
MCI_STATE_NEED_FLUSH_BT_INFO,
MCI_STATE_SET_CONCUR_TX_PRI,
MCI_STATE_RECOVER_RX,
MCI_STATE_NEED_FTP_STOMP,
MCI_STATE_NEED_TUNING,
MCI_STATE_DEBUG,
MCI_STATE_MAX
};
enum mci_gpm_coex_opcode {
MCI_GPM_COEX_VERSION_QUERY,
MCI_GPM_COEX_VERSION_RESPONSE,
MCI_GPM_COEX_STATUS_QUERY,
MCI_GPM_COEX_HALT_BT_GPM,
MCI_GPM_COEX_WLAN_CHANNELS,
MCI_GPM_COEX_BT_PROFILE_INFO,
MCI_GPM_COEX_BT_STATUS_UPDATE,
MCI_GPM_COEX_BT_UPDATE_FLAGS
};
#define MCI_GPM_NOMORE 0
#define MCI_GPM_MORE 1
#define MCI_GPM_INVALID 0xffffffff
#define MCI_GPM_RECYCLE(_p_gpm) do { \
*(((u32 *)_p_gpm) + MCI_GPM_COEX_W_GPM_PAYLOAD) = \
MCI_GPM_RSVD_PATTERN32; \
} while (0)
#define MCI_GPM_TYPE(_p_gpm) \
(*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) & 0xff)
#define MCI_GPM_OPCODE(_p_gpm) \
(*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) & 0xff)
#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type) do { \
*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_cal_type) & 0xff;\
} while (0)
#define MCI_GPM_SET_TYPE_OPCODE(_p_gpm, _type, _opcode) do { \
*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_type) & 0xff; \
*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) = (_opcode) & 0xff;\
} while (0)
#define MCI_GPM_IS_CAL_TYPE(_type) ((_type) <= MCI_GPM_WLAN_CAL_DONE)
/*
* Functions that are available to the MCI driver core.
*/
bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
u32 *payload, u8 len, bool wait_done,
bool check_bt);
u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data);
void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr);
void ar9003_mci_cleanup(struct ath_hw *ah);
void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
u32 *rx_msg_intr);
/*
* These functions are used by ath9k_hw.
*/
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
static inline bool ar9003_mci_is_ready(struct ath_hw *ah)
{
return ah->btcoex_hw.mci.ready;
}
void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep);
void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable);
void ar9003_mci_init_cal_done(struct ath_hw *ah);
void ar9003_mci_set_full_sleep(struct ath_hw *ah);
void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done);
void ar9003_mci_check_bt(struct ath_hw *ah);
bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan);
int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata);
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep);
void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked);
#else
static inline bool ar9003_mci_is_ready(struct ath_hw *ah)
{
return false;
}
static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
{
}
static inline void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable)
{
}
static inline void ar9003_mci_init_cal_done(struct ath_hw *ah)
{
}
static inline void ar9003_mci_set_full_sleep(struct ath_hw *ah)
{
}
static inline void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done)
{
}
static inline void ar9003_mci_check_bt(struct ath_hw *ah)
{
}
static inline bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
{
return false;
}
static inline int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata)
{
return 0;
}
static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep)
{
}
static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
{
}
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
#endif #endif

View File

@ -1099,13 +1099,20 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
{ {
ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
if (AR_SREV_9330(ah))
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ;
else
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ; ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ; ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
if (AR_SREV_9330(ah))
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ;
if (AR_SREV_9462(ah)) {
ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ;
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9462_2GHZ;
ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ;
ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9462_5GHZ;
}
} }
/* /*

View File

@ -325,13 +325,18 @@
#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200) #define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200)
#define AR_PHY_CCA_NOM_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -110) #define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110
#define AR_PHY_CCA_NOM_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -115) #define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -125) #define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -125) #define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100
#define AR_PHY_CCA_NOM_VAL_9462_2GHZ -127
#define AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ -127
#define AR_PHY_CCA_NOM_VAL_9462_5GHZ -127
#define AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ -127
#define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118 #define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118
/* /*
@ -612,16 +617,14 @@
#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4) #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_2_B0 (AR_SM_BASE + 0x4b8)
#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc) #define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc)
#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \ #define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + 0x4c4))
0x4c0 : 0x4c4)) #define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + 0x4c8))
#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
0x4c4 : 0x4c8))
#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) #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_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
#define AR_PHY_65NM_CH0_SYNTH4 0x1608c #define AR_PHY_65NM_CH0_SYNTH4 0x1608c
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1 #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1)
#define AR_PHY_65NM_CH0_SYNTH7 0x16098 #define AR_PHY_65NM_CH0_SYNTH7 0x16098
#define AR_PHY_65NM_CH0_BIAS1 0x160c0 #define AR_PHY_65NM_CH0_BIAS1 0x160c0
#define AR_PHY_65NM_CH0_BIAS2 0x160c4 #define AR_PHY_65NM_CH0_BIAS2 0x160c4

File diff suppressed because it is too large Load Diff

View File

@ -98,14 +98,6 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
{0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
}; };
static const u32 ar9462_2p0_mac_core_emulation[][2] = {
/* Addr allmodes */
{0x00000030, 0x000e0085},
{0x00000044, 0x00000008},
{0x0000805c, 0xffffc7ff},
{0x00008344, 0xaa4a105b},
};
static const u32 ar9462_common_rx_gain_table_2p0[][2] = { static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x0000a000, 0x00010000}, {0x0000a000, 0x00010000},
@ -380,349 +372,6 @@ static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
{0x00018c08, 0x0003580c}, {0x00018c08, 0x0003580c},
}; };
static const u32 ar9462_2p0_sys3ant[][2] = {
/* Addr allmodes */
{0x00063280, 0x00040807},
{0x00063284, 0x104ccccc},
};
static const u32 ar9462_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 ar9462_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 ar9462_2p0_radio_postamble_sys3ant[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
{0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
};
static const u32 ar9462_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 ar9462_2p0_radio_postamble_sys2ant[][5] = { static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
@ -1356,24 +1005,6 @@ static const u32 ar9462_2p0_radio_core[][2] = {
{0x00016548, 0x000080c0}, {0x00016548, 0x000080c0},
}; };
static const u32 ar9462_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 ar9462_2p0_soc_preamble[][2] = { static const u32 ar9462_2p0_soc_preamble[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x00007020, 0x00000000}, {0x00007020, 0x00000000},
@ -1381,11 +1012,6 @@ static const u32 ar9462_2p0_soc_preamble[][2] = {
{0x00007038, 0x000004c2}, {0x00007038, 0x000004c2},
}; };
static const u32 ar9462_2p0_sys2ant[][2] = {
/* Addr allmodes */
{0x00063120, 0x00801980},
};
static const u32 ar9462_2p0_mac_core[][2] = { static const u32 ar9462_2p0_mac_core[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x00000008, 0x00000000}, {0x00000008, 0x00000000},
@ -1822,75 +1448,6 @@ static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
{0x0000b1fc, 0x00000196}, {0x0000b1fc, 0x00000196},
}; };
static const u32 ar9462_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, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83},
{0x0000a550, 0x5d025ef6, 0x5d025ef6, 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 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = { static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
/* Addr allmodes */ /* Addr allmodes */
{0x000018c0, 0x10101010}, {0x000018c0, 0x10101010},
@ -1903,26 +1460,4 @@ static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
{0x000018dc, 0x10101010}, {0x000018dc, 0x10101010},
}; };
static const u32 ar9462_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_9462_2P0_H */ #endif /* INITVALS_9462_2P0_H */

View File

@ -454,9 +454,39 @@ struct ath_btcoex {
struct ath_mci_profile mci; struct ath_mci_profile mci;
}; };
int ath_init_btcoex_timer(struct ath_softc *sc); #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
int ath9k_init_btcoex(struct ath_softc *sc);
void ath9k_deinit_btcoex(struct ath_softc *sc);
void ath9k_start_btcoex(struct ath_softc *sc);
void ath9k_stop_btcoex(struct ath_softc *sc);
void ath9k_btcoex_timer_resume(struct ath_softc *sc); void ath9k_btcoex_timer_resume(struct ath_softc *sc);
void ath9k_btcoex_timer_pause(struct ath_softc *sc); void ath9k_btcoex_timer_pause(struct ath_softc *sc);
void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status);
u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen);
#else
static inline int ath9k_init_btcoex(struct ath_softc *sc)
{
return 0;
}
static inline void ath9k_deinit_btcoex(struct ath_softc *sc)
{
}
static inline void ath9k_start_btcoex(struct ath_softc *sc)
{
}
static inline void ath9k_stop_btcoex(struct ath_softc *sc)
{
}
static inline void ath9k_btcoex_handle_interrupt(struct ath_softc *sc,
u32 status)
{
}
static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc,
u32 max_4ms_framelen)
{
return 0;
}
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
/********************/ /********************/
/* LED Control */ /* LED Control */
@ -650,8 +680,11 @@ struct ath_softc {
struct ath_beacon_config cur_beacon_conf; struct ath_beacon_config cur_beacon_conf;
struct delayed_work tx_complete_work; struct delayed_work tx_complete_work;
struct delayed_work hw_pll_work; struct delayed_work hw_pll_work;
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
struct ath_btcoex btcoex; struct ath_btcoex btcoex;
struct ath_mci_coex mci_coex; struct ath_mci_coex mci_coex;
#endif
struct ath_descdma txsdma; struct ath_descdma txsdma;

View File

@ -68,9 +68,6 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
u32 i, idx; u32 i, idx;
bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
if (AR_SREV_9300_20_OR_LATER(ah)) if (AR_SREV_9300_20_OR_LATER(ah))
rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
@ -98,13 +95,44 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
} }
EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw); EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);
void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
/*
* Check if BTCOEX is globally disabled.
*/
if (!common->btcoex_enabled) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
return;
}
if (AR_SREV_9462(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
} else if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
if (AR_SREV_9285(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9285;
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
}
}
}
EXPORT_SYMBOL(ath9k_hw_btcoex_init_scheme);
void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah) void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah)
{ {
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
/* connect bt_active to baseband */ /* connect bt_active to baseband */
REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
@ -127,9 +155,6 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
{ {
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
/* btcoex 3-wire */ /* btcoex 3-wire */
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB | (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
@ -152,13 +177,34 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah)
} }
EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire); EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire);
void ath9k_hw_btcoex_init_mci(struct ath_hw *ah)
{
ah->btcoex_hw.mci.ready = false;
ah->btcoex_hw.mci.bt_state = 0;
ah->btcoex_hw.mci.bt_ver_major = 3;
ah->btcoex_hw.mci.bt_ver_minor = 0;
ah->btcoex_hw.mci.bt_version_known = false;
ah->btcoex_hw.mci.update_2g5g = true;
ah->btcoex_hw.mci.is_2g = true;
ah->btcoex_hw.mci.wlan_channels_update = false;
ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000;
ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff;
ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff;
ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff;
ah->btcoex_hw.mci.query_bt = true;
ah->btcoex_hw.mci.unhalt_bt_gpm = true;
ah->btcoex_hw.mci.halted_bt_gpm = false;
ah->btcoex_hw.mci.need_flush_btinfo = false;
ah->btcoex_hw.mci.wlan_cal_seq = 0;
ah->btcoex_hw.mci.wlan_cal_done = 0;
ah->btcoex_hw.mci.config = 0x2201;
}
EXPORT_SYMBOL(ath9k_hw_btcoex_init_mci);
static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah) static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah)
{ {
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
/* Configure the desired GPIO port for TX_FRAME output */ /* Configure the desired GPIO port for TX_FRAME output */
ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
@ -170,9 +216,6 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
{ {
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
SM(wlan_weight, AR_BTCOEX_WL_WGHT); SM(wlan_weight, AR_BTCOEX_WL_WGHT);
} }
@ -261,9 +304,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
int i; int i;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
btcoex_hw->enabled = false; btcoex_hw->enabled = false;
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) {
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
@ -312,9 +352,6 @@ static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type) enum ath_stomp_type stomp_type)
{ {
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
if (AR_SREV_9300_20_OR_LATER(ah)) { if (AR_SREV_9300_20_OR_LATER(ah)) {
ar9003_btcoex_bt_stomp(ah, stomp_type); ar9003_btcoex_bt_stomp(ah, stomp_type);
return; return;

View File

@ -67,7 +67,6 @@ struct ath9k_hw_mci {
u32 wlan_cal_done; u32 wlan_cal_done;
u32 config; u32 config;
u8 *gpm_buf; u8 *gpm_buf;
u8 *sched_buf;
bool ready; bool ready;
bool update_2g5g; bool update_2g5g;
bool is_2g; bool is_2g;
@ -98,13 +97,14 @@ struct ath_btcoex_hw {
u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
}; };
void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah);
void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah); void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah);
void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah); void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah);
void ath9k_hw_btcoex_init_mci(struct ath_hw *ah);
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum); void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum);
void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
u32 bt_weight, u32 bt_weight,
u32 wlan_weight); u32 wlan_weight);
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
void ath9k_hw_btcoex_disable(struct ath_hw *ah); void ath9k_hw_btcoex_disable(struct ath_hw *ah);
void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type); enum ath_stomp_type stomp_type);

View File

@ -451,109 +451,6 @@ static const struct file_operations fops_interrupt = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static const char *channel_type_str(enum nl80211_channel_type t)
{
switch (t) {
case NL80211_CHAN_NO_HT:
return "no ht";
case NL80211_CHAN_HT20:
return "ht20";
case NL80211_CHAN_HT40MINUS:
return "ht40-";
case NL80211_CHAN_HT40PLUS:
return "ht40+";
default:
return "???";
}
}
static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ieee80211_channel *chan = sc->hw->conf.channel;
struct ieee80211_conf *conf = &(sc->hw->conf);
char buf[512];
unsigned int len = 0;
u8 addr[ETH_ALEN];
u32 tmp;
len += snprintf(buf + len, sizeof(buf) - len,
"%s (chan=%d center-freq: %d MHz channel-type: %d (%s))\n",
wiphy_name(sc->hw->wiphy),
ieee80211_frequency_to_channel(chan->center_freq),
chan->center_freq,
conf->channel_type,
channel_type_str(conf->channel_type));
ath9k_ps_wakeup(sc);
put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
len += snprintf(buf + len, sizeof(buf) - len,
"addr: %pM\n", addr);
put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_BSSMSKL), addr);
put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
len += snprintf(buf + len, sizeof(buf) - len,
"addrmask: %pM\n", addr);
tmp = ath9k_hw_getrxfilter(sc->sc_ah);
ath9k_ps_restore(sc);
len += snprintf(buf + len, sizeof(buf) - len,
"rfilt: 0x%x", tmp);
if (tmp & ATH9K_RX_FILTER_UCAST)
len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
if (tmp & ATH9K_RX_FILTER_MCAST)
len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
if (tmp & ATH9K_RX_FILTER_BCAST)
len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
if (tmp & ATH9K_RX_FILTER_CONTROL)
len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
if (tmp & ATH9K_RX_FILTER_BEACON)
len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
if (tmp & ATH9K_RX_FILTER_PROM)
len += snprintf(buf + len, sizeof(buf) - len, " PROM");
if (tmp & ATH9K_RX_FILTER_PROBEREQ)
len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
if (tmp & ATH9K_RX_FILTER_PHYERR)
len += snprintf(buf + len, sizeof(buf) - len, " PHYERR");
if (tmp & ATH9K_RX_FILTER_MYBEACON)
len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON");
if (tmp & ATH9K_RX_FILTER_COMP_BAR)
len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR");
if (tmp & ATH9K_RX_FILTER_PSPOLL)
len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL");
if (tmp & ATH9K_RX_FILTER_PHYRADAR)
len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
len += snprintf(buf + len, sizeof(buf) - len,
"\n\nReset causes:\n"
" baseband hang: %d\n"
" baseband watchdog: %d\n"
" fatal hardware error interrupt: %d\n"
" tx hardware error: %d\n"
" tx path hang: %d\n"
" pll rx hang: %d\n",
sc->debug.stats.reset[RESET_TYPE_BB_HANG],
sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG],
sc->debug.stats.reset[RESET_TYPE_FATAL_INT],
sc->debug.stats.reset[RESET_TYPE_TX_ERROR],
sc->debug.stats.reset[RESET_TYPE_TX_HANG],
sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
if (len > sizeof(buf))
len = sizeof(buf);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static const struct file_operations fops_wiphy = {
.read = read_file_wiphy,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum
#define PR(str, elem) \ #define PR(str, elem) \
do { \ do { \
@ -763,87 +660,128 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
{ {
struct ath_softc *sc = file->private_data; struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_hw *ah = sc->sc_ah;
struct ieee80211_hw *hw = sc->hw; struct ieee80211_hw *hw = sc->hw;
char *buf; struct ath9k_vif_iter_data iter_data;
unsigned int len = 0, size = 8000; char buf[512];
unsigned int len = 0;
ssize_t retval = 0; ssize_t retval = 0;
unsigned int reg; unsigned int reg;
struct ath9k_vif_iter_data iter_data; u32 rxfilter;
len += snprintf(buf + len, sizeof(buf) - len,
"BSSID: %pM\n", common->curbssid);
len += snprintf(buf + len, sizeof(buf) - len,
"BSSID-MASK: %pM\n", common->bssidmask);
len += snprintf(buf + len, sizeof(buf) - len,
"OPMODE: %s\n", ath_opmode_to_string(sc->sc_ah->opmode));
ath9k_ps_wakeup(sc);
rxfilter = ath9k_hw_getrxfilter(sc->sc_ah);
ath9k_ps_restore(sc);
len += snprintf(buf + len, sizeof(buf) - len,
"RXFILTER: 0x%x", rxfilter);
if (rxfilter & ATH9K_RX_FILTER_UCAST)
len += snprintf(buf + len, sizeof(buf) - len, " UCAST");
if (rxfilter & ATH9K_RX_FILTER_MCAST)
len += snprintf(buf + len, sizeof(buf) - len, " MCAST");
if (rxfilter & ATH9K_RX_FILTER_BCAST)
len += snprintf(buf + len, sizeof(buf) - len, " BCAST");
if (rxfilter & ATH9K_RX_FILTER_CONTROL)
len += snprintf(buf + len, sizeof(buf) - len, " CONTROL");
if (rxfilter & ATH9K_RX_FILTER_BEACON)
len += snprintf(buf + len, sizeof(buf) - len, " BEACON");
if (rxfilter & ATH9K_RX_FILTER_PROM)
len += snprintf(buf + len, sizeof(buf) - len, " PROM");
if (rxfilter & ATH9K_RX_FILTER_PROBEREQ)
len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ");
if (rxfilter & ATH9K_RX_FILTER_PHYERR)
len += snprintf(buf + len, sizeof(buf) - len, " PHYERR");
if (rxfilter & ATH9K_RX_FILTER_MYBEACON)
len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON");
if (rxfilter & ATH9K_RX_FILTER_COMP_BAR)
len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR");
if (rxfilter & ATH9K_RX_FILTER_PSPOLL)
len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL");
if (rxfilter & ATH9K_RX_FILTER_PHYRADAR)
len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER)
len += snprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER");
len += snprintf(buf + len, sizeof(buf) - len, "\n");
reg = sc->sc_ah->imask;
len += snprintf(buf + len, sizeof(buf) - len, "INTERRUPT-MASK: 0x%x", reg);
if (reg & ATH9K_INT_SWBA)
len += snprintf(buf + len, sizeof(buf) - len, " SWBA");
if (reg & ATH9K_INT_BMISS)
len += snprintf(buf + len, sizeof(buf) - len, " BMISS");
if (reg & ATH9K_INT_CST)
len += snprintf(buf + len, sizeof(buf) - len, " CST");
if (reg & ATH9K_INT_RX)
len += snprintf(buf + len, sizeof(buf) - len, " RX");
if (reg & ATH9K_INT_RXHP)
len += snprintf(buf + len, sizeof(buf) - len, " RXHP");
if (reg & ATH9K_INT_RXLP)
len += snprintf(buf + len, sizeof(buf) - len, " RXLP");
if (reg & ATH9K_INT_BB_WATCHDOG)
len += snprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG");
len += snprintf(buf + len, sizeof(buf) - len, "\n");
ath9k_calculate_iter_data(hw, NULL, &iter_data); ath9k_calculate_iter_data(hw, NULL, &iter_data);
buf = kzalloc(size, GFP_KERNEL); len += snprintf(buf + len, sizeof(buf) - len,
if (buf == NULL) "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i"
return -ENOMEM; " ADHOC: %i OTHER: %i TOTAL: %hi BEACON-VIF: %hi\n",
ath9k_ps_wakeup(sc);
len += snprintf(buf + len, size - len,
"curbssid: %pM\n"
"OP-Mode: %s(%i)\n"
"Beacon-Timer-Register: 0x%x\n",
common->curbssid,
ath_opmode_to_string(sc->sc_ah->opmode),
(int)(sc->sc_ah->opmode),
REG_READ(ah, AR_BEACON_PERIOD));
reg = REG_READ(ah, AR_TIMER_MODE);
ath9k_ps_restore(sc);
len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (",
reg);
if (reg & AR_TBTT_TIMER_EN)
len += snprintf(buf + len, size - len, "TBTT ");
if (reg & AR_DBA_TIMER_EN)
len += snprintf(buf + len, size - len, "DBA ");
if (reg & AR_SWBA_TIMER_EN)
len += snprintf(buf + len, size - len, "SWBA ");
if (reg & AR_HCF_TIMER_EN)
len += snprintf(buf + len, size - len, "HCF ");
if (reg & AR_TIM_TIMER_EN)
len += snprintf(buf + len, size - len, "TIM ");
if (reg & AR_DTIM_TIMER_EN)
len += snprintf(buf + len, size - len, "DTIM ");
len += snprintf(buf + len, size - len, ")\n");
reg = sc->sc_ah->imask;
len += snprintf(buf + len, size - len, "imask: 0x%x (", reg);
if (reg & ATH9K_INT_SWBA)
len += snprintf(buf + len, size - len, "SWBA ");
if (reg & ATH9K_INT_BMISS)
len += snprintf(buf + len, size - len, "BMISS ");
if (reg & ATH9K_INT_CST)
len += snprintf(buf + len, size - len, "CST ");
if (reg & ATH9K_INT_RX)
len += snprintf(buf + len, size - len, "RX ");
if (reg & ATH9K_INT_RXHP)
len += snprintf(buf + len, size - len, "RXHP ");
if (reg & ATH9K_INT_RXLP)
len += snprintf(buf + len, size - len, "RXLP ");
if (reg & ATH9K_INT_BB_WATCHDOG)
len += snprintf(buf + len, size - len, "BB_WATCHDOG ");
/* there are other IRQs if one wanted to add them. */
len += snprintf(buf + len, size - len, ")\n");
len += snprintf(buf + len, size - len,
"VIF Counts: AP: %i STA: %i MESH: %i WDS: %i"
" ADHOC: %i OTHER: %i nvifs: %hi beacon-vifs: %hi\n",
iter_data.naps, iter_data.nstations, iter_data.nmeshes, iter_data.naps, iter_data.nstations, iter_data.nmeshes,
iter_data.nwds, iter_data.nadhocs, iter_data.nothers, iter_data.nwds, iter_data.nadhocs, iter_data.nothers,
sc->nvifs, sc->nbcnvifs); sc->nvifs, sc->nbcnvifs);
len += snprintf(buf + len, size - len, if (len > sizeof(buf))
"Calculated-BSSID-Mask: %pM\n", len = sizeof(buf);
iter_data.mask);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval; return retval;
} }
static ssize_t read_file_reset(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
char buf[512];
unsigned int len = 0;
len += snprintf(buf + len, sizeof(buf) - len,
"%17s: %2d\n", "Baseband Hang",
sc->debug.stats.reset[RESET_TYPE_BB_HANG]);
len += snprintf(buf + len, sizeof(buf) - len,
"%17s: %2d\n", "Baseband Watchdog",
sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]);
len += snprintf(buf + len, sizeof(buf) - len,
"%17s: %2d\n", "Fatal HW Error",
sc->debug.stats.reset[RESET_TYPE_FATAL_INT]);
len += snprintf(buf + len, sizeof(buf) - len,
"%17s: %2d\n", "TX HW error",
sc->debug.stats.reset[RESET_TYPE_TX_ERROR]);
len += snprintf(buf + len, sizeof(buf) - len,
"%17s: %2d\n", "TX Path Hang",
sc->debug.stats.reset[RESET_TYPE_TX_HANG]);
len += snprintf(buf + len, sizeof(buf) - len,
"%17s: %2d\n", "PLL RX Hang",
sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
if (len > sizeof(buf))
len = sizeof(buf);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, 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) unsigned int flags)
@ -931,16 +869,23 @@ static const struct file_operations fops_misc = {
.llseek = default_llseek, .llseek = default_llseek,
}; };
static const struct file_operations fops_reset = {
.read = read_file_reset,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static ssize_t read_file_recv(struct file *file, char __user *user_buf, static ssize_t read_file_recv(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
#define PHY_ERR(s, p) \ #define PHY_ERR(s, p) \
len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \ len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \
sc->debug.stats.rxstats.phy_err_stats[p]); sc->debug.stats.rxstats.phy_err_stats[p]);
struct ath_softc *sc = file->private_data; struct ath_softc *sc = file->private_data;
char *buf; char *buf;
unsigned int len = 0, size = 1400; unsigned int len = 0, size = 1600;
ssize_t retval = 0; ssize_t retval = 0;
buf = kzalloc(size, GFP_KERNEL); buf = kzalloc(size, GFP_KERNEL);
@ -948,87 +893,80 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
return -ENOMEM; return -ENOMEM;
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "CRC ERR", "%22s : %10u\n", "CRC ERR",
sc->debug.stats.rxstats.crc_err); sc->debug.stats.rxstats.crc_err);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "DECRYPT CRC ERR", "%22s : %10u\n", "DECRYPT CRC ERR",
sc->debug.stats.rxstats.decrypt_crc_err); sc->debug.stats.rxstats.decrypt_crc_err);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "PHY ERR", "%22s : %10u\n", "PHY ERR",
sc->debug.stats.rxstats.phy_err); sc->debug.stats.rxstats.phy_err);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "MIC ERR", "%22s : %10u\n", "MIC ERR",
sc->debug.stats.rxstats.mic_err); sc->debug.stats.rxstats.mic_err);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "PRE-DELIM CRC ERR", "%22s : %10u\n", "PRE-DELIM CRC ERR",
sc->debug.stats.rxstats.pre_delim_crc_err); sc->debug.stats.rxstats.pre_delim_crc_err);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "POST-DELIM CRC ERR", "%22s : %10u\n", "POST-DELIM CRC ERR",
sc->debug.stats.rxstats.post_delim_crc_err); sc->debug.stats.rxstats.post_delim_crc_err);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "DECRYPT BUSY ERR", "%22s : %10u\n", "DECRYPT BUSY ERR",
sc->debug.stats.rxstats.decrypt_busy_err); sc->debug.stats.rxstats.decrypt_busy_err);
PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-CTL0", "%22s : %10d\n", "RSSI-CTL0",
sc->debug.stats.rxstats.rs_rssi_ctl0); sc->debug.stats.rxstats.rs_rssi_ctl0);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-CTL1", "%22s : %10d\n", "RSSI-CTL1",
sc->debug.stats.rxstats.rs_rssi_ctl1); sc->debug.stats.rxstats.rs_rssi_ctl1);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-CTL2", "%22s : %10d\n", "RSSI-CTL2",
sc->debug.stats.rxstats.rs_rssi_ctl2); sc->debug.stats.rxstats.rs_rssi_ctl2);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-EXT0", "%22s : %10d\n", "RSSI-EXT0",
sc->debug.stats.rxstats.rs_rssi_ext0); sc->debug.stats.rxstats.rs_rssi_ext0);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-EXT1", "%22s : %10d\n", "RSSI-EXT1",
sc->debug.stats.rxstats.rs_rssi_ext1); sc->debug.stats.rxstats.rs_rssi_ext1);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-EXT2", "%22s : %10d\n", "RSSI-EXT2",
sc->debug.stats.rxstats.rs_rssi_ext2); sc->debug.stats.rxstats.rs_rssi_ext2);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10d\n", "Rx Antenna", "%22s : %10d\n", "Rx Antenna",
sc->debug.stats.rxstats.rs_antenna); sc->debug.stats.rxstats.rs_antenna);
PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
PHY_ERR("RATE", ATH9K_PHYERR_RATE);
PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
PHY_ERR("TOR", ATH9K_PHYERR_TOR);
PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "RX-Pkts-All", "%22s : %10u\n", "RX-Pkts-All",
sc->debug.stats.rxstats.rx_pkts_all); sc->debug.stats.rxstats.rx_pkts_all);
len += snprintf(buf + len, size - len, len += snprintf(buf + len, size - len,
"%18s : %10u\n", "RX-Bytes-All", "%22s : %10u\n", "RX-Bytes-All",
sc->debug.stats.rxstats.rx_bytes_all); sc->debug.stats.rxstats.rx_bytes_all);
if (len > size) if (len > size)
@ -1049,8 +987,6 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
#define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\ #define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\
[sc->debug.rsidx].c) [sc->debug.rsidx].c)
u32 phyerr;
RX_STAT_INC(rx_pkts_all); RX_STAT_INC(rx_pkts_all);
sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen; sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
@ -1069,8 +1005,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
if (rs->rs_status & ATH9K_RXERR_PHY) { if (rs->rs_status & ATH9K_RXERR_PHY) {
RX_STAT_INC(phy_err); RX_STAT_INC(phy_err);
phyerr = rs->rs_phyerr & 0x24; if (rs->rs_phyerr < ATH9K_PHYERR_MAX)
RX_PHY_ERR_INC(phyerr); RX_PHY_ERR_INC(rs->rs_phyerr);
} }
sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0;
@ -1637,14 +1573,14 @@ int ath9k_init_debug(struct ath_hw *ah)
&fops_dma); &fops_dma);
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_interrupt); &fops_interrupt);
debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
sc, &fops_wiphy);
debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_xmit); &fops_xmit);
debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_stations); &fops_stations);
debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_misc); &fops_misc);
debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_reset);
debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_recv); &fops_recv);
debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
@ -1677,10 +1613,5 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
sc->debug.regidx = 0;
memset(&sc->debug.bb_mac_samp, 0, sizeof(sc->debug.bb_mac_samp));
sc->debug.sampidx = 0;
sc->debug.tsidx = 0;
sc->debug.rsidx = 0;
return 0; return 0;
} }

View File

@ -110,6 +110,8 @@ void ath_start_rfkill_poll(struct ath_softc *sc)
wiphy_rfkill_start_polling(sc->hw->wiphy); wiphy_rfkill_start_polling(sc->hw->wiphy);
} }
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
/******************/ /******************/
/* BTCOEX */ /* BTCOEX */
/******************/ /******************/
@ -245,13 +247,10 @@ static void ath_btcoex_no_stomp_timer(void *arg)
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
} }
int ath_init_btcoex_timer(struct ath_softc *sc) static int ath_init_btcoex_timer(struct ath_softc *sc)
{ {
struct ath_btcoex *btcoex = &sc->btcoex; struct ath_btcoex *btcoex = &sc->btcoex;
if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_NONE)
return 0;
btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
btcoex->btcoex_period / 100; btcoex->btcoex_period / 100;
@ -284,9 +283,6 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
/* make sure duty cycle timer is also stopped when resuming */ /* make sure duty cycle timer is also stopped when resuming */
if (btcoex->hw_timer_enabled) if (btcoex->hw_timer_enabled)
ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
@ -307,9 +303,6 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc)
struct ath_btcoex *btcoex = &sc->btcoex; struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
del_timer_sync(&btcoex->period_timer); del_timer_sync(&btcoex->period_timer);
if (btcoex->hw_timer_enabled) if (btcoex->hw_timer_enabled)
@ -317,3 +310,113 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc)
btcoex->hw_timer_enabled = false; btcoex->hw_timer_enabled = false;
} }
u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
{
struct ath_mci_profile *mci = &sc->btcoex.mci;
u16 aggr_limit = 0;
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit)
aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4;
else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED)
aggr_limit = min((max_4ms_framelen * 3) / 8,
(u32)ATH_AMPDU_LIMIT_MAX);
return aggr_limit;
}
void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status)
{
struct ath_hw *ah = sc->sc_ah;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
if (status & ATH9K_INT_GENTIMER)
ath_gen_timer_isr(sc->sc_ah);
if (status & ATH9K_INT_MCI)
ath_mci_intr(sc);
}
void ath9k_start_btcoex(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) &&
!ah->btcoex_hw.enabled) {
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
ath9k_hw_btcoex_enable(ah);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_resume(sc);
}
}
void ath9k_stop_btcoex(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
if (ah->btcoex_hw.enabled &&
ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
ath9k_hw_btcoex_disable(ah);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_pause(sc);
ath_mci_flush_profile(&sc->btcoex.mci);
}
}
void ath9k_deinit_btcoex(struct ath_softc *sc)
{
if ((sc->btcoex.no_stomp_timer) &&
ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI)
ath_mci_cleanup(sc);
}
int ath9k_init_btcoex(struct ath_softc *sc)
{
struct ath_txq *txq;
struct ath_hw *ah = sc->sc_ah;
int r;
ath9k_hw_btcoex_init_scheme(ah);
switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) {
case ATH_BTCOEX_CFG_NONE:
break;
case ATH_BTCOEX_CFG_2WIRE:
ath9k_hw_btcoex_init_2wire(sc->sc_ah);
break;
case ATH_BTCOEX_CFG_3WIRE:
ath9k_hw_btcoex_init_3wire(sc->sc_ah);
r = ath_init_btcoex_timer(sc);
if (r)
return -1;
txq = sc->tx.txq_map[WME_AC_BE];
ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
break;
case ATH_BTCOEX_CFG_MCI:
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
INIT_LIST_HEAD(&sc->btcoex.mci.info);
r = ath_mci_setup(sc);
if (r)
return r;
ath9k_hw_btcoex_init_mci(ah);
break;
default:
WARN_ON(1);
break;
}
return 0;
}
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */

View File

@ -400,9 +400,21 @@ struct ath_btcoex {
u32 btscan_no_stomp; u32 btscan_no_stomp;
}; };
void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv); #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv); void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product);
void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv);
void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv);
#else
static inline void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product)
{
}
static inline void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv)
{
}
static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
{
}
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
#define OP_INVALID BIT(0) #define OP_INVALID BIT(0)
#define OP_SCANNING BIT(1) #define OP_SCANNING BIT(1)
@ -483,7 +495,10 @@ struct ath9k_htc_priv {
int cabq; int cabq;
int hwq_map[WME_NUM_AC]; int hwq_map[WME_NUM_AC];
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
struct ath_btcoex btcoex; struct ath_btcoex btcoex;
#endif
struct delayed_work coex_period_work; struct delayed_work coex_period_work;
struct delayed_work duty_cycle_work; struct delayed_work duty_cycle_work;
#ifdef CONFIG_ATH9K_HTC_DEBUGFS #ifdef CONFIG_ATH9K_HTC_DEBUGFS

View File

@ -20,6 +20,10 @@
/* BTCOEX */ /* BTCOEX */
/******************/ /******************/
#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
/* /*
* Detects if there is any priority bt traffic * Detects if there is any priority bt traffic
*/ */
@ -111,13 +115,10 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
ath9k_hw_btcoex_enable(priv->ah); ath9k_hw_btcoex_enable(priv->ah);
} }
void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) static void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
{ {
struct ath_btcoex *btcoex = &priv->btcoex; struct ath_btcoex *btcoex = &priv->btcoex;
if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE)
return;
btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
btcoex->btcoex_period / 100; btcoex->btcoex_period / 100;
@ -131,14 +132,11 @@ void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
* (Re)start btcoex work * (Re)start btcoex work
*/ */
void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) static void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
{ {
struct ath_btcoex *btcoex = &priv->btcoex; struct ath_btcoex *btcoex = &priv->btcoex;
struct ath_hw *ah = priv->ah; struct ath_hw *ah = priv->ah;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex work\n"); ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex work\n");
btcoex->bt_priority_cnt = 0; btcoex->bt_priority_cnt = 0;
@ -151,15 +149,66 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
/* /*
* Cancel btcoex and bt duty cycle work. * Cancel btcoex and bt duty cycle work.
*/ */
void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) static void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
{ {
if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE)
return;
cancel_delayed_work_sync(&priv->coex_period_work); cancel_delayed_work_sync(&priv->coex_period_work);
cancel_delayed_work_sync(&priv->duty_cycle_work); cancel_delayed_work_sync(&priv->duty_cycle_work);
} }
void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv)
{
struct ath_hw *ah = priv->ah;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) {
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
ath9k_hw_btcoex_enable(ah);
ath_htc_resume_btcoex_work(priv);
}
}
void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
{
struct ath_hw *ah = priv->ah;
if (ah->btcoex_hw.enabled &&
ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
ath9k_hw_btcoex_disable(ah);
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
ath_htc_cancel_btcoex_work(priv);
}
}
void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product)
{
struct ath_hw *ah = priv->ah;
int qnum;
if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
}
switch (ath9k_hw_get_btcoex_scheme(priv->ah)) {
case ATH_BTCOEX_CFG_NONE:
break;
case ATH_BTCOEX_CFG_3WIRE:
priv->ah->btcoex_hw.btactive_gpio = 7;
priv->ah->btcoex_hw.btpriority_gpio = 6;
priv->ah->btcoex_hw.wlanactive_gpio = 8;
priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
ath9k_hw_btcoex_init_3wire(priv->ah);
ath_htc_init_btcoex_work(priv);
qnum = priv->hwq_map[WME_AC_BE];
ath9k_hw_init_btcoex_hw(priv->ah, qnum);
break;
default:
WARN_ON(1);
break;
}
}
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
/*******/ /*******/
/* LED */ /* LED */
/*******/ /*******/

View File

@ -41,8 +41,6 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
.max_power = 20, \ .max_power = 20, \
} }
#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
static struct ieee80211_channel ath9k_2ghz_channels[] = { static struct ieee80211_channel ath9k_2ghz_channels[] = {
CHAN2G(2412, 0), /* Channel 1 */ CHAN2G(2412, 0), /* Channel 1 */
CHAN2G(2417, 1), /* Channel 2 */ CHAN2G(2417, 1), /* Channel 2 */
@ -603,29 +601,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv)
priv->ah->opmode = NL80211_IFTYPE_STATION; priv->ah->opmode = NL80211_IFTYPE_STATION;
} }
static void ath9k_init_btcoex(struct ath9k_htc_priv *priv)
{
int qnum;
switch (ath9k_hw_get_btcoex_scheme(priv->ah)) {
case ATH_BTCOEX_CFG_NONE:
break;
case ATH_BTCOEX_CFG_3WIRE:
priv->ah->btcoex_hw.btactive_gpio = 7;
priv->ah->btcoex_hw.btpriority_gpio = 6;
priv->ah->btcoex_hw.wlanactive_gpio = 8;
priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
ath9k_hw_btcoex_init_3wire(priv->ah);
ath_htc_init_btcoex_work(priv);
qnum = priv->hwq_map[WME_AC_BE];
ath9k_hw_init_btcoex_hw(priv->ah, qnum);
break;
default:
WARN_ON(1);
break;
}
}
static int ath9k_init_priv(struct ath9k_htc_priv *priv, static int ath9k_init_priv(struct ath9k_htc_priv *priv,
u16 devid, char *product, u16 devid, char *product,
u32 drv_info) u32 drv_info)
@ -698,12 +673,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
ath9k_cmn_init_crypto(ah); ath9k_cmn_init_crypto(ah);
ath9k_init_channels_rates(priv); ath9k_init_channels_rates(priv);
ath9k_init_misc(priv); ath9k_init_misc(priv);
ath9k_htc_init_btcoex(priv, product);
if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
ath9k_init_btcoex(priv);
}
return 0; return 0;

View File

@ -957,12 +957,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
mod_timer(&priv->tx.cleanup_timer, mod_timer(&priv->tx.cleanup_timer,
jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { ath9k_htc_start_btcoex(priv);
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
ath9k_hw_btcoex_enable(ah);
ath_htc_resume_btcoex_work(priv);
}
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return ret; return ret;
@ -1009,12 +1005,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (ah->btcoex_hw.enabled && ath9k_htc_stop_btcoex(priv);
ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
ath9k_hw_btcoex_disable(ah);
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
ath_htc_cancel_btcoex_work(priv);
}
/* Remove a monitor interface if it's present. */ /* Remove a monitor interface if it's present. */
if (priv->ah->is_monitoring) if (priv->ah->is_monitoring)

View File

@ -23,6 +23,7 @@
#include "hw-ops.h" #include "hw-ops.h"
#include "rc.h" #include "rc.h"
#include "ar9003_mac.h" #include "ar9003_mac.h"
#include "ar9003_mci.h"
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
@ -1518,60 +1519,21 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata, bool bChannelChange) struct ath9k_hw_cal_data *caldata, bool bChannelChange)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
u32 saveLedState; u32 saveLedState;
struct ath9k_channel *curchan = ah->curchan; struct ath9k_channel *curchan = ah->curchan;
u32 saveDefAntenna; u32 saveDefAntenna;
u32 macStaId1; u32 macStaId1;
u64 tsf = 0; u64 tsf = 0;
int i, r; int i, r;
bool allow_fbs = false; bool allow_fbs = false, start_mci_reset = false;
bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
bool save_fullsleep = ah->chip_fullsleep; bool save_fullsleep = ah->chip_fullsleep;
if (mci) { if (mci) {
start_mci_reset = ar9003_mci_start_reset(ah, chan);
ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan)); if (start_mci_reset)
return 0;
if (mci_hw->bt_state == MCI_BT_CAL_START) {
u32 payload[4] = {0, 0, 0, 0};
ath_dbg(common, MCI, "MCI stop rx for BT CAL\n");
mci_hw->bt_state = MCI_BT_CAL;
/*
* MCI FIX: disable mci interrupt here. This is to avoid
* SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
* lead to mci_intr reentry.
*/
ar9003_mci_disable_interrupt(ah);
ath_dbg(common, MCI, "send WLAN_CAL_GRANT\n");
MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
16, true, false);
ath_dbg(common, MCI, "\nMCI BT is calibrating\n");
/* Wait BT calibration to be completed for 25ms */
if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
0, 25000))
ath_dbg(common, MCI,
"MCI got BT_CAL_DONE\n");
else
ath_dbg(common, MCI,
"MCI ### BT cal takes to long, force bt_state to be bt_awake\n");
mci_hw->bt_state = MCI_BT_AWAKE;
/* MCI FIX: enable mci interrupt here */
ar9003_mci_enable_interrupt(ah);
return true;
} }
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO; return -EIO;
@ -1609,7 +1571,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (ath9k_hw_channel_change(ah, chan)) { if (ath9k_hw_channel_change(ah, chan)) {
ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah, true); ath9k_hw_start_nfcal(ah, true);
if (mci && mci_hw->ready) if (mci && ar9003_mci_is_ready(ah))
ar9003_mci_2g5g_switch(ah, true); ar9003_mci_2g5g_switch(ah, true);
if (AR_SREV_9271(ah)) if (AR_SREV_9271(ah))
@ -1618,19 +1580,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
} }
} }
if (mci) { if (mci)
ar9003_mci_disable_interrupt(ah); ar9003_mci_stop_bt(ah, save_fullsleep);
if (mci_hw->ready && !save_fullsleep) {
ar9003_mci_mute_bt(ah);
udelay(20);
REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
}
mci_hw->bt_state = MCI_BT_SLEEP;
mci_hw->ready = false;
}
saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
if (saveDefAntenna == 0) if (saveDefAntenna == 0)
@ -1807,54 +1758,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_loadnf(ah, chan); ath9k_hw_loadnf(ah, chan);
ath9k_hw_start_nfcal(ah, true); ath9k_hw_start_nfcal(ah, true);
if (mci && mci_hw->ready) { if (mci && ar9003_mci_end_reset(ah, chan, caldata))
if (IS_CHAN_2GHZ(chan) &&
(mci_hw->bt_state == MCI_BT_SLEEP)) {
if (ar9003_mci_check_int(ah,
AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
ar9003_mci_check_int(ah,
AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) {
/*
* BT is sleeping. Check if BT wakes up during
* WLAN calibration. If BT wakes up during
* WLAN calibration, need to go through all
* message exchanges again and recal.
*/
ath_dbg(common, MCI,
"MCI BT wakes up during WLAN calibration\n");
REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
ath_dbg(common, MCI, "MCI send REMOTE_RESET\n");
ar9003_mci_remote_reset(ah, true);
ar9003_mci_send_sys_waking(ah, true);
udelay(1);
if (IS_CHAN_2GHZ(chan))
ar9003_mci_send_lna_transfer(ah, true);
mci_hw->bt_state = MCI_BT_AWAKE;
ath_dbg(common, MCI, "MCI re-cal\n");
if (caldata) {
caldata->done_txiqcal_once = false;
caldata->done_txclcal_once = false;
caldata->rtt_hist.num_readings = 0;
}
if (!ath9k_hw_init_cal(ah, chan))
return -EIO; return -EIO;
}
}
ar9003_mci_enable_interrupt(ah);
}
ENABLE_REGWRITE_BUFFER(ah); ENABLE_REGWRITE_BUFFER(ah);
ath9k_hw_restore_chainmask(ah); ath9k_hw_restore_chainmask(ah);
@ -1894,24 +1800,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
#endif #endif
} }
if (ah->btcoex_hw.enabled && if (ath9k_hw_btcoex_is_enabled(ah))
ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
ath9k_hw_btcoex_enable(ah); ath9k_hw_btcoex_enable(ah);
if (mci && mci_hw->ready) { if (mci)
/* ar9003_mci_check_bt(ah);
* check BT state again to make
* sure it's not changed.
*/
ar9003_mci_sync_bt_state(ah);
ar9003_mci_2g5g_switch(ah, true);
if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
(mci_hw->query_bt == true)) {
mci_hw->need_flush_btinfo = true;
}
}
if (AR_SREV_9300_20_OR_LATER(ah)) { if (AR_SREV_9300_20_OR_LATER(ah)) {
ar9003_hw_bb_watchdog_config(ah); ar9003_hw_bb_watchdog_config(ah);
@ -1962,8 +1855,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
/* Shutdown chip. Active low */ /* Shutdown chip. Active low */
if (!AR_SREV_5416(ah) && if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) {
!AR_SREV_9271(ah) && !AR_SREV_9462_10(ah)) {
REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
udelay(2); udelay(2);
} }
@ -2076,7 +1968,6 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
int status = true, setChip = true; int status = true, setChip = true;
static const char *modes[] = { static const char *modes[] = {
"AWAKE", "AWAKE",
@ -2100,20 +1991,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
break; break;
case ATH9K_PM_FULL_SLEEP: case ATH9K_PM_FULL_SLEEP:
if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) { ar9003_mci_set_full_sleep(ah);
if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) &&
(mci->bt_state != MCI_BT_SLEEP) &&
!mci->halted_bt_gpm) {
ath_dbg(common, MCI,
"MCI halt BT GPM (full_sleep)\n");
ar9003_mci_send_coex_halt_bt_gpm(ah,
true, true);
}
mci->ready = false;
REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
}
ath9k_set_power_sleep(ah, setChip); ath9k_set_power_sleep(ah, setChip);
ah->chip_fullsleep = true; ah->chip_fullsleep = true;
@ -2303,7 +2182,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
unsigned int chip_chainmask; unsigned int chip_chainmask;
u16 eeval; u16 eeval;
@ -2422,30 +2300,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
if (common->btcoex_enabled) {
if (AR_SREV_9462(ah))
btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
else if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
if (AR_SREV_9285(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btpriority_gpio =
ATH_BTPRIORITY_GPIO_9285;
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
}
}
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
}
if (AR_SREV_9300_20_OR_LATER(ah)) { if (AR_SREV_9300_20_OR_LATER(ah)) {
pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah)) if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah))

View File

@ -209,11 +209,7 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_5GHZ = BIT(12), ATH9K_HW_CAP_5GHZ = BIT(12),
ATH9K_HW_CAP_APM = BIT(13), ATH9K_HW_CAP_APM = BIT(13),
ATH9K_HW_CAP_RTT = BIT(14), ATH9K_HW_CAP_RTT = BIT(14),
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
ATH9K_HW_CAP_MCI = BIT(15), ATH9K_HW_CAP_MCI = BIT(15),
#else
ATH9K_HW_CAP_MCI = 0,
#endif
ATH9K_HW_CAP_DFS = BIT(16), ATH9K_HW_CAP_DFS = BIT(16),
}; };
@ -432,161 +428,6 @@ enum ath9k_rx_qtype {
ATH9K_RX_QUEUE_MAX, ATH9K_RX_QUEUE_MAX,
}; };
enum mci_message_header { /* length of payload */
MCI_LNA_CTRL = 0x10, /* len = 0 */
MCI_CONT_NACK = 0x20, /* len = 0 */
MCI_CONT_INFO = 0x30, /* len = 4 */
MCI_CONT_RST = 0x40, /* len = 0 */
MCI_SCHD_INFO = 0x50, /* len = 16 */
MCI_CPU_INT = 0x60, /* len = 4 */
MCI_SYS_WAKING = 0x70, /* len = 0 */
MCI_GPM = 0x80, /* len = 16 */
MCI_LNA_INFO = 0x90, /* len = 1 */
MCI_LNA_STATE = 0x94,
MCI_LNA_TAKE = 0x98,
MCI_LNA_TRANS = 0x9c,
MCI_SYS_SLEEPING = 0xa0, /* len = 0 */
MCI_REQ_WAKE = 0xc0, /* len = 0 */
MCI_DEBUG_16 = 0xfe, /* len = 2 */
MCI_REMOTE_RESET = 0xff /* len = 16 */
};
enum ath_mci_gpm_coex_profile_type {
MCI_GPM_COEX_PROFILE_UNKNOWN,
MCI_GPM_COEX_PROFILE_RFCOMM,
MCI_GPM_COEX_PROFILE_A2DP,
MCI_GPM_COEX_PROFILE_HID,
MCI_GPM_COEX_PROFILE_BNEP,
MCI_GPM_COEX_PROFILE_VOICE,
MCI_GPM_COEX_PROFILE_MAX
};
/* MCI GPM/Coex opcode/type definitions */
enum {
MCI_GPM_COEX_W_GPM_PAYLOAD = 1,
MCI_GPM_COEX_B_GPM_TYPE = 4,
MCI_GPM_COEX_B_GPM_OPCODE = 5,
/* MCI_GPM_WLAN_CAL_REQ, MCI_GPM_WLAN_CAL_DONE */
MCI_GPM_WLAN_CAL_W_SEQUENCE = 2,
/* MCI_GPM_COEX_VERSION_QUERY */
/* MCI_GPM_COEX_VERSION_RESPONSE */
MCI_GPM_COEX_B_MAJOR_VERSION = 6,
MCI_GPM_COEX_B_MINOR_VERSION = 7,
/* MCI_GPM_COEX_STATUS_QUERY */
MCI_GPM_COEX_B_BT_BITMAP = 6,
MCI_GPM_COEX_B_WLAN_BITMAP = 7,
/* MCI_GPM_COEX_HALT_BT_GPM */
MCI_GPM_COEX_B_HALT_STATE = 6,
/* MCI_GPM_COEX_WLAN_CHANNELS */
MCI_GPM_COEX_B_CHANNEL_MAP = 6,
/* MCI_GPM_COEX_BT_PROFILE_INFO */
MCI_GPM_COEX_B_PROFILE_TYPE = 6,
MCI_GPM_COEX_B_PROFILE_LINKID = 7,
MCI_GPM_COEX_B_PROFILE_STATE = 8,
MCI_GPM_COEX_B_PROFILE_ROLE = 9,
MCI_GPM_COEX_B_PROFILE_RATE = 10,
MCI_GPM_COEX_B_PROFILE_VOTYPE = 11,
MCI_GPM_COEX_H_PROFILE_T = 12,
MCI_GPM_COEX_B_PROFILE_W = 14,
MCI_GPM_COEX_B_PROFILE_A = 15,
/* MCI_GPM_COEX_BT_STATUS_UPDATE */
MCI_GPM_COEX_B_STATUS_TYPE = 6,
MCI_GPM_COEX_B_STATUS_LINKID = 7,
MCI_GPM_COEX_B_STATUS_STATE = 8,
/* MCI_GPM_COEX_BT_UPDATE_FLAGS */
MCI_GPM_COEX_W_BT_FLAGS = 6,
MCI_GPM_COEX_B_BT_FLAGS_OP = 10
};
enum mci_gpm_subtype {
MCI_GPM_BT_CAL_REQ = 0,
MCI_GPM_BT_CAL_GRANT = 1,
MCI_GPM_BT_CAL_DONE = 2,
MCI_GPM_WLAN_CAL_REQ = 3,
MCI_GPM_WLAN_CAL_GRANT = 4,
MCI_GPM_WLAN_CAL_DONE = 5,
MCI_GPM_COEX_AGENT = 0x0c,
MCI_GPM_RSVD_PATTERN = 0xfe,
MCI_GPM_RSVD_PATTERN32 = 0xfefefefe,
MCI_GPM_BT_DEBUG = 0xff
};
enum mci_bt_state {
MCI_BT_SLEEP,
MCI_BT_AWAKE,
MCI_BT_CAL_START,
MCI_BT_CAL
};
/* Type of state query */
enum mci_state_type {
MCI_STATE_ENABLE,
MCI_STATE_INIT_GPM_OFFSET,
MCI_STATE_NEXT_GPM_OFFSET,
MCI_STATE_LAST_GPM_OFFSET,
MCI_STATE_BT,
MCI_STATE_SET_BT_SLEEP,
MCI_STATE_SET_BT_AWAKE,
MCI_STATE_SET_BT_CAL_START,
MCI_STATE_SET_BT_CAL,
MCI_STATE_LAST_SCHD_MSG_OFFSET,
MCI_STATE_REMOTE_SLEEP,
MCI_STATE_CONT_RSSI_POWER,
MCI_STATE_CONT_PRIORITY,
MCI_STATE_CONT_TXRX,
MCI_STATE_RESET_REQ_WAKE,
MCI_STATE_SEND_WLAN_COEX_VERSION,
MCI_STATE_SET_BT_COEX_VERSION,
MCI_STATE_SEND_WLAN_CHANNELS,
MCI_STATE_SEND_VERSION_QUERY,
MCI_STATE_SEND_STATUS_QUERY,
MCI_STATE_NEED_FLUSH_BT_INFO,
MCI_STATE_SET_CONCUR_TX_PRI,
MCI_STATE_RECOVER_RX,
MCI_STATE_NEED_FTP_STOMP,
MCI_STATE_NEED_TUNING,
MCI_STATE_DEBUG,
MCI_STATE_MAX
};
enum mci_gpm_coex_opcode {
MCI_GPM_COEX_VERSION_QUERY,
MCI_GPM_COEX_VERSION_RESPONSE,
MCI_GPM_COEX_STATUS_QUERY,
MCI_GPM_COEX_HALT_BT_GPM,
MCI_GPM_COEX_WLAN_CHANNELS,
MCI_GPM_COEX_BT_PROFILE_INFO,
MCI_GPM_COEX_BT_STATUS_UPDATE,
MCI_GPM_COEX_BT_UPDATE_FLAGS
};
#define MCI_GPM_NOMORE 0
#define MCI_GPM_MORE 1
#define MCI_GPM_INVALID 0xffffffff
#define MCI_GPM_RECYCLE(_p_gpm) do { \
*(((u32 *)_p_gpm) + MCI_GPM_COEX_W_GPM_PAYLOAD) = \
MCI_GPM_RSVD_PATTERN32; \
} while (0)
#define MCI_GPM_TYPE(_p_gpm) \
(*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) & 0xff)
#define MCI_GPM_OPCODE(_p_gpm) \
(*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) & 0xff)
#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type) do { \
*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_cal_type) & 0xff;\
} while (0)
#define MCI_GPM_SET_TYPE_OPCODE(_p_gpm, _type, _opcode) do { \
*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_type) & 0xff; \
*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) = (_opcode) & 0xff;\
} while (0)
#define MCI_GPM_IS_CAL_TYPE(_type) ((_type) <= MCI_GPM_WLAN_CAL_DONE)
struct ath9k_beacon_state { struct ath9k_beacon_state {
u32 bs_nexttbtt; u32 bs_nexttbtt;
u32 bs_nextdtim; u32 bs_nextdtim;
@ -956,8 +797,9 @@ struct ath_hw {
int firpwr[5]; int firpwr[5];
enum ath9k_ani_cmd ani_function; enum ath9k_ani_cmd ani_function;
/* Bluetooth coexistance */ #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
struct ath_btcoex_hw btcoex_hw; struct ath_btcoex_hw btcoex_hw;
#endif
u32 intr_txqs; u32 intr_txqs;
u8 txchainmask; u8 txchainmask;
@ -1205,41 +1047,31 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
void ath9k_hw_proc_mib_event(struct ath_hw *ah); void ath9k_hw_proc_mib_event(struct ath_hw *ah);
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
u32 *payload, u8 len, bool wait_done,
bool check_bt);
void ar9003_mci_mute_bt(struct ath_hw *ah);
u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data);
void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
u16 len, u32 sched_addr);
void ar9003_mci_cleanup(struct ath_hw *ah);
void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
bool wait_done);
u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
u8 gpm_opcode, int time_out);
void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g);
void ar9003_mci_disable_interrupt(struct ath_hw *ah);
void ar9003_mci_enable_interrupt(struct ath_hw *ah);
void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done);
void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
bool is_full_sleep);
bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints);
void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done);
void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done);
void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done);
void ar9003_mci_sync_bt_state(struct ath_hw *ah);
void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
u32 *rx_msg_intr);
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
{
return ah->btcoex_hw.enabled;
}
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
static inline enum ath_btcoex_scheme static inline enum ath_btcoex_scheme
ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
{ {
return ah->btcoex_hw.scheme; return ah->btcoex_hw.scheme;
} }
#else #else
#define ath9k_hw_get_btcoex_scheme(...) ATH_BTCOEX_CFG_NONE static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
#endif {
return false;
}
static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah)
{
}
static inline enum ath_btcoex_scheme
ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
{
return ATH_BTCOEX_CFG_NONE;
}
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
#define ATH9K_CLOCK_RATE_CCK 22 #define ATH9K_CLOCK_RATE_CCK 22
#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40

View File

@ -419,66 +419,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
return error; return error;
} }
static int ath9k_init_btcoex(struct ath_softc *sc)
{
struct ath_txq *txq;
struct ath_hw *ah = sc->sc_ah;
int r;
switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) {
case ATH_BTCOEX_CFG_NONE:
break;
case ATH_BTCOEX_CFG_2WIRE:
ath9k_hw_btcoex_init_2wire(sc->sc_ah);
break;
case ATH_BTCOEX_CFG_3WIRE:
ath9k_hw_btcoex_init_3wire(sc->sc_ah);
r = ath_init_btcoex_timer(sc);
if (r)
return -1;
txq = sc->tx.txq_map[WME_AC_BE];
ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
break;
case ATH_BTCOEX_CFG_MCI:
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
INIT_LIST_HEAD(&sc->btcoex.mci.info);
r = ath_mci_setup(sc);
if (r)
return r;
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
ah->btcoex_hw.mci.ready = false;
ah->btcoex_hw.mci.bt_state = 0;
ah->btcoex_hw.mci.bt_ver_major = 3;
ah->btcoex_hw.mci.bt_ver_minor = 0;
ah->btcoex_hw.mci.bt_version_known = false;
ah->btcoex_hw.mci.update_2g5g = true;
ah->btcoex_hw.mci.is_2g = true;
ah->btcoex_hw.mci.wlan_channels_update = false;
ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000;
ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff;
ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff;
ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff;
ah->btcoex_hw.mci.query_bt = true;
ah->btcoex_hw.mci.unhalt_bt_gpm = true;
ah->btcoex_hw.mci.halted_bt_gpm = false;
ah->btcoex_hw.mci.need_flush_btinfo = false;
ah->btcoex_hw.mci.wlan_cal_seq = 0;
ah->btcoex_hw.mci.wlan_cal_done = 0;
ah->btcoex_hw.mci.config = 0x2201;
}
break;
default:
WARN_ON(1);
break;
}
return 0;
}
static int ath9k_init_queues(struct ath_softc *sc) static int ath9k_init_queues(struct ath_softc *sc)
{ {
int i = 0; int i = 0;
@ -880,12 +820,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
if (sc->sbands[IEEE80211_BAND_5GHZ].channels) if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
if ((sc->btcoex.no_stomp_timer) && ath9k_deinit_btcoex(sc);
ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI)
ath_mci_cleanup(sc);
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, i)) if (ATH_TXQ_SETUP(sc, i))

View File

@ -371,12 +371,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
if (sc->sc_flags & SC_OP_INVALID) if (sc->sc_flags & SC_OP_INVALID)
return -EIO; return -EIO;
ath9k_ps_wakeup(sc);
r = ath_reset_internal(sc, hchan, false); r = ath_reset_internal(sc, hchan, false);
ath9k_ps_restore(sc);
return r; return r;
} }
@ -739,12 +735,7 @@ void ath9k_tasklet(unsigned long data)
ath_tx_tasklet(sc); ath_tx_tasklet(sc);
} }
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) ath9k_btcoex_handle_interrupt(sc, status);
if (status & ATH9K_INT_GENTIMER)
ath_gen_timer_isr(sc->sc_ah);
if ((status & ATH9K_INT_MCI) && ATH9K_HW_CAP_MCI)
ath_mci_intr(sc);
out: out:
/* re-enable hardware interrupt */ /* re-enable hardware interrupt */
@ -1079,16 +1070,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
spin_unlock_bh(&sc->sc_pcu_lock); spin_unlock_bh(&sc->sc_pcu_lock);
if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && ath9k_start_btcoex(sc);
!ah->btcoex_hw.enabled) {
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
ath9k_hw_btcoex_enable(ah);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_resume(sc);
}
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
common->bus_ops->extn_synch_en(common); common->bus_ops->extn_synch_en(common);
@ -1189,13 +1171,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
/* Ensure HW is awake when we try to shut it down. */ /* Ensure HW is awake when we try to shut it down. */
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
if (ah->btcoex_hw.enabled && ath9k_stop_btcoex(sc);
ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
ath9k_hw_btcoex_disable(ah);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_pause(sc);
ath_mci_flush_profile(&sc->btcoex.mci);
}
spin_lock_bh(&sc->sc_pcu_lock); spin_lock_bh(&sc->sc_pcu_lock);
@ -1587,12 +1563,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex); mutex_lock(&sc->mutex);
/*
* Leave this as the first check because we need to turn on the
* radio if it was disabled before prior to processing the rest
* of the changes. Likewise we must only disable the radio towards
* the end.
*/
if (changed & IEEE80211_CONF_CHANGE_IDLE) { if (changed & IEEE80211_CONF_CHANGE_IDLE) {
sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
if (sc->ps_idle) if (sc->ps_idle)

View File

@ -42,24 +42,18 @@ static bool ath_mci_add_profile(struct ath_common *common,
struct ath_mci_profile_info *entry; struct ath_mci_profile_info *entry;
if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) &&
(info->type == MCI_GPM_COEX_PROFILE_VOICE)) { (info->type == MCI_GPM_COEX_PROFILE_VOICE))
ath_dbg(common, MCI,
"Too many SCO profile, failed to add new profile\n");
return false; return false;
}
if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) && if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) &&
(info->type != MCI_GPM_COEX_PROFILE_VOICE)) { (info->type != MCI_GPM_COEX_PROFILE_VOICE))
ath_dbg(common, MCI,
"Too many ACL profile, failed to add new profile\n");
return false; return false;
}
entry = ath_mci_find_profile(mci, info); entry = ath_mci_find_profile(mci, info);
if (entry) if (entry) {
memcpy(entry, info, 10); memcpy(entry, info, 10);
else { } else {
entry = kzalloc(sizeof(*entry), GFP_KERNEL); entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) if (!entry)
return false; return false;
@ -68,6 +62,7 @@ static bool ath_mci_add_profile(struct ath_common *common,
INC_PROF(mci, info); INC_PROF(mci, info);
list_add_tail(&info->list, &mci->info); list_add_tail(&info->list, &mci->info);
} }
return true; return true;
} }
@ -79,10 +74,9 @@ static void ath_mci_del_profile(struct ath_common *common,
entry = ath_mci_find_profile(mci, info); entry = ath_mci_find_profile(mci, info);
if (!entry) { if (!entry)
ath_dbg(common, MCI, "Profile to be deleted not found\n");
return; return;
}
DEC_PROF(mci, entry); DEC_PROF(mci, entry);
list_del(&entry->list); list_del(&entry->list);
kfree(entry); kfree(entry);
@ -183,7 +177,6 @@ static void ath_mci_update_scheme(struct ath_softc *sc)
ath9k_btcoex_timer_resume(sc); ath9k_btcoex_timer_resume(sc);
} }
static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
@ -192,42 +185,24 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
switch (opcode) { switch (opcode) {
case MCI_GPM_BT_CAL_REQ: case MCI_GPM_BT_CAL_REQ:
ath_dbg(common, MCI, "MCI received BT_CAL_REQ\n");
if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) {
ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL);
ieee80211_queue_work(sc->hw, &sc->hw_reset_work); ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
} else } else {
ath_dbg(common, MCI, "MCI State mismatches: %d\n", ath_dbg(common, MCI, "MCI State mismatch: %d\n",
ar9003_mci_state(ah, MCI_STATE_BT, NULL)); ar9003_mci_state(ah, MCI_STATE_BT, NULL));
}
break; break;
case MCI_GPM_BT_CAL_DONE: case MCI_GPM_BT_CAL_DONE:
ar9003_mci_state(ah, MCI_STATE_BT, NULL);
ath_dbg(common, MCI, "MCI received BT_CAL_DONE\n");
if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_CAL)
ath_dbg(common, MCI, "MCI error illegal!\n");
else
ath_dbg(common, MCI, "MCI BT not in CAL state\n");
break; break;
case MCI_GPM_BT_CAL_GRANT: case MCI_GPM_BT_CAL_GRANT:
ath_dbg(common, MCI, "MCI received BT_CAL_GRANT\n");
/* Send WLAN_CAL_DONE for now */
ath_dbg(common, MCI, "MCI send WLAN_CAL_DONE\n");
MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
ar9003_mci_send_message(sc->sc_ah, MCI_GPM, 0, payload, ar9003_mci_send_message(sc->sc_ah, MCI_GPM, 0, payload,
16, false, true); 16, false, true);
break; break;
default: default:
ath_dbg(common, MCI, "MCI Unknown GPM CAL message\n"); ath_dbg(common, MCI, "Unknown GPM CAL message\n");
break; break;
} }
} }
@ -247,6 +222,7 @@ static void ath_mci_process_profile(struct ath_softc *sc,
btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD;
mci->aggr_limit = mci->num_sco ? 6 : 0; mci->aggr_limit = mci->num_sco ? 6 : 0;
if (NUM_PROF(mci)) { if (NUM_PROF(mci)) {
btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)];
@ -262,31 +238,24 @@ static void ath_mci_process_profile(struct ath_softc *sc,
static void ath_mci_process_status(struct ath_softc *sc, static void ath_mci_process_status(struct ath_softc *sc,
struct ath_mci_profile_status *status) struct ath_mci_profile_status *status)
{ {
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_btcoex *btcoex = &sc->btcoex; struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_mci_profile *mci = &btcoex->mci; struct ath_mci_profile *mci = &btcoex->mci;
struct ath_mci_profile_info info; struct ath_mci_profile_info info;
int i = 0, old_num_mgmt = mci->num_mgmt; int i = 0, old_num_mgmt = mci->num_mgmt;
/* Link status type are not handled */ /* Link status type are not handled */
if (status->is_link) { if (status->is_link)
ath_dbg(common, MCI, "Skip link type status update\n");
return; return;
}
memset(&info, 0, sizeof(struct ath_mci_profile_info)); memset(&info, 0, sizeof(struct ath_mci_profile_info));
info.conn_handle = status->conn_handle; info.conn_handle = status->conn_handle;
if (ath_mci_find_profile(mci, &info)) { if (ath_mci_find_profile(mci, &info))
ath_dbg(common, MCI,
"Skip non link state update for existing profile %d\n",
status->conn_handle);
return; return;
}
if (status->conn_handle >= ATH_MCI_MAX_PROFILE) { if (status->conn_handle >= ATH_MCI_MAX_PROFILE)
ath_dbg(common, MCI, "Ignore too many non-link update\n");
return; return;
}
if (status->is_critical) if (status->is_critical)
__set_bit(status->conn_handle, mci->status); __set_bit(status->conn_handle, mci->status);
else else
@ -314,43 +283,28 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
u32 seq_num; u32 seq_num;
switch (opcode) { switch (opcode) {
case MCI_GPM_COEX_VERSION_QUERY: case MCI_GPM_COEX_VERSION_QUERY:
ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n"); version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION,
version = ar9003_mci_state(ah, NULL);
MCI_STATE_SEND_WLAN_COEX_VERSION, NULL);
break; break;
case MCI_GPM_COEX_VERSION_RESPONSE: case MCI_GPM_COEX_VERSION_RESPONSE:
ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION);
minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION);
ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
major, minor);
version = (major << 8) + minor; version = (major << 8) + minor;
version = ar9003_mci_state(ah, version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION,
MCI_STATE_SET_BT_COEX_VERSION, &version); &version);
break; break;
case MCI_GPM_COEX_STATUS_QUERY: case MCI_GPM_COEX_STATUS_QUERY:
ath_dbg(common, MCI, ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL);
"MCI Recv GPM COEX Status Query = 0x%02x\n",
*(rx_payload + MCI_GPM_COEX_B_WLAN_BITMAP));
ar9003_mci_state(ah,
MCI_STATE_SEND_WLAN_CHANNELS, NULL);
break; break;
case MCI_GPM_COEX_BT_PROFILE_INFO: case MCI_GPM_COEX_BT_PROFILE_INFO:
ath_dbg(common, MCI, "MCI Recv GPM Coex BT profile info\n");
memcpy(&profile_info, memcpy(&profile_info,
(rx_payload + MCI_GPM_COEX_B_PROFILE_TYPE), 10); (rx_payload + MCI_GPM_COEX_B_PROFILE_TYPE), 10);
if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN) if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN) ||
|| (profile_info.type >= (profile_info.type >= MCI_GPM_COEX_PROFILE_MAX)) {
MCI_GPM_COEX_PROFILE_MAX)) {
ath_dbg(common, MCI, ath_dbg(common, MCI,
"illegal profile type = %d, state = %d\n", "Illegal profile type = %d, state = %d\n",
profile_info.type, profile_info.type,
profile_info.start); profile_info.start);
break; break;
@ -358,7 +312,6 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
ath_mci_process_profile(sc, &profile_info); ath_mci_process_profile(sc, &profile_info);
break; break;
case MCI_GPM_COEX_BT_STATUS_UPDATE: case MCI_GPM_COEX_BT_STATUS_UPDATE:
profile_status.is_link = *(rx_payload + profile_status.is_link = *(rx_payload +
MCI_GPM_COEX_B_STATUS_TYPE); MCI_GPM_COEX_B_STATUS_TYPE);
@ -369,98 +322,66 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
seq_num = *((u32 *)(rx_payload + 12)); seq_num = *((u32 *)(rx_payload + 12));
ath_dbg(common, MCI, ath_dbg(common, MCI,
"MCI Recv GPM COEX BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n", "BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n",
profile_status.is_link, profile_status.conn_handle, profile_status.is_link, profile_status.conn_handle,
profile_status.is_critical, seq_num); profile_status.is_critical, seq_num);
ath_mci_process_status(sc, &profile_status); ath_mci_process_status(sc, &profile_status);
break; break;
default: default:
ath_dbg(common, MCI, "MCI Unknown GPM COEX message = 0x%02x\n", ath_dbg(common, MCI, "Unknown GPM COEX message = 0x%02x\n", opcode);
opcode);
break; break;
} }
} }
static int ath_mci_buf_alloc(struct ath_softc *sc, struct ath_mci_buf *buf)
{
int error = 0;
buf->bf_addr = dma_alloc_coherent(sc->dev, buf->bf_len,
&buf->bf_paddr, GFP_KERNEL);
if (buf->bf_addr == NULL) {
error = -ENOMEM;
goto fail;
}
return 0;
fail:
memset(buf, 0, sizeof(*buf));
return error;
}
static void ath_mci_buf_free(struct ath_softc *sc, struct ath_mci_buf *buf)
{
if (buf->bf_addr) {
dma_free_coherent(sc->dev, buf->bf_len, buf->bf_addr,
buf->bf_paddr);
memset(buf, 0, sizeof(*buf));
}
}
int ath_mci_setup(struct ath_softc *sc) int ath_mci_setup(struct ath_softc *sc)
{ {
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_mci_coex *mci = &sc->mci_coex; struct ath_mci_coex *mci = &sc->mci_coex;
int error = 0; struct ath_mci_buf *buf = &mci->sched_buf;
if (!ATH9K_HW_CAP_MCI) buf->bf_addr = dma_alloc_coherent(sc->dev,
return 0; ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
&buf->bf_paddr, GFP_KERNEL);
mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE; if (buf->bf_addr == NULL) {
if (ath_mci_buf_alloc(sc, &mci->sched_buf)) {
ath_dbg(common, FATAL, "MCI buffer alloc failed\n"); ath_dbg(common, FATAL, "MCI buffer alloc failed\n");
error = -ENOMEM; return -ENOMEM;
goto fail;
} }
memset(buf->bf_addr, MCI_GPM_RSVD_PATTERN,
ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE);
mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE; mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE;
memset(mci->sched_buf.bf_addr, MCI_GPM_RSVD_PATTERN,
mci->sched_buf.bf_len);
mci->gpm_buf.bf_len = ATH_MCI_GPM_BUF_SIZE; mci->gpm_buf.bf_len = ATH_MCI_GPM_BUF_SIZE;
mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len;
mci->sched_buf.bf_len;
mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len; mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len;
/* initialize the buffer */
memset(mci->gpm_buf.bf_addr, MCI_GPM_RSVD_PATTERN, mci->gpm_buf.bf_len);
ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr,
mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
mci->sched_buf.bf_paddr); mci->sched_buf.bf_paddr);
fail:
return error; ath_dbg(common, MCI, "MCI Initialized\n");
return 0;
} }
void ath_mci_cleanup(struct ath_softc *sc) void ath_mci_cleanup(struct ath_softc *sc)
{ {
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_mci_coex *mci = &sc->mci_coex; struct ath_mci_coex *mci = &sc->mci_coex;
struct ath_mci_buf *buf = &mci->sched_buf;
if (!ATH9K_HW_CAP_MCI) if (buf->bf_addr)
return; dma_free_coherent(sc->dev,
ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE,
buf->bf_addr, buf->bf_paddr);
/*
* both schedule and gpm buffers will be released
*/
ath_mci_buf_free(sc, &mci->sched_buf);
ar9003_mci_cleanup(ah); ar9003_mci_cleanup(ah);
ath_dbg(common, MCI, "MCI De-Initialized\n");
} }
void ath_mci_intr(struct ath_softc *sc) void ath_mci_intr(struct ath_softc *sc)
@ -474,19 +395,10 @@ void ath_mci_intr(struct ath_softc *sc)
u32 more_data = MCI_GPM_MORE; u32 more_data = MCI_GPM_MORE;
bool skip_gpm = false; bool skip_gpm = false;
if (!ATH9K_HW_CAP_MCI)
return;
ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) {
ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
ar9003_mci_state(sc->sc_ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
ath_dbg(common, MCI, "MCI interrupt but MCI disabled\n");
ath_dbg(common, MCI,
"MCI interrupt: intr = 0x%x, intr_rxmsg = 0x%x\n",
mci_int, mci_int_rxmsg);
return; return;
} }
@ -499,11 +411,8 @@ void ath_mci_intr(struct ath_softc *sc)
* only when BT wake up. Now they are always sent, as a * only when BT wake up. Now they are always sent, as a
* recovery method to reset BT MCI's RX alignment. * recovery method to reset BT MCI's RX alignment.
*/ */
ath_dbg(common, MCI, "MCI interrupt send REMOTE_RESET\n");
ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0,
payload, 16, true, false); payload, 16, true, false);
ath_dbg(common, MCI, "MCI interrupt send SYS_WAKING\n");
ar9003_mci_send_message(ah, MCI_SYS_WAKING, 0, ar9003_mci_send_message(ah, MCI_SYS_WAKING, 0,
NULL, 0, true, false); NULL, 0, true, false);
@ -513,74 +422,51 @@ void ath_mci_intr(struct ath_softc *sc)
/* /*
* always do this for recovery and 2G/5G toggling and LNA_TRANS * always do this for recovery and 2G/5G toggling and LNA_TRANS
*/ */
ath_dbg(common, MCI, "MCI Set BT state to AWAKE\n");
ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL);
} }
/* Processing SYS_WAKING/SYS_SLEEPING */
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) {
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING;
if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) { if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) {
if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) !=
if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) MCI_BT_SLEEP)
== MCI_BT_SLEEP) ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE,
ath_dbg(common, MCI, NULL);
"MCI BT stays in sleep mode\n");
else {
ath_dbg(common, MCI,
"MCI Set BT state to AWAKE\n");
ar9003_mci_state(ah,
MCI_STATE_SET_BT_AWAKE, NULL);
} }
} else
ath_dbg(common, MCI, "MCI BT stays in AWAKE mode\n");
} }
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) {
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING;
if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) {
if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) !=
if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) MCI_BT_AWAKE)
== MCI_BT_AWAKE)
ath_dbg(common, MCI,
"MCI BT stays in AWAKE mode\n");
else {
ath_dbg(common, MCI,
"MCI SetBT state to SLEEP\n");
ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP,
NULL); NULL);
} }
} else
ath_dbg(common, MCI, "MCI BT stays in SLEEP mode\n");
} }
if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) ||
(mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) {
ath_dbg(common, MCI, "MCI RX broken, skip GPM msgs\n");
ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL);
skip_gpm = true; skip_gpm = true;
} }
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) {
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO;
offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET, offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET,
NULL); NULL);
} }
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) {
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM;
while (more_data == MCI_GPM_MORE) { while (more_data == MCI_GPM_MORE) {
pgpm = mci->gpm_buf.bf_addr; pgpm = mci->gpm_buf.bf_addr;
offset = ar9003_mci_state(ah, offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
MCI_STATE_NEXT_GPM_OFFSET, &more_data); &more_data);
if (offset == MCI_GPM_INVALID) if (offset == MCI_GPM_INVALID)
break; break;
@ -591,42 +477,36 @@ void ath_mci_intr(struct ath_softc *sc)
* The first dword is timer. * The first dword is timer.
* The real data starts from 2nd dword. * The real data starts from 2nd dword.
*/ */
subtype = MCI_GPM_TYPE(pgpm); subtype = MCI_GPM_TYPE(pgpm);
opcode = MCI_GPM_OPCODE(pgpm); opcode = MCI_GPM_OPCODE(pgpm);
if (!skip_gpm) { if (skip_gpm)
goto recycle;
if (MCI_GPM_IS_CAL_TYPE(subtype)) if (MCI_GPM_IS_CAL_TYPE(subtype)) {
ath_mci_cal_msg(sc, subtype, ath_mci_cal_msg(sc, subtype, (u8 *)pgpm);
(u8 *) pgpm); } else {
else {
switch (subtype) { switch (subtype) {
case MCI_GPM_COEX_AGENT: case MCI_GPM_COEX_AGENT:
ath_mci_msg(sc, opcode, ath_mci_msg(sc, opcode, (u8 *)pgpm);
(u8 *) pgpm);
break; break;
default: default:
break; break;
} }
} }
} recycle:
MCI_GPM_RECYCLE(pgpm); MCI_GPM_RECYCLE(pgpm);
} }
} }
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_HW_MSG_MASK) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_HW_MSG_MASK) {
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL) if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL)
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL;
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO)
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO;
ath_dbg(common, MCI, "MCI LNA_INFO\n");
}
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) {
int value_dbm = ar9003_mci_state(ah, int value_dbm = ar9003_mci_state(ah,
MCI_STATE_CONT_RSSI_POWER, NULL); MCI_STATE_CONT_RSSI_POWER, NULL);
@ -646,23 +526,15 @@ void ath_mci_intr(struct ath_softc *sc)
value_dbm); value_dbm);
} }
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK)
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_NACK; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_NACK;
ath_dbg(common, MCI, "MCI CONT_NACK\n");
}
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST) { if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST)
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_RST; mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_RST;
ath_dbg(common, MCI, "MCI CONT_RST\n");
}
} }
if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) ||
(mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT))
mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR |
AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT);
if (mci_int_rxmsg & 0xfffffffe)
ath_dbg(common, MCI, "MCI not processed mci_int_rxmsg = 0x%x\n",
mci_int_rxmsg);
} }

View File

@ -17,6 +17,8 @@
#ifndef MCI_H #ifndef MCI_H
#define MCI_H #define MCI_H
#include "ar9003_mci.h"
#define ATH_MCI_SCHED_BUF_SIZE (16 * 16) /* 16 entries, 4 dword each */ #define ATH_MCI_SCHED_BUF_SIZE (16 * 16) /* 16 entries, 4 dword each */
#define ATH_MCI_GPM_MAX_ENTRY 16 #define ATH_MCI_GPM_MAX_ENTRY 16
#define ATH_MCI_GPM_BUF_SIZE (ATH_MCI_GPM_MAX_ENTRY * 16) #define ATH_MCI_GPM_BUF_SIZE (ATH_MCI_GPM_MAX_ENTRY * 16)
@ -113,7 +115,6 @@ struct ath_mci_profile {
u8 num_bdr; u8 num_bdr;
}; };
struct ath_mci_buf { struct ath_mci_buf {
void *bf_addr; /* virtual addr of desc */ void *bf_addr; /* virtual addr of desc */
dma_addr_t bf_paddr; /* physical addr of buffer */ dma_addr_t bf_paddr; /* physical addr of buffer */
@ -121,10 +122,8 @@ struct ath_mci_buf {
}; };
struct ath_mci_coex { struct ath_mci_coex {
atomic_t mci_cal_flag;
struct ath_mci_buf sched_buf; struct ath_mci_buf sched_buf;
struct ath_mci_buf gpm_buf; struct ath_mci_buf gpm_buf;
u32 bt_cal_start;
}; };
void ath_mci_flush_profile(struct ath_mci_profile *mci); void ath_mci_flush_profile(struct ath_mci_profile *mci);

View File

@ -567,10 +567,8 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
const struct ath_rate_table *rate_table, const struct ath_rate_table *rate_table,
u8 *mcs_set, u32 capflag) struct ath_rateset *rateset, u32 capflag)
{ {
struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
u8 i, j, hi = 0; u8 i, j, hi = 0;
/* Use intersection of working rates and valid rates */ /* Use intersection of working rates and valid rates */
@ -1212,7 +1210,7 @@ static void ath_rc_init(struct ath_softc *sc,
{ {
struct ath_rateset *rateset = &ath_rc_priv->neg_rates; struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; struct ath_rateset *ht_mcs = &ath_rc_priv->neg_ht_rates;
u8 i, j, k, hi = 0, hthi = 0; u8 i, j, k, hi = 0, hthi = 0;
/* Initial rate table size. Will change depending /* Initial rate table size. Will change depending

View File

@ -797,7 +797,6 @@
#define AR_SREV_VERSION_9580 0x1C0 #define AR_SREV_VERSION_9580 0x1C0
#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ #define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
#define AR_SREV_VERSION_9462 0x280 #define AR_SREV_VERSION_9462 0x280
#define AR_SREV_REVISION_9462_10 0
#define AR_SREV_REVISION_9462_20 2 #define AR_SREV_REVISION_9462_20 2
#define AR_SREV_5416(_ah) \ #define AR_SREV_5416(_ah) \
@ -898,10 +897,6 @@
#define AR_SREV_9462(_ah) \ #define AR_SREV_9462(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
#define AR_SREV_9462_10(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_10))
#define AR_SREV_9462_20(_ah) \ #define AR_SREV_9462_20(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))

View File

@ -647,9 +647,8 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates; struct ieee80211_tx_rate *rates;
struct ath_mci_profile *mci = &sc->btcoex.mci;
u32 max_4ms_framelen, frmlen; u32 max_4ms_framelen, frmlen;
u16 aggr_limit, legacy = 0; u16 aggr_limit, bt_aggr_limit, legacy = 0;
int i; int i;
skb = bf->bf_mpdu; skb = bf->bf_mpdu;
@ -694,14 +693,14 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
return 0; return 0;
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_MAX);
aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4;
else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) /*
aggr_limit = min((max_4ms_framelen * 3) / 8, * Override the default aggregation limit for BTCOEX.
(u32)ATH_AMPDU_LIMIT_MAX); */
else bt_aggr_limit = ath9k_btcoex_aggr_limit(sc, max_4ms_framelen);
aggr_limit = min(max_4ms_framelen, if (bt_aggr_limit)
(u32)ATH_AMPDU_LIMIT_MAX); aggr_limit = bt_aggr_limit;
/* /*
* h/w can accept aggregates up to 16 bit lengths (65535). * h/w can accept aggregates up to 16 bit lengths (65535).

View File

@ -1236,6 +1236,7 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
{ {
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct carl9170_sta_info *sta_info; struct carl9170_sta_info *sta_info;
struct ieee80211_tx_info *tx_info;
rcu_read_lock(); rcu_read_lock();
sta = __carl9170_get_tx_sta(ar, skb); sta = __carl9170_get_tx_sta(ar, skb);
@ -1243,16 +1244,18 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
goto out_rcu; goto out_rcu;
sta_info = (void *) sta->drv_priv; sta_info = (void *) sta->drv_priv;
if (unlikely(sta_info->sleeping)) { tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_info *tx_info;
if (unlikely(sta_info->sleeping) &&
!(tx_info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
IEEE80211_TX_CTL_CLEAR_PS_FILT))) {
rcu_read_unlock(); rcu_read_unlock();
tx_info = IEEE80211_SKB_CB(skb);
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
atomic_dec(&ar->tx_ampdu_upload); atomic_dec(&ar->tx_ampdu_upload);
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
carl9170_release_dev_space(ar, skb);
carl9170_tx_status(ar, skb, false); carl9170_tx_status(ar, skb, false);
return true; return true;
} }

View File

@ -26,16 +26,25 @@ config BRCMFMAC
it'll be called brcmfmac.ko. it'll be called brcmfmac.ko.
config BRCMFMAC_SDIO config BRCMFMAC_SDIO
bool "SDIO bus interface support for FullMAC" bool "SDIO bus interface support for FullMAC driver"
depends on MMC depends on MMC
depends on BRCMFMAC depends on BRCMFMAC
select FW_LOADER select FW_LOADER
default y default y
---help--- ---help---
This option enables the SDIO bus interface support for Broadcom This option enables the SDIO bus interface support for Broadcom
FullMAC WLAN driver. IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
Say Y if you want to use brcmfmac for a compatible SDIO interface use the driver for a SDIO wireless card.
wireless card.
config BRCMFMAC_USB
bool "USB bus interface support for FullMAC driver"
depends on USB
depends on BRCMFMAC
select FW_LOADER
---help---
This option enables the USB bus interface support for Broadcom
IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
use the driver for an USB wireless card.
config BRCMDBG config BRCMDBG
bool "Broadcom driver debug functions" bool "Broadcom driver debug functions"

View File

@ -19,6 +19,8 @@ ccflags-y += \
-Idrivers/net/wireless/brcm80211/brcmfmac \ -Idrivers/net/wireless/brcm80211/brcmfmac \
-Idrivers/net/wireless/brcm80211/include -Idrivers/net/wireless/brcm80211/include
ccflags-y += -D__CHECK_ENDIAN__
obj-$(CONFIG_BRCMFMAC) += brcmfmac.o obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
brcmfmac-objs += \ brcmfmac-objs += \
wl_cfg80211.o \ wl_cfg80211.o \
@ -30,5 +32,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
bcmsdh.o \ bcmsdh.o \
bcmsdh_sdmmc.o \ bcmsdh_sdmmc.o \
sdio_chip.o sdio_chip.o
brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
ccflags-y += -D__CHECK_ENDIAN__ usb.o

View File

@ -294,13 +294,14 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
struct sk_buff *pkt) struct sk_buff *pkt)
{ {
int status; int status;
uint pkt_len = pkt->len; uint pkt_len;
bool fifo = (fix_inc == SDIOH_DATA_FIX); bool fifo = (fix_inc == SDIOH_DATA_FIX);
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
if (pkt == NULL) if (pkt == NULL)
return -EINVAL; return -EINVAL;
pkt_len = pkt->len;
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
if (brcmf_pm_resume_error(sdiodev)) if (brcmf_pm_resume_error(sdiodev))
@ -488,7 +489,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
sdiodev->func[0] = func->card->sdio_func[0]; sdiodev->func[0] = func->card->sdio_func[0];
sdiodev->func[1] = func; sdiodev->func[1] = func;
sdiodev->bus_if = bus_if; sdiodev->bus_if = bus_if;
bus_if->bus_priv = sdiodev; bus_if->bus_priv.sdio = sdiodev;
bus_if->type = SDIO_BUS; bus_if->type = SDIO_BUS;
bus_if->align = BRCMF_SDALIGN; bus_if->align = BRCMF_SDALIGN;
dev_set_drvdata(&func->card->dev, sdiodev); dev_set_drvdata(&func->card->dev, sdiodev);
@ -529,7 +530,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
if (func->num == 2) { if (func->num == 2) {
bus_if = dev_get_drvdata(&func->dev); bus_if = dev_get_drvdata(&func->dev);
sdiodev = bus_if->bus_priv; sdiodev = bus_if->bus_priv.sdio;
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n"); brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
brcmf_sdio_remove(sdiodev); brcmf_sdio_remove(sdiodev);
dev_set_drvdata(&func->card->dev, NULL); dev_set_drvdata(&func->card->dev, NULL);
@ -596,14 +597,14 @@ static struct sdio_driver brcmf_sdmmc_driver = {
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
}; };
static void __exit brcmf_sdio_exit(void) void brcmf_sdio_exit(void)
{ {
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
sdio_unregister_driver(&brcmf_sdmmc_driver); sdio_unregister_driver(&brcmf_sdmmc_driver);
} }
static int __init brcmf_sdio_init(void) int brcmf_sdio_init(void)
{ {
int ret; int ret;
@ -616,6 +617,3 @@ static int __init brcmf_sdio_init(void)
return ret; return ret;
} }
module_init(brcmf_sdio_init);
module_exit(brcmf_sdio_exit);

View File

@ -39,8 +39,11 @@ struct dngl_stats {
/* interface structure between common and bus layer */ /* interface structure between common and bus layer */
struct brcmf_bus { struct brcmf_bus {
u8 type; /* bus type */ u8 type; /* bus type */
void *bus_priv; /* pointer to bus private structure */ union {
void *drvr; /* pointer to driver pub structure brcmf_pub */ struct brcmf_sdio_dev *sdio;
struct brcmf_usbdev *usb;
} bus_priv;
struct brcmf_pub *drvr; /* pointer to driver pub structure brcmf_pub */
enum brcmf_bus_state state; enum brcmf_bus_state state;
uint maxctl; /* Max size rxctl request from proto to bus */ uint maxctl; /* Max size rxctl request from proto to bus */
bool drvr_up; /* Status flag of driver up/down */ bool drvr_up; /* Status flag of driver up/down */
@ -102,4 +105,14 @@ extern int brcmf_bus_start(struct device *dev);
extern int brcmf_add_if(struct device *dev, int ifidx, extern int brcmf_add_if(struct device *dev, int ifidx,
char *name, u8 *mac_addr); char *name, u8 *mac_addr);
#ifdef CONFIG_BRCMFMAC_SDIO
extern void brcmf_sdio_exit(void);
extern int brcmf_sdio_init(void);
#endif
#ifdef CONFIG_BRCMFMAC_USB
extern void brcmf_usb_exit(void);
extern int brcmf_usb_init(void);
#endif
#endif /* _BRCMF_BUS_H_ */ #endif /* _BRCMF_BUS_H_ */

View File

@ -796,18 +796,19 @@ static int brcmf_netdev_open(struct net_device *ndev)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = ifp->drvr; struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_bus *bus_if = drvr->bus_if;
u32 toe_ol; u32 toe_ol;
s32 ret = 0; s32 ret = 0;
brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
if (ifp->idx == 0) { /* do it only for primary eth0 */ if (ifp->idx == 0) { /* do it only for primary eth0 */
/* try to bring up bus */ /* If bus is not ready, can't continue */
ret = brcmf_bus_start(drvr->dev); if (bus_if->state != BRCMF_BUS_DATA) {
if (ret != 0) { brcmf_dbg(ERROR, "failed bus is not ready\n");
brcmf_dbg(ERROR, "failed with code %d\n", ret); return -EAGAIN;
return -1;
} }
atomic_set(&drvr->pend_8021x_cnt, 0); atomic_set(&drvr->pend_8021x_cnt, 0);
memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
@ -979,12 +980,6 @@ int brcmf_bus_start(struct device *dev)
return ret; return ret;
} }
/* If bus is not ready, can't come up */
if (bus_if->state != BRCMF_BUS_DATA) {
brcmf_dbg(ERROR, "failed bus is not ready\n");
return -ENODEV;
}
brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
iovbuf, sizeof(iovbuf)); iovbuf, sizeof(iovbuf));
brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf, brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf,
@ -1021,6 +1016,8 @@ int brcmf_bus_start(struct device *dev)
if (ret < 0) if (ret < 0)
return ret; return ret;
/* signal bus ready */
bus_if->state = BRCMF_BUS_DATA;
return 0; return 0;
} }
@ -1109,13 +1106,13 @@ void brcmf_detach(struct device *dev)
if (drvr->iflist[i]) if (drvr->iflist[i])
brcmf_del_if(drvr, i); brcmf_del_if(drvr, i);
cancel_work_sync(&drvr->setmacaddr_work);
cancel_work_sync(&drvr->multicast_work);
brcmf_bus_detach(drvr); brcmf_bus_detach(drvr);
if (drvr->prot) if (drvr->prot) {
cancel_work_sync(&drvr->setmacaddr_work);
cancel_work_sync(&drvr->multicast_work);
brcmf_proto_detach(drvr); brcmf_proto_detach(drvr);
}
bus_if->drvr = NULL; bus_if->drvr = NULL;
kfree(drvr); kfree(drvr);
@ -1183,3 +1180,35 @@ int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
return ret; return ret;
} }
#endif /* DEBUG */ #endif /* DEBUG */
static int __init brcmfmac_init(void)
{
int ret = 0;
#ifdef CONFIG_BRCMFMAC_SDIO
ret = brcmf_sdio_init();
if (ret)
goto fail;
#endif
#ifdef CONFIG_BRCMFMAC_USB
ret = brcmf_usb_init();
if (ret)
goto fail;
#endif
fail:
return ret;
}
static void __exit brcmfmac_exit(void)
{
#ifdef CONFIG_BRCMFMAC_SDIO
brcmf_sdio_exit();
#endif
#ifdef CONFIG_BRCMFMAC_USB
brcmf_usb_exit();
#endif
}
module_init(brcmfmac_init);
module_exit(brcmfmac_exit);

View File

@ -309,10 +309,10 @@ struct rte_console {
/* Flags for SDH calls */ /* Flags for SDH calls */
#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
#define BRCMFMAC_FW_NAME "brcm/brcmfmac.bin" #define BRCMF_SDIO_FW_NAME "brcm/brcmfmac-sdio.bin"
#define BRCMFMAC_NV_NAME "brcm/brcmfmac.txt" #define BRCMF_SDIO_NV_NAME "brcm/brcmfmac-sdio.txt"
MODULE_FIRMWARE(BRCMFMAC_FW_NAME); MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
MODULE_FIRMWARE(BRCMFMAC_NV_NAME); MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */ #define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
@ -2276,7 +2276,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
uint retries; uint retries;
int err; int err;
struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus; struct brcmf_sdio *bus = sdiodev->bus;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
@ -2626,7 +2626,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
int ret = -EBADE; int ret = -EBADE;
uint datalen, prec; uint datalen, prec;
struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus; struct brcmf_sdio *bus = sdiodev->bus;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
@ -2867,7 +2867,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
u8 doff = 0; u8 doff = 0;
int ret = -1; int ret = -1;
struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus; struct brcmf_sdio *bus = sdiodev->bus;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
@ -2976,7 +2976,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
uint rxlen = 0; uint rxlen = 0;
bool pending; bool pending;
struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus; struct brcmf_sdio *bus = sdiodev->bus;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
@ -3200,7 +3200,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
brcmf_dbg(INFO, "Enter\n"); brcmf_dbg(INFO, "Enter\n");
ret = request_firmware(&bus->firmware, BRCMFMAC_FW_NAME, ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME,
&bus->sdiodev->func[2]->dev); &bus->sdiodev->func[2]->dev);
if (ret) { if (ret) {
brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret); brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret);
@ -3297,7 +3297,7 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
char *bufp; char *bufp;
int ret; int ret;
ret = request_firmware(&bus->firmware, BRCMFMAC_NV_NAME, ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
&bus->sdiodev->func[2]->dev); &bus->sdiodev->func[2]->dev);
if (ret) { if (ret) {
brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret); brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
@ -3387,7 +3387,7 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
static int brcmf_sdbrcm_bus_init(struct device *dev) static int brcmf_sdbrcm_bus_init(struct device *dev)
{ {
struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus; struct brcmf_sdio *bus = sdiodev->bus;
unsigned long timeout; unsigned long timeout;
uint retries = 0; uint retries = 0;
@ -3462,16 +3462,12 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
SBSDIO_WATERMARK, 8, &err); SBSDIO_WATERMARK, 8, &err);
} else {
/* Set bus state according to enable result */
bus_if->state = BRCMF_BUS_DATA;
}
else {
/* Disable F2 again */ /* Disable F2 again */
enable = SDIO_FUNC_ENABLE_1; enable = SDIO_FUNC_ENABLE_1;
brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0,
SDIO_CCCR_IOEx, enable, NULL); SDIO_CCCR_IOEx, enable, NULL);
ret = -ENODEV;
} }
/* Restore previous clock setting */ /* Restore previous clock setting */
@ -3479,7 +3475,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
/* If we didn't come up, turn off backplane clock */ /* If we didn't come up, turn off backplane clock */
if (bus_if->state != BRCMF_BUS_DATA) if (!ret)
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
exit: exit:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2011 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.
*
* 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 BRCMFMAC_USB_H
#define BRCMFMAC_USB_H
enum brcmf_usb_state {
BCMFMAC_USB_STATE_DL_PENDING,
BCMFMAC_USB_STATE_DL_DONE,
BCMFMAC_USB_STATE_UP,
BCMFMAC_USB_STATE_DOWN,
BCMFMAC_USB_STATE_PNP_FWDL,
BCMFMAC_USB_STATE_DISCONNECT,
BCMFMAC_USB_STATE_SLEEP
};
enum brcmf_usb_pnp_state {
BCMFMAC_USB_PNP_DISCONNECT,
BCMFMAC_USB_PNP_SLEEP,
BCMFMAC_USB_PNP_RESUME,
};
struct brcmf_stats {
u32 tx_errors;
u32 tx_packets;
u32 tx_multicast;
u32 tx_ctlpkts;
u32 tx_ctlerrs;
u32 tx_dropped;
u32 tx_flushed;
u32 rx_errors;
u32 rx_packets;
u32 rx_multicast;
u32 rx_ctlpkts;
u32 rx_ctlerrs;
u32 rx_dropped;
u32 rx_flushed;
};
struct brcmf_usb_attrib {
int bustype;
int vid;
int pid;
int devid;
int chiprev; /* chip revsion number */
int mtu;
int nchan; /* Data Channels */
int has_2nd_bulk_in_ep;
};
struct brcmf_usbdev_info;
struct brcmf_usbdev {
struct brcmf_bus *bus;
struct brcmf_usbdev_info *devinfo;
enum brcmf_usb_state state;
struct brcmf_stats stats;
int ntxq, nrxq, rxsize;
u32 bus_mtu;
struct brcmf_usb_attrib attrib;
};
/* IO Request Block (IRB) */
struct brcmf_usbreq {
struct list_head list;
struct brcmf_usbdev_info *devinfo;
struct urb *urb;
struct sk_buff *skb;
};
#endif /* BRCMFMAC_USB_H */

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2011 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.
*
* 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 _USB_RDL_H
#define _USB_RDL_H
/* Control messages: bRequest values */
#define DL_GETSTATE 0 /* returns the rdl_state_t struct */
#define DL_CHECK_CRC 1 /* currently unused */
#define DL_GO 2 /* execute downloaded image */
#define DL_START 3 /* initialize dl state */
#define DL_REBOOT 4 /* reboot the device in 2 seconds */
#define DL_GETVER 5 /* returns the bootrom_id_t struct */
#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset
* event to occur in 2 seconds. It is the
* responsibility of the downloaded code to
* clear this event
*/
#define DL_EXEC 7 /* jump to a supplied address */
#define DL_RESETCFG 8 /* To support single enum on dongle
* - Not used by bootloader
*/
#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup
* if resp unavailable
*/
/* states */
#define DL_WAITING 0 /* waiting to rx first pkt */
#define DL_READY 1 /* hdr was good, waiting for more of the
* compressed image */
#define DL_BAD_HDR 2 /* hdr was corrupted */
#define DL_BAD_CRC 3 /* compressed image was corrupted */
#define DL_RUNNABLE 4 /* download was successful,waiting for go cmd */
#define DL_START_FAIL 5 /* failed to initialize correctly */
#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM
* value */
#define DL_IMAGE_TOOBIG 7 /* download image too big (exceeds DATA_START
* for rdl) */
struct rdl_state_le {
__le32 state;
__le32 bytes;
};
struct bootrom_id_le {
__le32 chip; /* Chip id */
__le32 chiprev; /* Chip rev */
__le32 ramsize; /* Size of RAM */
__le32 remapbase; /* Current remap base address */
__le32 boardtype; /* Type of board */
__le32 boardrev; /* Board revision */
};
#define RDL_CHUNK 1500 /* size of each dl transfer */
#define TRX_OFFSETS_DLFWLEN_IDX 0
#define TRX_OFFSETS_JUMPTO_IDX 1
#define TRX_OFFSETS_NVM_LEN_IDX 2
#define TRX_OFFSETS_DLBASE_IDX 0
#endif /* _USB_RDL_H */

View File

@ -1376,7 +1376,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
memset(&join_params, 0, sizeof(join_params)); memset(&join_params, 0, sizeof(join_params));
join_params_size = sizeof(join_params.ssid_le); join_params_size = sizeof(join_params.ssid_le);
ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len); ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len); memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len); memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
@ -3297,7 +3297,9 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
} }
/* /*
** push event to tail of the queue * push event to tail of the queue
*
* remark: this function may not sleep as it is called in atomic context.
*/ */
static s32 static s32
@ -3306,17 +3308,18 @@ brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
{ {
struct brcmf_cfg80211_event_q *e; struct brcmf_cfg80211_event_q *e;
s32 err = 0; s32 err = 0;
ulong flags;
e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL); e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
if (!e) if (!e)
return -ENOMEM; return -ENOMEM;
e->etype = event; e->etype = event;
memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
spin_lock_irq(&cfg_priv->evt_q_lock); spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list); list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
spin_unlock_irq(&cfg_priv->evt_q_lock); spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
return err; return err;
} }

View File

@ -1136,8 +1136,8 @@ static int brcms_suspend(struct bcma_device *pdev)
hw = bcma_get_drvdata(pdev); hw = bcma_get_drvdata(pdev);
wl = hw->priv; wl = hw->priv;
if (!wl) { if (!wl) {
wiphy_err(wl->wiphy, pr_err("%s: %s: no driver private struct!\n", KBUILD_MODNAME,
"brcms_suspend: bcma_get_drvdata failed\n"); __func__);
return -ENODEV; return -ENODEV;
} }

View File

@ -2901,7 +2901,6 @@ brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
objoff += 2; objoff += 2;
return bcma_read16(core, objoff); return bcma_read16(core, objoff);
;
} }
static void static void

View File

@ -17824,8 +17824,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
if (pi->sh->sromrev < 4) { if (pi->sh->sromrev < 4) {
idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
target_pwr_qtrdbm[0] = 13 * 4;
target_pwr_qtrdbm[1] = 13 * 4;
a1[0] = -424; a1[0] = -424;
a1[1] = -424; a1[1] = -424;
b0[0] = 5612; b0[0] = 5612;
@ -17839,10 +17837,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
case WL_CHAN_FREQ_RANGE_2G: case WL_CHAN_FREQ_RANGE_2G:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
target_pwr_qtrdbm[0] =
pi->nphy_pwrctrl_info[0].max_pwr_2g;
target_pwr_qtrdbm[1] =
pi->nphy_pwrctrl_info[1].max_pwr_2g;
a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1;
a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0;
@ -17853,10 +17847,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
case WL_CHAN_FREQ_RANGE_5GL: case WL_CHAN_FREQ_RANGE_5GL:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
target_pwr_qtrdbm[0] =
pi->nphy_pwrctrl_info[0].max_pwr_5gl;
target_pwr_qtrdbm[1] =
pi->nphy_pwrctrl_info[1].max_pwr_5gl;
a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1;
a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0;
@ -17867,10 +17857,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
case WL_CHAN_FREQ_RANGE_5GM: case WL_CHAN_FREQ_RANGE_5GM:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
target_pwr_qtrdbm[0] =
pi->nphy_pwrctrl_info[0].max_pwr_5gm;
target_pwr_qtrdbm[1] =
pi->nphy_pwrctrl_info[1].max_pwr_5gm;
a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1;
a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0;
@ -17881,10 +17867,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
case WL_CHAN_FREQ_RANGE_5GH: case WL_CHAN_FREQ_RANGE_5GH:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g;
idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g;
target_pwr_qtrdbm[0] =
pi->nphy_pwrctrl_info[0].max_pwr_5gh;
target_pwr_qtrdbm[1] =
pi->nphy_pwrctrl_info[1].max_pwr_5gh;
a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1;
a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0;
@ -17895,8 +17877,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
default: default:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g;
idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g;
target_pwr_qtrdbm[0] = 13 * 4;
target_pwr_qtrdbm[1] = 13 * 4;
a1[0] = -424; a1[0] = -424;
a1[1] = -424; a1[1] = -424;
b0[0] = 5612; b0[0] = 5612;
@ -17907,6 +17887,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
} }
} }
/* use the provided transmit power */
target_pwr_qtrdbm[0] = (s8) pi->tx_power_max; target_pwr_qtrdbm[0] = (s8) pi->tx_power_max;
target_pwr_qtrdbm[1] = (s8) pi->tx_power_max; target_pwr_qtrdbm[1] = (s8) pi->tx_power_max;
@ -19989,11 +19970,10 @@ static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
switch (pi->pubpi.radiorev) { switch (pi->pubpi.radiorev) {
case 5: case 5:
if (pi->pubpi.radiover == 0x0) if (NREV_IS(pi->pubpi.phy_rev, 8))
regs_2057_ptr = regs_2057_rev5; regs_2057_ptr = regs_2057_rev5;
else if (pi->pubpi.radiover == 0x1) else if (NREV_IS(pi->pubpi.phy_rev, 9))
regs_2057_ptr = regs_2057_rev5v1; regs_2057_ptr = regs_2057_rev5v1;
else
break; break;
case 7: case 7:

View File

@ -621,7 +621,7 @@ static inline void cpu_to_le16_buf(u16 *buf, uint nwords)
/* /*
* convert binary srom data into linked list of srom variable items. * convert binary srom data into linked list of srom variable items.
*/ */
static void static int
_initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
{ {
struct brcms_srom_list_head *entry; struct brcms_srom_list_head *entry;
@ -638,6 +638,9 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
/* first store the srom revision */ /* first store the srom revision */
entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->varid = BRCMS_SROM_REV; entry->varid = BRCMS_SROM_REV;
entry->var_type = BRCMS_SROM_UNUMBER; entry->var_type = BRCMS_SROM_UNUMBER;
entry->uval = sromrev; entry->uval = sromrev;
@ -715,6 +718,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
entry = kzalloc(sizeof(struct brcms_srom_list_head) + entry = kzalloc(sizeof(struct brcms_srom_list_head) +
extra_space, GFP_KERNEL); extra_space, GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->varid = id; entry->varid = id;
entry->var_type = type; entry->var_type = type;
if (flags & SRFL_ETHADDR) { if (flags & SRFL_ETHADDR) {
@ -754,6 +759,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
entry = entry =
kzalloc(sizeof(struct brcms_srom_list_head), kzalloc(sizeof(struct brcms_srom_list_head),
GFP_KERNEL); GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->varid = srv->varid+p; entry->varid = srv->varid+p;
entry->var_type = BRCMS_SROM_UNUMBER; entry->var_type = BRCMS_SROM_UNUMBER;
entry->uval = val; entry->uval = val;
@ -761,6 +768,7 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
} }
pb += psz; pb += psz;
} }
return 0;
} }
/* /*
@ -906,7 +914,9 @@ int srom_var_init(struct si_pub *sih)
INIT_LIST_HEAD(&sii->var_list); INIT_LIST_HEAD(&sii->var_list);
/* parse SROM into name=value pairs. */ /* parse SROM into name=value pairs. */
_initvars_srom_pci(sromrev, srom, &sii->var_list); err = _initvars_srom_pci(sromrev, srom, &sii->var_list);
if (err)
srom_free_vars(sih);
} }
errout: errout:

View File

@ -309,13 +309,6 @@ static const long ipw2100_frequencies[] = {
#define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies) #define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies)
static const long ipw2100_rates_11b[] = {
1000000,
2000000,
5500000,
11000000
};
static struct ieee80211_rate ipw2100_bg_rates[] = { static struct ieee80211_rate ipw2100_bg_rates[] = {
{ .bitrate = 10 }, { .bitrate = 10 },
{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
@ -323,7 +316,7 @@ static struct ieee80211_rate ipw2100_bg_rates[] = {
{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
}; };
#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b) #define RATE_COUNT ARRAY_SIZE(ipw2100_bg_rates)
/* Pre-decl until we get the code solid and then we can clean it up */ /* Pre-decl until we get the code solid and then we can clean it up */
static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
@ -6893,7 +6886,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
range->num_bitrates = RATE_COUNT; range->num_bitrates = RATE_COUNT;
for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
range->bitrate[i] = ipw2100_rates_11b[i]; range->bitrate[i] = ipw2100_bg_rates[i].bitrate * 100 * 1000;
} }
range->min_rts = MIN_RTS_THRESHOLD; range->min_rts = MIN_RTS_THRESHOLD;
@ -8105,61 +8098,41 @@ static int ipw2100_wx_get_crc_check(struct net_device *dev,
#endif /* CONFIG_IPW2100_MONITOR */ #endif /* CONFIG_IPW2100_MONITOR */
static iw_handler ipw2100_wx_handlers[] = { static iw_handler ipw2100_wx_handlers[] = {
NULL, /* SIOCSIWCOMMIT */ IW_HANDLER(SIOCGIWNAME, ipw2100_wx_get_name),
ipw2100_wx_get_name, /* SIOCGIWNAME */ IW_HANDLER(SIOCSIWFREQ, ipw2100_wx_set_freq),
NULL, /* SIOCSIWNWID */ IW_HANDLER(SIOCGIWFREQ, ipw2100_wx_get_freq),
NULL, /* SIOCGIWNWID */ IW_HANDLER(SIOCSIWMODE, ipw2100_wx_set_mode),
ipw2100_wx_set_freq, /* SIOCSIWFREQ */ IW_HANDLER(SIOCGIWMODE, ipw2100_wx_get_mode),
ipw2100_wx_get_freq, /* SIOCGIWFREQ */ IW_HANDLER(SIOCGIWRANGE, ipw2100_wx_get_range),
ipw2100_wx_set_mode, /* SIOCSIWMODE */ IW_HANDLER(SIOCSIWAP, ipw2100_wx_set_wap),
ipw2100_wx_get_mode, /* SIOCGIWMODE */ IW_HANDLER(SIOCGIWAP, ipw2100_wx_get_wap),
NULL, /* SIOCSIWSENS */ IW_HANDLER(SIOCSIWMLME, ipw2100_wx_set_mlme),
NULL, /* SIOCGIWSENS */ IW_HANDLER(SIOCSIWSCAN, ipw2100_wx_set_scan),
NULL, /* SIOCSIWRANGE */ IW_HANDLER(SIOCGIWSCAN, ipw2100_wx_get_scan),
ipw2100_wx_get_range, /* SIOCGIWRANGE */ IW_HANDLER(SIOCSIWESSID, ipw2100_wx_set_essid),
NULL, /* SIOCSIWPRIV */ IW_HANDLER(SIOCGIWESSID, ipw2100_wx_get_essid),
NULL, /* SIOCGIWPRIV */ IW_HANDLER(SIOCSIWNICKN, ipw2100_wx_set_nick),
NULL, /* SIOCSIWSTATS */ IW_HANDLER(SIOCGIWNICKN, ipw2100_wx_get_nick),
NULL, /* SIOCGIWSTATS */ IW_HANDLER(SIOCSIWRATE, ipw2100_wx_set_rate),
NULL, /* SIOCSIWSPY */ IW_HANDLER(SIOCGIWRATE, ipw2100_wx_get_rate),
NULL, /* SIOCGIWSPY */ IW_HANDLER(SIOCSIWRTS, ipw2100_wx_set_rts),
NULL, /* SIOCGIWTHRSPY */ IW_HANDLER(SIOCGIWRTS, ipw2100_wx_get_rts),
NULL, /* SIOCWIWTHRSPY */ IW_HANDLER(SIOCSIWFRAG, ipw2100_wx_set_frag),
ipw2100_wx_set_wap, /* SIOCSIWAP */ IW_HANDLER(SIOCGIWFRAG, ipw2100_wx_get_frag),
ipw2100_wx_get_wap, /* SIOCGIWAP */ IW_HANDLER(SIOCSIWTXPOW, ipw2100_wx_set_txpow),
ipw2100_wx_set_mlme, /* SIOCSIWMLME */ IW_HANDLER(SIOCGIWTXPOW, ipw2100_wx_get_txpow),
NULL, /* SIOCGIWAPLIST -- deprecated */ IW_HANDLER(SIOCSIWRETRY, ipw2100_wx_set_retry),
ipw2100_wx_set_scan, /* SIOCSIWSCAN */ IW_HANDLER(SIOCGIWRETRY, ipw2100_wx_get_retry),
ipw2100_wx_get_scan, /* SIOCGIWSCAN */ IW_HANDLER(SIOCSIWENCODE, ipw2100_wx_set_encode),
ipw2100_wx_set_essid, /* SIOCSIWESSID */ IW_HANDLER(SIOCGIWENCODE, ipw2100_wx_get_encode),
ipw2100_wx_get_essid, /* SIOCGIWESSID */ IW_HANDLER(SIOCSIWPOWER, ipw2100_wx_set_power),
ipw2100_wx_set_nick, /* SIOCSIWNICKN */ IW_HANDLER(SIOCGIWPOWER, ipw2100_wx_get_power),
ipw2100_wx_get_nick, /* SIOCGIWNICKN */ IW_HANDLER(SIOCSIWGENIE, ipw2100_wx_set_genie),
NULL, /* -- hole -- */ IW_HANDLER(SIOCGIWGENIE, ipw2100_wx_get_genie),
NULL, /* -- hole -- */ IW_HANDLER(SIOCSIWAUTH, ipw2100_wx_set_auth),
ipw2100_wx_set_rate, /* SIOCSIWRATE */ IW_HANDLER(SIOCGIWAUTH, ipw2100_wx_get_auth),
ipw2100_wx_get_rate, /* SIOCGIWRATE */ IW_HANDLER(SIOCSIWENCODEEXT, ipw2100_wx_set_encodeext),
ipw2100_wx_set_rts, /* SIOCSIWRTS */ IW_HANDLER(SIOCGIWENCODEEXT, ipw2100_wx_get_encodeext),
ipw2100_wx_get_rts, /* SIOCGIWRTS */
ipw2100_wx_set_frag, /* SIOCSIWFRAG */
ipw2100_wx_get_frag, /* SIOCGIWFRAG */
ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
ipw2100_wx_set_retry, /* SIOCSIWRETRY */
ipw2100_wx_get_retry, /* SIOCGIWRETRY */
ipw2100_wx_set_encode, /* SIOCSIWENCODE */
ipw2100_wx_get_encode, /* SIOCGIWENCODE */
ipw2100_wx_set_power, /* SIOCSIWPOWER */
ipw2100_wx_get_power, /* SIOCGIWPOWER */
NULL, /* -- hole -- */
NULL, /* -- hole -- */
ipw2100_wx_set_genie, /* SIOCSIWGENIE */
ipw2100_wx_get_genie, /* SIOCGIWGENIE */
ipw2100_wx_set_auth, /* SIOCSIWAUTH */
ipw2100_wx_get_auth, /* SIOCGIWAUTH */
ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
NULL, /* SIOCSIWPMKSA */
}; };
#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV #define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV

View File

@ -503,3 +503,9 @@ il3945_ucode_general_stats_read(struct file *file, char __user *user_buf,
kfree(buf); kfree(buf);
return ret; return ret;
} }
const struct il_debugfs_ops il3945_debugfs_ops = {
.rx_stats_read = il3945_ucode_rx_stats_read,
.tx_stats_read = il3945_ucode_tx_stats_read,
.general_stats_read = il3945_ucode_general_stats_read,
};

View File

@ -573,7 +573,6 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
len = (u16) skb->len; len = (u16) skb->len;
tx_cmd->len = cpu_to_le16(len); tx_cmd->len = cpu_to_le16(len);
il_dbg_log_tx_data_frame(il, len, hdr);
il_update_stats(il, true, fc, len); il_update_stats(il, true, fc, len);
tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
@ -616,7 +615,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
/* Add buffer containing Tx command and MAC(!) header to TFD's /* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */ * first entry */
il->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0);
/* Set up TFD's 2nd entry to point directly to remainder of skb, /* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */ * if any (802.11 null frames have no payload). */
@ -625,7 +624,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
phys_addr = phys_addr =
pci_map_single(il->pci_dev, skb->data + hdr_len, len, pci_map_single(il->pci_dev, skb->data + hdr_len, len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
U32_PAD(len)); U32_PAD(len));
} }
@ -810,16 +809,16 @@ il3945_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb)
_il_wr(il, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); _il_wr(il, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
if (flags & HW_CARD_DISABLED) if (flags & HW_CARD_DISABLED)
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
else else
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
il_scan_cancel(il); il_scan_cancel(il);
if ((test_bit(S_RF_KILL_HW, &status) != if ((test_bit(S_RFKILL, &status) !=
test_bit(S_RF_KILL_HW, &il->status))) test_bit(S_RFKILL, &il->status)))
wiphy_rfkill_set_hw_state(il->hw->wiphy, wiphy_rfkill_set_hw_state(il->hw->wiphy,
test_bit(S_RF_KILL_HW, &il->status)); test_bit(S_RFKILL, &il->status));
else else
wake_up(&il->wait_command_queue); wake_up(&il->wait_command_queue);
} }
@ -2167,7 +2166,7 @@ il3945_alive_start(struct il_priv *il)
D_INFO("RFKILL status: 0x%x\n", rfkill); D_INFO("RFKILL status: 0x%x\n", rfkill);
if (rfkill & 0x1) { if (rfkill & 0x1) {
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
/* if RFKILL is not on, then wait for thermal /* if RFKILL is not on, then wait for thermal
* sensor in adapter to kick in */ * sensor in adapter to kick in */
while (il3945_hw_get_temperature(il) == 0) { while (il3945_hw_get_temperature(il) == 0) {
@ -2179,7 +2178,7 @@ il3945_alive_start(struct il_priv *il)
D_INFO("Thermal calibration took %dus\n", D_INFO("Thermal calibration took %dus\n",
thermal_spin * 10); thermal_spin * 10);
} else } else
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
/* After the ALIVE response, we can send commands to 3945 uCode */ /* After the ALIVE response, we can send commands to 3945 uCode */
set_bit(S_ALIVE, &il->status); set_bit(S_ALIVE, &il->status);
@ -2273,12 +2272,8 @@ __il3945_down(struct il_priv *il)
* clear all bits but the RF Kill bits and return */ * clear all bits but the RF Kill bits and return */
if (!il_is_init(il)) { if (!il_is_init(il)) {
il->status = il->status =
test_bit(S_RF_KILL_HW, test_bit(S_RFKILL, &il->status) << S_RFKILL |
&il-> test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
status) << S_RF_KILL_HW |
test_bit(S_GEO_CONFIGURED,
&il->
status) << S_GEO_CONFIGURED |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
goto exit; goto exit;
} }
@ -2286,25 +2281,30 @@ __il3945_down(struct il_priv *il)
/* ...otherwise clear out all the status bits but the RF Kill /* ...otherwise clear out all the status bits but the RF Kill
* bit and continue taking the NIC down. */ * bit and continue taking the NIC down. */
il->status &= il->status &=
test_bit(S_RF_KILL_HW, test_bit(S_RFKILL, &il->status) << S_RFKILL |
&il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED, test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
&il-> test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
status) <<
S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
&il->
status) << S_FW_ERROR |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
/*
* We disabled and synchronized interrupt, and priv->mutex is taken, so
* here is the only thread which will program device registers, but
* still have lockdep assertions, so we are taking reg_lock.
*/
spin_lock_irq(&il->reg_lock);
/* FIXME: il_grab_nic_access if rfkill is off ? */
il3945_hw_txq_ctx_stop(il); il3945_hw_txq_ctx_stop(il);
il3945_hw_rxq_stop(il); il3945_hw_rxq_stop(il);
/* Power-down device's busmaster DMA clocks */ /* Power-down device's busmaster DMA clocks */
il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5); udelay(5);
/* Stop the device, and put it in low power state */ /* Stop the device, and put it in low power state */
il_apm_stop(il); _il_apm_stop(il);
spin_unlock_irq(&il->reg_lock);
il3945_hw_txq_ctx_free(il);
exit: exit:
memset(&il->card_alive, 0, sizeof(struct il_alive_resp)); memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
@ -2371,9 +2371,9 @@ __il3945_up(struct il_priv *il)
/* If platform's RF_KILL switch is NOT set to KILL */ /* If platform's RF_KILL switch is NOT set to KILL */
if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
else { else {
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
IL_WARN("Radio disabled by HW RF Kill switch\n"); IL_WARN("Radio disabled by HW RF Kill switch\n");
return -ENODEV; return -ENODEV;
} }
@ -2405,7 +2405,7 @@ __il3945_up(struct il_priv *il)
il->ucode_data.len); il->ucode_data.len);
/* We return success when we resume from suspend and rf_kill is on. */ /* We return success when we resume from suspend and rf_kill is on. */
if (test_bit(S_RF_KILL_HW, &il->status)) if (test_bit(S_RFKILL, &il->status))
return 0; return 0;
for (i = 0; i < MAX_HW_RESTARTS; i++) { for (i = 0; i < MAX_HW_RESTARTS; i++) {
@ -2413,7 +2413,7 @@ __il3945_up(struct il_priv *il)
/* load bootstrap state machine, /* load bootstrap state machine,
* load bootstrap program into processor's memory, * load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */ * prepare to load the "initialize" uCode */
rc = il->ops->lib->load_ucode(il); rc = il->ops->load_ucode(il);
if (rc) { if (rc) {
IL_ERR("Unable to set up bootstrap uCode: %d\n", rc); IL_ERR("Unable to set up bootstrap uCode: %d\n", rc);
@ -2485,15 +2485,15 @@ il3945_rfkill_poll(struct work_struct *data)
{ {
struct il_priv *il = struct il_priv *il =
container_of(data, struct il_priv, _3945.rfkill_poll.work); container_of(data, struct il_priv, _3945.rfkill_poll.work);
bool old_rfkill = test_bit(S_RF_KILL_HW, &il->status); bool old_rfkill = test_bit(S_RFKILL, &il->status);
bool new_rfkill = bool new_rfkill =
!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); !(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
if (new_rfkill != old_rfkill) { if (new_rfkill != old_rfkill) {
if (new_rfkill) if (new_rfkill)
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
else else
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy, new_rfkill); wiphy_rfkill_set_hw_state(il->hw->wiphy, new_rfkill);
@ -2782,10 +2782,9 @@ il3945_mac_start(struct ieee80211_hw *hw)
struct il_priv *il = hw->priv; struct il_priv *il = hw->priv;
int ret; int ret;
D_MAC80211("enter\n");
/* we should be verifying the device is ready to be opened */ /* we should be verifying the device is ready to be opened */
mutex_lock(&il->mutex); mutex_lock(&il->mutex);
D_MAC80211("enter\n");
/* fetch ucode file from disk, alloc and copy to bus-master buffers ... /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */ * ucode filename and max sizes are card-specific. */
@ -2941,16 +2940,20 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
* hardware will then not attempt to decrypt the frames. * hardware will then not attempt to decrypt the frames.
*/ */
if (vif->type == NL80211_IFTYPE_ADHOC && if (vif->type == NL80211_IFTYPE_ADHOC &&
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
D_MAC80211("leave - IBSS RSN\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
}
static_key = !il_is_associated(il); static_key = !il_is_associated(il);
if (!static_key) { if (!static_key) {
sta_id = il_sta_id_or_broadcast(il, sta); sta_id = il_sta_id_or_broadcast(il, sta);
if (sta_id == IL_INVALID_STATION) if (sta_id == IL_INVALID_STATION) {
D_MAC80211("leave - station not found\n");
return -EINVAL; return -EINVAL;
} }
}
mutex_lock(&il->mutex); mutex_lock(&il->mutex);
il_scan_cancel_timeout(il, 100); il_scan_cancel_timeout(il, 100);
@ -2974,8 +2977,8 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = -EINVAL; ret = -EINVAL;
} }
D_MAC80211("leave ret %d\n", ret);
mutex_unlock(&il->mutex); mutex_unlock(&il->mutex);
D_MAC80211("leave\n");
return ret; return ret;
} }
@ -2990,9 +2993,8 @@ il3945_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
bool is_ap = vif->type == NL80211_IFTYPE_STATION; bool is_ap = vif->type == NL80211_IFTYPE_STATION;
u8 sta_id; u8 sta_id;
D_INFO("received request to add station %pM\n", sta->addr);
mutex_lock(&il->mutex); mutex_lock(&il->mutex);
D_INFO("proceeding to add station %pM\n", sta->addr); D_INFO("station %pM\n", sta->addr);
sta_priv->common.sta_id = IL_INVALID_STATION; sta_priv->common.sta_id = IL_INVALID_STATION;
ret = il_add_station_common(il, sta->addr, is_ap, sta, &sta_id); ret = il_add_station_common(il, sta->addr, is_ap, sta, &sta_id);
@ -3098,11 +3100,9 @@ il3945_store_debug_level(struct device *d, struct device_attribute *attr,
ret = strict_strtoul(buf, 0, &val); ret = strict_strtoul(buf, 0, &val);
if (ret) if (ret)
IL_INFO("%s is not in hex or decimal form.\n", buf); IL_INFO("%s is not in hex or decimal form.\n", buf);
else { else
il->debug_level = val; il->debug_level = val;
if (il_alloc_traffic_mem(il))
IL_ERR("Not enough memory to generate traffic log\n");
}
return strnlen(buf, count); return strnlen(buf, count);
} }
@ -3619,12 +3619,12 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
D_INFO("*** LOAD DRIVER ***\n"); D_INFO("*** LOAD DRIVER ***\n");
il->cfg = cfg; il->cfg = cfg;
il->ops = &il3945_ops; il->ops = &il3945_ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
il->debugfs_ops = &il3945_debugfs_ops;
#endif
il->pci_dev = pdev; il->pci_dev = pdev;
il->inta_mask = CSR_INI_SET_MASK; il->inta_mask = CSR_INI_SET_MASK;
if (il_alloc_traffic_mem(il))
IL_ERR("Not enough memory to generate traffic log\n");
/*************************** /***************************
* 2. Initializing PCI bus * 2. Initializing PCI bus
* *************************/ * *************************/
@ -3655,7 +3655,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/*********************** /***********************
* 3. Read REV Register * 3. Read REV Register
* ********************/ * ********************/
il->hw_base = pci_iomap(pdev, 0, 0); il->hw_base = pci_ioremap_bar(pdev, 0);
if (!il->hw_base) { if (!il->hw_base) {
err = -ENODEV; err = -ENODEV;
goto out_pci_release_regions; goto out_pci_release_regions;
@ -3669,7 +3669,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* PCI Tx retries from interfering with C3 CPU state */ * PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, 0x41, 0x00); pci_write_config_byte(pdev, 0x41, 0x00);
/* these spin locks will be used in apm_ops.init and EEPROM access /* these spin locks will be used in apm_init and EEPROM access
* we should init now * we should init now
*/ */
spin_lock_init(&il->reg_lock); spin_lock_init(&il->reg_lock);
@ -3780,14 +3780,13 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_eeprom_free: out_eeprom_free:
il_eeprom_free(il); il_eeprom_free(il);
out_iounmap: out_iounmap:
pci_iounmap(pdev, il->hw_base); iounmap(il->hw_base);
out_pci_release_regions: out_pci_release_regions:
pci_release_regions(pdev); pci_release_regions(pdev);
out_pci_disable_device: out_pci_disable_device:
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev); pci_disable_device(pdev);
out_ieee80211_free_hw: out_ieee80211_free_hw:
il_free_traffic_mem(il);
ieee80211_free_hw(il->hw); ieee80211_free_hw(il->hw);
out: out:
return err; return err;
@ -3855,12 +3854,11 @@ il3945_pci_remove(struct pci_dev *pdev)
* until now... */ * until now... */
destroy_workqueue(il->workqueue); destroy_workqueue(il->workqueue);
il->workqueue = NULL; il->workqueue = NULL;
il_free_traffic_mem(il);
free_irq(pdev->irq, il); free_irq(pdev->irq, il);
pci_disable_msi(pdev); pci_disable_msi(pdev);
pci_iounmap(pdev, il->hw_base); iounmap(il->hw_base);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);

View File

@ -57,10 +57,6 @@ il3945_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)
return il_send_cmd(il, &cmd); return il_send_cmd(il, &cmd);
} }
const struct il_led_ops il3945_led_ops = {
.cmd = il3945_send_led_cmd,
};
#define IL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ #define IL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[RATE_##r##M_IDX] = { RATE_##r##M_PLCP, \ [RATE_##r##M_IDX] = { RATE_##r##M_PLCP, \
RATE_##r##M_IEEE, \ RATE_##r##M_IEEE, \
@ -303,7 +299,7 @@ il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
skb = txq->skbs[txq->q.read_ptr]; skb = txq->skbs[txq->q.read_ptr];
ieee80211_tx_status_irqsafe(il->hw, skb); ieee80211_tx_status_irqsafe(il->hw, skb);
txq->skbs[txq->q.read_ptr] = NULL; txq->skbs[txq->q.read_ptr] = NULL;
il->ops->lib->txq_free_tfd(il, txq); il->ops->txq_free_tfd(il, txq);
} }
if (il_queue_space(q) > q->low_mark && txq_id >= 0 && if (il_queue_space(q) > q->low_mark && txq_id >= 0 &&
@ -577,8 +573,6 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel), network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel),
rx_status.signal, rx_status.signal, rx_status.rate_idx); rx_status.signal, rx_status.signal, rx_status.rate_idx);
il_dbg_log_rx_data_frame(il, le16_to_cpu(rx_hdr->len), header);
if (network_packet) { if (network_packet) {
il->_3945.last_beacon_time = il->_3945.last_beacon_time =
le32_to_cpu(rx_end->beacon_timestamp); le32_to_cpu(rx_end->beacon_timestamp);
@ -796,7 +790,6 @@ il3945_rx_init(struct il_priv *il, struct il_rx_queue *rxq)
static int static int
il3945_tx_reset(struct il_priv *il) il3945_tx_reset(struct il_priv *il)
{ {
/* bypass mode */ /* bypass mode */
il_wr_prph(il, ALM_SCD_MODE_REG, 0x2); il_wr_prph(il, ALM_SCD_MODE_REG, 0x2);
@ -833,8 +826,7 @@ il3945_tx_reset(struct il_priv *il)
static int static int
il3945_txq_ctx_reset(struct il_priv *il) il3945_txq_ctx_reset(struct il_priv *il)
{ {
int rc; int rc, txq_id;
int txq_id, slots_num;
il3945_hw_txq_ctx_free(il); il3945_hw_txq_ctx_free(il);
@ -850,10 +842,7 @@ il3945_txq_ctx_reset(struct il_priv *il)
/* Tx queue(s) */ /* Tx queue(s) */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
slots_num = rc = il_tx_queue_init(il, txq_id);
(txq_id ==
IL39_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
rc = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id);
if (rc) { if (rc) {
IL_ERR("Tx %d queue init failed\n", txq_id); IL_ERR("Tx %d queue init failed\n", txq_id);
goto error; goto error;
@ -958,12 +947,11 @@ il3945_hw_nic_init(struct il_priv *il)
struct il_rx_queue *rxq = &il->rxq; struct il_rx_queue *rxq = &il->rxq;
spin_lock_irqsave(&il->lock, flags); spin_lock_irqsave(&il->lock, flags);
il->ops->lib->apm_ops.init(il); il3945_apm_init(il);
spin_unlock_irqrestore(&il->lock, flags); spin_unlock_irqrestore(&il->lock, flags);
il3945_set_pwr_vmain(il); il3945_set_pwr_vmain(il);
il3945_nic_config(il);
il->ops->lib->apm_ops.config(il);
/* Allocate the RX queue, or reset if it is already allocated */ /* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) { if (!rxq->bd) {
@ -1014,7 +1002,7 @@ il3945_hw_txq_ctx_free(struct il_priv *il)
il_tx_queue_free(il, txq_id); il_tx_queue_free(il, txq_id);
/* free tx queue structure */ /* free tx queue structure */
il_txq_mem(il); il_free_txq_mem(il);
} }
void void
@ -1023,18 +1011,17 @@ il3945_hw_txq_ctx_stop(struct il_priv *il)
int txq_id; int txq_id;
/* stop SCD */ /* stop SCD */
il_wr_prph(il, ALM_SCD_MODE_REG, 0); _il_wr_prph(il, ALM_SCD_MODE_REG, 0);
il_wr_prph(il, ALM_SCD_TXFACT_REG, 0); _il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
/* reset TFD queues */ /* reset TFD queues */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0); _il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
il_poll_bit(il, FH39_TSSR_TX_STATUS, _il_poll_bit(il, FH39_TSSR_TX_STATUS,
FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1000); 1000);
} }
il3945_hw_txq_ctx_free(il);
} }
/** /**
@ -1613,7 +1600,7 @@ il3945_hw_reg_comp_txpower_temp(struct il_priv *il)
} }
/* send Txpower command for current channel to ucode */ /* send Txpower command for current channel to ucode */
return il->ops->lib->send_tx_power(il); return il->ops->send_tx_power(il);
} }
int int
@ -2183,12 +2170,14 @@ il3945_txpower_set_from_eeprom(struct il_priv *il)
int int
il3945_hw_rxq_stop(struct il_priv *il) il3945_hw_rxq_stop(struct il_priv *il)
{ {
int rc; int ret;
il_wr(il, FH39_RCSR_CONFIG(0), 0); _il_wr(il, FH39_RCSR_CONFIG(0), 0);
rc = il_poll_bit(il, FH39_RSSR_STATUS, ret = _il_poll_bit(il, FH39_RSSR_STATUS,
FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
if (rc < 0) FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
1000);
if (ret < 0)
IL_ERR("Can't stop Rx DMA.\n"); IL_ERR("Can't stop Rx DMA.\n");
return 0; return 0;
@ -2630,65 +2619,31 @@ il3945_load_bsm(struct il_priv *il)
return 0; return 0;
} }
static struct il_hcmd_ops il3945_hcmd = { const struct il_ops il3945_ops = {
.rxon_assoc = il3945_send_rxon_assoc,
.commit_rxon = il3945_commit_rxon,
};
static struct il_lib_ops il3945_lib = {
.txq_attach_buf_to_tfd = il3945_hw_txq_attach_buf_to_tfd, .txq_attach_buf_to_tfd = il3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = il3945_hw_txq_free_tfd, .txq_free_tfd = il3945_hw_txq_free_tfd,
.txq_init = il3945_hw_tx_queue_init, .txq_init = il3945_hw_tx_queue_init,
.load_ucode = il3945_load_bsm, .load_ucode = il3945_load_bsm,
.dump_nic_error_log = il3945_dump_nic_error_log, .dump_nic_error_log = il3945_dump_nic_error_log,
.apm_ops = { .apm_init = il3945_apm_init,
.init = il3945_apm_init,
.config = il3945_nic_config,
},
.eeprom_ops = {
.regulatory_bands = {
EEPROM_REGULATORY_BAND_1_CHANNELS,
EEPROM_REGULATORY_BAND_2_CHANNELS,
EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_REGULATORY_BAND_NO_HT40,
EEPROM_REGULATORY_BAND_NO_HT40,
},
.acquire_semaphore = il3945_eeprom_acquire_semaphore,
.release_semaphore = il3945_eeprom_release_semaphore,
},
.send_tx_power = il3945_send_tx_power, .send_tx_power = il3945_send_tx_power,
.is_valid_rtc_data_addr = il3945_hw_valid_rtc_data_addr, .is_valid_rtc_data_addr = il3945_hw_valid_rtc_data_addr,
.eeprom_acquire_semaphore = il3945_eeprom_acquire_semaphore,
.eeprom_release_semaphore = il3945_eeprom_release_semaphore,
#ifdef CONFIG_IWLEGACY_DEBUGFS .rxon_assoc = il3945_send_rxon_assoc,
.debugfs_ops = { .commit_rxon = il3945_commit_rxon,
.rx_stats_read = il3945_ucode_rx_stats_read,
.tx_stats_read = il3945_ucode_tx_stats_read,
.general_stats_read = il3945_ucode_general_stats_read,
},
#endif
};
static const struct il_legacy_ops il3945_legacy_ops = {
.post_associate = il3945_post_associate,
.config_ap = il3945_config_ap,
.manage_ibss_station = il3945_manage_ibss_station,
};
static struct il_hcmd_utils_ops il3945_hcmd_utils = {
.get_hcmd_size = il3945_get_hcmd_size, .get_hcmd_size = il3945_get_hcmd_size,
.build_addsta_hcmd = il3945_build_addsta_hcmd, .build_addsta_hcmd = il3945_build_addsta_hcmd,
.request_scan = il3945_request_scan, .request_scan = il3945_request_scan,
.post_scan = il3945_post_scan, .post_scan = il3945_post_scan,
};
const struct il_ops il3945_ops = { .post_associate = il3945_post_associate,
.lib = &il3945_lib, .config_ap = il3945_config_ap,
.hcmd = &il3945_hcmd, .manage_ibss_station = il3945_manage_ibss_station,
.utils = &il3945_hcmd_utils,
.led = &il3945_led_ops, .send_led_cmd = il3945_send_led_cmd,
.legacy = &il3945_legacy_ops,
}; };
static struct il_cfg il3945_bg_cfg = { static struct il_cfg il3945_bg_cfg = {
@ -2707,7 +2662,17 @@ static struct il_cfg il3945_bg_cfg = {
.set_l0s = false, .set_l0s = false,
.use_bsm = true, .use_bsm = true,
.led_compensation = 64, .led_compensation = 64,
.wd_timeout = IL_DEF_WD_TIMEOUT .wd_timeout = IL_DEF_WD_TIMEOUT,
.regulatory_bands = {
EEPROM_REGULATORY_BAND_1_CHANNELS,
EEPROM_REGULATORY_BAND_2_CHANNELS,
EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_REGULATORY_BAND_NO_HT40,
EEPROM_REGULATORY_BAND_NO_HT40,
},
}; };
static struct il_cfg il3945_abg_cfg = { static struct il_cfg il3945_abg_cfg = {
@ -2726,7 +2691,17 @@ static struct il_cfg il3945_abg_cfg = {
.set_l0s = false, .set_l0s = false,
.use_bsm = true, .use_bsm = true,
.led_compensation = 64, .led_compensation = 64,
.wd_timeout = IL_DEF_WD_TIMEOUT .wd_timeout = IL_DEF_WD_TIMEOUT,
.regulatory_bands = {
EEPROM_REGULATORY_BAND_1_CHANNELS,
EEPROM_REGULATORY_BAND_2_CHANNELS,
EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_REGULATORY_BAND_NO_HT40,
EEPROM_REGULATORY_BAND_NO_HT40,
},
}; };
DEFINE_PCI_DEVICE_TABLE(il3945_hw_card_ids) = { DEFINE_PCI_DEVICE_TABLE(il3945_hw_card_ids) = {

View File

@ -595,13 +595,7 @@ struct il3945_tfd {
} __packed; } __packed;
#ifdef CONFIG_IWLEGACY_DEBUGFS #ifdef CONFIG_IWLEGACY_DEBUGFS
ssize_t il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, extern const struct il_debugfs_ops il3945_debugfs_ops;
size_t count, loff_t *ppos);
ssize_t il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
ssize_t il3945_ucode_general_stats_read(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos);
#endif #endif
#endif #endif

View File

@ -79,18 +79,6 @@ struct stats_general_data {
u32 beacon_energy_c; u32 beacon_energy_c;
}; };
void
il4965_calib_free_results(struct il_priv *il)
{
int i;
for (i = 0; i < IL_CALIB_MAX; i++) {
kfree(il->calib_results[i].buf);
il->calib_results[i].buf = NULL;
il->calib_results[i].buf_len = 0;
}
}
/***************************************************************************** /*****************************************************************************
* RUNTIME calibrations framework * RUNTIME calibrations framework
*****************************************************************************/ *****************************************************************************/
@ -923,8 +911,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
/* Some power changes may have been made during the calibration. /* Some power changes may have been made during the calibration.
* Update and commit the RXON * Update and commit the RXON
*/ */
if (il->ops->lib->update_chain_flags) if (il->ops->update_chain_flags)
il->ops->lib->update_chain_flags(il); il->ops->update_chain_flags(il);
data->state = IL_CHAIN_NOISE_DONE; data->state = IL_CHAIN_NOISE_DONE;
il_power_update_mode(il, false); il_power_update_mode(il, false);

View File

@ -744,3 +744,9 @@ il4965_ucode_general_stats_read(struct file *file, char __user *user_buf,
kfree(buf); kfree(buf);
return ret; return ret;
} }
const struct il_debugfs_ops il4965_debugfs_ops = {
.rx_stats_read = il4965_ucode_rx_stats_read,
.tx_stats_read = il4965_ucode_tx_stats_read,
.general_stats_read = il4965_ucode_general_stats_read,
};

View File

@ -199,18 +199,14 @@ il4965_hw_nic_init(struct il_priv *il)
struct il_rx_queue *rxq = &il->rxq; struct il_rx_queue *rxq = &il->rxq;
int ret; int ret;
/* nic_init */
spin_lock_irqsave(&il->lock, flags); spin_lock_irqsave(&il->lock, flags);
il->ops->lib->apm_ops.init(il); il_apm_init(il);
/* Set interrupt coalescing calibration timer to default (512 usecs) */ /* Set interrupt coalescing calibration timer to default (512 usecs) */
il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF); il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF);
spin_unlock_irqrestore(&il->lock, flags); spin_unlock_irqrestore(&il->lock, flags);
il4965_set_pwr_vmain(il); il4965_set_pwr_vmain(il);
il4965_nic_config(il);
il->ops->lib->apm_ops.config(il);
/* Allocate the RX queue, or reset if it is already allocated */ /* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) { if (!rxq->bd) {
@ -445,11 +441,15 @@ il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq)
int int
il4965_rxq_stop(struct il_priv *il) il4965_rxq_stop(struct il_priv *il)
{ {
int ret;
/* stop Rx DMA */ _il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0); ret = _il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG, FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
1000);
if (ret < 0)
IL_ERR("Can't stop Rx DMA.\n");
return 0; return 0;
} }
@ -692,7 +692,6 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
/* Find max signal strength (dBm) among 3 antenna/receiver chains */ /* Find max signal strength (dBm) among 3 antenna/receiver chains */
rx_status.signal = il4965_calc_rssi(il, phy_res); rx_status.signal = il4965_calc_rssi(il, phy_res);
il_dbg_log_rx_data_frame(il, len, header);
D_STATS("Rssi %d, TSF %llu\n", rx_status.signal, D_STATS("Rssi %d, TSF %llu\n", rx_status.signal,
(unsigned long long)rx_status.mactime); (unsigned long long)rx_status.mactime);
@ -1343,12 +1342,11 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats)
} }
#endif #endif
#define REG_RECALIB_PERIOD (60)
void void
il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb) il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
{ {
int change; const int recalib_seconds = 60;
bool change;
struct il_rx_pkt *pkt = rxb_addr(rxb); struct il_rx_pkt *pkt = rxb_addr(rxb);
D_RX("Statistics notification received (%d vs %d).\n", D_RX("Statistics notification received (%d vs %d).\n",
@ -1369,20 +1367,21 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
set_bit(S_STATS, &il->status); set_bit(S_STATS, &il->status);
/* Reschedule the stats timer to occur in /*
* REG_RECALIB_PERIOD seconds to ensure we get a * Reschedule the stats timer to occur in recalib_seconds to ensure
* thermal update even if the uCode doesn't give * we get a thermal update even if the uCode doesn't give us one
* us one */ */
mod_timer(&il->stats_periodic, mod_timer(&il->stats_periodic,
jiffies + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); jiffies + msecs_to_jiffies(recalib_seconds * 1000));
if (unlikely(!test_bit(S_SCANNING, &il->status)) && if (unlikely(!test_bit(S_SCANNING, &il->status)) &&
(pkt->hdr.cmd == N_STATS)) { (pkt->hdr.cmd == N_STATS)) {
il4965_rx_calc_noise(il); il4965_rx_calc_noise(il);
queue_work(il->workqueue, &il->run_time_calib_work); queue_work(il->workqueue, &il->run_time_calib_work);
} }
if (il->ops->lib->temp_ops.temperature && change)
il->ops->lib->temp_ops.temperature(il); if (change)
il4965_temperature_calib(il);
} }
void void
@ -1694,7 +1693,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
sta_priv = (void *)sta->drv_priv; sta_priv = (void *)sta->drv_priv;
if (sta_priv && sta_priv->asleep && if (sta_priv && sta_priv->asleep &&
(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) { (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) {
/* /*
* This sends an asynchronous command to the device, * This sends an asynchronous command to the device,
* but we can rely on it being processed before the * but we can rely on it being processed before the
@ -1785,7 +1784,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
/* TODO need this for burst mode later on */ /* TODO need this for burst mode later on */
il4965_tx_cmd_build_basic(il, skb, tx_cmd, info, hdr, sta_id); il4965_tx_cmd_build_basic(il, skb, tx_cmd, info, hdr, sta_id);
il_dbg_log_tx_data_frame(il, len, hdr);
il4965_tx_cmd_build_rate(il, tx_cmd, info, fc); il4965_tx_cmd_build_rate(il, tx_cmd, info, fc);
@ -1815,7 +1813,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
dma_unmap_len_set(out_meta, len, firstlen); dma_unmap_len_set(out_meta, len, firstlen);
/* Add buffer containing Tx command and MAC(!) header to TFD's /* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */ * first entry */
il->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
if (!ieee80211_has_morefrags(hdr->frame_control)) { if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1; txq->need_update = 1;
@ -1831,8 +1829,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
phys_addr = phys_addr =
pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen, pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen,
secondlen, 0, 0); 0, 0);
} }
scratch_phys = scratch_phys =
@ -1852,8 +1850,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
/* Set up entry for this TFD in Tx byte-count array */ /* Set up entry for this TFD in Tx byte-count array */
if (info->flags & IEEE80211_TX_CTL_AMPDU) if (info->flags & IEEE80211_TX_CTL_AMPDU)
il->ops->lib->txq_update_byte_cnt_tbl(il, txq, il->ops->txq_update_byte_cnt_tbl(il, txq, le16_to_cpu(tx_cmd->len));
le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen, pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen,
PCI_DMA_BIDIRECTIONAL); PCI_DMA_BIDIRECTIONAL);
@ -1942,7 +1939,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il)
il4965_free_dma_ptr(il, &il->scd_bc_tbls); il4965_free_dma_ptr(il, &il->scd_bc_tbls);
/* free tx queue structure */ /* free tx queue structure */
il_txq_mem(il); il_free_txq_mem(il);
} }
/** /**
@ -1955,8 +1952,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il)
int int
il4965_txq_ctx_alloc(struct il_priv *il) il4965_txq_ctx_alloc(struct il_priv *il)
{ {
int ret; int ret, txq_id;
int txq_id, slots_num;
unsigned long flags; unsigned long flags;
/* Free all tx/cmd queues and keep-warm buffer */ /* Free all tx/cmd queues and keep-warm buffer */
@ -1993,10 +1989,7 @@ il4965_txq_ctx_alloc(struct il_priv *il)
/* Alloc and init all Tx queues, including the command queue (#4/#9) */ /* Alloc and init all Tx queues, including the command queue (#4/#9) */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
slots_num = ret = il_tx_queue_init(il, txq_id);
(txq_id ==
il->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
ret = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id);
if (ret) { if (ret) {
IL_ERR("Tx %d queue init failed\n", txq_id); IL_ERR("Tx %d queue init failed\n", txq_id);
goto error; goto error;
@ -2017,52 +2010,27 @@ il4965_txq_ctx_alloc(struct il_priv *il)
void void
il4965_txq_ctx_reset(struct il_priv *il) il4965_txq_ctx_reset(struct il_priv *il)
{ {
int txq_id, slots_num; int txq_id;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&il->lock, flags); spin_lock_irqsave(&il->lock, flags);
/* Turn off all Tx DMA fifos */ /* Turn off all Tx DMA fifos */
il4965_txq_set_sched(il, 0); il4965_txq_set_sched(il, 0);
/* Tell NIC where to find the "keep warm" buffer */ /* Tell NIC where to find the "keep warm" buffer */
il_wr(il, FH49_KW_MEM_ADDR_REG, il->kw.dma >> 4); il_wr(il, FH49_KW_MEM_ADDR_REG, il->kw.dma >> 4);
spin_unlock_irqrestore(&il->lock, flags); spin_unlock_irqrestore(&il->lock, flags);
/* Alloc and init all Tx queues, including the command queue (#4) */ /* Alloc and init all Tx queues, including the command queue (#4) */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
slots_num = il_tx_queue_reset(il, txq_id);
txq_id == il->cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
il_tx_queue_reset(il, &il->txq[txq_id], slots_num, txq_id);
}
} }
/**
* il4965_txq_ctx_stop - Stop all Tx DMA channels
*/
void void
il4965_txq_ctx_stop(struct il_priv *il) il4965_txq_ctx_unmap(struct il_priv *il)
{ {
int ch, txq_id; int txq_id;
unsigned long flags;
/* Turn off all Tx DMA fifos */
spin_lock_irqsave(&il->lock, flags);
il4965_txq_set_sched(il, 0);
/* Stop each Tx DMA channel, and wait for it to be idle */
for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
if (il_poll_bit
(il, FH49_TSSR_TX_STATUS_REG,
FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000))
IL_ERR("Failing on timeout while stopping"
" DMA channel %d [0x%08x]", ch,
il_rd(il, FH49_TSSR_TX_STATUS_REG));
}
spin_unlock_irqrestore(&il->lock, flags);
if (!il->txq) if (!il->txq)
return; return;
@ -2075,6 +2043,30 @@ il4965_txq_ctx_stop(struct il_priv *il)
il_tx_queue_unmap(il, txq_id); il_tx_queue_unmap(il, txq_id);
} }
/**
* il4965_txq_ctx_stop - Stop all Tx DMA channels
*/
void
il4965_txq_ctx_stop(struct il_priv *il)
{
int ch, ret;
_il_wr_prph(il, IL49_SCD_TXFACT, 0);
/* Stop each Tx DMA channel, and wait for it to be idle */
for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
_il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
ret =
_il_poll_bit(il, FH49_TSSR_TX_STATUS_REG,
FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
1000);
if (ret < 0)
IL_ERR("Timeout stopping DMA channel %d [0x%08x]",
ch, _il_rd(il, FH49_TSSR_TX_STATUS_REG));
}
}
/* /*
* Find first available (lowest unused) Tx Queue, mark it "active". * Find first available (lowest unused) Tx Queue, mark it "active".
* Called only when finding queue for aggregation. * Called only when finding queue for aggregation.
@ -2474,7 +2466,7 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
il4965_tx_status(il, skb, txq_id >= IL4965_FIRST_AMPDU_QUEUE); il4965_tx_status(il, skb, txq_id >= IL4965_FIRST_AMPDU_QUEUE);
txq->skbs[txq->q.read_ptr] = NULL; txq->skbs[txq->q.read_ptr] = NULL;
il->ops->lib->txq_free_tfd(il, txq); il->ops->txq_free_tfd(il, txq);
} }
return nfreed; return nfreed;
} }
@ -2548,6 +2540,308 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg,
return 0; return 0;
} }
static inline bool
il4965_is_tx_success(u32 status)
{
status &= TX_STATUS_MSK;
return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE);
}
static u8
il4965_find_station(struct il_priv *il, const u8 *addr)
{
int i;
int start = 0;
int ret = IL_INVALID_STATION;
unsigned long flags;
if (il->iw_mode == NL80211_IFTYPE_ADHOC)
start = IL_STA_ID;
if (is_broadcast_ether_addr(addr))
return il->hw_params.bcast_id;
spin_lock_irqsave(&il->sta_lock, flags);
for (i = start; i < il->hw_params.max_stations; i++)
if (il->stations[i].used &&
(!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) {
ret = i;
goto out;
}
D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations);
out:
/*
* It may be possible that more commands interacting with stations
* arrive before we completed processing the adding of
* station
*/
if (ret != IL_INVALID_STATION &&
(!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) ||
((il->stations[ret].used & IL_STA_UCODE_ACTIVE) &&
(il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) {
IL_ERR("Requested station info for sta %d before ready.\n",
ret);
ret = IL_INVALID_STATION;
}
spin_unlock_irqrestore(&il->sta_lock, flags);
return ret;
}
static int
il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
{
if (il->iw_mode == NL80211_IFTYPE_STATION)
return IL_AP_ID;
else {
u8 *da = ieee80211_get_DA(hdr);
return il4965_find_station(il, da);
}
}
static inline u32
il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
{
return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
}
static inline u32
il4965_tx_status_to_mac80211(u32 status)
{
status &= TX_STATUS_MSK;
switch (status) {
case TX_STATUS_SUCCESS:
case TX_STATUS_DIRECT_DONE:
return IEEE80211_TX_STAT_ACK;
case TX_STATUS_FAIL_DEST_PS:
return IEEE80211_TX_STAT_TX_FILTERED;
default:
return 0;
}
}
/**
* il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
*/
static int
il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
struct il4965_tx_resp *tx_resp, int txq_id,
u16 start_idx)
{
u16 status;
struct agg_tx_status *frame_status = tx_resp->u.agg_status;
struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
int i, sh, idx;
u16 seq;
if (agg->wait_for_ba)
D_TX_REPLY("got tx response w/o block-ack\n");
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
agg->rate_n_flags = rate_n_flags;
agg->bitmap = 0;
/* num frames attempted by Tx command */
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
status = le16_to_cpu(frame_status[0].status);
idx = start_idx;
D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]);
info->status.rates[0].count = tx_resp->failure_frame + 1;
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
info->flags |= il4965_tx_status_to_mac80211(status);
il4965_hwrate_to_tx_control(il, rate_n_flags, info);
D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff,
tx_resp->failure_frame);
D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
agg->wait_for_ba = 0;
} else {
/* Two or more frames were attempted; expect block-ack */
u64 bitmap = 0;
int start = agg->start_idx;
struct sk_buff *skb;
/* Construct bit-map of pending frames within Tx win */
for (i = 0; i < agg->frame_count; i++) {
u16 sc;
status = le16_to_cpu(frame_status[i].status);
seq = le16_to_cpu(frame_status[i].sequence);
idx = SEQ_TO_IDX(seq);
txq_id = SEQ_TO_QUEUE(seq);
if (status &
(AGG_TX_STATE_FEW_BYTES_MSK |
AGG_TX_STATE_ABORT_MSK))
continue;
D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
agg->frame_count, txq_id, idx);
skb = il->txq[txq_id].skbs[idx];
if (WARN_ON_ONCE(skb == NULL))
return -1;
hdr = (struct ieee80211_hdr *) skb->data;
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
IL_ERR("BUG_ON idx doesn't match seq control"
" idx=%d, seq_idx=%d, seq=%d\n", idx,
SEQ_TO_SN(sc), hdr->seq_ctrl);
return -1;
}
D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
SEQ_TO_SN(sc));
sh = idx - start;
if (sh > 64) {
sh = (start - idx) + 0xff;
bitmap = bitmap << sh;
sh = 0;
start = idx;
} else if (sh < -64)
sh = 0xff - (start - idx);
else if (sh < 0) {
sh = start - idx;
start = idx;
bitmap = bitmap << sh;
sh = 0;
}
bitmap |= 1ULL << sh;
D_TX_REPLY("start=%d bitmap=0x%llx\n", start,
(unsigned long long)bitmap);
}
agg->bitmap = bitmap;
agg->start_idx = start;
D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
if (bitmap)
agg->wait_for_ba = 1;
}
return 0;
}
/**
* il4965_hdl_tx - Handle standard (non-aggregation) Tx response
*/
static void
il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
{
struct il_rx_pkt *pkt = rxb_addr(rxb);
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int idx = SEQ_TO_IDX(sequence);
struct il_tx_queue *txq = &il->txq[txq_id];
struct sk_buff *skb;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info;
struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->u.status);
int uninitialized_var(tid);
int sta_id;
int freed;
u8 *qc = NULL;
unsigned long flags;
if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {
IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "
"is out of range [0-%d] %d %d\n", txq_id, idx,
txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);
return;
}
txq->time_stamp = jiffies;
skb = txq->skbs[txq->q.read_ptr];
info = IEEE80211_SKB_CB(skb);
memset(&info->status, 0, sizeof(info->status));
hdr = (struct ieee80211_hdr *) skb->data;
if (ieee80211_is_data_qos(hdr->frame_control)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
}
sta_id = il4965_get_ra_sta_id(il, hdr);
if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) {
IL_ERR("Station not known\n");
return;
}
spin_lock_irqsave(&il->sta_lock, flags);
if (txq->sched_retry) {
const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
struct il_ht_agg *agg = NULL;
WARN_ON(!qc);
agg = &il->stations[sta_id].tid[tid].agg;
il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx);
/* check if BAR is needed */
if (tx_resp->frame_count == 1 &&
!il4965_is_tx_success(status))
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
D_TX_REPLY("Retry scheduler reclaim scd_ssn "
"%d idx %d\n", scd_ssn, idx);
freed = il4965_tx_queue_reclaim(il, txq_id, idx);
if (qc)
il4965_free_tfds_in_queue(il, sta_id, tid,
freed);
if (il->mac80211_registered &&
il_queue_space(&txq->q) > txq->q.low_mark &&
agg->state != IL_EMPTYING_HW_QUEUE_DELBA)
il_wake_queue(il, txq);
}
} else {
info->status.rates[0].count = tx_resp->failure_frame + 1;
info->flags |= il4965_tx_status_to_mac80211(status);
il4965_hwrate_to_tx_control(il,
le32_to_cpu(tx_resp->rate_n_flags),
info);
D_TX_REPLY("TXQ %d status %s (0x%08x) "
"rate_n_flags 0x%x retries %d\n", txq_id,
il4965_get_tx_fail_reason(status), status,
le32_to_cpu(tx_resp->rate_n_flags),
tx_resp->failure_frame);
freed = il4965_tx_queue_reclaim(il, txq_id, idx);
if (qc && likely(sta_id != IL_INVALID_STATION))
il4965_free_tfds_in_queue(il, sta_id, tid, freed);
else if (sta_id == IL_INVALID_STATION)
D_TX_REPLY("Station not known\n");
if (il->mac80211_registered &&
il_queue_space(&txq->q) > txq->q.low_mark)
il_wake_queue(il, txq);
}
if (qc && likely(sta_id != IL_INVALID_STATION))
il4965_txq_check_empty(il, sta_id, tid, txq_id);
il4965_check_abort_status(il, tx_resp->frame_count, status);
spin_unlock_irqrestore(&il->sta_lock, flags);
}
/** /**
* translate ucode response to mac80211 tx status control values * translate ucode response to mac80211 tx status control values
*/ */
@ -3352,8 +3646,8 @@ il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt)
void void
il4965_update_chain_flags(struct il_priv *il) il4965_update_chain_flags(struct il_priv *il)
{ {
if (il->ops->hcmd->set_rxon_chain) { if (il->ops->set_rxon_chain) {
il->ops->hcmd->set_rxon_chain(il); il->ops->set_rxon_chain(il);
if (il->active.rx_chain != il->staging.rx_chain) if (il->active.rx_chain != il->staging.rx_chain)
il_commit_rxon(il); il_commit_rxon(il);
} }
@ -3726,9 +4020,9 @@ il4965_hdl_alive(struct il_priv *il, struct il_rx_buf *rxb)
* This callback is provided in order to send a stats request. * This callback is provided in order to send a stats request.
* *
* This timer function is continually reset to execute within * This timer function is continually reset to execute within
* REG_RECALIB_PERIOD seconds since the last N_STATS * 60 seconds since the last N_STATS was received. We need to
* was received. We need to ensure we receive the stats in order * ensure we receive the stats in order to update the temperature
* to update the temperature used for calibrating the TXPOWER. * used for calibrating the TXPOWER.
*/ */
static void static void
il4965_bg_stats_periodic(unsigned long data) il4965_bg_stats_periodic(unsigned long data)
@ -3778,7 +4072,7 @@ il4965_perform_ct_kill_task(struct il_priv *il)
_il_rd(il, CSR_UCODE_DRV_GP1); _il_rd(il, CSR_UCODE_DRV_GP1);
spin_lock_irqsave(&il->reg_lock, flags); spin_lock_irqsave(&il->reg_lock, flags);
if (!_il_grab_nic_access(il)) if (likely(_il_grab_nic_access(il)))
_il_release_nic_access(il); _il_release_nic_access(il);
spin_unlock_irqrestore(&il->reg_lock, flags); spin_unlock_irqrestore(&il->reg_lock, flags);
} }
@ -3816,17 +4110,17 @@ il4965_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb)
il4965_perform_ct_kill_task(il); il4965_perform_ct_kill_task(il);
if (flags & HW_CARD_DISABLED) if (flags & HW_CARD_DISABLED)
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
else else
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
if (!(flags & RXON_CARD_DISABLED)) if (!(flags & RXON_CARD_DISABLED))
il_scan_cancel(il); il_scan_cancel(il);
if ((test_bit(S_RF_KILL_HW, &status) != if ((test_bit(S_RFKILL, &status) !=
test_bit(S_RF_KILL_HW, &il->status))) test_bit(S_RFKILL, &il->status)))
wiphy_rfkill_set_hw_state(il->hw->wiphy, wiphy_rfkill_set_hw_state(il->hw->wiphy,
test_bit(S_RF_KILL_HW, &il->status)); test_bit(S_RFKILL, &il->status));
else else
wake_up(&il->wait_command_queue); wake_up(&il->wait_command_queue);
} }
@ -3868,10 +4162,11 @@ il4965_setup_handlers(struct il_priv *il)
/* Rx handlers */ /* Rx handlers */
il->handlers[N_RX_PHY] = il4965_hdl_rx_phy; il->handlers[N_RX_PHY] = il4965_hdl_rx_phy;
il->handlers[N_RX_MPDU] = il4965_hdl_rx; il->handlers[N_RX_MPDU] = il4965_hdl_rx;
il->handlers[N_RX] = il4965_hdl_rx;
/* block ack */ /* block ack */
il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba; il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba;
/* Set up hardware specific Rx handlers */ /* Tx response */
il->ops->lib->handler_setup(il); il->handlers[C_TX] = il4965_hdl_tx;
} }
/** /**
@ -4101,9 +4396,8 @@ il4965_irq_tasklet(struct il_priv *il)
/* HW RF KILL switch toggled */ /* HW RF KILL switch toggled */
if (inta & CSR_INT_BIT_RF_KILL) { if (inta & CSR_INT_BIT_RF_KILL) {
int hw_rf_kill = 0; int hw_rf_kill = 0;
if (!
(_il_rd(il, CSR_GP_CNTRL) & if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
hw_rf_kill = 1; hw_rf_kill = 1;
IL_WARN("RF_KILL bit toggled to %s.\n", IL_WARN("RF_KILL bit toggled to %s.\n",
@ -4118,9 +4412,9 @@ il4965_irq_tasklet(struct il_priv *il)
*/ */
if (!test_bit(S_ALIVE, &il->status)) { if (!test_bit(S_ALIVE, &il->status)) {
if (hw_rf_kill) if (hw_rf_kill)
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
else else
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill); wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
} }
@ -4244,11 +4538,9 @@ il4965_store_debug_level(struct device *d, struct device_attribute *attr,
ret = strict_strtoul(buf, 0, &val); ret = strict_strtoul(buf, 0, &val);
if (ret) if (ret)
IL_ERR("%s is not in hex or decimal form.\n", buf); IL_ERR("%s is not in hex or decimal form.\n", buf);
else { else
il->debug_level = val; il->debug_level = val;
if (il_alloc_traffic_mem(il))
IL_ERR("Not enough memory to generate traffic log\n");
}
return strnlen(buf, count); return strnlen(buf, count);
} }
@ -4773,7 +5065,7 @@ il4965_dump_nic_error_log(struct il_priv *il)
else else
base = le32_to_cpu(il->card_alive.error_event_table_ptr); base = le32_to_cpu(il->card_alive.error_event_table_ptr);
if (!il->ops->lib->is_valid_rtc_data_addr(base)) { if (!il->ops->is_valid_rtc_data_addr(base)) {
IL_ERR("Not valid error log pointer 0x%08X for %s uCode\n", IL_ERR("Not valid error log pointer 0x%08X for %s uCode\n",
base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT"); base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
return; return;
@ -5002,8 +5294,8 @@ il4965_alive_start(struct il_priv *il)
/* Initialize our rx_config data */ /* Initialize our rx_config data */
il_connection_init_rx_config(il); il_connection_init_rx_config(il);
if (il->ops->hcmd->set_rxon_chain) if (il->ops->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il); il->ops->set_rxon_chain(il);
} }
/* Configure bluetooth coexistence if enabled */ /* Configure bluetooth coexistence if enabled */
@ -5091,12 +5383,8 @@ __il4965_down(struct il_priv *il)
* clear all bits but the RF Kill bit and return */ * clear all bits but the RF Kill bit and return */
if (!il_is_init(il)) { if (!il_is_init(il)) {
il->status = il->status =
test_bit(S_RF_KILL_HW, test_bit(S_RFKILL, &il->status) << S_RFKILL |
&il-> test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
status) << S_RF_KILL_HW |
test_bit(S_GEO_CONFIGURED,
&il->
status) << S_GEO_CONFIGURED |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
goto exit; goto exit;
} }
@ -5104,28 +5392,32 @@ __il4965_down(struct il_priv *il)
/* ...otherwise clear out all the status bits but the RF Kill /* ...otherwise clear out all the status bits but the RF Kill
* bit and continue taking the NIC down. */ * bit and continue taking the NIC down. */
il->status &= il->status &=
test_bit(S_RF_KILL_HW, test_bit(S_RFKILL, &il->status) << S_RFKILL |
&il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED, test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
&il-> test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
status) <<
S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
&il->
status) << S_FW_ERROR |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
/*
* We disabled and synchronized interrupt, and priv->mutex is taken, so
* here is the only thread which will program device registers, but
* still have lockdep assertions, so we are taking reg_lock.
*/
spin_lock_irq(&il->reg_lock);
/* FIXME: il_grab_nic_access if rfkill is off ? */
il4965_txq_ctx_stop(il); il4965_txq_ctx_stop(il);
il4965_rxq_stop(il); il4965_rxq_stop(il);
/* Power-down device's busmaster DMA clocks */ /* Power-down device's busmaster DMA clocks */
il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5); udelay(5);
/* Make sure (redundant) we've released our request to stay awake */ /* Make sure (redundant) we've released our request to stay awake */
il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
/* Stop the device, and put it in low power state */ /* Stop the device, and put it in low power state */
il_apm_stop(il); _il_apm_stop(il);
spin_unlock_irq(&il->reg_lock);
il4965_txq_ctx_unmap(il);
exit: exit:
memset(&il->card_alive, 0, sizeof(struct il_alive_resp)); memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
@ -5146,40 +5438,36 @@ il4965_down(struct il_priv *il)
il4965_cancel_deferred_work(il); il4965_cancel_deferred_work(il);
} }
#define HW_READY_TIMEOUT (50)
static int static void
il4965_set_hw_ready(struct il_priv *il) il4965_set_hw_ready(struct il_priv *il)
{ {
int ret = 0; int ret;
il_set_bit(il, CSR_HW_IF_CONFIG_REG, il_set_bit(il, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
/* See if we got it */ /* See if we got it */
ret = ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
_il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT); CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
if (ret != -ETIMEDOUT) 100);
if (ret >= 0)
il->hw_ready = true; il->hw_ready = true;
else
il->hw_ready = false;
D_INFO("hardware %s\n", (il->hw_ready == 1) ? "ready" : "not ready"); D_INFO("hardware %s ready\n", (il->hw_ready) ? "" : "not");
return ret;
} }
static int static void
il4965_prepare_card_hw(struct il_priv *il) il4965_prepare_card_hw(struct il_priv *il)
{ {
int ret = 0; int ret;
D_INFO("il4965_prepare_card_hw enter\n"); il->hw_ready = false;
ret = il4965_set_hw_ready(il); il4965_set_hw_ready(il);
if (il->hw_ready) if (il->hw_ready)
return ret; return;
/* If HW is not ready, prepare the conditions to check again */ /* If HW is not ready, prepare the conditions to check again */
il_set_bit(il, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); il_set_bit(il, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE);
@ -5192,8 +5480,6 @@ il4965_prepare_card_hw(struct il_priv *il)
/* HW should be ready by now, check again. */ /* HW should be ready by now, check again. */
if (ret != -ETIMEDOUT) if (ret != -ETIMEDOUT)
il4965_set_hw_ready(il); il4965_set_hw_ready(il);
return ret;
} }
#define MAX_HW_RESTARTS 5 #define MAX_HW_RESTARTS 5
@ -5221,22 +5507,19 @@ __il4965_up(struct il_priv *il)
} }
il4965_prepare_card_hw(il); il4965_prepare_card_hw(il);
if (!il->hw_ready) { if (!il->hw_ready) {
IL_WARN("Exit HW not ready\n"); IL_ERR("HW not ready\n");
return -EIO; return -EIO;
} }
/* If platform's RF_KILL switch is NOT set to KILL */ /* If platform's RF_KILL switch is NOT set to KILL */
if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
else else {
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
if (il_is_rfkill(il)) {
wiphy_rfkill_set_hw_state(il->hw->wiphy, true); wiphy_rfkill_set_hw_state(il->hw->wiphy, true);
il_enable_interrupts(il); il_enable_rfkill_int(il);
IL_WARN("Radio disabled by HW RF Kill switch\n"); IL_WARN("Radio disabled by HW RF Kill switch\n");
return 0; return 0;
} }
@ -5275,7 +5558,7 @@ __il4965_up(struct il_priv *il)
/* load bootstrap state machine, /* load bootstrap state machine,
* load bootstrap program into processor's memory, * load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */ * prepare to load the "initialize" uCode */
ret = il->ops->lib->load_ucode(il); ret = il->ops->load_ucode(il);
if (ret) { if (ret) {
IL_ERR("Unable to set up bootstrap uCode: %d\n", ret); IL_ERR("Unable to set up bootstrap uCode: %d\n", ret);
@ -5316,7 +5599,7 @@ il4965_bg_init_alive_start(struct work_struct *data)
if (test_bit(S_EXIT_PENDING, &il->status)) if (test_bit(S_EXIT_PENDING, &il->status))
goto out; goto out;
il->ops->lib->init_alive_start(il); il->ops->init_alive_start(il);
out: out:
mutex_unlock(&il->mutex); mutex_unlock(&il->mutex);
} }
@ -5748,7 +6031,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
if (!il_is_associated(il)) if (!il_is_associated(il))
goto out; goto out;
if (!il->ops->lib->set_channel_switch) if (!il->ops->set_channel_switch)
goto out; goto out;
ch = channel->hw_value; ch = channel->hw_value;
@ -5800,7 +6083,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
*/ */
set_bit(S_CHANNEL_SWITCH_PENDING, &il->status); set_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
il->switch_channel = cpu_to_le16(ch); il->switch_channel = cpu_to_le16(ch);
if (il->ops->lib->set_channel_switch(il, ch_switch)) { if (il->ops->set_channel_switch(il, ch_switch)) {
clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status); clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
il->switch_channel = 0; il->switch_channel = 0;
ieee80211_chswitch_done(il->vif, false); ieee80211_chswitch_done(il->vif, false);
@ -5883,7 +6166,7 @@ il4965_bg_txpower_work(struct work_struct *work)
/* Regardless of if we are associated, we must reconfigure the /* Regardless of if we are associated, we must reconfigure the
* TX power since frames can be sent on non-radar channels while * TX power since frames can be sent on non-radar channels while
* not associated */ * not associated */
il->ops->lib->send_tx_power(il); il->ops->send_tx_power(il);
/* Update last_temperature to keep is_calib_needed from running /* Update last_temperature to keep is_calib_needed from running
* when it isn't needed... */ * when it isn't needed... */
@ -6035,8 +6318,8 @@ il4965_init_drv(struct il_priv *il)
il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD; il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD;
/* Choose which receivers/antennas to use */ /* Choose which receivers/antennas to use */
if (il->ops->hcmd->set_rxon_chain) if (il->ops->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il); il->ops->set_rxon_chain(il);
il_init_scan_params(il); il_init_scan_params(il);
@ -6064,7 +6347,6 @@ il4965_init_drv(struct il_priv *il)
static void static void
il4965_uninit_drv(struct il_priv *il) il4965_uninit_drv(struct il_priv *il)
{ {
il4965_calib_free_results(il);
il_free_geos(il); il_free_geos(il);
il_free_channel_map(il); il_free_channel_map(il);
kfree(il->scan_cmd); kfree(il->scan_cmd);
@ -6180,12 +6462,12 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
D_INFO("*** LOAD DRIVER ***\n"); D_INFO("*** LOAD DRIVER ***\n");
il->cfg = cfg; il->cfg = cfg;
il->ops = &il4965_ops; il->ops = &il4965_ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
il->debugfs_ops = &il4965_debugfs_ops;
#endif
il->pci_dev = pdev; il->pci_dev = pdev;
il->inta_mask = CSR_INI_SET_MASK; il->inta_mask = CSR_INI_SET_MASK;
if (il_alloc_traffic_mem(il))
IL_ERR("Not enough memory to generate traffic log\n");
/************************** /**************************
* 2. Initializing PCI bus * 2. Initializing PCI bus
**************************/ **************************/
@ -6224,7 +6506,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/*********************** /***********************
* 3. Read REV register * 3. Read REV register
***********************/ ***********************/
il->hw_base = pci_iomap(pdev, 0, 0); il->hw_base = pci_ioremap_bar(pdev, 0);
if (!il->hw_base) { if (!il->hw_base) {
err = -ENODEV; err = -ENODEV;
goto out_pci_release_regions; goto out_pci_release_regions;
@ -6329,12 +6611,12 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* If platform's RF_KILL switch is NOT set to KILL */ /* If platform's RF_KILL switch is NOT set to KILL */
if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(S_RF_KILL_HW, &il->status); clear_bit(S_RFKILL, &il->status);
else else
set_bit(S_RF_KILL_HW, &il->status); set_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy, wiphy_rfkill_set_hw_state(il->hw->wiphy,
test_bit(S_RF_KILL_HW, &il->status)); test_bit(S_RFKILL, &il->status));
il_power_initialize(il); il_power_initialize(il);
@ -6356,14 +6638,13 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_free_eeprom: out_free_eeprom:
il_eeprom_free(il); il_eeprom_free(il);
out_iounmap: out_iounmap:
pci_iounmap(pdev, il->hw_base); iounmap(il->hw_base);
out_pci_release_regions: out_pci_release_regions:
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev); pci_release_regions(pdev);
out_pci_disable_device: out_pci_disable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
out_ieee80211_free_hw: out_ieee80211_free_hw:
il_free_traffic_mem(il);
ieee80211_free_hw(il->hw); ieee80211_free_hw(il->hw);
out: out:
return err; return err;
@ -6434,11 +6715,10 @@ il4965_pci_remove(struct pci_dev *pdev)
* until now... */ * until now... */
destroy_workqueue(il->workqueue); destroy_workqueue(il->workqueue);
il->workqueue = NULL; il->workqueue = NULL;
il_free_traffic_mem(il);
free_irq(il->pci_dev->irq, il); free_irq(il->pci_dev->irq, il);
pci_disable_msi(il->pci_dev); pci_disable_msi(il->pci_dev);
pci_iounmap(pdev, il->hw_base); iounmap(il->hw_base);
pci_release_regions(pdev); pci_release_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);

View File

@ -264,10 +264,6 @@ il4965_led_enable(struct il_priv *il)
_il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON); _il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
} }
const struct il_led_ops il4965_led_ops = {
.cmd = il4965_send_led_cmd,
};
static int il4965_send_tx_power(struct il_priv *il); static int il4965_send_tx_power(struct il_priv *il);
static int il4965_hw_get_temperature(struct il_priv *il); static int il4965_hw_get_temperature(struct il_priv *il);
@ -508,7 +504,7 @@ iw4965_is_ht40_channel(__le32 rxon_flags)
chan_mod == CHANNEL_MODE_MIXED); chan_mod == CHANNEL_MODE_MIXED);
} }
static void void
il4965_nic_config(struct il_priv *il) il4965_nic_config(struct il_priv *il)
{ {
unsigned long flags; unsigned long flags;
@ -1678,7 +1674,7 @@ il4965_is_temp_calib_needed(struct il_priv *il)
return 1; return 1;
} }
static void void
il4965_temperature_calib(struct il_priv *il) il4965_temperature_calib(struct il_priv *il)
{ {
s32 temp; s32 temp;
@ -1737,323 +1733,6 @@ il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
return (u16) sizeof(struct il4965_addsta_cmd); return (u16) sizeof(struct il4965_addsta_cmd);
} }
static inline u32
il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
{
return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
}
static inline u32
il4965_tx_status_to_mac80211(u32 status)
{
status &= TX_STATUS_MSK;
switch (status) {
case TX_STATUS_SUCCESS:
case TX_STATUS_DIRECT_DONE:
return IEEE80211_TX_STAT_ACK;
case TX_STATUS_FAIL_DEST_PS:
return IEEE80211_TX_STAT_TX_FILTERED;
default:
return 0;
}
}
static inline bool
il4965_is_tx_success(u32 status)
{
status &= TX_STATUS_MSK;
return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE);
}
/**
* il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
*/
static int
il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
struct il4965_tx_resp *tx_resp, int txq_id,
u16 start_idx)
{
u16 status;
struct agg_tx_status *frame_status = tx_resp->u.agg_status;
struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
int i, sh, idx;
u16 seq;
if (agg->wait_for_ba)
D_TX_REPLY("got tx response w/o block-ack\n");
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
agg->rate_n_flags = rate_n_flags;
agg->bitmap = 0;
/* num frames attempted by Tx command */
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
status = le16_to_cpu(frame_status[0].status);
idx = start_idx;
D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]);
info->status.rates[0].count = tx_resp->failure_frame + 1;
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
info->flags |= il4965_tx_status_to_mac80211(status);
il4965_hwrate_to_tx_control(il, rate_n_flags, info);
D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff,
tx_resp->failure_frame);
D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
agg->wait_for_ba = 0;
} else {
/* Two or more frames were attempted; expect block-ack */
u64 bitmap = 0;
int start = agg->start_idx;
struct sk_buff *skb;
/* Construct bit-map of pending frames within Tx win */
for (i = 0; i < agg->frame_count; i++) {
u16 sc;
status = le16_to_cpu(frame_status[i].status);
seq = le16_to_cpu(frame_status[i].sequence);
idx = SEQ_TO_IDX(seq);
txq_id = SEQ_TO_QUEUE(seq);
if (status &
(AGG_TX_STATE_FEW_BYTES_MSK |
AGG_TX_STATE_ABORT_MSK))
continue;
D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
agg->frame_count, txq_id, idx);
skb = il->txq[txq_id].skbs[idx];
if (WARN_ON_ONCE(skb == NULL))
return -1;
hdr = (struct ieee80211_hdr *) skb->data;
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
IL_ERR("BUG_ON idx doesn't match seq control"
" idx=%d, seq_idx=%d, seq=%d\n", idx,
SEQ_TO_SN(sc), hdr->seq_ctrl);
return -1;
}
D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
SEQ_TO_SN(sc));
sh = idx - start;
if (sh > 64) {
sh = (start - idx) + 0xff;
bitmap = bitmap << sh;
sh = 0;
start = idx;
} else if (sh < -64)
sh = 0xff - (start - idx);
else if (sh < 0) {
sh = start - idx;
start = idx;
bitmap = bitmap << sh;
sh = 0;
}
bitmap |= 1ULL << sh;
D_TX_REPLY("start=%d bitmap=0x%llx\n", start,
(unsigned long long)bitmap);
}
agg->bitmap = bitmap;
agg->start_idx = start;
D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
if (bitmap)
agg->wait_for_ba = 1;
}
return 0;
}
static u8
il4965_find_station(struct il_priv *il, const u8 * addr)
{
int i;
int start = 0;
int ret = IL_INVALID_STATION;
unsigned long flags;
if ((il->iw_mode == NL80211_IFTYPE_ADHOC))
start = IL_STA_ID;
if (is_broadcast_ether_addr(addr))
return il->hw_params.bcast_id;
spin_lock_irqsave(&il->sta_lock, flags);
for (i = start; i < il->hw_params.max_stations; i++)
if (il->stations[i].used &&
(!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) {
ret = i;
goto out;
}
D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations);
out:
/*
* It may be possible that more commands interacting with stations
* arrive before we completed processing the adding of
* station
*/
if (ret != IL_INVALID_STATION &&
(!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) ||
((il->stations[ret].used & IL_STA_UCODE_ACTIVE) &&
(il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) {
IL_ERR("Requested station info for sta %d before ready.\n",
ret);
ret = IL_INVALID_STATION;
}
spin_unlock_irqrestore(&il->sta_lock, flags);
return ret;
}
static int
il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
{
if (il->iw_mode == NL80211_IFTYPE_STATION) {
return IL_AP_ID;
} else {
u8 *da = ieee80211_get_DA(hdr);
return il4965_find_station(il, da);
}
}
/**
* il4965_hdl_tx - Handle standard (non-aggregation) Tx response
*/
static void
il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
{
struct il_rx_pkt *pkt = rxb_addr(rxb);
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int idx = SEQ_TO_IDX(sequence);
struct il_tx_queue *txq = &il->txq[txq_id];
struct sk_buff *skb;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info;
struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->u.status);
int uninitialized_var(tid);
int sta_id;
int freed;
u8 *qc = NULL;
unsigned long flags;
if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {
IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "
"is out of range [0-%d] %d %d\n", txq_id, idx,
txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);
return;
}
txq->time_stamp = jiffies;
skb = txq->skbs[txq->q.read_ptr];
info = IEEE80211_SKB_CB(skb);
memset(&info->status, 0, sizeof(info->status));
hdr = (struct ieee80211_hdr *) skb->data;
if (ieee80211_is_data_qos(hdr->frame_control)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
}
sta_id = il4965_get_ra_sta_id(il, hdr);
if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) {
IL_ERR("Station not known\n");
return;
}
spin_lock_irqsave(&il->sta_lock, flags);
if (txq->sched_retry) {
const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
struct il_ht_agg *agg = NULL;
WARN_ON(!qc);
agg = &il->stations[sta_id].tid[tid].agg;
il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx);
/* check if BAR is needed */
if ((tx_resp->frame_count == 1) &&
!il4965_is_tx_success(status))
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
D_TX_REPLY("Retry scheduler reclaim scd_ssn "
"%d idx %d\n", scd_ssn, idx);
freed = il4965_tx_queue_reclaim(il, txq_id, idx);
if (qc)
il4965_free_tfds_in_queue(il, sta_id, tid,
freed);
if (il->mac80211_registered &&
il_queue_space(&txq->q) > txq->q.low_mark &&
agg->state != IL_EMPTYING_HW_QUEUE_DELBA)
il_wake_queue(il, txq);
}
} else {
info->status.rates[0].count = tx_resp->failure_frame + 1;
info->flags |= il4965_tx_status_to_mac80211(status);
il4965_hwrate_to_tx_control(il,
le32_to_cpu(tx_resp->rate_n_flags),
info);
D_TX_REPLY("TXQ %d status %s (0x%08x) "
"rate_n_flags 0x%x retries %d\n", txq_id,
il4965_get_tx_fail_reason(status), status,
le32_to_cpu(tx_resp->rate_n_flags),
tx_resp->failure_frame);
freed = il4965_tx_queue_reclaim(il, txq_id, idx);
if (qc && likely(sta_id != IL_INVALID_STATION))
il4965_free_tfds_in_queue(il, sta_id, tid, freed);
else if (sta_id == IL_INVALID_STATION)
D_TX_REPLY("Station not known\n");
if (il->mac80211_registered &&
il_queue_space(&txq->q) > txq->q.low_mark)
il_wake_queue(il, txq);
}
if (qc && likely(sta_id != IL_INVALID_STATION))
il4965_txq_check_empty(il, sta_id, tid, txq_id);
il4965_check_abort_status(il, tx_resp->frame_count, status);
spin_unlock_irqrestore(&il->sta_lock, flags);
}
/* Set up 4965-specific Rx frame reply handlers */
static void
il4965_handler_setup(struct il_priv *il)
{
/* Legacy Rx frames */
il->handlers[N_RX] = il4965_hdl_rx;
/* Tx response */
il->handlers[C_TX] = il4965_hdl_tx;
}
static struct il_hcmd_ops il4965_hcmd = {
.rxon_assoc = il4965_send_rxon_assoc,
.commit_rxon = il4965_commit_rxon,
.set_rxon_chain = il4965_set_rxon_chain,
};
static void static void
il4965_post_scan(struct il_priv *il) il4965_post_scan(struct il_priv *il)
{ {
@ -2093,8 +1772,8 @@ il4965_post_associate(struct il_priv *il)
il_set_rxon_ht(il, &il->current_ht_config); il_set_rxon_ht(il, &il->current_ht_config);
if (il->ops->hcmd->set_rxon_chain) if (il->ops->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il); il->ops->set_rxon_chain(il);
il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
@ -2168,8 +1847,8 @@ il4965_config_ap(struct il_priv *il)
/* AP has all antennas */ /* AP has all antennas */
il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant; il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant;
il_set_rxon_ht(il, &il->current_ht_config); il_set_rxon_ht(il, &il->current_ht_config);
if (il->ops->hcmd->set_rxon_chain) if (il->ops->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il); il->ops->set_rxon_chain(il);
il->staging.assoc_id = 0; il->staging.assoc_id = 0;
@ -2193,68 +1872,38 @@ il4965_config_ap(struct il_priv *il)
il4965_send_beacon_cmd(il); il4965_send_beacon_cmd(il);
} }
static struct il_hcmd_utils_ops il4965_hcmd_utils = { const struct il_ops il4965_ops = {
.get_hcmd_size = il4965_get_hcmd_size,
.build_addsta_hcmd = il4965_build_addsta_hcmd,
.request_scan = il4965_request_scan,
.post_scan = il4965_post_scan,
};
static struct il_lib_ops il4965_lib = {
.txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl, .txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl,
.txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd, .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = il4965_hw_txq_free_tfd, .txq_free_tfd = il4965_hw_txq_free_tfd,
.txq_init = il4965_hw_tx_queue_init, .txq_init = il4965_hw_tx_queue_init,
.handler_setup = il4965_handler_setup,
.is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr, .is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr,
.init_alive_start = il4965_init_alive_start, .init_alive_start = il4965_init_alive_start,
.load_ucode = il4965_load_bsm, .load_ucode = il4965_load_bsm,
.dump_nic_error_log = il4965_dump_nic_error_log, .dump_nic_error_log = il4965_dump_nic_error_log,
.dump_fh = il4965_dump_fh, .dump_fh = il4965_dump_fh,
.set_channel_switch = il4965_hw_channel_switch, .set_channel_switch = il4965_hw_channel_switch,
.apm_ops = { .apm_init = il_apm_init,
.init = il_apm_init,
.config = il4965_nic_config,
},
.eeprom_ops = {
.regulatory_bands = {
EEPROM_REGULATORY_BAND_1_CHANNELS,
EEPROM_REGULATORY_BAND_2_CHANNELS,
EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS},
.acquire_semaphore = il4965_eeprom_acquire_semaphore,
.release_semaphore = il4965_eeprom_release_semaphore,
},
.send_tx_power = il4965_send_tx_power, .send_tx_power = il4965_send_tx_power,
.update_chain_flags = il4965_update_chain_flags, .update_chain_flags = il4965_update_chain_flags,
.temp_ops = { .eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore,
.temperature = il4965_temperature_calib, .eeprom_release_semaphore = il4965_eeprom_release_semaphore,
},
#ifdef CONFIG_IWLEGACY_DEBUGFS .rxon_assoc = il4965_send_rxon_assoc,
.debugfs_ops = { .commit_rxon = il4965_commit_rxon,
.rx_stats_read = il4965_ucode_rx_stats_read, .set_rxon_chain = il4965_set_rxon_chain,
.tx_stats_read = il4965_ucode_tx_stats_read,
.general_stats_read = il4965_ucode_general_stats_read, .get_hcmd_size = il4965_get_hcmd_size,
}, .build_addsta_hcmd = il4965_build_addsta_hcmd,
#endif .request_scan = il4965_request_scan,
}; .post_scan = il4965_post_scan,
static const struct il_legacy_ops il4965_legacy_ops = {
.post_associate = il4965_post_associate, .post_associate = il4965_post_associate,
.config_ap = il4965_config_ap, .config_ap = il4965_config_ap,
.manage_ibss_station = il4965_manage_ibss_station, .manage_ibss_station = il4965_manage_ibss_station,
.update_bcast_stations = il4965_update_bcast_stations, .update_bcast_stations = il4965_update_bcast_stations,
};
const struct il_ops il4965_ops = { .send_led_cmd = il4965_send_led_cmd,
.lib = &il4965_lib,
.hcmd = &il4965_hcmd,
.utils = &il4965_hcmd_utils,
.led = &il4965_led_ops,
.legacy = &il4965_legacy_ops,
}; };
struct il_cfg il4965_cfg = { struct il_cfg il4965_cfg = {
@ -2288,6 +1937,17 @@ struct il_cfg il4965_cfg = {
.ucode_tracing = true, .ucode_tracing = true,
.sensitivity_calib_by_driver = true, .sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true, .chain_noise_calib_by_driver = true,
.regulatory_bands = {
EEPROM_REGULATORY_BAND_1_CHANNELS,
EEPROM_REGULATORY_BAND_2_CHANNELS,
EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
},
}; };
/* Module firmware */ /* Module firmware */

View File

@ -60,6 +60,8 @@ int il4965_rx_init(struct il_priv *il, struct il_rx_queue *rxq);
int il4965_hw_nic_init(struct il_priv *il); int il4965_hw_nic_init(struct il_priv *il);
int il4965_dump_fh(struct il_priv *il, char **buf, bool display); int il4965_dump_fh(struct il_priv *il, char **buf, bool display);
void il4965_nic_config(struct il_priv *il);
/* rx */ /* rx */
void il4965_rx_queue_restock(struct il_priv *il); void il4965_rx_queue_restock(struct il_priv *il);
void il4965_rx_replenish(struct il_priv *il); void il4965_rx_replenish(struct il_priv *il);
@ -67,8 +69,6 @@ void il4965_rx_replenish_now(struct il_priv *il);
void il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq); void il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq);
int il4965_rxq_stop(struct il_priv *il); int il4965_rxq_stop(struct il_priv *il);
int il4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); int il4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
void il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb);
void il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb);
void il4965_rx_handle(struct il_priv *il); void il4965_rx_handle(struct il_priv *il);
/* tx */ /* tx */
@ -84,7 +84,6 @@ int il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
int il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif, int il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid); struct ieee80211_sta *sta, u16 tid);
int il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id); int il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id);
void il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb);
int il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx); int il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx);
void il4965_hw_txq_ctx_free(struct il_priv *il); void il4965_hw_txq_ctx_free(struct il_priv *il);
int il4965_txq_ctx_alloc(struct il_priv *il); int il4965_txq_ctx_alloc(struct il_priv *il);
@ -106,12 +105,6 @@ void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx);
void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
int tx_fifo_id, int scd_retry); int tx_fifo_id, int scd_retry);
/* rx */
void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb);
bool il4965_good_plcp_health(struct il_priv *il, struct il_rx_pkt *pkt);
void il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb);
void il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb);
/* scan */ /* scan */
int il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif); int il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif);
@ -275,6 +268,7 @@ il4965_hw_valid_rtc_data_addr(u32 addr)
((t) < IL_TX_POWER_TEMPERATURE_MIN || \ ((t) < IL_TX_POWER_TEMPERATURE_MIN || \
(t) > IL_TX_POWER_TEMPERATURE_MAX) (t) > IL_TX_POWER_TEMPERATURE_MAX)
extern void il4965_temperature_calib(struct il_priv *il);
/********************* END TEMPERATURE ***************************************/ /********************* END TEMPERATURE ***************************************/
/********************* START TXPOWER *****************************************/ /********************* START TXPOWER *****************************************/
@ -933,17 +927,10 @@ void il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp);
void il4965_sensitivity_calibration(struct il_priv *il, void *resp); void il4965_sensitivity_calibration(struct il_priv *il, void *resp);
void il4965_init_sensitivity(struct il_priv *il); void il4965_init_sensitivity(struct il_priv *il);
void il4965_reset_run_time_calib(struct il_priv *il); void il4965_reset_run_time_calib(struct il_priv *il);
void il4965_calib_free_results(struct il_priv *il);
/* Debug */ /* Debug */
#ifdef CONFIG_IWLEGACY_DEBUGFS #ifdef CONFIG_IWLEGACY_DEBUGFS
ssize_t il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf, extern const struct il_debugfs_ops il4965_debugfs_ops;
size_t count, loff_t *ppos);
ssize_t il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
ssize_t il4965_ucode_general_stats_read(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos);
#endif #endif
/****************************/ /****************************/

View File

@ -6,45 +6,6 @@ config IWLEGACY
select LEDS_TRIGGERS select LEDS_TRIGGERS
select MAC80211_LEDS select MAC80211_LEDS
menu "Debugging Options"
depends on IWLEGACY
config IWLEGACY_DEBUG
bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers"
depends on IWLEGACY
---help---
This option will enable debug tracing output for the iwlegacy
drivers.
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/class/net/wlan0/device/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlegacy/common.h
If this is your first time using this driver, you should say Y here
as the debug information can assist others in helping you resolve
any problems you may encounter.
config IWLEGACY_DEBUGFS
bool "iwlegacy (iwl 3945/4965) debugfs support"
depends on IWLEGACY && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlegacy drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
endmenu
config IWL4965 config IWL4965
tristate "Intel Wireless WiFi 4965AGN (iwl4965)" tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
depends on PCI && MAC80211 depends on PCI && MAC80211
@ -98,3 +59,42 @@ config IWL3945
inserted in and removed from the running kernel whenever you want), inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945. module will be called iwl3945.
menu "iwl3945 / iwl4965 Debugging Options"
depends on IWLEGACY
config IWLEGACY_DEBUG
bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers"
depends on IWLEGACY
---help---
This option will enable debug tracing output for the iwlegacy
drivers.
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/class/net/wlan0/device/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlegacy/common.h
If this is your first time using this driver, you should say Y here
as the debug information can assist others in helping you resolve
any problems you may encounter.
config IWLEGACY_DEBUGFS
bool "iwlegacy (iwl 3945/4965) debugfs support"
depends on IWLEGACY && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlegacy drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
endmenu

File diff suppressed because it is too large Load Diff

View File

@ -425,12 +425,6 @@ struct il_eeprom_calib_info {
#define EEPROM_REGULATORY_BAND_NO_HT40 (0) #define EEPROM_REGULATORY_BAND_NO_HT40 (0)
struct il_eeprom_ops {
const u32 regulatory_bands[7];
int (*acquire_semaphore) (struct il_priv *il);
void (*release_semaphore) (struct il_priv *il);
};
int il_eeprom_init(struct il_priv *il); int il_eeprom_init(struct il_priv *il);
void il_eeprom_free(struct il_priv *il); void il_eeprom_free(struct il_priv *il);
const u8 *il_eeprom_query_addr(const struct il_priv *il, size_t offset); const u8 *il_eeprom_query_addr(const struct il_priv *il, size_t offset);
@ -962,26 +956,6 @@ enum il4965_chain_noise_state {
IL_CHAIN_NOISE_DONE, IL_CHAIN_NOISE_DONE,
}; };
enum il4965_calib_enabled_state {
IL_CALIB_DISABLED = 0, /* must be 0 */
IL_CALIB_ENABLED = 1,
};
/*
* enum il_calib
* defines the order in which results of initial calibrations
* should be sent to the runtime uCode
*/
enum il_calib {
IL_CALIB_MAX,
};
/* Opaque calibration results */
struct il_calib_result {
void *buf;
size_t buf_len;
};
enum ucode_type { enum ucode_type {
UCODE_NONE = 0, UCODE_NONE = 0,
UCODE_INIT, UCODE_INIT,
@ -1156,13 +1130,15 @@ struct il_power_mgr {
}; };
struct il_priv { struct il_priv {
/* ieee device used by generic ieee processing code */
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct ieee80211_channel *ieee_channels; struct ieee80211_channel *ieee_channels;
struct ieee80211_rate *ieee_rates; struct ieee80211_rate *ieee_rates;
struct il_cfg *cfg; struct il_cfg *cfg;
const struct il_ops *ops; const struct il_ops *ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
const struct il_debugfs_ops *debugfs_ops;
#endif
/* temporary frame storage list */ /* temporary frame storage list */
struct list_head free_frames; struct list_head free_frames;
@ -1199,9 +1175,6 @@ struct il_priv {
s32 temperature; /* degrees Kelvin */ s32 temperature; /* degrees Kelvin */
s32 last_temperature; s32 last_temperature;
/* init calibration results */
struct il_calib_result calib_results[IL_CALIB_MAX];
/* Scan related variables */ /* Scan related variables */
unsigned long scan_start; unsigned long scan_start;
unsigned long scan_start_tsf; unsigned long scan_start_tsf;
@ -1557,24 +1530,6 @@ il_free_pages(struct il_priv *il, unsigned long page)
#define IL_RX_BUF_SIZE_4K (4 * 1024) #define IL_RX_BUF_SIZE_4K (4 * 1024)
#define IL_RX_BUF_SIZE_8K (8 * 1024) #define IL_RX_BUF_SIZE_8K (8 * 1024)
struct il_hcmd_ops {
int (*rxon_assoc) (struct il_priv *il);
int (*commit_rxon) (struct il_priv *il);
void (*set_rxon_chain) (struct il_priv *il);
};
struct il_hcmd_utils_ops {
u16(*get_hcmd_size) (u8 cmd_id, u16 len);
u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data);
int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif);
void (*post_scan) (struct il_priv *il);
};
struct il_apm_ops {
int (*init) (struct il_priv *il);
void (*config) (struct il_priv *il);
};
#ifdef CONFIG_IWLEGACY_DEBUGFS #ifdef CONFIG_IWLEGACY_DEBUGFS
struct il_debugfs_ops { struct il_debugfs_ops {
ssize_t(*rx_stats_read) (struct file *file, char __user *user_buf, ssize_t(*rx_stats_read) (struct file *file, char __user *user_buf,
@ -1587,11 +1542,7 @@ struct il_debugfs_ops {
}; };
#endif #endif
struct il_temp_ops { struct il_ops {
void (*temperature) (struct il_priv *il);
};
struct il_lib_ops {
/* Handling TX */ /* Handling TX */
void (*txq_update_byte_cnt_tbl) (struct il_priv *il, void (*txq_update_byte_cnt_tbl) (struct il_priv *il,
struct il_tx_queue *txq, struct il_tx_queue *txq,
@ -1601,8 +1552,6 @@ struct il_lib_ops {
u16 len, u8 reset, u8 pad); u16 len, u8 reset, u8 pad);
void (*txq_free_tfd) (struct il_priv *il, struct il_tx_queue *txq); void (*txq_free_tfd) (struct il_priv *il, struct il_tx_queue *txq);
int (*txq_init) (struct il_priv *il, struct il_tx_queue *txq); int (*txq_init) (struct il_priv *il, struct il_tx_queue *txq);
/* setup Rx handler */
void (*handler_setup) (struct il_priv *il);
/* alive notification after init uCode load */ /* alive notification after init uCode load */
void (*init_alive_start) (struct il_priv *il); void (*init_alive_start) (struct il_priv *il);
/* check validity of rtc data address */ /* check validity of rtc data address */
@ -1615,44 +1564,33 @@ struct il_lib_ops {
int (*set_channel_switch) (struct il_priv *il, int (*set_channel_switch) (struct il_priv *il,
struct ieee80211_channel_switch *ch_switch); struct ieee80211_channel_switch *ch_switch);
/* power management */ /* power management */
struct il_apm_ops apm_ops; int (*apm_init) (struct il_priv *il);
/* power */ /* tx power */
int (*send_tx_power) (struct il_priv *il); int (*send_tx_power) (struct il_priv *il);
void (*update_chain_flags) (struct il_priv *il); void (*update_chain_flags) (struct il_priv *il);
/* eeprom operations */ /* eeprom operations */
struct il_eeprom_ops eeprom_ops; int (*eeprom_acquire_semaphore) (struct il_priv *il);
void (*eeprom_release_semaphore) (struct il_priv *il);
/* temperature */ int (*rxon_assoc) (struct il_priv *il);
struct il_temp_ops temp_ops; int (*commit_rxon) (struct il_priv *il);
void (*set_rxon_chain) (struct il_priv *il);
#ifdef CONFIG_IWLEGACY_DEBUGFS u16(*get_hcmd_size) (u8 cmd_id, u16 len);
struct il_debugfs_ops debugfs_ops; u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data);
#endif
}; int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif);
void (*post_scan) (struct il_priv *il);
struct il_led_ops {
int (*cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
};
struct il_legacy_ops {
void (*post_associate) (struct il_priv *il); void (*post_associate) (struct il_priv *il);
void (*config_ap) (struct il_priv *il); void (*config_ap) (struct il_priv *il);
/* station management */ /* station management */
int (*update_bcast_stations) (struct il_priv *il); int (*update_bcast_stations) (struct il_priv *il);
int (*manage_ibss_station) (struct il_priv *il, int (*manage_ibss_station) (struct il_priv *il,
struct ieee80211_vif *vif, bool add); struct ieee80211_vif *vif, bool add);
};
struct il_ops { int (*send_led_cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
const struct il_lib_ops *lib;
const struct il_hcmd_ops *hcmd;
const struct il_hcmd_utils_ops *utils;
const struct il_led_ops *led;
const struct il_nic_ops *nic;
const struct il_legacy_ops *legacy;
}; };
struct il_mod_params { struct il_mod_params {
@ -1665,22 +1603,6 @@ struct il_mod_params {
int restart_fw; /* def: 1 = restart firmware */ int restart_fw; /* def: 1 = restart firmware */
}; };
/*
* @led_compensation: compensate on the led on/off time per HW according
* to the deviation to achieve the desired led frequency.
* The detail algorithm is described in common.c
* @chain_noise_num_beacons: number of beacons used to compute chain noise
* @wd_timeout: TX queues watchdog timeout
* @temperature_kelvin: temperature report by uCode in kelvin
* @ucode_tracing: support ucode continuous tracing
* @sensitivity_calib_by_driver: driver has the capability to perform
* sensitivity calibration operation
* @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation
*/
struct il_base_params {
};
#define IL_LED_SOLID 11 #define IL_LED_SOLID 11
#define IL_DEF_LED_INTRVL cpu_to_le32(1000) #define IL_DEF_LED_INTRVL cpu_to_le32(1000)
@ -1769,6 +1691,8 @@ struct il_cfg {
const bool ucode_tracing; const bool ucode_tracing;
const bool sensitivity_calib_by_driver; const bool sensitivity_calib_by_driver;
const bool chain_noise_calib_by_driver; const bool chain_noise_calib_by_driver;
const u32 regulatory_bands[7];
}; };
/*************************** /***************************
@ -1800,60 +1724,24 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum nl80211_iftype newtype, bool newp2p); enum nl80211_iftype newtype, bool newp2p);
int il_alloc_txq_mem(struct il_priv *il); int il_alloc_txq_mem(struct il_priv *il);
void il_txq_mem(struct il_priv *il); void il_free_txq_mem(struct il_priv *il);
#ifdef CONFIG_IWLEGACY_DEBUGFS #ifdef CONFIG_IWLEGACY_DEBUGFS
int il_alloc_traffic_mem(struct il_priv *il); extern void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len);
void il_free_traffic_mem(struct il_priv *il);
void il_reset_traffic_log(struct il_priv *il);
void il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
struct ieee80211_hdr *header);
void il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
struct ieee80211_hdr *header);
const char *il_get_mgmt_string(int cmd);
const char *il_get_ctrl_string(int cmd);
void il_clear_traffic_stats(struct il_priv *il);
void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len);
#else #else
static inline int
il_alloc_traffic_mem(struct il_priv *il)
{
return 0;
}
static inline void
il_free_traffic_mem(struct il_priv *il)
{
}
static inline void
il_reset_traffic_log(struct il_priv *il)
{
}
static inline void
il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
struct ieee80211_hdr *header)
{
}
static inline void
il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
struct ieee80211_hdr *header)
{
}
static inline void static inline void
il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len) il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
{ {
} }
#endif #endif
/***************************************************** /*****************************************************
* RX handlers. * Handlers
* **************************************************/ ***************************************************/
void il_hdl_pm_sleep(struct il_priv *il, struct il_rx_buf *rxb); void il_hdl_pm_sleep(struct il_priv *il, struct il_rx_buf *rxb);
void il_hdl_pm_debug_stats(struct il_priv *il, struct il_rx_buf *rxb); void il_hdl_pm_debug_stats(struct il_priv *il, struct il_rx_buf *rxb);
void il_hdl_error(struct il_priv *il, struct il_rx_buf *rxb); void il_hdl_error(struct il_priv *il, struct il_rx_buf *rxb);
void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb);
/***************************************************** /*****************************************************
* RX * RX
@ -1864,25 +1752,20 @@ int il_rx_queue_alloc(struct il_priv *il);
void il_rx_queue_update_write_ptr(struct il_priv *il, struct il_rx_queue *q); void il_rx_queue_update_write_ptr(struct il_priv *il, struct il_rx_queue *q);
int il_rx_queue_space(const struct il_rx_queue *q); int il_rx_queue_space(const struct il_rx_queue *q);
void il_tx_cmd_complete(struct il_priv *il, struct il_rx_buf *rxb); void il_tx_cmd_complete(struct il_priv *il, struct il_rx_buf *rxb);
/* Handlers */
void il_hdl_spectrum_measurement(struct il_priv *il, struct il_rx_buf *rxb); void il_hdl_spectrum_measurement(struct il_priv *il, struct il_rx_buf *rxb);
void il_recover_from_stats(struct il_priv *il, struct il_rx_pkt *pkt); void il_recover_from_stats(struct il_priv *il, struct il_rx_pkt *pkt);
void il_chswitch_done(struct il_priv *il, bool is_success); void il_chswitch_done(struct il_priv *il, bool is_success);
void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb);
/* TX helpers */
/***************************************************** /*****************************************************
* TX * TX
******************************************************/ ******************************************************/
void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); extern void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq);
int il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num, extern int il_tx_queue_init(struct il_priv *il, u32 txq_id);
u32 txq_id); extern void il_tx_queue_reset(struct il_priv *il, u32 txq_id);
void il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq, extern void il_tx_queue_unmap(struct il_priv *il, int txq_id);
int slots_num, u32 txq_id); extern void il_tx_queue_free(struct il_priv *il, int txq_id);
void il_tx_queue_unmap(struct il_priv *il, int txq_id); extern void il_setup_watchdog(struct il_priv *il);
void il_tx_queue_free(struct il_priv *il, int txq_id);
void il_setup_watchdog(struct il_priv *il);
/***************************************************** /*****************************************************
* TX power * TX power
****************************************************/ ****************************************************/
@ -2000,7 +1883,7 @@ void il_free_geos(struct il_priv *il);
#define S_HCMD_ACTIVE 0 /* host command in progress */ #define S_HCMD_ACTIVE 0 /* host command in progress */
/* 1 is unused (used to be S_HCMD_SYNC_ACTIVE) */ /* 1 is unused (used to be S_HCMD_SYNC_ACTIVE) */
#define S_INT_ENABLED 2 #define S_INT_ENABLED 2
#define S_RF_KILL_HW 3 #define S_RFKILL 3
#define S_CT_KILL 4 #define S_CT_KILL 4
#define S_INIT 5 #define S_INIT 5
#define S_ALIVE 6 #define S_ALIVE 6
@ -2038,16 +1921,10 @@ il_is_init(struct il_priv *il)
return test_bit(S_INIT, &il->status); return test_bit(S_INIT, &il->status);
} }
static inline int
il_is_rfkill_hw(struct il_priv *il)
{
return test_bit(S_RF_KILL_HW, &il->status);
}
static inline int static inline int
il_is_rfkill(struct il_priv *il) il_is_rfkill(struct il_priv *il)
{ {
return il_is_rfkill_hw(il); return test_bit(S_RFKILL, &il->status);
} }
static inline int static inline int
@ -2068,7 +1945,9 @@ il_is_ready_rf(struct il_priv *il)
extern void il_send_bt_config(struct il_priv *il); extern void il_send_bt_config(struct il_priv *il);
extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear);
void il_apm_stop(struct il_priv *il); extern void il_apm_stop(struct il_priv *il);
extern void _il_apm_stop(struct il_priv *il);
int il_apm_init(struct il_priv *il); int il_apm_init(struct il_priv *il);
int il_send_rxon_timing(struct il_priv *il); int il_send_rxon_timing(struct il_priv *il);
@ -2076,13 +1955,13 @@ int il_send_rxon_timing(struct il_priv *il);
static inline int static inline int
il_send_rxon_assoc(struct il_priv *il) il_send_rxon_assoc(struct il_priv *il)
{ {
return il->ops->hcmd->rxon_assoc(il); return il->ops->rxon_assoc(il);
} }
static inline int static inline int
il_commit_rxon(struct il_priv *il) il_commit_rxon(struct il_priv *il)
{ {
return il->ops->hcmd->commit_rxon(il); return il->ops->commit_rxon(il);
} }
static inline const struct ieee80211_supported_band * static inline const struct ieee80211_supported_band *
@ -2103,7 +1982,7 @@ irqreturn_t il_isr(int irq, void *data);
extern void il_set_bit(struct il_priv *p, u32 r, u32 m); extern void il_set_bit(struct il_priv *p, u32 r, u32 m);
extern void il_clear_bit(struct il_priv *p, u32 r, u32 m); extern void il_clear_bit(struct il_priv *p, u32 r, u32 m);
extern int _il_grab_nic_access(struct il_priv *il); extern bool _il_grab_nic_access(struct il_priv *il);
extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout);
extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout);
extern u32 il_rd_prph(struct il_priv *il, u32 reg); extern u32 il_rd_prph(struct il_priv *il, u32 reg);
@ -2114,20 +1993,20 @@ extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val);
static inline void static inline void
_il_write8(struct il_priv *il, u32 ofs, u8 val) _il_write8(struct il_priv *il, u32 ofs, u8 val)
{ {
iowrite8(val, il->hw_base + ofs); writeb(val, il->hw_base + ofs);
} }
#define il_write8(il, ofs, val) _il_write8(il, ofs, val) #define il_write8(il, ofs, val) _il_write8(il, ofs, val)
static inline void static inline void
_il_wr(struct il_priv *il, u32 ofs, u32 val) _il_wr(struct il_priv *il, u32 ofs, u32 val)
{ {
iowrite32(val, il->hw_base + ofs); writel(val, il->hw_base + ofs);
} }
static inline u32 static inline u32
_il_rd(struct il_priv *il, u32 ofs) _il_rd(struct il_priv *il, u32 ofs)
{ {
return ioread32(il->hw_base + ofs); return readl(il->hw_base + ofs);
} }
static inline void static inline void
@ -2146,6 +2025,13 @@ static inline void
_il_release_nic_access(struct il_priv *il) _il_release_nic_access(struct il_priv *il)
{ {
_il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
/*
* In above we are reading CSR_GP_CNTRL register, what will flush any
* previous writes, but still want write, which clear MAC_ACCESS_REQ
* bit, be performed on PCI bus before any other writes scheduled on
* different CPUs (after we drop reg_lock).
*/
mmiowb();
} }
static inline u32 static inline u32
@ -2168,7 +2054,7 @@ il_wr(struct il_priv *il, u32 reg, u32 value)
unsigned long reg_flags; unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags); spin_lock_irqsave(&il->reg_lock, reg_flags);
if (!_il_grab_nic_access(il)) { if (likely(_il_grab_nic_access(il))) {
_il_wr(il, reg, value); _il_wr(il, reg, value);
_il_release_nic_access(il); _il_release_nic_access(il);
} }
@ -2179,7 +2065,6 @@ static inline u32
_il_rd_prph(struct il_priv *il, u32 reg) _il_rd_prph(struct il_priv *il, u32 reg)
{ {
_il_wr(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); _il_wr(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
rmb();
return _il_rd(il, HBUS_TARG_PRPH_RDAT); return _il_rd(il, HBUS_TARG_PRPH_RDAT);
} }
@ -2187,7 +2072,6 @@ static inline void
_il_wr_prph(struct il_priv *il, u32 addr, u32 val) _il_wr_prph(struct il_priv *il, u32 addr, u32 val)
{ {
_il_wr(il, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24))); _il_wr(il, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24)));
wmb();
_il_wr(il, HBUS_TARG_PRPH_WDAT, val); _il_wr(il, HBUS_TARG_PRPH_WDAT, val);
} }
@ -2197,9 +2081,10 @@ il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask)
unsigned long reg_flags; unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags); spin_lock_irqsave(&il->reg_lock, reg_flags);
_il_grab_nic_access(il); if (likely(_il_grab_nic_access(il))) {
_il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask)); _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
_il_release_nic_access(il); _il_release_nic_access(il);
}
spin_unlock_irqrestore(&il->reg_lock, reg_flags); spin_unlock_irqrestore(&il->reg_lock, reg_flags);
} }
@ -2209,9 +2094,10 @@ il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask)
unsigned long reg_flags; unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags); spin_lock_irqsave(&il->reg_lock, reg_flags);
_il_grab_nic_access(il); if (likely(_il_grab_nic_access(il))) {
_il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits)); _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
_il_release_nic_access(il); _il_release_nic_access(il);
}
spin_unlock_irqrestore(&il->reg_lock, reg_flags); spin_unlock_irqrestore(&il->reg_lock, reg_flags);
} }
@ -2222,10 +2108,11 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask)
u32 val; u32 val;
spin_lock_irqsave(&il->reg_lock, reg_flags); spin_lock_irqsave(&il->reg_lock, reg_flags);
_il_grab_nic_access(il); if (likely(_il_grab_nic_access(il))) {
val = _il_rd_prph(il, reg); val = _il_rd_prph(il, reg);
_il_wr_prph(il, reg, (val & ~mask)); _il_wr_prph(il, reg, (val & ~mask));
_il_release_nic_access(il); _il_release_nic_access(il);
}
spin_unlock_irqrestore(&il->reg_lock, reg_flags); spin_unlock_irqrestore(&il->reg_lock, reg_flags);
} }
@ -2487,8 +2374,8 @@ struct il_rb_status {
__le32 __unused; /* 3945 only */ __le32 __unused; /* 3945 only */
} __packed; } __packed;
#define TFD_QUEUE_SIZE_MAX (256) #define TFD_QUEUE_SIZE_MAX 256
#define TFD_QUEUE_SIZE_BC_DUP (64) #define TFD_QUEUE_SIZE_BC_DUP 64
#define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP) #define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
#define IL_TX_DMA_MASK DMA_BIT_MASK(36) #define IL_TX_DMA_MASK DMA_BIT_MASK(36)
#define IL_NUM_OF_TBS 20 #define IL_NUM_OF_TBS 20

View File

@ -31,6 +31,101 @@
#include "common.h" #include "common.h"
void
il_clear_traffic_stats(struct il_priv *il)
{
memset(&il->tx_stats, 0, sizeof(struct traffic_stats));
memset(&il->rx_stats, 0, sizeof(struct traffic_stats));
}
/*
* il_update_stats function record all the MGMT, CTRL and DATA pkt for
* both TX and Rx . Use debugfs to display the rx/rx_stats
*/
void
il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
{
struct traffic_stats *stats;
if (is_tx)
stats = &il->tx_stats;
else
stats = &il->rx_stats;
if (ieee80211_is_mgmt(fc)) {
switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
break;
case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
break;
case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
stats->mgmt[MANAGEMENT_PROBE_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
stats->mgmt[MANAGEMENT_PROBE_RESP]++;
break;
case cpu_to_le16(IEEE80211_STYPE_BEACON):
stats->mgmt[MANAGEMENT_BEACON]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ATIM):
stats->mgmt[MANAGEMENT_ATIM]++;
break;
case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
stats->mgmt[MANAGEMENT_DISASSOC]++;
break;
case cpu_to_le16(IEEE80211_STYPE_AUTH):
stats->mgmt[MANAGEMENT_AUTH]++;
break;
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
stats->mgmt[MANAGEMENT_DEAUTH]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ACTION):
stats->mgmt[MANAGEMENT_ACTION]++;
break;
}
} else if (ieee80211_is_ctl(fc)) {
switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
stats->ctrl[CONTROL_BACK_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_BACK):
stats->ctrl[CONTROL_BACK]++;
break;
case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
stats->ctrl[CONTROL_PSPOLL]++;
break;
case cpu_to_le16(IEEE80211_STYPE_RTS):
stats->ctrl[CONTROL_RTS]++;
break;
case cpu_to_le16(IEEE80211_STYPE_CTS):
stats->ctrl[CONTROL_CTS]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ACK):
stats->ctrl[CONTROL_ACK]++;
break;
case cpu_to_le16(IEEE80211_STYPE_CFEND):
stats->ctrl[CONTROL_CFEND]++;
break;
case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
stats->ctrl[CONTROL_CFENDACK]++;
break;
}
} else {
/* data */
stats->data_cnt++;
stats->data_bytes += len;
}
}
EXPORT_SYMBOL(il_update_stats);
/* create and remove of files */ /* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
if (!debugfs_create_file(#name, mode, parent, il, \ if (!debugfs_create_file(#name, mode, parent, il, \
@ -98,6 +193,46 @@ static const struct file_operations il_dbgfs_##name##_ops = { \
.llseek = generic_file_llseek, \ .llseek = generic_file_llseek, \
}; };
static const char *
il_get_mgmt_string(int cmd)
{
switch (cmd) {
IL_CMD(MANAGEMENT_ASSOC_REQ);
IL_CMD(MANAGEMENT_ASSOC_RESP);
IL_CMD(MANAGEMENT_REASSOC_REQ);
IL_CMD(MANAGEMENT_REASSOC_RESP);
IL_CMD(MANAGEMENT_PROBE_REQ);
IL_CMD(MANAGEMENT_PROBE_RESP);
IL_CMD(MANAGEMENT_BEACON);
IL_CMD(MANAGEMENT_ATIM);
IL_CMD(MANAGEMENT_DISASSOC);
IL_CMD(MANAGEMENT_AUTH);
IL_CMD(MANAGEMENT_DEAUTH);
IL_CMD(MANAGEMENT_ACTION);
default:
return "UNKNOWN";
}
}
static const char *
il_get_ctrl_string(int cmd)
{
switch (cmd) {
IL_CMD(CONTROL_BACK_REQ);
IL_CMD(CONTROL_BACK);
IL_CMD(CONTROL_PSPOLL);
IL_CMD(CONTROL_RTS);
IL_CMD(CONTROL_CTS);
IL_CMD(CONTROL_ACK);
IL_CMD(CONTROL_CFEND);
IL_CMD(CONTROL_CFENDACK);
default:
return "UNKNOWN";
}
}
static ssize_t static ssize_t
il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count, il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,
loff_t *ppos) loff_t *ppos)
@ -495,8 +630,8 @@ il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count,
scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n", scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
test_bit(S_INT_ENABLED, &il->status)); test_bit(S_INT_ENABLED, &il->status));
pos += pos +=
scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n", scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n",
test_bit(S_RF_KILL_HW, &il->status)); test_bit(S_RFKILL, &il->status));
pos += pos +=
scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n", scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
test_bit(S_CT_KILL, &il->status)); test_bit(S_CT_KILL, &il->status));
@ -714,112 +849,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
DEBUGFS_READ_FILE_OPS(qos); DEBUGFS_READ_FILE_OPS(qos);
DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
static ssize_t
il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct il_priv *il = file->private_data;
int pos = 0, ofs = 0;
int cnt = 0, entry;
struct il_tx_queue *txq;
struct il_queue *q;
struct il_rx_queue *rxq = &il->rxq;
char *buf;
int bufsz =
((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
(il->cfg->num_of_queues * 32 * 8) + 400;
const u8 *ptr;
ssize_t ret;
if (!il->txq) {
IL_ERR("txq not ready\n");
return -EAGAIN;
}
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) {
IL_ERR("Can not allocate buffer\n");
return -ENOMEM;
}
pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
txq = &il->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 (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
ptr = il->tx_traffic;
pos +=
scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n",
il->tx_traffic_idx);
for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
for (entry = 0; entry < IL_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 (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
ptr = il->rx_traffic;
pos +=
scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n",
il->rx_traffic_idx);
for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
for (entry = 0; entry < IL_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
il_dbgfs_traffic_log_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct il_priv *il = 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)
il_reset_traffic_log(il);
return count;
}
static ssize_t static ssize_t
il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count, il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
loff_t *ppos) loff_t *ppos)
@ -901,7 +930,8 @@ il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct il_priv *il = file->private_data; struct il_priv *il = file->private_data;
return il->ops->lib->debugfs_ops.rx_stats_read(file, user_buf, count, ppos);
return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos);
} }
static ssize_t static ssize_t
@ -909,7 +939,8 @@ il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct il_priv *il = file->private_data; struct il_priv *il = file->private_data;
return il->ops->lib->debugfs_ops.tx_stats_read(file, user_buf, count, ppos);
return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos);
} }
static ssize_t static ssize_t
@ -917,7 +948,8 @@ il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct il_priv *il = file->private_data; struct il_priv *il = file->private_data;
return il->ops->lib->debugfs_ops.general_stats_read(file, user_buf, count, ppos);
return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos);
} }
static ssize_t static ssize_t
@ -1175,8 +1207,8 @@ il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
int pos = 0; int pos = 0;
ssize_t ret = -EFAULT; ssize_t ret = -EFAULT;
if (il->ops->lib->dump_fh) { if (il->ops->dump_fh) {
ret = pos = il->ops->lib->dump_fh(il, &buf, true); ret = pos = il->ops->dump_fh(il, &buf, true);
if (buf) { if (buf) {
ret = ret =
simple_read_from_buffer(user_buf, count, ppos, buf, simple_read_from_buffer(user_buf, count, ppos, buf,
@ -1300,7 +1332,6 @@ il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
DEBUGFS_READ_FILE_OPS(rx_stats); DEBUGFS_READ_FILE_OPS(rx_stats);
DEBUGFS_READ_FILE_OPS(tx_stats); DEBUGFS_READ_FILE_OPS(tx_stats);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
DEBUGFS_READ_FILE_OPS(rx_queue); DEBUGFS_READ_FILE_OPS(rx_queue);
DEBUGFS_READ_FILE_OPS(tx_queue); DEBUGFS_READ_FILE_OPS(tx_queue);
DEBUGFS_READ_FILE_OPS(ucode_rx_stats); DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
@ -1354,7 +1385,6 @@ il_dbgfs_register(struct il_priv *il, const char *name)
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);

View File

@ -1,7 +1,7 @@
# WIFI # WIFI
obj-$(CONFIG_IWLWIFI) += iwlwifi.o obj-$(CONFIG_IWLWIFI) += iwlwifi.o
iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o
iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o iwl-debug.o
iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
@ -13,6 +13,7 @@ iwlwifi-objs += iwl-6000.o
iwlwifi-objs += iwl-1000.o iwlwifi-objs += iwl-1000.o
iwlwifi-objs += iwl-2000.o iwlwifi-objs += iwl-2000.o
iwlwifi-objs += iwl-pci.o iwlwifi-objs += iwl-pci.o
iwlwifi-objs += iwl-drv.o
iwlwifi-objs += iwl-trans.o iwlwifi-objs += iwl-trans.o
iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o

View File

@ -120,7 +120,7 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
.nrg_th_cca = 62, .nrg_th_cca = 62,
}; };
static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
{ {
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@ -128,8 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params.num_of_queues; iwlagn_mod_params.num_of_queues;
hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ);
@ -146,8 +144,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */ /* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl1000_sensitivity; hw_params(priv).sens = &iwl1000_sensitivity;
return 0;
} }
static struct iwl_lib_ops iwl1000_lib = { static struct iwl_lib_ops iwl1000_lib = {
@ -193,6 +189,8 @@ static struct iwl_ht_params iwl1000_ht_params = {
.ucode_api_max = IWL1000_UCODE_API_MAX, \ .ucode_api_max = IWL1000_UCODE_API_MAX, \
.ucode_api_ok = IWL1000_UCODE_API_OK, \ .ucode_api_ok = IWL1000_UCODE_API_OK, \
.ucode_api_min = IWL1000_UCODE_API_MIN, \ .ucode_api_min = IWL1000_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.lib = &iwl1000_lib, \ .lib = &iwl1000_lib, \
@ -215,6 +213,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
.ucode_api_max = IWL100_UCODE_API_MAX, \ .ucode_api_max = IWL100_UCODE_API_MAX, \
.ucode_api_ok = IWL100_UCODE_API_OK, \ .ucode_api_ok = IWL100_UCODE_API_OK, \
.ucode_api_min = IWL100_UCODE_API_MIN, \ .ucode_api_min = IWL100_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.lib = &iwl1000_lib, \ .lib = &iwl1000_lib, \

View File

@ -116,7 +116,7 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
.nrg_th_cca = 62, .nrg_th_cca = 62,
}; };
static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
{ {
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@ -124,8 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params.num_of_queues; iwlagn_mod_params.num_of_queues;
hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ);
@ -142,8 +140,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */ /* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl2000_sensitivity; hw_params(priv).sens = &iwl2000_sensitivity;
return 0;
} }
static struct iwl_lib_ops iwl2000_lib = { static struct iwl_lib_ops iwl2000_lib = {
@ -242,6 +238,8 @@ static struct iwl_bt_params iwl2030_bt_params = {
.ucode_api_max = IWL2000_UCODE_API_MAX, \ .ucode_api_max = IWL2000_UCODE_API_MAX, \
.ucode_api_ok = IWL2000_UCODE_API_OK, \ .ucode_api_ok = IWL2000_UCODE_API_OK, \
.ucode_api_min = IWL2000_UCODE_API_MIN, \ .ucode_api_min = IWL2000_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2000_lib, \ .lib = &iwl2000_lib, \
@ -268,6 +266,8 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = {
.ucode_api_max = IWL2030_UCODE_API_MAX, \ .ucode_api_max = IWL2030_UCODE_API_MAX, \
.ucode_api_ok = IWL2030_UCODE_API_OK, \ .ucode_api_ok = IWL2030_UCODE_API_OK, \
.ucode_api_min = IWL2030_UCODE_API_MIN, \ .ucode_api_min = IWL2030_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2030_lib, \ .lib = &iwl2030_lib, \
@ -290,6 +290,8 @@ struct iwl_cfg iwl2030_2bgn_cfg = {
.ucode_api_max = IWL105_UCODE_API_MAX, \ .ucode_api_max = IWL105_UCODE_API_MAX, \
.ucode_api_ok = IWL105_UCODE_API_OK, \ .ucode_api_ok = IWL105_UCODE_API_OK, \
.ucode_api_min = IWL105_UCODE_API_MIN, \ .ucode_api_min = IWL105_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2000_lib, \ .lib = &iwl2000_lib, \
@ -318,6 +320,8 @@ struct iwl_cfg iwl105_bgn_d_cfg = {
.ucode_api_max = IWL135_UCODE_API_MAX, \ .ucode_api_max = IWL135_UCODE_API_MAX, \
.ucode_api_ok = IWL135_UCODE_API_OK, \ .ucode_api_ok = IWL135_UCODE_API_OK, \
.ucode_api_min = IWL135_UCODE_API_MIN, \ .ucode_api_min = IWL135_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2030_lib, \ .lib = &iwl2030_lib, \

View File

@ -162,7 +162,7 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
} }
static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
{ {
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@ -170,8 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params.num_of_queues; iwlagn_mod_params.num_of_queues;
hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ); BIT(IEEE80211_BAND_5GHZ);
@ -185,11 +183,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */ /* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl5000_sensitivity; hw_params(priv).sens = &iwl5000_sensitivity;
return 0;
} }
static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
{ {
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@ -197,8 +193,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params.num_of_queues; iwlagn_mod_params.num_of_queues;
hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ); BIT(IEEE80211_BAND_5GHZ);
@ -212,8 +206,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */ /* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl5150_sensitivity; hw_params(priv).sens = &iwl5150_sensitivity;
return 0;
} }
static void iwl5150_temperature(struct iwl_priv *priv) static void iwl5150_temperature(struct iwl_priv *priv)
@ -356,6 +348,8 @@ static struct iwl_ht_params iwl5000_ht_params = {
.fw_name_pre = IWL5000_FW_PRE, \ .fw_name_pre = IWL5000_FW_PRE, \
.ucode_api_max = IWL5000_UCODE_API_MAX, \ .ucode_api_max = IWL5000_UCODE_API_MAX, \
.ucode_api_min = IWL5000_UCODE_API_MIN, \ .ucode_api_min = IWL5000_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
.lib = &iwl5000_lib, \ .lib = &iwl5000_lib, \
@ -399,6 +393,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN, .ucode_api_min = IWL5000_UCODE_API_MIN,
.max_inst_size = IWLAGN_RTC_INST_SIZE,
.max_data_size = IWLAGN_RTC_DATA_SIZE,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.lib = &iwl5000_lib, .lib = &iwl5000_lib,
@ -412,6 +408,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5150_FW_PRE, \ .fw_name_pre = IWL5150_FW_PRE, \
.ucode_api_max = IWL5150_UCODE_API_MAX, \ .ucode_api_max = IWL5150_UCODE_API_MAX, \
.ucode_api_min = IWL5150_UCODE_API_MIN, \ .ucode_api_min = IWL5150_UCODE_API_MIN, \
.max_inst_size = IWLAGN_RTC_INST_SIZE, \
.max_data_size = IWLAGN_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
.lib = &iwl5150_lib, \ .lib = &iwl5150_lib, \

View File

@ -137,7 +137,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
.nrg_th_cca = 62, .nrg_th_cca = 62,
}; };
static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
{ {
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
@ -145,8 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
iwlagn_mod_params.num_of_queues; iwlagn_mod_params.num_of_queues;
hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ); BIT(IEEE80211_BAND_5GHZ);
@ -165,7 +163,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */ /* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl6000_sensitivity; hw_params(priv).sens = &iwl6000_sensitivity;
return 0;
} }
static int iwl6000_hw_channel_switch(struct iwl_priv *priv, static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
@ -349,6 +346,8 @@ static struct iwl_bt_params iwl6000_bt_params = {
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
.ucode_api_ok = IWL6000G2_UCODE_API_OK, \ .ucode_api_ok = IWL6000G2_UCODE_API_OK, \
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
.lib = &iwl6000_lib, \ .lib = &iwl6000_lib, \
@ -384,11 +383,24 @@ struct iwl_cfg iwl6005_2agn_d_cfg = {
.ht_params = &iwl6000_ht_params, .ht_params = &iwl6000_ht_params,
}; };
struct iwl_cfg iwl6005_2agn_mow1_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6206 AGN",
IWL_DEVICE_6005,
.ht_params = &iwl6000_ht_params,
};
struct iwl_cfg iwl6005_2agn_mow2_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6207 AGN",
IWL_DEVICE_6005,
.ht_params = &iwl6000_ht_params,
};
#define IWL_DEVICE_6030 \ #define IWL_DEVICE_6030 \
.fw_name_pre = IWL6030_FW_PRE, \ .fw_name_pre = IWL6030_FW_PRE, \
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \
.ucode_api_ok = IWL6000G2_UCODE_API_OK, \ .ucode_api_ok = IWL6000G2_UCODE_API_OK, \
.ucode_api_min = IWL6000G2_UCODE_API_MIN, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
.lib = &iwl6030_lib, \ .lib = &iwl6030_lib, \
@ -458,6 +470,8 @@ struct iwl_cfg iwl130_bg_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX, \ .ucode_api_max = IWL6000_UCODE_API_MAX, \
.ucode_api_ok = IWL6000_UCODE_API_OK, \ .ucode_api_ok = IWL6000_UCODE_API_OK, \
.ucode_api_min = IWL6000_UCODE_API_MIN, \ .ucode_api_min = IWL6000_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \
.valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
@ -487,6 +501,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \ .fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \
.ucode_api_min = IWL6050_UCODE_API_MIN, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \
.valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \
.lib = &iwl6000_lib, \ .lib = &iwl6000_lib, \
@ -512,6 +528,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \ .fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \
.ucode_api_min = IWL6050_UCODE_API_MIN, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.lib = &iwl6000_lib, \ .lib = &iwl6000_lib, \
.additional_nic_config = iwl6150_additional_nic_config, \ .additional_nic_config = iwl6150_additional_nic_config, \
.eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \
@ -537,6 +555,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_max = IWL6000_UCODE_API_MAX,
.ucode_api_ok = IWL6000_UCODE_API_OK, .ucode_api_ok = IWL6000_UCODE_API_OK,
.ucode_api_min = IWL6000_UCODE_API_MIN, .ucode_api_min = IWL6000_UCODE_API_MIN,
.max_inst_size = IWL60_RTC_INST_SIZE,
.max_data_size = IWL60_RTC_DATA_SIZE,
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.lib = &iwl6000_lib, .lib = &iwl6000_lib,

View File

@ -68,6 +68,8 @@
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-wifi.h"
#include "iwl-ucode.h"
/***************************************************************************** /*****************************************************************************
* INIT calibrations framework * INIT calibrations framework
@ -634,7 +636,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
data->last_bad_plcp_cnt_cck = 0; data->last_bad_plcp_cnt_cck = 0;
data->last_fa_cnt_cck = 0; data->last_fa_cnt_cck = 0;
if (priv->enhance_sensitivity_table) if (nic(priv)->fw.enhance_sensitivity_table)
ret |= iwl_enhance_sensitivity_write(priv); ret |= iwl_enhance_sensitivity_write(priv);
else else
ret |= iwl_sensitivity_write(priv); ret |= iwl_sensitivity_write(priv);
@ -745,7 +747,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv)
iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
if (priv->enhance_sensitivity_table) if (nic(priv)->fw.enhance_sensitivity_table)
iwl_enhance_sensitivity_write(priv); iwl_enhance_sensitivity_write(priv);
else else
iwl_sensitivity_write(priv); iwl_sensitivity_write(priv);

View File

@ -77,7 +77,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
if (IWL_UCODE_API(priv->ucode_ver) == 1) if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) == 1)
tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
else else
tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
@ -700,7 +700,7 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
priv->kill_cts_mask = bt_kill_cts_msg[kill_msk]; priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
/* schedule to send runtime bt_config */ /* schedule to send runtime bt_config */
queue_work(priv->shrd->workqueue, &priv->bt_runtime_config); queue_work(priv->workqueue, &priv->bt_runtime_config);
} }
} }
@ -745,7 +745,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
IWL_BT_COEX_TRAFFIC_LOAD_NONE; IWL_BT_COEX_TRAFFIC_LOAD_NONE;
} }
priv->bt_status = coex->bt_status; priv->bt_status = coex->bt_status;
queue_work(priv->shrd->workqueue, queue_work(priv->workqueue,
&priv->bt_traffic_change_work); &priv->bt_traffic_change_work);
} }
} }
@ -959,7 +959,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
struct ieee80211_key_conf *key, struct ieee80211_key_conf *key,
void *_data) void *_data)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct wowlan_key_data *data = _data; struct wowlan_key_data *data = _data;
struct iwl_rxon_context *ctx = data->ctx; struct iwl_rxon_context *ctx = data->ctx;
struct aes_sc *aes_sc, *aes_tx_sc = NULL; struct aes_sc *aes_sc, *aes_tx_sc = NULL;

View File

@ -38,6 +38,7 @@
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h" #include "iwl-core.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-op-mode.h"
#define RS_NAME "iwl-agn-rs" #define RS_NAME "iwl-agn-rs"
@ -892,7 +893,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
queue_work(priv->shrd->workqueue, &priv->bt_full_concurrency); queue_work(priv->workqueue, &priv->bt_full_concurrency);
} }
} }
@ -909,7 +910,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
struct iwl_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
struct iwl_link_quality_cmd *table; struct iwl_link_quality_cmd *table;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct iwl_priv *priv = (struct iwl_priv *)priv_r; struct iwl_op_mode *op_mode = (struct iwl_op_mode *)priv_r;
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
enum mac80211_rate_control_flags mac_flags; enum mac80211_rate_control_flags mac_flags;
u32 tx_rate; u32 tx_rate;
@ -2737,7 +2739,9 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb = txrc->skb; struct sk_buff *skb = txrc->skb;
struct ieee80211_supported_band *sband = txrc->sband; struct ieee80211_supported_band *sband = txrc->sband;
struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; struct iwl_op_mode *op_mode __maybe_unused =
(struct iwl_op_mode *)priv_r;
struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl_lq_sta *lq_sta = priv_sta; struct iwl_lq_sta *lq_sta = priv_sta;
int rate_idx; int rate_idx;
@ -2805,9 +2809,10 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
gfp_t gfp) gfp_t gfp)
{ {
struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv; struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
struct iwl_priv *priv; struct iwl_op_mode *op_mode __maybe_unused =
(struct iwl_op_mode *)priv_rate;
struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);
priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE(priv, "create station rate scale window\n"); IWL_DEBUG_RATE(priv, "create station rate scale window\n");
return &sta_priv->lq_sta; return &sta_priv->lq_sta;
@ -3074,7 +3079,8 @@ static void rs_free(void *priv_rate)
static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
void *priv_sta) void *priv_sta)
{ {
struct iwl_priv *priv __maybe_unused = priv_r; struct iwl_op_mode *op_mode __maybe_unused = priv_r;
struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode);
IWL_DEBUG_RATE(priv, "enter\n"); IWL_DEBUG_RATE(priv, "enter\n");
IWL_DEBUG_RATE(priv, "leave\n"); IWL_DEBUG_RATE(priv, "leave\n");

View File

@ -581,7 +581,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) && if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) &&
(pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
iwlagn_rx_calc_noise(priv); iwlagn_rx_calc_noise(priv);
queue_work(priv->shrd->workqueue, &priv->run_time_calib_work); queue_work(priv->workqueue, &priv->run_time_calib_work);
} }
if (cfg(priv)->lib->temperature && change) if (cfg(priv)->lib->temperature && change)
cfg(priv)->lib->temperature(priv); cfg(priv)->lib->temperature(priv);
@ -1141,10 +1141,11 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
} }
int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb,
struct iwl_device_cmd *cmd) struct iwl_device_cmd *cmd)
{ {
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
int err = 0; int err = 0;
/* /*

View File

@ -549,7 +549,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf,
int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx; struct iwl_rxon_context *ctx;
struct ieee80211_conf *conf = &hw->conf; struct ieee80211_conf *conf = &hw->conf;
struct ieee80211_channel *channel = conf->channel; struct ieee80211_channel *channel = conf->channel;
@ -805,7 +805,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf, struct ieee80211_bss_conf *bss_conf,
u32 changes) u32 changes)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
int ret; int ret;
bool force = false; bool force = false;
@ -900,6 +900,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
} }
} }
/*
* If the ucode decides to do beacon filtering before
* association, it will lose beacons that are needed
* before sending frames out on passive channels. This
* causes association failures on those channels. Enable
* receiving beacons in such cases.
*/
if (vif->type == NL80211_IFTYPE_STATION) {
if (!bss_conf->assoc)
ctx->staging.filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
else
ctx->staging.filter_flags &=
~RXON_FILTER_BCON_AWARE_MSK;
}
if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
iwlagn_commit_rxon(priv, ctx); iwlagn_commit_rxon(priv, ctx);

View File

@ -568,7 +568,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
return; return;
IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n");
queue_work(priv->shrd->workqueue, &priv->ct_enter); queue_work(priv->workqueue, &priv->ct_enter);
} }
void iwl_tt_exit_ct_kill(struct iwl_priv *priv) void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
@ -577,7 +577,7 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
return; return;
IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n");
queue_work(priv->shrd->workqueue, &priv->ct_exit); queue_work(priv->workqueue, &priv->ct_exit);
} }
static void iwl_bg_tt_work(struct work_struct *work) static void iwl_bg_tt_work(struct work_struct *work)
@ -600,7 +600,7 @@ void iwl_tt_handler(struct iwl_priv *priv)
return; return;
IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n");
queue_work(priv->shrd->workqueue, &priv->tt_work); queue_work(priv->workqueue, &priv->tt_work);
} }
/* Thermal throttling initialization /* Thermal throttling initialization

View File

@ -322,7 +322,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
sta_priv = (void *)info->control.sta->drv_priv; sta_priv = (void *)info->control.sta->drv_priv;
if (sta_priv && sta_priv->asleep && if (sta_priv && sta_priv->asleep &&
(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) { (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) {
/* /*
* This sends an asynchronous command to the device, * This sends an asynchronous command to the device,
* but we can rely on it being processed before the * but we can rely on it being processed before the
@ -331,6 +331,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
* counter. * counter.
* For now set the counter to just 1 since we do not * For now set the counter to just 1 since we do not
* support uAPSD yet. * support uAPSD yet.
*
* FIXME: If we get two non-bufferable frames one
* after the other, we might only send out one of
* them because this is racy.
*/ */
iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
} }
@ -983,7 +987,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
IWL_ERR(priv, "Tx flush command to flush out all frames\n"); IWL_ERR(priv, "Tx flush command to flush out all frames\n");
if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
queue_work(priv->shrd->workqueue, &priv->tx_flush); queue_work(priv->workqueue, &priv->tx_flush);
} }
} }

View File

@ -50,8 +50,8 @@
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-shared.h" #include "iwl-shared.h"
#include "iwl-bus.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-op-mode.h"
/****************************************************************************** /******************************************************************************
* *
@ -618,7 +618,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
.valid = cpu_to_le32(valid_tx_ant), .valid = cpu_to_le32(valid_tx_ant),
}; };
if (IWL_UCODE_API(priv->ucode_ver) > 1) { if (IWL_UCODE_API(nic(priv)->fw.ucode_ver) > 1) {
IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant);
return iwl_trans_send_cmd_pdu(trans(priv), return iwl_trans_send_cmd_pdu(trans(priv),
TX_ANT_CONFIGURATION_CMD, TX_ANT_CONFIGURATION_CMD,
@ -738,14 +738,14 @@ int iwl_alive_start(struct iwl_priv *priv)
return iwl_power_update_mode(priv, true); return iwl_power_update_mode(priv, true);
} }
static void iwl_cancel_deferred_work(struct iwl_priv *priv); void iwl_down(struct iwl_priv *priv)
void __iwl_down(struct iwl_priv *priv)
{ {
int exit_pending; int exit_pending;
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
lockdep_assert_held(&priv->shrd->mutex);
iwl_scan_cancel_timeout(priv, 200); iwl_scan_cancel_timeout(priv, 200);
/* /*
@ -803,15 +803,6 @@ void __iwl_down(struct iwl_priv *priv)
priv->beacon_skb = NULL; priv->beacon_skb = NULL;
} }
void iwl_down(struct iwl_priv *priv)
{
mutex_lock(&priv->shrd->mutex);
__iwl_down(priv);
mutex_unlock(&priv->shrd->mutex);
iwl_cancel_deferred_work(priv);
}
/***************************************************************************** /*****************************************************************************
* *
* Workqueue callbacks * Workqueue callbacks
@ -869,7 +860,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
bt_status = priv->bt_status; bt_status = priv->bt_status;
bt_is_sco = priv->bt_is_sco; bt_is_sco = priv->bt_is_sco;
__iwl_down(priv); iwl_down(priv);
priv->bt_full_concurrent = bt_full_concurrent; priv->bt_full_concurrent = bt_full_concurrent;
priv->bt_ci_compliance = bt_ci_compliance; priv->bt_ci_compliance = bt_ci_compliance;
@ -939,7 +930,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work)
static void iwl_setup_deferred_work(struct iwl_priv *priv) static void iwl_setup_deferred_work(struct iwl_priv *priv)
{ {
priv->shrd->workqueue = create_singlethread_workqueue(DRV_NAME); priv->workqueue = create_singlethread_workqueue(DRV_NAME);
init_waitqueue_head(&priv->shrd->wait_command_queue); init_waitqueue_head(&priv->shrd->wait_command_queue);
@ -970,7 +961,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
priv->watchdog.function = iwl_bg_watchdog; priv->watchdog.function = iwl_bg_watchdog;
} }
static void iwl_cancel_deferred_work(struct iwl_priv *priv) void iwl_cancel_deferred_work(struct iwl_priv *priv)
{ {
if (cfg(priv)->lib->cancel_deferred_work) if (cfg(priv)->lib->cancel_deferred_work)
cfg(priv)->lib->cancel_deferred_work(priv); cfg(priv)->lib->cancel_deferred_work(priv);
@ -1091,7 +1082,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
#define IWL_RX_BUF_SIZE_4K (4 * 1024) #define IWL_RX_BUF_SIZE_4K (4 * 1024)
#define IWL_RX_BUF_SIZE_8K (8 * 1024) #define IWL_RX_BUF_SIZE_8K (8 * 1024)
static int iwl_set_hw_params(struct iwl_priv *priv) static void iwl_set_hw_params(struct iwl_priv *priv)
{ {
if (iwlagn_mod_params.amsdu_size_8K) if (iwlagn_mod_params.amsdu_size_8K)
hw_params(priv).rx_page_order = hw_params(priv).rx_page_order =
@ -1111,7 +1102,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout;
/* Device-specific setup */ /* Device-specific setup */
return cfg(priv)->lib->set_hw_params(priv); cfg(priv)->lib->set_hw_params(priv);
} }
@ -1151,37 +1142,43 @@ static void iwl_debug_config(struct iwl_priv *priv)
#endif #endif
} }
int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
struct iwl_cfg *cfg)
{ {
struct iwl_fw *fw = &nic(trans)->fw;
int err = 0; int err = 0;
struct iwl_priv *priv; struct iwl_priv *priv;
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct iwl_op_mode *op_mode;
u16 num_mac; u16 num_mac;
u32 ucode_flags;
/************************ /************************
* 1. Allocating HW data * 1. Allocating HW data
************************/ ************************/
hw = iwl_alloc_all(); hw = iwl_alloc_all();
if (!hw) { if (!hw) {
pr_err("%s: Cannot allocate network device\n", cfg->name); pr_err("%s: Cannot allocate network device\n",
cfg(trans)->name);
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
} }
priv = hw->priv; op_mode = hw->priv;
priv->shrd = bus->shrd; op_mode->ops = &iwl_dvm_ops;
priv = IWL_OP_MODE_GET_DVM(op_mode);
priv->shrd = trans->shrd;
priv->shrd->priv = priv; priv->shrd->priv = priv;
iwl_trans_configure(trans(priv), op_mode);
/* At this point both hw and priv are allocated. */ /* At this point both hw and priv are allocated. */
SET_IEEE80211_DEV(hw, trans(priv)->dev); SET_IEEE80211_DEV(priv->hw, trans(priv)->dev);
/* show what debugging capabilities we have */ /* show what debugging capabilities we have */
iwl_debug_config(priv); iwl_debug_config(priv);
IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
cfg(priv) = cfg;
/* is antenna coupling more than 35dB ? */ /* is antenna coupling more than 35dB ? */
priv->bt_ant_couple_ok = priv->bt_ant_couple_ok =
@ -1217,7 +1214,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
* 4. Read EEPROM * 4. Read EEPROM
*****************/ *****************/
/* Read the EEPROM */ /* Read the EEPROM */
err = iwl_eeprom_init(priv, trans(priv)->hw_rev); err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev);
/* Reset chip to save power until we load uCode during "up". */ /* Reset chip to save power until we load uCode during "up". */
iwl_trans_stop_hw(trans(priv)); iwl_trans_stop_hw(trans(priv));
if (err) { if (err) {
@ -1248,11 +1245,23 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
/************************ /************************
* 5. Setup HW constants * 5. Setup HW constants
************************/ ************************/
if (iwl_set_hw_params(priv)) { iwl_set_hw_params(priv);
err = -ENOENT;
IWL_ERR(priv, "failed to set hw parameters\n"); ucode_flags = fw->ucode_capa.flags;
goto out_free_eeprom;
} #ifndef CONFIG_IWLWIFI_P2P
ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
#endif
if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE))
ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
/*
* if not PAN, then don't support P2P -- might be a uCode
* packaging bug or due to the eeprom check above
*/
if (!(ucode_flags & IWL_UCODE_TLV_FLAGS_PAN))
ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
/******************* /*******************
* 6. Setup priv * 6. Setup priv
@ -1273,17 +1282,49 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
iwl_power_initialize(priv); iwl_power_initialize(priv);
iwl_tt_initialize(priv); iwl_tt_initialize(priv);
init_completion(&priv->firmware_loading_complete); snprintf(priv->hw->wiphy->fw_version,
sizeof(priv->hw->wiphy->fw_version),
"%s", fw->fw_version);
err = iwl_request_firmware(priv, true); priv->new_scan_threshold_behaviour =
!!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) {
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
} else {
priv->sta_key_max_num = STA_KEY_MAX_NUM;
priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
}
priv->phy_calib_chain_noise_reset_cmd =
fw->ucode_capa.standard_phy_calibration_size;
priv->phy_calib_chain_noise_gain_cmd =
fw->ucode_capa.standard_phy_calibration_size + 1;
/* initialize all valid contexts */
iwl_init_context(priv, ucode_flags);
/**************************************************
* This is still part of probe() in a sense...
*
* 9. Setup and register with mac80211 and debugfs
**************************************************/
err = iwlagn_mac_setup_register(priv, &fw->ucode_capa);
if (err) if (err)
goto out_destroy_workqueue; goto out_destroy_workqueue;
return 0; err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
IWL_ERR(priv,
"failed to create debugfs files. Ignoring error: %d\n",
err);
return op_mode;
out_destroy_workqueue: out_destroy_workqueue:
destroy_workqueue(priv->shrd->workqueue); destroy_workqueue(priv->workqueue);
priv->shrd->workqueue = NULL; priv->workqueue = NULL;
iwl_uninit_drv(priv); iwl_uninit_drv(priv);
out_free_eeprom: out_free_eeprom:
iwl_eeprom_free(priv->shrd); iwl_eeprom_free(priv->shrd);
@ -1291,12 +1332,15 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
iwl_free_traffic_mem(priv); iwl_free_traffic_mem(priv);
ieee80211_free_hw(priv->hw); ieee80211_free_hw(priv->hw);
out: out:
return err; op_mode = NULL;
return op_mode;
} }
void __devexit iwl_remove(struct iwl_priv * priv) static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
{ {
wait_for_completion(&priv->firmware_loading_complete); struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
wait_for_completion(&nic(priv)->request_firmware_complete);
IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
@ -1316,18 +1360,18 @@ void __devexit iwl_remove(struct iwl_priv * priv)
/*This will stop the queues, move the device to low power state */ /*This will stop the queues, move the device to low power state */
iwl_trans_stop_device(trans(priv)); iwl_trans_stop_device(trans(priv));
iwl_dealloc_ucode(trans(priv)); iwl_dealloc_ucode(nic(priv));
iwl_eeprom_free(priv->shrd); iwl_eeprom_free(priv->shrd);
/*netif_stop_queue(dev); */ /*netif_stop_queue(dev); */
flush_workqueue(priv->shrd->workqueue); flush_workqueue(priv->workqueue);
/* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes /* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes
* priv->shrd->workqueue... so we can't take down the workqueue * priv->workqueue... so we can't take down the workqueue
* until now... */ * until now... */
destroy_workqueue(priv->shrd->workqueue); destroy_workqueue(priv->workqueue);
priv->shrd->workqueue = NULL; priv->workqueue = NULL;
iwl_free_traffic_mem(priv); iwl_free_traffic_mem(priv);
iwl_uninit_drv(priv); iwl_uninit_drv(priv);
@ -1337,6 +1381,16 @@ void __devexit iwl_remove(struct iwl_priv * priv)
ieee80211_free_hw(priv->hw); ieee80211_free_hw(priv->hw);
} }
const struct iwl_op_mode_ops iwl_dvm_ops = {
.start = iwl_op_mode_dvm_start,
.stop = iwl_op_mode_dvm_stop,
.rx = iwl_rx_dispatch,
.queue_full = iwl_stop_sw_queue,
.queue_not_full = iwl_wake_sw_queue,
.hw_rf_kill = iwl_set_hw_rfkill_state,
.free_skb = iwl_free_skb,
.nic_error = iwl_nic_error,
};
/***************************************************************************** /*****************************************************************************
* *

View File

@ -65,11 +65,7 @@
#include "iwl-dev.h" #include "iwl-dev.h"
struct iwlagn_ucode_capabilities { struct iwl_ucode_capabilities;
u32 max_probe_length;
u32 standard_phy_calibration_size;
u32 flags;
};
extern struct ieee80211_ops iwlagn_hw_ops; extern struct ieee80211_ops iwlagn_hw_ops;
@ -81,14 +77,23 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
hdr->data_valid = 1; hdr->data_valid = 1;
} }
void __iwl_down(struct iwl_priv *priv);
void iwl_down(struct iwl_priv *priv); void iwl_down(struct iwl_priv *priv);
void iwl_cancel_deferred_work(struct iwl_priv *priv);
void iwlagn_prepare_restart(struct iwl_priv *priv); void iwlagn_prepare_restart(struct iwl_priv *priv);
void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb);
int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode,
struct iwl_rx_mem_buffer *rxb,
struct iwl_device_cmd *cmd);
void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state);
void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac);
void iwl_nic_error(struct iwl_op_mode *op_mode);
/* MAC80211 */ /* MAC80211 */
struct ieee80211_hw *iwl_alloc_all(void); struct ieee80211_hw *iwl_alloc_all(void);
int iwlagn_mac_setup_register(struct iwl_priv *priv, int iwlagn_mac_setup_register(struct iwl_priv *priv,
struct iwlagn_ucode_capabilities *capa); struct iwl_ucode_capabilities *capa);
void iwlagn_mac_unregister(struct iwl_priv *priv); void iwlagn_mac_unregister(struct iwl_priv *priv);
/* RXON */ /* RXON */
@ -387,4 +392,14 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
} }
#endif #endif
#ifdef CONFIG_IWLWIFI_DEBUG
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,
enum iwl_rxon_context_id ctxid)
{
}
#endif
#endif /* __iwl_agn_h__ */ #endif /* __iwl_agn_h__ */

View File

@ -1,145 +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) 2007 - 2012 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 <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2012 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.
*
*****************************************************************************/
#ifndef __iwl_bus_h__
#define __iwl_bus_h__
#include <linux/types.h>
#include <linux/spinlock.h>
/**
* 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 - bus common data
*
* This data is common to all bus layer implementations.
*
* @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
*/
struct iwl_bus {
struct iwl_shared *shrd;
/* pointer to bus specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
char bus_specific[0] __attribute__((__aligned__(sizeof(void *))));
};
/*****************************************************
* Bus layer registration functions
******************************************************/
int __must_check iwl_pci_register_driver(void);
void iwl_pci_unregister_driver(void);
#endif /* __iwl_bus_h__ */

View File

@ -80,6 +80,8 @@ extern struct iwl_cfg iwl6005_2abg_cfg;
extern struct iwl_cfg iwl6005_2bg_cfg; extern struct iwl_cfg iwl6005_2bg_cfg;
extern struct iwl_cfg iwl6005_2agn_sff_cfg; extern struct iwl_cfg iwl6005_2agn_sff_cfg;
extern struct iwl_cfg iwl6005_2agn_d_cfg; extern struct iwl_cfg iwl6005_2agn_d_cfg;
extern struct iwl_cfg iwl6005_2agn_mow1_cfg;
extern struct iwl_cfg iwl6005_2agn_mow2_cfg;
extern struct iwl_cfg iwl1030_bgn_cfg; extern struct iwl_cfg iwl1030_bgn_cfg;
extern struct iwl_cfg iwl1030_bg_cfg; extern struct iwl_cfg iwl1030_bg_cfg;
extern struct iwl_cfg iwl6030_2agn_cfg; extern struct iwl_cfg iwl6030_2agn_cfg;

View File

@ -38,10 +38,10 @@
#include "iwl-core.h" #include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-power.h" #include "iwl-power.h"
#include "iwl-agn.h"
#include "iwl-shared.h" #include "iwl-shared.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-wifi.h"
const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@ -643,7 +643,7 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv,
* NOTE: Does not commit to the hardware; it sets appropriate bit fields * NOTE: Does not commit to the hardware; it sets appropriate bit fields
* in the staging RXON flag structure based on the ch->band * in the staging RXON flag structure based on the ch->band
*/ */
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
struct iwl_rxon_context *ctx) struct iwl_rxon_context *ctx)
{ {
enum ieee80211_band band = ch->band; enum ieee80211_band band = ch->band;
@ -651,7 +651,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
if ((le16_to_cpu(ctx->staging.channel) == channel) && if ((le16_to_cpu(ctx->staging.channel) == channel) &&
(priv->band == band)) (priv->band == band))
return 0; return;
ctx->staging.channel = cpu_to_le16(channel); ctx->staging.channel = cpu_to_le16(channel);
if (band == IEEE80211_BAND_5GHZ) if (band == IEEE80211_BAND_5GHZ)
@ -663,7 +663,6 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band); IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
return 0;
} }
void iwl_set_flags_for_band(struct iwl_priv *priv, void iwl_set_flags_for_band(struct iwl_priv *priv,
@ -831,11 +830,16 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
} }
#endif #endif
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
{ {
unsigned int reload_msec; unsigned int reload_msec;
unsigned long reload_jiffies; unsigned long reload_jiffies;
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_get_debug_level(priv->shrd) & IWL_DL_FW_ERRORS)
iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
#endif
/* Set the FW error flag -- cleared on iwl_down */ /* Set the FW error flag -- cleared on iwl_down */
set_bit(STATUS_FW_ERROR, &priv->shrd->status); set_bit(STATUS_FW_ERROR, &priv->shrd->status);
@ -875,7 +879,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
if (iwlagn_mod_params.restart_fw) { if (iwlagn_mod_params.restart_fw) {
IWL_DEBUG_FW_ERRORS(priv, IWL_DEBUG_FW_ERRORS(priv,
"Restarting adapter due to uCode error.\n"); "Restarting adapter due to uCode error.\n");
queue_work(priv->shrd->workqueue, &priv->restart); queue_work(priv->workqueue, &priv->restart);
} else } else
IWL_DEBUG_FW_ERRORS(priv, IWL_DEBUG_FW_ERRORS(priv,
"Detected FW error, but not restarting\n"); "Detected FW error, but not restarting\n");
@ -1456,8 +1460,17 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
return cpu_to_le32(res); return cpu_to_le32(res);
} }
void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state) void iwl_nic_error(struct iwl_op_mode *op_mode)
{ {
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
iwlagn_fw_error(priv, false);
}
void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
{
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
} }
@ -1466,8 +1479,9 @@ void iwl_nic_config(struct iwl_priv *priv)
cfg(priv)->lib->nic_config(priv); cfg(priv)->lib->nic_config(priv);
} }
void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb) void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
{ {
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
info = IEEE80211_SKB_CB(skb); info = IEEE80211_SKB_CB(skb);
@ -1475,12 +1489,16 @@ void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb)
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac) void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
{ {
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
ieee80211_stop_queue(priv->hw, ac); ieee80211_stop_queue(priv->hw, ac);
} }
void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac) void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac)
{ {
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
ieee80211_wake_queue(priv->hw, ac); ieee80211_wake_queue(priv->hw, ac);
} }

View File

@ -76,7 +76,7 @@ struct iwl_cmd;
struct iwl_lib_ops { struct iwl_lib_ops {
/* set hw dependent parameters */ /* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv); void (*set_hw_params)(struct iwl_priv *priv);
/* setup BT Rx handler */ /* setup BT Rx handler */
void (*bt_rx_handler_setup)(struct iwl_priv *priv); void (*bt_rx_handler_setup)(struct iwl_priv *priv);
/* setup BT related deferred work */ /* setup BT related deferred work */
@ -169,7 +169,7 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
int hw_decrypt); int hw_decrypt);
int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
struct iwl_rxon_context *ctx); struct iwl_rxon_context *ctx);
void iwl_set_flags_for_band(struct iwl_priv *priv, void iwl_set_flags_for_band(struct iwl_priv *priv,
struct iwl_rxon_context *ctx, struct iwl_rxon_context *ctx,
@ -197,6 +197,8 @@ const char *get_ctrl_string(int cmd);
void iwl_clear_traffic_stats(struct iwl_priv *priv); void iwl_clear_traffic_stats(struct iwl_priv *priv);
void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc,
u16 len); u16 len);
void iwl_reset_traffic_log(struct iwl_priv *priv);
#else #else
static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv) static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv)
{ {

View File

@ -0,0 +1,127 @@
/******************************************************************************
*
* 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 <ilw@linux.intel.com>
* 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 <linux/interrupt.h>
#include "iwl-debug.h"
#define __iwl_fn(fn) \
void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \
{ \
struct va_format vaf = { \
.fmt = fmt, \
}; \
va_list args; \
\
va_start(args, fmt); \
vaf.va = &args; \
dev_ ##fn(dev, "%pV", &vaf); \
trace_iwlwifi_ ##fn(&vaf); \
va_end(args); \
}
__iwl_fn(warn)
__iwl_fn(info)
__iwl_fn(crit)
void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
const char *fmt, ...)
{
struct va_format vaf = {
.fmt = fmt,
};
va_list args;
va_start(args, fmt);
vaf.va = &args;
if (!trace_only) {
if (rfkill_prefix)
dev_err(dev, "(RFKILL) %pV", &vaf);
else
dev_err(dev, "%pV", &vaf);
}
trace_iwlwifi_err(&vaf);
va_end(args);
}
#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
void __iwl_dbg(struct iwl_shared *shared, struct device *dev,
u32 level, bool limit, const char *function,
const char *fmt, ...)
{
struct va_format vaf = {
.fmt = fmt,
};
va_list args;
va_start(args, fmt);
vaf.va = &args;
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_get_debug_level(shared) & level &&
(!limit || net_ratelimit()))
dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U',
function, &vaf);
#endif
trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);
va_end(args);
}
#endif

View File

@ -29,16 +29,34 @@
#ifndef __iwl_debug_h__ #ifndef __iwl_debug_h__
#define __iwl_debug_h__ #define __iwl_debug_h__
#include "iwl-bus.h"
#include "iwl-shared.h" #include "iwl-shared.h"
#include "iwl-devtrace.h"
struct iwl_priv; struct iwl_priv;
/*No matter what is m (priv, bus, trans), this will work */ void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
#define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a) const char *fmt, ...);
#define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a) void __iwl_warn(struct device *dev, const char *fmt, ...);
#define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a) void __iwl_info(struct device *dev, const char *fmt, ...);
#define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a) void __iwl_crit(struct device *dev, const char *fmt, ...);
/* No matter what is m (priv, bus, trans), this will work */
#define IWL_ERR(m, f, a...) __iwl_err(trans(m)->dev, false, false, f, ## a)
#define IWL_WARN(m, f, a...) __iwl_warn(trans(m)->dev, f, ## a)
#define IWL_INFO(m, f, a...) __iwl_info(trans(m)->dev, f, ## a)
#define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a)
#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
void __iwl_dbg(struct iwl_shared *shared, struct device *dev,
u32 level, bool limit, const char *function,
const char *fmt, ...);
#else
static inline void
__iwl_dbg(struct iwl_shared *shared, struct device *dev,
u32 level, bool limit, const char *function,
const char *fmt, ...)
{}
#endif
#define iwl_print_hex_error(m, p, len) \ #define iwl_print_hex_error(m, p, len) \
do { \ do { \
@ -46,53 +64,35 @@ do { \
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
} while (0) } while (0)
#define IWL_DEBUG(m, level, fmt, args...) \
__iwl_dbg((m)->shrd, trans(m)->dev, level, false, __func__, fmt, ##args)
#define IWL_DEBUG_LIMIT(m, level, fmt, args...) \
__iwl_dbg((m)->shrd, trans(m)->dev, level, true, __func__, fmt, ##args)
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
#define IWL_DEBUG(m, level, fmt, ...) \
do { \
if (iwl_get_debug_level((m)->shrd) & (level)) \
dev_err(trans(m)->dev, "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
} while (0)
#define IWL_DEBUG_LIMIT(m, level, fmt, ...) \
do { \
if (iwl_get_debug_level((m)->shrd) & (level) && \
net_ratelimit()) \
dev_err(trans(m)->dev, "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
} while (0)
#define iwl_print_hex_dump(m, level, p, len) \ #define iwl_print_hex_dump(m, level, p, len) \
do { \ do { \
if (iwl_get_debug_level((m)->shrd) & level) \ if (iwl_get_debug_level((m)->shrd) & level) \
print_hex_dump(KERN_DEBUG, "iwl data: ", \ print_hex_dump(KERN_DEBUG, "iwl data: ", \
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
} while (0) } while (0)
#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \
#define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \
do { \ do { \
if (!iwl_is_rfkill(p->shrd)) \ if (!iwl_is_rfkill((m)->shrd)) \
dev_err(trans(p)->dev, "%s%c %s " fmt, \ IWL_ERR(m, fmt, ##args); \
"", \ else \
in_interrupt() ? 'I' : 'U', __func__, \ __iwl_err(trans(m)->dev, true, \
##__VA_ARGS__); \ !(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\
else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ fmt, ##args); \
dev_err(trans(p)->dev, "%s%c %s " fmt, \
"(RFKILL) ", \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
} while (0) } while (0)
#else #else
#define IWL_DEBUG(m, level, fmt, args...)
#define IWL_DEBUG_LIMIT(m, level, fmt, args...)
#define iwl_print_hex_dump(m, level, p, len) #define iwl_print_hex_dump(m, level, p, len)
#define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...) \ #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \
do { \ do { \
if (!iwl_is_rfkill(p->shrd)) \ if (!iwl_is_rfkill((m)->shrd)) \
IWL_ERR(p, fmt, ##args); \ IWL_ERR(m, fmt, ##args); \
else \
__iwl_err(trans(m)->dev, true, true, fmt, ##args); \
} while (0) } while (0)
#endif /* CONFIG_IWLWIFI_DEBUG */ #endif /* CONFIG_IWLWIFI_DEBUG */

View File

@ -40,6 +40,7 @@
#include "iwl-core.h" #include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-wifi.h"
/* create and remove of files */ /* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
@ -234,12 +235,12 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
/* default is to dump the entire data segment */ /* default is to dump the entire data segment */
if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
struct iwl_trans *trans = trans(priv); struct iwl_nic *nic = nic(priv);
priv->dbgfs_sram_offset = 0x800000; priv->dbgfs_sram_offset = 0x800000;
if (trans->shrd->ucode_type == IWL_UCODE_INIT) if (nic->shrd->ucode_type == IWL_UCODE_INIT)
priv->dbgfs_sram_len = trans->ucode_init.data.len; priv->dbgfs_sram_len = nic->fw.ucode_init.data.len;
else else
priv->dbgfs_sram_len = trans->ucode_rt.data.len; priv->dbgfs_sram_len = nic->fw.ucode_rt.data.len;
} }
len = priv->dbgfs_sram_len; len = priv->dbgfs_sram_len;
@ -342,7 +343,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, return simple_read_from_buffer(user_buf, count, ppos,
priv->wowlan_sram, priv->wowlan_sram,
trans(priv)->ucode_wowlan.data.len); nic(priv)->fw.ucode_wowlan.data.len);
} }
static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)

View File

@ -47,9 +47,9 @@
#include "iwl-power.h" #include "iwl-power.h"
#include "iwl-agn-rs.h" #include "iwl-agn-rs.h"
#include "iwl-agn-tt.h" #include "iwl-agn-tt.h"
#include "iwl-bus.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-shared.h" #include "iwl-shared.h"
#include "iwl-op-mode.h"
struct iwl_tx_queue; struct iwl_tx_queue;
@ -442,9 +442,6 @@ struct iwl_chain_noise_data {
u8 state; u8 state;
}; };
#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
enum { enum {
MEASUREMENT_READY = (1 << 0), MEASUREMENT_READY = (1 << 0),
MEASUREMENT_ACTIVE = (1 << 1), MEASUREMENT_ACTIVE = (1 << 1),
@ -696,11 +693,11 @@ struct iwl_testmode_trace {
dma_addr_t dma_addr; dma_addr_t dma_addr;
bool trace_enabled; bool trace_enabled;
}; };
struct iwl_testmode_sram { struct iwl_testmode_mem {
u32 buff_size; u32 buff_size;
u32 num_chunks; u32 num_chunks;
u8 *buff_addr; u8 *buff_addr;
bool sram_readed; bool read_in_progress;
}; };
#endif #endif
@ -710,6 +707,13 @@ struct iwl_wipan_noa_data {
u8 data[]; u8 data[];
}; };
#define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \
((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific))
#define IWL_MAC80211_GET_DVM(_hw) \
((struct iwl_priv *) ((struct iwl_op_mode *) \
(_hw)->priv)->op_mode_specific)
struct iwl_priv { struct iwl_priv {
/*data shared among all the driver's layers */ /*data shared among all the driver's layers */
@ -721,6 +725,8 @@ struct iwl_priv {
struct ieee80211_rate *ieee_rates; struct ieee80211_rate *ieee_rates;
struct kmem_cache *tx_cmd_pool; struct kmem_cache *tx_cmd_pool;
struct workqueue_struct *workqueue;
enum ieee80211_band band; enum ieee80211_band band;
void (*pre_rx_handler)(struct iwl_priv *priv, void (*pre_rx_handler)(struct iwl_priv *priv,
@ -785,13 +791,6 @@ struct iwl_priv {
/* EEPROM MAC addresses */ /* EEPROM MAC addresses */
struct mac_address addresses[2]; struct mac_address addresses[2];
/* uCode images, save to reload in case of failure */
int fw_index; /* firmware we're trying to load */
u32 ucode_ver; /* version of ucode, copy of
iwl_ucode.ver */
char firmware_name[25];
struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
__le16 switch_channel; __le16 switch_channel;
@ -801,7 +800,6 @@ struct iwl_priv {
u8 start_calib; u8 start_calib;
struct iwl_sensitivity_data sensitivity_data; struct iwl_sensitivity_data sensitivity_data;
struct iwl_chain_noise_data chain_noise_data; struct iwl_chain_noise_data chain_noise_data;
bool enhance_sensitivity_table;
__le16 sensitivity_tbl[HD_TABLE_SIZE]; __le16 sensitivity_tbl[HD_TABLE_SIZE];
__le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES]; __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES];
@ -869,11 +867,6 @@ struct iwl_priv {
struct iwl_rx_phy_res last_phy_res; struct iwl_rx_phy_res last_phy_res;
bool last_phy_res_valid; bool last_phy_res_valid;
struct completion firmware_loading_complete;
u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
/* /*
* chain noise reset and gain commands are the * chain noise reset and gain commands are the
* two extra calibration commands follows the standard * two extra calibration commands follows the standard
@ -964,7 +957,7 @@ struct iwl_priv {
bool led_registered; bool led_registered;
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
struct iwl_testmode_trace testmode_trace; struct iwl_testmode_trace testmode_trace;
struct iwl_testmode_sram testmode_sram; struct iwl_testmode_mem testmode_mem;
u32 tm_fixed_rate; u32 tm_fixed_rate;
#endif #endif

View File

@ -34,6 +34,11 @@
#undef TRACE_EVENT #undef TRACE_EVENT
#define TRACE_EVENT(name, proto, ...) \ #define TRACE_EVENT(name, proto, ...) \
static inline void trace_ ## name(proto) {} static inline void trace_ ## name(proto) {}
#undef DECLARE_EVENT_CLASS
#define DECLARE_EVENT_CLASS(...)
#undef DEFINE_EVENT
#define DEFINE_EVENT(evt_class, name, proto, ...) \
static inline void trace_ ## name(proto) {}
#endif #endif
#define PRIV_ENTRY __field(void *, priv) #define PRIV_ENTRY __field(void *, priv)
@ -163,6 +168,66 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
__entry->p_entry) __entry->p_entry)
); );
#undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi_msg
#define MAX_MSG_LEN 100
DECLARE_EVENT_CLASS(iwlwifi_msg_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
__dynamic_array(char, msg, MAX_MSG_LEN)
),
TP_fast_assign(
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
MAX_MSG_LEN, vaf->fmt,
*vaf->va) >= MAX_MSG_LEN);
),
TP_printk("%s", (char *)__get_dynamic_array(msg))
);
DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf)
);
DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf)
);
DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf)
);
DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf)
);
TRACE_EVENT(iwlwifi_dbg,
TP_PROTO(u32 level, bool in_interrupt, const char *function,
struct va_format *vaf),
TP_ARGS(level, in_interrupt, function, vaf),
TP_STRUCT__entry(
__field(u32, level)
__field(u8, in_interrupt)
__string(function, function)
__dynamic_array(char, msg, MAX_MSG_LEN)
),
TP_fast_assign(
__entry->level = level;
__entry->in_interrupt = in_interrupt;
__assign_str(function, function);
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
MAX_MSG_LEN, vaf->fmt,
*vaf->va) >= MAX_MSG_LEN);
),
TP_printk("%s", (char *)__get_dynamic_array(msg))
);
#undef TRACE_SYSTEM #undef TRACE_SYSTEM
#define TRACE_SYSTEM iwlwifi #define TRACE_SYSTEM iwlwifi

View File

@ -0,0 +1,103 @@
/******************************************************************************
*
* 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 - 2012 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 <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2012 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 <linux/completion.h>
#include "iwl-drv.h"
#include "iwl-trans.h"
#include "iwl-wifi.h"
#include "iwl-op-mode.h"
int iwl_drv_start(struct iwl_shared *shrd,
struct iwl_trans *trans, struct iwl_cfg *cfg)
{
int ret;
shrd->cfg = cfg;
shrd->nic = kzalloc(sizeof(*shrd->nic), GFP_KERNEL);
if (!shrd->nic) {
dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_nic");
return -ENOMEM;
}
shrd->nic->shrd = shrd;
init_completion(&shrd->nic->request_firmware_complete);
ret = iwl_request_firmware(shrd->nic, true);
if (ret) {
dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw");
kfree(shrd->nic);
}
return ret;
}
void iwl_drv_stop(struct iwl_shared *shrd)
{
/* op_mode can be NULL if its start failed */
if (shrd->nic->op_mode)
iwl_op_mode_stop(shrd->nic->op_mode);
kfree(shrd->nic);
}

View File

@ -0,0 +1,123 @@
/******************************************************************************
*
* 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 - 2012 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 <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2012 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.
*****************************************************************************/
#ifndef __iwl_drv_h__
#define __iwl_drv_h__
#include "iwl-shared.h"
/**
* DOC: Driver system flows - drv component
*
* This component implements the system flows such as bus enumeration, bus
* removal. Bus dependent parts of system flows (such as iwl_pci_probe) are in
* bus specific files (transport files). This is the code that is common among
* different buses.
*
* This component is also in charge of managing the several implementations of
* the wifi flows: it will allow to have several fw API implementation. These
* different implementations will differ in the way they implement mac80211's
* handlers too.
* The init flow wrt to the drv component looks like this:
* 1) The bus specific component is called from module_init
* 2) The bus specific component registers the bus driver
* 3) The bus driver calls the probe function
* 4) The bus specific component configures the bus
* 5) The bus specific component calls to the drv bus agnostic part
* (iwl_drv_start)
* 6) iwl_drv_start fetches the fw ASYNC, iwl_ucode_callback
* 7) iwl_ucode_callback parses the fw file
* 8) iwl_ucode_callback starts the wifi implementation to matches the fw
*/
/**
* iwl_drv_start - start the drv
*
* @shrd: the shrd area
* @trans_ops: the ops of the transport
* @cfg: device specific constants / virtual functions
*
* TODO: review the parameters given to this function
*
* starts the driver: fetches the firmware. This should be called by bus
* specific system flows implementations. For example, the bus specific probe
* function should do bus related operations only, and then call to this
* function.
*/
int iwl_drv_start(struct iwl_shared *shrd,
struct iwl_trans *trans, struct iwl_cfg *cfg);
/**
* iwl_drv_stop - stop the drv
*
* @shrd: the shrd area
*
* TODO: review the parameters given to this function
*
* Stop the driver. This should be called by bus specific system flows
* implementations. For example, the bus specific remove function should first
* call this function and then do the bus related operations only.
*/
void iwl_drv_stop(struct iwl_shared *shrd);
#endif /* __iwl_drv_h__ */

View File

@ -149,23 +149,27 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */
* EEPROM chip, not a single event, so even reads could conflict if they * EEPROM chip, not a single event, so even reads could conflict if they
* weren't arbitrated by the semaphore. * weren't arbitrated by the semaphore.
*/ */
static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus)
#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans)
{ {
u16 count; u16 count;
int ret; int ret;
for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
/* Request semaphore */ /* Request semaphore */
iwl_set_bit(trans(bus), CSR_HW_IF_CONFIG_REG, iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
/* See if we got it */ /* See if we got it */
ret = iwl_poll_bit(trans(bus), CSR_HW_IF_CONFIG_REG, ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
EEPROM_SEM_TIMEOUT); EEPROM_SEM_TIMEOUT);
if (ret >= 0) { if (ret >= 0) {
IWL_DEBUG_EEPROM(trans(bus), IWL_DEBUG_EEPROM(trans,
"Acquired semaphore after %d tries.\n", "Acquired semaphore after %d tries.\n",
count+1); count+1);
return ret; return ret;
@ -175,9 +179,9 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus)
return ret; return ret;
} }
static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) static void iwl_eeprom_release_semaphore(struct iwl_trans *trans)
{ {
iwl_clear_bit(trans(bus), CSR_HW_IF_CONFIG_REG, iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
} }
@ -304,19 +308,20 @@ void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac)
* *
******************************************************************************/ ******************************************************************************/
static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) static void iwl_set_otp_access(struct iwl_trans *trans,
enum iwl_access_mode mode)
{ {
iwl_read32(trans(bus), CSR_OTP_GP_REG); iwl_read32(trans, CSR_OTP_GP_REG);
if (mode == IWL_OTP_ACCESS_ABSOLUTE) if (mode == IWL_OTP_ACCESS_ABSOLUTE)
iwl_clear_bit(trans(bus), CSR_OTP_GP_REG, iwl_clear_bit(trans, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_OTP_ACCESS_MODE); CSR_OTP_GP_REG_OTP_ACCESS_MODE);
else else
iwl_set_bit(trans(bus), CSR_OTP_GP_REG, iwl_set_bit(trans, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_OTP_ACCESS_MODE); CSR_OTP_GP_REG_OTP_ACCESS_MODE);
} }
static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) static int iwl_get_nvm_type(struct iwl_trans *trans, u32 hw_rev)
{ {
u32 otpgp; u32 otpgp;
int nvm_type; int nvm_type;
@ -324,7 +329,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
/* OTP only valid for CP/PP and after */ /* OTP only valid for CP/PP and after */
switch (hw_rev & CSR_HW_REV_TYPE_MSK) { switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_NONE: case CSR_HW_REV_TYPE_NONE:
IWL_ERR(bus, "Unknown hardware type\n"); IWL_ERR(trans, "Unknown hardware type\n");
return -ENOENT; return -ENOENT;
case CSR_HW_REV_TYPE_5300: case CSR_HW_REV_TYPE_5300:
case CSR_HW_REV_TYPE_5350: case CSR_HW_REV_TYPE_5350:
@ -333,7 +338,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
nvm_type = NVM_DEVICE_TYPE_EEPROM; nvm_type = NVM_DEVICE_TYPE_EEPROM;
break; break;
default: default:
otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); otpgp = iwl_read32(trans, CSR_OTP_GP_REG);
if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT)
nvm_type = NVM_DEVICE_TYPE_OTP; nvm_type = NVM_DEVICE_TYPE_OTP;
else else
@ -343,73 +348,74 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
return nvm_type; return nvm_type;
} }
static int iwl_init_otp_access(struct iwl_bus *bus) static int iwl_init_otp_access(struct iwl_trans *trans)
{ {
int ret; int ret;
/* Enable 40MHz radio clock */ /* Enable 40MHz radio clock */
iwl_write32(trans(bus), CSR_GP_CNTRL, iwl_write32(trans, CSR_GP_CNTRL,
iwl_read32(trans(bus), CSR_GP_CNTRL) | iwl_read32(trans, CSR_GP_CNTRL) |
CSR_GP_CNTRL_REG_FLAG_INIT_DONE); CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* wait for clock to be ready */ /* wait for clock to be ready */
ret = iwl_poll_bit(trans(bus), CSR_GP_CNTRL, ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
25000); 25000);
if (ret < 0) if (ret < 0)
IWL_ERR(bus, "Time out access OTP\n"); IWL_ERR(trans, "Time out access OTP\n");
else { else {
iwl_set_bits_prph(trans(bus), APMG_PS_CTRL_REG, iwl_set_bits_prph(trans, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ); APMG_PS_CTRL_VAL_RESET_REQ);
udelay(5); udelay(5);
iwl_clear_bits_prph(trans(bus), APMG_PS_CTRL_REG, iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ); APMG_PS_CTRL_VAL_RESET_REQ);
/* /*
* CSR auto clock gate disable bit - * CSR auto clock gate disable bit -
* this is only applicable for HW with OTP shadow RAM * this is only applicable for HW with OTP shadow RAM
*/ */
if (cfg(bus)->base_params->shadow_ram_support) if (cfg(trans)->base_params->shadow_ram_support)
iwl_set_bit(trans(bus), CSR_DBG_LINK_PWR_MGMT_REG, iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
CSR_RESET_LINK_PWR_MGMT_DISABLED); CSR_RESET_LINK_PWR_MGMT_DISABLED);
} }
return ret; return ret;
} }
static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr,
__le16 *eeprom_data)
{ {
int ret = 0; int ret = 0;
u32 r; u32 r;
u32 otpgp; u32 otpgp;
iwl_write32(trans(bus), CSR_EEPROM_REG, iwl_write32(trans, CSR_EEPROM_REG,
CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
ret = iwl_poll_bit(trans(bus), CSR_EEPROM_REG, ret = iwl_poll_bit(trans, CSR_EEPROM_REG,
CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK,
CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK,
IWL_EEPROM_ACCESS_TIMEOUT); IWL_EEPROM_ACCESS_TIMEOUT);
if (ret < 0) { if (ret < 0) {
IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); IWL_ERR(trans, "Time out reading OTP[%d]\n", addr);
return ret; return ret;
} }
r = iwl_read32(trans(bus), CSR_EEPROM_REG); r = iwl_read32(trans, CSR_EEPROM_REG);
/* check for ECC errors: */ /* check for ECC errors: */
otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); otpgp = iwl_read32(trans, CSR_OTP_GP_REG);
if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
/* stop in this case */ /* stop in this case */
/* set the uncorrectable OTP ECC bit for acknowledgement */ /* set the uncorrectable OTP ECC bit for acknowledgement */
iwl_set_bit(trans(bus), CSR_OTP_GP_REG, iwl_set_bit(trans, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n");
return -EINVAL; return -EINVAL;
} }
if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
/* continue in this case */ /* continue in this case */
/* set the correctable OTP ECC bit for acknowledgement */ /* set the correctable OTP ECC bit for acknowledgement */
iwl_set_bit(trans(bus), CSR_OTP_GP_REG, iwl_set_bit(trans, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); IWL_ERR(trans, "Correctable OTP ECC error, continue read\n");
} }
*eeprom_data = cpu_to_le16(r >> 16); *eeprom_data = cpu_to_le16(r >> 16);
return 0; return 0;
@ -418,20 +424,20 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data)
/* /*
* iwl_is_otp_empty: check for empty OTP * iwl_is_otp_empty: check for empty OTP
*/ */
static bool iwl_is_otp_empty(struct iwl_bus *bus) static bool iwl_is_otp_empty(struct iwl_trans *trans)
{ {
u16 next_link_addr = 0; u16 next_link_addr = 0;
__le16 link_value; __le16 link_value;
bool is_empty = false; bool is_empty = false;
/* locate the beginning of OTP link list */ /* locate the beginning of OTP link list */
if (!iwl_read_otp_word(bus, next_link_addr, &link_value)) { if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) {
if (!link_value) { if (!link_value) {
IWL_ERR(bus, "OTP is empty\n"); IWL_ERR(trans, "OTP is empty\n");
is_empty = true; is_empty = true;
} }
} else { } else {
IWL_ERR(bus, "Unable to read first block of OTP list.\n"); IWL_ERR(trans, "Unable to read first block of OTP list.\n");
is_empty = true; is_empty = true;
} }
@ -448,7 +454,7 @@ static bool iwl_is_otp_empty(struct iwl_bus *bus)
* we should read and used to configure the device. * we should read and used to configure the device.
* only perform this operation if shadow RAM is disabled * only perform this operation if shadow RAM is disabled
*/ */
static int iwl_find_otp_image(struct iwl_bus *bus, static int iwl_find_otp_image(struct iwl_trans *trans,
u16 *validblockaddr) u16 *validblockaddr)
{ {
u16 next_link_addr = 0, valid_addr; u16 next_link_addr = 0, valid_addr;
@ -456,10 +462,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
int usedblocks = 0; int usedblocks = 0;
/* set addressing mode to absolute to traverse the link list */ /* set addressing mode to absolute to traverse the link list */
iwl_set_otp_access(bus, IWL_OTP_ACCESS_ABSOLUTE); iwl_set_otp_access(trans, IWL_OTP_ACCESS_ABSOLUTE);
/* checking for empty OTP or error */ /* checking for empty OTP or error */
if (iwl_is_otp_empty(bus)) if (iwl_is_otp_empty(trans))
return -EINVAL; return -EINVAL;
/* /*
@ -473,9 +479,9 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
*/ */
valid_addr = next_link_addr; valid_addr = next_link_addr;
next_link_addr = le16_to_cpu(link_value) * sizeof(u16); next_link_addr = le16_to_cpu(link_value) * sizeof(u16);
IWL_DEBUG_EEPROM(bus, "OTP blocks %d addr 0x%x\n", IWL_DEBUG_EEPROM(trans, "OTP blocks %d addr 0x%x\n",
usedblocks, next_link_addr); usedblocks, next_link_addr);
if (iwl_read_otp_word(bus, next_link_addr, &link_value)) if (iwl_read_otp_word(trans, next_link_addr, &link_value))
return -EINVAL; return -EINVAL;
if (!link_value) { if (!link_value) {
/* /*
@ -490,10 +496,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
} }
/* more in the link list, continue */ /* more in the link list, continue */
usedblocks++; usedblocks++;
} while (usedblocks <= cfg(bus)->base_params->max_ll_items); } while (usedblocks <= cfg(trans)->base_params->max_ll_items);
/* OTP has no valid blocks */ /* OTP has no valid blocks */
IWL_DEBUG_EEPROM(bus, "OTP has no valid blocks\n"); IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n");
return -EINVAL; return -EINVAL;
} }
@ -653,63 +659,62 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
* *
* NOTE: This routine uses the non-debug IO access functions. * NOTE: This routine uses the non-debug IO access functions.
*/ */
int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev)
{ {
struct iwl_shared *shrd = priv->shrd;
__le16 *e; __le16 *e;
u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP); u32 gp = iwl_read32(trans, CSR_EEPROM_GP);
int sz; int sz;
int ret; int ret;
u16 addr; u16 addr;
u16 validblockaddr = 0; u16 validblockaddr = 0;
u16 cache_addr = 0; u16 cache_addr = 0;
trans(priv)->nvm_device_type = iwl_get_nvm_type(bus(priv), hw_rev); trans->nvm_device_type = iwl_get_nvm_type(trans, hw_rev);
if (trans(priv)->nvm_device_type == -ENOENT) if (trans->nvm_device_type == -ENOENT)
return -ENOENT; return -ENOENT;
/* allocate eeprom */ /* allocate eeprom */
sz = cfg(priv)->base_params->eeprom_size; sz = cfg(trans)->base_params->eeprom_size;
IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); IWL_DEBUG_EEPROM(trans, "NVM size = %d\n", sz);
shrd->eeprom = kzalloc(sz, GFP_KERNEL); trans->shrd->eeprom = kzalloc(sz, GFP_KERNEL);
if (!shrd->eeprom) { if (!trans->shrd->eeprom) {
ret = -ENOMEM; ret = -ENOMEM;
goto alloc_err; goto alloc_err;
} }
e = (__le16 *)shrd->eeprom; e = (__le16 *)trans->shrd->eeprom;
ret = iwl_eeprom_verify_signature(trans(priv)); ret = iwl_eeprom_verify_signature(trans);
if (ret < 0) { if (ret < 0) {
IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
ret = -ENOENT; ret = -ENOENT;
goto err; goto err;
} }
/* Make sure driver (instead of uCode) is allowed to read EEPROM */ /* Make sure driver (instead of uCode) is allowed to read EEPROM */
ret = iwl_eeprom_acquire_semaphore(bus(priv)); ret = iwl_eeprom_acquire_semaphore(trans);
if (ret < 0) { if (ret < 0) {
IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT; ret = -ENOENT;
goto err; goto err;
} }
if (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) { if (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
ret = iwl_init_otp_access(bus(priv)); ret = iwl_init_otp_access(trans);
if (ret) { if (ret) {
IWL_ERR(priv, "Failed to initialize OTP access.\n"); IWL_ERR(trans, "Failed to initialize OTP access.\n");
ret = -ENOENT; ret = -ENOENT;
goto done; goto done;
} }
iwl_write32(trans(priv), CSR_EEPROM_GP, iwl_write32(trans, CSR_EEPROM_GP,
iwl_read32(trans(priv), CSR_EEPROM_GP) & iwl_read32(trans, CSR_EEPROM_GP) &
~CSR_EEPROM_GP_IF_OWNER_MSK); ~CSR_EEPROM_GP_IF_OWNER_MSK);
iwl_set_bit(trans(priv), CSR_OTP_GP_REG, iwl_set_bit(trans, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
/* traversing the linked list if no shadow ram supported */ /* traversing the linked list if no shadow ram supported */
if (!cfg(priv)->base_params->shadow_ram_support) { if (!cfg(trans)->base_params->shadow_ram_support) {
if (iwl_find_otp_image(bus(priv), &validblockaddr)) { if (iwl_find_otp_image(trans, &validblockaddr)) {
ret = -ENOENT; ret = -ENOENT;
goto done; goto done;
} }
@ -718,7 +723,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
addr += sizeof(u16)) { addr += sizeof(u16)) {
__le16 eeprom_data; __le16 eeprom_data;
ret = iwl_read_otp_word(bus(priv), addr, &eeprom_data); ret = iwl_read_otp_word(trans, addr, &eeprom_data);
if (ret) if (ret)
goto done; goto done;
e[cache_addr / 2] = eeprom_data; e[cache_addr / 2] = eeprom_data;
@ -729,34 +734,35 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
for (addr = 0; addr < sz; addr += sizeof(u16)) { for (addr = 0; addr < sz; addr += sizeof(u16)) {
u32 r; u32 r;
iwl_write32(trans(priv), CSR_EEPROM_REG, iwl_write32(trans, CSR_EEPROM_REG,
CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG, ret = iwl_poll_bit(trans, CSR_EEPROM_REG,
CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK,
CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK,
IWL_EEPROM_ACCESS_TIMEOUT); IWL_EEPROM_ACCESS_TIMEOUT);
if (ret < 0) { if (ret < 0) {
IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); IWL_ERR(trans,
"Time out reading EEPROM[%d]\n", addr);
goto done; goto done;
} }
r = iwl_read32(trans(priv), CSR_EEPROM_REG); r = iwl_read32(trans, CSR_EEPROM_REG);
e[addr / 2] = cpu_to_le16(r >> 16); e[addr / 2] = cpu_to_le16(r >> 16);
} }
} }
IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", IWL_DEBUG_EEPROM(trans, "NVM Type: %s, version: 0x%x\n",
(trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP)
? "OTP" : "EEPROM", ? "OTP" : "EEPROM",
iwl_eeprom_query16(shrd, EEPROM_VERSION)); iwl_eeprom_query16(trans->shrd, EEPROM_VERSION));
ret = 0; ret = 0;
done: done:
iwl_eeprom_release_semaphore(bus(priv)); iwl_eeprom_release_semaphore(trans);
err: err:
if (ret) if (ret)
iwl_eeprom_free(priv->shrd); iwl_eeprom_free(trans->shrd);
alloc_err: alloc_err:
return ret; return ret;
} }

View File

@ -67,6 +67,7 @@
struct iwl_priv; struct iwl_priv;
struct iwl_shared; struct iwl_shared;
struct iwl_trans;
/* /*
* EEPROM access time values: * EEPROM access time values:
@ -305,7 +306,7 @@ struct iwl_eeprom_ops {
}; };
int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev); int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev);
void iwl_eeprom_free(struct iwl_shared *shrd); void iwl_eeprom_free(struct iwl_shared *shrd);
int iwl_eeprom_check_version(struct iwl_priv *priv); int iwl_eeprom_check_version(struct iwl_priv *priv);
int iwl_eeprom_check_sku(struct iwl_priv *priv); int iwl_eeprom_check_sku(struct iwl_priv *priv);

View File

@ -51,8 +51,8 @@
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-shared.h" #include "iwl-shared.h"
#include "iwl-bus.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-op-mode.h"
/***************************************************************************** /*****************************************************************************
* *
@ -136,7 +136,7 @@ iwlagn_iface_combinations_p2p[] = {
* other mac80211 functions grouped here. * other mac80211 functions grouped here.
*/ */
int iwlagn_mac_setup_register(struct iwl_priv *priv, int iwlagn_mac_setup_register(struct iwl_priv *priv,
struct iwlagn_ucode_capabilities *capa) struct iwl_ucode_capabilities *capa)
{ {
int ret; int ret;
struct ieee80211_hw *hw = priv->hw; struct ieee80211_hw *hw = priv->hw;
@ -195,7 +195,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_DISABLE_BEACON_HINTS |
WIPHY_FLAG_IBSS_RSN; WIPHY_FLAG_IBSS_RSN;
if (trans(priv)->ucode_wowlan.code.len && if (nic(priv)->fw.ucode_wowlan.code.len &&
device_can_wakeup(trans(priv)->dev)) { device_can_wakeup(trans(priv)->dev)) {
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_DISCONNECT |
@ -296,7 +296,7 @@ static int __iwl_up(struct iwl_priv *priv)
error: error:
set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
__iwl_down(priv); iwl_down(priv);
clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
IWL_ERR(priv, "Unable to initialize device.\n"); IWL_ERR(priv, "Unable to initialize device.\n");
@ -305,7 +305,7 @@ static int __iwl_up(struct iwl_priv *priv)
static int iwlagn_mac_start(struct ieee80211_hw *hw) static int iwlagn_mac_start(struct ieee80211_hw *hw)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
int ret; int ret;
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
@ -332,7 +332,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
static void iwlagn_mac_stop(struct ieee80211_hw *hw) static void iwlagn_mac_stop(struct ieee80211_hw *hw)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
@ -341,9 +341,13 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
priv->is_open = 0; priv->is_open = 0;
mutex_lock(&priv->shrd->mutex);
iwl_down(priv); iwl_down(priv);
mutex_unlock(&priv->shrd->mutex);
flush_workqueue(priv->shrd->workqueue); iwl_cancel_deferred_work(priv);
flush_workqueue(priv->workqueue);
/* User space software may expect getting rfkill changes /* User space software may expect getting rfkill changes
* even if interface is down, trans->down will leave the RF * even if interface is down, trans->down will leave the RF
@ -358,7 +362,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct cfg80211_gtk_rekey_data *data) struct cfg80211_gtk_rekey_data *data)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
if (iwlagn_mod_params.sw_crypto) if (iwlagn_mod_params.sw_crypto)
return; return;
@ -385,7 +389,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
static int iwlagn_mac_suspend(struct ieee80211_hw *hw, static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
struct cfg80211_wowlan *wowlan) struct cfg80211_wowlan *wowlan)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
int ret; int ret;
@ -427,7 +431,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
static int iwlagn_mac_resume(struct ieee80211_hw *hw) static int iwlagn_mac_resume(struct ieee80211_hw *hw)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
unsigned long flags; unsigned long flags;
@ -453,17 +457,17 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
if (ret == 0) { if (ret == 0) {
struct iwl_trans *trans = trans(priv); struct iwl_nic *nic = nic(priv);
if (!priv->wowlan_sram) if (!priv->wowlan_sram)
priv->wowlan_sram = priv->wowlan_sram =
kzalloc(trans->ucode_wowlan.data.len, kzalloc(nic->fw.ucode_wowlan.data.len,
GFP_KERNEL); GFP_KERNEL);
if (priv->wowlan_sram) if (priv->wowlan_sram)
_iwl_read_targ_mem_words( _iwl_read_targ_mem_words(
trans(priv), 0x800000, trans(priv), 0x800000,
priv->wowlan_sram, priv->wowlan_sram,
trans->ucode_wowlan.data.len / 4); nic->fw.ucode_wowlan.data.len / 4);
} }
#endif #endif
} }
@ -493,7 +497,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
@ -508,7 +512,7 @@ static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
u32 iv32, u16 *phase1key) u32 iv32, u16 *phase1key)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key);
} }
@ -518,7 +522,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key) struct ieee80211_key_conf *key)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *ctx = vif_priv->ctx; struct iwl_rxon_context *ctx = vif_priv->ctx;
int ret; int ret;
@ -622,7 +626,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid, u16 *ssn, struct ieee80211_sta *sta, u16 tid, u16 *ssn,
u8 buf_size) u8 buf_size)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
int ret = -EINVAL; int ret = -EINVAL;
struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
@ -688,7 +692,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
bool is_ap = vif->type == NL80211_IFTYPE_STATION; bool is_ap = vif->type == NL80211_IFTYPE_STATION;
@ -731,7 +735,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
struct ieee80211_channel_switch *ch_switch) struct ieee80211_channel_switch *ch_switch)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
const struct iwl_channel_info *ch_info; const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf; struct ieee80211_conf *conf = &hw->conf;
struct ieee80211_channel *channel = ch_switch->channel; struct ieee80211_channel *channel = ch_switch->channel;
@ -818,7 +822,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
unsigned int *total_flags, unsigned int *total_flags,
u64 multicast) u64 multicast)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
__le32 filter_or = 0, filter_nand = 0; __le32 filter_or = 0, filter_nand = 0;
struct iwl_rxon_context *ctx; struct iwl_rxon_context *ctx;
@ -865,7 +869,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
mutex_lock(&priv->shrd->mutex); mutex_lock(&priv->shrd->mutex);
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
@ -902,7 +906,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
enum nl80211_channel_type channel_type, enum nl80211_channel_type channel_type,
int duration) int duration)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
int err = 0; int err = 0;
@ -992,7 +996,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -1012,7 +1016,7 @@ static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw,
const u8 *bssid, const u8 *bssid,
enum ieee80211_tx_sync_type type) enum ieee80211_tx_sync_type type)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *ctx = vif_priv->ctx; struct iwl_rxon_context *ctx = vif_priv->ctx;
int ret; int ret;
@ -1066,7 +1070,7 @@ static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
const u8 *bssid, const u8 *bssid,
enum ieee80211_tx_sync_type type) enum ieee80211_tx_sync_type type)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *ctx = vif_priv->ctx; struct iwl_rxon_context *ctx = vif_priv->ctx;
@ -1090,7 +1094,7 @@ static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
enum ieee80211_rssi_event rssi_event) enum ieee80211_rssi_event rssi_event)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->shrd->mutex); mutex_lock(&priv->shrd->mutex);
@ -1115,9 +1119,9 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, static int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, bool set) struct ieee80211_sta *sta, bool set)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
queue_work(priv->shrd->workqueue, &priv->beacon_update); queue_work(priv->workqueue, &priv->beacon_update);
return 0; return 0;
} }
@ -1126,7 +1130,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u16 queue, struct ieee80211_vif *vif, u16 queue,
const struct ieee80211_tx_queue_params *params) const struct ieee80211_tx_queue_params *params)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *ctx = vif_priv->ctx; struct iwl_rxon_context *ctx = vif_priv->ctx;
unsigned long flags; unsigned long flags;
@ -1169,7 +1173,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
return priv->ibss_manager == IWL_IBSS_MANAGER; return priv->ibss_manager == IWL_IBSS_MANAGER;
} }
@ -1223,7 +1227,7 @@ static int iwl_setup_interface(struct iwl_priv *priv,
static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *tmp, *ctx = NULL; struct iwl_rxon_context *tmp, *ctx = NULL;
int err; int err;
@ -1320,7 +1324,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv,
static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
@ -1348,7 +1352,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
enum nl80211_iftype newtype, bool newp2p) enum nl80211_iftype newtype, bool newp2p)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl_rxon_context *tmp; struct iwl_rxon_context *tmp;
@ -1434,7 +1438,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req) struct cfg80211_scan_request *req)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
int ret; int ret;
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
@ -1480,7 +1484,7 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
int ret; int ret;
@ -1519,7 +1523,7 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd, enum sta_notify_cmd cmd,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
int sta_id; int sta_id;
@ -1587,15 +1591,18 @@ struct ieee80211_ops iwlagn_hw_ops = {
struct ieee80211_hw *iwl_alloc_all(void) struct ieee80211_hw *iwl_alloc_all(void)
{ {
struct iwl_priv *priv; struct iwl_priv *priv;
struct iwl_op_mode *op_mode;
/* mac80211 allocates memory for this device instance, including /* mac80211 allocates memory for this device instance, including
* space for this driver's private structure */ * space for this driver's private structure */
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); hw = ieee80211_alloc_hw(sizeof(struct iwl_priv) +
sizeof(struct iwl_op_mode), &iwlagn_hw_ops);
if (!hw) if (!hw)
goto out; goto out;
priv = hw->priv; op_mode = hw->priv;
priv = IWL_OP_MODE_GET_DVM(op_mode);
priv->hw = hw; priv->hw = hw;
out: out:

View File

@ -0,0 +1,198 @@
/******************************************************************************
*
* 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 - 2012 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 <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2012 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.
*
*****************************************************************************/
#ifndef __iwl_op_mode_h__
#define __iwl_op_mode_h__
struct iwl_op_mode;
struct iwl_trans;
struct sk_buff;
struct iwl_device_cmd;
struct iwl_rx_mem_buffer;
/**
* DOC: Operational mode - what is it ?
*
* The operational mode (a.k.a. op_mode) is the layer that implements
* mac80211's handlers. It knows two APIs: mac80211's and the fw's. It uses
* the transport API to access the HW. The op_mode doesn't need to know how the
* underlying HW works, since the transport layer takes care of that.
*
* There can be several op_mode: i.e. different fw APIs will require two
* different op_modes. This is why the op_mode is virtualized.
*/
/**
* DOC: Life cycle of the Operational mode
*
* The operational mode has a very simple life cycle.
*
* 1) The driver layer (iwl-drv.c) chooses the op_mode based on the
* capabilities advertized by the fw file (in TLV format).
* 2) The driver layer starts the op_mode (ops->start)
* 3) The op_mode registers registers mac80211
* 4) The op_mode is governed by mac80211
* 5) The driver layer stops the op_mode
*/
/**
* struct iwl_op_mode_ops - op_mode specific operations
*
* The op_mode exports its ops so that external components can start it and
* interact with it. The driver layer typically calls the start and stop
* handlers, the transport layer calls the others.
*
* All the handlers MUST be implemented
*
* @start: start the op_mode. The transport layer is already allocated.
* May sleep
* @stop: stop the op_mode. Must free all the memory allocated.
* May sleep
* @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
* HCMD the this Rx responds to.
* Must be atomic.
* @queue_full: notifies that a HW queue is full. Ac is the ac of the queue
* Must be atomic
* @queue_not_full: notifies that a HW queue is not full any more.
* Ac is the ac of the queue. Must be atomic
* @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
* the radio is killed. Must be atomic.
* @free_skb: allows the transport layer to free skbs that haven't been
* reclaimed by the op_mode. This can happen when the driver is freed and
* there are Tx packets pending in the transport layer.
* Must be atomic
* @nic_error: error notification. Must be atomic
*/
struct iwl_op_mode_ops {
struct iwl_op_mode *(*start)(struct iwl_trans *trans);
void (*stop)(struct iwl_op_mode *op_mode);
int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_mem_buffer *rxb,
struct iwl_device_cmd *cmd);
void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac);
void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac);
void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
void (*nic_error)(struct iwl_op_mode *op_mode);
};
/**
* struct iwl_op_mode - operational mode
*
* This holds an implementation of the mac80211 / fw API.
*
* @ops - pointer to its own ops
*/
struct iwl_op_mode {
const struct iwl_op_mode_ops *ops;
const struct iwl_trans *trans;
char op_mode_specific[0] __aligned(sizeof(void *));
};
static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
{
might_sleep();
op_mode->ops->stop(op_mode);
}
static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode,
struct iwl_rx_mem_buffer *rxb,
struct iwl_device_cmd *cmd)
{
return op_mode->ops->rx(op_mode, rxb, cmd);
}
static inline void iwl_op_mode_queue_full(struct iwl_op_mode *op_mode, u8 ac)
{
op_mode->ops->queue_full(op_mode, ac);
}
static inline void iwl_op_mode_queue_not_full(struct iwl_op_mode *op_mode,
u8 ac)
{
op_mode->ops->queue_not_full(op_mode, ac);
}
static inline void iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode,
bool state)
{
op_mode->ops->hw_rf_kill(op_mode, state);
}
static inline void iwl_op_mode_free_skb(struct iwl_op_mode *op_mode,
struct sk_buff *skb)
{
op_mode->ops->free_skb(op_mode, skb);
}
static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode)
{
op_mode->ops->nic_error(op_mode);
}
/*****************************************************
* Op mode layers implementations
******************************************************/
extern const struct iwl_op_mode_ops iwl_dvm_ops;
#endif /* __iwl_op_mode_h__ */

View File

@ -64,12 +64,13 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci-aspm.h> #include <linux/pci-aspm.h>
#include "iwl-bus.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-shared.h" #include "iwl-shared.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-csr.h" #include "iwl-csr.h"
#include "iwl-cfg.h" #include "iwl-cfg.h"
#include "iwl-drv.h"
#include "iwl-trans.h"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \ #define IWL_PCI_DEVICE(dev, subdev, cfg) \
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
@ -157,9 +158,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)},
{IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)},
{IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_cfg)},/* low 5GHz active */ {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */
{IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_cfg)},/* high 5GHz active */ {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */
/* 6x30 Series */ /* 6x30 Series */
{IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)},
@ -240,6 +241,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)},
{IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},
/* 105 Series */ /* 105 Series */
{IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
@ -262,44 +264,40 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
struct iwl_bus *bus; struct iwl_shared *shrd;
struct iwl_trans *iwl_trans;
int err; int err;
bus = kzalloc(sizeof(*bus), GFP_KERNEL); shrd = kzalloc(sizeof(*iwl_trans->shrd), GFP_KERNEL);
if (!bus) { if (!shrd) {
dev_printk(KERN_ERR, &pdev->dev,
"Couldn't allocate iwl_pci_bus");
return -ENOMEM;
}
bus->shrd = kzalloc(sizeof(*bus->shrd), GFP_KERNEL);
if (!bus->shrd) {
dev_printk(KERN_ERR, &pdev->dev, dev_printk(KERN_ERR, &pdev->dev,
"Couldn't allocate iwl_shared"); "Couldn't allocate iwl_shared");
err = -ENOMEM; err = -ENOMEM;
goto out_free_bus; goto out_free_bus;
} }
bus->shrd->bus = bus;
pci_set_drvdata(pdev, bus);
#ifdef CONFIG_IWLWIFI_IDI #ifdef CONFIG_IWLWIFI_IDI
trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent);
if (trans(bus) == NULL) { if (iwl_trans == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto out_free_bus; goto out_free_bus;
} }
err = iwl_probe(bus, &trans_ops_idi, cfg); shrd->trans = iwl_trans;
pci_set_drvdata(pdev, iwl_trans);
err = iwl_drv_start(shrd, iwl_trans, cfg);
#else #else
trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent);
if (trans(bus) == NULL) { if (iwl_trans == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto out_free_bus; goto out_free_bus;
} }
err = iwl_probe(bus, &trans_ops_pcie, cfg); shrd->trans = iwl_trans;
pci_set_drvdata(pdev, iwl_trans);
err = iwl_drv_start(shrd, iwl_trans, cfg);
#endif #endif
if (err) if (err)
goto out_free_trans; goto out_free_trans;
@ -307,26 +305,24 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0; return 0;
out_free_trans: out_free_trans:
iwl_trans_free(trans(bus)); iwl_trans_free(iwl_trans);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
out_free_bus: out_free_bus:
kfree(bus->shrd); kfree(shrd);
kfree(bus);
return err; return err;
} }
static void __devexit iwl_pci_remove(struct pci_dev *pdev) static void __devexit iwl_pci_remove(struct pci_dev *pdev)
{ {
struct iwl_bus *bus = pci_get_drvdata(pdev); struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
struct iwl_shared *shrd = bus->shrd; struct iwl_shared *shrd = iwl_trans->shrd;
iwl_remove(shrd->priv); iwl_drv_stop(shrd);
iwl_trans_free(shrd->trans); iwl_trans_free(shrd->trans);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
kfree(bus->shrd); kfree(shrd);
kfree(bus);
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
@ -334,22 +330,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
static int iwl_pci_suspend(struct device *device) static int iwl_pci_suspend(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct iwl_bus *bus = pci_get_drvdata(pdev); struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
struct iwl_shared *shrd = bus->shrd;
/* Before you put code here, think about WoWLAN. You cannot check here /* 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 * 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. * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx.
*/ */
return iwl_trans_suspend(shrd->trans); return iwl_trans_suspend(iwl_trans);
} }
static int iwl_pci_resume(struct device *device) static int iwl_pci_resume(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct iwl_bus *bus = pci_get_drvdata(pdev); struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
struct iwl_shared *shrd = bus->shrd;
/* Before you put code here, think about WoWLAN. You cannot check here /* 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 * whether WoWLAN is enabled or not, and your code will run even if
@ -362,7 +356,7 @@ static int iwl_pci_resume(struct device *device)
*/ */
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
return iwl_trans_resume(shrd->trans); return iwl_trans_resume(iwl_trans);
} }
static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);

View File

@ -218,7 +218,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
int iwl_scan_cancel(struct iwl_priv *priv) int iwl_scan_cancel(struct iwl_priv *priv)
{ {
IWL_DEBUG_SCAN(priv, "Queuing abort scan\n"); IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
queue_work(priv->shrd->workqueue, &priv->abort_scan); queue_work(priv->workqueue, &priv->abort_scan);
return 0; return 0;
} }
@ -354,7 +354,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
*/ */
set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status);
clear_bit(STATUS_SCAN_HW, &priv->shrd->status); clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
queue_work(priv->shrd->workqueue, &priv->scan_completed); queue_work(priv->workqueue, &priv->scan_completed);
if (priv->iw_mode != NL80211_IFTYPE_ADHOC && if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
iwl_advanced_bt_coexist(priv) && iwl_advanced_bt_coexist(priv) &&
@ -374,7 +374,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
IWL_BT_COEX_TRAFFIC_LOAD_NONE; IWL_BT_COEX_TRAFFIC_LOAD_NONE;
} }
priv->bt_status = scan_notif->bt_status; priv->bt_status = scan_notif->bt_status;
queue_work(priv->shrd->workqueue, queue_work(priv->workqueue,
&priv->bt_traffic_change_work); &priv->bt_traffic_change_work);
} }
return 0; return 0;
@ -950,7 +950,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
return ret; return ret;
} }
queue_delayed_work(priv->shrd->workqueue, &priv->scan_check, queue_delayed_work(priv->workqueue, &priv->scan_check,
IWL_SCAN_CHECK_WATCHDOG); IWL_SCAN_CHECK_WATCHDOG);
return 0; return 0;
@ -963,7 +963,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
*/ */
void iwl_internal_short_hw_scan(struct iwl_priv *priv) void iwl_internal_short_hw_scan(struct iwl_priv *priv)
{ {
queue_work(priv->shrd->workqueue, &priv->start_internal_scan); queue_work(priv->workqueue, &priv->start_internal_scan);
} }
static void iwl_bg_start_internal_scan(struct work_struct *work) static void iwl_bg_start_internal_scan(struct work_struct *work)

View File

@ -94,7 +94,6 @@
* This implementation is iwl-pci.c * This implementation is iwl-pci.c
*/ */
struct iwl_bus;
struct iwl_priv; struct iwl_priv;
struct iwl_trans; struct iwl_trans;
struct iwl_sensitivity_ranges; struct iwl_sensitivity_ranges;
@ -173,8 +172,6 @@ struct iwl_mod_params {
* @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
* @sku: sku read from EEPROM * @sku: sku read from EEPROM
* @rx_page_order: Rx buffer page order * @rx_page_order: Rx buffer page order
* @max_inst_size: for ucode use
* @max_data_size: for ucode use
* @ct_kill_threshold: temperature threshold - in hw dependent unit * @ct_kill_threshold: temperature threshold - in hw dependent unit
* @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
* relevant for 1000, 6000 and up * relevant for 1000, 6000 and up
@ -192,8 +189,6 @@ struct iwl_hw_params {
bool shadow_reg_enable; bool shadow_reg_enable;
u16 sku; u16 sku;
u32 rx_page_order; u32 rx_page_order;
u32 max_inst_size;
u32 max_data_size;
u32 ct_kill_threshold; u32 ct_kill_threshold;
u32 ct_kill_exit_threshold; u32 ct_kill_exit_threshold;
unsigned int wd_timeout; unsigned int wd_timeout;
@ -283,6 +278,8 @@ enum iwl_led_mode {
* @ucode_api_ok: oldest version of the uCode API that is OK to load * @ucode_api_ok: oldest version of the uCode API that is OK to load
* without a warning, for use in transitions * without a warning, for use in transitions
* @ucode_api_min: Lowest version of uCode API supported by driver. * @ucode_api_min: Lowest version of uCode API supported by driver.
* @max_inst_size: The maximal length of the fw inst section
* @max_data_size: The maximal length of the fw data section
* @valid_tx_ant: valid transmit antenna * @valid_tx_ant: valid transmit antenna
* @valid_rx_ant: valid receive antenna * @valid_rx_ant: valid receive antenna
* @sku: sku information from EEPROM * @sku: sku information from EEPROM
@ -320,6 +317,8 @@ struct iwl_cfg {
const unsigned int ucode_api_max; const unsigned int ucode_api_max;
const unsigned int ucode_api_ok; const unsigned int ucode_api_ok;
const unsigned int ucode_api_min; const unsigned int ucode_api_min;
const u32 max_data_size;
const u32 max_inst_size;
u8 valid_tx_ant; u8 valid_tx_ant;
u8 valid_rx_ant; u8 valid_rx_ant;
u16 sku; u16 sku;
@ -358,8 +357,8 @@ struct iwl_cfg {
* @cfg: see struct iwl_cfg * @cfg: see struct iwl_cfg
* @priv: pointer to the upper layer data * @priv: pointer to the upper layer data
* @trans: pointer to the transport layer data * @trans: pointer to the transport layer data
* @nic: pointer to the nic data
* @hw_params: see struct iwl_hw_params * @hw_params: see struct iwl_hw_params
* @workqueue: the workqueue used by all the layers of the driver
* @lock: protect general shared data * @lock: protect general shared data
* @sta_lock: protects the station table. * @sta_lock: protects the station table.
* If lock and sta_lock are needed, lock must be acquired first. * If lock and sta_lock are needed, lock must be acquired first.
@ -385,13 +384,12 @@ struct iwl_shared {
bool wowlan; bool wowlan;
u8 valid_contexts; u8 valid_contexts;
struct iwl_bus *bus;
struct iwl_cfg *cfg; struct iwl_cfg *cfg;
struct iwl_priv *priv; struct iwl_priv *priv;
struct iwl_trans *trans; struct iwl_trans *trans;
struct iwl_nic *nic;
struct iwl_hw_params hw_params; struct iwl_hw_params hw_params;
struct workqueue_struct *workqueue;
spinlock_t lock; spinlock_t lock;
spinlock_t sta_lock; spinlock_t sta_lock;
struct mutex mutex; struct mutex mutex;
@ -416,10 +414,10 @@ struct iwl_shared {
}; };
/*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */
#define priv(_m) ((_m)->shrd->priv) #define priv(_m) ((_m)->shrd->priv)
#define cfg(_m) ((_m)->shrd->cfg) #define cfg(_m) ((_m)->shrd->cfg)
#define bus(_m) ((_m)->shrd->bus) #define nic(_m) ((_m)->shrd->nic)
#define trans(_m) ((_m)->shrd->trans) #define trans(_m) ((_m)->shrd->trans)
#define hw_params(_m) ((_m)->shrd->hw_params) #define hw_params(_m) ((_m)->shrd->hw_params)
@ -531,24 +529,11 @@ enum iwl_rxon_context_id {
NUM_IWL_RXON_CTX NUM_IWL_RXON_CTX
}; };
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);
int iwlagn_hw_valid_rtc_data_addr(u32 addr); int iwlagn_hw_valid_rtc_data_addr(u32 addr);
void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state);
void iwl_nic_config(struct iwl_priv *priv); void iwl_nic_config(struct iwl_priv *priv);
void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
const char *get_cmd_string(u8 cmd); const char *get_cmd_string(u8 cmd);
bool iwl_check_for_ct_kill(struct iwl_priv *priv); 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);
/* notification wait support */ /* notification wait support */
void iwl_abort_notification_waits(struct iwl_shared *shrd); void iwl_abort_notification_waits(struct iwl_shared *shrd);
@ -568,20 +553,6 @@ void __releases(wait_entry)
iwl_remove_notification(struct iwl_shared *shrd, iwl_remove_notification(struct iwl_shared *shrd,
struct iwl_notification_wait *wait_entry); struct iwl_notification_wait *wait_entry);
#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,
enum iwl_rxon_context_id ctxid);
#else
static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
enum iwl_rxon_context_id ctxid)
{
}
#endif
#define IWL_CMD(x) case x: return #x #define IWL_CMD(x) case x: return #x
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))

Some files were not shown because too many files have changed in this diff Show More