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

This commit is contained in:
John W. Linville 2012-03-05 15:05:54 -05:00
commit 051d3b5043
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
M: Brett Rudley <brudley@broadcom.com>
M: Henry Ptasinski <henryp@broadcom.com>
M: Roland Vossen <rvossen@broadcom.com>
M: Arend van Spriel <arend@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) {
/* 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;
__raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
/* Enable global WMAC swapping */
reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP);
reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
reg |= AR5K_AR2315_BYTESWAP_WMAC;
__raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
} else {
/* Enable WMAC DMA access (assuming 5312 or 231x*/
/* 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)
reg |= AR5K_AR5312_ENABLE_WLAN0;
else
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
@ -203,17 +203,17 @@ static int ath_ahb_remove(struct platform_device *pdev)
if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
/* 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;
__raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
} else {
/*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)
reg &= ~AR5K_AR5312_ENABLE_WLAN0;
else
reg &= ~AR5K_AR5312_ENABLE_WLAN1;
__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
}
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)
{
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)
{
__raw_writel(val, ath5k_ahb_reg(ah, reg));
iowrite32(val, ath5k_ahb_reg(ah, reg));
}
#else

View File

@ -473,14 +473,14 @@ ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
}
/* Put BB/MAC into reset */
regval = __raw_readl(reg);
__raw_writel(regval | val, reg);
regval = __raw_readl(reg);
regval = ioread32(reg);
iowrite32(regval | val, reg);
regval = ioread32(reg);
usleep_range(100, 150);
/* Bring BB/MAC out of reset */
__raw_writel(regval & ~val, reg);
regval = __raw_readl(reg);
iowrite32(regval & ~val, reg);
regval = ioread32(reg);
/*
* 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;
}
static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
struct beacon_parameters *info, bool add)
static int ath6kl_set_ies(struct ath6kl_vif *vif,
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_vif *vif = netdev_priv(dev);
@ -2281,7 +2315,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
int res;
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))
return -EIO;
@ -2289,31 +2323,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
if (vif->next_mode != AP_NETWORK)
return -EOPNOTSUPP;
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;
}
if (!add)
return 0;
res = ath6kl_set_ies(vif, &info->beacon);
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
*/
if (info->head == NULL)
if (info->beacon.head == NULL)
return -EINVAL;
mgmt = (struct ieee80211_mgmt *) info->head;
mgmt = (struct ieee80211_mgmt *) info->beacon.head;
ies = mgmt->u.beacon.variable;
if (ies > info->head + info->head_len)
if (ies > info->beacon.head + info->beacon.head_len)
return -EINVAL;
ies_len = info->head + info->head_len - ies;
ies_len = info->beacon.head + info->beacon.head_len - ies;
if (info->ssid == NULL)
return -EINVAL;
@ -2436,19 +2446,21 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
struct beacon_parameters *info)
static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
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,
struct beacon_parameters *info)
{
return ath6kl_ap_beacon(wiphy, dev, info, false);
}
static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
{
struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev);
@ -2783,9 +2795,9 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
.resume = __ath6kl_cfg80211_resume,
#endif
.set_channel = ath6kl_set_channel,
.add_beacon = ath6kl_add_beacon,
.set_beacon = ath6kl_set_beacon,
.del_beacon = ath6kl_del_beacon,
.start_ap = ath6kl_start_ap,
.change_beacon = ath6kl_change_beacon,
.stop_ap = ath6kl_stop_ap,
.del_station = ath6kl_del_station,
.change_station = ath6kl_change_station,
.remain_on_channel = ath6kl_remain_on_channel,

View File

@ -6,6 +6,14 @@ config ATH9K_DFS_DEBUGFS
def_bool y
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
tristate "Atheros 802.11n wireless cards support"
depends on MAC80211
@ -81,14 +89,6 @@ config ATH9K_RATE_CONTROL
Say Y, if you want to use the ath9k specific rate control
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
tristate "Atheros HTC based wireless cards support"
depends on USB && MAC80211

View File

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

View File

@ -459,97 +459,6 @@ static const u32 ar5416Common_9100[][2] = {
{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] = {
/* Addr 5G_HT20 5G_HT40 */
{0x0000989c, 0x00000000, 0x00000000},
@ -624,13 +533,6 @@ static const u32 ar5416Bank6TPC_9100[][3] = {
{0x000098d0, 0x0000000f, 0x0010000f},
};
static const u32 ar5416Bank7_9100[][2] = {
/* Addr allmodes */
{0x0000989c, 0x00000500},
{0x0000989c, 0x00000800},
{0x000098cc, 0x0000000e},
};
static const u32 ar5416Addac_9100[][2] = {
/* Addr allmodes */
{0x0000989c, 0x00000000},
@ -1113,178 +1015,6 @@ static const u32 ar5416Common_9160[][2] = {
{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] = {
/* Addr allmodes */
{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,
ARRAY_SIZE(ar9271Common_9271), 2);
INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
ar9271Common_normal_cck_fir_coeff_9271,
ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
ar9287Common_normal_cck_fir_coeff_9287_1_1,
ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 2);
INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
ar9271Common_japan_2484_cck_fir_coeff_9271,
ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 2);
INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
ar9271Modes_9271_1_0_only,
ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5);
@ -54,53 +54,31 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
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)) {
INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
ARRAY_SIZE(ar9287Modes_9287_1_1), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
ARRAY_SIZE(ar9287Common_9287_1_1), 2);
if (ah->config.pcie_clock_req)
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)) {
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
ARRAY_SIZE(ar9285Modes_9285_1_2), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_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)) {
INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
ARRAY_SIZE(ar9280Modes_9280_2), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_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,
ar9280Modes_fast_clock_9280_2,
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);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
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)) {
INIT_INI_ARRAY(&ah->iniAddac,
ar5416Addac_9160_1_1,
@ -138,22 +100,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
ARRAY_SIZE(ar5416Modes_9100), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
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,
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,
ARRAY_SIZE(ar5416Addac_9100), 2);
} else {
@ -161,24 +109,37 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
ARRAY_SIZE(ar5416Modes), 5);
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
ARRAY_SIZE(ar5416Common), 2);
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
ARRAY_SIZE(ar5416Bank0), 2);
INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
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,
ARRAY_SIZE(ar5416BB_RfGain), 3);
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
ARRAY_SIZE(ar5416Bank0), 2);
INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
ARRAY_SIZE(ar5416Bank1), 2);
INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
ARRAY_SIZE(ar5416Bank2), 2);
INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
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,
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 */

View File

@ -925,34 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
{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] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
@ -1743,34 +1715,6 @@ static const u32 ar9285Modes_XE2_0_high_power[][5] = {
{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] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160},
@ -2512,34 +2456,6 @@ static const u32 ar9287Modes_rx_gain_9287_1_1[][5] = {
{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] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
@ -3176,20 +3092,6 @@ static const u32 ar9271Common_9271[][2] = {
{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] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{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 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 is_reusable = true, status = true;
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)
run_agc_cal = true;
if (mci && IS_CHAN_2GHZ(chan) &&
(mci_hw->bt_state == MCI_BT_AWAKE) &&
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");
}
}
if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
ar9003_mci_init_cal_req(ah, &is_reusable);
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
@ -1041,19 +1018,8 @@ skip_tx_iqcal:
0, AH_WAIT_TIMEOUT);
}
if (mci && IS_CHAN_2GHZ(chan) &&
(mci_hw->bt_state == MCI_BT_AWAKE) &&
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 (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
ar9003_mci_init_cal_done(ah);
if (rtt && !run_rtt_cal) {
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);
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,
AR_SWITCH_TABLE_COM_AR9462_ALL, value);
} else

View File

@ -22,7 +22,6 @@
#include "ar9330_1p1_initvals.h"
#include "ar9330_1p2_initvals.h"
#include "ar9580_1p0_initvals.h"
#include "ar9462_1p0_initvals.h"
#include "ar9462_2p0_initvals.h"
/* 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,
ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
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)) {
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,
ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
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))
INIT_INI_ARRAY(&ah->iniModesTxGain,
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,
ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
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))
INIT_INI_ARRAY(&ah->iniModesTxGain,
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,
ARRAY_SIZE(ar9580_1p0_rx_gain_table),
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))
INIT_INI_ARRAY(&ah->iniModesRxGain,
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,
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
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))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9462_common_wo_xlna_rx_gain_table_2p0,
@ -775,14 +697,10 @@ static void ar9003_rx_gain_table_mode1(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,
ar9462_common_mixed_rx_gain_table_2p0,
ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);
ar9462_common_mixed_rx_gain_table_2p0,
ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);
}
static void ar9003_rx_gain_table_apply(struct ath_hw *ah)

View File

@ -16,6 +16,7 @@
#include <linux/export.h>
#include "hw.h"
#include "ar9003_mac.h"
#include "ar9003_mci.h"
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;
int checksum = 0;
u32 val, ctl12, ctl17;
u8 desc_len;
desc_len = (AR_SREV_9462(ah) ? 0x18 : 0x17);
val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
(1 << AR_TxRxDesc_S) |
(1 << AR_CtrlStat_S) |
(i->qcu << AR_TxQcuNum_S) | 0x17;
(i->qcu << AR_TxQcuNum_S) | desc_len;
checksum += 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->ctl21 = 0;
ads->ctl22 = 0;
ads->ctl23 = 0;
ctl17 = SM(i->keytype, AR_EncrType);
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;
struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
u32 sync_cause = 0, 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);
}
if (async_cause & AR_INTR_ASYNC_MASK_MCI) {
u32 raw_intr, rx_msg_intr;
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 (async_cause & AR_INTR_ASYNC_MASK_MCI)
ar9003_mci_get_isr(ah, masked);
if (sync_cause) {
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)
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);
/*
* 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_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)

View File

@ -92,7 +92,8 @@ struct ar9003_txc {
u32 ctl20; /* DMA control 20 */
u32 ctl21; /* DMA control 21 */
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);
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)
#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

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.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.min = AR_PHY_CCA_MIN_GOOD_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_CCA_NOM_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -110)
#define AR_PHY_CCA_NOM_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -115)
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -125)
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -125)
#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110
#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -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_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
/*
@ -612,16 +617,14 @@
#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4)
#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8)
#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc)
#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
0x4c0 : 0x4c4))
#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
0x4c4 : 0x4c8))
#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + 0x4c4))
#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + 0x4c8))
#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)
#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_BIAS1 0x160c0
#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},
};
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] = {
/* Addr allmodes */
{0x0000a000, 0x00010000},
@ -380,349 +372,6 @@ static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
{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] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
@ -1356,24 +1005,6 @@ static const u32 ar9462_2p0_radio_core[][2] = {
{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] = {
/* Addr allmodes */
{0x00007020, 0x00000000},
@ -1381,11 +1012,6 @@ static const u32 ar9462_2p0_soc_preamble[][2] = {
{0x00007038, 0x000004c2},
};
static const u32 ar9462_2p0_sys2ant[][2] = {
/* Addr allmodes */
{0x00063120, 0x00801980},
};
static const u32 ar9462_2p0_mac_core[][2] = {
/* Addr allmodes */
{0x00000008, 0x00000000},
@ -1822,75 +1448,6 @@ static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
{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] = {
/* Addr allmodes */
{0x000018c0, 0x10101010},
@ -1903,26 +1460,4 @@ static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
{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 */

View File

@ -454,9 +454,39 @@ struct ath_btcoex {
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_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 */
@ -650,8 +680,11 @@ struct ath_softc {
struct ath_beacon_config cur_beacon_conf;
struct delayed_work tx_complete_work;
struct delayed_work hw_pll_work;
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
struct ath_btcoex btcoex;
struct ath_mci_coex mci_coex;
#endif
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;
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))
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);
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)
{
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 */
REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
(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;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
/* btcoex 3-wire */
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
(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);
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)
{
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 */
ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
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;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_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;
int i;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
btcoex_hw->enabled = false;
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) {
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,
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)) {
ar9003_btcoex_bt_stomp(ah, stomp_type);
return;

View File

@ -67,7 +67,6 @@ struct ath9k_hw_mci {
u32 wlan_cal_done;
u32 config;
u8 *gpm_buf;
u8 *sched_buf;
bool ready;
bool update_2g5g;
bool is_2g;
@ -98,13 +97,14 @@ struct ath_btcoex_hw {
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_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_btcoex_set_weight(struct ath_hw *ah,
u32 bt_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_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type);

View File

@ -451,109 +451,6 @@ static const struct file_operations fops_interrupt = {
.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(str, elem) \
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_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_hw *ah = sc->sc_ah;
struct ieee80211_hw *hw = sc->hw;
char *buf;
unsigned int len = 0, size = 8000;
struct ath9k_vif_iter_data iter_data;
char buf[512];
unsigned int len = 0;
ssize_t retval = 0;
unsigned int reg;
struct ath9k_vif_iter_data iter_data;
u32 rxfilter;
ath9k_calculate_iter_data(hw, NULL, &iter_data);
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
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);
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);
rxfilter = ath9k_hw_getrxfilter(sc->sc_ah);
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");
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, 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",
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);
len += snprintf(buf + len, sizeof(buf) - len,
"VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i"
" ADHOC: %i OTHER: %i TOTAL: %hi BEACON-VIF: %hi\n",
iter_data.naps, iter_data.nstations, iter_data.nmeshes,
iter_data.nwds, iter_data.nadhocs, iter_data.nothers,
sc->nvifs, sc->nbcnvifs);
len += snprintf(buf + len, size - len,
"Calculated-BSSID-Mask: %pM\n",
iter_data.mask);
if (len > size)
len = size;
if (len > sizeof(buf))
len = sizeof(buf);
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
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,
struct ath_tx_status *ts, struct ath_txq *txq,
unsigned int flags)
@ -931,16 +869,23 @@ static const struct file_operations fops_misc = {
.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,
size_t count, loff_t *ppos)
{
#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]);
struct ath_softc *sc = file->private_data;
char *buf;
unsigned int len = 0, size = 1400;
unsigned int len = 0, size = 1600;
ssize_t retval = 0;
buf = kzalloc(size, GFP_KERNEL);
@ -948,87 +893,80 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
return -ENOMEM;
len += snprintf(buf + len, size - len,
"%18s : %10u\n", "CRC ERR",
"%22s : %10u\n", "CRC ERR",
sc->debug.stats.rxstats.crc_err);
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);
len += snprintf(buf + len, size - len,
"%18s : %10u\n", "PHY ERR",
"%22s : %10u\n", "PHY ERR",
sc->debug.stats.rxstats.phy_err);
len += snprintf(buf + len, size - len,
"%18s : %10u\n", "MIC ERR",
"%22s : %10u\n", "MIC ERR",
sc->debug.stats.rxstats.mic_err);
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);
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);
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);
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,
"%18s : %10d\n", "RSSI-CTL0",
"%22s : %10d\n", "RSSI-CTL0",
sc->debug.stats.rxstats.rs_rssi_ctl0);
len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-CTL1",
"%22s : %10d\n", "RSSI-CTL1",
sc->debug.stats.rxstats.rs_rssi_ctl1);
len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-CTL2",
"%22s : %10d\n", "RSSI-CTL2",
sc->debug.stats.rxstats.rs_rssi_ctl2);
len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-EXT0",
"%22s : %10d\n", "RSSI-EXT0",
sc->debug.stats.rxstats.rs_rssi_ext0);
len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-EXT1",
"%22s : %10d\n", "RSSI-EXT1",
sc->debug.stats.rxstats.rs_rssi_ext1);
len += snprintf(buf + len, size - len,
"%18s : %10d\n", "RSSI-EXT2",
"%22s : %10d\n", "RSSI-EXT2",
sc->debug.stats.rxstats.rs_rssi_ext2);
len += snprintf(buf + len, size - len,
"%18s : %10d\n", "Rx Antenna",
"%22s : %10d\n", "Rx 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,
"%18s : %10u\n", "RX-Pkts-All",
"%22s : %10u\n", "RX-Pkts-All",
sc->debug.stats.rxstats.rx_pkts_all);
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);
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\
[sc->debug.rsidx].c)
u32 phyerr;
RX_STAT_INC(rx_pkts_all);
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) {
RX_STAT_INC(phy_err);
phyerr = rs->rs_phyerr & 0x24;
RX_PHY_ERR_INC(phyerr);
if (rs->rs_phyerr < ATH9K_PHYERR_MAX)
RX_PHY_ERR_INC(rs->rs_phyerr);
}
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);
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
&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,
&fops_xmit);
debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_stations);
debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
&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,
&fops_recv);
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,
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;
}

View File

@ -110,6 +110,8 @@ void ath_start_rfkill_poll(struct ath_softc *sc)
wiphy_rfkill_start_polling(sc->hw->wiphy);
}
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
/******************/
/* BTCOEX */
/******************/
@ -245,13 +247,10 @@ static void ath_btcoex_no_stomp_timer(void *arg)
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;
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_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
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");
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
/* make sure duty cycle timer is also stopped when resuming */
if (btcoex->hw_timer_enabled)
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_hw *ah = sc->sc_ah;
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
return;
del_timer_sync(&btcoex->period_timer);
if (btcoex->hw_timer_enabled)
@ -317,3 +310,113 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc)
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;
};
void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv);
void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv);
void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product);
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_SCANNING BIT(1)
@ -483,7 +495,10 @@ struct ath9k_htc_priv {
int cabq;
int hwq_map[WME_NUM_AC];
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
struct ath_btcoex btcoex;
#endif
struct delayed_work coex_period_work;
struct delayed_work duty_cycle_work;
#ifdef CONFIG_ATH9K_HTC_DEBUGFS

View File

@ -20,6 +20,10 @@
/* BTCOEX */
/******************/
#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
/*
* 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);
}
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;
if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE)
return;
btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
btcoex->btcoex_period / 100;
@ -131,14 +132,11 @@ void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
* (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_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");
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.
*/
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->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 */
/*******/

View File

@ -41,8 +41,6 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
.max_power = 20, \
}
#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193"
static struct ieee80211_channel ath9k_2ghz_channels[] = {
CHAN2G(2412, 0), /* Channel 1 */
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;
}
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,
u16 devid, char *product,
u32 drv_info)
@ -698,12 +673,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
ath9k_cmn_init_crypto(ah);
ath9k_init_channels_rates(priv);
ath9k_init_misc(priv);
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);
}
ath9k_htc_init_btcoex(priv, product);
return 0;

View File

@ -957,12 +957,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
mod_timer(&priv->tx.cleanup_timer,
jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
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);
}
ath9k_htc_start_btcoex(priv);
mutex_unlock(&priv->mutex);
return ret;
@ -1009,12 +1005,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex);
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);
}
ath9k_htc_stop_btcoex(priv);
/* Remove a monitor interface if it's present. */
if (priv->ah->is_monitoring)

View File

@ -23,6 +23,7 @@
#include "hw-ops.h"
#include "rc.h"
#include "ar9003_mac.h"
#include "ar9003_mci.h"
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
@ -1518,61 +1519,22 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata, bool bChannelChange)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
u32 saveLedState;
struct ath9k_channel *curchan = ah->curchan;
u32 saveDefAntenna;
u32 macStaId1;
u64 tsf = 0;
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 save_fullsleep = ah->chip_fullsleep;
if (mci) {
ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
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;
}
start_mci_reset = ar9003_mci_start_reset(ah, chan);
if (start_mci_reset)
return 0;
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
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)) {
ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah, true);
if (mci && mci_hw->ready)
if (mci && ar9003_mci_is_ready(ah))
ar9003_mci_2g5g_switch(ah, true);
if (AR_SREV_9271(ah))
@ -1618,19 +1580,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
}
}
if (mci) {
ar9003_mci_disable_interrupt(ah);
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;
}
if (mci)
ar9003_mci_stop_bt(ah, save_fullsleep);
saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
if (saveDefAntenna == 0)
@ -1807,53 +1758,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_loadnf(ah, chan);
ath9k_hw_start_nfcal(ah, true);
if (mci && mci_hw->ready) {
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;
}
}
ar9003_mci_enable_interrupt(ah);
}
if (mci && ar9003_mci_end_reset(ah, chan, caldata))
return -EIO;
ENABLE_REGWRITE_BUFFER(ah);
@ -1894,24 +1800,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
#endif
}
if (ah->btcoex_hw.enabled &&
ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
if (ath9k_hw_btcoex_is_enabled(ah))
ath9k_hw_btcoex_enable(ah);
if (mci && mci_hw->ready) {
/*
* 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 (mci)
ar9003_mci_check_bt(ah);
if (AR_SREV_9300_20_OR_LATER(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);
/* Shutdown chip. Active low */
if (!AR_SREV_5416(ah) &&
!AR_SREV_9271(ah) && !AR_SREV_9462_10(ah)) {
if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) {
REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
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)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
int status = true, setChip = true;
static const char *modes[] = {
"AWAKE",
@ -2100,20 +1991,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
break;
case ATH9K_PM_FULL_SLEEP:
if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
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);
}
if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
ar9003_mci_set_full_sleep(ah);
ath9k_set_power_sleep(ah, setChip);
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 ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath_common *common = ath9k_hw_common(ah);
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
unsigned int chip_chainmask;
u16 eeval;
@ -2422,30 +2300,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
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)) {
pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
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_APM = BIT(13),
ATH9K_HW_CAP_RTT = BIT(14),
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
ATH9K_HW_CAP_MCI = BIT(15),
#else
ATH9K_HW_CAP_MCI = 0,
#endif
ATH9K_HW_CAP_DFS = BIT(16),
};
@ -432,161 +428,6 @@ enum ath9k_rx_qtype {
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 {
u32 bs_nexttbtt;
u32 bs_nextdtim;
@ -956,8 +797,9 @@ struct ath_hw {
int firpwr[5];
enum ath9k_ani_cmd ani_function;
/* Bluetooth coexistance */
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
struct ath_btcoex_hw btcoex_hw;
#endif
u32 intr_txqs;
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_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
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
ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
{
return ah->btcoex_hw.scheme;
}
#else
#define ath9k_hw_get_btcoex_scheme(...) ATH_BTCOEX_CFG_NONE
#endif
static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
{
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_5GHZ_OFDM 40

View File

@ -419,66 +419,6 @@ fail:
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)
{
int i = 0;
@ -880,12 +820,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
if (sc->sbands[IEEE80211_BAND_5GHZ].channels)
kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
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);
ath9k_deinit_btcoex(sc);
for (i = 0; i < ATH9K_NUM_TX_QUEUES; 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)
return -EIO;
ath9k_ps_wakeup(sc);
r = ath_reset_internal(sc, hchan, false);
ath9k_ps_restore(sc);
return r;
}
@ -739,12 +735,7 @@ void ath9k_tasklet(unsigned long data)
ath_tx_tasklet(sc);
}
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) && ATH9K_HW_CAP_MCI)
ath_mci_intr(sc);
ath9k_btcoex_handle_interrupt(sc, status);
out:
/* re-enable hardware interrupt */
@ -1079,16 +1070,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
spin_unlock_bh(&sc->sc_pcu_lock);
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);
}
ath9k_start_btcoex(sc);
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
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. */
ath9k_ps_wakeup(sc);
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);
}
ath9k_stop_btcoex(sc);
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);
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) {
sc->ps_idle = !!(conf->flags & IEEE80211_CONF_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;
if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) &&
(info->type == MCI_GPM_COEX_PROFILE_VOICE)) {
ath_dbg(common, MCI,
"Too many SCO profile, failed to add new profile\n");
(info->type == MCI_GPM_COEX_PROFILE_VOICE))
return false;
}
if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) &&
(info->type != MCI_GPM_COEX_PROFILE_VOICE)) {
ath_dbg(common, MCI,
"Too many ACL profile, failed to add new profile\n");
(info->type != MCI_GPM_COEX_PROFILE_VOICE))
return false;
}
entry = ath_mci_find_profile(mci, info);
if (entry)
if (entry) {
memcpy(entry, info, 10);
else {
} else {
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return false;
@ -68,6 +62,7 @@ static bool ath_mci_add_profile(struct ath_common *common,
INC_PROF(mci, info);
list_add_tail(&info->list, &mci->info);
}
return true;
}
@ -79,10 +74,9 @@ static void ath_mci_del_profile(struct ath_common *common,
entry = ath_mci_find_profile(mci, info);
if (!entry) {
ath_dbg(common, MCI, "Profile to be deleted not found\n");
if (!entry)
return;
}
DEC_PROF(mci, entry);
list_del(&entry->list);
kfree(entry);
@ -177,13 +171,12 @@ static void ath_mci_update_scheme(struct ath_softc *sc)
btcoex->btcoex_period *= 1000;
btcoex->btcoex_no_stomp = btcoex->btcoex_period *
(100 - btcoex->duty_cycle) / 100;
(100 - btcoex->duty_cycle) / 100;
ath9k_hw_btcoex_enable(sc->sc_ah);
ath9k_btcoex_timer_resume(sc);
}
static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
{
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) {
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) {
ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL);
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
} else
ath_dbg(common, MCI, "MCI State mismatches: %d\n",
} else {
ath_dbg(common, MCI, "MCI State mismatch: %d\n",
ar9003_mci_state(ah, MCI_STATE_BT, NULL));
}
break;
case MCI_GPM_BT_CAL_DONE:
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");
ar9003_mci_state(ah, MCI_STATE_BT, NULL);
break;
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);
ar9003_mci_send_message(sc->sc_ah, MCI_GPM, 0, payload,
16, false, true);
break;
default:
ath_dbg(common, MCI, "MCI Unknown GPM CAL message\n");
ath_dbg(common, MCI, "Unknown GPM CAL message\n");
break;
}
}
@ -247,6 +222,7 @@ static void ath_mci_process_profile(struct ath_softc *sc,
btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD;
mci->aggr_limit = mci->num_sco ? 6 : 0;
if (NUM_PROF(mci)) {
btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
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,
struct ath_mci_profile_status *status)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_mci_profile *mci = &btcoex->mci;
struct ath_mci_profile_info info;
int i = 0, old_num_mgmt = mci->num_mgmt;
/* Link status type are not handled */
if (status->is_link) {
ath_dbg(common, MCI, "Skip link type status update\n");
if (status->is_link)
return;
}
memset(&info, 0, sizeof(struct ath_mci_profile_info));
info.conn_handle = status->conn_handle;
if (ath_mci_find_profile(mci, &info)) {
ath_dbg(common, MCI,
"Skip non link state update for existing profile %d\n",
status->conn_handle);
if (ath_mci_find_profile(mci, &info))
return;
}
if (status->conn_handle >= ATH_MCI_MAX_PROFILE) {
ath_dbg(common, MCI, "Ignore too many non-link update\n");
if (status->conn_handle >= ATH_MCI_MAX_PROFILE)
return;
}
if (status->is_critical)
__set_bit(status->conn_handle, mci->status);
else
@ -314,43 +283,28 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
u32 seq_num;
switch (opcode) {
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, NULL);
version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION,
NULL);
break;
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);
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 = ar9003_mci_state(ah,
MCI_STATE_SET_BT_COEX_VERSION, &version);
version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION,
&version);
break;
case MCI_GPM_COEX_STATUS_QUERY:
ath_dbg(common, MCI,
"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);
ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL);
break;
case MCI_GPM_COEX_BT_PROFILE_INFO:
ath_dbg(common, MCI, "MCI Recv GPM Coex BT profile info\n");
memcpy(&profile_info,
(rx_payload + MCI_GPM_COEX_B_PROFILE_TYPE), 10);
if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN)
|| (profile_info.type >=
MCI_GPM_COEX_PROFILE_MAX)) {
if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN) ||
(profile_info.type >= MCI_GPM_COEX_PROFILE_MAX)) {
ath_dbg(common, MCI,
"illegal profile type = %d, state = %d\n",
"Illegal profile type = %d, state = %d\n",
profile_info.type,
profile_info.start);
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);
break;
case MCI_GPM_COEX_BT_STATUS_UPDATE:
profile_status.is_link = *(rx_payload +
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));
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_critical, seq_num);
ath_mci_process_status(sc, &profile_status);
break;
default:
ath_dbg(common, MCI, "MCI Unknown GPM COEX message = 0x%02x\n",
opcode);
ath_dbg(common, MCI, "Unknown GPM COEX message = 0x%02x\n", opcode);
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)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_mci_coex *mci = &sc->mci_coex;
int error = 0;
struct ath_mci_buf *buf = &mci->sched_buf;
if (!ATH9K_HW_CAP_MCI)
return 0;
buf->bf_addr = dma_alloc_coherent(sc->dev,
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 (ath_mci_buf_alloc(sc, &mci->sched_buf)) {
if (buf->bf_addr == NULL) {
ath_dbg(common, FATAL, "MCI buffer alloc failed\n");
error = -ENOMEM;
goto fail;
return -ENOMEM;
}
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;
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_addr = (u8 *)mci->sched_buf.bf_addr +
mci->sched_buf.bf_len;
mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + 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,
mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4),
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)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_hw *ah = sc->sc_ah;
struct ath_mci_coex *mci = &sc->mci_coex;
struct ath_mci_buf *buf = &mci->sched_buf;
if (!ATH9K_HW_CAP_MCI)
return;
if (buf->bf_addr)
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);
ath_dbg(common, MCI, "MCI De-Initialized\n");
}
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;
bool skip_gpm = false;
if (!ATH9K_HW_CAP_MCI)
return;
ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) {
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);
ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL);
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
* 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,
payload, 16, true, false);
ath_dbg(common, MCI, "MCI interrupt send SYS_WAKING\n");
ar9003_mci_send_message(ah, MCI_SYS_WAKING, 0,
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
*/
ath_dbg(common, MCI, "MCI Set BT state to AWAKE\n");
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) {
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_REMOTE_SLEEP, NULL)
== MCI_BT_SLEEP)
ath_dbg(common, MCI,
"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 (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) !=
MCI_BT_SLEEP)
ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE,
NULL);
}
}
if (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_REMOTE_SLEEP, NULL)
== 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");
if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) !=
MCI_BT_AWAKE)
ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP,
NULL);
}
} else
ath_dbg(common, MCI, "MCI BT stays in SLEEP mode\n");
}
}
if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) ||
(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);
skip_gpm = true;
}
if (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,
NULL);
}
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) {
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM;
while (more_data == MCI_GPM_MORE) {
pgpm = mci->gpm_buf.bf_addr;
offset = ar9003_mci_state(ah,
MCI_STATE_NEXT_GPM_OFFSET, &more_data);
offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET,
&more_data);
if (offset == MCI_GPM_INVALID)
break;
@ -591,44 +477,38 @@ void ath_mci_intr(struct ath_softc *sc)
* The first dword is timer.
* The real data starts from 2nd dword.
*/
subtype = MCI_GPM_TYPE(pgpm);
opcode = MCI_GPM_OPCODE(pgpm);
if (!skip_gpm) {
if (skip_gpm)
goto recycle;
if (MCI_GPM_IS_CAL_TYPE(subtype))
ath_mci_cal_msg(sc, subtype,
(u8 *) pgpm);
else {
switch (subtype) {
case MCI_GPM_COEX_AGENT:
ath_mci_msg(sc, opcode,
(u8 *) pgpm);
break;
default:
break;
}
if (MCI_GPM_IS_CAL_TYPE(subtype)) {
ath_mci_cal_msg(sc, subtype, (u8 *)pgpm);
} else {
switch (subtype) {
case MCI_GPM_COEX_AGENT:
ath_mci_msg(sc, opcode, (u8 *)pgpm);
break;
default:
break;
}
}
recycle:
MCI_GPM_RECYCLE(pgpm);
}
}
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_HW_MSG_MASK) {
if (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;
ath_dbg(common, MCI, "MCI LNA_INFO\n");
}
if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) {
int value_dbm = ar9003_mci_state(ah,
MCI_STATE_CONT_RSSI_POWER, NULL);
MCI_STATE_CONT_RSSI_POWER, NULL);
mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO;
@ -636,33 +516,25 @@ void ath_mci_intr(struct ath_softc *sc)
ath_dbg(common, MCI,
"MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n",
ar9003_mci_state(ah,
MCI_STATE_CONT_PRIORITY, NULL),
MCI_STATE_CONT_PRIORITY, NULL),
value_dbm);
else
ath_dbg(common, MCI,
"MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n",
ar9003_mci_state(ah,
MCI_STATE_CONT_PRIORITY, NULL),
MCI_STATE_CONT_PRIORITY, NULL),
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;
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;
ath_dbg(common, MCI, "MCI CONT_RST\n");
}
}
if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) ||
(mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT))
mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR |
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
#define MCI_H
#include "ar9003_mci.h"
#define ATH_MCI_SCHED_BUF_SIZE (16 * 16) /* 16 entries, 4 dword each */
#define 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;
};
struct ath_mci_buf {
void *bf_addr; /* virtual addr of desc */
dma_addr_t bf_paddr; /* physical addr of buffer */
@ -121,10 +122,8 @@ struct ath_mci_buf {
};
struct ath_mci_coex {
atomic_t mci_cal_flag;
struct ath_mci_buf sched_buf;
struct ath_mci_buf gpm_buf;
u32 bt_cal_start;
};
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,
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;
/* 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_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;
/* Initial rate table size. Will change depending

View File

@ -797,7 +797,6 @@
#define AR_SREV_VERSION_9580 0x1C0
#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
#define AR_SREV_VERSION_9462 0x280
#define AR_SREV_REVISION_9462_10 0
#define AR_SREV_REVISION_9462_20 2
#define AR_SREV_5416(_ah) \
@ -898,10 +897,6 @@
#define AR_SREV_9462(_ah) \
(((_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) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
((_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 ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates;
struct ath_mci_profile *mci = &sc->btcoex.mci;
u32 max_4ms_framelen, frmlen;
u16 aggr_limit, legacy = 0;
u16 aggr_limit, bt_aggr_limit, legacy = 0;
int i;
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)
return 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);
else
aggr_limit = min(max_4ms_framelen,
(u32)ATH_AMPDU_LIMIT_MAX);
aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_MAX);
/*
* Override the default aggregation limit for BTCOEX.
*/
bt_aggr_limit = ath9k_btcoex_aggr_limit(sc, max_4ms_framelen);
if (bt_aggr_limit)
aggr_limit = bt_aggr_limit;
/*
* 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 carl9170_sta_info *sta_info;
struct ieee80211_tx_info *tx_info;
rcu_read_lock();
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;
sta_info = (void *) sta->drv_priv;
if (unlikely(sta_info->sleeping)) {
struct ieee80211_tx_info *tx_info;
tx_info = IEEE80211_SKB_CB(skb);
if (unlikely(sta_info->sleeping) &&
!(tx_info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
IEEE80211_TX_CTL_CLEAR_PS_FILT))) {
rcu_read_unlock();
tx_info = IEEE80211_SKB_CB(skb);
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
atomic_dec(&ar->tx_ampdu_upload);
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
carl9170_release_dev_space(ar, skb);
carl9170_tx_status(ar, skb, false);
return true;
}

View File

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

View File

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

View File

@ -294,13 +294,14 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
struct sk_buff *pkt)
{
int status;
uint pkt_len = pkt->len;
uint pkt_len;
bool fifo = (fix_inc == SDIOH_DATA_FIX);
brcmf_dbg(TRACE, "Enter\n");
if (pkt == NULL)
return -EINVAL;
pkt_len = pkt->len;
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
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[1] = func;
sdiodev->bus_if = bus_if;
bus_if->bus_priv = sdiodev;
bus_if->bus_priv.sdio = sdiodev;
bus_if->type = SDIO_BUS;
bus_if->align = BRCMF_SDALIGN;
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) {
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_sdio_remove(sdiodev);
dev_set_drvdata(&func->card->dev, NULL);
@ -596,14 +597,14 @@ static struct sdio_driver brcmf_sdmmc_driver = {
#endif /* CONFIG_PM_SLEEP */
};
static void __exit brcmf_sdio_exit(void)
void brcmf_sdio_exit(void)
{
brcmf_dbg(TRACE, "Enter\n");
sdio_unregister_driver(&brcmf_sdmmc_driver);
}
static int __init brcmf_sdio_init(void)
int brcmf_sdio_init(void)
{
int ret;
@ -616,6 +617,3 @@ static int __init brcmf_sdio_init(void)
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 */
struct brcmf_bus {
u8 type; /* bus type */
void *bus_priv; /* pointer to bus private structure */
void *drvr; /* pointer to driver pub structure brcmf_pub */
union {
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;
uint maxctl; /* Max size rxctl request from proto to bus */
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,
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_ */

View File

@ -796,18 +796,19 @@ static int brcmf_netdev_open(struct net_device *ndev)
{
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_bus *bus_if = drvr->bus_if;
u32 toe_ol;
s32 ret = 0;
brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);
if (ifp->idx == 0) { /* do it only for primary eth0 */
/* try to bring up bus */
ret = brcmf_bus_start(drvr->dev);
if (ret != 0) {
brcmf_dbg(ERROR, "failed with code %d\n", ret);
return -1;
/* If bus is not ready, can't continue */
if (bus_if->state != BRCMF_BUS_DATA) {
brcmf_dbg(ERROR, "failed bus is not ready\n");
return -EAGAIN;
}
atomic_set(&drvr->pend_8021x_cnt, 0);
memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);
@ -979,12 +980,6 @@ int brcmf_bus_start(struct device *dev)
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,
iovbuf, sizeof(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)
return ret;
/* signal bus ready */
bus_if->state = BRCMF_BUS_DATA;
return 0;
}
@ -1109,13 +1106,13 @@ void brcmf_detach(struct device *dev)
if (drvr->iflist[i])
brcmf_del_if(drvr, i);
cancel_work_sync(&drvr->setmacaddr_work);
cancel_work_sync(&drvr->multicast_work);
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);
}
bus_if->drvr = NULL;
kfree(drvr);
@ -1183,3 +1180,35 @@ exit:
return ret;
}
#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 */
#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
#define BRCMFMAC_FW_NAME "brcm/brcmfmac.bin"
#define BRCMFMAC_NV_NAME "brcm/brcmfmac.txt"
MODULE_FIRMWARE(BRCMFMAC_FW_NAME);
MODULE_FIRMWARE(BRCMFMAC_NV_NAME);
#define BRCMF_SDIO_FW_NAME "brcm/brcmfmac-sdio.bin"
#define BRCMF_SDIO_NV_NAME "brcm/brcmfmac-sdio.txt"
MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
#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;
int err;
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;
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;
uint datalen, prec;
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;
brcmf_dbg(TRACE, "Enter\n");
@ -2867,7 +2867,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
u8 doff = 0;
int ret = -1;
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;
brcmf_dbg(TRACE, "Enter\n");
@ -2976,7 +2976,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
uint rxlen = 0;
bool pending;
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;
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");
ret = request_firmware(&bus->firmware, BRCMFMAC_FW_NAME,
ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME,
&bus->sdiodev->func[2]->dev);
if (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;
int ret;
ret = request_firmware(&bus->firmware, BRCMFMAC_NV_NAME,
ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
&bus->sdiodev->func[2]->dev);
if (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)
{
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;
unsigned long timeout;
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,
SBSDIO_WATERMARK, 8, &err);
/* Set bus state according to enable result */
bus_if->state = BRCMF_BUS_DATA;
}
else {
} else {
/* Disable F2 again */
enable = SDIO_FUNC_ENABLE_1;
brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0,
SDIO_CCCR_IOEx, enable, NULL);
ret = -ENODEV;
}
/* Restore previous clock setting */
@ -3479,7 +3475,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
/* 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);
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));
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(&ssid.SSID, sme->ssid, 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
@ -3306,17 +3308,18 @@ brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
{
struct brcmf_cfg80211_event_q *e;
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)
return -ENOMEM;
e->etype = event;
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);
spin_unlock_irq(&cfg_priv->evt_q_lock);
spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
return err;
}

View File

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

View File

@ -2901,7 +2901,6 @@ brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel)
objoff += 2;
return bcma_read16(core, objoff);
;
}
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) {
idle_tssi[0] = pi->nphy_pwrctrl_info[0].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[1] = -424;
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:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].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[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1;
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:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].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[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1;
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:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].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[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1;
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:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].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[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1;
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:
idle_tssi[0] = pi->nphy_pwrctrl_info[0].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[1] = -424;
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[1] = (s8) pi->tx_power_max;
@ -19989,12 +19970,11 @@ static void wlc_phy_radio_init_2057(struct brcms_phy *pi)
switch (pi->pubpi.radiorev) {
case 5:
if (pi->pubpi.radiover == 0x0)
if (NREV_IS(pi->pubpi.phy_rev, 8))
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;
else
break;
break;
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.
*/
static void
static int
_initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
{
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 */
entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->varid = BRCMS_SROM_REV;
entry->var_type = BRCMS_SROM_UNUMBER;
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) +
extra_space, GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->varid = id;
entry->var_type = type;
if (flags & SRFL_ETHADDR) {
@ -754,6 +759,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
entry =
kzalloc(sizeof(struct brcms_srom_list_head),
GFP_KERNEL);
if (!entry)
return -ENOMEM;
entry->varid = srv->varid+p;
entry->var_type = BRCMS_SROM_UNUMBER;
entry->uval = val;
@ -761,6 +768,7 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
}
pb += psz;
}
return 0;
}
/*
@ -906,7 +914,9 @@ int srom_var_init(struct si_pub *sih)
INIT_LIST_HEAD(&sii->var_list);
/* 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:

View File

@ -309,13 +309,6 @@ static const long 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[] = {
{ .bitrate = 10 },
{ .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 },
};
#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 */
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;
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;
@ -8105,61 +8098,41 @@ static int ipw2100_wx_get_crc_check(struct net_device *dev,
#endif /* CONFIG_IPW2100_MONITOR */
static iw_handler ipw2100_wx_handlers[] = {
NULL, /* SIOCSIWCOMMIT */
ipw2100_wx_get_name, /* SIOCGIWNAME */
NULL, /* SIOCSIWNWID */
NULL, /* SIOCGIWNWID */
ipw2100_wx_set_freq, /* SIOCSIWFREQ */
ipw2100_wx_get_freq, /* SIOCGIWFREQ */
ipw2100_wx_set_mode, /* SIOCSIWMODE */
ipw2100_wx_get_mode, /* SIOCGIWMODE */
NULL, /* SIOCSIWSENS */
NULL, /* SIOCGIWSENS */
NULL, /* SIOCSIWRANGE */
ipw2100_wx_get_range, /* SIOCGIWRANGE */
NULL, /* SIOCSIWPRIV */
NULL, /* SIOCGIWPRIV */
NULL, /* SIOCSIWSTATS */
NULL, /* SIOCGIWSTATS */
NULL, /* SIOCSIWSPY */
NULL, /* SIOCGIWSPY */
NULL, /* SIOCGIWTHRSPY */
NULL, /* SIOCWIWTHRSPY */
ipw2100_wx_set_wap, /* SIOCSIWAP */
ipw2100_wx_get_wap, /* SIOCGIWAP */
ipw2100_wx_set_mlme, /* SIOCSIWMLME */
NULL, /* SIOCGIWAPLIST -- deprecated */
ipw2100_wx_set_scan, /* SIOCSIWSCAN */
ipw2100_wx_get_scan, /* SIOCGIWSCAN */
ipw2100_wx_set_essid, /* SIOCSIWESSID */
ipw2100_wx_get_essid, /* SIOCGIWESSID */
ipw2100_wx_set_nick, /* SIOCSIWNICKN */
ipw2100_wx_get_nick, /* SIOCGIWNICKN */
NULL, /* -- hole -- */
NULL, /* -- hole -- */
ipw2100_wx_set_rate, /* SIOCSIWRATE */
ipw2100_wx_get_rate, /* SIOCGIWRATE */
ipw2100_wx_set_rts, /* SIOCSIWRTS */
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 */
IW_HANDLER(SIOCGIWNAME, ipw2100_wx_get_name),
IW_HANDLER(SIOCSIWFREQ, ipw2100_wx_set_freq),
IW_HANDLER(SIOCGIWFREQ, ipw2100_wx_get_freq),
IW_HANDLER(SIOCSIWMODE, ipw2100_wx_set_mode),
IW_HANDLER(SIOCGIWMODE, ipw2100_wx_get_mode),
IW_HANDLER(SIOCGIWRANGE, ipw2100_wx_get_range),
IW_HANDLER(SIOCSIWAP, ipw2100_wx_set_wap),
IW_HANDLER(SIOCGIWAP, ipw2100_wx_get_wap),
IW_HANDLER(SIOCSIWMLME, ipw2100_wx_set_mlme),
IW_HANDLER(SIOCSIWSCAN, ipw2100_wx_set_scan),
IW_HANDLER(SIOCGIWSCAN, ipw2100_wx_get_scan),
IW_HANDLER(SIOCSIWESSID, ipw2100_wx_set_essid),
IW_HANDLER(SIOCGIWESSID, ipw2100_wx_get_essid),
IW_HANDLER(SIOCSIWNICKN, ipw2100_wx_set_nick),
IW_HANDLER(SIOCGIWNICKN, ipw2100_wx_get_nick),
IW_HANDLER(SIOCSIWRATE, ipw2100_wx_set_rate),
IW_HANDLER(SIOCGIWRATE, ipw2100_wx_get_rate),
IW_HANDLER(SIOCSIWRTS, ipw2100_wx_set_rts),
IW_HANDLER(SIOCGIWRTS, ipw2100_wx_get_rts),
IW_HANDLER(SIOCSIWFRAG, ipw2100_wx_set_frag),
IW_HANDLER(SIOCGIWFRAG, ipw2100_wx_get_frag),
IW_HANDLER(SIOCSIWTXPOW, ipw2100_wx_set_txpow),
IW_HANDLER(SIOCGIWTXPOW, ipw2100_wx_get_txpow),
IW_HANDLER(SIOCSIWRETRY, ipw2100_wx_set_retry),
IW_HANDLER(SIOCGIWRETRY, ipw2100_wx_get_retry),
IW_HANDLER(SIOCSIWENCODE, ipw2100_wx_set_encode),
IW_HANDLER(SIOCGIWENCODE, ipw2100_wx_get_encode),
IW_HANDLER(SIOCSIWPOWER, ipw2100_wx_set_power),
IW_HANDLER(SIOCGIWPOWER, ipw2100_wx_get_power),
IW_HANDLER(SIOCSIWGENIE, ipw2100_wx_set_genie),
IW_HANDLER(SIOCGIWGENIE, ipw2100_wx_get_genie),
IW_HANDLER(SIOCSIWAUTH, ipw2100_wx_set_auth),
IW_HANDLER(SIOCGIWAUTH, ipw2100_wx_get_auth),
IW_HANDLER(SIOCSIWENCODEEXT, ipw2100_wx_set_encodeext),
IW_HANDLER(SIOCGIWENCODEEXT, ipw2100_wx_get_encodeext),
};
#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);
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;
tx_cmd->len = cpu_to_le16(len);
il_dbg_log_tx_data_frame(il, len, hdr);
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_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
* 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,
* if any (802.11 null frames have no payload). */
@ -625,8 +624,8 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
phys_addr =
pci_map_single(il->pci_dev, skb->data + hdr_len, len,
PCI_DMA_TODEVICE);
il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
U32_PAD(len));
il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
U32_PAD(len));
}
/* Tell device the write idx *just past* this latest filled TFD */
@ -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);
if (flags & HW_CARD_DISABLED)
set_bit(S_RF_KILL_HW, &il->status);
set_bit(S_RFKILL, &il->status);
else
clear_bit(S_RF_KILL_HW, &il->status);
clear_bit(S_RFKILL, &il->status);
il_scan_cancel(il);
if ((test_bit(S_RF_KILL_HW, &status) !=
test_bit(S_RF_KILL_HW, &il->status)))
if ((test_bit(S_RFKILL, &status) !=
test_bit(S_RFKILL, &il->status)))
wiphy_rfkill_set_hw_state(il->hw->wiphy,
test_bit(S_RF_KILL_HW, &il->status));
test_bit(S_RFKILL, &il->status));
else
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);
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
* sensor in adapter to kick in */
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",
thermal_spin * 10);
} 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 */
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 */
if (!il_is_init(il)) {
il->status =
test_bit(S_RF_KILL_HW,
&il->
status) << S_RF_KILL_HW |
test_bit(S_GEO_CONFIGURED,
&il->
status) << S_GEO_CONFIGURED |
test_bit(S_RFKILL, &il->status) << S_RFKILL |
test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
goto exit;
}
@ -2286,25 +2281,30 @@ __il3945_down(struct il_priv *il)
/* ...otherwise clear out all the status bits but the RF Kill
* bit and continue taking the NIC down. */
il->status &=
test_bit(S_RF_KILL_HW,
&il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED,
&il->
status) <<
S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
&il->
status) << S_FW_ERROR |
test_bit(S_RFKILL, &il->status) << S_RFKILL |
test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
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_rxq_stop(il);
/* 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);
/* 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:
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 (_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 {
set_bit(S_RF_KILL_HW, &il->status);
set_bit(S_RFKILL, &il->status);
IL_WARN("Radio disabled by HW RF Kill switch\n");
return -ENODEV;
}
@ -2405,7 +2405,7 @@ __il3945_up(struct il_priv *il)
il->ucode_data.len);
/* 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;
for (i = 0; i < MAX_HW_RESTARTS; i++) {
@ -2413,7 +2413,7 @@ __il3945_up(struct il_priv *il)
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
rc = il->ops->lib->load_ucode(il);
rc = il->ops->load_ucode(il);
if (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 =
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 =
!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
if (new_rfkill != old_rfkill) {
if (new_rfkill)
set_bit(S_RF_KILL_HW, &il->status);
set_bit(S_RFKILL, &il->status);
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);
@ -2782,10 +2782,9 @@ il3945_mac_start(struct ieee80211_hw *hw)
struct il_priv *il = hw->priv;
int ret;
D_MAC80211("enter\n");
/* we should be verifying the device is ready to be opened */
mutex_lock(&il->mutex);
D_MAC80211("enter\n");
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
@ -2941,15 +2940,19 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
* hardware will then not attempt to decrypt the frames.
*/
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;
}
static_key = !il_is_associated(il);
if (!static_key) {
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;
}
}
mutex_lock(&il->mutex);
@ -2974,8 +2977,8 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = -EINVAL;
}
D_MAC80211("leave ret %d\n", ret);
mutex_unlock(&il->mutex);
D_MAC80211("leave\n");
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;
u8 sta_id;
D_INFO("received request to add station %pM\n", sta->addr);
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;
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);
if (ret)
IL_INFO("%s is not in hex or decimal form.\n", buf);
else {
else
il->debug_level = val;
if (il_alloc_traffic_mem(il))
IL_ERR("Not enough memory to generate traffic log\n");
}
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");
il->cfg = cfg;
il->ops = &il3945_ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
il->debugfs_ops = &il3945_debugfs_ops;
#endif
il->pci_dev = pdev;
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
* *************************/
@ -3655,7 +3655,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/***********************
* 3. Read REV Register
* ********************/
il->hw_base = pci_iomap(pdev, 0, 0);
il->hw_base = pci_ioremap_bar(pdev, 0);
if (!il->hw_base) {
err = -ENODEV;
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_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
*/
spin_lock_init(&il->reg_lock);
@ -3780,14 +3780,13 @@ out_unset_hw_params:
out_eeprom_free:
il_eeprom_free(il);
out_iounmap:
pci_iounmap(pdev, il->hw_base);
iounmap(il->hw_base);
out_pci_release_regions:
pci_release_regions(pdev);
out_pci_disable_device:
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
out_ieee80211_free_hw:
il_free_traffic_mem(il);
ieee80211_free_hw(il->hw);
out:
return err;
@ -3855,12 +3854,11 @@ il3945_pci_remove(struct pci_dev *pdev)
* until now... */
destroy_workqueue(il->workqueue);
il->workqueue = NULL;
il_free_traffic_mem(il);
free_irq(pdev->irq, il);
pci_disable_msi(pdev);
pci_iounmap(pdev, il->hw_base);
iounmap(il->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
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);
}
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) \
[RATE_##r##M_IDX] = { RATE_##r##M_PLCP, \
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];
ieee80211_tx_status_irqsafe(il->hw, skb);
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 &&
@ -577,8 +573,6 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel),
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) {
il->_3945.last_beacon_time =
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
il3945_tx_reset(struct il_priv *il)
{
/* bypass mode */
il_wr_prph(il, ALM_SCD_MODE_REG, 0x2);
@ -833,8 +826,7 @@ il3945_tx_reset(struct il_priv *il)
static int
il3945_txq_ctx_reset(struct il_priv *il)
{
int rc;
int txq_id, slots_num;
int rc, txq_id;
il3945_hw_txq_ctx_free(il);
@ -850,10 +842,7 @@ il3945_txq_ctx_reset(struct il_priv *il)
/* Tx queue(s) */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
slots_num =
(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);
rc = il_tx_queue_init(il, txq_id);
if (rc) {
IL_ERR("Tx %d queue init failed\n", txq_id);
goto error;
@ -958,12 +947,11 @@ il3945_hw_nic_init(struct il_priv *il)
struct il_rx_queue *rxq = &il->rxq;
spin_lock_irqsave(&il->lock, flags);
il->ops->lib->apm_ops.init(il);
il3945_apm_init(il);
spin_unlock_irqrestore(&il->lock, flags);
il3945_set_pwr_vmain(il);
il->ops->lib->apm_ops.config(il);
il3945_nic_config(il);
/* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) {
@ -1014,7 +1002,7 @@ il3945_hw_txq_ctx_free(struct il_priv *il)
il_tx_queue_free(il, txq_id);
/* free tx queue structure */
il_txq_mem(il);
il_free_txq_mem(il);
}
void
@ -1023,18 +1011,17 @@ il3945_hw_txq_ctx_stop(struct il_priv *il)
int txq_id;
/* stop SCD */
il_wr_prph(il, ALM_SCD_MODE_REG, 0);
il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
_il_wr_prph(il, ALM_SCD_MODE_REG, 0);
_il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
/* reset TFD queues */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
il_poll_bit(il, FH39_TSSR_TX_STATUS,
FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1000);
_il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
_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),
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 */
return il->ops->lib->send_tx_power(il);
return il->ops->send_tx_power(il);
}
int
@ -2183,12 +2170,14 @@ il3945_txpower_set_from_eeprom(struct il_priv *il)
int
il3945_hw_rxq_stop(struct il_priv *il)
{
int rc;
int ret;
il_wr(il, FH39_RCSR_CONFIG(0), 0);
rc = il_poll_bit(il, FH39_RSSR_STATUS,
FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
if (rc < 0)
_il_wr(il, FH39_RCSR_CONFIG(0), 0);
ret = _il_poll_bit(il, FH39_RSSR_STATUS,
FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
1000);
if (ret < 0)
IL_ERR("Can't stop Rx DMA.\n");
return 0;
@ -2630,65 +2619,31 @@ il3945_load_bsm(struct il_priv *il)
return 0;
}
static struct il_hcmd_ops il3945_hcmd = {
.rxon_assoc = il3945_send_rxon_assoc,
.commit_rxon = il3945_commit_rxon,
};
static struct il_lib_ops il3945_lib = {
const struct il_ops il3945_ops = {
.txq_attach_buf_to_tfd = il3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = il3945_hw_txq_free_tfd,
.txq_init = il3945_hw_tx_queue_init,
.load_ucode = il3945_load_bsm,
.dump_nic_error_log = il3945_dump_nic_error_log,
.apm_ops = {
.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,
},
.apm_init = il3945_apm_init,
.send_tx_power = il3945_send_tx_power,
.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
.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,
},
#endif
};
.rxon_assoc = il3945_send_rxon_assoc,
.commit_rxon = il3945_commit_rxon,
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,
.build_addsta_hcmd = il3945_build_addsta_hcmd,
.request_scan = il3945_request_scan,
.post_scan = il3945_post_scan,
};
const struct il_ops il3945_ops = {
.lib = &il3945_lib,
.hcmd = &il3945_hcmd,
.utils = &il3945_hcmd_utils,
.led = &il3945_led_ops,
.legacy = &il3945_legacy_ops,
.post_associate = il3945_post_associate,
.config_ap = il3945_config_ap,
.manage_ibss_station = il3945_manage_ibss_station,
.send_led_cmd = il3945_send_led_cmd,
};
static struct il_cfg il3945_bg_cfg = {
@ -2707,7 +2662,17 @@ static struct il_cfg il3945_bg_cfg = {
.set_l0s = false,
.use_bsm = true,
.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 = {
@ -2726,7 +2691,17 @@ static struct il_cfg il3945_abg_cfg = {
.set_l0s = false,
.use_bsm = true,
.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) = {

View File

@ -595,13 +595,7 @@ struct il3945_tfd {
} __packed;
#ifdef CONFIG_IWLEGACY_DEBUGFS
ssize_t il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
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);
extern const struct il_debugfs_ops il3945_debugfs_ops;
#endif
#endif

View File

@ -79,18 +79,6 @@ struct stats_general_data {
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
*****************************************************************************/
@ -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.
* Update and commit the RXON
*/
if (il->ops->lib->update_chain_flags)
il->ops->lib->update_chain_flags(il);
if (il->ops->update_chain_flags)
il->ops->update_chain_flags(il);
data->state = IL_CHAIN_NOISE_DONE;
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);
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;
int ret;
/* nic_init */
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) */
il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF);
spin_unlock_irqrestore(&il->lock, flags);
il4965_set_pwr_vmain(il);
il->ops->lib->apm_ops.config(il);
il4965_nic_config(il);
/* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) {
@ -445,11 +441,15 @@ il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq)
int
il4965_rxq_stop(struct il_priv *il)
{
int ret;
/* stop Rx DMA */
il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
_il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
ret = _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);
if (ret < 0)
IL_ERR("Can't stop Rx DMA.\n");
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 */
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,
(unsigned long long)rx_status.mactime);
@ -1343,12 +1342,11 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats)
}
#endif
#define REG_RECALIB_PERIOD (60)
void
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);
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);
/* Reschedule the stats timer to occur in
* REG_RECALIB_PERIOD seconds to ensure we get a
* thermal update even if the uCode doesn't give
* us one */
/*
* Reschedule the stats timer to occur in recalib_seconds to ensure
* we get a thermal update even if the uCode doesn't give us one
*/
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)) &&
(pkt->hdr.cmd == N_STATS)) {
il4965_rx_calc_noise(il);
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
@ -1694,7 +1693,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
sta_priv = (void *)sta->drv_priv;
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,
* 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 */
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);
@ -1815,7 +1813,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
dma_unmap_len_set(out_meta, len, firstlen);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* 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)) {
txq->need_update = 1;
@ -1831,8 +1829,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
phys_addr =
pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
PCI_DMA_TODEVICE);
il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
secondlen, 0, 0);
il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen,
0, 0);
}
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 */
if (info->flags & IEEE80211_TX_CTL_AMPDU)
il->ops->lib->txq_update_byte_cnt_tbl(il, txq,
le16_to_cpu(tx_cmd->len));
il->ops->txq_update_byte_cnt_tbl(il, txq, le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen,
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);
/* 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
il4965_txq_ctx_alloc(struct il_priv *il)
{
int ret;
int txq_id, slots_num;
int ret, txq_id;
unsigned long flags;
/* 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) */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
slots_num =
(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);
ret = il_tx_queue_init(il, txq_id);
if (ret) {
IL_ERR("Tx %d queue init failed\n", txq_id);
goto error;
@ -2017,52 +2010,27 @@ error_bc_tbls:
void
il4965_txq_ctx_reset(struct il_priv *il)
{
int txq_id, slots_num;
int txq_id;
unsigned long flags;
spin_lock_irqsave(&il->lock, flags);
/* Turn off all Tx DMA fifos */
il4965_txq_set_sched(il, 0);
/* Tell NIC where to find the "keep warm" buffer */
il_wr(il, FH49_KW_MEM_ADDR_REG, il->kw.dma >> 4);
spin_unlock_irqrestore(&il->lock, flags);
/* 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++) {
slots_num =
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);
}
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
il_tx_queue_reset(il, txq_id);
}
/**
* il4965_txq_ctx_stop - Stop all Tx DMA channels
*/
void
il4965_txq_ctx_stop(struct il_priv *il)
il4965_txq_ctx_unmap(struct il_priv *il)
{
int ch, 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);
int txq_id;
if (!il->txq)
return;
@ -2075,6 +2043,30 @@ il4965_txq_ctx_stop(struct il_priv *il)
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".
* 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);
txq->skbs[txq->q.read_ptr] = NULL;
il->ops->lib->txq_free_tfd(il, txq);
il->ops->txq_free_tfd(il, txq);
}
return nfreed;
}
@ -2548,6 +2540,308 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg,
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
*/
@ -3352,8 +3646,8 @@ il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt)
void
il4965_update_chain_flags(struct il_priv *il)
{
if (il->ops->hcmd->set_rxon_chain) {
il->ops->hcmd->set_rxon_chain(il);
if (il->ops->set_rxon_chain) {
il->ops->set_rxon_chain(il);
if (il->active.rx_chain != il->staging.rx_chain)
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 timer function is continually reset to execute within
* REG_RECALIB_PERIOD seconds since the last N_STATS
* was received. We need to ensure we receive the stats in order
* to update the temperature used for calibrating the TXPOWER.
* 60 seconds since the last N_STATS was received. We need to
* ensure we receive the stats in order to update the temperature
* used for calibrating the TXPOWER.
*/
static void
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);
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);
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);
if (flags & HW_CARD_DISABLED)
set_bit(S_RF_KILL_HW, &il->status);
set_bit(S_RFKILL, &il->status);
else
clear_bit(S_RF_KILL_HW, &il->status);
clear_bit(S_RFKILL, &il->status);
if (!(flags & RXON_CARD_DISABLED))
il_scan_cancel(il);
if ((test_bit(S_RF_KILL_HW, &status) !=
test_bit(S_RF_KILL_HW, &il->status)))
if ((test_bit(S_RFKILL, &status) !=
test_bit(S_RFKILL, &il->status)))
wiphy_rfkill_set_hw_state(il->hw->wiphy,
test_bit(S_RF_KILL_HW, &il->status));
test_bit(S_RFKILL, &il->status));
else
wake_up(&il->wait_command_queue);
}
@ -3868,10 +4162,11 @@ il4965_setup_handlers(struct il_priv *il)
/* Rx handlers */
il->handlers[N_RX_PHY] = il4965_hdl_rx_phy;
il->handlers[N_RX_MPDU] = il4965_hdl_rx;
il->handlers[N_RX] = il4965_hdl_rx;
/* block ack */
il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba;
/* Set up hardware specific Rx handlers */
il->ops->lib->handler_setup(il);
/* Tx response */
il->handlers[C_TX] = il4965_hdl_tx;
}
/**
@ -4101,9 +4396,8 @@ il4965_irq_tasklet(struct il_priv *il)
/* HW RF KILL switch toggled */
if (inta & CSR_INT_BIT_RF_KILL) {
int hw_rf_kill = 0;
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))
hw_rf_kill = 1;
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 (hw_rf_kill)
set_bit(S_RF_KILL_HW, &il->status);
set_bit(S_RFKILL, &il->status);
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);
}
@ -4244,11 +4538,9 @@ il4965_store_debug_level(struct device *d, struct device_attribute *attr,
ret = strict_strtoul(buf, 0, &val);
if (ret)
IL_ERR("%s is not in hex or decimal form.\n", buf);
else {
else
il->debug_level = val;
if (il_alloc_traffic_mem(il))
IL_ERR("Not enough memory to generate traffic log\n");
}
return strnlen(buf, count);
}
@ -4773,7 +5065,7 @@ il4965_dump_nic_error_log(struct il_priv *il)
else
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",
base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
return;
@ -5002,8 +5294,8 @@ il4965_alive_start(struct il_priv *il)
/* Initialize our rx_config data */
il_connection_init_rx_config(il);
if (il->ops->hcmd->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il);
if (il->ops->set_rxon_chain)
il->ops->set_rxon_chain(il);
}
/* 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 */
if (!il_is_init(il)) {
il->status =
test_bit(S_RF_KILL_HW,
&il->
status) << S_RF_KILL_HW |
test_bit(S_GEO_CONFIGURED,
&il->
status) << S_GEO_CONFIGURED |
test_bit(S_RFKILL, &il->status) << S_RFKILL |
test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
goto exit;
}
@ -5104,28 +5392,32 @@ __il4965_down(struct il_priv *il)
/* ...otherwise clear out all the status bits but the RF Kill
* bit and continue taking the NIC down. */
il->status &=
test_bit(S_RF_KILL_HW,
&il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED,
&il->
status) <<
S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
&il->
status) << S_FW_ERROR |
test_bit(S_RFKILL, &il->status) << S_RFKILL |
test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
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_rxq_stop(il);
/* 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);
/* 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 */
il_apm_stop(il);
_il_apm_stop(il);
spin_unlock_irq(&il->reg_lock);
il4965_txq_ctx_unmap(il);
exit:
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);
}
#define HW_READY_TIMEOUT (50)
static int
static void
il4965_set_hw_ready(struct il_priv *il)
{
int ret = 0;
int ret;
il_set_bit(il, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
/* See if we got it */
ret =
_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, HW_READY_TIMEOUT);
if (ret != -ETIMEDOUT)
ret = _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,
100);
if (ret >= 0)
il->hw_ready = true;
else
il->hw_ready = false;
D_INFO("hardware %s\n", (il->hw_ready == 1) ? "ready" : "not ready");
return ret;
D_INFO("hardware %s ready\n", (il->hw_ready) ? "" : "not");
}
static int
static void
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)
return ret;
return;
/* 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);
@ -5192,8 +5480,6 @@ il4965_prepare_card_hw(struct il_priv *il)
/* HW should be ready by now, check again. */
if (ret != -ETIMEDOUT)
il4965_set_hw_ready(il);
return ret;
}
#define MAX_HW_RESTARTS 5
@ -5221,22 +5507,19 @@ __il4965_up(struct il_priv *il)
}
il4965_prepare_card_hw(il);
if (!il->hw_ready) {
IL_WARN("Exit HW not ready\n");
IL_ERR("HW not ready\n");
return -EIO;
}
/* 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)
clear_bit(S_RF_KILL_HW, &il->status);
else
set_bit(S_RF_KILL_HW, &il->status);
if (il_is_rfkill(il)) {
clear_bit(S_RFKILL, &il->status);
else {
set_bit(S_RFKILL, &il->status);
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");
return 0;
}
@ -5275,7 +5558,7 @@ __il4965_up(struct il_priv *il)
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
ret = il->ops->lib->load_ucode(il);
ret = il->ops->load_ucode(il);
if (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))
goto out;
il->ops->lib->init_alive_start(il);
il->ops->init_alive_start(il);
out:
mutex_unlock(&il->mutex);
}
@ -5748,7 +6031,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
if (!il_is_associated(il))
goto out;
if (!il->ops->lib->set_channel_switch)
if (!il->ops->set_channel_switch)
goto out;
ch = channel->hw_value;
@ -5800,7 +6083,7 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
*/
set_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
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);
il->switch_channel = 0;
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
* TX power since frames can be sent on non-radar channels while
* 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
* 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;
/* Choose which receivers/antennas to use */
if (il->ops->hcmd->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il);
if (il->ops->set_rxon_chain)
il->ops->set_rxon_chain(il);
il_init_scan_params(il);
@ -6064,7 +6347,6 @@ err:
static void
il4965_uninit_drv(struct il_priv *il)
{
il4965_calib_free_results(il);
il_free_geos(il);
il_free_channel_map(il);
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");
il->cfg = cfg;
il->ops = &il4965_ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
il->debugfs_ops = &il4965_debugfs_ops;
#endif
il->pci_dev = pdev;
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
**************************/
@ -6224,7 +6506,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/***********************
* 3. Read REV register
***********************/
il->hw_base = pci_iomap(pdev, 0, 0);
il->hw_base = pci_ioremap_bar(pdev, 0);
if (!il->hw_base) {
err = -ENODEV;
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 (_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
set_bit(S_RF_KILL_HW, &il->status);
set_bit(S_RFKILL, &il->status);
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);
@ -6356,14 +6638,13 @@ out_disable_msi:
out_free_eeprom:
il_eeprom_free(il);
out_iounmap:
pci_iounmap(pdev, il->hw_base);
iounmap(il->hw_base);
out_pci_release_regions:
pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev);
out_pci_disable_device:
pci_disable_device(pdev);
out_ieee80211_free_hw:
il_free_traffic_mem(il);
ieee80211_free_hw(il->hw);
out:
return err;
@ -6434,11 +6715,10 @@ il4965_pci_remove(struct pci_dev *pdev)
* until now... */
destroy_workqueue(il->workqueue);
il->workqueue = NULL;
il_free_traffic_mem(il);
free_irq(il->pci_dev->irq, il);
pci_disable_msi(il->pci_dev);
pci_iounmap(pdev, il->hw_base);
iounmap(il->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
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);
}
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_hw_get_temperature(struct il_priv *il);
@ -508,7 +504,7 @@ iw4965_is_ht40_channel(__le32 rxon_flags)
chan_mod == CHANNEL_MODE_MIXED);
}
static void
void
il4965_nic_config(struct il_priv *il)
{
unsigned long flags;
@ -1678,7 +1674,7 @@ il4965_is_temp_calib_needed(struct il_priv *il)
return 1;
}
static void
void
il4965_temperature_calib(struct il_priv *il)
{
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);
}
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
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);
if (il->ops->hcmd->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il);
if (il->ops->set_rxon_chain)
il->ops->set_rxon_chain(il);
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 */
il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant;
il_set_rxon_ht(il, &il->current_ht_config);
if (il->ops->hcmd->set_rxon_chain)
il->ops->hcmd->set_rxon_chain(il);
if (il->ops->set_rxon_chain)
il->ops->set_rxon_chain(il);
il->staging.assoc_id = 0;
@ -2193,68 +1872,38 @@ il4965_config_ap(struct il_priv *il)
il4965_send_beacon_cmd(il);
}
static struct il_hcmd_utils_ops il4965_hcmd_utils = {
.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 = {
const struct il_ops il4965_ops = {
.txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl,
.txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = il4965_hw_txq_free_tfd,
.txq_init = il4965_hw_tx_queue_init,
.handler_setup = il4965_handler_setup,
.is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr,
.init_alive_start = il4965_init_alive_start,
.load_ucode = il4965_load_bsm,
.dump_nic_error_log = il4965_dump_nic_error_log,
.dump_fh = il4965_dump_fh,
.set_channel_switch = il4965_hw_channel_switch,
.apm_ops = {
.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,
},
.apm_init = il_apm_init,
.send_tx_power = il4965_send_tx_power,
.update_chain_flags = il4965_update_chain_flags,
.temp_ops = {
.temperature = il4965_temperature_calib,
},
#ifdef CONFIG_IWLEGACY_DEBUGFS
.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,
},
#endif
};
.eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore,
.eeprom_release_semaphore = il4965_eeprom_release_semaphore,
.rxon_assoc = il4965_send_rxon_assoc,
.commit_rxon = il4965_commit_rxon,
.set_rxon_chain = il4965_set_rxon_chain,
.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 const struct il_legacy_ops il4965_legacy_ops = {
.post_associate = il4965_post_associate,
.config_ap = il4965_config_ap,
.manage_ibss_station = il4965_manage_ibss_station,
.update_bcast_stations = il4965_update_bcast_stations,
};
const struct il_ops il4965_ops = {
.lib = &il4965_lib,
.hcmd = &il4965_hcmd,
.utils = &il4965_hcmd_utils,
.led = &il4965_led_ops,
.legacy = &il4965_legacy_ops,
.send_led_cmd = il4965_send_led_cmd,
};
struct il_cfg il4965_cfg = {
@ -2288,6 +1937,17 @@ struct il_cfg il4965_cfg = {
.ucode_tracing = true,
.sensitivity_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 */

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_dump_fh(struct il_priv *il, char **buf, bool display);
void il4965_nic_config(struct il_priv *il);
/* rx */
void il4965_rx_queue_restock(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);
int il4965_rxq_stop(struct il_priv *il);
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);
/* 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,
struct ieee80211_sta *sta, u16 tid);
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);
void il4965_hw_txq_ctx_free(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,
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 */
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_MAX)
extern void il4965_temperature_calib(struct il_priv *il);
/********************* END TEMPERATURE ***************************************/
/********************* 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_init_sensitivity(struct il_priv *il);
void il4965_reset_run_time_calib(struct il_priv *il);
void il4965_calib_free_results(struct il_priv *il);
/* Debug */
#ifdef CONFIG_IWLEGACY_DEBUGFS
ssize_t il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
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);
extern const struct il_debugfs_ops il4965_debugfs_ops;
#endif
/****************************/

View File

@ -6,45 +6,6 @@ config IWLEGACY
select LEDS_TRIGGERS
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
tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
depends on PCI && MAC80211
@ -98,3 +59,42 @@ config IWL3945
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called 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)
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);
void il_eeprom_free(struct il_priv *il);
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,
};
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 {
UCODE_NONE = 0,
UCODE_INIT,
@ -1156,13 +1130,15 @@ struct il_power_mgr {
};
struct il_priv {
/* ieee device used by generic ieee processing code */
struct ieee80211_hw *hw;
struct ieee80211_channel *ieee_channels;
struct ieee80211_rate *ieee_rates;
struct il_cfg *cfg;
const struct il_ops *ops;
#ifdef CONFIG_IWLEGACY_DEBUGFS
const struct il_debugfs_ops *debugfs_ops;
#endif
/* temporary frame storage list */
struct list_head free_frames;
@ -1199,9 +1175,6 @@ struct il_priv {
s32 temperature; /* degrees Kelvin */
s32 last_temperature;
/* init calibration results */
struct il_calib_result calib_results[IL_CALIB_MAX];
/* Scan related variables */
unsigned long scan_start;
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_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
struct il_debugfs_ops {
ssize_t(*rx_stats_read) (struct file *file, char __user *user_buf,
@ -1587,11 +1542,7 @@ struct il_debugfs_ops {
};
#endif
struct il_temp_ops {
void (*temperature) (struct il_priv *il);
};
struct il_lib_ops {
struct il_ops {
/* Handling TX */
void (*txq_update_byte_cnt_tbl) (struct il_priv *il,
struct il_tx_queue *txq,
@ -1601,8 +1552,6 @@ struct il_lib_ops {
u16 len, u8 reset, u8 pad);
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);
/* setup Rx handler */
void (*handler_setup) (struct il_priv *il);
/* alive notification after init uCode load */
void (*init_alive_start) (struct il_priv *il);
/* check validity of rtc data address */
@ -1615,44 +1564,33 @@ struct il_lib_ops {
int (*set_channel_switch) (struct il_priv *il,
struct ieee80211_channel_switch *ch_switch);
/* 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);
void (*update_chain_flags) (struct il_priv *il);
/* 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 */
struct il_temp_ops temp_ops;
int (*rxon_assoc) (struct il_priv *il);
int (*commit_rxon) (struct il_priv *il);
void (*set_rxon_chain) (struct il_priv *il);
#ifdef CONFIG_IWLEGACY_DEBUGFS
struct il_debugfs_ops debugfs_ops;
#endif
u16(*get_hcmd_size) (u8 cmd_id, u16 len);
u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data);
};
struct il_led_ops {
int (*cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
};
struct il_legacy_ops {
int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif);
void (*post_scan) (struct il_priv *il);
void (*post_associate) (struct il_priv *il);
void (*config_ap) (struct il_priv *il);
/* station management */
int (*update_bcast_stations) (struct il_priv *il);
int (*manage_ibss_station) (struct il_priv *il,
struct ieee80211_vif *vif, bool add);
};
struct il_ops {
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;
int (*send_led_cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
};
struct il_mod_params {
@ -1665,22 +1603,6 @@ struct il_mod_params {
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_DEF_LED_INTRVL cpu_to_le32(1000)
@ -1769,6 +1691,8 @@ struct il_cfg {
const bool ucode_tracing;
const bool sensitivity_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,
enum nl80211_iftype newtype, bool newp2p);
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
int il_alloc_traffic_mem(struct il_priv *il);
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);
extern void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len);
#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
il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
{
}
#endif
/*****************************************************
* RX handlers.
* **************************************************/
* Handlers
***************************************************/
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_error(struct il_priv *il, struct il_rx_buf *rxb);
void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb);
/*****************************************************
* 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);
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);
/* Handlers */
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_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
******************************************************/
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,
u32 txq_id);
void il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq,
int slots_num, u32 txq_id);
void il_tx_queue_unmap(struct il_priv *il, int txq_id);
void il_tx_queue_free(struct il_priv *il, int txq_id);
void il_setup_watchdog(struct il_priv *il);
extern void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq);
extern int il_tx_queue_init(struct il_priv *il, u32 txq_id);
extern void il_tx_queue_reset(struct il_priv *il, u32 txq_id);
extern void il_tx_queue_unmap(struct il_priv *il, int txq_id);
extern void il_tx_queue_free(struct il_priv *il, int txq_id);
extern void il_setup_watchdog(struct il_priv *il);
/*****************************************************
* TX power
****************************************************/
@ -2000,7 +1883,7 @@ void il_free_geos(struct il_priv *il);
#define S_HCMD_ACTIVE 0 /* host command in progress */
/* 1 is unused (used to be S_HCMD_SYNC_ACTIVE) */
#define S_INT_ENABLED 2
#define S_RF_KILL_HW 3
#define S_RFKILL 3
#define S_CT_KILL 4
#define S_INIT 5
#define S_ALIVE 6
@ -2038,16 +1921,10 @@ il_is_init(struct il_priv *il)
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
il_is_rfkill(struct il_priv *il)
{
return il_is_rfkill_hw(il);
return test_bit(S_RFKILL, &il->status);
}
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 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_send_rxon_timing(struct il_priv *il);
@ -2076,13 +1955,13 @@ int il_send_rxon_timing(struct il_priv *il);
static inline int
il_send_rxon_assoc(struct il_priv *il)
{
return il->ops->hcmd->rxon_assoc(il);
return il->ops->rxon_assoc(il);
}
static inline int
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 *
@ -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_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 mask, int timeout);
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
_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)
static inline void
_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
_il_rd(struct il_priv *il, u32 ofs)
{
return ioread32(il->hw_base + ofs);
return readl(il->hw_base + ofs);
}
static inline void
@ -2146,6 +2025,13 @@ static inline void
_il_release_nic_access(struct il_priv *il)
{
_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
@ -2168,7 +2054,7 @@ il_wr(struct il_priv *il, u32 reg, u32 value)
unsigned long 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_release_nic_access(il);
}
@ -2179,7 +2065,6 @@ static inline u32
_il_rd_prph(struct il_priv *il, u32 reg)
{
_il_wr(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
rmb();
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(il, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24)));
wmb();
_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;
spin_lock_irqsave(&il->reg_lock, reg_flags);
_il_grab_nic_access(il);
_il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
_il_release_nic_access(il);
if (likely(_il_grab_nic_access(il))) {
_il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
_il_release_nic_access(il);
}
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;
spin_lock_irqsave(&il->reg_lock, reg_flags);
_il_grab_nic_access(il);
_il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
_il_release_nic_access(il);
if (likely(_il_grab_nic_access(il))) {
_il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
_il_release_nic_access(il);
}
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;
spin_lock_irqsave(&il->reg_lock, reg_flags);
_il_grab_nic_access(il);
val = _il_rd_prph(il, reg);
_il_wr_prph(il, reg, (val & ~mask));
_il_release_nic_access(il);
if (likely(_il_grab_nic_access(il))) {
val = _il_rd_prph(il, reg);
_il_wr_prph(il, reg, (val & ~mask));
_il_release_nic_access(il);
}
spin_unlock_irqrestore(&il->reg_lock, reg_flags);
}
@ -2487,10 +2374,10 @@ struct il_rb_status {
__le32 __unused; /* 3945 only */
} __packed;
#define TFD_QUEUE_SIZE_MAX (256)
#define TFD_QUEUE_SIZE_BC_DUP (64)
#define TFD_QUEUE_SIZE_MAX 256
#define TFD_QUEUE_SIZE_BC_DUP 64
#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
static inline u8

View File

@ -31,6 +31,101 @@
#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 */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
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, \
};
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
il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,
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",
test_bit(S_INT_ENABLED, &il->status));
pos +=
scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
test_bit(S_RF_KILL_HW, &il->status));
scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n",
test_bit(S_RFKILL, &il->status));
pos +=
scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
test_bit(S_CT_KILL, &il->status));
@ -714,112 +849,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
DEBUGFS_READ_FILE_OPS(qos);
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
il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
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)
{
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
@ -909,7 +939,8 @@ il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
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
@ -917,7 +948,8 @@ il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
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
@ -1175,8 +1207,8 @@ il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
int pos = 0;
ssize_t ret = -EFAULT;
if (il->ops->lib->dump_fh) {
ret = pos = il->ops->lib->dump_fh(il, &buf, true);
if (il->ops->dump_fh) {
ret = pos = il->ops->dump_fh(il, &buf, true);
if (buf) {
ret =
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(tx_stats);
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
DEBUGFS_READ_FILE_OPS(rx_queue);
DEBUGFS_READ_FILE_OPS(tx_queue);
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(rx_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(tx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);

View File

@ -1,7 +1,7 @@
# WIFI
obj-$(CONFIG_IWLWIFI) += iwlwifi.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-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-2000.o
iwlwifi-objs += iwl-pci.o
iwlwifi-objs += iwl-drv.o
iwlwifi-objs += iwl-trans.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,
};
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 &&
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;
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);
@ -146,8 +144,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl1000_sensitivity;
return 0;
}
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_ok = IWL1000_UCODE_API_OK, \
.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_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.lib = &iwl1000_lib, \
@ -215,6 +213,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
.ucode_api_max = IWL100_UCODE_API_MAX, \
.ucode_api_ok = IWL100_UCODE_API_OK, \
.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_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
.lib = &iwl1000_lib, \

View File

@ -116,7 +116,7 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
.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 &&
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;
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);
@ -142,8 +140,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl2000_sensitivity;
return 0;
}
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_ok = IWL2000_UCODE_API_OK, \
.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_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2000_lib, \
@ -268,6 +266,8 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = {
.ucode_api_max = IWL2030_UCODE_API_MAX, \
.ucode_api_ok = IWL2030_UCODE_API_OK, \
.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_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2030_lib, \
@ -290,6 +290,8 @@ struct iwl_cfg iwl2030_2bgn_cfg = {
.ucode_api_max = IWL105_UCODE_API_MAX, \
.ucode_api_ok = IWL105_UCODE_API_OK, \
.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_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.lib = &iwl2000_lib, \
@ -318,6 +320,8 @@ struct iwl_cfg iwl105_bgn_d_cfg = {
.ucode_api_max = IWL135_UCODE_API_MAX, \
.ucode_api_ok = IWL135_UCODE_API_OK, \
.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_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
.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;
}
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 &&
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;
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) |
BIT(IEEE80211_BAND_5GHZ);
@ -185,11 +183,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
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 &&
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;
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) |
BIT(IEEE80211_BAND_5GHZ);
@ -212,8 +206,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl5150_sensitivity;
return 0;
}
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, \
.ucode_api_max = IWL5000_UCODE_API_MAX, \
.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_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
.lib = &iwl5000_lib, \
@ -399,6 +393,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.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_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.lib = &iwl5000_lib,
@ -412,6 +408,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.fw_name_pre = IWL5150_FW_PRE, \
.ucode_api_max = IWL5150_UCODE_API_MAX, \
.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_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
.lib = &iwl5150_lib, \

View File

@ -137,7 +137,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
.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 &&
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;
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) |
BIT(IEEE80211_BAND_5GHZ);
@ -165,7 +163,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
/* Set initial sensitivity parameters */
hw_params(priv).sens = &iwl6000_sensitivity;
return 0;
}
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_ok = IWL6000G2_UCODE_API_OK, \
.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_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
.lib = &iwl6000_lib, \
@ -384,11 +383,24 @@ struct iwl_cfg iwl6005_2agn_d_cfg = {
.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 \
.fw_name_pre = IWL6030_FW_PRE, \
.ucode_api_max = IWL6000G2_UCODE_API_MAX, \
.ucode_api_ok = IWL6000G2_UCODE_API_OK, \
.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_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
.lib = &iwl6030_lib, \
@ -458,6 +470,8 @@ struct iwl_cfg iwl130_bg_cfg = {
.ucode_api_max = IWL6000_UCODE_API_MAX, \
.ucode_api_ok = IWL6000_UCODE_API_OK, \
.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_rx_ant = ANT_BC, /* .cfg overwrite */ \
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
@ -487,6 +501,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \
.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_rx_ant = ANT_AB, /* .cfg overwrite */ \
.lib = &iwl6000_lib, \
@ -512,6 +528,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.fw_name_pre = IWL6050_FW_PRE, \
.ucode_api_max = IWL6050_UCODE_API_MAX, \
.ucode_api_min = IWL6050_UCODE_API_MIN, \
.max_inst_size = IWL60_RTC_INST_SIZE, \
.max_data_size = IWL60_RTC_DATA_SIZE, \
.lib = &iwl6000_lib, \
.additional_nic_config = iwl6150_additional_nic_config, \
.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_ok = IWL6000_UCODE_API_OK,
.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_calib_ver = EEPROM_6000_TX_POWER_VERSION,
.lib = &iwl6000_lib,

View File

@ -68,6 +68,8 @@
#include "iwl-agn-calib.h"
#include "iwl-trans.h"
#include "iwl-agn.h"
#include "iwl-wifi.h"
#include "iwl-ucode.h"
/*****************************************************************************
* INIT calibrations framework
@ -634,7 +636,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
data->last_bad_plcp_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);
else
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_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);
else
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.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;
else
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];
/* 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;
}
priv->bt_status = coex->bt_status;
queue_work(priv->shrd->workqueue,
queue_work(priv->workqueue,
&priv->bt_traffic_change_work);
}
}
@ -959,7 +959,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,
struct ieee80211_key_conf *key,
void *_data)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct wowlan_key_data *data = _data;
struct iwl_rxon_context *ctx = data->ctx;
struct aes_sc *aes_sc, *aes_tx_sc = NULL;

View File

@ -38,6 +38,7 @@
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-agn.h"
#include "iwl-op-mode.h"
#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);
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_link_quality_cmd *table;
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);
enum mac80211_rate_control_flags mac_flags;
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 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 iwl_lq_sta *lq_sta = priv_sta;
int rate_idx;
@ -2805,9 +2809,10 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
gfp_t gfp)
{
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");
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,
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, "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)) &&
(pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
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)
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_rx_packet *pkt = rxb_addr(rxb);
struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
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)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_rxon_context *ctx;
struct ieee80211_conf *conf = &hw->conf;
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,
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);
int ret;
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)))
iwlagn_commit_rxon(priv, ctx);

View File

@ -568,7 +568,7 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
return;
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)
@ -577,7 +577,7 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
return;
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)
@ -600,7 +600,7 @@ void iwl_tt_handler(struct iwl_priv *priv)
return;
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

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;
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,
* 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.
* For now set the counter to just 1 since we do not
* 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);
}
@ -983,7 +987,7 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
IWL_ERR(priv, "Tx flush command to flush out all frames\n");
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.h"
#include "iwl-shared.h"
#include "iwl-bus.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),
};
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);
return iwl_trans_send_cmd_pdu(trans(priv),
TX_ANT_CONFIGURATION_CMD,
@ -738,14 +738,14 @@ int iwl_alive_start(struct iwl_priv *priv)
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;
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
lockdep_assert_held(&priv->shrd->mutex);
iwl_scan_cancel_timeout(priv, 200);
/*
@ -803,15 +803,6 @@ void __iwl_down(struct iwl_priv *priv)
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
@ -869,7 +860,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
bt_status = priv->bt_status;
bt_is_sco = priv->bt_is_sco;
__iwl_down(priv);
iwl_down(priv);
priv->bt_full_concurrent = bt_full_concurrent;
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)
{
priv->shrd->workqueue = create_singlethread_workqueue(DRV_NAME);
priv->workqueue = create_singlethread_workqueue(DRV_NAME);
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;
}
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)
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_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)
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;
/* 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
}
int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
struct iwl_cfg *cfg)
static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
{
struct iwl_fw *fw = &nic(trans)->fw;
int err = 0;
struct iwl_priv *priv;
struct ieee80211_hw *hw;
struct iwl_op_mode *op_mode;
u16 num_mac;
u32 ucode_flags;
/************************
* 1. Allocating HW data
************************/
hw = iwl_alloc_all();
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;
goto out;
}
priv = hw->priv;
priv->shrd = bus->shrd;
op_mode = hw->priv;
op_mode->ops = &iwl_dvm_ops;
priv = IWL_OP_MODE_GET_DVM(op_mode);
priv->shrd = trans->shrd;
priv->shrd->priv = priv;
iwl_trans_configure(trans(priv), op_mode);
/* 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 */
iwl_debug_config(priv);
IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
cfg(priv) = cfg;
/* is antenna coupling more than 35dB ? */
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
*****************/
/* 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". */
iwl_trans_stop_hw(trans(priv));
if (err) {
@ -1248,11 +1245,23 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
/************************
* 5. Setup HW constants
************************/
if (iwl_set_hw_params(priv)) {
err = -ENOENT;
IWL_ERR(priv, "failed to set hw parameters\n");
goto out_free_eeprom;
}
iwl_set_hw_params(priv);
ucode_flags = fw->ucode_capa.flags;
#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
@ -1273,17 +1282,49 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
iwl_power_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)
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:
destroy_workqueue(priv->shrd->workqueue);
priv->shrd->workqueue = NULL;
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
iwl_uninit_drv(priv);
out_free_eeprom:
iwl_eeprom_free(priv->shrd);
@ -1291,12 +1332,15 @@ out_free_traffic_mem:
iwl_free_traffic_mem(priv);
ieee80211_free_hw(priv->hw);
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");
@ -1316,18 +1360,18 @@ void __devexit iwl_remove(struct iwl_priv * priv)
/*This will stop the queues, move the device to low power state */
iwl_trans_stop_device(trans(priv));
iwl_dealloc_ucode(trans(priv));
iwl_dealloc_ucode(nic(priv));
iwl_eeprom_free(priv->shrd);
/*netif_stop_queue(dev); */
flush_workqueue(priv->shrd->workqueue);
flush_workqueue(priv->workqueue);
/* 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... */
destroy_workqueue(priv->shrd->workqueue);
priv->shrd->workqueue = NULL;
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
iwl_free_traffic_mem(priv);
iwl_uninit_drv(priv);
@ -1337,6 +1381,16 @@ void __devexit iwl_remove(struct iwl_priv * priv)
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"
struct iwlagn_ucode_capabilities {
u32 max_probe_length;
u32 standard_phy_calibration_size;
u32 flags;
};
struct iwl_ucode_capabilities;
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;
}
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 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 */
struct ieee80211_hw *iwl_alloc_all(void);
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);
/* RXON */
@ -387,4 +392,14 @@ void iwl_testmode_cleanup(struct iwl_priv *priv)
}
#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__ */

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_2agn_sff_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_bg_cfg;
extern struct iwl_cfg iwl6030_2agn_cfg;

View File

@ -38,10 +38,10 @@
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-power.h"
#include "iwl-agn.h"
#include "iwl-shared.h"
#include "iwl-agn.h"
#include "iwl-trans.h"
#include "iwl-wifi.h"
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
* 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)
{
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) &&
(priv->band == band))
return 0;
return;
ctx->staging.channel = cpu_to_le16(channel);
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);
return 0;
}
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
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 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_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) {
IWL_DEBUG_FW_ERRORS(priv,
"Restarting adapter due to uCode error.\n");
queue_work(priv->shrd->workqueue, &priv->restart);
queue_work(priv->workqueue, &priv->restart);
} else
IWL_DEBUG_FW_ERRORS(priv,
"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);
}
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);
}
@ -1466,8 +1479,9 @@ void iwl_nic_config(struct iwl_priv *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;
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);
}
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);
}
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);
}

View File

@ -76,7 +76,7 @@ struct iwl_cmd;
struct iwl_lib_ops {
/* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
void (*set_hw_params)(struct iwl_priv *priv);
/* setup BT Rx handler */
void (*bt_rx_handler_setup)(struct iwl_priv *priv);
/* 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 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_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);
void iwl_set_flags_for_band(struct iwl_priv *priv,
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_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc,
u16 len);
void iwl_reset_traffic_log(struct iwl_priv *priv);
#else
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__
#define __iwl_debug_h__
#include "iwl-bus.h"
#include "iwl-shared.h"
#include "iwl-devtrace.h"
struct iwl_priv;
/*No matter what is m (priv, bus, trans), this will work */
#define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a)
#define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a)
#define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a)
#define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a)
void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
const char *fmt, ...);
void __iwl_warn(struct device *dev, const char *fmt, ...);
void __iwl_info(struct device *dev, const char *fmt, ...);
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) \
do { \
@ -46,53 +64,35 @@ do { \
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
} 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
#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) \
do { \
if (iwl_get_debug_level((m)->shrd) & level) \
print_hex_dump(KERN_DEBUG, "iwl data: ", \
DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
} while (0)
#define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \
#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \
do { \
if (!iwl_is_rfkill(p->shrd)) \
dev_err(trans(p)->dev, "%s%c %s " fmt, \
"", \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \
dev_err(trans(p)->dev, "%s%c %s " fmt, \
"(RFKILL) ", \
in_interrupt() ? 'I' : 'U', __func__, \
##__VA_ARGS__); \
if (!iwl_is_rfkill((m)->shrd)) \
IWL_ERR(m, fmt, ##args); \
else \
__iwl_err(trans(m)->dev, true, \
!(iwl_get_debug_level((m)->shrd) & IWL_DL_RADIO),\
fmt, ##args); \
} while (0)
#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_DEBUG_QUIET_RFKILL(p, fmt, args...) \
do { \
if (!iwl_is_rfkill(p->shrd)) \
IWL_ERR(p, fmt, ##args); \
#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \
do { \
if (!iwl_is_rfkill((m)->shrd)) \
IWL_ERR(m, fmt, ##args); \
else \
__iwl_err(trans(m)->dev, true, true, fmt, ##args); \
} while (0)
#endif /* CONFIG_IWLWIFI_DEBUG */

View File

@ -40,6 +40,7 @@
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-agn.h"
#include "iwl-wifi.h"
/* create and remove of files */
#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 */
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;
if (trans->shrd->ucode_type == IWL_UCODE_INIT)
priv->dbgfs_sram_len = trans->ucode_init.data.len;
if (nic->shrd->ucode_type == IWL_UCODE_INIT)
priv->dbgfs_sram_len = nic->fw.ucode_init.data.len;
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;
@ -342,7 +343,7 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos,
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,
size_t count, loff_t *ppos)

View File

@ -47,9 +47,9 @@
#include "iwl-power.h"
#include "iwl-agn-rs.h"
#include "iwl-agn-tt.h"
#include "iwl-bus.h"
#include "iwl-trans.h"
#include "iwl-shared.h"
#include "iwl-op-mode.h"
struct iwl_tx_queue;
@ -442,9 +442,6 @@ struct iwl_chain_noise_data {
u8 state;
};
#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
enum {
MEASUREMENT_READY = (1 << 0),
MEASUREMENT_ACTIVE = (1 << 1),
@ -696,11 +693,11 @@ struct iwl_testmode_trace {
dma_addr_t dma_addr;
bool trace_enabled;
};
struct iwl_testmode_sram {
struct iwl_testmode_mem {
u32 buff_size;
u32 num_chunks;
u8 *buff_addr;
bool sram_readed;
bool read_in_progress;
};
#endif
@ -710,6 +707,13 @@ struct iwl_wipan_noa_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 {
/*data shared among all the driver's layers */
@ -721,6 +725,8 @@ struct iwl_priv {
struct ieee80211_rate *ieee_rates;
struct kmem_cache *tx_cmd_pool;
struct workqueue_struct *workqueue;
enum ieee80211_band band;
void (*pre_rx_handler)(struct iwl_priv *priv,
@ -785,13 +791,6 @@ struct iwl_priv {
/* EEPROM MAC addresses */
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];
__le16 switch_channel;
@ -801,7 +800,6 @@ struct iwl_priv {
u8 start_calib;
struct iwl_sensitivity_data sensitivity_data;
struct iwl_chain_noise_data chain_noise_data;
bool enhance_sensitivity_table;
__le16 sensitivity_tbl[HD_TABLE_SIZE];
__le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES];
@ -869,11 +867,6 @@ struct iwl_priv {
struct iwl_rx_phy_res last_phy_res;
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
* two extra calibration commands follows the standard
@ -964,7 +957,7 @@ struct iwl_priv {
bool led_registered;
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
struct iwl_testmode_trace testmode_trace;
struct iwl_testmode_sram testmode_sram;
struct iwl_testmode_mem testmode_mem;
u32 tm_fixed_rate;
#endif

View File

@ -34,6 +34,11 @@
#undef TRACE_EVENT
#define TRACE_EVENT(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
#define PRIV_ENTRY __field(void *, priv)
@ -163,6 +168,66 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
__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
#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
* 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;
int ret;
for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
/* 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);
/* 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,
EEPROM_SEM_TIMEOUT);
if (ret >= 0) {
IWL_DEBUG_EEPROM(trans(bus),
IWL_DEBUG_EEPROM(trans,
"Acquired semaphore after %d tries.\n",
count+1);
return ret;
@ -175,9 +179,9 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus)
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);
}
@ -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)
iwl_clear_bit(trans(bus), CSR_OTP_GP_REG,
iwl_clear_bit(trans, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_OTP_ACCESS_MODE);
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);
}
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;
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 */
switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_NONE:
IWL_ERR(bus, "Unknown hardware type\n");
IWL_ERR(trans, "Unknown hardware type\n");
return -ENOENT;
case CSR_HW_REV_TYPE_5300:
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;
break;
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)
nvm_type = NVM_DEVICE_TYPE_OTP;
else
@ -343,73 +348,74 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
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;
/* Enable 40MHz radio clock */
iwl_write32(trans(bus), CSR_GP_CNTRL,
iwl_read32(trans(bus), CSR_GP_CNTRL) |
iwl_write32(trans, CSR_GP_CNTRL,
iwl_read32(trans, CSR_GP_CNTRL) |
CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* 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,
25000);
if (ret < 0)
IWL_ERR(bus, "Time out access OTP\n");
IWL_ERR(trans, "Time out access OTP\n");
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);
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);
/*
* CSR auto clock gate disable bit -
* this is only applicable for HW with OTP shadow RAM
*/
if (cfg(bus)->base_params->shadow_ram_support)
iwl_set_bit(trans(bus), CSR_DBG_LINK_PWR_MGMT_REG,
if (cfg(trans)->base_params->shadow_ram_support)
iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
CSR_RESET_LINK_PWR_MGMT_DISABLED);
}
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;
u32 r;
u32 otpgp;
iwl_write32(trans(bus), CSR_EEPROM_REG,
iwl_write32(trans, CSR_EEPROM_REG,
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,
IWL_EEPROM_ACCESS_TIMEOUT);
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;
}
r = iwl_read32(trans(bus), CSR_EEPROM_REG);
r = iwl_read32(trans, CSR_EEPROM_REG);
/* 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) {
/* stop in this case */
/* 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);
IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n");
IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n");
return -EINVAL;
}
if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
/* continue in this case */
/* 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);
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);
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
*/
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;
__le16 link_value;
bool is_empty = false;
/* 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) {
IWL_ERR(bus, "OTP is empty\n");
IWL_ERR(trans, "OTP is empty\n");
is_empty = true;
}
} 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;
}
@ -448,7 +454,7 @@ static bool iwl_is_otp_empty(struct iwl_bus *bus)
* we should read and used to configure the device.
* 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 next_link_addr = 0, valid_addr;
@ -456,10 +462,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
int usedblocks = 0;
/* 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 */
if (iwl_is_otp_empty(bus))
if (iwl_is_otp_empty(trans))
return -EINVAL;
/*
@ -473,9 +479,9 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
*/
valid_addr = next_link_addr;
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);
if (iwl_read_otp_word(bus, next_link_addr, &link_value))
if (iwl_read_otp_word(trans, next_link_addr, &link_value))
return -EINVAL;
if (!link_value) {
/*
@ -490,10 +496,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus,
}
/* more in the link list, continue */
usedblocks++;
} while (usedblocks <= cfg(bus)->base_params->max_ll_items);
} while (usedblocks <= cfg(trans)->base_params->max_ll_items);
/* 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;
}
@ -653,63 +659,62 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
*
* 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;
u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP);
u32 gp = iwl_read32(trans, CSR_EEPROM_GP);
int sz;
int ret;
u16 addr;
u16 validblockaddr = 0;
u16 cache_addr = 0;
trans(priv)->nvm_device_type = iwl_get_nvm_type(bus(priv), hw_rev);
if (trans(priv)->nvm_device_type == -ENOENT)
trans->nvm_device_type = iwl_get_nvm_type(trans, hw_rev);
if (trans->nvm_device_type == -ENOENT)
return -ENOENT;
/* allocate eeprom */
sz = cfg(priv)->base_params->eeprom_size;
IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
shrd->eeprom = kzalloc(sz, GFP_KERNEL);
if (!shrd->eeprom) {
sz = cfg(trans)->base_params->eeprom_size;
IWL_DEBUG_EEPROM(trans, "NVM size = %d\n", sz);
trans->shrd->eeprom = kzalloc(sz, GFP_KERNEL);
if (!trans->shrd->eeprom) {
ret = -ENOMEM;
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) {
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;
goto err;
}
/* 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) {
IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
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) {
IWL_ERR(priv, "Failed to initialize OTP access.\n");
IWL_ERR(trans, "Failed to initialize OTP access.\n");
ret = -ENOENT;
goto done;
}
iwl_write32(trans(priv), CSR_EEPROM_GP,
iwl_read32(trans(priv), CSR_EEPROM_GP) &
iwl_write32(trans, CSR_EEPROM_GP,
iwl_read32(trans, CSR_EEPROM_GP) &
~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_UNCORR_STATUS_MSK);
/* traversing the linked list if no shadow ram supported */
if (!cfg(priv)->base_params->shadow_ram_support) {
if (iwl_find_otp_image(bus(priv), &validblockaddr)) {
if (!cfg(trans)->base_params->shadow_ram_support) {
if (iwl_find_otp_image(trans, &validblockaddr)) {
ret = -ENOENT;
goto done;
}
@ -718,7 +723,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
addr += sizeof(u16)) {
__le16 eeprom_data;
ret = iwl_read_otp_word(bus(priv), addr, &eeprom_data);
ret = iwl_read_otp_word(trans, addr, &eeprom_data);
if (ret)
goto done;
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)) {
u32 r;
iwl_write32(trans(priv), CSR_EEPROM_REG,
iwl_write32(trans, CSR_EEPROM_REG,
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,
IWL_EEPROM_ACCESS_TIMEOUT);
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;
}
r = iwl_read32(trans(priv), CSR_EEPROM_REG);
r = iwl_read32(trans, CSR_EEPROM_REG);
e[addr / 2] = cpu_to_le16(r >> 16);
}
}
IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
(trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP)
IWL_DEBUG_EEPROM(trans, "NVM Type: %s, version: 0x%x\n",
(trans->nvm_device_type == NVM_DEVICE_TYPE_OTP)
? "OTP" : "EEPROM",
iwl_eeprom_query16(shrd, EEPROM_VERSION));
iwl_eeprom_query16(trans->shrd, EEPROM_VERSION));
ret = 0;
done:
iwl_eeprom_release_semaphore(bus(priv));
iwl_eeprom_release_semaphore(trans);
err:
if (ret)
iwl_eeprom_free(priv->shrd);
iwl_eeprom_free(trans->shrd);
alloc_err:
return ret;
}

View File

@ -67,6 +67,7 @@
struct iwl_priv;
struct iwl_shared;
struct iwl_trans;
/*
* 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);
int iwl_eeprom_check_version(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.h"
#include "iwl-shared.h"
#include "iwl-bus.h"
#include "iwl-trans.h"
#include "iwl-op-mode.h"
/*****************************************************************************
*
@ -136,7 +136,7 @@ iwlagn_iface_combinations_p2p[] = {
* other mac80211 functions grouped here.
*/
int iwlagn_mac_setup_register(struct iwl_priv *priv,
struct iwlagn_ucode_capabilities *capa)
struct iwl_ucode_capabilities *capa)
{
int ret;
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_IBSS_RSN;
if (trans(priv)->ucode_wowlan.code.len &&
if (nic(priv)->fw.ucode_wowlan.code.len &&
device_can_wakeup(trans(priv)->dev)) {
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
WIPHY_WOWLAN_DISCONNECT |
@ -296,7 +296,7 @@ static int __iwl_up(struct iwl_priv *priv)
error:
set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
__iwl_down(priv);
iwl_down(priv);
clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
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)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
int ret;
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)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
IWL_DEBUG_MAC80211(priv, "enter\n");
@ -341,9 +341,13 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
priv->is_open = 0;
mutex_lock(&priv->shrd->mutex);
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
* 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 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)
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,
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];
int ret;
@ -427,7 +431,7 @@ static int iwlagn_mac_suspend(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 ieee80211_vif *vif;
unsigned long flags;
@ -453,17 +457,17 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
#ifdef CONFIG_IWLWIFI_DEBUGFS
if (ret == 0) {
struct iwl_trans *trans = trans(priv);
struct iwl_nic *nic = nic(priv);
if (!priv->wowlan_sram)
priv->wowlan_sram =
kzalloc(trans->ucode_wowlan.data.len,
kzalloc(nic->fw.ucode_wowlan.data.len,
GFP_KERNEL);
if (priv->wowlan_sram)
_iwl_read_targ_mem_words(
trans(priv), 0x800000,
priv->wowlan_sram,
trans->ucode_wowlan.data.len / 4);
nic->fw.ucode_wowlan.data.len / 4);
}
#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)
{
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,
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,
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);
}
@ -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_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_rxon_context *ctx = vif_priv->ctx;
int ret;
@ -622,7 +626,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
u8 buf_size)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
int ret = -EINVAL;
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_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_vif_priv *vif_priv = (void *)vif->drv_priv;
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,
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;
struct ieee80211_conf *conf = &hw->conf;
struct ieee80211_channel *channel = ch_switch->channel;
@ -818,7 +822,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
unsigned int *total_flags,
u64 multicast)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
__le32 filter_or = 0, filter_nand = 0;
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)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
mutex_lock(&priv->shrd->mutex);
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,
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];
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)
{
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)))
return -EOPNOTSUPP;
@ -1012,7 +1016,7 @@ static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw,
const u8 *bssid,
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_rxon_context *ctx = vif_priv->ctx;
int ret;
@ -1066,7 +1070,7 @@ static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
const u8 *bssid,
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_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,
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");
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,
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;
}
@ -1126,7 +1130,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u16 queue,
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_rxon_context *ctx = vif_priv->ctx;
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)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
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,
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_rxon_context *tmp, *ctx = NULL;
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,
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);
IWL_DEBUG_MAC80211(priv, "enter\n");
@ -1348,7 +1352,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
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 *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
struct iwl_rxon_context *tmp;
@ -1434,7 +1438,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_scan_request *req)
{
struct iwl_priv *priv = hw->priv;
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
int ret;
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_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;
int ret;
@ -1519,7 +1523,7 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd,
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;
int sta_id;
@ -1587,15 +1591,18 @@ struct ieee80211_ops iwlagn_hw_ops = {
struct ieee80211_hw *iwl_alloc_all(void)
{
struct iwl_priv *priv;
struct iwl_op_mode *op_mode;
/* mac80211 allocates memory for this device instance, including
* space for this driver's private structure */
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)
goto out;
priv = hw->priv;
op_mode = hw->priv;
priv = IWL_OP_MODE_GET_DVM(op_mode);
priv->hw = hw;
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-aspm.h>
#include "iwl-bus.h"
#include "iwl-io.h"
#include "iwl-shared.h"
#include "iwl-trans.h"
#include "iwl-csr.h"
#include "iwl-cfg.h"
#include "iwl-drv.h"
#include "iwl-trans.h"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
.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(0x0082, 0xC020, 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, 0x1304, iwl6005_2agn_cfg)},/* low 5GHz active */
{IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_cfg)},/* high 5GHz active */
{IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)},
{IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */
{IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */
/* 6x30 Series */
{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(0x088F, 0x4260, iwl6035_2agn_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
{IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},
/* 105 Series */
{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)
{
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;
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (!bus) {
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) {
shrd = kzalloc(sizeof(*iwl_trans->shrd), GFP_KERNEL);
if (!shrd) {
dev_printk(KERN_ERR, &pdev->dev,
"Couldn't allocate iwl_shared");
err = -ENOMEM;
goto out_free_bus;
}
bus->shrd->bus = bus;
pci_set_drvdata(pdev, bus);
#ifdef CONFIG_IWLWIFI_IDI
trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent);
if (trans(bus) == NULL) {
iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent);
if (iwl_trans == NULL) {
err = -ENOMEM;
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
trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent);
if (trans(bus) == NULL) {
iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent);
if (iwl_trans == NULL) {
err = -ENOMEM;
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
if (err)
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;
out_free_trans:
iwl_trans_free(trans(bus));
iwl_trans_free(iwl_trans);
pci_set_drvdata(pdev, NULL);
out_free_bus:
kfree(bus->shrd);
kfree(bus);
kfree(shrd);
return err;
}
static void __devexit iwl_pci_remove(struct pci_dev *pdev)
{
struct iwl_bus *bus = pci_get_drvdata(pdev);
struct iwl_shared *shrd = bus->shrd;
struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
struct iwl_shared *shrd = iwl_trans->shrd;
iwl_remove(shrd->priv);
iwl_drv_stop(shrd);
iwl_trans_free(shrd->trans);
pci_set_drvdata(pdev, NULL);
kfree(bus->shrd);
kfree(bus);
kfree(shrd);
}
#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)
{
struct pci_dev *pdev = to_pci_dev(device);
struct iwl_bus *bus = pci_get_drvdata(pdev);
struct iwl_shared *shrd = bus->shrd;
struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
/* Before you put code here, think about WoWLAN. You cannot check here
* whether WoWLAN is enabled or not, and your code will run even if
* WoWLAN is enabled - don't kill the NIC, someone may need it in Sx.
*/
return iwl_trans_suspend(shrd->trans);
return iwl_trans_suspend(iwl_trans);
}
static int iwl_pci_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct iwl_bus *bus = pci_get_drvdata(pdev);
struct iwl_shared *shrd = bus->shrd;
struct iwl_trans *iwl_trans = pci_get_drvdata(pdev);
/* Before you put code here, think about WoWLAN. You cannot check here
* whether WoWLAN is enabled or not, and your code will run even if
@ -362,7 +356,7 @@ static int iwl_pci_resume(struct device *device)
*/
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);

View File

@ -218,7 +218,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
int iwl_scan_cancel(struct iwl_priv *priv)
{
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;
}
@ -354,7 +354,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
*/
set_bit(STATUS_SCAN_COMPLETE, &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 &&
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;
}
priv->bt_status = scan_notif->bt_status;
queue_work(priv->shrd->workqueue,
queue_work(priv->workqueue,
&priv->bt_traffic_change_work);
}
return 0;
@ -950,7 +950,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
return ret;
}
queue_delayed_work(priv->shrd->workqueue, &priv->scan_check,
queue_delayed_work(priv->workqueue, &priv->scan_check,
IWL_SCAN_CHECK_WATCHDOG);
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)
{
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)

View File

@ -94,7 +94,6 @@
* This implementation is iwl-pci.c
*/
struct iwl_bus;
struct iwl_priv;
struct iwl_trans;
struct iwl_sensitivity_ranges;
@ -173,8 +172,6 @@ struct iwl_mod_params {
* @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX)
* @sku: sku read from EEPROM
* @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_exit_threshold: when to reeable the device - in hw dependent unit
* relevant for 1000, 6000 and up
@ -192,8 +189,6 @@ struct iwl_hw_params {
bool shadow_reg_enable;
u16 sku;
u32 rx_page_order;
u32 max_inst_size;
u32 max_data_size;
u32 ct_kill_threshold;
u32 ct_kill_exit_threshold;
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
* without a warning, for use in transitions
* @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_rx_ant: valid receive antenna
* @sku: sku information from EEPROM
@ -320,6 +317,8 @@ struct iwl_cfg {
const unsigned int ucode_api_max;
const unsigned int ucode_api_ok;
const unsigned int ucode_api_min;
const u32 max_data_size;
const u32 max_inst_size;
u8 valid_tx_ant;
u8 valid_rx_ant;
u16 sku;
@ -358,8 +357,8 @@ struct iwl_cfg {
* @cfg: see struct iwl_cfg
* @priv: pointer to the upper layer data
* @trans: pointer to the transport layer data
* @nic: pointer to the nic data
* @hw_params: see struct iwl_hw_params
* @workqueue: the workqueue used by all the layers of the driver
* @lock: protect general shared data
* @sta_lock: protects the station table.
* If lock and sta_lock are needed, lock must be acquired first.
@ -385,13 +384,12 @@ struct iwl_shared {
bool wowlan;
u8 valid_contexts;
struct iwl_bus *bus;
struct iwl_cfg *cfg;
struct iwl_priv *priv;
struct iwl_trans *trans;
struct iwl_nic *nic;
struct iwl_hw_params hw_params;
struct workqueue_struct *workqueue;
spinlock_t lock;
spinlock_t sta_lock;
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 cfg(_m) ((_m)->shrd->cfg)
#define bus(_m) ((_m)->shrd->bus)
#define nic(_m) ((_m)->shrd->nic)
#define trans(_m) ((_m)->shrd->trans)
#define hw_params(_m) ((_m)->shrd->hw_params)
@ -531,24 +529,11 @@ enum iwl_rxon_context_id {
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);
void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state);
void iwl_nic_config(struct iwl_priv *priv);
void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
const char *get_cmd_string(u8 cmd);
bool iwl_check_for_ct_kill(struct iwl_priv *priv);
void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac);
void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac);
/* notification wait support */
void iwl_abort_notification_waits(struct iwl_shared *shrd);
@ -568,20 +553,6 @@ void __releases(wait_entry)
iwl_remove_notification(struct iwl_shared *shrd,
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_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