mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-10 15:10:38 +00:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/hw.c
This commit is contained in:
commit
01a2829809
99
Documentation/networking/mac80211-auth-assoc-deauth.txt
Normal file
99
Documentation/networking/mac80211-auth-assoc-deauth.txt
Normal file
@ -0,0 +1,99 @@
|
||||
#
|
||||
# This outlines the Linux authentication/association and
|
||||
# deauthentication/disassociation flows.
|
||||
#
|
||||
# This can be converted into a diagram using the service
|
||||
# at http://www.websequencediagrams.com/
|
||||
#
|
||||
|
||||
participant userspace
|
||||
participant mac80211
|
||||
participant driver
|
||||
|
||||
alt authentication needed (not FT)
|
||||
userspace->mac80211: authenticate
|
||||
|
||||
alt authenticated/authenticating already
|
||||
mac80211->driver: sta_state(AP, not-exists)
|
||||
mac80211->driver: bss_info_changed(clear BSSID)
|
||||
else associated
|
||||
note over mac80211,driver
|
||||
like deauth/disassoc, without sending the
|
||||
BA session stop & deauth/disassoc frames
|
||||
end note
|
||||
end
|
||||
|
||||
mac80211->driver: config(channel, non-HT)
|
||||
mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap)
|
||||
mac80211->driver: sta_state(AP, exists)
|
||||
|
||||
alt no probe request data known
|
||||
mac80211->driver: TX directed probe request
|
||||
driver->mac80211: RX probe response
|
||||
end
|
||||
|
||||
mac80211->driver: TX auth frame
|
||||
driver->mac80211: RX auth frame
|
||||
|
||||
alt WEP shared key auth
|
||||
mac80211->driver: TX auth frame
|
||||
driver->mac80211: RX auth frame
|
||||
end
|
||||
|
||||
mac80211->driver: sta_state(AP, authenticated)
|
||||
mac80211->userspace: RX auth frame
|
||||
|
||||
end
|
||||
|
||||
userspace->mac80211: associate
|
||||
alt authenticated or associated
|
||||
note over mac80211,driver: cleanup like for authenticate
|
||||
end
|
||||
|
||||
alt not previously authenticated (FT)
|
||||
mac80211->driver: config(channel, non-HT)
|
||||
mac80211->driver: bss_info_changed(set BSSID, basic rate bitmap)
|
||||
mac80211->driver: sta_state(AP, exists)
|
||||
mac80211->driver: sta_state(AP, authenticated)
|
||||
end
|
||||
mac80211->driver: TX assoc
|
||||
driver->mac80211: RX assoc response
|
||||
note over mac80211: init rate control
|
||||
mac80211->driver: sta_state(AP, associated)
|
||||
|
||||
alt not using WPA
|
||||
mac80211->driver: sta_state(AP, authorized)
|
||||
end
|
||||
|
||||
mac80211->driver: set up QoS parameters
|
||||
|
||||
alt is HT channel
|
||||
mac80211->driver: config(channel, HT params)
|
||||
end
|
||||
|
||||
mac80211->driver: bss_info_changed(QoS, HT, associated with AID)
|
||||
mac80211->userspace: associated
|
||||
|
||||
note left of userspace: associated now
|
||||
|
||||
alt using WPA
|
||||
note over userspace
|
||||
do 4-way-handshake
|
||||
(data frames)
|
||||
end note
|
||||
userspace->mac80211: authorized
|
||||
mac80211->driver: sta_state(AP, authorized)
|
||||
end
|
||||
|
||||
userspace->mac80211: deauthenticate/disassociate
|
||||
mac80211->driver: stop BA sessions
|
||||
mac80211->driver: TX deauth/disassoc
|
||||
mac80211->driver: flush frames
|
||||
mac80211->driver: sta_state(AP,associated)
|
||||
mac80211->driver: sta_state(AP,authenticated)
|
||||
mac80211->driver: sta_state(AP,exists)
|
||||
mac80211->driver: sta_state(AP,not-exists)
|
||||
mac80211->driver: turn off powersave
|
||||
mac80211->driver: bss_info_changed(clear BSSID, not associated, no QoS, ...)
|
||||
mac80211->driver: config(non-HT channel type)
|
||||
mac80211->userspace: disconnected
|
@ -174,28 +174,24 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry);
|
||||
void ath_hw_cycle_counters_update(struct ath_common *common);
|
||||
int32_t ath_hw_get_listen_time(struct ath_common *common);
|
||||
|
||||
extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...);
|
||||
|
||||
#define _ath_printk(level, common, fmt, ...) \
|
||||
do { \
|
||||
__always_unused struct ath_common *unused = common; \
|
||||
ath_printk(level, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
__printf(3, 4)
|
||||
void ath_printk(const char *level, const struct ath_common *common,
|
||||
const char *fmt, ...);
|
||||
|
||||
#define ath_emerg(common, fmt, ...) \
|
||||
_ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__)
|
||||
ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__)
|
||||
#define ath_alert(common, fmt, ...) \
|
||||
_ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__)
|
||||
ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__)
|
||||
#define ath_crit(common, fmt, ...) \
|
||||
_ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__)
|
||||
ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__)
|
||||
#define ath_err(common, fmt, ...) \
|
||||
_ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__)
|
||||
ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__)
|
||||
#define ath_warn(common, fmt, ...) \
|
||||
_ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__)
|
||||
ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__)
|
||||
#define ath_notice(common, fmt, ...) \
|
||||
_ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__)
|
||||
ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__)
|
||||
#define ath_info(common, fmt, ...) \
|
||||
_ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__)
|
||||
ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* enum ath_debug_level - atheros wireless debug level
|
||||
@ -256,7 +252,7 @@ enum ATH_DEBUG {
|
||||
#define ath_dbg(common, dbg_mask, fmt, ...) \
|
||||
do { \
|
||||
if ((common)->debug_mask & ATH_DBG_##dbg_mask) \
|
||||
_ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \
|
||||
ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ATH_DBG_WARN(foo, arg...) WARN(foo, arg)
|
||||
|
@ -1,5 +1,6 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# Copyright (c) 2004-2010 Atheros Communications Inc.
|
||||
# Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
# Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -105,7 +106,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n",
|
||||
targ_info->version, targ_info->type);
|
||||
targ_info->version, targ_info->type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -192,7 +193,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
|
||||
memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BMI,
|
||||
"bmi write memory: addr: 0x%x, len: %d\n", addr, len);
|
||||
"bmi write memory: addr: 0x%x, len: %d\n", addr, len);
|
||||
|
||||
len_remain = len;
|
||||
while (len_remain) {
|
||||
@ -434,7 +435,7 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
|
||||
memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
|
||||
offset += sizeof(tx_len);
|
||||
memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain],
|
||||
tx_len);
|
||||
tx_len);
|
||||
offset += tx_len;
|
||||
|
||||
ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -222,6 +223,29 @@ struct ath6kl_bmi_target_info {
|
||||
__le32 type; /* target type */
|
||||
} __packed;
|
||||
|
||||
#define ath6kl_bmi_write_hi32(ar, item, val) \
|
||||
({ \
|
||||
u32 addr; \
|
||||
__le32 v; \
|
||||
\
|
||||
addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \
|
||||
v = cpu_to_le32(val); \
|
||||
ath6kl_bmi_write(ar, addr, (u8 *) &v, sizeof(v)); \
|
||||
})
|
||||
|
||||
#define ath6kl_bmi_read_hi32(ar, item, val) \
|
||||
({ \
|
||||
u32 addr, *check_type = val; \
|
||||
__le32 tmp; \
|
||||
int ret; \
|
||||
\
|
||||
(void) (check_type == val); \
|
||||
addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \
|
||||
ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \
|
||||
*val = le32_to_cpu(tmp); \
|
||||
ret; \
|
||||
})
|
||||
|
||||
int ath6kl_bmi_init(struct ath6kl *ar);
|
||||
void ath6kl_bmi_cleanup(struct ath6kl *ar);
|
||||
void ath6kl_bmi_reset(struct ath6kl *ar);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -68,6 +69,10 @@ static struct ieee80211_rate ath6kl_rates[] = {
|
||||
#define ath6kl_g_rates (ath6kl_rates + 0)
|
||||
#define ath6kl_g_rates_size 12
|
||||
|
||||
#define ath6kl_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
|
||||
IEEE80211_HT_CAP_SGI_20 | \
|
||||
IEEE80211_HT_CAP_SGI_40)
|
||||
|
||||
static struct ieee80211_channel ath6kl_2ghz_channels[] = {
|
||||
CHAN2G(1, 2412, 0),
|
||||
CHAN2G(2, 2417, 0),
|
||||
@ -112,6 +117,8 @@ static struct ieee80211_supported_band ath6kl_band_2ghz = {
|
||||
.channels = ath6kl_2ghz_channels,
|
||||
.n_bitrates = ath6kl_g_rates_size,
|
||||
.bitrates = ath6kl_g_rates,
|
||||
.ht_cap.cap = ath6kl_g_htcap,
|
||||
.ht_cap.ht_supported = true,
|
||||
};
|
||||
|
||||
static struct ieee80211_supported_band ath6kl_band_5ghz = {
|
||||
@ -119,6 +126,8 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = {
|
||||
.channels = ath6kl_5ghz_a_channels,
|
||||
.n_bitrates = ath6kl_a_rates_size,
|
||||
.bitrates = ath6kl_a_rates,
|
||||
.ht_cap.cap = ath6kl_g_htcap,
|
||||
.ht_cap.ht_supported = true,
|
||||
};
|
||||
|
||||
#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
|
||||
@ -381,7 +390,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
|
||||
return false;
|
||||
|
||||
if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
|
||||
ar->num_vif))
|
||||
ar->num_vif))
|
||||
return false;
|
||||
|
||||
if (type == NL80211_IFTYPE_STATION ||
|
||||
@ -407,6 +416,12 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ath6kl_is_tx_pending(struct ath6kl *ar)
|
||||
{
|
||||
return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
|
||||
}
|
||||
|
||||
|
||||
static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_connect_params *sme)
|
||||
{
|
||||
@ -414,6 +429,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||
int status;
|
||||
u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
|
||||
u16 interval;
|
||||
|
||||
ath6kl_cfg80211_sscan_disable(vif);
|
||||
|
||||
@ -450,8 +466,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
* sleep until the command queue drains
|
||||
*/
|
||||
wait_event_interruptible_timeout(ar->event_wq,
|
||||
ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
|
||||
WMI_TIMEOUT);
|
||||
ath6kl_is_tx_pending(ar),
|
||||
WMI_TIMEOUT);
|
||||
if (signal_pending(current)) {
|
||||
ath6kl_err("cmd queue drain timeout\n");
|
||||
up(&ar->sem);
|
||||
@ -546,7 +562,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
if (!ar->usr_bss_filter) {
|
||||
clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
|
||||
if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
ALL_BSS_FILTER, 0) != 0) {
|
||||
ALL_BSS_FILTER, 0) != 0) {
|
||||
ath6kl_err("couldn't set bss filtering\n");
|
||||
up(&ar->sem);
|
||||
return -EIO;
|
||||
@ -568,6 +584,20 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
vif->grp_crypto_len, vif->ch_hint);
|
||||
|
||||
vif->reconnect_flag = 0;
|
||||
|
||||
if (vif->nw_type == INFRA_NETWORK) {
|
||||
interval = max_t(u16, vif->listen_intvl_t,
|
||||
ATH6KL_MAX_WOW_LISTEN_INTL);
|
||||
status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
interval,
|
||||
0);
|
||||
if (status) {
|
||||
ath6kl_err("couldn't set listen intervel\n");
|
||||
up(&ar->sem);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
|
||||
vif->dot11_auth_mode, vif->auth_mode,
|
||||
vif->prwise_crypto,
|
||||
@ -590,8 +620,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
}
|
||||
|
||||
if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
|
||||
((vif->auth_mode == WPA_PSK_AUTH)
|
||||
|| (vif->auth_mode == WPA2_PSK_AUTH))) {
|
||||
((vif->auth_mode == WPA_PSK_AUTH) ||
|
||||
(vif->auth_mode == WPA2_PSK_AUTH))) {
|
||||
mod_timer(&vif->disconnect_timer,
|
||||
jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
|
||||
}
|
||||
@ -824,13 +854,13 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
|
||||
|
||||
if (vif->sme_state == SME_CONNECTING) {
|
||||
cfg80211_connect_result(vif->ndev,
|
||||
bssid, NULL, 0,
|
||||
NULL, 0,
|
||||
WLAN_STATUS_UNSPECIFIED_FAILURE,
|
||||
GFP_KERNEL);
|
||||
bssid, NULL, 0,
|
||||
NULL, 0,
|
||||
WLAN_STATUS_UNSPECIFIED_FAILURE,
|
||||
GFP_KERNEL);
|
||||
} else if (vif->sme_state == SME_CONNECTED) {
|
||||
cfg80211_disconnected(vif->ndev, reason,
|
||||
NULL, 0, GFP_KERNEL);
|
||||
NULL, 0, GFP_KERNEL);
|
||||
}
|
||||
|
||||
vif->sme_state = SME_DISCONNECTED;
|
||||
@ -876,19 +906,14 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
request->ssids[i].ssid);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: we should clear the IE in fw if it's not set so just
|
||||
* remove the check altogether
|
||||
*/
|
||||
if (request->ie) {
|
||||
ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
WMI_FRAME_PROBE_REQ,
|
||||
request->ie, request->ie_len);
|
||||
if (ret) {
|
||||
ath6kl_err("failed to set Probe Request appie for "
|
||||
"scan");
|
||||
return ret;
|
||||
}
|
||||
/* this also clears IE in fw if it's not set */
|
||||
ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
WMI_FRAME_PROBE_REQ,
|
||||
request->ie, request->ie_len);
|
||||
if (ret) {
|
||||
ath6kl_err("failed to set Probe Request appie for "
|
||||
"scan");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -917,7 +942,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
force_fg_scan = 1;
|
||||
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
|
||||
ar->fw_capabilities)) {
|
||||
ar->fw_capabilities)) {
|
||||
/*
|
||||
* If capable of doing P2P mgmt operations using
|
||||
* station interface, send additional information like
|
||||
@ -926,14 +951,17 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
*/
|
||||
ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
WMI_LONG_SCAN, force_fg_scan,
|
||||
false, 0, 0, n_channels,
|
||||
channels, request->no_cck,
|
||||
false, 0,
|
||||
ATH6KL_FG_SCAN_INTERVAL,
|
||||
n_channels, channels,
|
||||
request->no_cck,
|
||||
request->rates);
|
||||
} else {
|
||||
ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
WMI_LONG_SCAN, force_fg_scan,
|
||||
false, 0, 0, n_channels,
|
||||
channels);
|
||||
false, 0,
|
||||
ATH6KL_FG_SCAN_INTERVAL,
|
||||
n_channels, channels);
|
||||
}
|
||||
if (ret)
|
||||
ath6kl_err("wmi_startscan_cmd failed\n");
|
||||
@ -1046,9 +1074,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (((vif->auth_mode == WPA_PSK_AUTH)
|
||||
|| (vif->auth_mode == WPA2_PSK_AUTH))
|
||||
&& (key_usage & GROUP_USAGE))
|
||||
if (((vif->auth_mode == WPA_PSK_AUTH) ||
|
||||
(vif->auth_mode == WPA2_PSK_AUTH)) &&
|
||||
(key_usage & GROUP_USAGE))
|
||||
del_timer(&vif->disconnect_timer);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
|
||||
@ -1058,7 +1086,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
|
||||
if (vif->nw_type == AP_NETWORK && !pairwise &&
|
||||
(key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
|
||||
key_type == WAPI_CRYPT) && params) {
|
||||
key_type == WAPI_CRYPT)) {
|
||||
ar->ap_mode_bkey.valid = true;
|
||||
ar->ap_mode_bkey.key_index = key_index;
|
||||
ar->ap_mode_bkey.key_type = key_type;
|
||||
@ -1263,7 +1291,6 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
|
||||
{
|
||||
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
|
||||
struct ath6kl_vif *vif;
|
||||
u8 ath6kl_dbm;
|
||||
int dbm = MBM_TO_DBM(mbm);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
|
||||
@ -1280,7 +1307,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
|
||||
case NL80211_TX_POWER_AUTOMATIC:
|
||||
return 0;
|
||||
case NL80211_TX_POWER_LIMITED:
|
||||
ar->tx_pwr = ath6kl_dbm = dbm;
|
||||
ar->tx_pwr = dbm;
|
||||
break;
|
||||
default:
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
|
||||
@ -1288,7 +1315,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);
|
||||
ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1349,7 +1376,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
mode.pwr_mode) != 0) {
|
||||
mode.pwr_mode) != 0) {
|
||||
ath6kl_err("wmi_powermode_cmd failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
@ -1904,7 +1931,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
||||
struct ath6kl_vif *vif;
|
||||
int ret, left;
|
||||
u32 filter = 0;
|
||||
u16 i;
|
||||
u16 i, bmiss_time;
|
||||
u8 index = 0;
|
||||
__be32 ips[MAX_IP_ADDRS];
|
||||
|
||||
@ -1941,6 +1968,34 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
netif_stop_queue(vif->ndev);
|
||||
|
||||
if (vif->nw_type != AP_NETWORK) {
|
||||
ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
ATH6KL_MAX_WOW_LISTEN_INTL,
|
||||
0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set listen interval x 15 times as bmiss time */
|
||||
bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
|
||||
if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
|
||||
bmiss_time = ATH6KL_MAX_BMISS_TIME;
|
||||
|
||||
ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
bmiss_time, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
0xFFFF, 0, 0xFFFF, 0, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ar->state = ATH6KL_STATE_SUSPENDING;
|
||||
|
||||
/* Setup own IP addr for ARP agent. */
|
||||
in_dev = __in_dev_get_rtnl(vif->ndev);
|
||||
if (!in_dev)
|
||||
@ -2019,15 +2074,46 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
|
||||
if (!vif)
|
||||
return -EIO;
|
||||
|
||||
ar->state = ATH6KL_STATE_RESUMING;
|
||||
|
||||
ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
ATH6KL_HOST_MODE_AWAKE);
|
||||
return ret;
|
||||
if (ret) {
|
||||
ath6kl_warn("Failed to configure host sleep mode for "
|
||||
"wow resume: %d\n", ret);
|
||||
ar->state = ATH6KL_STATE_WOW;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (vif->nw_type != AP_NETWORK) {
|
||||
ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
vif->listen_intvl_t, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
vif->bmiss_time_t, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ar->state = ATH6KL_STATE_ON;
|
||||
|
||||
netif_wake_queue(vif->ndev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath6kl_cfg80211_suspend(struct ath6kl *ar,
|
||||
enum ath6kl_cfg_suspend_mode mode,
|
||||
struct cfg80211_wowlan *wow)
|
||||
{
|
||||
enum ath6kl_state prev_state;
|
||||
int ret;
|
||||
|
||||
switch (mode) {
|
||||
@ -2038,11 +2124,14 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
|
||||
/* Flush all non control pkts in TX path */
|
||||
ath6kl_tx_data_cleanup(ar);
|
||||
|
||||
prev_state = ar->state;
|
||||
|
||||
ret = ath6kl_wow_suspend(ar, wow);
|
||||
if (ret) {
|
||||
ath6kl_err("wow suspend failed: %d\n", ret);
|
||||
ar->state = prev_state;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ar->state = ATH6KL_STATE_WOW;
|
||||
break;
|
||||
|
||||
@ -2114,7 +2203,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ar->state = ATH6KL_STATE_ON;
|
||||
break;
|
||||
|
||||
case ATH6KL_STATE_DEEPSLEEP:
|
||||
@ -2188,6 +2276,9 @@ static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
|
||||
*/
|
||||
void ath6kl_check_wow_status(struct ath6kl *ar)
|
||||
{
|
||||
if (ar->state == ATH6KL_STATE_SUSPENDING)
|
||||
return;
|
||||
|
||||
if (ar->state == ATH6KL_STATE_WOW)
|
||||
ath6kl_cfg80211_resume(ar);
|
||||
}
|
||||
@ -2275,30 +2366,27 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
|
||||
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;
|
||||
}
|
||||
/* this also clears IE in fw if it's not set */
|
||||
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;
|
||||
}
|
||||
/* this also clears IE in fw if it's not set */
|
||||
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;
|
||||
}
|
||||
/* this also clears IE in fw if it's not set */
|
||||
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;
|
||||
}
|
||||
@ -2309,6 +2397,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ath6kl *ar = ath6kl_priv(dev);
|
||||
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
bool hidden = false;
|
||||
u8 *ies;
|
||||
int ies_len;
|
||||
struct wmi_connect_cmd p;
|
||||
@ -2345,7 +2434,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
memcpy(vif->ssid, info->ssid, info->ssid_len);
|
||||
vif->ssid_len = info->ssid_len;
|
||||
if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
|
||||
return -EOPNOTSUPP; /* TODO */
|
||||
hidden = true;
|
||||
|
||||
res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
ret = ath6kl_set_auth_type(vif, info->auth_type);
|
||||
if (ret)
|
||||
@ -2584,6 +2677,76 @@ static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
|
||||
u32 id,
|
||||
u32 freq,
|
||||
u32 wait,
|
||||
const u8 *buf,
|
||||
size_t len,
|
||||
bool *more_data,
|
||||
bool no_cck)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
struct ath6kl_sta *conn;
|
||||
bool is_psq_empty = false;
|
||||
struct ath6kl_mgmt_buff *mgmt_buf;
|
||||
size_t mgmt_buf_size;
|
||||
struct ath6kl *ar = vif->ar;
|
||||
|
||||
mgmt = (struct ieee80211_mgmt *) buf;
|
||||
if (is_multicast_ether_addr(mgmt->da))
|
||||
return false;
|
||||
|
||||
conn = ath6kl_find_sta(vif, mgmt->da);
|
||||
if (!conn)
|
||||
return false;
|
||||
|
||||
if (conn->sta_flags & STA_PS_SLEEP) {
|
||||
if (!(conn->sta_flags & STA_PS_POLLED)) {
|
||||
/* Queue the frames if the STA is sleeping */
|
||||
mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
|
||||
mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
|
||||
if (!mgmt_buf)
|
||||
return false;
|
||||
|
||||
INIT_LIST_HEAD(&mgmt_buf->list);
|
||||
mgmt_buf->id = id;
|
||||
mgmt_buf->freq = freq;
|
||||
mgmt_buf->wait = wait;
|
||||
mgmt_buf->len = len;
|
||||
mgmt_buf->no_cck = no_cck;
|
||||
memcpy(mgmt_buf->buf, buf, len);
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
is_psq_empty = skb_queue_empty(&conn->psq) &&
|
||||
(conn->mgmt_psq_len == 0);
|
||||
list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
|
||||
conn->mgmt_psq_len++;
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
|
||||
/*
|
||||
* If this is the first pkt getting queued
|
||||
* for this STA, update the PVB for this
|
||||
* STA.
|
||||
*/
|
||||
if (is_psq_empty)
|
||||
ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
conn->aid, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This tx is because of a PsPoll.
|
||||
* Determine if MoreData bit has to be set.
|
||||
*/
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
|
||||
*more_data = true;
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
enum nl80211_channel_type channel_type,
|
||||
@ -2595,6 +2758,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||
u32 id;
|
||||
const struct ieee80211_mgmt *mgmt;
|
||||
bool more_data, queued;
|
||||
|
||||
mgmt = (const struct ieee80211_mgmt *) buf;
|
||||
if (buf + len >= mgmt->u.probe_resp.variable &&
|
||||
@ -2620,22 +2784,19 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
*cookie = id;
|
||||
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
|
||||
ar->fw_capabilities)) {
|
||||
/*
|
||||
* If capable of doing P2P mgmt operations using
|
||||
* station interface, send additional information like
|
||||
* supported rates to advertise and xmit rates for
|
||||
* probe requests
|
||||
*/
|
||||
return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
|
||||
chan->center_freq, wait,
|
||||
buf, len, no_cck);
|
||||
} else {
|
||||
return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id,
|
||||
chan->center_freq, wait,
|
||||
buf, len);
|
||||
/* AP mode Power saving processing */
|
||||
if (vif->nw_type == AP_NETWORK) {
|
||||
queued = ath6kl_mgmt_powersave_ap(vif,
|
||||
id, chan->center_freq,
|
||||
wait, buf,
|
||||
len, &more_data, no_cck);
|
||||
if (queued)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
|
||||
chan->center_freq, wait,
|
||||
buf, len, no_cck);
|
||||
}
|
||||
|
||||
static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
|
||||
@ -2929,7 +3090,10 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
|
||||
vif->wdev.netdev = ndev;
|
||||
vif->wdev.iftype = type;
|
||||
vif->fw_vif_idx = fw_vif_idx;
|
||||
vif->nw_type = vif->next_mode = nw_type;
|
||||
vif->nw_type = nw_type;
|
||||
vif->next_mode = nw_type;
|
||||
vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
|
||||
vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
|
||||
|
||||
memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
|
||||
if (fw_vif_idx != 0)
|
||||
@ -3009,18 +3173,36 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||
|
||||
wiphy->max_sched_scan_ssids = 10;
|
||||
|
||||
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
|
||||
WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
|
||||
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
|
||||
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
|
||||
|
||||
ar->wiphy->probe_resp_offload =
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
|
||||
|
||||
ret = wiphy_register(wiphy);
|
||||
if (ret < 0) {
|
||||
ath6kl_err("couldn't register wiphy device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ar->wiphy_registered = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
|
||||
{
|
||||
wiphy_unregister(ar->wiphy);
|
||||
|
||||
ar->wiphy_registered = false;
|
||||
}
|
||||
|
||||
struct ath6kl *ath6kl_cfg80211_create(void)
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -26,12 +27,14 @@
|
||||
|
||||
unsigned int debug_mask;
|
||||
static unsigned int suspend_mode;
|
||||
static unsigned int wow_mode;
|
||||
static unsigned int uart_debug;
|
||||
static unsigned int ath6kl_p2p;
|
||||
static unsigned int testmode;
|
||||
|
||||
module_param(debug_mask, uint, 0644);
|
||||
module_param(suspend_mode, uint, 0644);
|
||||
module_param(wow_mode, uint, 0644);
|
||||
module_param(uart_debug, uint, 0644);
|
||||
module_param(ath6kl_p2p, uint, 0644);
|
||||
module_param(testmode, uint, 0644);
|
||||
@ -97,14 +100,59 @@ int ath6kl_core_init(struct ath6kl *ar)
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
|
||||
|
||||
/* setup access class priority mappings */
|
||||
ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */
|
||||
ar->ac_stream_pri_map[WMM_AC_BE] = 1;
|
||||
ar->ac_stream_pri_map[WMM_AC_VI] = 2;
|
||||
ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
|
||||
|
||||
/* allocate some buffers that handle larger AMSDU frames */
|
||||
ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
|
||||
|
||||
ath6kl_cookie_init(ar);
|
||||
|
||||
ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
|
||||
ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
|
||||
|
||||
if (suspend_mode &&
|
||||
suspend_mode >= WLAN_POWER_STATE_CUT_PWR &&
|
||||
suspend_mode <= WLAN_POWER_STATE_WOW)
|
||||
ar->suspend_mode = suspend_mode;
|
||||
else
|
||||
ar->suspend_mode = 0;
|
||||
|
||||
if (suspend_mode == WLAN_POWER_STATE_WOW &&
|
||||
(wow_mode == WLAN_POWER_STATE_CUT_PWR ||
|
||||
wow_mode == WLAN_POWER_STATE_DEEP_SLEEP))
|
||||
ar->wow_suspend_mode = wow_mode;
|
||||
else
|
||||
ar->wow_suspend_mode = 0;
|
||||
|
||||
if (uart_debug)
|
||||
ar->conf_flags |= ATH6KL_CONF_UART_DEBUG;
|
||||
|
||||
set_bit(FIRST_BOOT, &ar->flag);
|
||||
|
||||
ath6kl_debug_init(ar);
|
||||
|
||||
ret = ath6kl_init_hw_start(ar);
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to start hardware: %d\n", ret);
|
||||
goto err_rxbuf_cleanup;
|
||||
}
|
||||
|
||||
/* give our connected endpoints some buffers */
|
||||
ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
|
||||
ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
|
||||
|
||||
ret = ath6kl_cfg80211_init(ar);
|
||||
if (ret)
|
||||
goto err_node_cleanup;
|
||||
goto err_rxbuf_cleanup;
|
||||
|
||||
ret = ath6kl_debug_init(ar);
|
||||
ret = ath6kl_debug_init_fs(ar);
|
||||
if (ret) {
|
||||
wiphy_unregister(ar->wiphy);
|
||||
goto err_node_cleanup;
|
||||
goto err_rxbuf_cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < ar->vif_max; i++)
|
||||
@ -122,83 +170,18 @@ int ath6kl_core_init(struct ath6kl *ar)
|
||||
ath6kl_err("Failed to instantiate a network device\n");
|
||||
ret = -ENOMEM;
|
||||
wiphy_unregister(ar->wiphy);
|
||||
goto err_debug_init;
|
||||
}
|
||||
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
|
||||
__func__, ndev->name, ndev, ar);
|
||||
|
||||
/* setup access class priority mappings */
|
||||
ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */
|
||||
ar->ac_stream_pri_map[WMM_AC_BE] = 1;
|
||||
ar->ac_stream_pri_map[WMM_AC_VI] = 2;
|
||||
ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
|
||||
|
||||
/* give our connected endpoints some buffers */
|
||||
ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
|
||||
ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
|
||||
|
||||
/* allocate some buffers that handle larger AMSDU frames */
|
||||
ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
|
||||
|
||||
ath6kl_cookie_init(ar);
|
||||
|
||||
ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
|
||||
ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
|
||||
|
||||
if (suspend_mode &&
|
||||
suspend_mode >= WLAN_POWER_STATE_CUT_PWR &&
|
||||
suspend_mode <= WLAN_POWER_STATE_WOW)
|
||||
ar->suspend_mode = suspend_mode;
|
||||
else
|
||||
ar->suspend_mode = 0;
|
||||
|
||||
if (uart_debug)
|
||||
ar->conf_flags |= ATH6KL_CONF_UART_DEBUG;
|
||||
|
||||
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
|
||||
WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
|
||||
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
|
||||
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
|
||||
|
||||
ar->wiphy->probe_resp_offload =
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
|
||||
|
||||
set_bit(FIRST_BOOT, &ar->flag);
|
||||
|
||||
ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
|
||||
ret = ath6kl_init_hw_start(ar);
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to start hardware: %d\n", ret);
|
||||
goto err_rxbuf_cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set mac address which is received in ready event
|
||||
* FIXME: Move to ath6kl_interface_add()
|
||||
*/
|
||||
memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
|
||||
__func__, ndev->name, ndev, ar);
|
||||
|
||||
return ret;
|
||||
|
||||
err_rxbuf_cleanup:
|
||||
ath6kl_debug_cleanup(ar);
|
||||
ath6kl_htc_flush_rx_buf(ar->htc_target);
|
||||
ath6kl_cleanup_amsdu_rxbufs(ar);
|
||||
rtnl_lock();
|
||||
ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev));
|
||||
rtnl_unlock();
|
||||
wiphy_unregister(ar->wiphy);
|
||||
err_debug_init:
|
||||
ath6kl_debug_cleanup(ar);
|
||||
err_node_cleanup:
|
||||
ath6kl_wmi_shutdown(ar->wmi);
|
||||
clear_bit(WMI_ENABLED, &ar->flag);
|
||||
ar->wmi = NULL;
|
||||
@ -245,9 +228,7 @@ struct ath6kl *ath6kl_core_create(struct device *dev)
|
||||
clear_bit(SKIP_SCAN, &ar->flag);
|
||||
clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
|
||||
|
||||
ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL;
|
||||
ar->tx_pwr = 0;
|
||||
|
||||
ar->intra_bss = 1;
|
||||
ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
|
||||
|
||||
@ -261,6 +242,8 @@ struct ath6kl *ath6kl_core_create(struct device *dev)
|
||||
spin_lock_init(&ar->sta_list[ctr].psq_lock);
|
||||
skb_queue_head_init(&ar->sta_list[ctr].psq);
|
||||
skb_queue_head_init(&ar->sta_list[ctr].apsdq);
|
||||
ar->sta_list[ctr].mgmt_psq_len = 0;
|
||||
INIT_LIST_HEAD(&ar->sta_list[ctr].mgmt_psq);
|
||||
ar->sta_list[ctr].aggr_conn =
|
||||
kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
|
||||
if (!ar->sta_list[ctr].aggr_conn) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -59,8 +60,9 @@
|
||||
#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
|
||||
|
||||
#define DISCON_TIMER_INTVAL 10000 /* in msec */
|
||||
#define A_DEFAULT_LISTEN_INTERVAL 1 /* beacon intervals */
|
||||
#define A_MAX_WOW_LISTEN_INTERVAL 1000
|
||||
|
||||
/* Channel dwell time in fg scan */
|
||||
#define ATH6KL_FG_SCAN_INTERVAL 50 /* in ms */
|
||||
|
||||
/* includes also the null byte */
|
||||
#define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL"
|
||||
@ -183,6 +185,11 @@ struct ath6kl_fw_ie {
|
||||
|
||||
#define MBOX_YIELD_LIMIT 99
|
||||
|
||||
#define ATH6KL_DEFAULT_LISTEN_INTVAL 100 /* in TUs */
|
||||
#define ATH6KL_DEFAULT_BMISS_TIME 1500
|
||||
#define ATH6KL_MAX_WOW_LISTEN_INTL 300 /* in TUs */
|
||||
#define ATH6KL_MAX_BMISS_TIME 5000
|
||||
|
||||
/* configuration lags */
|
||||
/*
|
||||
* ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in
|
||||
@ -226,6 +233,12 @@ struct rxtid {
|
||||
u32 hold_q_sz;
|
||||
struct skb_hold_q *hold_q;
|
||||
struct sk_buff_head q;
|
||||
|
||||
/*
|
||||
* FIXME: No clue what this should protect. Apparently it should
|
||||
* protect some of the fields above but they are also accessed
|
||||
* without taking the lock.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
@ -285,6 +298,16 @@ struct ath6kl_cookie {
|
||||
struct ath6kl_cookie *arc_list_next;
|
||||
};
|
||||
|
||||
struct ath6kl_mgmt_buff {
|
||||
struct list_head list;
|
||||
u32 freq;
|
||||
u32 wait;
|
||||
u32 id;
|
||||
bool no_cck;
|
||||
size_t len;
|
||||
u8 buf[0];
|
||||
};
|
||||
|
||||
struct ath6kl_sta {
|
||||
u16 sta_flags;
|
||||
u8 mac[ETH_ALEN];
|
||||
@ -294,7 +317,12 @@ struct ath6kl_sta {
|
||||
u8 auth;
|
||||
u8 wpa_ie[ATH6KL_MAX_IE];
|
||||
struct sk_buff_head psq;
|
||||
|
||||
/* protects psq, mgmt_psq, apsdq, and mgmt_psq_len fields */
|
||||
spinlock_t psq_lock;
|
||||
|
||||
struct list_head mgmt_psq;
|
||||
size_t mgmt_psq_len;
|
||||
u8 apsd_info;
|
||||
struct sk_buff_head apsdq;
|
||||
struct aggr_info_conn *aggr_conn;
|
||||
@ -494,6 +522,8 @@ struct ath6kl_vif {
|
||||
bool probe_req_report;
|
||||
u16 next_chan;
|
||||
u16 assoc_bss_beacon_int;
|
||||
u16 listen_intvl_t;
|
||||
u16 bmiss_time_t;
|
||||
u8 assoc_bss_dtim_period;
|
||||
struct net_device_stats net_stats;
|
||||
struct target_stats target_stats;
|
||||
@ -521,6 +551,8 @@ enum ath6kl_dev_state {
|
||||
enum ath6kl_state {
|
||||
ATH6KL_STATE_OFF,
|
||||
ATH6KL_STATE_ON,
|
||||
ATH6KL_STATE_SUSPENDING,
|
||||
ATH6KL_STATE_RESUMING,
|
||||
ATH6KL_STATE_DEEPSLEEP,
|
||||
ATH6KL_STATE_CUTPOWER,
|
||||
ATH6KL_STATE_WOW,
|
||||
@ -549,9 +581,14 @@ struct ath6kl {
|
||||
unsigned int vif_max;
|
||||
u8 max_norm_iface;
|
||||
u8 avail_idx_map;
|
||||
|
||||
/*
|
||||
* Protects at least amsdu_rx_buffer_queue, ath6kl_alloc_cookie()
|
||||
* calls, tx_pending and total_tx_data_pend.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
|
||||
struct semaphore sem;
|
||||
u16 listen_intvl_b;
|
||||
u8 lrssi_roam_threshold;
|
||||
struct ath6kl_version version;
|
||||
u32 target_type;
|
||||
@ -577,7 +614,13 @@ struct ath6kl {
|
||||
u8 sta_list_index;
|
||||
struct ath6kl_req_key ap_mode_bkey;
|
||||
struct sk_buff_head mcastpsq;
|
||||
|
||||
/*
|
||||
* FIXME: protects access to mcastpsq but is actually useless as
|
||||
* all skbe_queue_*() functions provide serialisation themselves
|
||||
*/
|
||||
spinlock_t mcastpsq_lock;
|
||||
|
||||
u8 intra_bss;
|
||||
struct wmi_ap_mode_stat ap_stats;
|
||||
u8 ap_country_code[3];
|
||||
@ -620,6 +663,7 @@ struct ath6kl {
|
||||
|
||||
u16 conf_flags;
|
||||
u16 suspend_mode;
|
||||
u16 wow_suspend_mode;
|
||||
wait_queue_head_t event_wq;
|
||||
struct ath6kl_mbox_info mbox_info;
|
||||
|
||||
@ -650,12 +694,16 @@ struct ath6kl {
|
||||
|
||||
bool p2p;
|
||||
|
||||
bool wiphy_registered;
|
||||
|
||||
#ifdef CONFIG_ATH6KL_DEBUG
|
||||
struct {
|
||||
struct circ_buf fwlog_buf;
|
||||
spinlock_t fwlog_lock;
|
||||
void *fwlog_tmp;
|
||||
struct sk_buff_head fwlog_queue;
|
||||
struct completion fwlog_completion;
|
||||
bool fwlog_open;
|
||||
|
||||
u32 fwlog_mask;
|
||||
|
||||
unsigned int dbgfs_diag_reg;
|
||||
u32 diag_reg_addr_wr;
|
||||
u32 diag_reg_val_wr;
|
||||
@ -727,10 +775,10 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
|
||||
void aggr_module_destroy(struct aggr_info *aggr_info);
|
||||
void aggr_reset_state(struct aggr_info_conn *aggr_conn);
|
||||
|
||||
struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr);
|
||||
struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr);
|
||||
struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
|
||||
|
||||
void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver);
|
||||
void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver);
|
||||
int ath6kl_control_tx(void *devt, struct sk_buff *skb,
|
||||
enum htc_endpoint_id eid);
|
||||
void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,7 +17,7 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/export.h>
|
||||
@ -32,9 +33,8 @@ struct ath6kl_fwlog_slot {
|
||||
u8 payload[0];
|
||||
};
|
||||
|
||||
#define ATH6KL_FWLOG_SIZE 32768
|
||||
#define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \
|
||||
ATH6KL_FWLOG_PAYLOAD_SIZE)
|
||||
#define ATH6KL_FWLOG_MAX_ENTRIES 20
|
||||
|
||||
#define ATH6KL_FWLOG_VALID_MASK 0x1ffff
|
||||
|
||||
int ath6kl_printk(const char *level, const char *fmt, ...)
|
||||
@ -119,29 +119,29 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
|
||||
|
||||
if (irq_proc_reg != NULL) {
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Host Int status: 0x%x\n",
|
||||
irq_proc_reg->host_int_status);
|
||||
"Host Int status: 0x%x\n",
|
||||
irq_proc_reg->host_int_status);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"CPU Int status: 0x%x\n",
|
||||
irq_proc_reg->cpu_int_status);
|
||||
irq_proc_reg->cpu_int_status);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Error Int status: 0x%x\n",
|
||||
irq_proc_reg->error_int_status);
|
||||
irq_proc_reg->error_int_status);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Counter Int status: 0x%x\n",
|
||||
irq_proc_reg->counter_int_status);
|
||||
irq_proc_reg->counter_int_status);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Mbox Frame: 0x%x\n",
|
||||
irq_proc_reg->mbox_frame);
|
||||
irq_proc_reg->mbox_frame);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Rx Lookahead Valid: 0x%x\n",
|
||||
irq_proc_reg->rx_lkahd_valid);
|
||||
irq_proc_reg->rx_lkahd_valid);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Rx Lookahead 0: 0x%x\n",
|
||||
irq_proc_reg->rx_lkahd[0]);
|
||||
irq_proc_reg->rx_lkahd[0]);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Rx Lookahead 1: 0x%x\n",
|
||||
irq_proc_reg->rx_lkahd[1]);
|
||||
irq_proc_reg->rx_lkahd[1]);
|
||||
|
||||
if (dev->ar->mbox_info.gmbox_addr != 0) {
|
||||
/*
|
||||
@ -149,27 +149,27 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
|
||||
* additional state.
|
||||
*/
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"GMBOX Host Int status 2: 0x%x\n",
|
||||
irq_proc_reg->host_int_status2);
|
||||
"GMBOX Host Int status 2: 0x%x\n",
|
||||
irq_proc_reg->host_int_status2);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"GMBOX RX Avail: 0x%x\n",
|
||||
irq_proc_reg->gmbox_rx_avail);
|
||||
"GMBOX RX Avail: 0x%x\n",
|
||||
irq_proc_reg->gmbox_rx_avail);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"GMBOX lookahead alias 0: 0x%x\n",
|
||||
irq_proc_reg->rx_gmbox_lkahd_alias[0]);
|
||||
"GMBOX lookahead alias 0: 0x%x\n",
|
||||
irq_proc_reg->rx_gmbox_lkahd_alias[0]);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"GMBOX lookahead alias 1: 0x%x\n",
|
||||
irq_proc_reg->rx_gmbox_lkahd_alias[1]);
|
||||
"GMBOX lookahead alias 1: 0x%x\n",
|
||||
irq_proc_reg->rx_gmbox_lkahd_alias[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (irq_enable_reg != NULL) {
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"Int status Enable: 0x%x\n",
|
||||
irq_enable_reg->int_status_en);
|
||||
"Int status Enable: 0x%x\n",
|
||||
irq_enable_reg->int_status_en);
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n",
|
||||
irq_enable_reg->cntr_int_status_en);
|
||||
irq_enable_reg->cntr_int_status_en);
|
||||
}
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n");
|
||||
}
|
||||
@ -268,105 +268,103 @@ static const struct file_operations fops_war_stats = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf,
|
||||
size_t buf_len)
|
||||
{
|
||||
struct circ_buf *fwlog = &ar->debug.fwlog_buf;
|
||||
size_t space;
|
||||
int i;
|
||||
|
||||
/* entries must all be equal size */
|
||||
if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE))
|
||||
return;
|
||||
|
||||
space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE);
|
||||
if (space < buf_len)
|
||||
/* discard oldest slot */
|
||||
fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) &
|
||||
(ATH6KL_FWLOG_SIZE - 1);
|
||||
|
||||
for (i = 0; i < buf_len; i += space) {
|
||||
space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail,
|
||||
ATH6KL_FWLOG_SIZE);
|
||||
|
||||
if ((size_t) space > buf_len - i)
|
||||
space = buf_len - i;
|
||||
|
||||
memcpy(&fwlog->buf[fwlog->head], buf, space);
|
||||
fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len)
|
||||
{
|
||||
struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp;
|
||||
struct ath6kl_fwlog_slot *slot;
|
||||
struct sk_buff *skb;
|
||||
size_t slot_len;
|
||||
|
||||
if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&ar->debug.fwlog_lock);
|
||||
slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE;
|
||||
|
||||
skb = alloc_skb(slot_len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
slot = (struct ath6kl_fwlog_slot *) skb_put(skb, slot_len);
|
||||
slot->timestamp = cpu_to_le32(jiffies);
|
||||
slot->length = cpu_to_le32(len);
|
||||
memcpy(slot->payload, buf, len);
|
||||
|
||||
slot_len = sizeof(*slot) + len;
|
||||
/* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */
|
||||
memset(slot->payload + len, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - len);
|
||||
|
||||
if (slot_len < ATH6KL_FWLOG_SLOT_SIZE)
|
||||
memset(slot->payload + len, 0,
|
||||
ATH6KL_FWLOG_SLOT_SIZE - slot_len);
|
||||
spin_lock(&ar->debug.fwlog_queue.lock);
|
||||
|
||||
ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE);
|
||||
__skb_queue_tail(&ar->debug.fwlog_queue, skb);
|
||||
complete(&ar->debug.fwlog_completion);
|
||||
|
||||
spin_unlock_bh(&ar->debug.fwlog_lock);
|
||||
/* drop oldest entries */
|
||||
while (skb_queue_len(&ar->debug.fwlog_queue) >
|
||||
ATH6KL_FWLOG_MAX_ENTRIES) {
|
||||
skb = __skb_dequeue(&ar->debug.fwlog_queue);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
spin_unlock(&ar->debug.fwlog_queue.lock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar)
|
||||
static int ath6kl_fwlog_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return CIRC_CNT(ar->debug.fwlog_buf.head,
|
||||
ar->debug.fwlog_buf.tail,
|
||||
ATH6KL_FWLOG_SLOT_SIZE) == 0;
|
||||
struct ath6kl *ar = inode->i_private;
|
||||
|
||||
if (ar->debug.fwlog_open)
|
||||
return -EBUSY;
|
||||
|
||||
ar->debug.fwlog_open = true;
|
||||
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath6kl_fwlog_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ath6kl *ar = inode->i_private;
|
||||
|
||||
ar->debug.fwlog_open = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath6kl *ar = file->private_data;
|
||||
struct circ_buf *fwlog = &ar->debug.fwlog_buf;
|
||||
size_t len = 0, buf_len = count;
|
||||
struct sk_buff *skb;
|
||||
ssize_t ret_cnt;
|
||||
size_t len = 0;
|
||||
char *buf;
|
||||
int ccnt;
|
||||
|
||||
buf = vmalloc(buf_len);
|
||||
buf = vmalloc(count);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* read undelivered logs from firmware */
|
||||
ath6kl_read_fwlogs(ar);
|
||||
|
||||
spin_lock_bh(&ar->debug.fwlog_lock);
|
||||
spin_lock(&ar->debug.fwlog_queue.lock);
|
||||
|
||||
while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) {
|
||||
ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail,
|
||||
ATH6KL_FWLOG_SIZE);
|
||||
while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) {
|
||||
if (skb->len > count - len) {
|
||||
/* not enough space, put skb back and leave */
|
||||
__skb_queue_head(&ar->debug.fwlog_queue, skb);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((size_t) ccnt > buf_len - len)
|
||||
ccnt = buf_len - len;
|
||||
|
||||
memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt);
|
||||
len += ccnt;
|
||||
memcpy(buf + len, skb->data, skb->len);
|
||||
len += skb->len;
|
||||
|
||||
fwlog->tail = (fwlog->tail + ccnt) &
|
||||
(ATH6KL_FWLOG_SIZE - 1);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&ar->debug.fwlog_lock);
|
||||
spin_unlock(&ar->debug.fwlog_queue.lock);
|
||||
|
||||
if (WARN_ON(len > buf_len))
|
||||
len = buf_len;
|
||||
/* FIXME: what to do if len == 0? */
|
||||
|
||||
ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
|
||||
@ -376,12 +374,87 @@ static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
|
||||
}
|
||||
|
||||
static const struct file_operations fops_fwlog = {
|
||||
.open = ath6kl_debugfs_open,
|
||||
.open = ath6kl_fwlog_open,
|
||||
.release = ath6kl_fwlog_release,
|
||||
.read = ath6kl_fwlog_read,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath6kl_fwlog_block_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct ath6kl *ar = file->private_data;
|
||||
struct sk_buff *skb;
|
||||
ssize_t ret_cnt;
|
||||
size_t len = 0, not_copied;
|
||||
char *buf;
|
||||
int ret;
|
||||
|
||||
buf = vmalloc(count);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock(&ar->debug.fwlog_queue.lock);
|
||||
|
||||
if (skb_queue_len(&ar->debug.fwlog_queue) == 0) {
|
||||
/* we must init under queue lock */
|
||||
init_completion(&ar->debug.fwlog_completion);
|
||||
|
||||
spin_unlock(&ar->debug.fwlog_queue.lock);
|
||||
|
||||
ret = wait_for_completion_interruptible(
|
||||
&ar->debug.fwlog_completion);
|
||||
if (ret == -ERESTARTSYS)
|
||||
return ret;
|
||||
|
||||
spin_lock(&ar->debug.fwlog_queue.lock);
|
||||
}
|
||||
|
||||
while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) {
|
||||
if (skb->len > count - len) {
|
||||
/* not enough space, put skb back and leave */
|
||||
__skb_queue_head(&ar->debug.fwlog_queue, skb);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
memcpy(buf + len, skb->data, skb->len);
|
||||
len += skb->len;
|
||||
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
spin_unlock(&ar->debug.fwlog_queue.lock);
|
||||
|
||||
/* FIXME: what to do if len == 0? */
|
||||
|
||||
not_copied = copy_to_user(user_buf, buf, len);
|
||||
if (not_copied != 0) {
|
||||
ret_cnt = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*ppos = *ppos + len;
|
||||
|
||||
ret_cnt = len;
|
||||
|
||||
out:
|
||||
vfree(buf);
|
||||
|
||||
return ret_cnt;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_fwlog_block = {
|
||||
.open = ath6kl_fwlog_open,
|
||||
.release = ath6kl_fwlog_release,
|
||||
.read = ath6kl_fwlog_block_read,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
@ -667,9 +740,13 @@ static ssize_t ath6kl_endpoint_stats_read(struct file *file,
|
||||
return -ENOMEM;
|
||||
|
||||
#define EPSTAT(name) \
|
||||
len = print_endpoint_stat(target, buf, buf_len, len, \
|
||||
offsetof(struct htc_endpoint_stats, name), \
|
||||
#name)
|
||||
do { \
|
||||
len = print_endpoint_stat(target, buf, buf_len, len, \
|
||||
offsetof(struct htc_endpoint_stats, \
|
||||
name), \
|
||||
#name); \
|
||||
} while (0)
|
||||
|
||||
EPSTAT(cred_low_indicate);
|
||||
EPSTAT(tx_issued);
|
||||
EPSTAT(tx_pkt_bundled);
|
||||
@ -779,17 +856,9 @@ static ssize_t ath6kl_regread_write(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath6kl *ar = file->private_data;
|
||||
u8 buf[50];
|
||||
unsigned int len;
|
||||
unsigned long reg_addr;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
buf[len] = '\0';
|
||||
|
||||
if (strict_strtoul(buf, 0, ®_addr))
|
||||
if (kstrtoul_from_user(user_buf, count, 0, ®_addr))
|
||||
return -EINVAL;
|
||||
|
||||
if ((reg_addr % 4) != 0)
|
||||
@ -903,15 +972,8 @@ static ssize_t ath6kl_lrssi_roam_write(struct file *file,
|
||||
{
|
||||
struct ath6kl *ar = file->private_data;
|
||||
unsigned long lrssi_roam_threshold;
|
||||
char buf[32];
|
||||
ssize_t len;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
buf[len] = '\0';
|
||||
if (strict_strtoul(buf, 0, &lrssi_roam_threshold))
|
||||
if (kstrtoul_from_user(user_buf, count, 0, &lrssi_roam_threshold))
|
||||
return -EINVAL;
|
||||
|
||||
ar->lrssi_roam_threshold = lrssi_roam_threshold;
|
||||
@ -1558,12 +1620,12 @@ static ssize_t ath6kl_listen_int_write(struct file *file,
|
||||
if (kstrtou16(buf, 0, &listen_interval))
|
||||
return -EINVAL;
|
||||
|
||||
if ((listen_interval < 1) || (listen_interval > 50))
|
||||
if ((listen_interval < 15) || (listen_interval > 3000))
|
||||
return -EINVAL;
|
||||
|
||||
ar->listen_intvl_b = listen_interval;
|
||||
ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0,
|
||||
ar->listen_intvl_b);
|
||||
vif->listen_intvl_t = listen_interval;
|
||||
ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
vif->listen_intvl_t, 0);
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -1573,10 +1635,15 @@ static ssize_t ath6kl_listen_int_read(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath6kl *ar = file->private_data;
|
||||
struct ath6kl_vif *vif;
|
||||
char buf[32];
|
||||
int len;
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b);
|
||||
vif = ath6kl_vif_first(ar);
|
||||
if (!vif)
|
||||
return -EIO;
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%u\n", vif->listen_intvl_t);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
@ -1649,33 +1716,29 @@ static const struct file_operations fops_power_params = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int ath6kl_debug_init(struct ath6kl *ar)
|
||||
void ath6kl_debug_init(struct ath6kl *ar)
|
||||
{
|
||||
ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE);
|
||||
if (ar->debug.fwlog_buf.buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL);
|
||||
if (ar->debug.fwlog_tmp == NULL) {
|
||||
vfree(ar->debug.fwlog_buf.buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_init(&ar->debug.fwlog_lock);
|
||||
skb_queue_head_init(&ar->debug.fwlog_queue);
|
||||
init_completion(&ar->debug.fwlog_completion);
|
||||
|
||||
/*
|
||||
* Actually we are lying here but don't know how to read the mask
|
||||
* value from the firmware.
|
||||
*/
|
||||
ar->debug.fwlog_mask = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialisation needs to happen in two stages as fwlog events can come
|
||||
* before cfg80211 is initialised, and debugfs depends on cfg80211
|
||||
* initialisation.
|
||||
*/
|
||||
int ath6kl_debug_init_fs(struct ath6kl *ar)
|
||||
{
|
||||
ar->debugfs_phy = debugfs_create_dir("ath6kl",
|
||||
ar->wiphy->debugfsdir);
|
||||
if (!ar->debugfs_phy) {
|
||||
vfree(ar->debug.fwlog_buf.buf);
|
||||
kfree(ar->debug.fwlog_tmp);
|
||||
if (!ar->debugfs_phy)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
|
||||
&fops_tgt_stats);
|
||||
@ -1689,6 +1752,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
|
||||
debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar,
|
||||
&fops_fwlog);
|
||||
|
||||
debugfs_create_file("fwlog_block", S_IRUSR, ar->debugfs_phy, ar,
|
||||
&fops_fwlog_block);
|
||||
|
||||
debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy,
|
||||
ar, &fops_fwlog_mask);
|
||||
|
||||
@ -1723,27 +1789,26 @@ int ath6kl_debug_init(struct ath6kl *ar)
|
||||
ar->debugfs_phy, ar, &fops_disconnect_timeout);
|
||||
|
||||
debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar,
|
||||
&fops_create_qos);
|
||||
&fops_create_qos);
|
||||
|
||||
debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar,
|
||||
&fops_delete_qos);
|
||||
&fops_delete_qos);
|
||||
|
||||
debugfs_create_file("bgscan_interval", S_IWUSR,
|
||||
ar->debugfs_phy, ar, &fops_bgscan_int);
|
||||
ar->debugfs_phy, ar, &fops_bgscan_int);
|
||||
|
||||
debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR,
|
||||
ar->debugfs_phy, ar, &fops_listen_int);
|
||||
|
||||
debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
|
||||
&fops_power_params);
|
||||
&fops_power_params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath6kl_debug_cleanup(struct ath6kl *ar)
|
||||
{
|
||||
vfree(ar->debug.fwlog_buf.buf);
|
||||
kfree(ar->debug.fwlog_tmp);
|
||||
skb_queue_purge(&ar->debug.fwlog_queue);
|
||||
kfree(ar->debug.roam_tbl);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -77,7 +78,8 @@ int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf,
|
||||
size_t len);
|
||||
void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive);
|
||||
void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout);
|
||||
int ath6kl_debug_init(struct ath6kl *ar);
|
||||
void ath6kl_debug_init(struct ath6kl *ar);
|
||||
int ath6kl_debug_init_fs(struct ath6kl *ar);
|
||||
void ath6kl_debug_cleanup(struct ath6kl *ar);
|
||||
|
||||
#else
|
||||
@ -127,7 +129,11 @@ static inline void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar,
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ath6kl_debug_init(struct ath6kl *ar)
|
||||
static inline void ath6kl_debug_init(struct ath6kl *ar)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ath6kl_debug_init_fs(struct ath6kl *ar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -89,7 +90,7 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n",
|
||||
regdump_addr);
|
||||
regdump_addr);
|
||||
regdump_addr = TARG_VTOP(ar->target_type, regdump_addr);
|
||||
|
||||
/* fetch register dump data */
|
||||
@ -106,9 +107,9 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
|
||||
|
||||
BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4);
|
||||
|
||||
for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) {
|
||||
for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) {
|
||||
ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
|
||||
4 * i,
|
||||
i,
|
||||
le32_to_cpu(regdump_val[i]),
|
||||
le32_to_cpu(regdump_val[i + 1]),
|
||||
le32_to_cpu(regdump_val[i + 2]),
|
||||
@ -134,6 +135,7 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
|
||||
ath6kl_warn("Failed to clear debug interrupt: %d\n", ret);
|
||||
|
||||
ath6kl_hif_dump_fw_crash(dev->ar);
|
||||
ath6kl_read_fwlogs(dev->ar);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -283,7 +285,7 @@ static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev)
|
||||
dev->irq_en_reg.cntr_int_status_en;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
|
||||
"valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
|
||||
counter_int_status);
|
||||
|
||||
/*
|
||||
@ -358,7 +360,7 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev)
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_IRQ,
|
||||
"valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
|
||||
"valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
|
||||
cpu_int_status);
|
||||
|
||||
/* Clear the interrupt */
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -197,6 +198,8 @@ struct hif_scatter_req {
|
||||
u8 *virt_dma_buf;
|
||||
|
||||
struct hif_scatter_item scat_list[1];
|
||||
|
||||
u32 scat_q_depth;
|
||||
};
|
||||
|
||||
struct ath6kl_irq_proc_registers {
|
||||
@ -220,6 +223,7 @@ struct ath6kl_irq_enable_reg {
|
||||
} __packed;
|
||||
|
||||
struct ath6kl_device {
|
||||
/* protects irq_proc_reg and irq_en_reg below */
|
||||
spinlock_t lock;
|
||||
struct ath6kl_irq_proc_registers irq_proc_reg;
|
||||
struct ath6kl_irq_enable_reg irq_en_reg;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -22,6 +23,9 @@
|
||||
|
||||
#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
|
||||
|
||||
/* threshold to re-enable Tx bundling for an AC*/
|
||||
#define TX_RESUME_BUNDLE_THRESHOLD 1500
|
||||
|
||||
/* Functions for Tx credit handling */
|
||||
static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info,
|
||||
struct htc_endpoint_credit_dist *ep_dist,
|
||||
@ -168,31 +172,29 @@ static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info,
|
||||
static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
|
||||
struct list_head *epdist_list)
|
||||
{
|
||||
struct htc_endpoint_credit_dist *cur_dist_list;
|
||||
struct htc_endpoint_credit_dist *cur_list;
|
||||
|
||||
list_for_each_entry(cur_dist_list, epdist_list, list) {
|
||||
if (cur_dist_list->endpoint == ENDPOINT_0)
|
||||
list_for_each_entry(cur_list, epdist_list, list) {
|
||||
if (cur_list->endpoint == ENDPOINT_0)
|
||||
continue;
|
||||
|
||||
if (cur_dist_list->cred_to_dist > 0) {
|
||||
cur_dist_list->credits +=
|
||||
cur_dist_list->cred_to_dist;
|
||||
cur_dist_list->cred_to_dist = 0;
|
||||
if (cur_dist_list->credits >
|
||||
cur_dist_list->cred_assngd)
|
||||
if (cur_list->cred_to_dist > 0) {
|
||||
cur_list->credits += cur_list->cred_to_dist;
|
||||
cur_list->cred_to_dist = 0;
|
||||
|
||||
if (cur_list->credits > cur_list->cred_assngd)
|
||||
ath6kl_credit_reduce(cred_info,
|
||||
cur_dist_list,
|
||||
cur_dist_list->cred_assngd);
|
||||
cur_list,
|
||||
cur_list->cred_assngd);
|
||||
|
||||
if (cur_dist_list->credits >
|
||||
cur_dist_list->cred_norm)
|
||||
ath6kl_credit_reduce(cred_info, cur_dist_list,
|
||||
cur_dist_list->cred_norm);
|
||||
if (cur_list->credits > cur_list->cred_norm)
|
||||
ath6kl_credit_reduce(cred_info, cur_list,
|
||||
cur_list->cred_norm);
|
||||
|
||||
if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
|
||||
if (cur_dist_list->txq_depth == 0)
|
||||
if (!(cur_list->dist_flags & HTC_EP_ACTIVE)) {
|
||||
if (cur_list->txq_depth == 0)
|
||||
ath6kl_credit_reduce(cred_info,
|
||||
cur_dist_list, 0);
|
||||
cur_list, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -460,8 +462,8 @@ static void htc_async_tx_scat_complete(struct htc_target *target,
|
||||
INIT_LIST_HEAD(&tx_compq);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc tx scat complete len %d entries %d\n",
|
||||
scat_req->len, scat_req->scat_entries);
|
||||
"htc tx scat complete len %d entries %d\n",
|
||||
scat_req->len, scat_req->scat_entries);
|
||||
|
||||
if (scat_req->status)
|
||||
ath6kl_err("send scatter req failed: %d\n", scat_req->status);
|
||||
@ -599,8 +601,8 @@ static void ath6kl_htc_tx_pkts_get(struct htc_target *target,
|
||||
list);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc tx got packet 0x%p queue depth %d\n",
|
||||
packet, get_queue_depth(&endpoint->txq));
|
||||
"htc tx got packet 0x%p queue depth %d\n",
|
||||
packet, get_queue_depth(&endpoint->txq));
|
||||
|
||||
len = CALC_TXRX_PADDED_LEN(target,
|
||||
packet->act_len + HTC_HDR_LENGTH);
|
||||
@ -670,6 +672,7 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
|
||||
struct htc_packet *packet;
|
||||
int i, len, rem_scat, cred_pad;
|
||||
int status = 0;
|
||||
u8 flags;
|
||||
|
||||
rem_scat = target->max_tx_bndl_sz;
|
||||
|
||||
@ -696,9 +699,9 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
|
||||
|
||||
scat_req->scat_list[i].packet = packet;
|
||||
/* prepare packet and flag message as part of a send bundle */
|
||||
ath6kl_htc_tx_prep_pkt(packet,
|
||||
packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
|
||||
cred_pad, packet->info.tx.seqno);
|
||||
flags = packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE;
|
||||
ath6kl_htc_tx_prep_pkt(packet, flags,
|
||||
cred_pad, packet->info.tx.seqno);
|
||||
/* Make sure the buffer is 4-byte aligned */
|
||||
ath6kl_htc_tx_buf_align(&packet->buf,
|
||||
packet->act_len + HTC_HDR_LENGTH);
|
||||
@ -744,6 +747,12 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
|
||||
struct hif_scatter_req *scat_req = NULL;
|
||||
int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
|
||||
int status;
|
||||
u32 txb_mask;
|
||||
u8 ac = WMM_NUM_AC;
|
||||
|
||||
if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
|
||||
(WMI_CONTROL_SVC != endpoint->svc_id))
|
||||
ac = target->dev->ar->ep2ac_map[endpoint->eid];
|
||||
|
||||
while (true) {
|
||||
status = 0;
|
||||
@ -759,10 +768,35 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
|
||||
if (!scat_req) {
|
||||
/* no scatter resources */
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc tx no more scatter resources\n");
|
||||
"htc tx no more scatter resources\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) {
|
||||
if (WMM_AC_BE == ac)
|
||||
/*
|
||||
* BE, BK have priorities and bit
|
||||
* positions reversed
|
||||
*/
|
||||
txb_mask = (1 << WMM_AC_BK);
|
||||
else
|
||||
/*
|
||||
* any AC with priority lower than
|
||||
* itself
|
||||
*/
|
||||
txb_mask = ((1 << ac) - 1);
|
||||
/*
|
||||
* when the scatter request resources drop below a
|
||||
* certain threshold, disable Tx bundling for all
|
||||
* AC's with priority lower than the current requesting
|
||||
* AC. Otherwise re-enable Tx bundling for them
|
||||
*/
|
||||
if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS)
|
||||
target->tx_bndl_mask &= ~txb_mask;
|
||||
else
|
||||
target->tx_bndl_mask |= txb_mask;
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n",
|
||||
n_scat);
|
||||
|
||||
@ -806,6 +840,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
|
||||
struct htc_packet *packet;
|
||||
int bundle_sent;
|
||||
int n_pkts_bundle;
|
||||
u8 ac = WMM_NUM_AC;
|
||||
|
||||
spin_lock_bh(&target->tx_lock);
|
||||
|
||||
@ -823,6 +858,10 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
|
||||
*/
|
||||
INIT_LIST_HEAD(&txq);
|
||||
|
||||
if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
|
||||
(WMI_CONTROL_SVC != endpoint->svc_id))
|
||||
ac = target->dev->ar->ep2ac_map[endpoint->eid];
|
||||
|
||||
while (true) {
|
||||
|
||||
if (list_empty(&endpoint->txq))
|
||||
@ -840,15 +879,18 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
|
||||
|
||||
while (true) {
|
||||
/* try to send a bundle on each pass */
|
||||
if ((target->tx_bndl_enable) &&
|
||||
if ((target->tx_bndl_mask) &&
|
||||
(get_queue_depth(&txq) >=
|
||||
HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
|
||||
int temp1 = 0, temp2 = 0;
|
||||
|
||||
ath6kl_htc_tx_bundle(endpoint, &txq,
|
||||
&temp1, &temp2);
|
||||
bundle_sent += temp1;
|
||||
n_pkts_bundle += temp2;
|
||||
/* check if bundling is enabled for an AC */
|
||||
if (target->tx_bndl_mask & (1 << ac)) {
|
||||
ath6kl_htc_tx_bundle(endpoint, &txq,
|
||||
&temp1, &temp2);
|
||||
bundle_sent += temp1;
|
||||
n_pkts_bundle += temp2;
|
||||
}
|
||||
}
|
||||
|
||||
if (list_empty(&txq))
|
||||
@ -867,6 +909,26 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target,
|
||||
|
||||
endpoint->ep_st.tx_bundles += bundle_sent;
|
||||
endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle;
|
||||
|
||||
/*
|
||||
* if an AC has bundling disabled and no tx bundling
|
||||
* has occured continously for a certain number of TX,
|
||||
* enable tx bundling for this AC
|
||||
*/
|
||||
if (!bundle_sent) {
|
||||
if (!(target->tx_bndl_mask & (1 << ac)) &&
|
||||
(ac < WMM_NUM_AC)) {
|
||||
if (++target->ac_tx_count[ac] >=
|
||||
TX_RESUME_BUNDLE_THRESHOLD) {
|
||||
target->ac_tx_count[ac] = 0;
|
||||
target->tx_bndl_mask |= (1 << ac);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* tx bundling will reset the counter */
|
||||
if (ac < WMM_NUM_AC)
|
||||
target->ac_tx_count[ac] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
endpoint->tx_proc_cnt = 0;
|
||||
@ -979,8 +1041,8 @@ static int htc_setup_tx_complete(struct htc_target *target)
|
||||
memcpy(&setup_comp_ext->flags, &flags,
|
||||
sizeof(setup_comp_ext->flags));
|
||||
set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext,
|
||||
sizeof(struct htc_setup_comp_ext_msg),
|
||||
ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
|
||||
sizeof(struct htc_setup_comp_ext_msg),
|
||||
ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
|
||||
|
||||
} else {
|
||||
struct htc_setup_comp_msg *setup_comp;
|
||||
@ -988,8 +1050,8 @@ static int htc_setup_tx_complete(struct htc_target *target)
|
||||
memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg));
|
||||
setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID);
|
||||
set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp,
|
||||
sizeof(struct htc_setup_comp_msg),
|
||||
ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
|
||||
sizeof(struct htc_setup_comp_msg),
|
||||
ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
|
||||
}
|
||||
|
||||
/* we want synchronous operation */
|
||||
@ -1088,9 +1150,9 @@ void ath6kl_htc_flush_txep(struct htc_target *target,
|
||||
packet->status = -ECANCELED;
|
||||
list_del(&packet->list);
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n",
|
||||
packet, packet->act_len,
|
||||
packet->endpoint, packet->info.tx.tag);
|
||||
"htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n",
|
||||
packet, packet->act_len,
|
||||
packet->endpoint, packet->info.tx.tag);
|
||||
|
||||
INIT_LIST_HEAD(&container);
|
||||
list_add_tail(&packet->list, &container);
|
||||
@ -1490,7 +1552,7 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
|
||||
|
||||
if (packets->act_len > 0) {
|
||||
ath6kl_err("htc_ctrl_rx, got message with len:%zu\n",
|
||||
packets->act_len + HTC_HDR_LENGTH);
|
||||
packets->act_len + HTC_HDR_LENGTH);
|
||||
|
||||
ath6kl_dbg_dump(ATH6KL_DBG_HTC,
|
||||
"htc rx unexpected endpoint 0 message", "",
|
||||
@ -1609,8 +1671,8 @@ static int htc_parse_trailer(struct htc_target *target,
|
||||
}
|
||||
|
||||
lk_ahd = (struct htc_lookahead_report *) record_buf;
|
||||
if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF))
|
||||
&& next_lk_ahds) {
|
||||
if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) &&
|
||||
next_lk_ahds) {
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
|
||||
@ -2038,13 +2100,13 @@ fail_rx:
|
||||
list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) {
|
||||
list_del(&packet->list);
|
||||
htc_reclaim_rxbuf(target, packet,
|
||||
&target->endpoint[packet->endpoint]);
|
||||
&target->endpoint[packet->endpoint]);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) {
|
||||
list_del(&packet->list);
|
||||
htc_reclaim_rxbuf(target, packet,
|
||||
&target->endpoint[packet->endpoint]);
|
||||
&target->endpoint[packet->endpoint]);
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -2176,11 +2238,11 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
|
||||
u32 look_ahead;
|
||||
|
||||
if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead,
|
||||
HTC_TARGET_RESPONSE_TIMEOUT))
|
||||
HTC_TARGET_RESPONSE_TIMEOUT))
|
||||
return NULL;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx wait ctrl look_ahead 0x%X\n", look_ahead);
|
||||
"htc rx wait ctrl look_ahead 0x%X\n", look_ahead);
|
||||
|
||||
htc_hdr = (struct htc_frame_hdr *)&look_ahead;
|
||||
|
||||
@ -2245,7 +2307,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
|
||||
depth = get_queue_depth(pkt_queue);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx add multiple ep id %d cnt %d len %d\n",
|
||||
"htc rx add multiple ep id %d cnt %d len %d\n",
|
||||
first_pkt->endpoint, depth, first_pkt->buf_len);
|
||||
|
||||
endpoint = &target->endpoint[first_pkt->endpoint];
|
||||
@ -2271,8 +2333,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
|
||||
if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
|
||||
if (target->ep_waiting == first_pkt->endpoint) {
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx blocked on ep %d, unblocking\n",
|
||||
target->ep_waiting);
|
||||
"htc rx blocked on ep %d, unblocking\n",
|
||||
target->ep_waiting);
|
||||
target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS;
|
||||
target->ep_waiting = ENDPOINT_MAX;
|
||||
rx_unblock = true;
|
||||
@ -2309,7 +2371,21 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target)
|
||||
"htc rx flush pkt 0x%p len %d ep %d\n",
|
||||
packet, packet->buf_len,
|
||||
packet->endpoint);
|
||||
dev_kfree_skb(packet->pkt_cntxt);
|
||||
/*
|
||||
* packets in rx_bufq of endpoint 0 have originally
|
||||
* been queued from target->free_ctrl_rxbuf where
|
||||
* packet and packet->buf_start are allocated
|
||||
* separately using kmalloc(). For other endpoint
|
||||
* rx_bufq, it is allocated as skb where packet is
|
||||
* skb->head. Take care of this difference while freeing
|
||||
* the memory.
|
||||
*/
|
||||
if (packet->endpoint == ENDPOINT_0) {
|
||||
kfree(packet->buf_start);
|
||||
kfree(packet);
|
||||
} else {
|
||||
dev_kfree_skb(packet->pkt_cntxt);
|
||||
}
|
||||
spin_lock_bh(&target->rx_lock);
|
||||
}
|
||||
spin_unlock_bh(&target->rx_lock);
|
||||
@ -2328,6 +2404,7 @@ int ath6kl_htc_conn_service(struct htc_target *target,
|
||||
enum htc_endpoint_id assigned_ep = ENDPOINT_MAX;
|
||||
unsigned int max_msg_sz = 0;
|
||||
int status = 0;
|
||||
u16 msg_id;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc connect service target 0x%p service id 0x%x\n",
|
||||
@ -2371,9 +2448,10 @@ int ath6kl_htc_conn_service(struct htc_target *target,
|
||||
}
|
||||
|
||||
resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf;
|
||||
msg_id = le16_to_cpu(resp_msg->msg_id);
|
||||
|
||||
if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID)
|
||||
|| (rx_pkt->act_len < sizeof(*resp_msg))) {
|
||||
if ((msg_id != HTC_MSG_CONN_SVC_RESP_ID) ||
|
||||
(rx_pkt->act_len < sizeof(*resp_msg))) {
|
||||
status = -ENOMEM;
|
||||
goto fail_tx;
|
||||
}
|
||||
@ -2420,6 +2498,15 @@ int ath6kl_htc_conn_service(struct htc_target *target,
|
||||
endpoint->cred_dist.endpoint = assigned_ep;
|
||||
endpoint->cred_dist.cred_sz = target->tgt_cred_sz;
|
||||
|
||||
switch (endpoint->svc_id) {
|
||||
case WMI_DATA_BK_SVC:
|
||||
endpoint->tx_drop_packet_threshold = MAX_DEF_COOKIE_NUM / 3;
|
||||
break;
|
||||
default:
|
||||
endpoint->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (conn_req->max_rxmsg_sz) {
|
||||
/*
|
||||
* Override cred_per_msg calculation, this optimizes
|
||||
@ -2517,7 +2604,8 @@ static void htc_setup_msg_bndl(struct htc_target *target)
|
||||
target->max_rx_bndl_sz, target->max_tx_bndl_sz);
|
||||
|
||||
if (target->max_tx_bndl_sz)
|
||||
target->tx_bndl_enable = true;
|
||||
/* tx_bndl_mask is enabled per AC, each has 1 bit */
|
||||
target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1;
|
||||
|
||||
if (target->max_rx_bndl_sz)
|
||||
target->rx_bndl_enable = true;
|
||||
@ -2532,7 +2620,7 @@ static void htc_setup_msg_bndl(struct htc_target *target)
|
||||
* padding will spill into the next credit buffer
|
||||
* which is fatal.
|
||||
*/
|
||||
target->tx_bndl_enable = false;
|
||||
target->tx_bndl_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2589,8 +2677,8 @@ int ath6kl_htc_wait_target(struct htc_target *target)
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n",
|
||||
(target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
|
||||
target->htc_tgt_ver);
|
||||
(target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
|
||||
target->htc_tgt_ver);
|
||||
|
||||
if (target->msg_per_bndl_max > 0)
|
||||
htc_setup_msg_bndl(target);
|
||||
@ -2784,14 +2872,14 @@ void ath6kl_htc_cleanup(struct htc_target *target)
|
||||
ath6kl_hif_cleanup_scatter(target->dev->ar);
|
||||
|
||||
list_for_each_entry_safe(packet, tmp_packet,
|
||||
&target->free_ctrl_txbuf, list) {
|
||||
&target->free_ctrl_txbuf, list) {
|
||||
list_del(&packet->list);
|
||||
kfree(packet->buf_start);
|
||||
kfree(packet);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(packet, tmp_packet,
|
||||
&target->free_ctrl_rxbuf, list) {
|
||||
&target->free_ctrl_rxbuf, list) {
|
||||
list_del(&packet->list);
|
||||
kfree(packet->buf_start);
|
||||
kfree(packet);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -87,6 +88,8 @@
|
||||
#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
|
||||
#define WMI_MAX_SERVICES 5
|
||||
|
||||
#define WMM_NUM_AC 4
|
||||
|
||||
/* reserved and used to flush ALL packets */
|
||||
#define HTC_TX_PACKET_TAG_ALL 0
|
||||
#define HTC_SERVICE_TX_PACKET_TAG 1
|
||||
@ -498,6 +501,7 @@ struct htc_endpoint {
|
||||
u8 seqno;
|
||||
u32 conn_flags;
|
||||
struct htc_endpoint_stats ep_st;
|
||||
u16 tx_drop_packet_threshold;
|
||||
};
|
||||
|
||||
struct htc_control_buffer {
|
||||
@ -519,9 +523,16 @@ struct htc_target {
|
||||
struct ath6kl_htc_credit_info *credit_info;
|
||||
int tgt_creds;
|
||||
unsigned int tgt_cred_sz;
|
||||
|
||||
/* protects free_ctrl_txbuf and free_ctrl_rxbuf */
|
||||
spinlock_t htc_lock;
|
||||
|
||||
/* FIXME: does this protext rx_bufq and endpoint structures or what? */
|
||||
spinlock_t rx_lock;
|
||||
|
||||
/* protects endpoint->txq */
|
||||
spinlock_t tx_lock;
|
||||
|
||||
struct ath6kl_device *dev;
|
||||
u32 htc_flags;
|
||||
u32 rx_st_flags;
|
||||
@ -531,7 +542,7 @@ struct htc_target {
|
||||
/* max messages per bundle for HTC */
|
||||
int msg_per_bndl_max;
|
||||
|
||||
bool tx_bndl_enable;
|
||||
u32 tx_bndl_mask;
|
||||
int rx_bndl_enable;
|
||||
int max_rx_bndl_sz;
|
||||
int max_tx_bndl_sz;
|
||||
@ -543,6 +554,9 @@ struct htc_target {
|
||||
int max_xfer_szper_scatreq;
|
||||
|
||||
int chk_irq_status_cnt;
|
||||
|
||||
/* counts the number of Tx without bundling continously per AC */
|
||||
u32 ac_tx_count[WMM_NUM_AC];
|
||||
};
|
||||
|
||||
void *ath6kl_htc_create(struct ath6kl *ar);
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -74,7 +75,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
},
|
||||
|
||||
.fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE,
|
||||
.fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
|
||||
.fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
|
||||
},
|
||||
{
|
||||
.id = AR6004_HW_1_0_VERSION,
|
||||
@ -351,11 +352,7 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
|
||||
blk_size |= ((u32)htc_ctrl_buf) << 16;
|
||||
|
||||
/* set the host interest area for the block size */
|
||||
status = ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_mbox_io_block_sz)),
|
||||
(u8 *)&blk_size,
|
||||
4);
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_mbox_io_block_sz, blk_size);
|
||||
if (status) {
|
||||
ath6kl_err("bmi_write_memory for IO block size failed\n");
|
||||
goto out;
|
||||
@ -367,11 +364,8 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
|
||||
|
||||
if (mbox_isr_yield_val) {
|
||||
/* set the host interest area for the mbox ISR yield limit */
|
||||
status = ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_mbox_isr_yield_limit)),
|
||||
(u8 *)&mbox_isr_yield_val,
|
||||
4);
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_mbox_isr_yield_limit,
|
||||
mbox_isr_yield_val);
|
||||
if (status) {
|
||||
ath6kl_err("bmi_write_memory for yield limit failed\n");
|
||||
goto out;
|
||||
@ -384,7 +378,6 @@ out:
|
||||
|
||||
static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
|
||||
{
|
||||
int status = 0;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@ -392,43 +385,54 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
|
||||
* default values. Required if checksum offload is needed. Set
|
||||
* RxMetaVersion to 2.
|
||||
*/
|
||||
if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx,
|
||||
ar->rx_meta_ver, 0, 0)) {
|
||||
ath6kl_err("unable to set the rx frame format\n");
|
||||
status = -EIO;
|
||||
ret = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx,
|
||||
ar->rx_meta_ver, 0, 0);
|
||||
if (ret) {
|
||||
ath6kl_err("unable to set the rx frame format: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN)
|
||||
if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1,
|
||||
IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
|
||||
ath6kl_err("unable to set power save fail event policy\n");
|
||||
status = -EIO;
|
||||
if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) {
|
||||
ret = ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1,
|
||||
IGNORE_PS_FAIL_DURING_SCAN);
|
||||
if (ret) {
|
||||
ath6kl_err("unable to set power save fail event policy: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER))
|
||||
if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0,
|
||||
WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
|
||||
ath6kl_err("unable to set barker preamble policy\n");
|
||||
status = -EIO;
|
||||
}
|
||||
|
||||
if (ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx,
|
||||
WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) {
|
||||
ath6kl_err("unable to set keep alive interval\n");
|
||||
status = -EIO;
|
||||
}
|
||||
|
||||
if (ath6kl_wmi_disctimeout_cmd(ar->wmi, idx,
|
||||
WLAN_CONFIG_DISCONNECT_TIMEOUT)) {
|
||||
ath6kl_err("unable to set disconnect timeout\n");
|
||||
status = -EIO;
|
||||
if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) {
|
||||
ret = ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0,
|
||||
WMI_FOLLOW_BARKER_IN_ERP);
|
||||
if (ret) {
|
||||
ath6kl_err("unable to set barker preamble policy: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST))
|
||||
if (ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED)) {
|
||||
ath6kl_err("unable to set txop bursting\n");
|
||||
status = -EIO;
|
||||
ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx,
|
||||
WLAN_CONFIG_KEEP_ALIVE_INTERVAL);
|
||||
if (ret) {
|
||||
ath6kl_err("unable to set keep alive interval: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, idx,
|
||||
WLAN_CONFIG_DISCONNECT_TIMEOUT);
|
||||
if (ret) {
|
||||
ath6kl_err("unable to set disconnect timeout: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) {
|
||||
ret = ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED);
|
||||
if (ret) {
|
||||
ath6kl_err("unable to set txop bursting: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (ar->p2p && (ar->vif_max == 1 || idx)) {
|
||||
ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx,
|
||||
@ -452,7 +456,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath6kl_configure_target(struct ath6kl *ar)
|
||||
@ -462,8 +466,7 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
int i, status;
|
||||
|
||||
param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG);
|
||||
if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_serial_enable)), (u8 *)¶m, 4)) {
|
||||
if (ath6kl_bmi_write_hi32(ar, hi_serial_enable, param)) {
|
||||
ath6kl_err("bmi_write_memory for uart debug failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
@ -499,11 +502,8 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
if (ar->p2p && ar->vif_max == 1)
|
||||
fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
|
||||
|
||||
param = HTC_PROTOCOL_VERSION;
|
||||
if (ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_app_host_interest)),
|
||||
(u8 *)¶m, 4) != 0) {
|
||||
if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest,
|
||||
HTC_PROTOCOL_VERSION) != 0) {
|
||||
ath6kl_err("bmi_write_memory for htc version failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
@ -511,10 +511,7 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
/* set the firmware mode to STA/IBSS/AP */
|
||||
param = 0;
|
||||
|
||||
if (ath6kl_bmi_read(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_option_flag)),
|
||||
(u8 *)¶m, 4) != 0) {
|
||||
if (ath6kl_bmi_read_hi32(ar, hi_option_flag, ¶m) != 0) {
|
||||
ath6kl_err("bmi_read_memory for setting fwmode failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
@ -526,11 +523,7 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
|
||||
param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
|
||||
|
||||
if (ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_option_flag)),
|
||||
(u8 *)¶m,
|
||||
4) != 0) {
|
||||
if (ath6kl_bmi_write_hi32(ar, hi_option_flag, param) != 0) {
|
||||
ath6kl_err("bmi_write_memory for setting fwmode failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
@ -549,16 +542,13 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
param = ar->hw.board_ext_data_addr;
|
||||
ram_reserved_size = ar->hw.reserved_ram_size;
|
||||
|
||||
if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_board_ext_data)),
|
||||
(u8 *)¶m, 4) != 0) {
|
||||
if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) {
|
||||
ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_end_ram_reserve_sz)),
|
||||
(u8 *)&ram_reserved_size, 4) != 0) {
|
||||
if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz,
|
||||
ram_reserved_size) != 0) {
|
||||
ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
@ -569,20 +559,13 @@ int ath6kl_configure_target(struct ath6kl *ar)
|
||||
return -EIO;
|
||||
|
||||
/* Configure GPIO AR600x UART */
|
||||
param = ar->hw.uarttx_pin;
|
||||
status = ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_dbg_uart_txpin)),
|
||||
(u8 *)¶m, 4);
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_dbg_uart_txpin,
|
||||
ar->hw.uarttx_pin);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Configure target refclk_hz */
|
||||
param = ar->hw.refclk_hz;
|
||||
status = ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_refclk_hz)),
|
||||
(u8 *)¶m, 4);
|
||||
status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
@ -832,13 +815,13 @@ static int ath6kl_fetch_testscript_file(struct ath6kl *ar)
|
||||
return 0;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s",
|
||||
ar->hw.fw.dir, ar->hw.fw.testscript);
|
||||
ar->hw.fw.dir, ar->hw.fw.testscript);
|
||||
|
||||
ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript,
|
||||
&ar->fw_testscript_len);
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to get testscript file %s: %d\n",
|
||||
filename, ret);
|
||||
filename, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -922,7 +905,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
switch (ie_id) {
|
||||
case ATH6KL_FW_IE_OTP_IMAGE:
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
|
||||
ie_len);
|
||||
ie_len);
|
||||
|
||||
ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL);
|
||||
|
||||
@ -935,7 +918,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
break;
|
||||
case ATH6KL_FW_IE_FW_IMAGE:
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
|
||||
ie_len);
|
||||
ie_len);
|
||||
|
||||
/* in testmode we already might have a fw file */
|
||||
if (ar->fw != NULL)
|
||||
@ -952,7 +935,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
break;
|
||||
case ATH6KL_FW_IE_PATCH_IMAGE:
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n",
|
||||
ie_len);
|
||||
ie_len);
|
||||
|
||||
ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL);
|
||||
|
||||
@ -1096,22 +1079,14 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
||||
*/
|
||||
if (ar->hw.board_addr != 0) {
|
||||
board_address = ar->hw.board_addr;
|
||||
ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_board_data)),
|
||||
(u8 *) &board_address, 4);
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_data,
|
||||
board_address);
|
||||
} else {
|
||||
ath6kl_bmi_read(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_board_data)),
|
||||
(u8 *) &board_address, 4);
|
||||
ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
|
||||
}
|
||||
|
||||
/* determine where in target ram to write extended board data */
|
||||
ath6kl_bmi_read(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_board_ext_data)),
|
||||
(u8 *) &board_ext_address, 4);
|
||||
ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
|
||||
|
||||
if (ar->target_type == TARGET_TYPE_AR6003 &&
|
||||
board_ext_address == 0) {
|
||||
@ -1123,6 +1098,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
||||
case TARGET_TYPE_AR6003:
|
||||
board_data_size = AR6003_BOARD_DATA_SZ;
|
||||
board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ;
|
||||
if (ar->fw_board_len > (board_data_size + board_ext_data_size))
|
||||
board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2;
|
||||
break;
|
||||
case TARGET_TYPE_AR6004:
|
||||
board_data_size = AR6004_BOARD_DATA_SZ;
|
||||
@ -1154,10 +1131,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
||||
/* record that extended board data is initialized */
|
||||
param = (board_ext_data_size << 16) | 1;
|
||||
|
||||
ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_board_ext_data_config)),
|
||||
(unsigned char *) ¶m, 4);
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_ext_data_config, param);
|
||||
}
|
||||
|
||||
if (ar->fw_board_len < board_data_size) {
|
||||
@ -1178,11 +1152,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
|
||||
}
|
||||
|
||||
/* record the fact that Board Data IS initialized */
|
||||
param = 1;
|
||||
ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_board_data_initialized)),
|
||||
(u8 *)¶m, 4);
|
||||
ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1209,10 +1179,7 @@ static int ath6kl_upload_otp(struct ath6kl *ar)
|
||||
}
|
||||
|
||||
/* read firmware start address */
|
||||
ret = ath6kl_bmi_read(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_app_start)),
|
||||
(u8 *) &address, sizeof(address));
|
||||
ret = ath6kl_bmi_read_hi32(ar, hi_app_start, &address);
|
||||
|
||||
if (ret) {
|
||||
ath6kl_err("Failed to read hi_app_start: %d\n", ret);
|
||||
@ -1270,7 +1237,7 @@ static int ath6kl_upload_firmware(struct ath6kl *ar)
|
||||
|
||||
static int ath6kl_upload_patch(struct ath6kl *ar)
|
||||
{
|
||||
u32 address, param;
|
||||
u32 address;
|
||||
int ret;
|
||||
|
||||
if (ar->fw_patch == NULL)
|
||||
@ -1287,18 +1254,14 @@ static int ath6kl_upload_patch(struct ath6kl *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
param = address;
|
||||
ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_dset_list_head)),
|
||||
(unsigned char *) ¶m, 4);
|
||||
ath6kl_bmi_write_hi32(ar, hi_dset_list_head, address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath6kl_upload_testscript(struct ath6kl *ar)
|
||||
{
|
||||
u32 address, param;
|
||||
u32 address;
|
||||
int ret;
|
||||
|
||||
if (ar->testmode != 2)
|
||||
@ -1310,7 +1273,7 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
|
||||
address = ar->hw.testscript_addr;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n",
|
||||
address, ar->fw_testscript_len);
|
||||
address, ar->fw_testscript_len);
|
||||
|
||||
ret = ath6kl_bmi_write(ar, address, ar->fw_testscript,
|
||||
ar->fw_testscript_len);
|
||||
@ -1319,23 +1282,9 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
param = address;
|
||||
ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_ota_testscript)),
|
||||
(unsigned char *) ¶m, 4);
|
||||
|
||||
param = 4096;
|
||||
ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_end_ram_reserve_sz)),
|
||||
(unsigned char *) ¶m, 4);
|
||||
|
||||
param = 1;
|
||||
ath6kl_bmi_write(ar,
|
||||
ath6kl_get_hi_item_addr(ar,
|
||||
HI_ITEM(hi_test_apps_related)),
|
||||
(unsigned char *) ¶m, 4);
|
||||
ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
|
||||
ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
|
||||
ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1346,7 +1295,7 @@ static int ath6kl_init_upload(struct ath6kl *ar)
|
||||
int status = 0;
|
||||
|
||||
if (ar->target_type != TARGET_TYPE_AR6003 &&
|
||||
ar->target_type != TARGET_TYPE_AR6004)
|
||||
ar->target_type != TARGET_TYPE_AR6004)
|
||||
return -EINVAL;
|
||||
|
||||
/* temporarily disable system sleep */
|
||||
@ -1403,7 +1352,8 @@ static int ath6kl_init_upload(struct ath6kl *ar)
|
||||
return status;
|
||||
|
||||
/* WAR to avoid SDIO CRC err */
|
||||
if (ar->version.target_ver == AR6003_HW_2_0_VERSION) {
|
||||
if (ar->version.target_ver == AR6003_HW_2_0_VERSION ||
|
||||
ar->version.target_ver == AR6003_HW_2_1_1_VERSION) {
|
||||
ath6kl_err("temporary war to avoid sdio crc error\n");
|
||||
|
||||
param = 0x20;
|
||||
@ -1726,9 +1676,11 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
|
||||
* configure NOT to reset the target during a debug session.
|
||||
*/
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC,
|
||||
"attempting to reset target on instance destroy\n");
|
||||
"attempting to reset target on instance destroy\n");
|
||||
ath6kl_reset_device(ar, ar->target_type, true, true);
|
||||
|
||||
clear_bit(WLAN_ENABLED, &ar->flag);
|
||||
|
||||
up(&ar->sem);
|
||||
}
|
||||
EXPORT_SYMBOL(ath6kl_stop_txrx);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -80,11 +81,21 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid,
|
||||
static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
|
||||
{
|
||||
struct ath6kl_sta *sta = &ar->sta_list[i];
|
||||
struct ath6kl_mgmt_buff *entry, *tmp;
|
||||
|
||||
/* empty the queued pkts in the PS queue if any */
|
||||
spin_lock_bh(&sta->psq_lock);
|
||||
skb_queue_purge(&sta->psq);
|
||||
skb_queue_purge(&sta->apsdq);
|
||||
|
||||
if (sta->mgmt_psq_len != 0) {
|
||||
list_for_each_entry_safe(entry, tmp, &sta->mgmt_psq, list) {
|
||||
kfree(entry);
|
||||
}
|
||||
INIT_LIST_HEAD(&sta->mgmt_psq);
|
||||
sta->mgmt_psq_len = 0;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&sta->psq_lock);
|
||||
|
||||
memset(&ar->ap_stats.sta[sta->aid - 1], 0,
|
||||
@ -339,7 +350,7 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
|
||||
__le32 data;
|
||||
|
||||
if (target_type != TARGET_TYPE_AR6003 &&
|
||||
target_type != TARGET_TYPE_AR6004)
|
||||
target_type != TARGET_TYPE_AR6004)
|
||||
return;
|
||||
|
||||
data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
|
||||
@ -588,11 +599,9 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
|
||||
memcpy(vif->bssid, bssid, sizeof(vif->bssid));
|
||||
vif->bss_ch = channel;
|
||||
|
||||
if ((vif->nw_type == INFRA_NETWORK)) {
|
||||
ar->listen_intvl_b = listen_int;
|
||||
if ((vif->nw_type == INFRA_NETWORK))
|
||||
ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
0, ar->listen_intvl_b);
|
||||
}
|
||||
vif->listen_intvl_t, 0);
|
||||
|
||||
netif_wake_queue(vif->ndev);
|
||||
|
||||
@ -810,6 +819,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid)
|
||||
struct sk_buff *skb;
|
||||
bool psq_empty = false;
|
||||
struct ath6kl *ar = vif->ar;
|
||||
struct ath6kl_mgmt_buff *mgmt_buf;
|
||||
|
||||
conn = ath6kl_find_sta_by_aid(ar, aid);
|
||||
|
||||
@ -820,7 +830,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid)
|
||||
* becomes empty update the PVB for this station.
|
||||
*/
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
psq_empty = skb_queue_empty(&conn->psq);
|
||||
psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0);
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
|
||||
if (psq_empty)
|
||||
@ -828,15 +838,31 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid)
|
||||
return;
|
||||
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
skb = skb_dequeue(&conn->psq);
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
if (conn->mgmt_psq_len > 0) {
|
||||
mgmt_buf = list_first_entry(&conn->mgmt_psq,
|
||||
struct ath6kl_mgmt_buff, list);
|
||||
list_del(&mgmt_buf->list);
|
||||
conn->mgmt_psq_len--;
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
|
||||
conn->sta_flags |= STA_PS_POLLED;
|
||||
ath6kl_data_tx(skb, vif->ndev);
|
||||
conn->sta_flags &= ~STA_PS_POLLED;
|
||||
conn->sta_flags |= STA_PS_POLLED;
|
||||
ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
mgmt_buf->id, mgmt_buf->freq,
|
||||
mgmt_buf->wait, mgmt_buf->buf,
|
||||
mgmt_buf->len, mgmt_buf->no_cck);
|
||||
conn->sta_flags &= ~STA_PS_POLLED;
|
||||
kfree(mgmt_buf);
|
||||
} else {
|
||||
skb = skb_dequeue(&conn->psq);
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
|
||||
conn->sta_flags |= STA_PS_POLLED;
|
||||
ath6kl_data_tx(skb, vif->ndev);
|
||||
conn->sta_flags &= ~STA_PS_POLLED;
|
||||
}
|
||||
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
psq_empty = skb_queue_empty(&conn->psq);
|
||||
psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0);
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
|
||||
if (psq_empty)
|
||||
@ -922,8 +948,8 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
|
||||
}
|
||||
|
||||
ath6kl_cfg80211_disconnect_event(vif, reason, bssid,
|
||||
assoc_resp_len, assoc_info,
|
||||
prot_reason_status);
|
||||
assoc_resp_len, assoc_info,
|
||||
prot_reason_status);
|
||||
|
||||
aggr_reset_state(vif->aggr_cntxt->aggr_conn);
|
||||
|
||||
@ -943,9 +969,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
|
||||
} else {
|
||||
set_bit(CONNECT_PEND, &vif->flags);
|
||||
if (((reason == ASSOC_FAILED) &&
|
||||
(prot_reason_status == 0x11)) ||
|
||||
((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
|
||||
&& (vif->reconnect_flag == 1))) {
|
||||
(prot_reason_status == 0x11)) ||
|
||||
((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) &&
|
||||
(vif->reconnect_flag == 1))) {
|
||||
set_bit(CONNECTED, &vif->flags);
|
||||
return;
|
||||
}
|
||||
@ -1079,7 +1105,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
if (mc_all_on || mc_all_off) {
|
||||
/* Enable/disable all multicast */
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n",
|
||||
mc_all_on ? "enabling" : "disabling");
|
||||
mc_all_on ? "enabling" : "disabling");
|
||||
ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
|
||||
mc_all_on);
|
||||
if (ret)
|
||||
@ -1092,7 +1118,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
found = false;
|
||||
netdev_for_each_mc_addr(ha, ndev) {
|
||||
if (memcmp(ha->addr, mc_filter->hw_addr,
|
||||
ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
|
||||
ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -1111,7 +1137,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
false);
|
||||
if (ret) {
|
||||
ath6kl_warn("Failed to remove multicast filter:%pM\n",
|
||||
mc_filter->hw_addr);
|
||||
mc_filter->hw_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1126,7 +1152,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
found = false;
|
||||
list_for_each_entry(mc_filter, &vif->mc_filter, list) {
|
||||
if (memcmp(ha->addr, mc_filter->hw_addr,
|
||||
ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
|
||||
ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -1151,7 +1177,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
true);
|
||||
if (ret) {
|
||||
ath6kl_warn("Failed to add multicast filter :%pM\n",
|
||||
mc_filter->hw_addr);
|
||||
mc_filter->hw_addr);
|
||||
kfree(mc_filter);
|
||||
goto out;
|
||||
}
|
||||
@ -1184,5 +1210,7 @@ void init_netdev(struct net_device *dev)
|
||||
sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
|
||||
+ WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
|
||||
|
||||
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -31,6 +32,7 @@
|
||||
struct ath6kl_sdio {
|
||||
struct sdio_func *func;
|
||||
|
||||
/* protects access to bus_req_freeq */
|
||||
spinlock_t lock;
|
||||
|
||||
/* free list */
|
||||
@ -49,16 +51,20 @@ struct ath6kl_sdio {
|
||||
/* scatter request list head */
|
||||
struct list_head scat_req;
|
||||
|
||||
/* Avoids disabling irq while the interrupts being handled */
|
||||
struct mutex mtx_irq;
|
||||
atomic_t irq_handling;
|
||||
wait_queue_head_t irq_wq;
|
||||
|
||||
/* protects access to scat_req */
|
||||
spinlock_t scat_lock;
|
||||
|
||||
bool scatter_enabled;
|
||||
|
||||
bool is_disabled;
|
||||
const struct sdio_device_id *id;
|
||||
struct work_struct wr_async_work;
|
||||
struct list_head wr_asyncq;
|
||||
|
||||
/* protects access to wr_asyncq */
|
||||
spinlock_t wr_async_lock;
|
||||
};
|
||||
|
||||
@ -404,7 +410,10 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
|
||||
return -ENOMEM;
|
||||
mutex_lock(&ar_sdio->dma_buffer_mutex);
|
||||
tbuf = ar_sdio->dma_buffer;
|
||||
memcpy(tbuf, buf, len);
|
||||
|
||||
if (request & HIF_WRITE)
|
||||
memcpy(tbuf, buf, len);
|
||||
|
||||
bounced = true;
|
||||
} else
|
||||
tbuf = buf;
|
||||
@ -462,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
|
||||
ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
|
||||
|
||||
ar_sdio = sdio_get_drvdata(func);
|
||||
mutex_lock(&ar_sdio->mtx_irq);
|
||||
atomic_set(&ar_sdio->irq_handling, 1);
|
||||
/*
|
||||
* Release the host during interrups so we can pick it back up when
|
||||
* we process commands.
|
||||
@ -471,7 +480,10 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
|
||||
|
||||
status = ath6kl_hif_intr_bh_handler(ar_sdio->ar);
|
||||
sdio_claim_host(ar_sdio->func);
|
||||
mutex_unlock(&ar_sdio->mtx_irq);
|
||||
|
||||
atomic_set(&ar_sdio->irq_handling, 0);
|
||||
wake_up(&ar_sdio->irq_wq);
|
||||
|
||||
WARN_ON(status && status != -ECANCELED);
|
||||
}
|
||||
|
||||
@ -572,6 +584,13 @@ static void ath6kl_sdio_irq_enable(struct ath6kl *ar)
|
||||
sdio_release_host(ar_sdio->func);
|
||||
}
|
||||
|
||||
static bool ath6kl_sdio_is_on_irq(struct ath6kl *ar)
|
||||
{
|
||||
struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
|
||||
|
||||
return !atomic_read(&ar_sdio->irq_handling);
|
||||
}
|
||||
|
||||
static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
|
||||
{
|
||||
struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
|
||||
@ -579,14 +598,21 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
|
||||
|
||||
sdio_claim_host(ar_sdio->func);
|
||||
|
||||
mutex_lock(&ar_sdio->mtx_irq);
|
||||
if (atomic_read(&ar_sdio->irq_handling)) {
|
||||
sdio_release_host(ar_sdio->func);
|
||||
|
||||
ret = wait_event_interruptible(ar_sdio->irq_wq,
|
||||
ath6kl_sdio_is_on_irq(ar));
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
sdio_claim_host(ar_sdio->func);
|
||||
}
|
||||
|
||||
ret = sdio_release_irq(ar_sdio->func);
|
||||
if (ret)
|
||||
ath6kl_err("Failed to release sdio irq: %d\n", ret);
|
||||
|
||||
mutex_unlock(&ar_sdio->mtx_irq);
|
||||
|
||||
sdio_release_host(ar_sdio->func);
|
||||
}
|
||||
|
||||
@ -601,6 +627,8 @@ static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar)
|
||||
node = list_first_entry(&ar_sdio->scat_req,
|
||||
struct hif_scatter_req, list);
|
||||
list_del(&node->list);
|
||||
|
||||
node->scat_q_depth = get_queue_depth(&ar_sdio->scat_req);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&ar_sdio->scat_lock);
|
||||
@ -633,8 +661,8 @@ static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar,
|
||||
return -EINVAL;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_SCATTER,
|
||||
"hif-scatter: total len: %d scatter entries: %d\n",
|
||||
scat_req->len, scat_req->scat_entries);
|
||||
"hif-scatter: total len: %d scatter entries: %d\n",
|
||||
scat_req->len, scat_req->scat_entries);
|
||||
|
||||
if (request & HIF_SYNCHRONOUS)
|
||||
status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest);
|
||||
@ -813,6 +841,7 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
||||
struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
|
||||
struct sdio_func *func = ar_sdio->func;
|
||||
mmc_pm_flag_t flags;
|
||||
bool try_deepsleep = false;
|
||||
int ret;
|
||||
|
||||
if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
|
||||
@ -839,14 +868,22 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
||||
goto cut_pwr;
|
||||
|
||||
ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
|
||||
if (ret)
|
||||
goto cut_pwr;
|
||||
if (ret && ret != -ENOTCONN)
|
||||
ath6kl_err("wow suspend failed: %d\n", ret);
|
||||
|
||||
return 0;
|
||||
if (ret &&
|
||||
(!ar->wow_suspend_mode ||
|
||||
ar->wow_suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP))
|
||||
try_deepsleep = true;
|
||||
else if (ret &&
|
||||
ar->wow_suspend_mode == WLAN_POWER_STATE_CUT_PWR)
|
||||
goto cut_pwr;
|
||||
if (!ret)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
|
||||
!ar->suspend_mode) {
|
||||
!ar->suspend_mode || try_deepsleep) {
|
||||
|
||||
flags = sdio_get_host_pm_caps(func);
|
||||
if (!(flags & MMC_PM_KEEP_POWER))
|
||||
@ -901,8 +938,15 @@ static int ath6kl_sdio_resume(struct ath6kl *ar)
|
||||
|
||||
case ATH6KL_STATE_WOW:
|
||||
break;
|
||||
|
||||
case ATH6KL_STATE_SCHED_SCAN:
|
||||
break;
|
||||
|
||||
case ATH6KL_STATE_SUSPENDING:
|
||||
break;
|
||||
|
||||
case ATH6KL_STATE_RESUMING:
|
||||
break;
|
||||
}
|
||||
|
||||
ath6kl_cfg80211_resume(ar);
|
||||
@ -981,7 +1025,7 @@ static int ath6kl_sdio_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
|
||||
(u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC);
|
||||
if (status) {
|
||||
ath6kl_err("%s: failed to read from window data addr\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1285,7 +1329,6 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
|
||||
spin_lock_init(&ar_sdio->scat_lock);
|
||||
spin_lock_init(&ar_sdio->wr_async_lock);
|
||||
mutex_init(&ar_sdio->dma_buffer_mutex);
|
||||
mutex_init(&ar_sdio->mtx_irq);
|
||||
|
||||
INIT_LIST_HEAD(&ar_sdio->scat_req);
|
||||
INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
|
||||
@ -1293,6 +1336,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
|
||||
|
||||
INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work);
|
||||
|
||||
init_waitqueue_head(&ar_sdio->irq_wq);
|
||||
|
||||
for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
|
||||
ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2010 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -19,6 +20,7 @@
|
||||
|
||||
#define AR6003_BOARD_DATA_SZ 1024
|
||||
#define AR6003_BOARD_EXT_DATA_SZ 768
|
||||
#define AR6003_BOARD_EXT_DATA_SZ_V2 1024
|
||||
|
||||
#define AR6004_BOARD_DATA_SZ 6144
|
||||
#define AR6004_BOARD_EXT_DATA_SZ 0
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -158,8 +159,8 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn,
|
||||
*/
|
||||
if (is_apsdq_empty) {
|
||||
ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
|
||||
vif->fw_vif_idx,
|
||||
conn->aid, 1, 0);
|
||||
vif->fw_vif_idx,
|
||||
conn->aid, 1, 0);
|
||||
}
|
||||
*flags |= WMI_DATA_HDR_FLAGS_UAPSD;
|
||||
|
||||
@ -284,6 +285,9 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
|
||||
int status = 0;
|
||||
struct ath6kl_cookie *cookie = NULL;
|
||||
|
||||
if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW))
|
||||
return -EACCES;
|
||||
|
||||
spin_lock_bh(&ar->lock);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
|
||||
@ -359,6 +363,11 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) {
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!test_bit(WMI_READY, &ar->flag))
|
||||
goto fail_tx;
|
||||
|
||||
@ -370,7 +379,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
if (test_bit(WMI_ENABLED, &ar->flag)) {
|
||||
if ((dev->features & NETIF_F_IP_CSUM) &&
|
||||
(csum == CHECKSUM_PARTIAL)) {
|
||||
(csum == CHECKSUM_PARTIAL)) {
|
||||
csum_start = skb->csum_start -
|
||||
(skb_network_header(skb) - skb->head) +
|
||||
sizeof(struct ath6kl_llc_snap_hdr);
|
||||
@ -394,7 +403,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
if ((dev->features & NETIF_F_IP_CSUM) &&
|
||||
(csum == CHECKSUM_PARTIAL)) {
|
||||
(csum == CHECKSUM_PARTIAL)) {
|
||||
meta_v2.csum_start = csum_start;
|
||||
meta_v2.csum_dest = csum_dest;
|
||||
|
||||
@ -419,7 +428,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
if ((vif->nw_type == ADHOC_NETWORK) &&
|
||||
ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags))
|
||||
ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags))
|
||||
chk_adhoc_ps_mapping = true;
|
||||
else {
|
||||
/* get the stream mapping */
|
||||
@ -593,7 +602,8 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
|
||||
*/
|
||||
if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] <
|
||||
ar->hiac_stream_active_pri &&
|
||||
ar->cookie_count <= MAX_HI_COOKIE_NUM)
|
||||
ar->cookie_count <=
|
||||
target->endpoint[endpoint].tx_drop_packet_threshold)
|
||||
/*
|
||||
* Give preference to the highest priority stream by
|
||||
* dropping the packets which overflowed.
|
||||
@ -876,7 +886,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
|
||||
if (!IS_ALIGNED((unsigned long) skb->data, 4))
|
||||
skb->data = PTR_ALIGN(skb->data - 4, 4);
|
||||
set_htc_rxpkt_info(packet, skb, skb->data,
|
||||
ATH6KL_BUFFER_SIZE, endpoint);
|
||||
ATH6KL_BUFFER_SIZE, endpoint);
|
||||
list_add_tail(&packet->list, &queue);
|
||||
}
|
||||
|
||||
@ -1256,8 +1266,8 @@ static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif,
|
||||
flags = 0;
|
||||
|
||||
ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
|
||||
vif->fw_vif_idx,
|
||||
conn->aid, 0, flags);
|
||||
vif->fw_vif_idx,
|
||||
conn->aid, 0, flags);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1296,7 +1306,15 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
||||
skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
|
||||
skb_pull(skb, HTC_HDR_LENGTH);
|
||||
|
||||
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
|
||||
skb->data, skb->len);
|
||||
|
||||
if (ept == ar->ctrl_ep) {
|
||||
if (test_bit(WMI_ENABLED, &ar->flag)) {
|
||||
ath6kl_check_wow_status(ar);
|
||||
ath6kl_wmi_control_rx(ar->wmi, skb);
|
||||
return;
|
||||
}
|
||||
if_idx =
|
||||
wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data);
|
||||
} else {
|
||||
@ -1321,10 +1339,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
||||
|
||||
spin_unlock_bh(&vif->if_lock);
|
||||
|
||||
|
||||
ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
|
||||
skb->data, skb->len);
|
||||
|
||||
skb->dev = vif->ndev;
|
||||
|
||||
if (!test_bit(WMI_ENABLED, &ar->flag)) {
|
||||
@ -1336,11 +1350,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
||||
|
||||
ath6kl_check_wow_status(ar);
|
||||
|
||||
if (ept == ar->ctrl_ep) {
|
||||
ath6kl_wmi_control_rx(ar->wmi, skb);
|
||||
return;
|
||||
}
|
||||
|
||||
min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) +
|
||||
sizeof(struct ath6kl_llc_snap_hdr);
|
||||
|
||||
@ -1416,8 +1425,33 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
||||
if (!(conn->sta_flags & STA_PS_SLEEP)) {
|
||||
struct sk_buff *skbuff = NULL;
|
||||
bool is_apsdq_empty;
|
||||
struct ath6kl_mgmt_buff *mgmt;
|
||||
u8 idx;
|
||||
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
while (conn->mgmt_psq_len > 0) {
|
||||
mgmt = list_first_entry(
|
||||
&conn->mgmt_psq,
|
||||
struct ath6kl_mgmt_buff,
|
||||
list);
|
||||
list_del(&mgmt->list);
|
||||
conn->mgmt_psq_len--;
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
idx = vif->fw_vif_idx;
|
||||
|
||||
ath6kl_wmi_send_mgmt_cmd(ar->wmi,
|
||||
idx,
|
||||
mgmt->id,
|
||||
mgmt->freq,
|
||||
mgmt->wait,
|
||||
mgmt->buf,
|
||||
mgmt->len,
|
||||
mgmt->no_cck);
|
||||
|
||||
kfree(mgmt);
|
||||
spin_lock_bh(&conn->psq_lock);
|
||||
}
|
||||
conn->mgmt_psq_len = 0;
|
||||
while ((skbuff = skb_dequeue(&conn->psq))) {
|
||||
spin_unlock_bh(&conn->psq_lock);
|
||||
ath6kl_data_tx(skbuff, vif->ndev);
|
||||
@ -1541,7 +1575,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
||||
aggr_conn = vif->aggr_cntxt->aggr_conn;
|
||||
|
||||
if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
|
||||
is_amsdu, skb)) {
|
||||
is_amsdu, skb)) {
|
||||
/* aggregation code will handle the skb */
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -126,7 +127,7 @@ int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb)
|
||||
|
||||
if (!is_ethertype(be16_to_cpu(type))) {
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"%s: pkt is already in 802.3 format\n", __func__);
|
||||
"%s: pkt is already in 802.3 format\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -827,8 +828,8 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
|
||||
if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 &&
|
||||
pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) {
|
||||
/* WMM OUT (00:50:F2) */
|
||||
if (pie[1] > 5
|
||||
&& pie[6] == WMM_PARAM_OUI_SUBTYPE)
|
||||
if (pie[1] > 5 &&
|
||||
pie[6] == WMM_PARAM_OUI_SUBTYPE)
|
||||
wmi->is_wmm_enabled = true;
|
||||
}
|
||||
break;
|
||||
@ -912,17 +913,17 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
|
||||
regpair = ath6kl_get_regpair((u16) reg_code);
|
||||
country = ath6kl_regd_find_country_by_rd((u16) reg_code);
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
|
||||
regpair->regDmnEnum);
|
||||
regpair->regDmnEnum);
|
||||
}
|
||||
|
||||
if (country) {
|
||||
if (country && wmi->parent_dev->wiphy_registered) {
|
||||
alpha2[0] = country->isoName[0];
|
||||
alpha2[1] = country->isoName[1];
|
||||
|
||||
regulatory_hint(wmi->parent_dev->wiphy, alpha2);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n",
|
||||
alpha2[0], alpha2[1]);
|
||||
alpha2[0], alpha2[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1033,8 +1034,9 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
|
||||
if (len < 8 + 2 + 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags)
|
||||
&& memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) {
|
||||
if (bih->frame_type == BEACON_FTYPE &&
|
||||
test_bit(CONNECTED, &vif->flags) &&
|
||||
memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) {
|
||||
const u8 *tim;
|
||||
tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
|
||||
len - 8 - 2 - 2);
|
||||
@ -1366,8 +1368,8 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
|
||||
/* Upper threshold breached */
|
||||
if (rssi < sq_thresh->upper_threshold[0]) {
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"spurious upper rssi threshold event: %d\n",
|
||||
rssi);
|
||||
"spurious upper rssi threshold event: %d\n",
|
||||
rssi);
|
||||
} else if ((rssi < sq_thresh->upper_threshold[1]) &&
|
||||
(rssi >= sq_thresh->upper_threshold[0])) {
|
||||
new_threshold = WMI_RSSI_THRESHOLD1_ABOVE;
|
||||
@ -1390,7 +1392,7 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
|
||||
/* Lower threshold breached */
|
||||
if (rssi > sq_thresh->lower_threshold[0]) {
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"spurious lower rssi threshold event: %d %d\n",
|
||||
"spurious lower rssi threshold event: %d %d\n",
|
||||
rssi, sq_thresh->lower_threshold[0]);
|
||||
} else if ((rssi > sq_thresh->lower_threshold[1]) &&
|
||||
(rssi <= sq_thresh->lower_threshold[0])) {
|
||||
@ -1551,8 +1553,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
|
||||
/* Upper threshold breached */
|
||||
if (snr < sq_thresh->upper_threshold[0]) {
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"spurious upper snr threshold event: %d\n",
|
||||
snr);
|
||||
"spurious upper snr threshold event: %d\n",
|
||||
snr);
|
||||
} else if ((snr < sq_thresh->upper_threshold[1]) &&
|
||||
(snr >= sq_thresh->upper_threshold[0])) {
|
||||
new_threshold = WMI_SNR_THRESHOLD1_ABOVE;
|
||||
@ -1569,8 +1571,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
|
||||
/* Lower threshold breached */
|
||||
if (snr > sq_thresh->lower_threshold[0]) {
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"spurious lower snr threshold event: %d\n",
|
||||
sq_thresh->lower_threshold[0]);
|
||||
"spurious lower snr threshold event: %d\n",
|
||||
sq_thresh->lower_threshold[0]);
|
||||
} else if ((snr > sq_thresh->lower_threshold[1]) &&
|
||||
(snr <= sq_thresh->lower_threshold[0])) {
|
||||
new_threshold = WMI_SNR_THRESHOLD4_BELOW;
|
||||
@ -2028,6 +2030,26 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx,
|
||||
u16 bmiss_time, u16 num_beacons)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct wmi_bmiss_time_cmd *cmd;
|
||||
int ret;
|
||||
|
||||
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_bmiss_time_cmd *) skb->data;
|
||||
cmd->bmiss_time = cpu_to_le16(bmiss_time);
|
||||
cmd->num_beacons = cpu_to_le16(num_beacons);
|
||||
|
||||
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BMISS_TIME_CMDID,
|
||||
NO_SYNC_WMIFLAG);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@ -2613,7 +2635,7 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
|
||||
int ret;
|
||||
|
||||
if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) &&
|
||||
wow_mode != ATH6KL_WOW_MODE_DISABLE) {
|
||||
wow_mode != ATH6KL_WOW_MODE_DISABLE) {
|
||||
ath6kl_err("invalid wow mode: %d\n", wow_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -3014,6 +3036,22 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
|
||||
NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct wmi_ap_hidden_ssid_cmd *cmd;
|
||||
|
||||
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_ap_hidden_ssid_cmd *) skb->data;
|
||||
cmd->hidden_ssid = enable ? 1 : 0;
|
||||
|
||||
return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_HIDDEN_SSID_CMDID,
|
||||
NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
/* This command will be used to enable/disable AP uAPSD feature */
|
||||
int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable)
|
||||
{
|
||||
@ -3183,8 +3221,9 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur)
|
||||
* ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P
|
||||
* mgmt operations using station interface.
|
||||
*/
|
||||
int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
|
||||
u32 wait, const u8 *data, u16 data_len)
|
||||
static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
|
||||
u32 freq, u32 wait, const u8 *data,
|
||||
u16 data_len)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct wmi_send_action_cmd *p;
|
||||
@ -3220,9 +3259,9 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
|
||||
NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
|
||||
u32 wait, const u8 *data, u16 data_len,
|
||||
u32 no_cck)
|
||||
static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
|
||||
u32 freq, u32 wait, const u8 *data,
|
||||
u16 data_len, u32 no_cck)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct wmi_send_mgmt_cmd *p;
|
||||
@ -3259,6 +3298,32 @@ int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
|
||||
NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
|
||||
u32 wait, const u8 *data, u16 data_len,
|
||||
u32 no_cck)
|
||||
{
|
||||
int status;
|
||||
struct ath6kl *ar = wmi->parent_dev;
|
||||
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
|
||||
ar->fw_capabilities)) {
|
||||
/*
|
||||
* If capable of doing P2P mgmt operations using
|
||||
* station interface, send additional information like
|
||||
* supported rates to advertise and xmit rates for
|
||||
* probe requests
|
||||
*/
|
||||
status = __ath6kl_wmi_send_mgmt_cmd(ar->wmi, if_idx, id, freq,
|
||||
wait, data, data_len,
|
||||
no_cck);
|
||||
} else {
|
||||
status = ath6kl_wmi_send_action_cmd(ar->wmi, if_idx, id, freq,
|
||||
wait, data, data_len);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
|
||||
const u8 *dst, const u8 *data,
|
||||
u16 data_len)
|
||||
@ -3370,48 +3435,108 @@ static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len)
|
||||
return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len);
|
||||
}
|
||||
|
||||
/* Control Path */
|
||||
int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
/* Process interface specific wmi events, caller would free the datap */
|
||||
static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id,
|
||||
u8 *datap, u32 len)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd;
|
||||
struct ath6kl_vif *vif;
|
||||
u32 len;
|
||||
u16 id;
|
||||
u8 if_idx;
|
||||
u8 *datap;
|
||||
int ret = 0;
|
||||
|
||||
if (WARN_ON(skb == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
if (skb->len < sizeof(struct wmi_cmd_hdr)) {
|
||||
ath6kl_err("bad packet 1\n");
|
||||
dev_kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cmd = (struct wmi_cmd_hdr *) skb->data;
|
||||
id = le16_to_cpu(cmd->cmd_id);
|
||||
if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK;
|
||||
|
||||
skb_pull(skb, sizeof(struct wmi_cmd_hdr));
|
||||
|
||||
datap = skb->data;
|
||||
len = skb->len;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "wmi rx id %d len %d\n", id, len);
|
||||
ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ",
|
||||
datap, len);
|
||||
|
||||
vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx);
|
||||
if (!vif) {
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"Wmi event for unavailable vif, vif_index:%d\n",
|
||||
if_idx);
|
||||
dev_kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (cmd_id) {
|
||||
case WMI_CONNECT_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
|
||||
return ath6kl_wmi_connect_event_rx(wmi, datap, len, vif);
|
||||
case WMI_DISCONNECT_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
|
||||
return ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif);
|
||||
case WMI_TKIP_MICERR_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
|
||||
return ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif);
|
||||
case WMI_BSSINFO_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
|
||||
return ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif);
|
||||
case WMI_NEIGHBOR_REPORT_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
|
||||
return ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len,
|
||||
vif);
|
||||
case WMI_SCAN_COMPLETE_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
|
||||
return ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif);
|
||||
case WMI_REPORT_STATISTICS_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
|
||||
return ath6kl_wmi_stats_event_rx(wmi, datap, len, vif);
|
||||
case WMI_CAC_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
|
||||
return ath6kl_wmi_cac_event_rx(wmi, datap, len, vif);
|
||||
case WMI_PSPOLL_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
|
||||
return ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif);
|
||||
case WMI_DTIMEXPIRY_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
|
||||
return ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif);
|
||||
case WMI_ADDBA_REQ_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
|
||||
return ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif);
|
||||
case WMI_DELBA_REQ_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
|
||||
return ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif);
|
||||
case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
|
||||
return ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
|
||||
case WMI_REMAIN_ON_CHNL_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
|
||||
return ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
|
||||
case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n");
|
||||
return ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap,
|
||||
len, vif);
|
||||
case WMI_TX_STATUS_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n");
|
||||
return ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif);
|
||||
case WMI_RX_PROBE_REQ_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n");
|
||||
return ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif);
|
||||
case WMI_RX_ACTION_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
|
||||
return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
|
||||
default:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath6kl_wmi_proc_events(struct wmi *wmi, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd;
|
||||
int ret = 0;
|
||||
u32 len;
|
||||
u16 id;
|
||||
u8 if_idx;
|
||||
u8 *datap;
|
||||
|
||||
cmd = (struct wmi_cmd_hdr *) skb->data;
|
||||
id = le16_to_cpu(cmd->cmd_id);
|
||||
if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK;
|
||||
|
||||
skb_pull(skb, sizeof(struct wmi_cmd_hdr));
|
||||
datap = skb->data;
|
||||
len = skb->len;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "wmi rx id %d len %d\n", id, len);
|
||||
ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ",
|
||||
datap, len);
|
||||
|
||||
switch (id) {
|
||||
case WMI_GET_BITRATE_CMDID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n");
|
||||
@ -3429,26 +3554,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n");
|
||||
ret = ath6kl_wmi_ready_event_rx(wmi, datap, len);
|
||||
break;
|
||||
case WMI_CONNECT_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
|
||||
ret = ath6kl_wmi_connect_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_DISCONNECT_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
|
||||
ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_PEER_NODE_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n");
|
||||
ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len);
|
||||
break;
|
||||
case WMI_TKIP_MICERR_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
|
||||
ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_BSSINFO_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
|
||||
ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_REGDOMAIN_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
|
||||
ath6kl_wmi_regdomain_event(wmi, datap, len);
|
||||
@ -3457,23 +3566,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
|
||||
ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len);
|
||||
break;
|
||||
case WMI_NEIGHBOR_REPORT_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
|
||||
ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len,
|
||||
vif);
|
||||
break;
|
||||
case WMI_SCAN_COMPLETE_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
|
||||
ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_CMDERROR_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n");
|
||||
ret = ath6kl_wmi_error_event_rx(wmi, datap, len);
|
||||
break;
|
||||
case WMI_REPORT_STATISTICS_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
|
||||
ret = ath6kl_wmi_stats_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_RSSI_THRESHOLD_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n");
|
||||
ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len);
|
||||
@ -3493,10 +3589,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n");
|
||||
ret = ath6kl_wmi_control_rx_xtnd(wmi, skb);
|
||||
break;
|
||||
case WMI_CAC_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
|
||||
ret = ath6kl_wmi_cac_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_CHANNEL_CHANGE_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n");
|
||||
break;
|
||||
@ -3536,28 +3628,12 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n");
|
||||
ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len);
|
||||
break;
|
||||
case WMI_PSPOLL_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
|
||||
ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_DTIMEXPIRY_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
|
||||
ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_SET_PARAMS_REPLY_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n");
|
||||
break;
|
||||
case WMI_ADDBA_REQ_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
|
||||
ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_ADDBA_RESP_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n");
|
||||
break;
|
||||
case WMI_DELBA_REQ_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
|
||||
ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_REPORT_BTCOEX_CONFIG_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"WMI_REPORT_BTCOEX_CONFIG_EVENTID\n");
|
||||
@ -3570,52 +3646,39 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
|
||||
ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
|
||||
break;
|
||||
case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
|
||||
ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
|
||||
break;
|
||||
case WMI_REMAIN_ON_CHNL_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
|
||||
ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n");
|
||||
ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap,
|
||||
len, vif);
|
||||
break;
|
||||
case WMI_TX_STATUS_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n");
|
||||
ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_RX_PROBE_REQ_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n");
|
||||
ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_P2P_CAPABILITIES_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n");
|
||||
ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len);
|
||||
break;
|
||||
case WMI_RX_ACTION_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
|
||||
ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
|
||||
break;
|
||||
case WMI_P2P_INFO_EVENTID:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n");
|
||||
ret = ath6kl_wmi_p2p_info_event_rx(datap, len);
|
||||
break;
|
||||
default:
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id);
|
||||
ret = -EINVAL;
|
||||
/* may be the event is interface specific */
|
||||
ret = ath6kl_wmi_proc_events_vif(wmi, if_idx, id, datap, len);
|
||||
break;
|
||||
}
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Control Path */
|
||||
int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
|
||||
{
|
||||
if (WARN_ON(skb == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
if (skb->len < sizeof(struct wmi_cmd_hdr)) {
|
||||
ath6kl_err("bad packet 1\n");
|
||||
dev_kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ath6kl_wmi_proc_events(wmi, skb);
|
||||
}
|
||||
|
||||
void ath6kl_wmi_reset(struct wmi *wmi)
|
||||
{
|
||||
spin_lock_bh(&wmi->lock);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -110,6 +111,8 @@ struct wmi {
|
||||
u8 fat_pipe_exist;
|
||||
struct ath6kl *parent_dev;
|
||||
u8 pwr_mode;
|
||||
|
||||
/* protects fat_pipe_exist and stream_exist_for_ac */
|
||||
spinlock_t lock;
|
||||
enum htc_endpoint_id ep_id;
|
||||
struct sq_threshold_params
|
||||
@ -997,6 +1000,12 @@ struct wmi_listen_int_cmd {
|
||||
__le16 num_beacons;
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_BMISS_TIME_CMDID */
|
||||
struct wmi_bmiss_time_cmd {
|
||||
__le16 bmiss_time;
|
||||
__le16 num_beacons;
|
||||
};
|
||||
|
||||
/* WMI_SET_POWER_MODE_CMDID */
|
||||
enum wmi_power_mode {
|
||||
REC_POWER = 0x01,
|
||||
@ -1014,7 +1023,7 @@ struct wmi_power_mode_cmd {
|
||||
*/
|
||||
enum power_save_fail_event_policy {
|
||||
SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
|
||||
IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
|
||||
IGNORE_PS_FAIL_DURING_SCAN = 2,
|
||||
};
|
||||
|
||||
struct wmi_power_params_cmd {
|
||||
@ -1212,7 +1221,7 @@ struct wmi_snr_threshold_params_cmd {
|
||||
|
||||
enum wmi_preamble_policy {
|
||||
WMI_IGNORE_BARKER_IN_ERP = 0,
|
||||
WMI_DONOT_IGNORE_BARKER_IN_ERP
|
||||
WMI_FOLLOW_BARKER_IN_ERP,
|
||||
};
|
||||
|
||||
struct wmi_set_lpreamble_cmd {
|
||||
@ -2128,6 +2137,10 @@ struct wmi_rx_frame_format_cmd {
|
||||
u8 reserved[1];
|
||||
} __packed;
|
||||
|
||||
struct wmi_ap_hidden_ssid_cmd {
|
||||
u8 hidden_ssid;
|
||||
} __packed;
|
||||
|
||||
/* AP mode events */
|
||||
struct wmi_ap_set_apsd_cmd {
|
||||
u8 enable;
|
||||
@ -2413,6 +2426,8 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
|
||||
int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
|
||||
u16 listen_interval,
|
||||
u16 listen_beacons);
|
||||
int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx,
|
||||
u16 bmiss_time, u16 num_beacons);
|
||||
int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode);
|
||||
int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period,
|
||||
u16 ps_poll_num, u16 dtim_policy,
|
||||
@ -2484,6 +2499,7 @@ u8 ath6kl_wmi_get_traffic_class(u8 user_priority);
|
||||
|
||||
u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri);
|
||||
/* AP mode */
|
||||
int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable);
|
||||
int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
|
||||
struct wmi_connect_cmd *p);
|
||||
|
||||
@ -2505,9 +2521,6 @@ int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable);
|
||||
int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
|
||||
u32 dur);
|
||||
|
||||
int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
|
||||
u32 wait, const u8 *data, u16 data_len);
|
||||
|
||||
int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
|
||||
u32 wait, const u8 *data, u16 data_len,
|
||||
u32 no_cck);
|
||||
|
@ -834,9 +834,10 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||
AR_SREV_9287_11_OR_LATER(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9271_10(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
|
||||
modesIndex, regWrites);
|
||||
if (AR_SREV_9271_10(ah)) {
|
||||
REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA);
|
||||
REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa);
|
||||
}
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
@ -858,21 +859,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
|
||||
if (AR_SREV_9271(ah)) {
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
|
||||
REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
|
||||
modesIndex, regWrites);
|
||||
else
|
||||
REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
|
||||
modesIndex, regWrites);
|
||||
}
|
||||
|
||||
REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
|
||||
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan)) {
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
|
||||
REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex,
|
||||
regWrites);
|
||||
}
|
||||
|
||||
ar5008_hw_override_ini(ah, chan);
|
||||
ar5008_hw_set_channel_regs(ah, chan);
|
||||
|
@ -34,23 +34,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ARRAY_SIZE(ar9271Modes_9271), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
|
||||
ARRAY_SIZE(ar9271Common_9271), 2);
|
||||
INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
|
||||
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,
|
||||
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);
|
||||
INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
|
||||
ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5);
|
||||
INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
|
||||
ar9271Modes_high_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5);
|
||||
INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
|
||||
ar9271Modes_normal_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -79,7 +64,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
|
||||
ARRAY_SIZE(ar9280Common_9280_2), 2);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9280Modes_fast_clock_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
|
||||
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
|
||||
@ -160,11 +145,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
INI_RA(addac, 31,1) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Support for Japan ch.14 (2484) spread */
|
||||
void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniCckfirNormal,
|
||||
ar9287Common_normal_cck_fir_coeff_9287_1_1,
|
||||
@ -204,14 +184,10 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
|
||||
static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
|
||||
{
|
||||
u32 txgain_type;
|
||||
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
|
||||
AR5416_EEP_MINOR_VER_19) {
|
||||
txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
|
||||
|
||||
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9280Modes_high_power_tx_gain_9280_2,
|
||||
@ -227,8 +203,22 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
|
||||
{
|
||||
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9271Modes_high_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9271Modes_normal_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5);
|
||||
}
|
||||
|
||||
static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
{
|
||||
u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9287Modes_rx_gain_9287_1_1,
|
||||
@ -236,15 +226,15 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
else if (AR_SREV_9280_20(ah))
|
||||
ar9280_20_hw_init_rxgain_ini(ah);
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
if (AR_SREV_9271(ah)) {
|
||||
ar9271_hw_init_txgain_ini(ah, txgain_type);
|
||||
} else if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9287Modes_tx_gain_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5);
|
||||
} else if (AR_SREV_9280_20(ah)) {
|
||||
ar9280_20_hw_init_txgain_ini(ah);
|
||||
ar9280_20_hw_init_txgain_ini(ah, txgain_type);
|
||||
} else if (AR_SREV_9285_12_OR_LATER(ah)) {
|
||||
u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
|
||||
|
||||
/* txgain table */
|
||||
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
|
||||
if (AR_SREV_9285E_20(ah)) {
|
||||
|
@ -3092,12 +3092,6 @@ static const u32 ar9271Common_9271[][2] = {
|
||||
{0x0000d384, 0xf3307ff0},
|
||||
};
|
||||
|
||||
static const u32 ar9271Modes_9271_1_0_only[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311},
|
||||
{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
|
||||
};
|
||||
|
||||
static const u32 ar9271Modes_9271_ANI_reg[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2},
|
||||
|
@ -347,15 +347,12 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 size, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
|
||||
ads->ds_ctl1 = size & AR_BufLen;
|
||||
if (flags & ATH9K_RXDESC_INTREQ)
|
||||
ads->ds_ctl1 |= AR_RxIntrReq;
|
||||
|
||||
ads->ds_rxstatus8 &= ~AR_RxDone;
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
||||
memset(&(ads->u), 0, sizeof(ads->u));
|
||||
memset(&ads->u.rx, 0, sizeof(ads->u.rx));
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
|
||||
|
||||
|
@ -60,6 +60,8 @@
|
||||
#define AR_PHY_RF_CTL3 0x9828
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
|
||||
#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
|
||||
#define AR_PHY_TX_END_TO_ADC_ON 0xFF000000
|
||||
#define AR_PHY_TX_END_TO_ADC_ON_S 24
|
||||
|
||||
#define AR_PHY_ADC_CTL 0x982C
|
||||
#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
|
||||
|
@ -295,266 +295,6 @@ static const u32 ar9300_2p2_radio_core[][2] = {
|
||||
{0x00016bd4, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9300Common_rx_gain_table_merlin_2p2[][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 ar9300_2p2_mac_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
@ -572,48 +312,6 @@ static const u32 ar9300_2p2_soc_postamble[][5] = {
|
||||
{0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
|
||||
};
|
||||
|
||||
static const u32 ar9200_merlin_2p2_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 ar9300_2p2_baseband_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
|
||||
|
@ -87,11 +87,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
/* additional clock settings */
|
||||
if (ah->is_clk_25mhz)
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniAdditional,
|
||||
ar9331_1p1_xtal_25M,
|
||||
ARRAY_SIZE(ar9331_1p1_xtal_25M), 2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniAdditional,
|
||||
ar9331_1p1_xtal_40M,
|
||||
ARRAY_SIZE(ar9331_1p1_xtal_40M), 2);
|
||||
} else if (AR_SREV_9330_12(ah)) {
|
||||
@ -140,11 +140,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
/* additional clock settings */
|
||||
if (ah->is_clk_25mhz)
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniAdditional,
|
||||
ar9331_1p2_xtal_25M,
|
||||
ARRAY_SIZE(ar9331_1p2_xtal_25M), 2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniAdditional,
|
||||
ar9331_1p2_xtal_40M,
|
||||
ARRAY_SIZE(ar9331_1p2_xtal_40M), 2);
|
||||
} else if (AR_SREV_9340(ah)) {
|
||||
@ -194,15 +194,16 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9340Modes_fast_clock_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
|
||||
3);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
|
||||
ar9340_1p0_radio_core_40M,
|
||||
ARRAY_SIZE(ar9340_1p0_radio_core_40M),
|
||||
2);
|
||||
if (!ah->is_clk_25mhz)
|
||||
INIT_INI_ARRAY(&ah->iniAdditional,
|
||||
ar9340_1p0_radio_core_40M,
|
||||
ARRAY_SIZE(ar9340_1p0_radio_core_40M),
|
||||
2);
|
||||
} else if (AR_SREV_9485_11(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
@ -321,7 +322,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
2);
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9462_modes_fast_clock_2p0,
|
||||
ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3);
|
||||
|
||||
@ -378,7 +379,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
|
||||
5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9580_1p0_modes_fast_clock,
|
||||
ARRAY_SIZE(ar9580_1p0_modes_fast_clock),
|
||||
3);
|
||||
@ -445,7 +446,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
2);
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9300Modes_fast_clock_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
|
||||
3);
|
||||
|
@ -679,18 +679,17 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
* different modal values.
|
||||
*/
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional,
|
||||
REG_WRITE_ARRAY(&ah->iniModesFastClock,
|
||||
modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9330(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
|
||||
|
||||
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
|
||||
REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
|
||||
|
||||
if (AR_SREV_9462(ah))
|
||||
ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1);
|
||||
|
||||
if (chan->channel == 2484)
|
||||
ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1);
|
||||
|
||||
ah->modes_index = modesIndex;
|
||||
ar9003_hw_override_ini(ah);
|
||||
ar9003_hw_set_channel_regs(ah, chan);
|
||||
@ -1320,13 +1319,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
|
||||
* different modal values.
|
||||
*/
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites);
|
||||
REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9330(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
|
||||
|
||||
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
|
||||
REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
|
||||
|
||||
ah->modes_index = modesIndex;
|
||||
*ini_reloaded = true;
|
||||
|
@ -583,19 +583,13 @@ struct ath_ant_comb {
|
||||
|
||||
#define SC_OP_INVALID BIT(0)
|
||||
#define SC_OP_BEACONS BIT(1)
|
||||
#define SC_OP_RXAGGR BIT(2)
|
||||
#define SC_OP_TXAGGR BIT(3)
|
||||
#define SC_OP_OFFCHANNEL BIT(4)
|
||||
#define SC_OP_PREAMBLE_SHORT BIT(5)
|
||||
#define SC_OP_PROTECT_ENABLE BIT(6)
|
||||
#define SC_OP_RXFLUSH BIT(7)
|
||||
#define SC_OP_LED_ASSOCIATED BIT(8)
|
||||
#define SC_OP_LED_ON BIT(9)
|
||||
#define SC_OP_TSF_RESET BIT(11)
|
||||
#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
|
||||
#define SC_OP_BT_SCAN BIT(13)
|
||||
#define SC_OP_ANI_RUN BIT(14)
|
||||
#define SC_OP_PRIM_STA_VIF BIT(15)
|
||||
#define SC_OP_OFFCHANNEL BIT(2)
|
||||
#define SC_OP_RXFLUSH BIT(3)
|
||||
#define SC_OP_TSF_RESET BIT(4)
|
||||
#define SC_OP_BT_PRIORITY_DETECTED BIT(5)
|
||||
#define SC_OP_BT_SCAN BIT(6)
|
||||
#define SC_OP_ANI_RUN BIT(7)
|
||||
#define SC_OP_PRIM_STA_VIF BIT(8)
|
||||
|
||||
/* Powersave flags */
|
||||
#define PS_WAIT_FOR_BEACON BIT(0)
|
||||
@ -617,15 +611,12 @@ struct ath9k_vif_iter_data {
|
||||
int nstations; /* number of station vifs */
|
||||
int nwds; /* number of WDS vifs */
|
||||
int nadhocs; /* number of adhoc vifs */
|
||||
int nothers; /* number of vifs not specified above. */
|
||||
};
|
||||
|
||||
struct ath_softc {
|
||||
struct ieee80211_hw *hw;
|
||||
struct device *dev;
|
||||
|
||||
int chan_idx;
|
||||
int chan_is_ht;
|
||||
struct survey_info *cur_survey;
|
||||
struct survey_info survey[ATH9K_NUM_CHANNELS];
|
||||
|
||||
|
@ -67,7 +67,7 @@ int ath_beaconq_config(struct ath_softc *sc)
|
||||
* up rate codes, and channel flags. Beacons are always sent out at the
|
||||
* lowest rate, and are not retried.
|
||||
*/
|
||||
static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
|
||||
static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
|
||||
struct ath_buf *bf, int rateidx)
|
||||
{
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
@ -82,7 +82,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
|
||||
|
||||
sband = &sc->sbands[common->hw->conf.channel->band];
|
||||
rate = sband->bitrates[rateidx].hw_value;
|
||||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
if (vif->bss_conf.use_short_preamble)
|
||||
rate |= sband->bitrates[rateidx].hw_value_short;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
@ -209,7 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
|
||||
}
|
||||
}
|
||||
|
||||
ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx);
|
||||
ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx);
|
||||
|
||||
while (skb) {
|
||||
ath_tx_cabq(hw, skb);
|
||||
|
@ -738,9 +738,9 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
|
||||
|
||||
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",
|
||||
" ADHOC: %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,
|
||||
iter_data.nwds, iter_data.nadhocs,
|
||||
sc->nvifs, sc->nbcnvifs);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
|
@ -362,7 +362,8 @@ void ath9k_stop_btcoex(struct ath_softc *sc)
|
||||
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);
|
||||
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI)
|
||||
ath_mci_flush_profile(&sc->btcoex.mci);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -919,7 +919,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
|
||||
/* setup initial channel */
|
||||
init_channel = ath9k_cmn_get_curchannel(hw, ah);
|
||||
|
||||
ath9k_hw_htc_resetinit(ah);
|
||||
ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
|
||||
if (ret) {
|
||||
ath_err(common,
|
||||
|
@ -449,6 +449,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
|
||||
ah->slottime = ATH9K_SLOT_TIME_9;
|
||||
ah->globaltxtimeout = (u32) -1;
|
||||
ah->power_mode = ATH9K_PM_UNDEFINED;
|
||||
ah->htc_reset_init = true;
|
||||
}
|
||||
|
||||
static int ath9k_hw_init_macaddr(struct ath_hw *ah)
|
||||
@ -555,7 +556,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
|
||||
if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
|
||||
if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
|
||||
((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
|
||||
!ah->is_pciexpress)) {
|
||||
@ -619,9 +620,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
if (!ah->is_pciexpress)
|
||||
ath9k_hw_disablepcie(ah);
|
||||
|
||||
if (!AR_SREV_9300_20_OR_LATER(ah))
|
||||
ar9002_hw_cck_chan14_spread(ah);
|
||||
|
||||
r = ath9k_hw_post_init(ah);
|
||||
if (r)
|
||||
return r;
|
||||
@ -1521,17 +1519,81 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_check_alive);
|
||||
|
||||
/*
|
||||
* Fast channel change:
|
||||
* (Change synthesizer based on channel freq without resetting chip)
|
||||
*
|
||||
* Don't do FCC when
|
||||
* - Flag is not set
|
||||
* - Chip is just coming out of full sleep
|
||||
* - Channel to be set is same as current channel
|
||||
* - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel)
|
||||
*/
|
||||
static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int ret;
|
||||
|
||||
if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
|
||||
goto fail;
|
||||
|
||||
if (ah->chip_fullsleep)
|
||||
goto fail;
|
||||
|
||||
if (!ah->curchan)
|
||||
goto fail;
|
||||
|
||||
if (chan->channel == ah->curchan->channel)
|
||||
goto fail;
|
||||
|
||||
if ((chan->channelFlags & CHANNEL_ALL) !=
|
||||
(ah->curchan->channelFlags & CHANNEL_ALL))
|
||||
goto fail;
|
||||
|
||||
if (!ath9k_hw_check_alive(ah))
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* For AR9462, make sure that calibration data for
|
||||
* re-using are present.
|
||||
*/
|
||||
if (AR_SREV_9462(ah) && (!ah->caldata ||
|
||||
!ah->caldata->done_txiqcal_once ||
|
||||
!ah->caldata->done_txclcal_once ||
|
||||
!ah->caldata->rtt_hist.num_readings))
|
||||
goto fail;
|
||||
|
||||
ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n",
|
||||
ah->curchan->channel, chan->channel);
|
||||
|
||||
ret = ath9k_hw_channel_change(ah, chan);
|
||||
if (!ret)
|
||||
goto fail;
|
||||
|
||||
ath9k_hw_loadnf(ah, ah->curchan);
|
||||
ath9k_hw_start_nfcal(ah, true);
|
||||
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah))
|
||||
ar9003_mci_2g5g_switch(ah, true);
|
||||
|
||||
if (AR_SREV_9271(ah))
|
||||
ar9002_hw_load_ani_reg(ah, chan);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_hw_cal_data *caldata, bool bChannelChange)
|
||||
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 saveLedState;
|
||||
struct ath9k_channel *curchan = ah->curchan;
|
||||
u32 saveDefAntenna;
|
||||
u32 macStaId1;
|
||||
u64 tsf = 0;
|
||||
int i, r;
|
||||
bool allow_fbs = false, start_mci_reset = false;
|
||||
bool start_mci_reset = false;
|
||||
bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
|
||||
bool save_fullsleep = ah->chip_fullsleep;
|
||||
|
||||
@ -1544,8 +1606,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
|
||||
return -EIO;
|
||||
|
||||
if (curchan && !ah->chip_fullsleep)
|
||||
ath9k_hw_getnf(ah, curchan);
|
||||
if (ah->curchan && !ah->chip_fullsleep)
|
||||
ath9k_hw_getnf(ah, ah->curchan);
|
||||
|
||||
ah->caldata = caldata;
|
||||
if (caldata &&
|
||||
@ -1558,32 +1620,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
}
|
||||
ah->noise = ath9k_hw_getchan_noise(ah, chan);
|
||||
|
||||
if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
|
||||
bChannelChange = false;
|
||||
|
||||
if (caldata &&
|
||||
caldata->done_txiqcal_once &&
|
||||
caldata->done_txclcal_once &&
|
||||
caldata->rtt_hist.num_readings)
|
||||
allow_fbs = true;
|
||||
|
||||
if (bChannelChange &&
|
||||
(!ah->chip_fullsleep) &&
|
||||
(ah->curchan != NULL) &&
|
||||
(chan->channel != ah->curchan->channel) &&
|
||||
(allow_fbs ||
|
||||
((chan->channelFlags & CHANNEL_ALL) ==
|
||||
(ah->curchan->channelFlags & CHANNEL_ALL)))) {
|
||||
if (ath9k_hw_channel_change(ah, chan)) {
|
||||
ath9k_hw_loadnf(ah, ah->curchan);
|
||||
ath9k_hw_start_nfcal(ah, true);
|
||||
if (mci && ar9003_mci_is_ready(ah))
|
||||
ar9003_mci_2g5g_switch(ah, true);
|
||||
|
||||
if (AR_SREV_9271(ah))
|
||||
ar9002_hw_load_ani_reg(ah, chan);
|
||||
return 0;
|
||||
}
|
||||
if (fastcc) {
|
||||
r = ath9k_hw_do_fastcc(ah, chan);
|
||||
if (!r)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (mci)
|
||||
@ -2389,8 +2429,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
if (AR_SREV_9485_OR_LATER(ah))
|
||||
ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
|
||||
}
|
||||
if (AR_SREV_9462(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI;
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
|
||||
if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_MCI;
|
||||
|
||||
if (AR_SREV_9462_20(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_RTT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2516,12 +2565,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set_gpio);
|
||||
|
||||
u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
|
||||
{
|
||||
return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_getdefantenna);
|
||||
|
||||
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
|
||||
{
|
||||
REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
|
||||
@ -2579,6 +2622,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah)
|
||||
return false;
|
||||
|
||||
ath9k_hw_init_pll(ah, NULL);
|
||||
ah->htc_reset_init = true;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_phy_disable);
|
||||
@ -2939,12 +2983,6 @@ EXPORT_SYMBOL(ath_gen_timer_isr);
|
||||
/* HTC */
|
||||
/********/
|
||||
|
||||
void ath9k_hw_htc_resetinit(struct ath_hw *ah)
|
||||
{
|
||||
ah->htc_reset_init = true;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_htc_resetinit);
|
||||
|
||||
static struct {
|
||||
u32 version;
|
||||
const char * name;
|
||||
|
@ -827,19 +827,14 @@ struct ath_hw {
|
||||
struct ar5416IniArray iniAddac;
|
||||
struct ar5416IniArray iniPcieSerdes;
|
||||
struct ar5416IniArray iniPcieSerdesLowPower;
|
||||
struct ar5416IniArray iniModesAdditional;
|
||||
struct ar5416IniArray iniModesAdditional_40M;
|
||||
struct ar5416IniArray iniModesFastClock;
|
||||
struct ar5416IniArray iniAdditional;
|
||||
struct ar5416IniArray iniModesRxGain;
|
||||
struct ar5416IniArray iniModesTxGain;
|
||||
struct ar5416IniArray iniModes_9271_1_0_only;
|
||||
struct ar5416IniArray iniCckfirNormal;
|
||||
struct ar5416IniArray iniCckfirJapan2484;
|
||||
struct ar5416IniArray ini_japan2484;
|
||||
struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
|
||||
struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
|
||||
struct ar5416IniArray iniModes_9271_ANI_reg;
|
||||
struct ar5416IniArray iniModes_high_power_tx_gain_9271;
|
||||
struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
|
||||
struct ar5416IniArray ini_radio_post_sys2ant;
|
||||
struct ar5416IniArray ini_BTCOEX_MAX_TXPWR;
|
||||
|
||||
@ -924,7 +919,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid);
|
||||
void ath9k_hw_deinit(struct ath_hw *ah);
|
||||
int ath9k_hw_init(struct ath_hw *ah);
|
||||
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_hw_cal_data *caldata, bool bChannelChange);
|
||||
struct ath9k_hw_cal_data *caldata, bool fastcc);
|
||||
int ath9k_hw_fill_cap_info(struct ath_hw *ah);
|
||||
u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
|
||||
|
||||
@ -934,7 +929,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
|
||||
void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
|
||||
u32 ah_signal_type);
|
||||
void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
|
||||
u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
|
||||
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
|
||||
|
||||
/* General Operation */
|
||||
@ -988,9 +982,6 @@ void ath_gen_timer_isr(struct ath_hw *hw);
|
||||
|
||||
void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
|
||||
|
||||
/* HTC */
|
||||
void ath9k_hw_htc_resetinit(struct ath_hw *ah);
|
||||
|
||||
/* PHY */
|
||||
void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
|
||||
u32 *coef_mantissa, u32 *coef_exponent);
|
||||
@ -1000,7 +991,6 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
* Code Specific to AR5008, AR9001 or AR9002,
|
||||
* we stuff these here to avoid callbacks for AR9003.
|
||||
*/
|
||||
void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
|
||||
int ar9002_hw_rf_claim(struct ath_hw *ah);
|
||||
void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
|
||||
|
||||
|
@ -172,7 +172,7 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||
|
||||
if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
|
||||
if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&sc->sc_serial_rw, flags);
|
||||
iowrite32(val, sc->mem + reg_offset);
|
||||
@ -188,7 +188,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
|
||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||
u32 val;
|
||||
|
||||
if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
|
||||
if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&sc->sc_serial_rw, flags);
|
||||
val = ioread32(sc->mem + reg_offset);
|
||||
@ -219,7 +219,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl
|
||||
unsigned long uninitialized_var(flags);
|
||||
u32 val;
|
||||
|
||||
if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
|
||||
if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
|
||||
spin_lock_irqsave(&sc->sc_serial_rw, flags);
|
||||
val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
|
||||
spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
|
||||
@ -484,19 +484,11 @@ static void ath9k_init_misc(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
int i = 0;
|
||||
|
||||
setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
|
||||
|
||||
sc->config.txpowlimit = ATH_TXPOWER_MAX;
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
|
||||
sc->sc_flags |= SC_OP_TXAGGR;
|
||||
sc->sc_flags |= SC_OP_RXAGGR;
|
||||
}
|
||||
|
||||
sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
|
||||
|
||||
memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
|
||||
|
||||
sc->beacon.slottime = ATH9K_SLOT_TIME_9;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
|
||||
|
@ -185,13 +185,6 @@ bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_stop_dma_queue);
|
||||
|
||||
void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
|
||||
{
|
||||
*txqs &= ah->intr_txqs;
|
||||
ah->intr_txqs &= ~(*txqs);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs);
|
||||
|
||||
bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
|
||||
const struct ath9k_tx_queue_info *qinfo)
|
||||
{
|
||||
@ -340,6 +333,15 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_setuptxqueue);
|
||||
|
||||
static void ath9k_hw_clear_queue_interrupts(struct ath_hw *ah, u32 q)
|
||||
{
|
||||
ah->txok_interrupt_mask &= ~(1 << q);
|
||||
ah->txerr_interrupt_mask &= ~(1 << q);
|
||||
ah->txdesc_interrupt_mask &= ~(1 << q);
|
||||
ah->txeol_interrupt_mask &= ~(1 << q);
|
||||
ah->txurn_interrupt_mask &= ~(1 << q);
|
||||
}
|
||||
|
||||
bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@ -354,11 +356,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
|
||||
ath_dbg(common, QUEUE, "Release TX queue: %u\n", q);
|
||||
|
||||
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
|
||||
ah->txok_interrupt_mask &= ~(1 << q);
|
||||
ah->txerr_interrupt_mask &= ~(1 << q);
|
||||
ah->txdesc_interrupt_mask &= ~(1 << q);
|
||||
ah->txeol_interrupt_mask &= ~(1 << q);
|
||||
ah->txurn_interrupt_mask &= ~(1 << q);
|
||||
ath9k_hw_clear_queue_interrupts(ah, q);
|
||||
ath9k_hw_set_txq_interrupts(ah, qi);
|
||||
|
||||
return true;
|
||||
@ -510,26 +508,17 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
|
||||
|
||||
if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
|
||||
ath9k_hw_clear_queue_interrupts(ah, q);
|
||||
if (qi->tqi_qflags & TXQ_FLAG_TXINT_ENABLE) {
|
||||
ah->txok_interrupt_mask |= 1 << q;
|
||||
else
|
||||
ah->txok_interrupt_mask &= ~(1 << q);
|
||||
if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
|
||||
ah->txerr_interrupt_mask |= 1 << q;
|
||||
else
|
||||
ah->txerr_interrupt_mask &= ~(1 << q);
|
||||
}
|
||||
if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
|
||||
ah->txdesc_interrupt_mask |= 1 << q;
|
||||
else
|
||||
ah->txdesc_interrupt_mask &= ~(1 << q);
|
||||
if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
|
||||
ah->txeol_interrupt_mask |= 1 << q;
|
||||
else
|
||||
ah->txeol_interrupt_mask &= ~(1 << q);
|
||||
if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
|
||||
ah->txurn_interrupt_mask |= 1 << q;
|
||||
else
|
||||
ah->txurn_interrupt_mask &= ~(1 << q);
|
||||
ath9k_hw_set_txq_interrupts(ah, qi);
|
||||
|
||||
return true;
|
||||
@ -747,8 +736,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
|
||||
qi.tqi_cwmax = 0;
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
|
||||
TXQ_FLAG_TXERRINT_ENABLE;
|
||||
qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE;
|
||||
|
||||
return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
|
||||
}
|
||||
|
@ -583,8 +583,7 @@ enum ath9k_tx_queue {
|
||||
#define ATH9K_WME_UPSD 4
|
||||
|
||||
enum ath9k_tx_queue_flags {
|
||||
TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
|
||||
TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
|
||||
TXQ_FLAG_TXINT_ENABLE = 0x0001,
|
||||
TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
|
||||
TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
|
||||
TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
|
||||
@ -714,7 +713,6 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
|
||||
bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
|
||||
bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q);
|
||||
void ath9k_hw_abort_tx_dma(struct ath_hw *ah);
|
||||
void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
|
||||
bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
|
||||
const struct ath9k_tx_queue_info *qinfo);
|
||||
bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
|
||||
|
@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc)
|
||||
if (--sc->ps_usecount != 0)
|
||||
goto unlock;
|
||||
|
||||
if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
|
||||
if (sc->ps_flags & PS_WAIT_FOR_TX_ACK)
|
||||
goto unlock;
|
||||
|
||||
if (sc->ps_idle)
|
||||
mode = ATH9K_PM_FULL_SLEEP;
|
||||
else if (sc->ps_enabled &&
|
||||
!(sc->ps_flags & (PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
PS_WAIT_FOR_TX_ACK)))
|
||||
PS_WAIT_FOR_PSPOLL_DATA)))
|
||||
mode = ATH9K_PM_NETWORK_SLEEP;
|
||||
else
|
||||
goto unlock;
|
||||
@ -332,10 +334,6 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
||||
hchan = ah->curchan;
|
||||
}
|
||||
|
||||
if (fastcc && (ah->chip_fullsleep ||
|
||||
!ath9k_hw_check_alive(ah)))
|
||||
fastcc = false;
|
||||
|
||||
if (!ath_prepare_reset(sc, retry_tx, flush))
|
||||
fastcc = false;
|
||||
|
||||
@ -641,7 +639,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
#endif
|
||||
an->sta = sta;
|
||||
an->vif = vif;
|
||||
if (sc->sc_flags & SC_OP_TXAGGR) {
|
||||
|
||||
if (sta->ht_cap.ht_supported) {
|
||||
ath_tx_node_init(sc, an);
|
||||
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
sta->ht_cap.ampdu_factor);
|
||||
@ -660,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
|
||||
an->sta = NULL;
|
||||
#endif
|
||||
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
if (sta->ht_cap.ht_supported)
|
||||
ath_tx_node_cleanup(sc, an);
|
||||
}
|
||||
|
||||
@ -993,12 +992,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
curchan->center_freq);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
/* setup initial channel */
|
||||
sc->chan_idx = curchan->hw_value;
|
||||
|
||||
init_channel = ath9k_cmn_get_curchannel(hw, ah);
|
||||
|
||||
/* Reset SERDES registers */
|
||||
@ -1047,9 +1042,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
sc->sc_flags &= ~SC_OP_INVALID;
|
||||
sc->sc_ah->is_monitoring = false;
|
||||
|
||||
/* Disable BMISS interrupt when we're not associated */
|
||||
ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
|
||||
|
||||
if (!ath_complete_reset(sc, false)) {
|
||||
r = -EIO;
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
@ -1277,7 +1269,6 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
||||
iter_data->nwds++;
|
||||
break;
|
||||
default:
|
||||
iter_data->nothers++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1761,7 +1752,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_node *an = (struct ath_node *) sta->drv_priv;
|
||||
|
||||
if (!(sc->sc_flags & SC_OP_TXAGGR))
|
||||
if (!sta->ht_cap.ht_supported)
|
||||
return;
|
||||
|
||||
switch (cmd) {
|
||||
@ -1973,7 +1964,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
ath9k_ps_wakeup(sc);
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
if (changed & BSS_CHANGED_BSSID) {
|
||||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
ath9k_config_bss(sc, vif);
|
||||
|
||||
ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
|
||||
@ -2053,25 +2044,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
ath_beacon_config(sc, vif);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
|
||||
ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n",
|
||||
bss_conf->use_short_preamble);
|
||||
if (bss_conf->use_short_preamble)
|
||||
sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
|
||||
else
|
||||
sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
|
||||
ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n",
|
||||
bss_conf->use_cts_prot);
|
||||
if (bss_conf->use_cts_prot &&
|
||||
hw->conf.channel->band != IEEE80211_BAND_5GHZ)
|
||||
sc->sc_flags |= SC_OP_PROTECT_ENABLE;
|
||||
else
|
||||
sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc->mutex);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
@ -2129,15 +2101,10 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
|
||||
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
if (!(sc->sc_flags & SC_OP_RXAGGR))
|
||||
ret = -ENOTSUPP;
|
||||
break;
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
break;
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
if (!(sc->sc_flags & SC_OP_TXAGGR))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ret = ath_tx_aggr_start(sc, sta, tid, ssn);
|
||||
if (!ret)
|
||||
|
@ -748,7 +748,8 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
|
||||
* If 802.11g protection is enabled, determine whether to use RTS/CTS or
|
||||
* just CTS. Note that this is only done for OFDM/HT unicast frames.
|
||||
*/
|
||||
if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
|
||||
if ((tx_info->control.vif &&
|
||||
tx_info->control.vif->bss_conf.use_cts_prot) &&
|
||||
(rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
|
||||
WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
|
||||
rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
|
||||
@ -1298,12 +1299,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
return caps;
|
||||
}
|
||||
|
||||
static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
|
||||
static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
u8 tidno)
|
||||
{
|
||||
struct ath_node *an = (struct ath_node *)sta->drv_priv;
|
||||
struct ath_atx_tid *txtid;
|
||||
|
||||
if (!(sc->sc_flags & SC_OP_TXAGGR))
|
||||
if (!sta->ht_cap.ht_supported)
|
||||
return false;
|
||||
|
||||
txtid = ATH_AN_2_TID(an, tidno);
|
||||
@ -1374,13 +1376,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
|
||||
if (ieee80211_is_data_qos(fc) &&
|
||||
skb_get_queue_mapping(skb) != IEEE80211_AC_VO) {
|
||||
u8 *qc, tid;
|
||||
struct ath_node *an;
|
||||
|
||||
qc = ieee80211_get_qos_ctl(hdr);
|
||||
tid = qc[0] & 0xf;
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
|
||||
if(ath_tx_aggr_check(sc, an, tid))
|
||||
if(ath_tx_aggr_check(sc, sta, tid))
|
||||
ieee80211_start_tx_ba_session(sta, tid, 0);
|
||||
}
|
||||
}
|
||||
|
@ -982,8 +982,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
|
||||
{
|
||||
struct ath_hw *ah = common->ah;
|
||||
|
||||
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
|
||||
|
||||
/*
|
||||
* everything but the rate is checked here, the rate check is done
|
||||
* separately to avoid doing two lookups for a rate for each frame.
|
||||
@ -1841,6 +1839,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
if (sc->sc_flags & SC_OP_RXFLUSH)
|
||||
goto requeue_drop_frag;
|
||||
|
||||
memset(rxs, 0, sizeof(struct ieee80211_rx_status));
|
||||
|
||||
rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
|
||||
if (rs.rs_tstamp > tsf_lower &&
|
||||
unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
|
||||
|
@ -1151,6 +1151,7 @@ enum {
|
||||
#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
|
||||
#define AR_ENT_OTP 0x40d8
|
||||
#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
|
||||
#define AR_ENT_OTP_49GHZ_DISABLE 0x00100000
|
||||
#define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000
|
||||
|
||||
#define AR_CH0_BB_DPLL1 0x16180
|
||||
|
@ -955,7 +955,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
|
||||
*/
|
||||
rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
|
||||
info->rtscts_rate = rate->hw_value;
|
||||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
|
||||
if (tx_info->control.vif &&
|
||||
tx_info->control.vif->bss_conf.use_short_preamble)
|
||||
info->rtscts_rate |= rate->hw_value_short;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
@ -1290,14 +1292,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
|
||||
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
|
||||
if (sc->sc_flags & SC_OP_TXAGGR) {
|
||||
txtid = ATH_AN_2_TID(an, tid);
|
||||
txtid->baw_size =
|
||||
IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
|
||||
txtid->state |= AGGR_ADDBA_COMPLETE;
|
||||
txtid->state &= ~AGGR_ADDBA_PROGRESS;
|
||||
ath_tx_resume_tid(sc, txtid);
|
||||
}
|
||||
txtid = ATH_AN_2_TID(an, tid);
|
||||
txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
|
||||
txtid->state |= AGGR_ADDBA_COMPLETE;
|
||||
txtid->state &= ~AGGR_ADDBA_PROGRESS;
|
||||
ath_tx_resume_tid(sc, txtid);
|
||||
}
|
||||
|
||||
/********************/
|
||||
@ -1356,8 +1355,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
* based intr on the EOSP frames.
|
||||
*/
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
|
||||
TXQ_FLAG_TXERRINT_ENABLE;
|
||||
qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE;
|
||||
} else {
|
||||
if (qtype == ATH9K_TX_QUEUE_UAPSD)
|
||||
qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
|
||||
@ -1523,7 +1521,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
||||
ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx);
|
||||
|
||||
/* flush any pending frames if aggregation is enabled */
|
||||
if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx)
|
||||
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx)
|
||||
ath_txq_drain_pending_buffers(sc, txq);
|
||||
|
||||
ath_txq_unlock_complete(sc, txq);
|
||||
@ -1871,7 +1869,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
|
||||
struct ath_buf *bf;
|
||||
u8 tidno;
|
||||
|
||||
if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
|
||||
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an &&
|
||||
ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
tidno = ieee80211_get_qos_ctl(hdr)[0] &
|
||||
IEEE80211_QOS_CTL_TID_MASK;
|
||||
@ -2141,7 +2139,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||
} else
|
||||
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
|
||||
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
|
||||
ath_txq_schedule(sc, txq);
|
||||
}
|
||||
|
||||
@ -2166,7 +2164,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
|
||||
if (list_empty(&txq->axq_q)) {
|
||||
txq->axq_link = NULL;
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
|
||||
ath_txq_schedule(sc, txq);
|
||||
break;
|
||||
}
|
||||
@ -2263,10 +2261,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
|
||||
|
||||
void ath_tx_tasklet(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs;
|
||||
int i;
|
||||
u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
|
||||
|
||||
ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
|
||||
|
@ -57,7 +57,8 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
|
||||
}
|
||||
EXPORT_SYMBOL(ath_rxbuf_alloc);
|
||||
|
||||
void ath_printk(const char *level, const char *fmt, ...)
|
||||
void ath_printk(const char *level, const struct ath_common* common,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
struct va_format vaf;
|
||||
va_list args;
|
||||
@ -67,7 +68,11 @@ void ath_printk(const char *level, const char *fmt, ...)
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
|
||||
printk("%sath: %pV", level, &vaf);
|
||||
if (common && common->hw && common->hw->wiphy)
|
||||
printk("%sath: %s: %pV",
|
||||
level, wiphy_name(common->hw->wiphy), &vaf);
|
||||
else
|
||||
printk("%sath: %pV", level, &vaf);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
@ -932,6 +932,9 @@ struct b43_wl {
|
||||
/* Flag that implement the queues stopping. */
|
||||
bool tx_queue_stopped[B43_QOS_QUEUE_NUM];
|
||||
|
||||
/* firmware loading work */
|
||||
struct work_struct firmware_load;
|
||||
|
||||
/* The device LEDs. */
|
||||
struct b43_leds leds;
|
||||
|
||||
|
@ -2390,8 +2390,14 @@ error:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int b43_request_firmware(struct b43_wldev *dev)
|
||||
static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl);
|
||||
static void b43_one_core_detach(struct b43_bus_dev *dev);
|
||||
|
||||
static void b43_request_firmware(struct work_struct *work)
|
||||
{
|
||||
struct b43_wl *wl = container_of(work,
|
||||
struct b43_wl, firmware_load);
|
||||
struct b43_wldev *dev = wl->current_dev;
|
||||
struct b43_request_fw_context *ctx;
|
||||
unsigned int i;
|
||||
int err;
|
||||
@ -2399,23 +2405,23 @@ static int b43_request_firmware(struct b43_wldev *dev)
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
return;
|
||||
ctx->dev = dev;
|
||||
|
||||
ctx->req_type = B43_FWTYPE_PROPRIETARY;
|
||||
err = b43_try_request_fw(ctx);
|
||||
if (!err)
|
||||
goto out; /* Successfully loaded it. */
|
||||
err = ctx->fatal_failure;
|
||||
if (err)
|
||||
goto start_ieee80211; /* Successfully loaded it. */
|
||||
/* Was fw version known? */
|
||||
if (ctx->fatal_failure)
|
||||
goto out;
|
||||
|
||||
/* proprietary fw not found, try open source */
|
||||
ctx->req_type = B43_FWTYPE_OPENSOURCE;
|
||||
err = b43_try_request_fw(ctx);
|
||||
if (!err)
|
||||
goto out; /* Successfully loaded it. */
|
||||
err = ctx->fatal_failure;
|
||||
if (err)
|
||||
goto start_ieee80211; /* Successfully loaded it. */
|
||||
if(ctx->fatal_failure)
|
||||
goto out;
|
||||
|
||||
/* Could not find a usable firmware. Print the errors. */
|
||||
@ -2425,11 +2431,20 @@ static int b43_request_firmware(struct b43_wldev *dev)
|
||||
b43err(dev->wl, errmsg);
|
||||
}
|
||||
b43_print_fw_helptext(dev->wl, 1);
|
||||
err = -ENOENT;
|
||||
goto out;
|
||||
|
||||
start_ieee80211:
|
||||
err = ieee80211_register_hw(wl->hw);
|
||||
if (err)
|
||||
goto err_one_core_detach;
|
||||
b43_leds_register(wl->current_dev);
|
||||
goto out;
|
||||
|
||||
err_one_core_detach:
|
||||
b43_one_core_detach(dev->dev);
|
||||
|
||||
out:
|
||||
kfree(ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int b43_upload_microcode(struct b43_wldev *dev)
|
||||
@ -3023,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev)
|
||||
macctl |= B43_MACCTL_INFRA;
|
||||
b43_write32(dev, B43_MMIO_MACCTL, macctl);
|
||||
|
||||
err = b43_request_firmware(dev);
|
||||
if (err)
|
||||
goto out;
|
||||
err = b43_upload_microcode(dev);
|
||||
if (err)
|
||||
goto out; /* firmware is released later */
|
||||
@ -4155,6 +4167,7 @@ redo:
|
||||
mutex_unlock(&wl->mutex);
|
||||
cancel_delayed_work_sync(&dev->periodic_work);
|
||||
cancel_work_sync(&wl->tx_work);
|
||||
cancel_work_sync(&wl->firmware_load);
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
if (!dev || b43_status(dev) < B43_STAT_STARTED) {
|
||||
@ -5314,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core)
|
||||
if (err)
|
||||
goto bcma_err_wireless_exit;
|
||||
|
||||
err = ieee80211_register_hw(wl->hw);
|
||||
if (err)
|
||||
goto bcma_err_one_core_detach;
|
||||
b43_leds_register(wl->current_dev);
|
||||
/* setup and start work to load firmware */
|
||||
INIT_WORK(&wl->firmware_load, b43_request_firmware);
|
||||
schedule_work(&wl->firmware_load);
|
||||
|
||||
bcma_out:
|
||||
return err;
|
||||
|
||||
bcma_err_one_core_detach:
|
||||
b43_one_core_detach(dev);
|
||||
bcma_err_wireless_exit:
|
||||
ieee80211_free_hw(wl->hw);
|
||||
return err;
|
||||
@ -5390,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
|
||||
if (err)
|
||||
goto err_wireless_exit;
|
||||
|
||||
if (first) {
|
||||
err = ieee80211_register_hw(wl->hw);
|
||||
if (err)
|
||||
goto err_one_core_detach;
|
||||
b43_leds_register(wl->current_dev);
|
||||
}
|
||||
/* setup and start work to load firmware */
|
||||
INIT_WORK(&wl->firmware_load, b43_request_firmware);
|
||||
schedule_work(&wl->firmware_load);
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
||||
err_one_core_detach:
|
||||
b43_one_core_detach(dev);
|
||||
err_wireless_exit:
|
||||
if (first)
|
||||
b43_wireless_exit(dev, wl);
|
||||
|
@ -581,6 +581,9 @@ struct b43legacy_wl {
|
||||
struct mutex mutex; /* locks wireless core state */
|
||||
spinlock_t leds_lock; /* lock for leds */
|
||||
|
||||
/* firmware loading work */
|
||||
struct work_struct firmware_load;
|
||||
|
||||
/* We can only have one operating interface (802.11 core)
|
||||
* at a time. General information about this interface follows.
|
||||
*/
|
||||
|
@ -1557,8 +1557,15 @@ err_format:
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
|
||||
static int b43legacy_one_core_attach(struct ssb_device *dev,
|
||||
struct b43legacy_wl *wl);
|
||||
static void b43legacy_one_core_detach(struct ssb_device *dev);
|
||||
|
||||
static void b43legacy_request_firmware(struct work_struct *work)
|
||||
{
|
||||
struct b43legacy_wl *wl = container_of(work,
|
||||
struct b43legacy_wl, firmware_load);
|
||||
struct b43legacy_wldev *dev = wl->current_dev;
|
||||
struct b43legacy_firmware *fw = &dev->fw;
|
||||
const u8 rev = dev->dev->id.revision;
|
||||
const char *filename;
|
||||
@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
|
||||
if (err)
|
||||
goto err_load;
|
||||
}
|
||||
err = ieee80211_register_hw(wl->hw);
|
||||
if (err)
|
||||
goto err_one_core_detach;
|
||||
return;
|
||||
|
||||
return 0;
|
||||
err_one_core_detach:
|
||||
b43legacy_one_core_detach(dev->dev);
|
||||
goto error;
|
||||
|
||||
err_load:
|
||||
b43legacy_print_fw_helptext(dev->wl);
|
||||
@ -1639,7 +1652,7 @@ err_no_initvals:
|
||||
|
||||
error:
|
||||
b43legacy_release_firmware(dev);
|
||||
return err;
|
||||
return;
|
||||
}
|
||||
|
||||
static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
|
||||
@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
|
||||
macctl |= B43legacy_MACCTL_INFRA;
|
||||
b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
|
||||
|
||||
err = b43legacy_request_firmware(dev);
|
||||
if (err)
|
||||
goto out;
|
||||
err = b43legacy_upload_microcode(dev);
|
||||
if (err)
|
||||
goto out; /* firmware is released later */
|
||||
@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev,
|
||||
if (err)
|
||||
goto err_wireless_exit;
|
||||
|
||||
if (first) {
|
||||
err = ieee80211_register_hw(wl->hw);
|
||||
if (err)
|
||||
goto err_one_core_detach;
|
||||
}
|
||||
/* setup and start work to load firmware */
|
||||
INIT_WORK(&wl->firmware_load, b43legacy_request_firmware);
|
||||
schedule_work(&wl->firmware_load);
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
||||
err_one_core_detach:
|
||||
b43legacy_one_core_detach(dev);
|
||||
err_wireless_exit:
|
||||
if (first)
|
||||
b43legacy_wireless_exit(dev, wl);
|
||||
@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev)
|
||||
/* We must cancel any work here before unregistering from ieee80211,
|
||||
* as the ieee80211 unreg will destroy the workqueue. */
|
||||
cancel_work_sync(&wldev->restart_work);
|
||||
cancel_work_sync(&wl->firmware_load);
|
||||
|
||||
B43legacy_WARN_ON(!wl);
|
||||
if (wl->current_dev == wldev)
|
||||
|
@ -2003,7 +2003,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
s32 err = 0;
|
||||
u16 channel;
|
||||
u32 freq;
|
||||
u64 notify_timestamp;
|
||||
u16 notify_capability;
|
||||
u16 notify_interval;
|
||||
u8 *notify_ie;
|
||||
@ -2026,7 +2025,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
freq = ieee80211_channel_to_frequency(channel, band->band);
|
||||
notify_channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
||||
notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
|
||||
notify_capability = le16_to_cpu(bi->capability);
|
||||
notify_interval = le16_to_cpu(bi->beacon_period);
|
||||
notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
|
||||
@ -2040,10 +2038,9 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
WL_CONN("Capability: %X\n", notify_capability);
|
||||
WL_CONN("Beacon interval: %d\n", notify_interval);
|
||||
WL_CONN("Signal: %d\n", notify_signal);
|
||||
WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
|
||||
|
||||
bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
|
||||
notify_timestamp, notify_capability, notify_interval, notify_ie,
|
||||
0, notify_capability, notify_interval, notify_ie,
|
||||
notify_ielen, notify_signal, GFP_KERNEL);
|
||||
|
||||
if (!bss)
|
||||
@ -2098,7 +2095,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
s32 err = 0;
|
||||
u16 channel;
|
||||
u32 freq;
|
||||
u64 notify_timestamp;
|
||||
u16 notify_capability;
|
||||
u16 notify_interval;
|
||||
u8 *notify_ie;
|
||||
@ -2134,7 +2130,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
freq = ieee80211_channel_to_frequency(channel, band->band);
|
||||
notify_channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
||||
notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
|
||||
notify_capability = le16_to_cpu(bi->capability);
|
||||
notify_interval = le16_to_cpu(bi->beacon_period);
|
||||
notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
|
||||
@ -2145,10 +2140,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
WL_CONN("capability: %X\n", notify_capability);
|
||||
WL_CONN("beacon interval: %d\n", notify_interval);
|
||||
WL_CONN("signal: %d\n", notify_signal);
|
||||
WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
|
||||
|
||||
bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
|
||||
notify_timestamp, notify_capability, notify_interval,
|
||||
0, notify_capability, notify_interval,
|
||||
notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
|
||||
|
||||
if (!bss) {
|
||||
|
@ -1997,18 +1997,6 @@ struct ipw_cmd_log {
|
||||
#define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */
|
||||
#define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */
|
||||
|
||||
/*
|
||||
* The definitions below were lifted off the ipw2100 driver, which only
|
||||
* supports 'b' mode, so I'm sure these are not exactly correct.
|
||||
*
|
||||
* Somebody fix these!!
|
||||
*/
|
||||
#define REG_MIN_CHANNEL 0
|
||||
#define REG_MAX_CHANNEL 14
|
||||
|
||||
#define REG_CHANNEL_MASK 0x00003FFF
|
||||
#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
|
||||
|
||||
#define IPW_MAX_CONFIG_RETRIES 10
|
||||
|
||||
#endif /* __ipw2200_h__ */
|
||||
|
@ -5355,7 +5355,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
if (changes & BSS_CHANGED_ASSOC) {
|
||||
D_MAC80211("ASSOC %d\n", bss_conf->assoc);
|
||||
if (bss_conf->assoc) {
|
||||
il->timestamp = bss_conf->timestamp;
|
||||
il->timestamp = bss_conf->last_tsf;
|
||||
|
||||
if (!il_is_rfkill(il))
|
||||
il->ops->post_associate(il);
|
||||
|
@ -1189,6 +1189,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
|
||||
|
||||
memcpy(&rxon, &ctx->active, sizeof(rxon));
|
||||
|
||||
priv->ucode_loaded = false;
|
||||
iwl_trans_stop_device(trans(priv));
|
||||
|
||||
priv->wowlan = true;
|
||||
|
@ -671,7 +671,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
|
||||
wiphy_rfkill_set_hw_state(priv->hw->wiphy,
|
||||
test_bit(STATUS_RF_KILL_HW, &priv->status));
|
||||
else
|
||||
wake_up(&priv->shrd->wait_command_queue);
|
||||
wake_up(&trans(priv)->wait_command_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -822,7 +822,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
|
||||
|
||||
if (changes & BSS_CHANGED_ASSOC) {
|
||||
if (bss_conf->assoc) {
|
||||
priv->timestamp = bss_conf->timestamp;
|
||||
priv->timestamp = bss_conf->last_tsf;
|
||||
ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
|
||||
} else {
|
||||
/*
|
||||
|
@ -816,6 +816,7 @@ void iwl_down(struct iwl_priv *priv)
|
||||
if (priv->mac80211_registered)
|
||||
ieee80211_stop_queues(priv->hw);
|
||||
|
||||
priv->ucode_loaded = false;
|
||||
iwl_trans_stop_device(trans(priv));
|
||||
|
||||
/* Clear out all status bits but a few that are stable across reset */
|
||||
@ -962,8 +963,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
{
|
||||
priv->workqueue = create_singlethread_workqueue(DRV_NAME);
|
||||
|
||||
init_waitqueue_head(&priv->shrd->wait_command_queue);
|
||||
|
||||
INIT_WORK(&priv->restart, iwl_bg_restart);
|
||||
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
|
||||
INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
|
||||
@ -1186,6 +1185,14 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
u16 num_mac;
|
||||
u32 ucode_flags;
|
||||
struct iwl_trans_config trans_cfg;
|
||||
static const u8 no_reclaim_cmds[] = {
|
||||
REPLY_RX_PHY_CMD,
|
||||
REPLY_RX,
|
||||
REPLY_RX_MPDU_CMD,
|
||||
REPLY_COMPRESSED_BA,
|
||||
STATISTICS_NOTIFICATION,
|
||||
REPLY_TX,
|
||||
};
|
||||
|
||||
/************************
|
||||
* 1. Allocating HW data
|
||||
@ -1211,6 +1218,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
* to know about.
|
||||
*/
|
||||
trans_cfg.op_mode = op_mode;
|
||||
trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
|
||||
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
|
||||
|
||||
ucode_flags = fw->ucode_capa.flags;
|
||||
|
||||
@ -1398,6 +1407,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
|
||||
iwl_tt_exit(priv);
|
||||
|
||||
/*This will stop the queues, move the device to low power state */
|
||||
priv->ucode_loaded = false;
|
||||
iwl_trans_stop_device(trans(priv));
|
||||
|
||||
iwl_eeprom_free(priv->shrd);
|
||||
|
@ -838,6 +838,9 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
|
||||
iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
|
||||
#endif
|
||||
|
||||
/* uCode is no longer loaded. */
|
||||
priv->ucode_loaded = false;
|
||||
|
||||
/* Set the FW error flag -- cleared on iwl_down */
|
||||
set_bit(STATUS_FW_ERROR, &priv->shrd->status);
|
||||
|
||||
@ -850,7 +853,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
|
||||
* commands by clearing the ready bit */
|
||||
clear_bit(STATUS_READY, &priv->status);
|
||||
|
||||
wake_up(&priv->shrd->wait_command_queue);
|
||||
wake_up(&trans(priv)->wait_command_queue);
|
||||
|
||||
if (!ondemand) {
|
||||
/*
|
||||
|
@ -230,15 +230,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
|
||||
int pos = 0;
|
||||
int sram;
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
const struct fw_img *img;
|
||||
size_t bufsz;
|
||||
|
||||
/* default is to dump the entire data segment */
|
||||
if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
|
||||
priv->dbgfs_sram_offset = 0x800000;
|
||||
if (priv->shrd->ucode_type == IWL_UCODE_INIT)
|
||||
priv->dbgfs_sram_len = priv->fw->ucode_init.data.len;
|
||||
else
|
||||
priv->dbgfs_sram_len = priv->fw->ucode_rt.data.len;
|
||||
if (!priv->ucode_loaded) {
|
||||
IWL_ERR(priv, "No uCode has been loadded.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
img = &priv->fw->img[priv->shrd->ucode_type];
|
||||
priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
|
||||
}
|
||||
len = priv->dbgfs_sram_len;
|
||||
|
||||
@ -335,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN];
|
||||
|
||||
if (!priv->wowlan_sram)
|
||||
return -ENODATA;
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos,
|
||||
priv->wowlan_sram,
|
||||
priv->fw->ucode_wowlan.data.len);
|
||||
img->sec[IWL_UCODE_SECTION_DATA].len);
|
||||
}
|
||||
static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
|
@ -769,6 +769,8 @@ struct iwl_priv {
|
||||
/* firmware reload counter and timestamp */
|
||||
unsigned long reload_jiffies;
|
||||
int reload_count;
|
||||
bool ucode_loaded;
|
||||
bool init_ucode_run; /* Don't run init uCode again */
|
||||
|
||||
/* we allocate array of iwl_channel_info for NIC's valid channels.
|
||||
* Access via channel # using indirect index array */
|
||||
|
@ -69,6 +69,7 @@
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-shared.h"
|
||||
#include "iwl-op-mode.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
/* private includes */
|
||||
#include "iwl-fw-file.h"
|
||||
@ -96,6 +97,16 @@ struct iwl_drv {
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct fw_sec: Just for the image parsing proccess.
|
||||
* For the fw storage we are using struct fw_desc.
|
||||
*/
|
||||
struct fw_sec {
|
||||
const void *data; /* the sec data */
|
||||
size_t size; /* section size */
|
||||
u32 offset; /* offset of writing in the device */
|
||||
};
|
||||
|
||||
static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
|
||||
{
|
||||
if (desc->v_addr)
|
||||
@ -107,32 +118,34 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
|
||||
|
||||
static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
|
||||
{
|
||||
iwl_free_fw_desc(drv, &img->code);
|
||||
iwl_free_fw_desc(drv, &img->data);
|
||||
int i;
|
||||
for (i = 0; i < IWL_UCODE_SECTION_MAX; i++)
|
||||
iwl_free_fw_desc(drv, &img->sec[i]);
|
||||
}
|
||||
|
||||
static void iwl_dealloc_ucode(struct iwl_drv *drv)
|
||||
{
|
||||
iwl_free_fw_img(drv, &drv->fw.ucode_rt);
|
||||
iwl_free_fw_img(drv, &drv->fw.ucode_init);
|
||||
iwl_free_fw_img(drv, &drv->fw.ucode_wowlan);
|
||||
int i;
|
||||
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
|
||||
iwl_free_fw_img(drv, drv->fw.img + i);
|
||||
}
|
||||
|
||||
static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
|
||||
const void *data, size_t len)
|
||||
struct fw_sec *sec)
|
||||
{
|
||||
if (!len) {
|
||||
if (!sec || !sec->size) {
|
||||
desc->v_addr = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc->v_addr = dma_alloc_coherent(trans(drv)->dev, len,
|
||||
desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size,
|
||||
&desc->p_addr, GFP_KERNEL);
|
||||
if (!desc->v_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
desc->len = len;
|
||||
memcpy(desc->v_addr, data, len);
|
||||
desc->len = sec->size;
|
||||
desc->offset = sec->offset;
|
||||
memcpy(desc->v_addr, sec->data, sec->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -177,18 +190,123 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
|
||||
GFP_KERNEL, drv, iwl_ucode_callback);
|
||||
}
|
||||
|
||||
struct iwlagn_firmware_pieces {
|
||||
const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
|
||||
size_t inst_size, data_size, init_size, init_data_size,
|
||||
wowlan_inst_size, wowlan_data_size;
|
||||
struct fw_img_parsing {
|
||||
struct fw_sec sec[IWL_UCODE_SECTION_MAX];
|
||||
int sec_counter;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct fw_sec_parsing: to extract fw section and it's offset from tlv
|
||||
*/
|
||||
struct fw_sec_parsing {
|
||||
__le32 offset;
|
||||
const u8 data[];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_tlv_calib_data - parse the default calib data from TLV
|
||||
*
|
||||
* @ucode_type: the uCode to which the following default calib relates.
|
||||
* @calib: default calibrations.
|
||||
*/
|
||||
struct iwl_tlv_calib_data {
|
||||
__le32 ucode_type;
|
||||
__le64 calib;
|
||||
} __packed;
|
||||
|
||||
struct iwl_firmware_pieces {
|
||||
struct fw_img_parsing img[IWL_UCODE_TYPE_MAX];
|
||||
|
||||
u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
|
||||
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* These functions are just to extract uCode section data from the pieces
|
||||
* structure.
|
||||
*/
|
||||
static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type,
|
||||
int sec)
|
||||
{
|
||||
return &pieces->img[type].sec[sec];
|
||||
}
|
||||
|
||||
static void set_sec_data(struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type,
|
||||
int sec,
|
||||
const void *data)
|
||||
{
|
||||
pieces->img[type].sec[sec].data = data;
|
||||
}
|
||||
|
||||
static void set_sec_size(struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type,
|
||||
int sec,
|
||||
size_t size)
|
||||
{
|
||||
pieces->img[type].sec[sec].size = size;
|
||||
}
|
||||
|
||||
static size_t get_sec_size(struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type,
|
||||
int sec)
|
||||
{
|
||||
return pieces->img[type].sec[sec].size;
|
||||
}
|
||||
|
||||
static void set_sec_offset(struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type,
|
||||
int sec,
|
||||
u32 offset)
|
||||
{
|
||||
pieces->img[type].sec[sec].offset = offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets uCode section from tlv.
|
||||
*/
|
||||
static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces,
|
||||
const void *data, enum iwl_ucode_type type,
|
||||
int size)
|
||||
{
|
||||
struct fw_img_parsing *img;
|
||||
struct fw_sec *sec;
|
||||
struct fw_sec_parsing *sec_parse;
|
||||
|
||||
if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX))
|
||||
return -1;
|
||||
|
||||
sec_parse = (struct fw_sec_parsing *)data;
|
||||
|
||||
img = &pieces->img[type];
|
||||
sec = &img->sec[img->sec_counter];
|
||||
|
||||
sec->offset = le32_to_cpu(sec_parse->offset);
|
||||
sec->data = sec_parse->data;
|
||||
|
||||
++img->sec_counter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
|
||||
{
|
||||
struct iwl_tlv_calib_data *def_calib =
|
||||
(struct iwl_tlv_calib_data *)data;
|
||||
u32 ucode_type = le32_to_cpu(def_calib->ucode_type);
|
||||
if (ucode_type >= IWL_UCODE_TYPE_MAX) {
|
||||
IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n",
|
||||
ucode_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
const struct firmware *ucode_raw,
|
||||
struct iwlagn_firmware_pieces *pieces)
|
||||
const struct firmware *ucode_raw,
|
||||
struct iwl_firmware_pieces *pieces)
|
||||
{
|
||||
struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
|
||||
u32 api_ver, hdr_size, build;
|
||||
@ -206,11 +324,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
return -EINVAL;
|
||||
}
|
||||
build = le32_to_cpu(ucode->u.v2.build);
|
||||
pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
|
||||
pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
|
||||
pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
|
||||
pieces->init_data_size =
|
||||
le32_to_cpu(ucode->u.v2.init_data_size);
|
||||
set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST,
|
||||
le32_to_cpu(ucode->u.v2.inst_size));
|
||||
set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA,
|
||||
le32_to_cpu(ucode->u.v2.data_size));
|
||||
set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST,
|
||||
le32_to_cpu(ucode->u.v2.init_size));
|
||||
set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA,
|
||||
le32_to_cpu(ucode->u.v2.init_data_size));
|
||||
src = ucode->u.v2.data;
|
||||
break;
|
||||
case 0:
|
||||
@ -222,11 +343,14 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
return -EINVAL;
|
||||
}
|
||||
build = 0;
|
||||
pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
|
||||
pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
|
||||
pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
|
||||
pieces->init_data_size =
|
||||
le32_to_cpu(ucode->u.v1.init_data_size);
|
||||
set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST,
|
||||
le32_to_cpu(ucode->u.v1.inst_size));
|
||||
set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA,
|
||||
le32_to_cpu(ucode->u.v1.data_size));
|
||||
set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST,
|
||||
le32_to_cpu(ucode->u.v1.init_size));
|
||||
set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA,
|
||||
le32_to_cpu(ucode->u.v1.init_data_size));
|
||||
src = ucode->u.v1.data;
|
||||
break;
|
||||
}
|
||||
@ -248,9 +372,12 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
buildstr);
|
||||
|
||||
/* Verify size of file vs. image size info in file's header */
|
||||
if (ucode_raw->size != hdr_size + pieces->inst_size +
|
||||
pieces->data_size + pieces->init_size +
|
||||
pieces->init_data_size) {
|
||||
|
||||
if (ucode_raw->size != hdr_size +
|
||||
get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) +
|
||||
get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) +
|
||||
get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) +
|
||||
get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) {
|
||||
|
||||
IWL_ERR(drv,
|
||||
"uCode file size %d does not match expected size\n",
|
||||
@ -258,21 +385,29 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pieces->inst = src;
|
||||
src += pieces->inst_size;
|
||||
pieces->data = src;
|
||||
src += pieces->data_size;
|
||||
pieces->init = src;
|
||||
src += pieces->init_size;
|
||||
pieces->init_data = src;
|
||||
src += pieces->init_data_size;
|
||||
|
||||
set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, src);
|
||||
src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST);
|
||||
set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, src);
|
||||
src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA);
|
||||
set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA,
|
||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||
set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, src);
|
||||
src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST);
|
||||
set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, src);
|
||||
src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA);
|
||||
set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA,
|
||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
const struct firmware *ucode_raw,
|
||||
struct iwlagn_firmware_pieces *pieces,
|
||||
struct iwl_firmware_pieces *pieces,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
{
|
||||
struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
|
||||
@ -368,20 +503,40 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
|
||||
switch (tlv_type) {
|
||||
case IWL_UCODE_TLV_INST:
|
||||
pieces->inst = tlv_data;
|
||||
pieces->inst_size = tlv_len;
|
||||
set_sec_data(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_INST, tlv_data);
|
||||
set_sec_size(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_INST, tlv_len);
|
||||
set_sec_offset(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_INST,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
break;
|
||||
case IWL_UCODE_TLV_DATA:
|
||||
pieces->data = tlv_data;
|
||||
pieces->data_size = tlv_len;
|
||||
set_sec_data(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA, tlv_data);
|
||||
set_sec_size(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA, tlv_len);
|
||||
set_sec_offset(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA,
|
||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT:
|
||||
pieces->init = tlv_data;
|
||||
pieces->init_size = tlv_len;
|
||||
set_sec_data(pieces, IWL_UCODE_INIT,
|
||||
IWL_UCODE_SECTION_INST, tlv_data);
|
||||
set_sec_size(pieces, IWL_UCODE_INIT,
|
||||
IWL_UCODE_SECTION_INST, tlv_len);
|
||||
set_sec_offset(pieces, IWL_UCODE_INIT,
|
||||
IWL_UCODE_SECTION_INST,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_DATA:
|
||||
pieces->init_data = tlv_data;
|
||||
pieces->init_data_size = tlv_len;
|
||||
set_sec_data(pieces, IWL_UCODE_INIT,
|
||||
IWL_UCODE_SECTION_DATA, tlv_data);
|
||||
set_sec_size(pieces, IWL_UCODE_INIT,
|
||||
IWL_UCODE_SECTION_DATA, tlv_len);
|
||||
set_sec_offset(pieces, IWL_UCODE_INIT,
|
||||
IWL_UCODE_SECTION_DATA,
|
||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||
break;
|
||||
case IWL_UCODE_TLV_BOOT:
|
||||
IWL_ERR(drv, "Found unexpected BOOT ucode\n");
|
||||
@ -455,12 +610,22 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
drv->fw.enhance_sensitivity_table = true;
|
||||
break;
|
||||
case IWL_UCODE_TLV_WOWLAN_INST:
|
||||
pieces->wowlan_inst = tlv_data;
|
||||
pieces->wowlan_inst_size = tlv_len;
|
||||
set_sec_data(pieces, IWL_UCODE_WOWLAN,
|
||||
IWL_UCODE_SECTION_INST, tlv_data);
|
||||
set_sec_size(pieces, IWL_UCODE_WOWLAN,
|
||||
IWL_UCODE_SECTION_INST, tlv_len);
|
||||
set_sec_offset(pieces, IWL_UCODE_WOWLAN,
|
||||
IWL_UCODE_SECTION_INST,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
break;
|
||||
case IWL_UCODE_TLV_WOWLAN_DATA:
|
||||
pieces->wowlan_data = tlv_data;
|
||||
pieces->wowlan_data_size = tlv_len;
|
||||
set_sec_data(pieces, IWL_UCODE_WOWLAN,
|
||||
IWL_UCODE_SECTION_DATA, tlv_data);
|
||||
set_sec_size(pieces, IWL_UCODE_WOWLAN,
|
||||
IWL_UCODE_SECTION_DATA, tlv_len);
|
||||
set_sec_offset(pieces, IWL_UCODE_WOWLAN,
|
||||
IWL_UCODE_SECTION_DATA,
|
||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||
break;
|
||||
case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
|
||||
if (tlv_len != sizeof(u32))
|
||||
@ -468,6 +633,32 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
capa->standard_phy_calibration_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_SEC_RT:
|
||||
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
|
||||
tlv_len);
|
||||
drv->fw.mvm_fw = true;
|
||||
break;
|
||||
case IWL_UCODE_TLV_SEC_INIT:
|
||||
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT,
|
||||
tlv_len);
|
||||
drv->fw.mvm_fw = true;
|
||||
break;
|
||||
case IWL_UCODE_TLV_SEC_WOWLAN:
|
||||
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN,
|
||||
tlv_len);
|
||||
drv->fw.mvm_fw = true;
|
||||
break;
|
||||
case IWL_UCODE_TLV_DEF_CALIB:
|
||||
if (tlv_len != sizeof(struct iwl_tlv_calib_data))
|
||||
goto invalid_tlv_len;
|
||||
if (iwl_set_default_calib(drv, tlv_data))
|
||||
goto tlv_error;
|
||||
break;
|
||||
case IWL_UCODE_TLV_PHY_SKU:
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
default:
|
||||
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
|
||||
break;
|
||||
@ -484,11 +675,77 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
|
||||
invalid_tlv_len:
|
||||
IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
|
||||
tlv_error:
|
||||
iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int alloc_pci_desc(struct iwl_drv *drv,
|
||||
struct iwl_firmware_pieces *pieces,
|
||||
enum iwl_ucode_type type)
|
||||
{
|
||||
int i;
|
||||
for (i = 0;
|
||||
i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i);
|
||||
i++)
|
||||
if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]),
|
||||
get_sec(pieces, type, i)))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_sec_sizes(struct iwl_drv *drv,
|
||||
struct iwl_firmware_pieces *pieces,
|
||||
const struct iwl_cfg *cfg)
|
||||
{
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n",
|
||||
get_sec_size(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_INST));
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n",
|
||||
get_sec_size(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA));
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n",
|
||||
get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST));
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n",
|
||||
get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA));
|
||||
|
||||
/* Verify that uCode images will fit in card's SRAM. */
|
||||
if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) >
|
||||
cfg->max_inst_size) {
|
||||
IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
|
||||
get_sec_size(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_INST));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) >
|
||||
cfg->max_data_size) {
|
||||
IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
|
||||
get_sec_size(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) >
|
||||
cfg->max_inst_size) {
|
||||
IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n",
|
||||
get_sec_size(pieces, IWL_UCODE_INIT,
|
||||
IWL_UCODE_SECTION_INST));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) >
|
||||
cfg->max_data_size) {
|
||||
IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n",
|
||||
get_sec_size(pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* iwl_ucode_callback - callback when firmware was loaded
|
||||
*
|
||||
@ -502,11 +759,12 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
struct iwl_fw *fw = &drv->fw;
|
||||
struct iwl_ucode_header *ucode;
|
||||
int err;
|
||||
struct iwlagn_firmware_pieces pieces;
|
||||
struct iwl_firmware_pieces pieces;
|
||||
const unsigned int api_max = cfg->ucode_api_max;
|
||||
unsigned int api_ok = cfg->ucode_api_ok;
|
||||
const unsigned int api_min = cfg->ucode_api_min;
|
||||
u32 api_ver;
|
||||
int i;
|
||||
|
||||
fw->ucode_capa.max_probe_length = 200;
|
||||
fw->ucode_capa.standard_phy_calibration_size =
|
||||
@ -588,76 +846,48 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n",
|
||||
drv->fw.ucode_ver);
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n",
|
||||
pieces.inst_size);
|
||||
get_sec_size(&pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_INST));
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n",
|
||||
pieces.data_size);
|
||||
get_sec_size(&pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA));
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n",
|
||||
pieces.init_size);
|
||||
get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST));
|
||||
IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n",
|
||||
pieces.init_data_size);
|
||||
get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA));
|
||||
|
||||
/* Verify that uCode images will fit in card's SRAM */
|
||||
if (pieces.inst_size > cfg->max_inst_size) {
|
||||
if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) >
|
||||
cfg->max_inst_size) {
|
||||
IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
|
||||
pieces.inst_size);
|
||||
get_sec_size(&pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_INST));
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
if (pieces.data_size > cfg->max_data_size) {
|
||||
if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) >
|
||||
cfg->max_data_size) {
|
||||
IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
|
||||
pieces.data_size);
|
||||
get_sec_size(&pieces, IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_SECTION_DATA));
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
if (pieces.init_size > cfg->max_inst_size) {
|
||||
IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n",
|
||||
pieces.init_size);
|
||||
/*
|
||||
* In mvm uCode there is no difference between data and instructions
|
||||
* sections.
|
||||
*/
|
||||
if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg))
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
if (pieces.init_data_size > cfg->max_data_size) {
|
||||
IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n",
|
||||
pieces.init_data_size);
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
/* Allocate ucode buffers for card's bus-master loading ... */
|
||||
|
||||
/* Runtime instructions and 2 copies of data:
|
||||
* 1) unmodified from disk
|
||||
* 2) backup cache for save/restore during power-downs */
|
||||
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.code,
|
||||
pieces.inst, pieces.inst_size))
|
||||
goto err_pci_alloc;
|
||||
if (iwl_alloc_fw_desc(drv, &drv->fw.ucode_rt.data,
|
||||
pieces.data, pieces.data_size))
|
||||
goto err_pci_alloc;
|
||||
|
||||
/* Initialization instructions and data */
|
||||
if (pieces.init_size && pieces.init_data_size) {
|
||||
if (iwl_alloc_fw_desc(drv,
|
||||
&drv->fw.ucode_init.code,
|
||||
pieces.init, pieces.init_size))
|
||||
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
|
||||
if (alloc_pci_desc(drv, &pieces, i))
|
||||
goto err_pci_alloc;
|
||||
if (iwl_alloc_fw_desc(drv,
|
||||
&drv->fw.ucode_init.data,
|
||||
pieces.init_data, pieces.init_data_size))
|
||||
goto err_pci_alloc;
|
||||
}
|
||||
|
||||
/* WoWLAN instructions and data */
|
||||
if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
|
||||
if (iwl_alloc_fw_desc(drv,
|
||||
&drv->fw.ucode_wowlan.code,
|
||||
pieces.wowlan_inst,
|
||||
pieces.wowlan_inst_size))
|
||||
goto err_pci_alloc;
|
||||
if (iwl_alloc_fw_desc(drv,
|
||||
&drv->fw.ucode_wowlan.data,
|
||||
pieces.wowlan_data,
|
||||
pieces.wowlan_data_size))
|
||||
goto err_pci_alloc;
|
||||
}
|
||||
|
||||
/* Now that we can no longer fail, copy information */
|
||||
|
||||
|
@ -124,6 +124,11 @@ enum iwl_ucode_tlv_type {
|
||||
IWL_UCODE_TLV_WOWLAN_INST = 16,
|
||||
IWL_UCODE_TLV_WOWLAN_DATA = 17,
|
||||
IWL_UCODE_TLV_FLAGS = 18,
|
||||
IWL_UCODE_TLV_SEC_RT = 19,
|
||||
IWL_UCODE_TLV_SEC_INIT = 20,
|
||||
IWL_UCODE_TLV_SEC_WOWLAN = 21,
|
||||
IWL_UCODE_TLV_DEF_CALIB = 22,
|
||||
IWL_UCODE_TLV_PHY_SKU = 23,
|
||||
};
|
||||
|
||||
struct iwl_ucode_tlv {
|
||||
|
@ -85,22 +85,52 @@ enum iwl_ucode_tlv_flag {
|
||||
#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
|
||||
#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253
|
||||
|
||||
/**
|
||||
* enum iwl_ucode_type
|
||||
*
|
||||
* The type of ucode.
|
||||
*
|
||||
* @IWL_UCODE_REGULAR: Normal runtime ucode
|
||||
* @IWL_UCODE_INIT: Initial ucode
|
||||
* @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
|
||||
*/
|
||||
enum iwl_ucode_type {
|
||||
IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_INIT,
|
||||
IWL_UCODE_WOWLAN,
|
||||
IWL_UCODE_TYPE_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* enumeration of ucode section.
|
||||
* This enumeration is used for legacy tlv style (before 16.0 uCode).
|
||||
*/
|
||||
enum iwl_ucode_sec {
|
||||
IWL_UCODE_SECTION_INST,
|
||||
IWL_UCODE_SECTION_DATA,
|
||||
};
|
||||
/*
|
||||
* For 16.0 uCode and above, there is no differentiation between sections,
|
||||
* just an offset to the HW address.
|
||||
*/
|
||||
#define IWL_UCODE_SECTION_MAX 4
|
||||
|
||||
struct iwl_ucode_capabilities {
|
||||
u32 max_probe_length;
|
||||
u32 standard_phy_calibration_size;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/* one for each uCode image (inst/data, boot/init/runtime) */
|
||||
/* one for each uCode image (inst/data, init/runtime/wowlan) */
|
||||
struct fw_desc {
|
||||
dma_addr_t p_addr; /* hardware address */
|
||||
void *v_addr; /* software address */
|
||||
u32 len; /* size in bytes */
|
||||
u32 offset; /* offset in the device */
|
||||
};
|
||||
|
||||
struct fw_img {
|
||||
struct fw_desc code; /* firmware code image */
|
||||
struct fw_desc data; /* firmware data image */
|
||||
struct fw_desc sec[IWL_UCODE_SECTION_MAX];
|
||||
};
|
||||
|
||||
/* uCode version contains 4 values: Major/Minor/API/Serial */
|
||||
@ -114,9 +144,7 @@ struct fw_img {
|
||||
*
|
||||
* @ucode_ver: ucode version from the ucode file
|
||||
* @fw_version: firmware version string
|
||||
* @ucode_rt: run time ucode image
|
||||
* @ucode_init: init ucode image
|
||||
* @ucode_wowlan: wake on wireless ucode image (optional)
|
||||
* @img: ucode image like ucode_rt, ucode_init, ucode_wowlan.
|
||||
* @ucode_capa: capabilities parsed from the ucode file.
|
||||
* @enhance_sensitivity_table: device can do enhanced sensitivity.
|
||||
* @init_evtlog_ptr: event log offset for init ucode.
|
||||
@ -132,15 +160,18 @@ struct iwl_fw {
|
||||
char fw_version[ETHTOOL_BUSINFO_LEN];
|
||||
|
||||
/* ucode images */
|
||||
struct fw_img ucode_rt;
|
||||
struct fw_img ucode_init;
|
||||
struct fw_img ucode_wowlan;
|
||||
struct fw_img img[IWL_UCODE_TYPE_MAX];
|
||||
|
||||
struct iwl_ucode_capabilities ucode_capa;
|
||||
bool enhance_sensitivity_table;
|
||||
|
||||
u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
|
||||
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
|
||||
|
||||
u64 default_calib[IWL_UCODE_TYPE_MAX];
|
||||
u32 phy_config;
|
||||
|
||||
bool mvm_fw;
|
||||
};
|
||||
|
||||
#endif /* __iwl_fw_h__ */
|
||||
|
@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
WIPHY_FLAG_DISABLE_BEACON_HINTS |
|
||||
WIPHY_FLAG_IBSS_RSN;
|
||||
|
||||
if (priv->fw->ucode_wowlan.code.len &&
|
||||
if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
|
||||
trans(priv)->ops->wowlan_suspend &&
|
||||
device_can_wakeup(trans(priv)->dev)) {
|
||||
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
|
||||
@ -437,6 +437,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
|
||||
unsigned long flags;
|
||||
u32 base, status = 0xffffffff;
|
||||
int ret = -EIO;
|
||||
const struct fw_img *img;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
mutex_lock(&priv->mutex);
|
||||
@ -457,16 +458,18 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
if (ret == 0) {
|
||||
if (!priv->wowlan_sram)
|
||||
img = &(priv->fw->img[IWL_UCODE_WOWLAN]);
|
||||
if (!priv->wowlan_sram) {
|
||||
priv->wowlan_sram =
|
||||
kzalloc(priv->fw->ucode_wowlan.data.len,
|
||||
kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
if (priv->wowlan_sram)
|
||||
_iwl_read_targ_mem_words(
|
||||
trans(priv), 0x800000,
|
||||
priv->wowlan_sram,
|
||||
priv->fw->ucode_wowlan.data.len / 4);
|
||||
trans(priv), 0x800000,
|
||||
priv->wowlan_sram,
|
||||
img->sec[IWL_UCODE_SECTION_DATA].len / 4);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -192,23 +192,6 @@ struct iwl_hw_params {
|
||||
const struct iwl_sensitivity_ranges *sens;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_ucode_type
|
||||
*
|
||||
* The type of ucode currently loaded on the hardware.
|
||||
*
|
||||
* @IWL_UCODE_NONE: No ucode loaded
|
||||
* @IWL_UCODE_REGULAR: Normal runtime ucode
|
||||
* @IWL_UCODE_INIT: Initial ucode
|
||||
* @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
|
||||
*/
|
||||
enum iwl_ucode_type {
|
||||
IWL_UCODE_NONE,
|
||||
IWL_UCODE_REGULAR,
|
||||
IWL_UCODE_INIT,
|
||||
IWL_UCODE_WOWLAN,
|
||||
};
|
||||
|
||||
/*
|
||||
* LED mode
|
||||
* IWL_LED_DEFAULT: use device default
|
||||
@ -376,7 +359,6 @@ struct iwl_cfg {
|
||||
* @nic: pointer to the nic data
|
||||
* @hw_params: see struct iwl_hw_params
|
||||
* @lock: protect general shared data
|
||||
* @wait_command_queue: the wait_queue for SYNC host commands
|
||||
* @eeprom: pointer to the eeprom/OTP image
|
||||
* @ucode_type: indicator of loaded ucode image
|
||||
* @device_pointers: pointers to ucode event tables
|
||||
@ -391,8 +373,6 @@ struct iwl_shared {
|
||||
struct iwl_hw_params hw_params;
|
||||
const struct iwl_fw *fw;
|
||||
|
||||
wait_queue_head_t wait_command_queue;
|
||||
|
||||
/* eeprom -- this is in the card's little endian byte order */
|
||||
u8 *eeprom;
|
||||
|
||||
|
@ -466,6 +466,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
unsigned char *rsp_data_ptr = NULL;
|
||||
int status = 0, rsp_data_len = 0;
|
||||
u32 devid, inst_size = 0, data_size = 0;
|
||||
const struct fw_img *img;
|
||||
|
||||
switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
|
||||
case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
|
||||
@ -494,6 +495,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
|
||||
case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
|
||||
iwl_testmode_cfg_init_calib(priv);
|
||||
priv->ucode_loaded = false;
|
||||
iwl_trans_stop_device(trans);
|
||||
break;
|
||||
|
||||
@ -512,6 +514,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
|
||||
case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
|
||||
iwl_scan_cancel_timeout(priv, 200);
|
||||
priv->ucode_loaded = false;
|
||||
iwl_trans_stop_device(trans);
|
||||
status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
|
||||
if (status) {
|
||||
@ -591,25 +594,13 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
IWL_ERR(priv, "Memory allocation fail\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
switch (priv->shrd->ucode_type) {
|
||||
case IWL_UCODE_REGULAR:
|
||||
inst_size = priv->fw->ucode_rt.code.len;
|
||||
data_size = priv->fw->ucode_rt.data.len;
|
||||
break;
|
||||
case IWL_UCODE_INIT:
|
||||
inst_size = priv->fw->ucode_init.code.len;
|
||||
data_size = priv->fw->ucode_init.data.len;
|
||||
break;
|
||||
case IWL_UCODE_WOWLAN:
|
||||
inst_size = priv->fw->ucode_wowlan.code.len;
|
||||
data_size = priv->fw->ucode_wowlan.data.len;
|
||||
break;
|
||||
case IWL_UCODE_NONE:
|
||||
if (!priv->ucode_loaded) {
|
||||
IWL_ERR(priv, "No uCode has not been loaded\n");
|
||||
break;
|
||||
default:
|
||||
IWL_ERR(priv, "Unsupported uCode type\n");
|
||||
break;
|
||||
return -EINVAL;
|
||||
} else {
|
||||
img = &priv->fw->img[priv->shrd->ucode_type];
|
||||
inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
|
||||
data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
|
||||
}
|
||||
NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
|
||||
NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
|
||||
|
@ -291,6 +291,8 @@ struct iwl_trans_pcie {
|
||||
wait_queue_head_t ucode_write_waitq;
|
||||
unsigned long status;
|
||||
u8 cmd_queue;
|
||||
u8 n_no_reclaim_cmds;
|
||||
u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
|
||||
};
|
||||
|
||||
#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
|
||||
|
@ -395,13 +395,17 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
|
||||
* there is no command buffer to reclaim.
|
||||
* Ucode should set SEQ_RX_FRAME bit if ucode-originated,
|
||||
* but apparently a few don't get set; catch them here. */
|
||||
reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
|
||||
(pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
|
||||
(pkt->hdr.cmd != REPLY_RX) &&
|
||||
(pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
|
||||
(pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
|
||||
(pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
|
||||
(pkt->hdr.cmd != REPLY_TX);
|
||||
reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME);
|
||||
if (reclaim) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) {
|
||||
if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) {
|
||||
reclaim = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sequence = le16_to_cpu(pkt->hdr.sequence);
|
||||
index = SEQ_TO_INDEX(sequence);
|
||||
@ -412,17 +416,6 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
|
||||
else
|
||||
cmd = NULL;
|
||||
|
||||
/* warn if this is cmd response / notification and the uCode
|
||||
* didn't set the SEQ_RX_FRAME for a frame that is
|
||||
* uCode-originated
|
||||
* If you saw this code after the second half of 2012, then
|
||||
* please remove it
|
||||
*/
|
||||
WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false &&
|
||||
(!(pkt->hdr.sequence & SEQ_RX_FRAME)),
|
||||
"reclaim is false, SEQ_RX_FRAME unset: %s\n",
|
||||
get_cmd_string(pkt->hdr.cmd));
|
||||
|
||||
err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
|
||||
|
||||
/*
|
||||
@ -691,7 +684,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
|
||||
*/
|
||||
clear_bit(STATUS_READY, &trans->shrd->status);
|
||||
clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
|
||||
wake_up(&trans->shrd->wait_command_queue);
|
||||
wake_up(&trans->wait_command_queue);
|
||||
IWL_ERR(trans, "RF is used by WiMAX\n");
|
||||
return;
|
||||
}
|
||||
|
@ -928,7 +928,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb,
|
||||
clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
|
||||
IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
|
||||
get_cmd_string(cmd->hdr.cmd));
|
||||
wake_up(&trans->shrd->wait_command_queue);
|
||||
wake_up(&trans->wait_command_queue);
|
||||
}
|
||||
|
||||
meta->flags = 0;
|
||||
@ -992,7 +992,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wait_event_timeout(trans->shrd->wait_command_queue,
|
||||
ret = wait_event_timeout(trans->wait_command_queue,
|
||||
!test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status),
|
||||
HOST_COMPLETE_TIMEOUT);
|
||||
if (!ret) {
|
||||
|
@ -951,12 +951,13 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
|
||||
/*
|
||||
* ucode
|
||||
*/
|
||||
static int iwl_load_section(struct iwl_trans *trans, const char *name,
|
||||
const struct fw_desc *image, u32 dst_addr)
|
||||
static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
|
||||
const struct fw_desc *section)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
dma_addr_t phy_addr = image->p_addr;
|
||||
u32 byte_cnt = image->len;
|
||||
dma_addr_t phy_addr = section->p_addr;
|
||||
u32 byte_cnt = section->len;
|
||||
u32 dst_addr = section->offset;
|
||||
int ret;
|
||||
|
||||
trans_pcie->ucode_write_complete = false;
|
||||
@ -989,12 +990,13 @@ static int iwl_load_section(struct iwl_trans *trans, const char *name,
|
||||
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
|
||||
FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
|
||||
|
||||
IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name);
|
||||
IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
|
||||
section_num);
|
||||
ret = wait_event_timeout(trans_pcie->ucode_write_waitq,
|
||||
trans_pcie->ucode_write_complete, 5 * HZ);
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Could not load the %s uCode section\n",
|
||||
name);
|
||||
IWL_ERR(trans, "Could not load the [%d] uCode section\n",
|
||||
section_num);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -1005,16 +1007,16 @@ static int iwl_load_given_ucode(struct iwl_trans *trans,
|
||||
const struct fw_img *image)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
ret = iwl_load_section(trans, "INST", &image->code,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) {
|
||||
if (!image->sec[i].p_addr)
|
||||
break;
|
||||
|
||||
ret = iwl_load_section(trans, "DATA", &image->data,
|
||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = iwl_load_section(trans, i, &image->sec[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Remove all resets to allow NIC to operate */
|
||||
iwl_write32(trans, CSR_RESET, 0);
|
||||
@ -1466,8 +1468,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n",
|
||||
le16_to_cpu(dev_cmd->hdr.sequence));
|
||||
IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
|
||||
iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
|
||||
iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
|
||||
|
||||
/* Set up entry for this TFD in Tx byte-count array */
|
||||
iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
|
||||
@ -1628,6 +1628,13 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
trans_pcie->cmd_queue = trans_cfg->cmd_queue;
|
||||
if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS))
|
||||
trans_pcie->n_no_reclaim_cmds = 0;
|
||||
else
|
||||
trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds;
|
||||
if (trans_pcie->n_no_reclaim_cmds)
|
||||
memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds,
|
||||
trans_pcie->n_no_reclaim_cmds * sizeof(u8));
|
||||
}
|
||||
|
||||
static void iwl_trans_pcie_free(struct iwl_trans *trans)
|
||||
@ -2322,6 +2329,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
|
||||
pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
|
||||
}
|
||||
|
||||
/* Initialize the wait queue for commands */
|
||||
init_waitqueue_head(&trans->wait_command_queue);
|
||||
|
||||
return trans;
|
||||
|
||||
out_pci_release_regions:
|
||||
|
@ -274,6 +274,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
|
||||
return p;
|
||||
}
|
||||
|
||||
#define MAX_NO_RECLAIM_CMDS 6
|
||||
|
||||
/**
|
||||
* struct iwl_trans_config - transport configuration
|
||||
*
|
||||
@ -281,10 +283,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
|
||||
* Must be set before any other call.
|
||||
* @cmd_queue: the index of the command queue.
|
||||
* Must be set before start_fw.
|
||||
* @no_reclaim_cmds: Some devices erroneously don't set the
|
||||
* SEQ_RX_FRAME bit on some notifications, this is the
|
||||
* list of such notifications to filter. Max length is
|
||||
* %MAX_NO_RECLAIM_CMDS.
|
||||
* @n_no_reclaim_cmds: # of commands in list
|
||||
*/
|
||||
struct iwl_trans_config {
|
||||
struct iwl_op_mode *op_mode;
|
||||
u8 cmd_queue;
|
||||
const u8 *no_reclaim_cmds;
|
||||
int n_no_reclaim_cmds;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -404,6 +413,7 @@ enum iwl_trans_state {
|
||||
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
|
||||
* @nvm_device_type: indicates OTP or eeprom
|
||||
* @pm_support: set to true in start_hw if link pm is supported
|
||||
* @wait_command_queue: the wait_queue for SYNC host commands
|
||||
*/
|
||||
struct iwl_trans {
|
||||
const struct iwl_trans_ops *ops;
|
||||
@ -420,6 +430,8 @@ struct iwl_trans {
|
||||
int nvm_device_type;
|
||||
bool pm_support;
|
||||
|
||||
wait_queue_head_t wait_command_queue;
|
||||
|
||||
/* pointer to trans specific struct */
|
||||
/*Ensure that this pointer will always be aligned to sizeof pointer */
|
||||
char trans_specific[0] __aligned(sizeof(void *));
|
||||
@ -488,8 +500,8 @@ static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans)
|
||||
static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
|
||||
struct iwl_host_cmd *cmd)
|
||||
{
|
||||
if (trans->state != IWL_TRANS_FW_ALIVE)
|
||||
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
|
||||
WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
|
||||
"%s bad state = %d", __func__, trans->state);
|
||||
|
||||
return trans->ops->send_cmd(trans, cmd);
|
||||
}
|
||||
@ -508,8 +520,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
|
||||
int tid, int txq_id, int ssn,
|
||||
struct sk_buff_head *skbs)
|
||||
{
|
||||
if (trans->state != IWL_TRANS_FW_ALIVE)
|
||||
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
|
||||
WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
|
||||
"%s bad state = %d", __func__, trans->state);
|
||||
|
||||
return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs);
|
||||
}
|
||||
@ -517,8 +529,8 @@ static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id,
|
||||
static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
|
||||
int sta_id, int tid)
|
||||
{
|
||||
if (trans->state != IWL_TRANS_FW_ALIVE)
|
||||
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
|
||||
WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
|
||||
"%s bad state = %d", __func__, trans->state);
|
||||
|
||||
return trans->ops->tx_agg_disable(trans, sta_id, tid);
|
||||
}
|
||||
@ -526,8 +538,8 @@ static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans,
|
||||
static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans,
|
||||
int sta_id, int tid)
|
||||
{
|
||||
if (trans->state != IWL_TRANS_FW_ALIVE)
|
||||
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
|
||||
WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
|
||||
"%s bad state = %d", __func__, trans->state);
|
||||
|
||||
return trans->ops->tx_agg_alloc(trans, sta_id, tid);
|
||||
}
|
||||
@ -540,8 +552,8 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
if (trans->state != IWL_TRANS_FW_ALIVE)
|
||||
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
|
||||
WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
|
||||
"%s bad state = %d", __func__, trans->state);
|
||||
|
||||
trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
|
||||
}
|
||||
@ -553,16 +565,16 @@ static inline void iwl_trans_free(struct iwl_trans *trans)
|
||||
|
||||
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->state != IWL_TRANS_FW_ALIVE)
|
||||
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
|
||||
WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
|
||||
"%s bad state = %d", __func__, trans->state);
|
||||
|
||||
return trans->ops->wait_tx_queue_empty(trans);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q)
|
||||
{
|
||||
if (trans->state != IWL_TRANS_FW_ALIVE)
|
||||
IWL_ERR(trans, "%s bad state = %d", __func__, trans->state);
|
||||
WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE,
|
||||
"%s bad state = %d", __func__, trans->state);
|
||||
|
||||
return trans->ops->check_stuck_queue(trans, q);
|
||||
}
|
||||
|
@ -80,17 +80,10 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
|
||||
static inline const struct fw_img *
|
||||
iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type)
|
||||
{
|
||||
switch (ucode_type) {
|
||||
case IWL_UCODE_INIT:
|
||||
return &priv->fw->ucode_init;
|
||||
case IWL_UCODE_WOWLAN:
|
||||
return &priv->fw->ucode_wowlan;
|
||||
case IWL_UCODE_REGULAR:
|
||||
return &priv->fw->ucode_rt;
|
||||
case IWL_UCODE_NONE:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
if (ucode_type >= IWL_UCODE_TYPE_MAX)
|
||||
return NULL;
|
||||
|
||||
return &priv->fw->img[ucode_type];
|
||||
}
|
||||
|
||||
/*
|
||||
@ -342,7 +335,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
|
||||
* using sample data 100 bytes apart. If these sample points are good,
|
||||
* it's a pretty good bet that everything between them is good, too.
|
||||
*/
|
||||
static int iwl_verify_inst_sparse(struct iwl_priv *priv,
|
||||
static int iwl_verify_sec_sparse(struct iwl_priv *priv,
|
||||
const struct fw_desc *fw_desc)
|
||||
{
|
||||
__le32 *image = (__le32 *)fw_desc->v_addr;
|
||||
@ -357,7 +350,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv,
|
||||
/* NOTE: Use the debugless read so we don't flood kernel log
|
||||
* if IWL_DL_IO is set */
|
||||
iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
|
||||
i + IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
i + fw_desc->offset);
|
||||
val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
|
||||
if (val != le32_to_cpu(*image))
|
||||
return -EIO;
|
||||
@ -366,7 +359,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_print_mismatch_inst(struct iwl_priv *priv,
|
||||
static void iwl_print_mismatch_sec(struct iwl_priv *priv,
|
||||
const struct fw_desc *fw_desc)
|
||||
{
|
||||
__le32 *image = (__le32 *)fw_desc->v_addr;
|
||||
@ -378,7 +371,7 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv,
|
||||
IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len);
|
||||
|
||||
iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
fw_desc->offset);
|
||||
|
||||
for (offs = 0;
|
||||
offs < len && errors < 20;
|
||||
@ -408,14 +401,14 @@ static int iwl_verify_ucode(struct iwl_priv *priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!iwl_verify_inst_sparse(priv, &img->code)) {
|
||||
if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) {
|
||||
IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
|
||||
|
||||
iwl_print_mismatch_inst(priv, &img->code);
|
||||
iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -465,6 +458,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
priv->shrd->ucode_type = ucode_type;
|
||||
fw = iwl_get_ucode_image(priv, ucode_type);
|
||||
|
||||
priv->ucode_loaded = false;
|
||||
|
||||
if (!fw)
|
||||
return -EINVAL;
|
||||
|
||||
@ -519,6 +514,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->ucode_loaded = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -530,10 +527,10 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
/* No init ucode required? Curious, but maybe ok */
|
||||
if (!priv->fw->ucode_init.code.len)
|
||||
if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len)
|
||||
return 0;
|
||||
|
||||
if (priv->shrd->ucode_type != IWL_UCODE_NONE)
|
||||
if (priv->init_ucode_run)
|
||||
return 0;
|
||||
|
||||
iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
|
||||
@ -555,6 +552,8 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
|
||||
*/
|
||||
ret = iwl_wait_notification(&priv->notif_wait, &calib_wait,
|
||||
UCODE_CALIB_TIMEOUT);
|
||||
if (!ret)
|
||||
priv->init_ucode_run = true;
|
||||
|
||||
goto out;
|
||||
|
||||
@ -563,5 +562,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv)
|
||||
out:
|
||||
/* Whatever happened, stop the device */
|
||||
iwl_trans_stop_device(trans(priv));
|
||||
priv->ucode_loaded = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1630,42 +1630,6 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* "Site survey", here just current channel and noise level
|
||||
*/
|
||||
|
||||
static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
|
||||
int idx, struct survey_info *survey)
|
||||
{
|
||||
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||
s8 signal, noise;
|
||||
int ret;
|
||||
|
||||
if (dev == priv->mesh_dev)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (idx != 0)
|
||||
ret = -ENOENT;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CFG80211);
|
||||
|
||||
survey->channel = ieee80211_get_channel(wiphy,
|
||||
ieee80211_channel_to_frequency(priv->channel,
|
||||
IEEE80211_BAND_2GHZ));
|
||||
|
||||
ret = lbs_get_rssi(priv, &signal, &noise);
|
||||
if (ret == 0) {
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = noise;
|
||||
}
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Change interface
|
||||
*/
|
||||
@ -2068,7 +2032,6 @@ static struct cfg80211_ops lbs_cfg80211_ops = {
|
||||
.del_key = lbs_cfg_del_key,
|
||||
.set_default_key = lbs_cfg_set_default_key,
|
||||
.get_station = lbs_cfg_get_station,
|
||||
.dump_survey = lbs_get_survey,
|
||||
.change_virtual_intf = lbs_change_intf,
|
||||
.join_ibss = lbs_join_ibss,
|
||||
.leave_ibss = lbs_leave_ibss,
|
||||
|
@ -639,7 +639,6 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
memset(&rx_status, 0, sizeof(rx_status));
|
||||
rx_status.mactime = le64_to_cpu(__mac80211_hwsim_get_tsf(data));
|
||||
rx_status.flag |= RX_FLAG_MACTIME_MPDU;
|
||||
rx_status.freq = data->channel->center_freq;
|
||||
rx_status.band = data->channel->band;
|
||||
@ -684,6 +683,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
||||
|
||||
if (mac80211_hwsim_addr_match(data2, hdr->addr1))
|
||||
ack = true;
|
||||
rx_status.mactime =
|
||||
le64_to_cpu(__mac80211_hwsim_get_tsf(data2));
|
||||
memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
|
||||
ieee80211_rx_irqsafe(data2->hw, nskb);
|
||||
}
|
||||
|
@ -44,16 +44,16 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
|
||||
|
||||
ht_cap->ht_cap.ampdu_params_info =
|
||||
(sband->ht_cap.ampdu_factor &
|
||||
IEEE80211_HT_AMPDU_PARM_FACTOR)|
|
||||
IEEE80211_HT_AMPDU_PARM_FACTOR) |
|
||||
((sband->ht_cap.ampdu_density <<
|
||||
IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) &
|
||||
IEEE80211_HT_AMPDU_PARM_DENSITY);
|
||||
|
||||
memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs,
|
||||
sizeof(sband->ht_cap.mcs));
|
||||
sizeof(sband->ht_cap.mcs));
|
||||
|
||||
if (priv->bss_mode == NL80211_IFTYPE_STATION ||
|
||||
(sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
|
||||
sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
|
||||
/* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
|
||||
SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
|
||||
|
||||
@ -69,8 +69,8 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
|
||||
* table which matches the requested BA status.
|
||||
*/
|
||||
static struct mwifiex_tx_ba_stream_tbl *
|
||||
mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv,
|
||||
enum mwifiex_ba_status ba_status)
|
||||
mwifiex_get_ba_status(struct mwifiex_private *priv,
|
||||
enum mwifiex_ba_status ba_status)
|
||||
{
|
||||
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
|
||||
unsigned long flags;
|
||||
@ -107,12 +107,11 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
|
||||
|
||||
tid = del_ba_param_set >> DELBA_TID_POS;
|
||||
if (del_ba->del_result == BA_RESULT_SUCCESS) {
|
||||
mwifiex_11n_delete_ba_stream_tbl(priv, tid,
|
||||
del_ba->peer_mac_addr, TYPE_DELBA_SENT,
|
||||
INITIATOR_BIT(del_ba_param_set));
|
||||
mwifiex_del_ba_tbl(priv, tid, del_ba->peer_mac_addr,
|
||||
TYPE_DELBA_SENT,
|
||||
INITIATOR_BIT(del_ba_param_set));
|
||||
|
||||
tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
|
||||
BA_STREAM_SETUP_INPROGRESS);
|
||||
tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS);
|
||||
if (tx_ba_tbl)
|
||||
mwifiex_send_addba(priv, tx_ba_tbl->tid,
|
||||
tx_ba_tbl->ra);
|
||||
@ -120,18 +119,17 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
|
||||
* In case of failure, recreate the deleted stream in case
|
||||
* we initiated the ADDBA
|
||||
*/
|
||||
if (INITIATOR_BIT(del_ba_param_set)) {
|
||||
mwifiex_11n_create_tx_ba_stream_tbl(priv,
|
||||
del_ba->peer_mac_addr, tid,
|
||||
BA_STREAM_SETUP_INPROGRESS);
|
||||
if (!INITIATOR_BIT(del_ba_param_set))
|
||||
return 0;
|
||||
|
||||
tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
|
||||
BA_STREAM_SETUP_INPROGRESS);
|
||||
if (tx_ba_tbl)
|
||||
mwifiex_11n_delete_ba_stream_tbl(priv,
|
||||
tx_ba_tbl->tid, tx_ba_tbl->ra,
|
||||
TYPE_DELBA_SENT, true);
|
||||
}
|
||||
mwifiex_create_ba_tbl(priv, del_ba->peer_mac_addr, tid,
|
||||
BA_SETUP_INPROGRESS);
|
||||
|
||||
tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS);
|
||||
|
||||
if (tx_ba_tbl)
|
||||
mwifiex_del_ba_tbl(priv, tx_ba_tbl->tid, tx_ba_tbl->ra,
|
||||
TYPE_DELBA_SENT, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -160,18 +158,17 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
|
||||
& IEEE80211_ADDBA_PARAM_TID_MASK)
|
||||
>> BLOCKACKPARAM_TID_POS;
|
||||
if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
|
||||
tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid,
|
||||
tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid,
|
||||
add_ba_rsp->peer_mac_addr);
|
||||
if (tx_ba_tbl) {
|
||||
dev_dbg(priv->adapter->dev, "info: BA stream complete\n");
|
||||
tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
|
||||
tx_ba_tbl->ba_status = BA_SETUP_COMPLETE;
|
||||
} else {
|
||||
dev_err(priv->adapter->dev, "BA stream not created\n");
|
||||
}
|
||||
} else {
|
||||
mwifiex_11n_delete_ba_stream_tbl(priv, tid,
|
||||
add_ba_rsp->peer_mac_addr,
|
||||
TYPE_DELBA_SENT, true);
|
||||
mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr,
|
||||
TYPE_DELBA_SENT, true);
|
||||
if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
|
||||
priv->aggr_prio_tbl[tid].ampdu_ap =
|
||||
BA_STREAM_NOT_ALLOWED;
|
||||
@ -392,9 +389,9 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
|
||||
chan_list->chan_scan_param[0].radio_type =
|
||||
mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
|
||||
|
||||
if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
|
||||
&& (bss_desc->bcn_ht_info->ht_param &
|
||||
IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
|
||||
if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
|
||||
bss_desc->bcn_ht_info->ht_param &
|
||||
IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)
|
||||
SET_SECONDARYCHAN(chan_list->chan_scan_param[0].
|
||||
radio_type,
|
||||
(bss_desc->bcn_ht_info->ht_param &
|
||||
@ -467,7 +464,7 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
|
||||
tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu);
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n",
|
||||
max_amsdu, priv->adapter->max_tx_buf_size);
|
||||
max_amsdu, priv->adapter->max_tx_buf_size);
|
||||
|
||||
if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K)
|
||||
curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
|
||||
@ -507,7 +504,7 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
|
||||
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl)
|
||||
{
|
||||
if (!tx_ba_tsr_tbl &&
|
||||
mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
|
||||
mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
|
||||
return;
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl);
|
||||
@ -544,16 +541,15 @@ void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
|
||||
* table which matches the given RA/TID pair.
|
||||
*/
|
||||
struct mwifiex_tx_ba_stream_tbl *
|
||||
mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
|
||||
int tid, u8 *ra)
|
||||
mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra)
|
||||
{
|
||||
struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
|
||||
list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
|
||||
if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN))
|
||||
&& (tx_ba_tsr_tbl->tid == tid)) {
|
||||
if (!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN) &&
|
||||
tx_ba_tsr_tbl->tid == tid) {
|
||||
spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
|
||||
flags);
|
||||
return tx_ba_tsr_tbl;
|
||||
@ -567,14 +563,13 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
|
||||
* This function creates an entry in Tx BA stream table for the
|
||||
* given RA/TID pair.
|
||||
*/
|
||||
void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
|
||||
u8 *ra, int tid,
|
||||
enum mwifiex_ba_status ba_status)
|
||||
void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
|
||||
enum mwifiex_ba_status ba_status)
|
||||
{
|
||||
struct mwifiex_tx_ba_stream_tbl *new_node;
|
||||
unsigned long flags;
|
||||
|
||||
if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) {
|
||||
if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
|
||||
new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
|
||||
GFP_ATOMIC);
|
||||
if (!new_node) {
|
||||
@ -668,9 +663,8 @@ void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba)
|
||||
|
||||
tid = del_ba_param_set >> DELBA_TID_POS;
|
||||
|
||||
mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
|
||||
TYPE_DELBA_RECEIVE,
|
||||
INITIATOR_BIT(del_ba_param_set));
|
||||
mwifiex_del_ba_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
|
||||
TYPE_DELBA_RECEIVE, INITIATOR_BIT(del_ba_param_set));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -724,7 +718,7 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
|
||||
list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
|
||||
rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid;
|
||||
dev_dbg(priv->adapter->dev, "data: %s tid=%d\n",
|
||||
__func__, rx_reo_tbl->tid);
|
||||
__func__, rx_reo_tbl->tid);
|
||||
memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN);
|
||||
rx_reo_tbl++;
|
||||
count++;
|
||||
|
@ -46,13 +46,12 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
|
||||
struct mwifiex_tx_ba_stream_tbl
|
||||
*tx_tbl);
|
||||
void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv);
|
||||
struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct
|
||||
struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct
|
||||
mwifiex_private
|
||||
*priv, int tid,
|
||||
u8 *ra);
|
||||
void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra,
|
||||
int tid,
|
||||
enum mwifiex_ba_status ba_status);
|
||||
void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
|
||||
enum mwifiex_ba_status ba_status);
|
||||
int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac);
|
||||
int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
|
||||
int initiator);
|
||||
@ -87,9 +86,8 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid)
|
||||
static inline u8
|
||||
mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid)
|
||||
{
|
||||
return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED)
|
||||
&& ((priv->is_data_rate_auto)
|
||||
|| !((priv->bitmap_rates[2]) & 0x03)))
|
||||
return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) &&
|
||||
(priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03)))
|
||||
? true : false);
|
||||
}
|
||||
|
||||
@ -150,11 +148,11 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
|
||||
*/
|
||||
static inline int
|
||||
mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
|
||||
struct mwifiex_ra_list_tbl *ptr, int tid)
|
||||
struct mwifiex_ra_list_tbl *ptr, int tid)
|
||||
{
|
||||
struct mwifiex_tx_ba_stream_tbl *tx_tbl;
|
||||
|
||||
tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra);
|
||||
tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra);
|
||||
if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl))
|
||||
return true;
|
||||
|
||||
|
@ -84,7 +84,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
|
||||
/* Add payload */
|
||||
skb_put(skb_aggr, skb_src->len);
|
||||
memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data,
|
||||
skb_src->len);
|
||||
skb_src->len);
|
||||
*pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len +
|
||||
LLC_SNAP_LEN)) & 3)) : 0;
|
||||
skb_put(skb_aggr, *pad);
|
||||
@ -119,14 +119,14 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
|
||||
local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
|
||||
local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
|
||||
local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
|
||||
sizeof(*local_tx_pd));
|
||||
sizeof(*local_tx_pd));
|
||||
|
||||
if (local_tx_pd->tx_control == 0)
|
||||
/* TxCtrl set by user or default */
|
||||
local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
|
||||
|
||||
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
|
||||
(priv->adapter->pps_uapsd_mode)) {
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
|
||||
priv->adapter->pps_uapsd_mode) {
|
||||
if (true == mwifiex_check_last_packet_indication(priv)) {
|
||||
priv->adapter->tx_lock_flag = true;
|
||||
local_tx_pd->flags =
|
||||
@ -257,9 +257,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
mwifiex_write_data_complete(adapter, skb_aggr, -1);
|
||||
return -1;
|
||||
}
|
||||
if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
|
||||
(adapter->pps_uapsd_mode) &&
|
||||
(adapter->tx_lock_flag)) {
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
|
||||
adapter->pps_uapsd_mode && adapter->tx_lock_flag) {
|
||||
priv->adapter->tx_lock_flag = false;
|
||||
if (ptx_pd)
|
||||
ptx_pd->flags = 0;
|
||||
@ -279,7 +278,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
|
||||
case -1:
|
||||
adapter->data_sent = false;
|
||||
dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
|
||||
__func__, ret);
|
||||
__func__, ret);
|
||||
adapter->dbg.num_tx_host_to_card_failure++;
|
||||
mwifiex_write_data_complete(adapter, skb_aggr, ret);
|
||||
return 0;
|
||||
|
@ -27,31 +27,31 @@
|
||||
#include "11n_rxreorder.h"
|
||||
|
||||
/*
|
||||
* This function dispatches all packets in the Rx reorder table.
|
||||
* This function dispatches all packets in the Rx reorder table until the
|
||||
* start window.
|
||||
*
|
||||
* There could be holes in the buffer, which are skipped by the function.
|
||||
* Since the buffer is linear, the function uses rotation to simulate
|
||||
* circular buffer.
|
||||
*/
|
||||
static void
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
|
||||
struct mwifiex_rx_reorder_tbl
|
||||
*rx_reor_tbl_ptr, int start_win)
|
||||
mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv,
|
||||
struct mwifiex_rx_reorder_tbl *tbl, int start_win)
|
||||
{
|
||||
int no_pkt_to_send, i;
|
||||
int pkt_to_send, i;
|
||||
void *rx_tmp_ptr;
|
||||
unsigned long flags;
|
||||
|
||||
no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ?
|
||||
min((start_win - rx_reor_tbl_ptr->start_win),
|
||||
rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size;
|
||||
pkt_to_send = (start_win > tbl->start_win) ?
|
||||
min((start_win - tbl->start_win), tbl->win_size) :
|
||||
tbl->win_size;
|
||||
|
||||
for (i = 0; i < no_pkt_to_send; ++i) {
|
||||
for (i = 0; i < pkt_to_send; ++i) {
|
||||
spin_lock_irqsave(&priv->rx_pkt_lock, flags);
|
||||
rx_tmp_ptr = NULL;
|
||||
if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
|
||||
rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
|
||||
if (tbl->rx_reorder_ptr[i]) {
|
||||
rx_tmp_ptr = tbl->rx_reorder_ptr[i];
|
||||
tbl->rx_reorder_ptr[i] = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
|
||||
if (rx_tmp_ptr)
|
||||
@ -63,13 +63,12 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
|
||||
* We don't have a circular buffer, hence use rotation to simulate
|
||||
* circular buffer
|
||||
*/
|
||||
for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) {
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[i] =
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i];
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL;
|
||||
for (i = 0; i < tbl->win_size - pkt_to_send; ++i) {
|
||||
tbl->rx_reorder_ptr[i] = tbl->rx_reorder_ptr[pkt_to_send + i];
|
||||
tbl->rx_reorder_ptr[pkt_to_send + i] = NULL;
|
||||
}
|
||||
|
||||
rx_reor_tbl_ptr->start_win = start_win;
|
||||
tbl->start_win = start_win;
|
||||
spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
|
||||
}
|
||||
|
||||
@ -83,20 +82,20 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
|
||||
*/
|
||||
static void
|
||||
mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
|
||||
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)
|
||||
struct mwifiex_rx_reorder_tbl *tbl)
|
||||
{
|
||||
int i, j, xchg;
|
||||
void *rx_tmp_ptr;
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) {
|
||||
for (i = 0; i < tbl->win_size; ++i) {
|
||||
spin_lock_irqsave(&priv->rx_pkt_lock, flags);
|
||||
if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
|
||||
if (!tbl->rx_reorder_ptr[i]) {
|
||||
spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
|
||||
break;
|
||||
}
|
||||
rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
|
||||
rx_tmp_ptr = tbl->rx_reorder_ptr[i];
|
||||
tbl->rx_reorder_ptr[i] = NULL;
|
||||
spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
|
||||
mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr);
|
||||
}
|
||||
@ -107,15 +106,13 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
|
||||
* circular buffer
|
||||
*/
|
||||
if (i > 0) {
|
||||
xchg = rx_reor_tbl_ptr->win_size - i;
|
||||
xchg = tbl->win_size - i;
|
||||
for (j = 0; j < xchg; ++j) {
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[j] =
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[i + j];
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL;
|
||||
tbl->rx_reorder_ptr[j] = tbl->rx_reorder_ptr[i + j];
|
||||
tbl->rx_reorder_ptr[i + j] = NULL;
|
||||
}
|
||||
}
|
||||
rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i)
|
||||
&(MAX_TID_VALUE - 1);
|
||||
tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1);
|
||||
spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
|
||||
}
|
||||
|
||||
@ -126,28 +123,25 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
|
||||
* pending packets in the Rx reorder table before deletion.
|
||||
*/
|
||||
static void
|
||||
mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
|
||||
struct mwifiex_rx_reorder_tbl
|
||||
*rx_reor_tbl_ptr)
|
||||
mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
|
||||
struct mwifiex_rx_reorder_tbl *tbl)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!rx_reor_tbl_ptr)
|
||||
if (!tbl)
|
||||
return;
|
||||
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
|
||||
(rx_reor_tbl_ptr->start_win +
|
||||
rx_reor_tbl_ptr->win_size)
|
||||
&(MAX_TID_VALUE - 1));
|
||||
mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) &
|
||||
(MAX_TID_VALUE - 1));
|
||||
|
||||
del_timer(&rx_reor_tbl_ptr->timer_context.timer);
|
||||
del_timer(&tbl->timer_context.timer);
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
list_del(&rx_reor_tbl_ptr->list);
|
||||
list_del(&tbl->list);
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
||||
kfree(rx_reor_tbl_ptr->rx_reorder_ptr);
|
||||
kfree(rx_reor_tbl_ptr);
|
||||
kfree(tbl->rx_reorder_ptr);
|
||||
kfree(tbl);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -157,16 +151,15 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
|
||||
static struct mwifiex_rx_reorder_tbl *
|
||||
mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
|
||||
{
|
||||
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
|
||||
struct mwifiex_rx_reorder_tbl *tbl;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
|
||||
if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN))
|
||||
&& (rx_reor_tbl_ptr->tid == tid)) {
|
||||
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) {
|
||||
if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
flags);
|
||||
return rx_reor_tbl_ptr;
|
||||
return tbl;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
@ -200,19 +193,19 @@ mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
|
||||
static void
|
||||
mwifiex_flush_data(unsigned long context)
|
||||
{
|
||||
struct reorder_tmr_cnxt *reorder_cnxt =
|
||||
struct reorder_tmr_cnxt *ctx =
|
||||
(struct reorder_tmr_cnxt *) context;
|
||||
int start_win;
|
||||
|
||||
start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr);
|
||||
if (start_win >= 0) {
|
||||
dev_dbg(reorder_cnxt->priv->adapter->dev,
|
||||
"info: flush data %d\n", start_win);
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv,
|
||||
reorder_cnxt->ptr,
|
||||
((reorder_cnxt->ptr->start_win +
|
||||
start_win + 1) & (MAX_TID_VALUE - 1)));
|
||||
}
|
||||
start_win = mwifiex_11n_find_last_seq_num(ctx->ptr);
|
||||
|
||||
if (start_win < 0)
|
||||
return;
|
||||
|
||||
dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", start_win);
|
||||
mwifiex_11n_dispatch_pkt(ctx->priv, ctx->ptr,
|
||||
(ctx->ptr->start_win + start_win + 1) &
|
||||
(MAX_TID_VALUE - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -227,10 +220,10 @@ mwifiex_flush_data(unsigned long context)
|
||||
*/
|
||||
static void
|
||||
mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
|
||||
int tid, int win_size, int seq_num)
|
||||
int tid, int win_size, int seq_num)
|
||||
{
|
||||
int i;
|
||||
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node;
|
||||
struct mwifiex_rx_reorder_tbl *tbl, *new_node;
|
||||
u16 last_seq = 0;
|
||||
unsigned long flags;
|
||||
|
||||
@ -238,17 +231,16 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
|
||||
* If we get a TID, ta pair which is already present dispatch all the
|
||||
* the packets and move the window size until the ssn
|
||||
*/
|
||||
rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
|
||||
if (rx_reor_tbl_ptr) {
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
|
||||
seq_num);
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
|
||||
if (tbl) {
|
||||
mwifiex_11n_dispatch_pkt(priv, tbl, seq_num);
|
||||
return;
|
||||
}
|
||||
/* if !rx_reor_tbl_ptr then create one */
|
||||
/* if !tbl then create one */
|
||||
new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL);
|
||||
if (!new_node) {
|
||||
dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -360,7 +352,8 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
|
||||
cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set);
|
||||
|
||||
mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr,
|
||||
tid, win_size, le16_to_cpu(cmd_addba_req->ssn));
|
||||
tid, win_size,
|
||||
le16_to_cpu(cmd_addba_req->ssn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -401,35 +394,34 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
|
||||
u16 seq_num, u16 tid,
|
||||
u8 *ta, u8 pkt_type, void *payload)
|
||||
{
|
||||
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
|
||||
struct mwifiex_rx_reorder_tbl *tbl;
|
||||
int start_win, end_win, win_size;
|
||||
u16 pkt_index;
|
||||
|
||||
rx_reor_tbl_ptr =
|
||||
mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
|
||||
tid, ta);
|
||||
if (!rx_reor_tbl_ptr) {
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
|
||||
tid, ta);
|
||||
if (!tbl) {
|
||||
if (pkt_type != PKT_TYPE_BAR)
|
||||
mwifiex_process_rx_packet(priv->adapter, payload);
|
||||
return 0;
|
||||
}
|
||||
start_win = rx_reor_tbl_ptr->start_win;
|
||||
win_size = rx_reor_tbl_ptr->win_size;
|
||||
start_win = tbl->start_win;
|
||||
win_size = tbl->win_size;
|
||||
end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
|
||||
del_timer(&rx_reor_tbl_ptr->timer_context.timer);
|
||||
mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies
|
||||
+ (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000);
|
||||
del_timer(&tbl->timer_context.timer);
|
||||
mod_timer(&tbl->timer_context.timer,
|
||||
jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000);
|
||||
|
||||
/*
|
||||
* If seq_num is less then starting win then ignore and drop the
|
||||
* packet
|
||||
*/
|
||||
if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */
|
||||
if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1))
|
||||
&& (seq_num < start_win))
|
||||
if (seq_num >= ((start_win + TWOPOW11) &
|
||||
(MAX_TID_VALUE - 1)) && (seq_num < start_win))
|
||||
return -1;
|
||||
} else if ((seq_num < start_win)
|
||||
|| (seq_num > (start_win + (TWOPOW11)))) {
|
||||
} else if ((seq_num < start_win) ||
|
||||
(seq_num > (start_win + TWOPOW11))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -440,17 +432,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
|
||||
if (pkt_type == PKT_TYPE_BAR)
|
||||
seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
|
||||
|
||||
if (((end_win < start_win)
|
||||
&& (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win)))
|
||||
&& (seq_num > end_win)) || ((end_win > start_win)
|
||||
&& ((seq_num > end_win) || (seq_num < start_win)))) {
|
||||
if (((end_win < start_win) &&
|
||||
(seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) &&
|
||||
(seq_num > end_win)) ||
|
||||
((end_win > start_win) && ((seq_num > end_win) ||
|
||||
(seq_num < start_win)))) {
|
||||
end_win = seq_num;
|
||||
if (((seq_num - win_size) + 1) >= 0)
|
||||
start_win = (end_win - win_size) + 1;
|
||||
else
|
||||
start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;
|
||||
mwifiex_11n_dispatch_pkt_until_start_win(priv,
|
||||
rx_reor_tbl_ptr, start_win);
|
||||
mwifiex_11n_dispatch_pkt(priv, tbl, start_win);
|
||||
}
|
||||
|
||||
if (pkt_type != PKT_TYPE_BAR) {
|
||||
@ -459,17 +451,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
|
||||
else
|
||||
pkt_index = (seq_num+MAX_TID_VALUE) - start_win;
|
||||
|
||||
if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index])
|
||||
if (tbl->rx_reorder_ptr[pkt_index])
|
||||
return -1;
|
||||
|
||||
rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload;
|
||||
tbl->rx_reorder_ptr[pkt_index] = payload;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dispatch all packets sequentially from start_win until a
|
||||
* hole is found and adjust the start_win appropriately
|
||||
*/
|
||||
mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);
|
||||
mwifiex_11n_scan_and_dispatch(priv, tbl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -480,10 +472,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
|
||||
* The TID/TA are taken from del BA event body.
|
||||
*/
|
||||
void
|
||||
mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
|
||||
u8 *peer_mac, u8 type, int initiator)
|
||||
mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
|
||||
u8 type, int initiator)
|
||||
{
|
||||
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
|
||||
struct mwifiex_rx_reorder_tbl *tbl;
|
||||
struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
|
||||
u8 cleanup_rx_reorder_tbl;
|
||||
unsigned long flags;
|
||||
@ -493,23 +485,23 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
|
||||
else
|
||||
cleanup_rx_reorder_tbl = (initiator) ? false : true;
|
||||
|
||||
dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, "
|
||||
"initiator=%d\n", peer_mac, tid, initiator);
|
||||
dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d initiator=%d\n",
|
||||
peer_mac, tid, initiator);
|
||||
|
||||
if (cleanup_rx_reorder_tbl) {
|
||||
rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
|
||||
peer_mac);
|
||||
if (!rx_reor_tbl_ptr) {
|
||||
if (!tbl) {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"event: TID, TA not found in table\n");
|
||||
"event: TID, TA not found in table\n");
|
||||
return;
|
||||
}
|
||||
mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr);
|
||||
mwifiex_del_rx_reorder_entry(priv, tbl);
|
||||
} else {
|
||||
ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac);
|
||||
ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac);
|
||||
if (!ptx_tbl) {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"event: TID, RA not found in table\n");
|
||||
"event: TID, RA not found in table\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -532,7 +524,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
|
||||
(struct host_cmd_ds_11n_addba_rsp *)
|
||||
&resp->params.add_ba_rsp;
|
||||
int tid, win_size;
|
||||
struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
|
||||
struct mwifiex_rx_reorder_tbl *tbl;
|
||||
uint16_t block_ack_param_set;
|
||||
|
||||
block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
|
||||
@ -548,19 +540,18 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
|
||||
IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
|
||||
>> BLOCKACKPARAM_WINSIZE_POS;
|
||||
|
||||
dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM"
|
||||
" tid=%d ssn=%d win_size=%d\n",
|
||||
add_ba_rsp->peer_mac_addr,
|
||||
tid, add_ba_rsp->ssn, win_size);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n",
|
||||
add_ba_rsp->peer_mac_addr, tid,
|
||||
add_ba_rsp->ssn, win_size);
|
||||
} else {
|
||||
dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n",
|
||||
add_ba_rsp->peer_mac_addr, tid);
|
||||
add_ba_rsp->peer_mac_addr, tid);
|
||||
|
||||
rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv,
|
||||
tid, add_ba_rsp->peer_mac_addr);
|
||||
if (rx_reor_tbl_ptr)
|
||||
mwifiex_11n_delete_rx_reorder_tbl_entry(priv,
|
||||
rx_reor_tbl_ptr);
|
||||
tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
|
||||
add_ba_rsp->peer_mac_addr);
|
||||
if (tbl)
|
||||
mwifiex_del_rx_reorder_entry(priv, tbl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -599,7 +590,7 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
|
||||
list_for_each_entry_safe(del_tbl_ptr, tmp_node,
|
||||
&priv->rx_reorder_tbl_ptr, list) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr);
|
||||
mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr);
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
|
||||
|
@ -41,9 +41,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *,
|
||||
u16 seqNum,
|
||||
u16 tid, u8 *ta,
|
||||
u8 pkttype, void *payload);
|
||||
void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid,
|
||||
u8 *PeerMACAddr, u8 type,
|
||||
int initiator);
|
||||
void mwifiex_del_ba_tbl(struct mwifiex_private *priv, int Tid,
|
||||
u8 *PeerMACAddr, u8 type, int initiator);
|
||||
void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_11n_batimeout *event);
|
||||
int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
|
||||
|
@ -127,8 +127,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
|
||||
|
||||
if (timeout)
|
||||
wiphy_dbg(wiphy,
|
||||
"info: ignoring the timeout value"
|
||||
" for IEEE power save\n");
|
||||
"info: ignore timeout value for IEEE Power Save\n");
|
||||
|
||||
ps_mode = enabled;
|
||||
|
||||
@ -168,7 +167,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
|
||||
|
||||
if (mwifiex_set_encode(priv, params->key, params->key_len,
|
||||
key_index, 0)) {
|
||||
key_index, 0)) {
|
||||
wiphy_err(wiphy, "crypto keys added\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
@ -225,7 +224,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
|
||||
}
|
||||
|
||||
if (ch->hw_value == next_chan + 1 &&
|
||||
ch->max_power == max_pwr) {
|
||||
ch->max_power == max_pwr) {
|
||||
next_chan++;
|
||||
no_of_parsed_chan++;
|
||||
} else {
|
||||
@ -252,7 +251,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
|
||||
domain_info->no_of_triplet = no_of_triplet;
|
||||
|
||||
if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL)) {
|
||||
HostCmd_ACT_GEN_SET, 0, NULL)) {
|
||||
wiphy_err(wiphy, "11D: setting domain info in FW\n");
|
||||
return -1;
|
||||
}
|
||||
@ -271,7 +270,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
|
||||
* - Set bt Country IE
|
||||
*/
|
||||
static int mwifiex_reg_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
|
||||
|
||||
@ -316,7 +315,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
|
||||
if (chan->band == IEEE80211_BAND_2GHZ) {
|
||||
if (channel_type == NL80211_CHAN_NO_HT)
|
||||
if (priv->adapter->config_bands == BAND_B ||
|
||||
priv->adapter->config_bands == BAND_G)
|
||||
priv->adapter->config_bands == BAND_G)
|
||||
config_bands =
|
||||
priv->adapter->config_bands;
|
||||
else
|
||||
@ -336,7 +335,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
|
||||
if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
|
||||
adapter->adhoc_start_band = config_bands;
|
||||
if ((config_bands & BAND_GN) ||
|
||||
(config_bands & BAND_AN))
|
||||
(config_bands & BAND_AN))
|
||||
adapter->adhoc_11n_enabled = true;
|
||||
else
|
||||
adapter->adhoc_11n_enabled = false;
|
||||
@ -350,9 +349,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
|
||||
mwifiex_send_domain_info_cmd_fw(wiphy);
|
||||
}
|
||||
|
||||
wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and "
|
||||
"mode %d\n", config_bands, adapter->sec_chan_offset,
|
||||
priv->bss_mode);
|
||||
wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n",
|
||||
config_bands, adapter->sec_chan_offset, priv->bss_mode);
|
||||
if (!chan)
|
||||
return 0;
|
||||
|
||||
@ -403,8 +401,8 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
|
||||
|| frag_thr > MWIFIEX_FRAG_MAX_VALUE)
|
||||
if (frag_thr < MWIFIEX_FRAG_MIN_VALUE ||
|
||||
frag_thr > MWIFIEX_FRAG_MAX_VALUE)
|
||||
return -EINVAL;
|
||||
|
||||
/* Send request to firmware */
|
||||
@ -746,8 +744,7 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
|
||||
adapter->channel_type = NL80211_CHAN_NO_HT;
|
||||
|
||||
wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n",
|
||||
(mode & BAND_B) ? "b" : "",
|
||||
(mode & BAND_G) ? "g" : "");
|
||||
(mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -802,8 +799,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
|
||||
ie_buf[1] = bss_info.ssid.ssid_len;
|
||||
|
||||
memcpy(&ie_buf[sizeof(struct ieee_types_header)],
|
||||
&bss_info.ssid.ssid,
|
||||
bss_info.ssid.ssid_len);
|
||||
&bss_info.ssid.ssid, bss_info.ssid.ssid_len);
|
||||
ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
|
||||
|
||||
band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
|
||||
@ -812,8 +808,8 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
|
||||
band));
|
||||
|
||||
bss = cfg80211_inform_bss(priv->wdev->wiphy, chan,
|
||||
bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
|
||||
0, ie_buf, ie_len, 0, GFP_KERNEL);
|
||||
bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
|
||||
0, ie_buf, ie_len, 0, GFP_KERNEL);
|
||||
cfg80211_put_bss(bss);
|
||||
memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
|
||||
|
||||
@ -952,14 +948,15 @@ done:
|
||||
|
||||
if (!bss) {
|
||||
if (is_scanning_required) {
|
||||
dev_warn(priv->adapter->dev, "assoc: requested "
|
||||
"bss not found in scan results\n");
|
||||
dev_warn(priv->adapter->dev,
|
||||
"assoc: requested bss not found in scan results\n");
|
||||
break;
|
||||
}
|
||||
is_scanning_required = 1;
|
||||
} else {
|
||||
dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
|
||||
(char *) req_ssid.ssid, bss->bssid);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: trying to associate to '%s' bssid %pM\n",
|
||||
(char *) req_ssid.ssid, bss->bssid);
|
||||
memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
|
||||
break;
|
||||
}
|
||||
@ -999,7 +996,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
}
|
||||
|
||||
wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
|
||||
(char *) sme->ssid, sme->bssid);
|
||||
(char *) sme->ssid, sme->bssid);
|
||||
|
||||
ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
|
||||
priv->bss_mode, sme->channel, sme, 0);
|
||||
@ -1041,11 +1038,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||
}
|
||||
|
||||
wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
|
||||
(char *) params->ssid, params->bssid);
|
||||
(char *) params->ssid, params->bssid);
|
||||
|
||||
ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
|
||||
params->bssid, priv->bss_mode,
|
||||
params->channel, NULL, params->privacy);
|
||||
params->bssid, priv->bss_mode,
|
||||
params->channel, NULL, params->privacy);
|
||||
done:
|
||||
if (!ret) {
|
||||
cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
|
||||
@ -1072,7 +1069,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
|
||||
priv->cfg_bssid);
|
||||
priv->cfg_bssid);
|
||||
if (mwifiex_deauthenticate(priv, NULL))
|
||||
return -EFAULT;
|
||||
|
||||
@ -1101,7 +1098,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
|
||||
priv->scan_request = request;
|
||||
|
||||
priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
if (!priv->user_scan_cfg) {
|
||||
dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
|
||||
return -ENOMEM;
|
||||
@ -1117,10 +1114,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
priv->user_scan_cfg->chan_list[i].scan_type =
|
||||
MWIFIEX_SCAN_TYPE_PASSIVE;
|
||||
MWIFIEX_SCAN_TYPE_PASSIVE;
|
||||
else
|
||||
priv->user_scan_cfg->chan_list[i].scan_type =
|
||||
MWIFIEX_SCAN_TYPE_ACTIVE;
|
||||
MWIFIEX_SCAN_TYPE_ACTIVE;
|
||||
|
||||
priv->user_scan_cfg->chan_list[i].scan_time = 0;
|
||||
}
|
||||
@ -1191,9 +1188,9 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
|
||||
memset(mcs, 0xff, rx_mcs_supp);
|
||||
/* Clear all the other values */
|
||||
memset(&mcs[rx_mcs_supp], 0,
|
||||
sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
|
||||
sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
|
||||
if (priv->bss_mode == NL80211_IFTYPE_STATION ||
|
||||
ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
|
||||
ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
|
||||
/* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
|
||||
SETHT_MCS32(mcs_set.rx_mask);
|
||||
|
||||
@ -1206,10 +1203,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
|
||||
* create a new virtual interface with the given name
|
||||
*/
|
||||
struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
||||
char *name,
|
||||
enum nl80211_iftype type,
|
||||
u32 *flags,
|
||||
struct vif_params *params)
|
||||
char *name,
|
||||
enum nl80211_iftype type,
|
||||
u32 *flags,
|
||||
struct vif_params *params)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
|
||||
struct mwifiex_adapter *adapter;
|
||||
@ -1367,11 +1364,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
|
||||
int ret;
|
||||
void *wdev_priv;
|
||||
struct wireless_dev *wdev;
|
||||
struct ieee80211_sta_ht_cap *ht_info;
|
||||
|
||||
wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
|
||||
if (!wdev) {
|
||||
dev_err(priv->adapter->dev, "%s: allocating wireless device\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
wdev->wiphy =
|
||||
@ -1383,17 +1381,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
|
||||
}
|
||||
wdev->iftype = NL80211_IFTYPE_STATION;
|
||||
wdev->wiphy->max_scan_ssids = 10;
|
||||
wdev->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
|
||||
wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
|
||||
mwifiex_setup_ht_caps(
|
||||
&wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
|
||||
ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap;
|
||||
mwifiex_setup_ht_caps(ht_info, priv);
|
||||
|
||||
if (priv->adapter->config_bands & BAND_A) {
|
||||
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
|
||||
mwifiex_setup_ht_caps(
|
||||
&wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
|
||||
ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap;
|
||||
mwifiex_setup_ht_caps(ht_info, priv);
|
||||
} else {
|
||||
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
|
||||
}
|
||||
@ -1420,13 +1418,13 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
|
||||
ret = wiphy_register(wdev->wiphy);
|
||||
if (ret < 0) {
|
||||
dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
|
||||
__func__);
|
||||
__func__);
|
||||
wiphy_free(wdev->wiphy);
|
||||
kfree(wdev);
|
||||
return ret;
|
||||
} else {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: successfully registered wiphy device\n");
|
||||
"info: successfully registered wiphy device\n");
|
||||
}
|
||||
|
||||
priv->wdev = wdev;
|
||||
|
@ -163,92 +163,66 @@ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates)
|
||||
return mwifiex_get_supported_rates(priv, rates);
|
||||
else
|
||||
return mwifiex_copy_rates(rates, 0,
|
||||
priv->curr_bss_params.data_rates,
|
||||
priv->curr_bss_params.num_of_rates);
|
||||
priv->curr_bss_params.data_rates,
|
||||
priv->curr_bss_params.num_of_rates);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function locates the Channel-Frequency-Power triplet based upon
|
||||
* band and channel parameters.
|
||||
* band and channel/frequency parameters.
|
||||
*/
|
||||
struct mwifiex_chan_freq_power *
|
||||
mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private
|
||||
*priv, u8 band, u16 channel)
|
||||
mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq)
|
||||
{
|
||||
struct mwifiex_chan_freq_power *cfp = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
struct ieee80211_channel *ch = NULL;
|
||||
int i;
|
||||
|
||||
if (!channel && !freq)
|
||||
return cfp;
|
||||
|
||||
if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
|
||||
sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
else
|
||||
sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
if (!sband) {
|
||||
dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
|
||||
" & channel %d\n", __func__, band, channel);
|
||||
dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n",
|
||||
__func__, band);
|
||||
return cfp;
|
||||
}
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (((ch->hw_value == channel) ||
|
||||
(channel == FIRST_VALID_CHANNEL))
|
||||
&& !(ch->flags & IEEE80211_CHAN_DISABLED)) {
|
||||
priv->cfp.channel = channel;
|
||||
priv->cfp.freq = ch->center_freq;
|
||||
priv->cfp.max_tx_power = ch->max_power;
|
||||
cfp = &priv->cfp;
|
||||
break;
|
||||
|
||||
if (ch->flags & IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
|
||||
if (freq) {
|
||||
if (ch->center_freq == freq)
|
||||
break;
|
||||
} else {
|
||||
/* find by valid channel*/
|
||||
if (ch->hw_value == channel ||
|
||||
channel == FIRST_VALID_CHANNEL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == sband->n_channels)
|
||||
if (i == sband->n_channels) {
|
||||
dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
|
||||
" & channel %d\n", __func__, band, channel);
|
||||
" & channel=%d freq=%d\n", __func__, band, channel,
|
||||
freq);
|
||||
} else {
|
||||
if (!ch)
|
||||
return cfp;
|
||||
|
||||
return cfp;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function locates the Channel-Frequency-Power triplet based upon
|
||||
* band and frequency parameters.
|
||||
*/
|
||||
struct mwifiex_chan_freq_power *
|
||||
mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv,
|
||||
u8 band, u32 freq)
|
||||
{
|
||||
struct mwifiex_chan_freq_power *cfp = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
int i;
|
||||
|
||||
if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
|
||||
sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
else
|
||||
sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
if (!sband) {
|
||||
dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
|
||||
" & freq %d\n", __func__, band, freq);
|
||||
return cfp;
|
||||
priv->cfp.channel = ch->hw_value;
|
||||
priv->cfp.freq = ch->center_freq;
|
||||
priv->cfp.max_tx_power = ch->max_power;
|
||||
cfp = &priv->cfp;
|
||||
}
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if ((ch->center_freq == freq) &&
|
||||
!(ch->flags & IEEE80211_CHAN_DISABLED)) {
|
||||
priv->cfp.channel = ch->hw_value;
|
||||
priv->cfp.freq = freq;
|
||||
priv->cfp.max_tx_power = ch->max_power;
|
||||
cfp = &priv->cfp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == sband->n_channels)
|
||||
dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
|
||||
" & freq %d\n", __func__, band, freq);
|
||||
|
||||
return cfp;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
|
||||
return NULL;
|
||||
}
|
||||
cmd_node = list_first_entry(&adapter->cmd_free_q,
|
||||
struct cmd_ctrl_node, list);
|
||||
struct cmd_ctrl_node, list);
|
||||
list_del(&cmd_node->list);
|
||||
spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
|
||||
|
||||
@ -158,8 +158,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
||||
/* Set command sequence number */
|
||||
adapter->seq_num++;
|
||||
host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
|
||||
(adapter->seq_num, cmd_node->priv->bss_num,
|
||||
cmd_node->priv->bss_type));
|
||||
(adapter->seq_num,
|
||||
cmd_node->priv->bss_num,
|
||||
cmd_node->priv->bss_type));
|
||||
|
||||
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
|
||||
adapter->curr_cmd = cmd_node;
|
||||
@ -174,8 +175,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
||||
dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
|
||||
" seqno %#x\n",
|
||||
tstamp.tv_sec, tstamp.tv_usec, cmd_code,
|
||||
le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
|
||||
le16_to_cpu(host_cmd->seq_num));
|
||||
le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
|
||||
le16_to_cpu(host_cmd->seq_num));
|
||||
|
||||
skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
|
||||
|
||||
@ -200,17 +201,17 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
||||
|
||||
/* Save the last command id and action to debug log */
|
||||
adapter->dbg.last_cmd_index =
|
||||
(adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
|
||||
(adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
|
||||
adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code;
|
||||
adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] =
|
||||
le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
|
||||
le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
|
||||
|
||||
/* Clear BSS_NO_BITS from HostCmd */
|
||||
cmd_code &= HostCmd_CMD_ID_MASK;
|
||||
|
||||
/* Setup the timer after transmit command */
|
||||
mod_timer(&adapter->cmd_timer,
|
||||
jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
|
||||
jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -230,7 +231,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
||||
struct mwifiex_private *priv;
|
||||
struct mwifiex_opt_sleep_confirm *sleep_cfm_buf =
|
||||
(struct mwifiex_opt_sleep_confirm *)
|
||||
adapter->sleep_cfm->data;
|
||||
adapter->sleep_cfm->data;
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
|
||||
sleep_cfm_buf->seq_num =
|
||||
@ -250,7 +251,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
||||
return -1;
|
||||
}
|
||||
if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
|
||||
== MWIFIEX_BSS_ROLE_STA) {
|
||||
== MWIFIEX_BSS_ROLE_STA) {
|
||||
if (!sleep_cfm_buf->resp_ctrl)
|
||||
/* Response is not needed for sleep
|
||||
confirm command */
|
||||
@ -258,12 +259,12 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
||||
else
|
||||
adapter->ps_state = PS_STATE_SLEEP_CFM;
|
||||
|
||||
if (!sleep_cfm_buf->resp_ctrl
|
||||
&& (adapter->is_hs_configured
|
||||
&& !adapter->sleep_period.period)) {
|
||||
if (!sleep_cfm_buf->resp_ctrl &&
|
||||
(adapter->is_hs_configured &&
|
||||
!adapter->sleep_period.period)) {
|
||||
adapter->pm_wakeup_card_req = true;
|
||||
mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_STA), true);
|
||||
mwifiex_hs_activated_event(mwifiex_get_priv
|
||||
(adapter, MWIFIEX_BSS_ROLE_STA), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,7 +294,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
|
||||
cmd_array = kzalloc(buf_size, GFP_KERNEL);
|
||||
if (!cmd_array) {
|
||||
dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -376,9 +377,9 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Save the last event to debug log */
|
||||
adapter->dbg.last_event_index =
|
||||
(adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
|
||||
(adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
|
||||
adapter->dbg.last_event[adapter->dbg.last_event_index] =
|
||||
(u16) eventcause;
|
||||
(u16) eventcause;
|
||||
|
||||
/* Get BSS number and corresponding priv */
|
||||
priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause),
|
||||
@ -398,7 +399,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
|
||||
if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
|
||||
tstamp.tv_sec, tstamp.tv_usec, eventcause);
|
||||
tstamp.tv_sec, tstamp.tv_usec, eventcause);
|
||||
}
|
||||
|
||||
ret = mwifiex_process_sta_event(priv);
|
||||
@ -509,7 +510,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
|
||||
/* Return error, since the command preparation failed */
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n",
|
||||
cmd_no);
|
||||
cmd_no);
|
||||
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
|
||||
return -1;
|
||||
}
|
||||
@ -577,9 +578,9 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
|
||||
/* Exit_PS command needs to be queued in the header always. */
|
||||
if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
|
||||
struct host_cmd_ds_802_11_ps_mode_enh *pm =
|
||||
&host_cmd->params.psmode_enh;
|
||||
if ((le16_to_cpu(pm->action) == DIS_PS)
|
||||
|| (le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
|
||||
&host_cmd->params.psmode_enh;
|
||||
if ((le16_to_cpu(pm->action) == DIS_PS) ||
|
||||
(le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
|
||||
if (adapter->ps_state != PS_STATE_AWAKE)
|
||||
add_tail = false;
|
||||
}
|
||||
@ -692,7 +693,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
||||
if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
|
||||
resp = (struct host_cmd_ds_command *) adapter->upld_buf;
|
||||
dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n",
|
||||
le16_to_cpu(resp->command));
|
||||
le16_to_cpu(resp->command));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -701,7 +702,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
||||
resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
|
||||
if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
|
||||
dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n",
|
||||
le16_to_cpu(resp->command));
|
||||
le16_to_cpu(resp->command));
|
||||
mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
|
||||
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
|
||||
adapter->curr_cmd = NULL;
|
||||
@ -725,8 +726,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Get BSS number and corresponding priv */
|
||||
priv = mwifiex_get_priv_by_id(adapter,
|
||||
HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
|
||||
HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
|
||||
HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
|
||||
HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
|
||||
if (!priv)
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
/* Clear RET_BIT from HostCmd */
|
||||
@ -737,9 +738,9 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Save the last command response to debug log */
|
||||
adapter->dbg.last_cmd_resp_index =
|
||||
(adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
|
||||
(adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
|
||||
adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
|
||||
orig_cmdresp_no;
|
||||
orig_cmdresp_no;
|
||||
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
|
||||
@ -761,8 +762,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
|
||||
|
||||
if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
|
||||
adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
|
||||
if ((cmdresp_result == HostCmd_RESULT_OK)
|
||||
&& (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
|
||||
if ((cmdresp_result == HostCmd_RESULT_OK) &&
|
||||
(cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
|
||||
ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
|
||||
} else {
|
||||
/* handle response */
|
||||
@ -824,44 +825,45 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
|
||||
adapter->dbg.timeout_cmd_act =
|
||||
adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x,"
|
||||
" act = %#x\n", __func__,
|
||||
tstamp.tv_sec, tstamp.tv_usec,
|
||||
adapter->dbg.timeout_cmd_id,
|
||||
adapter->dbg.timeout_cmd_act);
|
||||
dev_err(adapter->dev,
|
||||
"%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n",
|
||||
__func__, tstamp.tv_sec, tstamp.tv_usec,
|
||||
adapter->dbg.timeout_cmd_id,
|
||||
adapter->dbg.timeout_cmd_act);
|
||||
|
||||
dev_err(adapter->dev, "num_data_h2c_failure = %d\n",
|
||||
adapter->dbg.num_tx_host_to_card_failure);
|
||||
adapter->dbg.num_tx_host_to_card_failure);
|
||||
dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
|
||||
adapter->dbg.num_cmd_host_to_card_failure);
|
||||
adapter->dbg.num_cmd_host_to_card_failure);
|
||||
|
||||
dev_err(adapter->dev, "num_cmd_timeout = %d\n",
|
||||
adapter->dbg.num_cmd_timeout);
|
||||
adapter->dbg.num_cmd_timeout);
|
||||
dev_err(adapter->dev, "num_tx_timeout = %d\n",
|
||||
adapter->dbg.num_tx_timeout);
|
||||
adapter->dbg.num_tx_timeout);
|
||||
|
||||
dev_err(adapter->dev, "last_cmd_index = %d\n",
|
||||
adapter->dbg.last_cmd_index);
|
||||
adapter->dbg.last_cmd_index);
|
||||
print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET,
|
||||
adapter->dbg.last_cmd_id, DBG_CMD_NUM);
|
||||
adapter->dbg.last_cmd_id, DBG_CMD_NUM);
|
||||
print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET,
|
||||
adapter->dbg.last_cmd_act, DBG_CMD_NUM);
|
||||
adapter->dbg.last_cmd_act, DBG_CMD_NUM);
|
||||
|
||||
dev_err(adapter->dev, "last_cmd_resp_index = %d\n",
|
||||
adapter->dbg.last_cmd_resp_index);
|
||||
adapter->dbg.last_cmd_resp_index);
|
||||
print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET,
|
||||
adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM);
|
||||
adapter->dbg.last_cmd_resp_id,
|
||||
DBG_CMD_NUM);
|
||||
|
||||
dev_err(adapter->dev, "last_event_index = %d\n",
|
||||
adapter->dbg.last_event_index);
|
||||
adapter->dbg.last_event_index);
|
||||
print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET,
|
||||
adapter->dbg.last_event, DBG_CMD_NUM);
|
||||
adapter->dbg.last_event, DBG_CMD_NUM);
|
||||
|
||||
dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n",
|
||||
adapter->data_sent, adapter->cmd_sent);
|
||||
adapter->data_sent, adapter->cmd_sent);
|
||||
|
||||
dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
|
||||
adapter->ps_mode, adapter->ps_state);
|
||||
adapter->ps_mode, adapter->ps_state);
|
||||
}
|
||||
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
|
||||
mwifiex_init_fw_complete(adapter);
|
||||
@ -942,7 +944,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
|
||||
uint16_t cancel_scan_cmd = false;
|
||||
|
||||
if ((adapter->curr_cmd) &&
|
||||
(adapter->curr_cmd->wait_q_enabled)) {
|
||||
(adapter->curr_cmd->wait_q_enabled)) {
|
||||
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
|
||||
cmd_node = adapter->curr_cmd;
|
||||
cmd_node->wait_q_enabled = false;
|
||||
@ -996,9 +998,9 @@ mwifiex_check_ps_cond(struct mwifiex_adapter *adapter)
|
||||
else
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: Delay Sleep Confirm (%s%s%s)\n",
|
||||
(adapter->cmd_sent) ? "D" : "",
|
||||
(adapter->curr_cmd) ? "C" : "",
|
||||
(IS_CARD_RX_RCVD(adapter)) ? "R" : "");
|
||||
(adapter->cmd_sent) ? "D" : "",
|
||||
(adapter->curr_cmd) ? "C" : "",
|
||||
(IS_CARD_RX_RCVD(adapter)) ? "R" : "");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1050,8 +1052,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
|
||||
dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply"
|
||||
" result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n",
|
||||
resp->result, conditions,
|
||||
phs_cfg->params.hs_config.gpio,
|
||||
phs_cfg->params.hs_config.gap);
|
||||
phs_cfg->params.hs_config.gpio,
|
||||
phs_cfg->params.hs_config.gap);
|
||||
}
|
||||
if (conditions != HOST_SLEEP_CFG_CANCEL) {
|
||||
adapter->is_hs_configured = true;
|
||||
@ -1078,7 +1080,8 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
|
||||
adapter->hs_activated = false;
|
||||
adapter->is_hs_configured = false;
|
||||
mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_ANY), false);
|
||||
MWIFIEX_BSS_ROLE_ANY),
|
||||
false);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1114,22 +1117,24 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
|
||||
command &= HostCmd_CMD_ID_MASK;
|
||||
|
||||
if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
|
||||
dev_err(adapter->dev, "%s: received unexpected response for"
|
||||
" cmd %x, result = %x\n", __func__, command, result);
|
||||
dev_err(adapter->dev,
|
||||
"%s: rcvd unexpected resp for cmd %#x, result = %x\n",
|
||||
__func__, command, result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
dev_err(adapter->dev, "%s: sleep confirm cmd failed\n",
|
||||
__func__);
|
||||
__func__);
|
||||
adapter->pm_wakeup_card_req = false;
|
||||
adapter->ps_state = PS_STATE_AWAKE;
|
||||
return;
|
||||
}
|
||||
adapter->pm_wakeup_card_req = true;
|
||||
if (adapter->is_hs_configured)
|
||||
mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_ANY), true);
|
||||
mwifiex_hs_activated_event(mwifiex_get_priv
|
||||
(adapter, MWIFIEX_BSS_ROLE_ANY),
|
||||
true);
|
||||
adapter->ps_state = PS_STATE_SLEEP;
|
||||
cmd->command = cpu_to_le16(command);
|
||||
cmd->seq_num = cpu_to_le16(seq_num);
|
||||
@ -1163,17 +1168,17 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
|
||||
psmode_enh->action = cpu_to_le16(DIS_AUTO_PS);
|
||||
psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
|
||||
cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
|
||||
sizeof(psmode_enh->params.ps_bitmap));
|
||||
sizeof(psmode_enh->params.ps_bitmap));
|
||||
} else if (cmd_action == GET_PS) {
|
||||
psmode_enh->action = cpu_to_le16(GET_PS);
|
||||
psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
|
||||
cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
|
||||
sizeof(psmode_enh->params.ps_bitmap));
|
||||
sizeof(psmode_enh->params.ps_bitmap));
|
||||
} else if (cmd_action == EN_AUTO_PS) {
|
||||
psmode_enh->action = cpu_to_le16(EN_AUTO_PS);
|
||||
psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
|
||||
cmd_size = S_DS_GEN + sizeof(psmode_enh->action) +
|
||||
sizeof(psmode_enh->params.ps_bitmap);
|
||||
sizeof(psmode_enh->params.ps_bitmap);
|
||||
tlv = (u8 *) cmd + cmd_size;
|
||||
if (ps_bitmap & BITMAP_STA_PS) {
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
@ -1187,19 +1192,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
|
||||
tlv += sizeof(*ps_tlv);
|
||||
dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n");
|
||||
ps_mode->null_pkt_interval =
|
||||
cpu_to_le16(adapter->null_pkt_interval);
|
||||
cpu_to_le16(adapter->null_pkt_interval);
|
||||
ps_mode->multiple_dtims =
|
||||
cpu_to_le16(adapter->multiple_dtim);
|
||||
cpu_to_le16(adapter->multiple_dtim);
|
||||
ps_mode->bcn_miss_timeout =
|
||||
cpu_to_le16(adapter->bcn_miss_time_out);
|
||||
cpu_to_le16(adapter->bcn_miss_time_out);
|
||||
ps_mode->local_listen_interval =
|
||||
cpu_to_le16(adapter->local_listen_interval);
|
||||
ps_mode->adhoc_wake_period =
|
||||
cpu_to_le16(adapter->adhoc_awake_period);
|
||||
ps_mode->delay_to_ps =
|
||||
cpu_to_le16(adapter->delay_to_ps);
|
||||
ps_mode->mode =
|
||||
cpu_to_le16(adapter->enhanced_ps_mode);
|
||||
cpu_to_le16(adapter->delay_to_ps);
|
||||
ps_mode->mode = cpu_to_le16(adapter->enhanced_ps_mode);
|
||||
|
||||
}
|
||||
if (ps_bitmap & BITMAP_AUTO_DS) {
|
||||
@ -1217,7 +1221,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
|
||||
if (auto_ds)
|
||||
idletime = auto_ds->idle_time;
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"cmd: PS Command: Enter Auto Deep Sleep\n");
|
||||
"cmd: PS Command: Enter Auto Deep Sleep\n");
|
||||
auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime);
|
||||
}
|
||||
cmd->size = cpu_to_le16(cmd_size);
|
||||
@ -1244,8 +1248,9 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
|
||||
uint16_t auto_ps_bitmap =
|
||||
le16_to_cpu(ps_mode->params.ps_bitmap);
|
||||
|
||||
dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
|
||||
__func__, resp->result, action);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
|
||||
__func__, resp->result, action);
|
||||
if (action == EN_AUTO_PS) {
|
||||
if (auto_ps_bitmap & BITMAP_AUTO_DS) {
|
||||
dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n");
|
||||
@ -1254,7 +1259,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
|
||||
if (auto_ps_bitmap & BITMAP_STA_PS) {
|
||||
dev_dbg(adapter->dev, "cmd: Enabled STA power save\n");
|
||||
if (adapter->sleep_period.period)
|
||||
dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n");
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: set to uapsd/pps mode\n");
|
||||
}
|
||||
} else if (action == DIS_AUTO_PS) {
|
||||
if (ps_bitmap & BITMAP_AUTO_DS) {
|
||||
@ -1373,12 +1379,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
|
||||
adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
|
||||
|
||||
dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
|
||||
adapter->fw_release_number);
|
||||
adapter->fw_release_number);
|
||||
dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
|
||||
hw_spec->permanent_addr);
|
||||
dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n",
|
||||
hw_spec->permanent_addr);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n",
|
||||
le16_to_cpu(hw_spec->hw_if_version),
|
||||
le16_to_cpu(hw_spec->version));
|
||||
le16_to_cpu(hw_spec->version));
|
||||
|
||||
if (priv->curr_addr[0] == 0xff)
|
||||
memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN);
|
||||
@ -1393,7 +1400,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
|
||||
/* If it's unidentified region code, use the default (USA) */
|
||||
if (i >= MWIFIEX_MAX_REGION_CODE) {
|
||||
adapter->region_code = 0x10;
|
||||
dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n");
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: unknown region code, use default (USA)\n");
|
||||
}
|
||||
|
||||
adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
|
||||
|
@ -117,8 +117,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define BA_STREAM_NOT_ALLOWED 0xff
|
||||
|
||||
#define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \
|
||||
priv->adapter->config_bands & BAND_AN) \
|
||||
&& priv->curr_bss_params.bss_descriptor.bcn_ht_cap)
|
||||
priv->adapter->config_bands & BAND_AN) && \
|
||||
priv->curr_bss_params.bss_descriptor.bcn_ht_cap)
|
||||
#define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\
|
||||
BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS)
|
||||
|
||||
|
@ -35,28 +35,24 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct mwifiex_bss_prio_node *bss_prio;
|
||||
struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl;
|
||||
unsigned long flags;
|
||||
|
||||
bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
|
||||
if (!bss_prio) {
|
||||
dev_err(adapter->dev, "%s: failed to alloc bss_prio\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bss_prio->priv = priv;
|
||||
INIT_LIST_HEAD(&bss_prio->list);
|
||||
if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
|
||||
adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
|
||||
bss_prio;
|
||||
if (!tbl[priv->bss_priority].bss_prio_cur)
|
||||
tbl[priv->bss_priority].bss_prio_cur = bss_prio;
|
||||
|
||||
spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
|
||||
.bss_prio_lock, flags);
|
||||
list_add_tail(&bss_prio->list,
|
||||
&adapter->bss_prio_tbl[priv->bss_priority]
|
||||
.bss_prio_head);
|
||||
spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
|
||||
.bss_prio_lock, flags);
|
||||
spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags);
|
||||
list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head);
|
||||
spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -157,13 +153,13 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
|
||||
ret = mwifiex_alloc_cmd_buffer(adapter);
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
adapter->sleep_cfm =
|
||||
dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
|
||||
+ INTF_HEADER_LEN);
|
||||
+ INTF_HEADER_LEN);
|
||||
|
||||
if (!adapter->sleep_cfm) {
|
||||
dev_err(adapter->dev, "%s: failed to alloc sleep cfm"
|
||||
@ -520,7 +516,7 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur;
|
||||
struct list_head *head;
|
||||
spinlock_t *lock;
|
||||
spinlock_t *lock; /* bss priority lock */
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0; i < adapter->priv_num; ++i) {
|
||||
@ -638,7 +634,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
|
||||
ret = adapter->if_ops.check_fw_status(adapter, poll_num);
|
||||
if (!ret) {
|
||||
dev_notice(adapter->dev,
|
||||
"WLAN FW already running! Skip FW download\n");
|
||||
"WLAN FW already running! Skip FW download\n");
|
||||
goto done;
|
||||
}
|
||||
poll_num = MAX_FIRMWARE_POLL_TRIES;
|
||||
@ -646,8 +642,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
|
||||
/* Check if we are the winner for downloading FW */
|
||||
if (!adapter->winner) {
|
||||
dev_notice(adapter->dev,
|
||||
"Other interface already running!"
|
||||
" Skip FW download\n");
|
||||
"Other intf already running! Skip FW download\n");
|
||||
poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
|
||||
goto poll_fw;
|
||||
}
|
||||
|
@ -52,8 +52,9 @@ mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer)
|
||||
* parameter buffer pointer.
|
||||
*/
|
||||
if (priv->gen_ie_buf_len) {
|
||||
dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n",
|
||||
__func__, priv->gen_ie_buf_len, *buffer);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: %s: append generic ie len %d to %p\n",
|
||||
__func__, priv->gen_ie_buf_len, *buffer);
|
||||
|
||||
/* Wrap the generic IE buffer with a pass through TLV type */
|
||||
ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
|
||||
@ -123,8 +124,9 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
|
||||
|
||||
memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val));
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - "
|
||||
"%016llx\n", __func__, tsf_val, bss_desc->network_tsf);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: %s: TSF offset calc: %016llx - %016llx\n",
|
||||
__func__, tsf_val, bss_desc->network_tsf);
|
||||
|
||||
memcpy(*buffer, &tsf_val, sizeof(tsf_val));
|
||||
*buffer += sizeof(tsf_val);
|
||||
@ -167,7 +169,7 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
|
||||
}
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n",
|
||||
priv->data_rate);
|
||||
priv->data_rate);
|
||||
|
||||
if (!priv->is_data_rate_auto) {
|
||||
while (*ptr) {
|
||||
@ -212,7 +214,7 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
|
||||
card_rates, card_rates_size)) {
|
||||
*out_rates_size = 0;
|
||||
dev_err(priv->adapter->dev, "%s: cannot get common rates\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -248,7 +250,7 @@ mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer)
|
||||
*/
|
||||
if (priv->wapi_ie_len) {
|
||||
dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n",
|
||||
priv->wapi_ie_len, *buffer);
|
||||
priv->wapi_ie_len, *buffer);
|
||||
|
||||
/* Wrap the generic IE buffer with a pass through TLV type */
|
||||
ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE);
|
||||
@ -293,10 +295,10 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv,
|
||||
le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF);
|
||||
rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]);
|
||||
rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len)
|
||||
& 0x00FF);
|
||||
& 0x00FF);
|
||||
if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2))
|
||||
memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2],
|
||||
le16_to_cpu(rsn_ie_tlv->header.len));
|
||||
le16_to_cpu(rsn_ie_tlv->header.len));
|
||||
else
|
||||
return -1;
|
||||
|
||||
@ -379,7 +381,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID);
|
||||
ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len);
|
||||
memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid,
|
||||
le16_to_cpu(ssid_tlv->header.len));
|
||||
le16_to_cpu(ssid_tlv->header.len));
|
||||
pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len);
|
||||
|
||||
phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
|
||||
@ -411,7 +413,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
memcpy(rates_tlv->rates, rates, rates_size);
|
||||
pos += sizeof(rates_tlv->header) + rates_size;
|
||||
dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n",
|
||||
rates_size);
|
||||
rates_size);
|
||||
|
||||
/* Add the Authentication type to be used for Auth frames */
|
||||
auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
|
||||
@ -425,12 +427,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
|
||||
pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
|
||||
|
||||
if (IS_SUPPORT_MULTI_BANDS(priv->adapter)
|
||||
&& !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
|
||||
&& (!bss_desc->disable_11n)
|
||||
&& (priv->adapter->config_bands & BAND_GN
|
||||
|| priv->adapter->config_bands & BAND_AN)
|
||||
&& (bss_desc->bcn_ht_cap)
|
||||
if (IS_SUPPORT_MULTI_BANDS(priv->adapter) &&
|
||||
!(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
|
||||
(!bss_desc->disable_11n) &&
|
||||
(priv->adapter->config_bands & BAND_GN ||
|
||||
priv->adapter->config_bands & BAND_AN) &&
|
||||
(bss_desc->bcn_ht_cap)
|
||||
)
|
||||
) {
|
||||
/* Append a channel TLV for the channel the attempted AP was
|
||||
@ -445,13 +447,13 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
chan_tlv->chan_scan_param[0].chan_number =
|
||||
(bss_desc->phy_param_set.ds_param_set.current_chan);
|
||||
dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n",
|
||||
chan_tlv->chan_scan_param[0].chan_number);
|
||||
chan_tlv->chan_scan_param[0].chan_number);
|
||||
|
||||
chan_tlv->chan_scan_param[0].radio_type =
|
||||
mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n",
|
||||
chan_tlv->chan_scan_param[0].radio_type);
|
||||
chan_tlv->chan_scan_param[0].radio_type);
|
||||
pos += sizeof(chan_tlv->header) +
|
||||
sizeof(struct mwifiex_chan_scan_param_set);
|
||||
}
|
||||
@ -464,10 +466,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
|
||||
&& (!bss_desc->disable_11n)
|
||||
&& (priv->adapter->config_bands & BAND_GN
|
||||
|| priv->adapter->config_bands & BAND_AN))
|
||||
if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
|
||||
(!bss_desc->disable_11n) &&
|
||||
(priv->adapter->config_bands & BAND_GN ||
|
||||
priv->adapter->config_bands & BAND_AN))
|
||||
mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
|
||||
|
||||
/* Append vendor specific IE TLV */
|
||||
@ -493,7 +495,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
|
||||
|
||||
tmp_cap &= CAPINFO_MASK;
|
||||
dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
|
||||
tmp_cap, CAPINFO_MASK);
|
||||
tmp_cap, CAPINFO_MASK);
|
||||
assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
|
||||
|
||||
return 0;
|
||||
@ -573,17 +575,17 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
|
||||
|
||||
priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
|
||||
sizeof(priv->assoc_rsp_buf));
|
||||
sizeof(priv->assoc_rsp_buf));
|
||||
|
||||
memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
|
||||
|
||||
if (le16_to_cpu(assoc_rsp->status_code)) {
|
||||
priv->adapter->dbg.num_cmd_assoc_failure++;
|
||||
dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, "
|
||||
"status code = %d, error = 0x%x, a_id = 0x%x\n",
|
||||
le16_to_cpu(assoc_rsp->status_code),
|
||||
le16_to_cpu(assoc_rsp->cap_info_bitmap),
|
||||
le16_to_cpu(assoc_rsp->a_id));
|
||||
dev_err(priv->adapter->dev,
|
||||
"ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n",
|
||||
le16_to_cpu(assoc_rsp->status_code),
|
||||
le16_to_cpu(assoc_rsp->cap_info_bitmap),
|
||||
le16_to_cpu(assoc_rsp->a_id));
|
||||
|
||||
ret = le16_to_cpu(assoc_rsp->status_code);
|
||||
goto done;
|
||||
@ -600,7 +602,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
bss_desc = priv->attempted_bss_desc;
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n",
|
||||
bss_desc->ssid.ssid);
|
||||
bss_desc->ssid.ssid);
|
||||
|
||||
/* Make a copy of current BSSID descriptor */
|
||||
memcpy(&priv->curr_bss_params.bss_descriptor,
|
||||
@ -617,8 +619,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
else
|
||||
priv->curr_bss_params.wmm_enabled = false;
|
||||
|
||||
if ((priv->wmm_required || bss_desc->bcn_ht_cap)
|
||||
&& priv->curr_bss_params.wmm_enabled)
|
||||
if ((priv->wmm_required || bss_desc->bcn_ht_cap) &&
|
||||
priv->curr_bss_params.wmm_enabled)
|
||||
priv->wmm_enabled = true;
|
||||
else
|
||||
priv->wmm_enabled = false;
|
||||
@ -631,7 +633,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
|
||||
IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
|
||||
priv->curr_pkt_filter);
|
||||
priv->curr_pkt_filter);
|
||||
if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
|
||||
priv->wpa_is_gtk_set = false;
|
||||
|
||||
@ -755,7 +757,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len);
|
||||
|
||||
dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n",
|
||||
adhoc_start->ssid);
|
||||
adhoc_start->ssid);
|
||||
|
||||
memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
|
||||
memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len);
|
||||
@ -777,12 +779,11 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
|
||||
adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
|
||||
|
||||
if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
|
||||
(priv, adapter->adhoc_start_band, (u16)
|
||||
priv->adhoc_channel)) {
|
||||
if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band,
|
||||
(u16) priv->adhoc_channel, 0)) {
|
||||
struct mwifiex_chan_freq_power *cfp;
|
||||
cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
|
||||
adapter->adhoc_start_band, FIRST_VALID_CHANNEL);
|
||||
cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band,
|
||||
FIRST_VALID_CHANNEL, 0);
|
||||
if (cfp)
|
||||
priv->adhoc_channel = (u8) cfp->channel;
|
||||
}
|
||||
@ -793,7 +794,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
|
||||
priv->adhoc_channel);
|
||||
priv->adhoc_channel);
|
||||
|
||||
priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
|
||||
priv->curr_bss_params.band = adapter->adhoc_start_band;
|
||||
@ -814,7 +815,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
|
||||
adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
|
||||
adhoc_start->ss_param_set.ibss_param_set.atim_window
|
||||
= cpu_to_le16(priv->atim_window);
|
||||
= cpu_to_le16(priv->atim_window);
|
||||
memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
|
||||
sizeof(union ieee_types_ss_param_set));
|
||||
|
||||
@ -842,10 +843,10 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
if ((adapter->adhoc_start_band & BAND_G) &&
|
||||
(priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
|
||||
if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&priv->curr_pkt_filter)) {
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&priv->curr_pkt_filter)) {
|
||||
dev_err(adapter->dev,
|
||||
"ADHOC_S_CMD: G Protection config failed\n");
|
||||
"ADHOC_S_CMD: G Protection config failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -861,8 +862,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
&adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
|
||||
|
||||
dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n",
|
||||
adhoc_start->data_rate[0], adhoc_start->data_rate[1],
|
||||
adhoc_start->data_rate[2], adhoc_start->data_rate[3]);
|
||||
adhoc_start->data_rate[0], adhoc_start->data_rate[1],
|
||||
adhoc_start->data_rate[2], adhoc_start->data_rate[3]);
|
||||
|
||||
dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
|
||||
|
||||
@ -879,12 +880,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
(u8) priv->curr_bss_params.bss_descriptor.channel;
|
||||
|
||||
dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n",
|
||||
chan_tlv->chan_scan_param[0].chan_number);
|
||||
chan_tlv->chan_scan_param[0].chan_number);
|
||||
|
||||
chan_tlv->chan_scan_param[0].radio_type
|
||||
= mwifiex_band_to_radio_type(priv->curr_bss_params.band);
|
||||
if (adapter->adhoc_start_band & BAND_GN
|
||||
|| adapter->adhoc_start_band & BAND_AN) {
|
||||
if (adapter->adhoc_start_band & BAND_GN ||
|
||||
adapter->adhoc_start_band & BAND_AN) {
|
||||
if (adapter->sec_chan_offset ==
|
||||
IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
|
||||
chan_tlv->chan_scan_param[0].radio_type |=
|
||||
@ -895,7 +896,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
(IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4);
|
||||
}
|
||||
dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n",
|
||||
chan_tlv->chan_scan_param[0].radio_type);
|
||||
chan_tlv->chan_scan_param[0].radio_type);
|
||||
pos += sizeof(chan_tlv->header) +
|
||||
sizeof(struct mwifiex_chan_scan_param_set);
|
||||
cmd_append_size +=
|
||||
@ -926,15 +927,14 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
mwifiex_fill_cap_info(priv, radio_type, ht_cap);
|
||||
|
||||
pos += sizeof(struct mwifiex_ie_types_htcap);
|
||||
cmd_append_size +=
|
||||
sizeof(struct mwifiex_ie_types_htcap);
|
||||
cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
|
||||
|
||||
/* Fill HT INFORMATION */
|
||||
ht_info = (struct mwifiex_ie_types_htinfo *) pos;
|
||||
memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo));
|
||||
ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION);
|
||||
ht_info->header.len =
|
||||
cpu_to_le16(sizeof(struct ieee80211_ht_info));
|
||||
cpu_to_le16(sizeof(struct ieee80211_ht_info));
|
||||
|
||||
ht_info->ht_info.control_chan =
|
||||
(u8) priv->curr_bss_params.bss_descriptor.channel;
|
||||
@ -948,12 +948,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
|
||||
ht_info->ht_info.basic_set[0] = 0xff;
|
||||
pos += sizeof(struct mwifiex_ie_types_htinfo);
|
||||
cmd_append_size +=
|
||||
sizeof(struct mwifiex_ie_types_htinfo);
|
||||
sizeof(struct mwifiex_ie_types_htinfo);
|
||||
}
|
||||
|
||||
cmd->size = cpu_to_le16((u16)
|
||||
(sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
|
||||
+ S_DS_GEN + cmd_append_size));
|
||||
cmd->size =
|
||||
cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
|
||||
+ S_DS_GEN + cmd_append_size));
|
||||
|
||||
if (adapter->adhoc_start_band == BAND_B)
|
||||
tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
|
||||
@ -1006,10 +1006,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
|
||||
curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
|
||||
|
||||
if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&curr_pkt_filter)) {
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&curr_pkt_filter)) {
|
||||
dev_err(priv->adapter->dev,
|
||||
"ADHOC_J_CMD: G Protection config failed\n");
|
||||
"ADHOC_J_CMD: G Protection config failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1040,13 +1040,14 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
|
||||
|
||||
tmp_cap &= CAPINFO_MASK;
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X"
|
||||
" CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
|
||||
tmp_cap, CAPINFO_MASK);
|
||||
|
||||
/* Information on BSSID descriptor passed to FW */
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n",
|
||||
adhoc_join->bss_descriptor.bssid,
|
||||
adhoc_join->bss_descriptor.ssid);
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n",
|
||||
adhoc_join->bss_descriptor.bssid,
|
||||
adhoc_join->bss_descriptor.ssid);
|
||||
|
||||
for (i = 0; bss_desc->supported_rates[i] &&
|
||||
i < MWIFIEX_SUPPORTED_RATES;
|
||||
@ -1083,18 +1084,18 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
|
||||
sizeof(struct mwifiex_chan_scan_param_set));
|
||||
chan_tlv->chan_scan_param[0].chan_number =
|
||||
(bss_desc->phy_param_set.ds_param_set.current_chan);
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n",
|
||||
chan_tlv->chan_scan_param[0].chan_number);
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n",
|
||||
chan_tlv->chan_scan_param[0].chan_number);
|
||||
|
||||
chan_tlv->chan_scan_param[0].radio_type =
|
||||
mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n",
|
||||
chan_tlv->chan_scan_param[0].radio_type);
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n",
|
||||
chan_tlv->chan_scan_param[0].radio_type);
|
||||
pos += sizeof(chan_tlv->header) +
|
||||
sizeof(struct mwifiex_chan_scan_param_set);
|
||||
sizeof(struct mwifiex_chan_scan_param_set);
|
||||
cmd_append_size += sizeof(chan_tlv->header) +
|
||||
sizeof(struct mwifiex_chan_scan_param_set);
|
||||
sizeof(struct mwifiex_chan_scan_param_set);
|
||||
}
|
||||
|
||||
if (priv->sec_info.wpa_enabled)
|
||||
@ -1111,9 +1112,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
|
||||
cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
|
||||
MWIFIEX_VSIE_MASK_ADHOC, &pos);
|
||||
|
||||
cmd->size = cpu_to_le16((u16)
|
||||
(sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
|
||||
+ S_DS_GEN + cmd_append_size));
|
||||
cmd->size = cpu_to_le16
|
||||
((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
|
||||
+ S_DS_GEN + cmd_append_size));
|
||||
|
||||
adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
|
||||
|
||||
@ -1158,7 +1159,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
|
||||
|
||||
if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n",
|
||||
bss_desc->ssid.ssid);
|
||||
bss_desc->ssid.ssid);
|
||||
|
||||
/* Update the created network descriptor with the new BSSID */
|
||||
memcpy(bss_desc->mac_address,
|
||||
@ -1171,7 +1172,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
|
||||
* If BSSID has changed use SSID to compare instead of BSSID
|
||||
*/
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n",
|
||||
bss_desc->ssid.ssid);
|
||||
bss_desc->ssid.ssid);
|
||||
|
||||
/*
|
||||
* Make a copy of current BSSID descriptor, only needed for
|
||||
@ -1185,9 +1186,9 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n",
|
||||
priv->adhoc_channel);
|
||||
priv->adhoc_channel);
|
||||
dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n",
|
||||
priv->curr_bss_params.bss_descriptor.mac_address);
|
||||
priv->curr_bss_params.bss_descriptor.mac_address);
|
||||
|
||||
if (!netif_carrier_ok(priv->netdev))
|
||||
netif_carrier_on(priv->netdev);
|
||||
@ -1250,9 +1251,9 @@ mwifiex_adhoc_start(struct mwifiex_private *priv,
|
||||
dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
|
||||
priv->adhoc_channel);
|
||||
dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
|
||||
priv->curr_bss_params.bss_descriptor.channel);
|
||||
priv->curr_bss_params.bss_descriptor.channel);
|
||||
dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
|
||||
priv->curr_bss_params.band);
|
||||
priv->curr_bss_params.band);
|
||||
|
||||
return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START,
|
||||
HostCmd_ACT_GEN_SET, 0, adhoc_ssid);
|
||||
@ -1268,13 +1269,13 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n",
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid);
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid);
|
||||
dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n",
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
|
||||
dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n",
|
||||
bss_desc->ssid.ssid);
|
||||
dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n",
|
||||
bss_desc->ssid.ssid_len);
|
||||
bss_desc->ssid.ssid_len);
|
||||
|
||||
/* Check if the requested SSID is already joined */
|
||||
if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
|
||||
@ -1288,9 +1289,9 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
|
||||
priv->curr_bss_params.bss_descriptor.channel);
|
||||
priv->curr_bss_params.bss_descriptor.channel);
|
||||
dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
|
||||
priv->curr_bss_params.band);
|
||||
priv->curr_bss_params.band);
|
||||
|
||||
return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
|
||||
HostCmd_ACT_GEN_SET, 0, bss_desc);
|
||||
|
@ -64,11 +64,10 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
|
||||
adapter->priv_num = 0;
|
||||
|
||||
/* Allocate memory for private structure */
|
||||
adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private),
|
||||
GFP_KERNEL);
|
||||
adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL);
|
||||
if (!adapter->priv[0]) {
|
||||
dev_err(adapter->dev, "%s: failed to alloc priv[0]\n",
|
||||
__func__);
|
||||
dev_err(adapter->dev,
|
||||
"%s: failed to alloc priv[0]\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -169,8 +168,8 @@ process_start:
|
||||
if ((adapter->ps_state == PS_STATE_SLEEP) &&
|
||||
(adapter->pm_wakeup_card_req &&
|
||||
!adapter->pm_wakeup_fw_try) &&
|
||||
(is_command_pending(adapter)
|
||||
|| !mwifiex_wmm_lists_empty(adapter))) {
|
||||
(is_command_pending(adapter) ||
|
||||
!mwifiex_wmm_lists_empty(adapter))) {
|
||||
adapter->pm_wakeup_fw_try = true;
|
||||
adapter->if_ops.wakeup(adapter);
|
||||
continue;
|
||||
@ -187,10 +186,10 @@ process_start:
|
||||
adapter->tx_lock_flag)
|
||||
break;
|
||||
|
||||
if (adapter->scan_processing || adapter->data_sent
|
||||
|| mwifiex_wmm_lists_empty(adapter)) {
|
||||
if (adapter->cmd_sent || adapter->curr_cmd
|
||||
|| (!is_command_pending(adapter)))
|
||||
if (adapter->scan_processing || adapter->data_sent ||
|
||||
mwifiex_wmm_lists_empty(adapter)) {
|
||||
if (adapter->cmd_sent || adapter->curr_cmd ||
|
||||
(!is_command_pending(adapter)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -223,10 +222,10 @@ process_start:
|
||||
/* * The ps_state may have been changed during processing of
|
||||
* Sleep Request event.
|
||||
*/
|
||||
if ((adapter->ps_state == PS_STATE_SLEEP)
|
||||
|| (adapter->ps_state == PS_STATE_PRE_SLEEP)
|
||||
|| (adapter->ps_state == PS_STATE_SLEEP_CFM)
|
||||
|| adapter->tx_lock_flag)
|
||||
if ((adapter->ps_state == PS_STATE_SLEEP) ||
|
||||
(adapter->ps_state == PS_STATE_PRE_SLEEP) ||
|
||||
(adapter->ps_state == PS_STATE_SLEEP_CFM) ||
|
||||
adapter->tx_lock_flag)
|
||||
continue;
|
||||
|
||||
if (!adapter->cmd_sent && !adapter->curr_cmd) {
|
||||
@ -249,8 +248,8 @@ process_start:
|
||||
}
|
||||
|
||||
if (adapter->delay_null_pkt && !adapter->cmd_sent &&
|
||||
!adapter->curr_cmd && !is_command_pending(adapter)
|
||||
&& mwifiex_wmm_lists_empty(adapter)) {
|
||||
!adapter->curr_cmd && !is_command_pending(adapter) &&
|
||||
mwifiex_wmm_lists_empty(adapter)) {
|
||||
if (!mwifiex_send_null_packet
|
||||
(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
|
||||
MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
|
||||
@ -371,7 +370,7 @@ mwifiex_fill_buffer(struct sk_buff *skb)
|
||||
iph = ip_hdr(skb);
|
||||
tid = IPTOS_PREC(iph->tos);
|
||||
pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
|
||||
eth->h_proto, tid, skb->priority);
|
||||
eth->h_proto, tid, skb->priority);
|
||||
break;
|
||||
case __constant_htons(ETH_P_ARP):
|
||||
pr_debug("data: ARP packet: %04x\n", eth->h_proto);
|
||||
@ -425,7 +424,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
struct mwifiex_txinfo *tx_info;
|
||||
|
||||
dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
|
||||
jiffies, priv->bss_type, priv->bss_num);
|
||||
jiffies, priv->bss_type, priv->bss_num);
|
||||
|
||||
if (priv->adapter->surprise_removed) {
|
||||
kfree_skb(skb);
|
||||
@ -441,7 +440,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"data: Tx: insufficient skb headroom %d\n",
|
||||
skb_headroom(skb));
|
||||
skb_headroom(skb));
|
||||
/* Insufficient skb headroom - allocate a new skb */
|
||||
new_skb =
|
||||
skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
|
||||
@ -454,7 +453,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
kfree_skb(skb);
|
||||
skb = new_skb;
|
||||
dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
|
||||
skb_headroom(skb));
|
||||
skb_headroom(skb));
|
||||
}
|
||||
|
||||
tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
@ -494,8 +493,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
|
||||
if (!ret)
|
||||
memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
|
||||
else
|
||||
dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
|
||||
"\n", ret);
|
||||
dev_err(priv->adapter->dev,
|
||||
"set mac address failed: ret=%d\n", ret);
|
||||
|
||||
memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
|
||||
|
||||
@ -533,7 +532,7 @@ mwifiex_tx_timeout(struct net_device *dev)
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n",
|
||||
jiffies, priv->bss_type, priv->bss_num);
|
||||
jiffies, priv->bss_type, priv->bss_num);
|
||||
mwifiex_set_trans_start(dev);
|
||||
priv->num_tx_timeout++;
|
||||
}
|
||||
@ -704,7 +703,7 @@ mwifiex_add_card(void *card, struct semaphore *sem,
|
||||
rtnl_lock();
|
||||
/* Create station interface by default */
|
||||
if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
|
||||
NL80211_IFTYPE_STATION, NULL, NULL)) {
|
||||
NL80211_IFTYPE_STATION, NULL, NULL)) {
|
||||
rtnl_unlock();
|
||||
dev_err(adapter->dev, "cannot create default station"
|
||||
" interface\n");
|
||||
@ -781,7 +780,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
|
||||
if (priv && priv->netdev) {
|
||||
if (!netif_queue_stopped(priv->netdev))
|
||||
mwifiex_stop_net_dev_queue(priv->netdev,
|
||||
adapter);
|
||||
adapter);
|
||||
if (netif_carrier_ok(priv->netdev))
|
||||
netif_carrier_off(priv->netdev);
|
||||
}
|
||||
|
@ -462,9 +462,9 @@ struct mwifiex_private {
|
||||
};
|
||||
|
||||
enum mwifiex_ba_status {
|
||||
BA_STREAM_NOT_SETUP = 0,
|
||||
BA_STREAM_SETUP_INPROGRESS,
|
||||
BA_STREAM_SETUP_COMPLETE
|
||||
BA_SETUP_NONE = 0,
|
||||
BA_SETUP_INPROGRESS,
|
||||
BA_SETUP_COMPLETE
|
||||
};
|
||||
|
||||
struct mwifiex_tx_ba_stream_tbl {
|
||||
@ -771,13 +771,8 @@ int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
|
||||
int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp);
|
||||
int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd);
|
||||
struct mwifiex_chan_freq_power *
|
||||
mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
|
||||
struct mwifiex_private *priv,
|
||||
u8 band, u16 channel);
|
||||
struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
|
||||
struct mwifiex_private *priv,
|
||||
u8 band, u32 freq);
|
||||
struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv,
|
||||
u8 band, u16 channel, u32 freq);
|
||||
u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index,
|
||||
u8 ht_info);
|
||||
u32 mwifiex_find_freq_from_band_chan(u8, u8);
|
||||
@ -846,8 +841,8 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
if ((adapter->priv[i]->bss_num == bss_num)
|
||||
&& (adapter->priv[i]->bss_type == bss_type))
|
||||
if ((adapter->priv[i]->bss_num == bss_num) &&
|
||||
(adapter->priv[i]->bss_type == bss_type))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
|
||||
struct pcie_service_card *card;
|
||||
|
||||
pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
|
||||
pdev->vendor, pdev->device, pdev->revision);
|
||||
pdev->vendor, pdev->device, pdev->revision);
|
||||
|
||||
card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
|
||||
if (!card)
|
||||
@ -108,6 +108,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct pcie_service_card *card;
|
||||
struct mwifiex_adapter *adapter;
|
||||
struct mwifiex_private *priv;
|
||||
int i;
|
||||
|
||||
card = pci_get_drvdata(pdev);
|
||||
@ -126,16 +127,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++)
|
||||
if ((GET_BSS_ROLE(adapter->priv[i]) ==
|
||||
MWIFIEX_BSS_ROLE_STA) &&
|
||||
adapter->priv[i]->media_connected)
|
||||
MWIFIEX_BSS_ROLE_STA) &&
|
||||
adapter->priv[i]->media_connected)
|
||||
mwifiex_deauthenticate(adapter->priv[i], NULL);
|
||||
|
||||
mwifiex_disable_auto_ds(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_ANY));
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
|
||||
mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_ANY),
|
||||
MWIFIEX_FUNC_SHUTDOWN);
|
||||
mwifiex_disable_auto_ds(priv);
|
||||
|
||||
mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
|
||||
}
|
||||
|
||||
mwifiex_remove_card(card->adapter, &add_remove_card_sem);
|
||||
@ -219,7 +219,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev)
|
||||
netif_carrier_on(adapter->priv[i]->netdev);
|
||||
|
||||
mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
|
||||
MWIFIEX_ASYNC_CMD);
|
||||
MWIFIEX_ASYNC_CMD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -286,7 +286,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
|
||||
|
||||
while (mwifiex_pcie_ok_to_access_hw(adapter)) {
|
||||
i++;
|
||||
udelay(10);
|
||||
usleep_range(10, 20);
|
||||
/* 50ms max wait */
|
||||
if (i == 50000)
|
||||
break;
|
||||
@ -378,26 +378,26 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
|
||||
/* allocate shared memory for the BD ring and divide the same in to
|
||||
several descriptors */
|
||||
card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
|
||||
MWIFIEX_MAX_TXRX_BD;
|
||||
MWIFIEX_MAX_TXRX_BD;
|
||||
dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n",
|
||||
card->txbd_ring_size);
|
||||
card->txbd_ring_size);
|
||||
card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL);
|
||||
if (!card->txbd_ring_vbase) {
|
||||
dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n");
|
||||
dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase);
|
||||
|
||||
dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x,"
|
||||
"len: %x\n", card->txbd_ring_vbase,
|
||||
(u32)card->txbd_ring_pbase,
|
||||
(u32)((u64)card->txbd_ring_pbase >> 32),
|
||||
card->txbd_ring_size);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n",
|
||||
card->txbd_ring_vbase, (u32)card->txbd_ring_pbase,
|
||||
(u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size);
|
||||
|
||||
for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
|
||||
card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
|
||||
(card->txbd_ring_vbase +
|
||||
(sizeof(struct mwifiex_pcie_buf_desc) * i));
|
||||
(card->txbd_ring_vbase +
|
||||
(sizeof(struct mwifiex_pcie_buf_desc)
|
||||
* i));
|
||||
|
||||
/* Allocate buffer here so that firmware can DMA data from it */
|
||||
skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
|
||||
@ -410,10 +410,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter)
|
||||
|
||||
skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
|
||||
dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, "
|
||||
"buf_base: %p, buf_pbase: %#x:%x, "
|
||||
"buf_len: %#x\n", skb, skb->data,
|
||||
(u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)),
|
||||
skb->len);
|
||||
"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
|
||||
skb, skb->data, (u32)*buf_pa,
|
||||
(u32)(((u64)*buf_pa >> 32)), skb->len);
|
||||
|
||||
card->tx_buf_list[i] = skb;
|
||||
card->txbd_ring[i]->paddr = *buf_pa;
|
||||
@ -467,9 +466,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
|
||||
card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
|
||||
|
||||
card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
|
||||
MWIFIEX_MAX_TXRX_BD;
|
||||
MWIFIEX_MAX_TXRX_BD;
|
||||
dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n",
|
||||
card->rxbd_ring_size);
|
||||
card->rxbd_ring_size);
|
||||
card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL);
|
||||
if (!card->rxbd_ring_vbase) {
|
||||
dev_err(adapter->dev, "Unable to allocate buffer for "
|
||||
@ -478,21 +477,23 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase);
|
||||
|
||||
dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x,"
|
||||
"len: %#x\n", card->rxbd_ring_vbase,
|
||||
(u32)card->rxbd_ring_pbase,
|
||||
(u32)((u64)card->rxbd_ring_pbase >> 32),
|
||||
card->rxbd_ring_size);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n",
|
||||
card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase,
|
||||
(u32)((u64)card->rxbd_ring_pbase >> 32),
|
||||
card->rxbd_ring_size);
|
||||
|
||||
for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
|
||||
card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
|
||||
(card->rxbd_ring_vbase +
|
||||
(sizeof(struct mwifiex_pcie_buf_desc) * i));
|
||||
(card->rxbd_ring_vbase +
|
||||
(sizeof(struct mwifiex_pcie_buf_desc)
|
||||
* i));
|
||||
|
||||
/* Allocate skb here so that firmware can DMA data from it */
|
||||
skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
|
||||
if (!skb) {
|
||||
dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n");
|
||||
dev_err(adapter->dev,
|
||||
"Unable to allocate skb for RX ring.\n");
|
||||
kfree(card->rxbd_ring_vbase);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -500,10 +501,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
|
||||
skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE);
|
||||
|
||||
dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, "
|
||||
"buf_base: %p, buf_pbase: %#x:%x, "
|
||||
"buf_len: %#x\n", skb, skb->data,
|
||||
(u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
|
||||
skb->len);
|
||||
"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
|
||||
skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
|
||||
skb->len);
|
||||
|
||||
card->rx_buf_list[i] = skb;
|
||||
card->rxbd_ring[i]->paddr = *buf_pa;
|
||||
@ -560,32 +560,34 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
|
||||
card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND;
|
||||
|
||||
card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) *
|
||||
MWIFIEX_MAX_EVT_BD;
|
||||
MWIFIEX_MAX_EVT_BD;
|
||||
dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n",
|
||||
card->evtbd_ring_size);
|
||||
card->evtbd_ring_size);
|
||||
card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL);
|
||||
if (!card->evtbd_ring_vbase) {
|
||||
dev_err(adapter->dev, "Unable to allocate buffer. "
|
||||
"Terminating download\n");
|
||||
dev_err(adapter->dev,
|
||||
"Unable to allocate buffer. Terminating download\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase);
|
||||
|
||||
dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, "
|
||||
"pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase,
|
||||
(u32)card->evtbd_ring_pbase,
|
||||
(u32)((u64)card->evtbd_ring_pbase >> 32),
|
||||
card->evtbd_ring_size);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n",
|
||||
card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase,
|
||||
(u32)((u64)card->evtbd_ring_pbase >> 32),
|
||||
card->evtbd_ring_size);
|
||||
|
||||
for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) {
|
||||
card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *)
|
||||
(card->evtbd_ring_vbase +
|
||||
(sizeof(struct mwifiex_pcie_buf_desc) * i));
|
||||
(card->evtbd_ring_vbase +
|
||||
(sizeof(struct mwifiex_pcie_buf_desc)
|
||||
* i));
|
||||
|
||||
/* Allocate skb here so that firmware can DMA data from it */
|
||||
skb = dev_alloc_skb(MAX_EVENT_SIZE);
|
||||
if (!skb) {
|
||||
dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n");
|
||||
dev_err(adapter->dev,
|
||||
"Unable to allocate skb for EVENT buf.\n");
|
||||
kfree(card->evtbd_ring_vbase);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -593,10 +595,9 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
|
||||
skb_put(skb, MAX_EVENT_SIZE);
|
||||
|
||||
dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, "
|
||||
"buf_base: %p, buf_pbase: %#x:%x, "
|
||||
"buf_len: %#x\n", skb, skb->data,
|
||||
(u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
|
||||
skb->len);
|
||||
"buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n",
|
||||
skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32),
|
||||
skb->len);
|
||||
|
||||
card->evt_buf_list[i] = skb;
|
||||
card->evtbd_ring[i]->paddr = *buf_pa;
|
||||
@ -645,8 +646,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
|
||||
/* Allocate memory for receiving command response data */
|
||||
skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE);
|
||||
if (!skb) {
|
||||
dev_err(adapter->dev, "Unable to allocate skb for command "
|
||||
"response data.\n");
|
||||
dev_err(adapter->dev,
|
||||
"Unable to allocate skb for command response data.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
mwifiex_update_sk_buff_pa(skb);
|
||||
@ -657,8 +658,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter)
|
||||
/* Allocate memory for sending command to firmware */
|
||||
skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
|
||||
if (!skb) {
|
||||
dev_err(adapter->dev, "Unable to allocate skb for command "
|
||||
"data.\n");
|
||||
dev_err(adapter->dev,
|
||||
"Unable to allocate skb for command data.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
mwifiex_update_sk_buff_pa(skb);
|
||||
@ -700,8 +701,8 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
|
||||
/* Allocate memory for sleep cookie */
|
||||
skb = dev_alloc_skb(sizeof(u32));
|
||||
if (!skb) {
|
||||
dev_err(adapter->dev, "Unable to allocate skb for sleep "
|
||||
"cookie!\n");
|
||||
dev_err(adapter->dev,
|
||||
"Unable to allocate skb for sleep cookie!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
mwifiex_update_sk_buff_pa(skb);
|
||||
@ -711,7 +712,7 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter)
|
||||
*(u32 *)skb->data = FW_AWAKE_COOKIE;
|
||||
|
||||
dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n",
|
||||
*((u32 *)skb->data));
|
||||
*((u32 *)skb->data));
|
||||
|
||||
/* Save the sleep cookie */
|
||||
card->sleep_cookie = skb;
|
||||
@ -755,15 +756,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
|
||||
/* Read the TX ring read pointer set by firmware */
|
||||
if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) {
|
||||
dev_err(adapter->dev, "SEND DATA: failed to read "
|
||||
"REG_TXBD_RDPTR\n");
|
||||
dev_err(adapter->dev,
|
||||
"SEND DATA: failed to read REG_TXBD_RDPTR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK;
|
||||
|
||||
dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr,
|
||||
card->txbd_wrptr);
|
||||
card->txbd_wrptr);
|
||||
if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) !=
|
||||
(rdptr & MWIFIEX_TXBD_MASK)) ||
|
||||
((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) !=
|
||||
@ -795,32 +796,31 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
|
||||
/* Write the TX ring write pointer in to REG_TXBD_WRPTR */
|
||||
if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR,
|
||||
card->txbd_wrptr)) {
|
||||
dev_err(adapter->dev, "SEND DATA: failed to write "
|
||||
"REG_TXBD_WRPTR\n");
|
||||
card->txbd_wrptr)) {
|
||||
dev_err(adapter->dev,
|
||||
"SEND DATA: failed to write REG_TXBD_WRPTR\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send the TX ready interrupt */
|
||||
if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
|
||||
CPU_INTR_DNLD_RDY)) {
|
||||
dev_err(adapter->dev, "SEND DATA: failed to assert "
|
||||
"door-bell interrupt.\n");
|
||||
dev_err(adapter->dev,
|
||||
"SEND DATA: failed to assert door-bell intr\n");
|
||||
return -1;
|
||||
}
|
||||
dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: "
|
||||
"%#x> and sent packet to firmware "
|
||||
"successfully\n", rdptr,
|
||||
card->txbd_wrptr);
|
||||
"%#x> and sent packet to firmware successfully\n",
|
||||
rdptr, card->txbd_wrptr);
|
||||
} else {
|
||||
dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore "
|
||||
"packets to firmware\n");
|
||||
dev_dbg(adapter->dev,
|
||||
"info: TX Ring full, can't send packets to fw\n");
|
||||
adapter->data_sent = true;
|
||||
/* Send the TX ready interrupt */
|
||||
if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
|
||||
CPU_INTR_DNLD_RDY))
|
||||
dev_err(adapter->dev, "SEND DATA: failed to assert "
|
||||
"door-bell interrupt\n");
|
||||
dev_err(adapter->dev,
|
||||
"SEND DATA: failed to assert door-bell intr\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@ -840,8 +840,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Read the RX ring Write pointer set by firmware */
|
||||
if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
|
||||
dev_err(adapter->dev, "RECV DATA: failed to read "
|
||||
"REG_TXBD_RDPTR\n");
|
||||
dev_err(adapter->dev,
|
||||
"RECV DATA: failed to read REG_TXBD_RDPTR\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -859,12 +859,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
|
||||
/* Get data length from interface header -
|
||||
first byte is len, second byte is type */
|
||||
rx_len = *((u16 *)skb_data->data);
|
||||
dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, "
|
||||
"Len=%d\n", card->rxbd_rdptr, wrptr, rx_len);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
|
||||
card->rxbd_rdptr, wrptr, rx_len);
|
||||
skb_tmp = dev_alloc_skb(rx_len);
|
||||
if (!skb_tmp) {
|
||||
dev_dbg(adapter->dev, "info: Failed to alloc skb "
|
||||
"for RX\n");
|
||||
dev_dbg(adapter->dev,
|
||||
"info: Failed to alloc skb for RX\n");
|
||||
ret = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
@ -879,26 +880,26 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
|
||||
MWIFIEX_BD_FLAG_ROLLOVER_IND);
|
||||
}
|
||||
dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n",
|
||||
card->rxbd_rdptr, wrptr);
|
||||
card->rxbd_rdptr, wrptr);
|
||||
|
||||
/* Write the RX ring read pointer in to REG_RXBD_RDPTR */
|
||||
if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR,
|
||||
card->rxbd_rdptr)) {
|
||||
dev_err(adapter->dev, "RECV DATA: failed to "
|
||||
"write REG_RXBD_RDPTR\n");
|
||||
dev_err(adapter->dev,
|
||||
"RECV DATA: failed to write REG_RXBD_RDPTR\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read the RX ring Write pointer set by firmware */
|
||||
if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) {
|
||||
dev_err(adapter->dev, "RECV DATA: failed to read "
|
||||
"REG_TXBD_RDPTR\n");
|
||||
dev_err(adapter->dev,
|
||||
"RECV DATA: failed to read REG_TXBD_RDPTR\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
dev_dbg(adapter->dev, "info: RECV DATA: Received packet from "
|
||||
"firmware successfully\n");
|
||||
dev_dbg(adapter->dev,
|
||||
"info: RECV DATA: Rcvd packet from fw successfully\n");
|
||||
mwifiex_handle_rx_packet(adapter, skb_tmp);
|
||||
}
|
||||
|
||||
@ -917,17 +918,19 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb);
|
||||
|
||||
if (!(skb->data && skb->len && *buf_pa)) {
|
||||
dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, "
|
||||
"%x>\n", __func__, skb->data, skb->len,
|
||||
(u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
|
||||
dev_err(adapter->dev,
|
||||
"Invalid parameter in %s <%p, %#x:%x, %x>\n",
|
||||
__func__, skb->data, skb->len,
|
||||
(u32)*buf_pa, (u32)((u64)*buf_pa >> 32));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write the lower 32bits of the physical address to scratch
|
||||
* register 0 */
|
||||
if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) {
|
||||
dev_err(adapter->dev, "%s: failed to write download command "
|
||||
"to boot code.\n", __func__);
|
||||
dev_err(adapter->dev,
|
||||
"%s: failed to write download command to boot code.\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -935,23 +938,25 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
* register 1 */
|
||||
if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG,
|
||||
(u32)((u64)*buf_pa >> 32))) {
|
||||
dev_err(adapter->dev, "%s: failed to write download command "
|
||||
"to boot code.\n", __func__);
|
||||
dev_err(adapter->dev,
|
||||
"%s: failed to write download command to boot code.\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write the command length to scratch register 2 */
|
||||
if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) {
|
||||
dev_err(adapter->dev, "%s: failed to write command length to "
|
||||
"scratch register 2\n", __func__);
|
||||
dev_err(adapter->dev,
|
||||
"%s: failed to write command len to scratch reg 2\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Ring the door bell */
|
||||
if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
|
||||
CPU_INTR_DOOR_BELL)) {
|
||||
dev_err(adapter->dev, "%s: failed to assert door-bell "
|
||||
"interrupt.\n", __func__);
|
||||
dev_err(adapter->dev,
|
||||
"%s: failed to assert door-bell intr\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -971,14 +976,14 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
|
||||
if (!(skb->data && skb->len)) {
|
||||
dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n",
|
||||
__func__, skb->data, skb->len);
|
||||
__func__, skb->data, skb->len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make sure a command response buffer is available */
|
||||
if (!card->cmdrsp_buf) {
|
||||
dev_err(adapter->dev, "No response buffer available, send "
|
||||
"command failed\n");
|
||||
dev_err(adapter->dev,
|
||||
"No response buffer available, send command failed\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@ -1009,17 +1014,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
/* Write the lower 32bits of the cmdrsp buffer physical
|
||||
address */
|
||||
if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO,
|
||||
(u32)*cmdrsp_buf_pa)) {
|
||||
dev_err(adapter->dev, "Failed to write download command to boot code.\n");
|
||||
(u32)*cmdrsp_buf_pa)) {
|
||||
dev_err(adapter->dev,
|
||||
"Failed to write download cmd to boot code.\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
/* Write the upper 32bits of the cmdrsp buffer physical
|
||||
address */
|
||||
if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI,
|
||||
(u32)((u64)*cmdrsp_buf_pa >> 32))) {
|
||||
dev_err(adapter->dev, "Failed to write download command"
|
||||
" to boot code.\n");
|
||||
(u32)((u64)*cmdrsp_buf_pa >> 32))) {
|
||||
dev_err(adapter->dev,
|
||||
"Failed to write download cmd to boot code.\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -1027,27 +1033,25 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
|
||||
cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf);
|
||||
/* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */
|
||||
if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO,
|
||||
(u32)*cmd_buf_pa)) {
|
||||
dev_err(adapter->dev, "Failed to write download command "
|
||||
"to boot code.\n");
|
||||
if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) {
|
||||
dev_err(adapter->dev,
|
||||
"Failed to write download cmd to boot code.\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
/* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */
|
||||
if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI,
|
||||
(u32)((u64)*cmd_buf_pa >> 32))) {
|
||||
dev_err(adapter->dev, "Failed to write download command "
|
||||
"to boot code.\n");
|
||||
(u32)((u64)*cmd_buf_pa >> 32))) {
|
||||
dev_err(adapter->dev,
|
||||
"Failed to write download cmd to boot code.\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Write the command length to REG_CMD_SIZE */
|
||||
if (mwifiex_write_reg(adapter, REG_CMD_SIZE,
|
||||
card->cmd_buf->len)) {
|
||||
dev_err(adapter->dev, "Failed to write command length to "
|
||||
"REG_CMD_SIZE\n");
|
||||
if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) {
|
||||
dev_err(adapter->dev,
|
||||
"Failed to write cmd len to REG_CMD_SIZE\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -1055,8 +1059,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
|
||||
/* Ring the door bell */
|
||||
if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
|
||||
CPU_INTR_DOOR_BELL)) {
|
||||
dev_err(adapter->dev, "Failed to assert door-bell "
|
||||
"interrupt.\n");
|
||||
dev_err(adapter->dev,
|
||||
"Failed to assert door-bell intr\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -1074,30 +1078,29 @@ done:
|
||||
static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
|
||||
{
|
||||
struct pcie_service_card *card = adapter->card;
|
||||
struct sk_buff *skb = card->cmdrsp_buf;
|
||||
int count = 0;
|
||||
|
||||
dev_dbg(adapter->dev, "info: Rx CMD Response\n");
|
||||
|
||||
if (!adapter->curr_cmd) {
|
||||
skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN);
|
||||
skb_pull(skb, INTF_HEADER_LEN);
|
||||
if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
|
||||
mwifiex_process_sleep_confirm_resp(adapter,
|
||||
card->cmdrsp_buf->data,
|
||||
card->cmdrsp_buf->len);
|
||||
mwifiex_process_sleep_confirm_resp(adapter, skb->data,
|
||||
skb->len);
|
||||
while (mwifiex_pcie_ok_to_access_hw(adapter) &&
|
||||
(count++ < 10))
|
||||
udelay(50);
|
||||
usleep_range(50, 60);
|
||||
} else {
|
||||
dev_err(adapter->dev, "There is no command but "
|
||||
"got cmdrsp\n");
|
||||
dev_err(adapter->dev,
|
||||
"There is no command but got cmdrsp\n");
|
||||
}
|
||||
memcpy(adapter->upld_buf, card->cmdrsp_buf->data,
|
||||
min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER,
|
||||
card->cmdrsp_buf->len));
|
||||
skb_push(card->cmdrsp_buf, INTF_HEADER_LEN);
|
||||
memcpy(adapter->upld_buf, skb->data,
|
||||
min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
|
||||
skb_push(skb, INTF_HEADER_LEN);
|
||||
} else if (mwifiex_pcie_ok_to_access_hw(adapter)) {
|
||||
skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN);
|
||||
adapter->curr_cmd->resp_skb = card->cmdrsp_buf;
|
||||
skb_pull(skb, INTF_HEADER_LEN);
|
||||
adapter->curr_cmd->resp_skb = skb;
|
||||
adapter->cmd_resp_received = true;
|
||||
/* Take the pointer and set it to CMD node and will
|
||||
return in the response complete callback */
|
||||
@ -1107,15 +1110,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
|
||||
will prevent firmware from writing to the same response
|
||||
buffer again. */
|
||||
if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) {
|
||||
dev_err(adapter->dev, "cmd_done: failed to clear "
|
||||
"cmd_rsp address.\n");
|
||||
dev_err(adapter->dev,
|
||||
"cmd_done: failed to clear cmd_rsp_addr_lo\n");
|
||||
return -1;
|
||||
}
|
||||
/* Write the upper 32bits of the cmdrsp buffer physical
|
||||
address */
|
||||
if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) {
|
||||
dev_err(adapter->dev, "cmd_done: failed to clear "
|
||||
"cmd_rsp address.\n");
|
||||
dev_err(adapter->dev,
|
||||
"cmd_done: failed to clear cmd_rsp_addr_hi\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1149,8 +1152,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
|
||||
u32 wrptr, event;
|
||||
|
||||
if (adapter->event_received) {
|
||||
dev_dbg(adapter->dev, "info: Event being processed, "\
|
||||
"do not process this interrupt just yet\n");
|
||||
dev_dbg(adapter->dev, "info: Event being processed, "
|
||||
"do not process this interrupt just yet\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1161,14 +1164,15 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Read the event ring write pointer set by firmware */
|
||||
if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
|
||||
dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n");
|
||||
dev_err(adapter->dev,
|
||||
"EventReady: failed to read REG_EVTBD_WRPTR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>",
|
||||
card->evtbd_rdptr, wrptr);
|
||||
if (((wrptr & MWIFIEX_EVTBD_MASK) !=
|
||||
(card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) ||
|
||||
card->evtbd_rdptr, wrptr);
|
||||
if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr
|
||||
& MWIFIEX_EVTBD_MASK)) ||
|
||||
((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) ==
|
||||
(card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) {
|
||||
struct sk_buff *skb_cmd;
|
||||
@ -1228,13 +1232,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
|
||||
|
||||
if (rdptr >= MWIFIEX_MAX_EVT_BD) {
|
||||
dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n",
|
||||
rdptr);
|
||||
rdptr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Read the event ring write pointer set by firmware */
|
||||
if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) {
|
||||
dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n");
|
||||
dev_err(adapter->dev,
|
||||
"event_complete: failed to read REG_EVTBD_WRPTR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1247,9 +1252,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
|
||||
card->evtbd_ring[rdptr]->flags = 0;
|
||||
skb = NULL;
|
||||
} else {
|
||||
dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at "
|
||||
"index %d, <%p, %p>\n", rdptr,
|
||||
card->evt_buf_list[rdptr], skb);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: ERROR: buf still valid at index %d, <%p, %p>\n",
|
||||
rdptr, card->evt_buf_list[rdptr], skb);
|
||||
}
|
||||
|
||||
if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) {
|
||||
@ -1259,11 +1264,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter,
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>",
|
||||
card->evtbd_rdptr, wrptr);
|
||||
card->evtbd_rdptr, wrptr);
|
||||
|
||||
/* Write the event ring read pointer in to REG_EVTBD_RDPTR */
|
||||
if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) {
|
||||
dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n");
|
||||
dev_err(adapter->dev,
|
||||
"event_complete: failed to read REG_EVTBD_RDPTR\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1297,17 +1303,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
}
|
||||
|
||||
if (!firmware || !firmware_len) {
|
||||
dev_err(adapter->dev, "No firmware image found! "
|
||||
"Terminating download\n");
|
||||
dev_err(adapter->dev,
|
||||
"No firmware image found! Terminating download\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n",
|
||||
firmware_len);
|
||||
firmware_len);
|
||||
|
||||
if (mwifiex_pcie_disable_host_int(adapter)) {
|
||||
dev_err(adapter->dev, "%s: Disabling interrupts"
|
||||
" failed.\n", __func__);
|
||||
dev_err(adapter->dev,
|
||||
"%s: Disabling interrupts failed.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1330,19 +1336,20 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG,
|
||||
&len);
|
||||
if (ret) {
|
||||
dev_warn(adapter->dev, "Failed reading length from boot code\n");
|
||||
dev_warn(adapter->dev,
|
||||
"Failed reading len from boot code\n");
|
||||
goto done;
|
||||
}
|
||||
if (len)
|
||||
break;
|
||||
udelay(10);
|
||||
usleep_range(10, 20);
|
||||
}
|
||||
|
||||
if (!len) {
|
||||
break;
|
||||
} else if (len > MWIFIEX_UPLD_SIZE) {
|
||||
pr_err("FW download failure @ %d, invalid length %d\n",
|
||||
offset, len);
|
||||
offset, len);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -1358,8 +1365,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
goto done;
|
||||
}
|
||||
dev_err(adapter->dev, "FW CRC error indicated by the "
|
||||
"helper: len = 0x%04X, txlen = "
|
||||
"%d\n", len, txlen);
|
||||
"helper: len = 0x%04X, txlen = %d\n",
|
||||
len, txlen);
|
||||
len &= ~BIT(0);
|
||||
/* Setting this to 0 to resend from same offset */
|
||||
txlen = 0;
|
||||
@ -1372,9 +1379,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
|
||||
dev_dbg(adapter->dev, ".");
|
||||
|
||||
tx_blocks =
|
||||
(txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
|
||||
MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;
|
||||
tx_blocks = (txlen +
|
||||
MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) /
|
||||
MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD;
|
||||
|
||||
/* Copy payload to buffer */
|
||||
memmove(skb->data, &firmware[offset], txlen);
|
||||
@ -1385,7 +1392,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
|
||||
/* Send the boot command to device */
|
||||
if (mwifiex_pcie_send_boot_cmd(adapter, skb)) {
|
||||
dev_err(adapter->dev, "Failed to send firmware download command\n");
|
||||
dev_err(adapter->dev,
|
||||
"Failed to send firmware download command\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -1394,8 +1402,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
|
||||
&ireg_intr)) {
|
||||
dev_err(adapter->dev, "%s: Failed to read "
|
||||
"interrupt status during "
|
||||
"fw dnld.\n", __func__);
|
||||
"interrupt status during fw dnld.\n",
|
||||
__func__);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -1405,7 +1413,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
} while (true);
|
||||
|
||||
dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n",
|
||||
offset);
|
||||
offset);
|
||||
|
||||
ret = 0;
|
||||
|
||||
@ -1428,14 +1436,15 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
|
||||
|
||||
/* Mask spurios interrupts */
|
||||
if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK,
|
||||
HOST_INTR_MASK)) {
|
||||
HOST_INTR_MASK)) {
|
||||
dev_warn(adapter->dev, "Write register failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "Setting driver ready signature\n");
|
||||
if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) {
|
||||
dev_err(adapter->dev, "Failed to write driver ready signature\n");
|
||||
dev_err(adapter->dev,
|
||||
"Failed to write driver ready signature\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1466,8 +1475,9 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num)
|
||||
adapter->winner = 1;
|
||||
ret = -1;
|
||||
} else {
|
||||
dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n",
|
||||
ret, adapter->winner);
|
||||
dev_err(adapter->dev,
|
||||
"PCI-E is not the winner <%#x,%d>, exit dnld\n",
|
||||
ret, adapter->winner);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
@ -1510,10 +1520,11 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
|
||||
(adapter->ps_state == PS_STATE_SLEEP)) {
|
||||
mwifiex_pcie_enable_host_int(adapter);
|
||||
if (mwifiex_write_reg(adapter,
|
||||
PCIE_CPU_INT_EVENT,
|
||||
CPU_INTR_SLEEP_CFM_DONE)) {
|
||||
dev_warn(adapter->dev, "Write register"
|
||||
" failed\n");
|
||||
PCIE_CPU_INT_EVENT,
|
||||
CPU_INTR_SLEEP_CFM_DONE)
|
||||
) {
|
||||
dev_warn(adapter->dev,
|
||||
"Write register failed\n");
|
||||
return;
|
||||
|
||||
}
|
||||
@ -1549,7 +1560,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
|
||||
card = (struct pcie_service_card *) pci_get_drvdata(pdev);
|
||||
if (!card || !card->adapter) {
|
||||
pr_debug("info: %s: card=%p adapter=%p\n", __func__, card,
|
||||
card ? card->adapter : NULL);
|
||||
card ? card->adapter : NULL);
|
||||
goto exit;
|
||||
}
|
||||
adapter = card->adapter;
|
||||
@ -1592,7 +1603,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
if (adapter->int_status & HOST_INTR_DNLD_DONE) {
|
||||
adapter->int_status &= ~HOST_INTR_DNLD_DONE;
|
||||
if (adapter->data_sent) {
|
||||
dev_dbg(adapter->dev, "info: DATA sent Interrupt\n");
|
||||
dev_dbg(adapter->dev, "info: DATA sent intr\n");
|
||||
adapter->data_sent = false;
|
||||
}
|
||||
}
|
||||
@ -1614,7 +1625,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
if (adapter->int_status & HOST_INTR_CMD_DONE) {
|
||||
adapter->int_status &= ~HOST_INTR_CMD_DONE;
|
||||
if (adapter->cmd_sent) {
|
||||
dev_dbg(adapter->dev, "info: CMD sent Interrupt\n");
|
||||
dev_dbg(adapter->dev,
|
||||
"info: CMD sent Interrupt\n");
|
||||
adapter->cmd_sent = false;
|
||||
}
|
||||
/* Handle command response */
|
||||
@ -1626,15 +1638,17 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
if (mwifiex_pcie_ok_to_access_hw(adapter)) {
|
||||
if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
|
||||
&pcie_ireg)) {
|
||||
dev_warn(adapter->dev, "Read register failed\n");
|
||||
dev_warn(adapter->dev,
|
||||
"Read register failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
|
||||
if (mwifiex_write_reg(adapter,
|
||||
PCIE_HOST_INT_STATUS, ~pcie_ireg)) {
|
||||
dev_warn(adapter->dev, "Write register"
|
||||
" failed\n");
|
||||
PCIE_HOST_INT_STATUS,
|
||||
~pcie_ireg)) {
|
||||
dev_warn(adapter->dev,
|
||||
"Write register failed\n");
|
||||
return -1;
|
||||
}
|
||||
adapter->int_status |= pcie_ireg;
|
||||
@ -1644,7 +1658,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
}
|
||||
dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
|
||||
adapter->cmd_sent, adapter->data_sent);
|
||||
adapter->cmd_sent, adapter->data_sent);
|
||||
mwifiex_pcie_enable_host_int(adapter);
|
||||
|
||||
return 0;
|
||||
@ -1735,8 +1749,9 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter)
|
||||
goto err_iomap2;
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: "
|
||||
"%p\n", card->pci_mmap, card->pci_mmap1);
|
||||
dev_dbg(adapter->dev,
|
||||
"PCI memory map Virt0: %p PCI memory map Virt2: %p\n",
|
||||
card->pci_mmap, card->pci_mmap1);
|
||||
|
||||
card->cmdrsp_buf = NULL;
|
||||
ret = mwifiex_pcie_create_txbd_ring(adapter);
|
||||
@ -1806,7 +1821,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
|
||||
dev_dbg(adapter->dev, "Clearing driver ready signature\n");
|
||||
if (user_rmmod) {
|
||||
if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000))
|
||||
dev_err(adapter->dev, "Failed to write driver not-ready signature\n");
|
||||
dev_err(adapter->dev,
|
||||
"Failed to write driver not-ready signature\n");
|
||||
}
|
||||
|
||||
if (pdev) {
|
||||
|
@ -125,7 +125,7 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
|
||||
ieee_hdr.element_id == WLAN_EID_RSN))) {
|
||||
iebody = (struct ie_body *)
|
||||
(((u8 *) bss_desc->bcn_rsn_ie->data) +
|
||||
RSN_GTK_OUI_OFFSET);
|
||||
RSN_GTK_OUI_OFFSET);
|
||||
oui = &mwifiex_rsn_oui[cipher][0];
|
||||
ret = mwifiex_search_oui_in_ie(iebody, oui);
|
||||
if (ret)
|
||||
@ -148,8 +148,9 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
|
||||
struct ie_body *iebody;
|
||||
u8 ret = MWIFIEX_OUI_NOT_PRESENT;
|
||||
|
||||
if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).
|
||||
vend_hdr.element_id == WLAN_EID_WPA))) {
|
||||
if (((bss_desc->bcn_wpa_ie) &&
|
||||
((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id ==
|
||||
WLAN_EID_WPA))) {
|
||||
iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
|
||||
oui = &mwifiex_wpa_oui[cipher][0];
|
||||
ret = mwifiex_search_oui_in_ie(iebody, oui);
|
||||
@ -175,8 +176,8 @@ mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
|
||||
* compatible with it.
|
||||
*/
|
||||
static bool
|
||||
mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
mwifiex_is_bss_wapi(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
if (priv->sec_info.wapi_enabled &&
|
||||
(bss_desc->bcn_wapi_ie &&
|
||||
@ -192,18 +193,17 @@ mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv,
|
||||
* scanned network is compatible with it.
|
||||
*/
|
||||
static bool
|
||||
mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
mwifiex_is_bss_no_sec(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
|
||||
!priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
|
||||
((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
|
||||
WLAN_EID_WPA))
|
||||
&& ((!bss_desc->bcn_rsn_ie) ||
|
||||
WLAN_EID_WPA)) &&
|
||||
((!bss_desc->bcn_rsn_ie) ||
|
||||
((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
|
||||
WLAN_EID_RSN))
|
||||
&& !priv->sec_info.encryption_mode
|
||||
&& !bss_desc->privacy) {
|
||||
WLAN_EID_RSN)) &&
|
||||
!priv->sec_info.encryption_mode && !bss_desc->privacy) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -214,8 +214,8 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
|
||||
* is compatible with it.
|
||||
*/
|
||||
static bool
|
||||
mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
mwifiex_is_bss_static_wep(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
|
||||
!priv->sec_info.wpa2_enabled && bss_desc->privacy) {
|
||||
@ -229,8 +229,8 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
|
||||
* compatible with it.
|
||||
*/
|
||||
static bool
|
||||
mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
mwifiex_is_bss_wpa(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled &&
|
||||
!priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) &&
|
||||
@ -264,17 +264,18 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
|
||||
* compatible with it.
|
||||
*/
|
||||
static bool
|
||||
mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
mwifiex_is_bss_wpa2(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
|
||||
priv->sec_info.wpa2_enabled && ((bss_desc->bcn_rsn_ie) &&
|
||||
((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))
|
||||
/*
|
||||
* Privacy bit may NOT be set in some APs like
|
||||
* LinkSys WRT54G && bss_desc->privacy
|
||||
*/
|
||||
) {
|
||||
if (!priv->sec_info.wep_enabled &&
|
||||
!priv->sec_info.wpa_enabled &&
|
||||
priv->sec_info.wpa2_enabled &&
|
||||
((bss_desc->bcn_rsn_ie) &&
|
||||
((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) {
|
||||
/*
|
||||
* Privacy bit may NOT be set in some APs like
|
||||
* LinkSys WRT54G && bss_desc->privacy
|
||||
*/
|
||||
dev_dbg(priv->adapter->dev, "info: %s: WPA2: "
|
||||
" wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
|
||||
"EncMode=%#x privacy=%#x\n", __func__,
|
||||
@ -299,16 +300,16 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
|
||||
* compatible with it.
|
||||
*/
|
||||
static bool
|
||||
mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
|
||||
!priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
|
||||
((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA))
|
||||
&& ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
|
||||
element_id != WLAN_EID_RSN))
|
||||
&& !priv->sec_info.encryption_mode
|
||||
&& bss_desc->privacy) {
|
||||
!priv->sec_info.wpa2_enabled &&
|
||||
((!bss_desc->bcn_wpa_ie) ||
|
||||
((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) &&
|
||||
((!bss_desc->bcn_rsn_ie) ||
|
||||
((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
|
||||
!priv->sec_info.encryption_mode && bss_desc->privacy) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -319,16 +320,16 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
|
||||
* is compatible with it.
|
||||
*/
|
||||
static bool
|
||||
mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv,
|
||||
struct mwifiex_bssdescriptor *bss_desc)
|
||||
{
|
||||
if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
|
||||
!priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
|
||||
((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA))
|
||||
&& ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
|
||||
element_id != WLAN_EID_RSN))
|
||||
&& priv->sec_info.encryption_mode
|
||||
&& bss_desc->privacy) {
|
||||
!priv->sec_info.wpa2_enabled &&
|
||||
((!bss_desc->bcn_wpa_ie) ||
|
||||
((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) &&
|
||||
((!bss_desc->bcn_rsn_ie) ||
|
||||
((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
|
||||
priv->sec_info.encryption_mode && bss_desc->privacy) {
|
||||
dev_dbg(priv->adapter->dev, "info: %s: dynamic "
|
||||
"WEP: wpa_ie=%#x wpa2_ie=%#x "
|
||||
"EncMode=%#x privacy=%#x\n",
|
||||
@ -373,8 +374,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
|
||||
bss_desc->disable_11n = false;
|
||||
|
||||
/* Don't check for compatibility if roaming */
|
||||
if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION)
|
||||
&& (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
|
||||
if (priv->media_connected &&
|
||||
(priv->bss_mode == NL80211_IFTYPE_STATION) &&
|
||||
(bss_desc->bss_mode == NL80211_IFTYPE_STATION))
|
||||
return 0;
|
||||
|
||||
if (priv->wps.session_enable) {
|
||||
@ -383,32 +385,30 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) {
|
||||
if (mwifiex_is_bss_wapi(priv, bss_desc)) {
|
||||
dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bss_desc->bss_mode == mode) {
|
||||
if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) {
|
||||
if (mwifiex_is_bss_no_sec(priv, bss_desc)) {
|
||||
/* No security */
|
||||
return 0;
|
||||
} else if (mwifiex_is_network_compatible_for_static_wep(priv,
|
||||
bss_desc)) {
|
||||
} else if (mwifiex_is_bss_static_wep(priv, bss_desc)) {
|
||||
/* Static WEP enabled */
|
||||
dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
|
||||
bss_desc->disable_11n = true;
|
||||
return 0;
|
||||
} else if (mwifiex_is_network_compatible_for_wpa(priv,
|
||||
bss_desc)) {
|
||||
} else if (mwifiex_is_bss_wpa(priv, bss_desc)) {
|
||||
/* WPA enabled */
|
||||
if (((priv->adapter->config_bands & BAND_GN
|
||||
|| priv->adapter->config_bands & BAND_AN)
|
||||
&& bss_desc->bcn_ht_cap)
|
||||
&& !mwifiex_is_wpa_oui_present(bss_desc,
|
||||
CIPHER_SUITE_CCMP)) {
|
||||
if (((priv->adapter->config_bands & BAND_GN ||
|
||||
priv->adapter->config_bands & BAND_AN) &&
|
||||
bss_desc->bcn_ht_cap) &&
|
||||
!mwifiex_is_wpa_oui_present(bss_desc,
|
||||
CIPHER_SUITE_CCMP)) {
|
||||
|
||||
if (mwifiex_is_wpa_oui_present(bss_desc,
|
||||
CIPHER_SUITE_TKIP)) {
|
||||
if (mwifiex_is_wpa_oui_present
|
||||
(bss_desc, CIPHER_SUITE_TKIP)) {
|
||||
dev_dbg(adapter->dev,
|
||||
"info: Disable 11n if AES "
|
||||
"is not supported by AP\n");
|
||||
@ -418,17 +418,16 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (mwifiex_is_network_compatible_for_wpa2(priv,
|
||||
bss_desc)) {
|
||||
} else if (mwifiex_is_bss_wpa2(priv, bss_desc)) {
|
||||
/* WPA2 enabled */
|
||||
if (((priv->adapter->config_bands & BAND_GN
|
||||
|| priv->adapter->config_bands & BAND_AN)
|
||||
&& bss_desc->bcn_ht_cap)
|
||||
&& !mwifiex_is_rsn_oui_present(bss_desc,
|
||||
CIPHER_SUITE_CCMP)) {
|
||||
if (((priv->adapter->config_bands & BAND_GN ||
|
||||
priv->adapter->config_bands & BAND_AN) &&
|
||||
bss_desc->bcn_ht_cap) &&
|
||||
!mwifiex_is_rsn_oui_present(bss_desc,
|
||||
CIPHER_SUITE_CCMP)) {
|
||||
|
||||
if (mwifiex_is_rsn_oui_present(bss_desc,
|
||||
CIPHER_SUITE_TKIP)) {
|
||||
if (mwifiex_is_rsn_oui_present
|
||||
(bss_desc, CIPHER_SUITE_TKIP)) {
|
||||
dev_dbg(adapter->dev,
|
||||
"info: Disable 11n if AES "
|
||||
"is not supported by AP\n");
|
||||
@ -438,31 +437,26 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (mwifiex_is_network_compatible_for_adhoc_aes(priv,
|
||||
bss_desc)) {
|
||||
} else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) {
|
||||
/* Ad-hoc AES enabled */
|
||||
return 0;
|
||||
} else if (mwifiex_is_network_compatible_for_dynamic_wep(priv,
|
||||
bss_desc)) {
|
||||
} else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) {
|
||||
/* Dynamic WEP enabled */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Security doesn't match */
|
||||
dev_dbg(adapter->dev, "info: %s: failed: "
|
||||
"wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode"
|
||||
"=%#x privacy=%#x\n",
|
||||
__func__,
|
||||
(bss_desc->bcn_wpa_ie) ?
|
||||
(*(bss_desc->bcn_wpa_ie)).vend_hdr.
|
||||
element_id : 0,
|
||||
(bss_desc->bcn_rsn_ie) ?
|
||||
(*(bss_desc->bcn_rsn_ie)).ieee_hdr.
|
||||
element_id : 0,
|
||||
(priv->sec_info.wep_enabled) ? "e" : "d",
|
||||
(priv->sec_info.wpa_enabled) ? "e" : "d",
|
||||
(priv->sec_info.wpa2_enabled) ? "e" : "d",
|
||||
priv->sec_info.encryption_mode, bss_desc->privacy);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s "
|
||||
"WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__,
|
||||
(bss_desc->bcn_wpa_ie) ?
|
||||
(*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0,
|
||||
(bss_desc->bcn_rsn_ie) ?
|
||||
(*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0,
|
||||
(priv->sec_info.wep_enabled) ? "e" : "d",
|
||||
(priv->sec_info.wpa_enabled) ? "e" : "d",
|
||||
(priv->sec_info.wpa2_enabled) ? "e" : "d",
|
||||
priv->sec_info.encryption_mode, bss_desc->privacy);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -479,11 +473,11 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv,
|
||||
*/
|
||||
static void
|
||||
mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
|
||||
const struct mwifiex_user_scan_cfg
|
||||
*user_scan_in,
|
||||
struct mwifiex_chan_scan_param_set
|
||||
*scan_chan_list,
|
||||
u8 filtered_scan)
|
||||
const struct mwifiex_user_scan_cfg
|
||||
*user_scan_in,
|
||||
struct mwifiex_chan_scan_param_set
|
||||
*scan_chan_list,
|
||||
u8 filtered_scan)
|
||||
{
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
@ -505,7 +499,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
|
||||
scan_chan_list[chan_idx].radio_type = band;
|
||||
|
||||
if (user_scan_in &&
|
||||
user_scan_in->chan_list[0].scan_time)
|
||||
user_scan_in->chan_list[0].scan_time)
|
||||
scan_chan_list[chan_idx].max_scan_time =
|
||||
cpu_to_le16((u16) user_scan_in->
|
||||
chan_list[0].scan_time);
|
||||
@ -594,19 +588,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
|
||||
* - done_early is set (controlling individual scanning of
|
||||
* 1,6,11)
|
||||
*/
|
||||
while (tlv_idx < max_chan_per_scan
|
||||
&& tmp_chan_list->chan_number && !done_early) {
|
||||
while (tlv_idx < max_chan_per_scan &&
|
||||
tmp_chan_list->chan_number && !done_early) {
|
||||
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: Scan: Chan(%3d), Radio(%d),"
|
||||
" Mode(%d, %d), Dur(%d)\n",
|
||||
tmp_chan_list->chan_number,
|
||||
tmp_chan_list->radio_type,
|
||||
tmp_chan_list->chan_scan_mode_bitmap
|
||||
& MWIFIEX_PASSIVE_SCAN,
|
||||
(tmp_chan_list->chan_scan_mode_bitmap
|
||||
& MWIFIEX_DISABLE_CHAN_FILT) >> 1,
|
||||
le16_to_cpu(tmp_chan_list->max_scan_time));
|
||||
tmp_chan_list->chan_number,
|
||||
tmp_chan_list->radio_type,
|
||||
tmp_chan_list->chan_scan_mode_bitmap
|
||||
& MWIFIEX_PASSIVE_SCAN,
|
||||
(tmp_chan_list->chan_scan_mode_bitmap
|
||||
& MWIFIEX_DISABLE_CHAN_FILT) >> 1,
|
||||
le16_to_cpu(tmp_chan_list->max_scan_time));
|
||||
|
||||
/* Copy the current channel TLV to the command being
|
||||
prepared */
|
||||
@ -648,9 +642,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
|
||||
/* Stop the loop if the *current* channel is in the
|
||||
1,6,11 set and we are not filtering on a BSSID
|
||||
or SSID. */
|
||||
if (!filtered_scan && (tmp_chan_list->chan_number == 1
|
||||
|| tmp_chan_list->chan_number == 6
|
||||
|| tmp_chan_list->chan_number == 11))
|
||||
if (!filtered_scan &&
|
||||
(tmp_chan_list->chan_number == 1 ||
|
||||
tmp_chan_list->chan_number == 6 ||
|
||||
tmp_chan_list->chan_number == 11))
|
||||
done_early = true;
|
||||
|
||||
/* Increment the tmp pointer to the next channel to
|
||||
@ -660,9 +655,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
|
||||
/* Stop the loop if the *next* channel is in the 1,6,11
|
||||
set. This will cause it to be the only channel
|
||||
scanned on the next interation */
|
||||
if (!filtered_scan && (tmp_chan_list->chan_number == 1
|
||||
|| tmp_chan_list->chan_number == 6
|
||||
|| tmp_chan_list->chan_number == 11))
|
||||
if (!filtered_scan &&
|
||||
(tmp_chan_list->chan_number == 1 ||
|
||||
tmp_chan_list->chan_number == 6 ||
|
||||
tmp_chan_list->chan_number == 11))
|
||||
done_early = true;
|
||||
}
|
||||
|
||||
@ -714,15 +710,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv,
|
||||
* If the number of probes is not set, adapter default setting is used.
|
||||
*/
|
||||
static void
|
||||
mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||
const struct mwifiex_user_scan_cfg *user_scan_in,
|
||||
struct mwifiex_scan_cmd_config *scan_cfg_out,
|
||||
struct mwifiex_ie_types_chan_list_param_set
|
||||
**chan_list_out,
|
||||
struct mwifiex_chan_scan_param_set
|
||||
*scan_chan_list,
|
||||
u8 *max_chan_per_scan, u8 *filtered_scan,
|
||||
u8 *scan_current_only)
|
||||
mwifiex_config_scan(struct mwifiex_private *priv,
|
||||
const struct mwifiex_user_scan_cfg *user_scan_in,
|
||||
struct mwifiex_scan_cmd_config *scan_cfg_out,
|
||||
struct mwifiex_ie_types_chan_list_param_set **chan_list_out,
|
||||
struct mwifiex_chan_scan_param_set *scan_chan_list,
|
||||
u8 *max_chan_per_scan, u8 *filtered_scan,
|
||||
u8 *scan_current_only)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct mwifiex_ie_types_num_probes *num_probes_tlv;
|
||||
@ -840,9 +834,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||
* truncate scan results. That is not an issue with an SSID
|
||||
* or BSSID filter applied to the scan results in the firmware.
|
||||
*/
|
||||
if ((i && ssid_filter)
|
||||
|| memcmp(scan_cfg_out->specific_bssid, &zero_mac,
|
||||
sizeof(zero_mac)))
|
||||
if ((i && ssid_filter) ||
|
||||
memcmp(scan_cfg_out->specific_bssid, &zero_mac,
|
||||
sizeof(zero_mac)))
|
||||
*filtered_scan = true;
|
||||
} else {
|
||||
scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
|
||||
@ -863,7 +857,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||
if (num_probes) {
|
||||
|
||||
dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
|
||||
num_probes);
|
||||
num_probes);
|
||||
|
||||
num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
|
||||
num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
|
||||
@ -889,9 +883,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||
|
||||
dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size);
|
||||
|
||||
if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
|
||||
&& (priv->adapter->config_bands & BAND_GN
|
||||
|| priv->adapter->config_bands & BAND_AN)) {
|
||||
if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
|
||||
(priv->adapter->config_bands & BAND_GN ||
|
||||
priv->adapter->config_bands & BAND_AN)) {
|
||||
ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
|
||||
memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
|
||||
ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
|
||||
@ -920,8 +914,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||
dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
|
||||
|
||||
for (chan_idx = 0;
|
||||
chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX
|
||||
&& user_scan_in->chan_list[chan_idx].chan_number;
|
||||
chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX &&
|
||||
user_scan_in->chan_list[chan_idx].chan_number;
|
||||
chan_idx++) {
|
||||
|
||||
channel = user_scan_in->chan_list[chan_idx].chan_number;
|
||||
@ -961,9 +955,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
/* Check if we are only scanning the current channel */
|
||||
if ((chan_idx == 1)
|
||||
&& (user_scan_in->chan_list[0].chan_number
|
||||
== priv->curr_bss_params.bss_descriptor.channel)) {
|
||||
if ((chan_idx == 1) &&
|
||||
(user_scan_in->chan_list[0].chan_number ==
|
||||
priv->curr_bss_params.bss_descriptor.channel)) {
|
||||
*scan_current_only = true;
|
||||
dev_dbg(adapter->dev,
|
||||
"info: Scan: Scanning current channel only\n");
|
||||
@ -971,7 +965,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
|
||||
|
||||
} else {
|
||||
dev_dbg(adapter->dev,
|
||||
"info: Scan: Creating full region channel list\n");
|
||||
"info: Scan: Creating full region channel list\n");
|
||||
mwifiex_scan_create_channel_list(priv, user_scan_in,
|
||||
scan_chan_list,
|
||||
*filtered_scan);
|
||||
@ -1003,7 +997,7 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
|
||||
*tlv_data = NULL;
|
||||
|
||||
dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
|
||||
tlv_buf_size);
|
||||
tlv_buf_size);
|
||||
|
||||
while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
|
||||
|
||||
@ -1100,8 +1094,9 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||
bss_entry->ssid.ssid_len = element_len;
|
||||
memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
|
||||
element_len);
|
||||
dev_dbg(adapter->dev, "info: InterpretIE: ssid: "
|
||||
"%-32s\n", bss_entry->ssid.ssid);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: InterpretIE: ssid: %-32s\n",
|
||||
bss_entry->ssid.ssid);
|
||||
break;
|
||||
|
||||
case WLAN_EID_SUPP_RATES:
|
||||
@ -1189,13 +1184,13 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
|
||||
bss_entry->bcn_wpa_ie =
|
||||
(struct ieee_types_vendor_specific *)
|
||||
current_ptr;
|
||||
bss_entry->wpa_offset = (u16) (current_ptr -
|
||||
bss_entry->beacon_buf);
|
||||
bss_entry->wpa_offset = (u16)
|
||||
(current_ptr - bss_entry->beacon_buf);
|
||||
} else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
|
||||
sizeof(wmm_oui))) {
|
||||
if (total_ie_len ==
|
||||
sizeof(struct ieee_types_wmm_parameter)
|
||||
|| total_ie_len ==
|
||||
sizeof(struct ieee_types_wmm_parameter) ||
|
||||
total_ie_len ==
|
||||
sizeof(struct ieee_types_wmm_info))
|
||||
/*
|
||||
* Only accept and copy the WMM IE if
|
||||
@ -1316,14 +1311,14 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
if (!scan_cfg_out) {
|
||||
dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
|
||||
MWIFIEX_USER_SCAN_CHAN_MAX;
|
||||
MWIFIEX_USER_SCAN_CHAN_MAX;
|
||||
scan_chan_list = kzalloc(buf_size, GFP_KERNEL);
|
||||
if (!scan_chan_list) {
|
||||
dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
|
||||
@ -1331,10 +1326,9 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mwifiex_scan_setup_scan_config(priv, user_scan_in,
|
||||
&scan_cfg_out->config, &chan_list_out,
|
||||
scan_chan_list, &max_chan_per_scan,
|
||||
&filtered_scan, &scan_current_chan_only);
|
||||
mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
|
||||
&chan_list_out, scan_chan_list, &max_chan_per_scan,
|
||||
&filtered_scan, &scan_current_chan_only);
|
||||
|
||||
ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
|
||||
&scan_cfg_out->config, chan_list_out,
|
||||
@ -1345,10 +1339,10 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
|
||||
if (!list_empty(&adapter->scan_pending_q)) {
|
||||
cmd_node = list_first_entry(&adapter->scan_pending_q,
|
||||
struct cmd_ctrl_node, list);
|
||||
struct cmd_ctrl_node, list);
|
||||
list_del(&cmd_node->list);
|
||||
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
|
||||
flags);
|
||||
flags);
|
||||
adapter->cmd_queued = cmd_node;
|
||||
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
|
||||
true);
|
||||
@ -1434,8 +1428,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
|
||||
if (!bss_desc)
|
||||
return -1;
|
||||
|
||||
if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
|
||||
(u8) bss_desc->bss_band, (u16) bss_desc->channel))) {
|
||||
if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band,
|
||||
(u16) bss_desc->channel, 0))) {
|
||||
switch (priv->bss_mode) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
@ -1514,7 +1508,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid,
|
||||
|
||||
/* Make a copy of current BSSID descriptor */
|
||||
memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
|
||||
sizeof(priv->curr_bss_params.bss_descriptor));
|
||||
sizeof(priv->curr_bss_params.bss_descriptor));
|
||||
mwifiex_save_curr_bcn(priv);
|
||||
spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
|
||||
|
||||
@ -1565,7 +1559,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
struct cfg80211_bss *bss;
|
||||
|
||||
is_bgscan_resp = (le16_to_cpu(resp->command)
|
||||
== HostCmd_CMD_802_11_BG_SCAN_QUERY);
|
||||
== HostCmd_CMD_802_11_BG_SCAN_QUERY);
|
||||
if (is_bgscan_resp)
|
||||
scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
|
||||
else
|
||||
@ -1574,20 +1568,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
|
||||
if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
|
||||
dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
|
||||
scan_rsp->number_of_sets);
|
||||
scan_rsp->number_of_sets);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
|
||||
dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
|
||||
bytes_left);
|
||||
bytes_left);
|
||||
|
||||
scan_resp_size = le16_to_cpu(resp->size);
|
||||
|
||||
dev_dbg(adapter->dev,
|
||||
"info: SCAN_RESP: returned %d APs before parsing\n",
|
||||
scan_rsp->number_of_sets);
|
||||
scan_rsp->number_of_sets);
|
||||
|
||||
bss_info = scan_rsp->bss_desc_and_tlv_buffer;
|
||||
|
||||
@ -1625,7 +1619,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
s32 rssi;
|
||||
const u8 *ie_buf;
|
||||
size_t ie_len;
|
||||
int channel = -1;
|
||||
u16 channel = 0;
|
||||
u64 network_tsf = 0;
|
||||
u16 beacon_size = 0;
|
||||
u32 curr_bcn_bytes;
|
||||
@ -1663,7 +1657,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
* and capability information
|
||||
*/
|
||||
if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) {
|
||||
dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
|
||||
dev_err(adapter->dev,
|
||||
"InterpretIE: not enough bytes left\n");
|
||||
continue;
|
||||
}
|
||||
bcn_param = (struct mwifiex_bcn_param *)current_ptr;
|
||||
@ -1673,20 +1668,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
memcpy(bssid, bcn_param->bssid, ETH_ALEN);
|
||||
|
||||
rssi = (s32) (bcn_param->rssi);
|
||||
dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n",
|
||||
rssi);
|
||||
dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", rssi);
|
||||
|
||||
beacon_period = le16_to_cpu(bcn_param->beacon_period);
|
||||
|
||||
cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
|
||||
dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
|
||||
cap_info_bitmap);
|
||||
cap_info_bitmap);
|
||||
|
||||
/* Rest of the current buffer are IE's */
|
||||
ie_buf = current_ptr;
|
||||
ie_len = curr_bcn_bytes;
|
||||
dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP"
|
||||
" = %d\n", curr_bcn_bytes);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: InterpretIE: IELength for this AP = %d\n",
|
||||
curr_bcn_bytes);
|
||||
|
||||
while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
|
||||
u8 element_id, element_len;
|
||||
@ -1695,8 +1690,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
element_len = *(current_ptr + 1);
|
||||
if (curr_bcn_bytes < element_len +
|
||||
sizeof(struct ieee_types_header)) {
|
||||
dev_err(priv->adapter->dev, "%s: in processing"
|
||||
" IE, bytes left < IE length\n",
|
||||
dev_err(priv->adapter->dev,
|
||||
"%s: bytes left < IE length\n",
|
||||
__func__);
|
||||
goto done;
|
||||
}
|
||||
@ -1720,10 +1715,10 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
*/
|
||||
if (tsf_tlv)
|
||||
memcpy(&network_tsf,
|
||||
&tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
|
||||
sizeof(network_tsf));
|
||||
&tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
|
||||
sizeof(network_tsf));
|
||||
|
||||
if (channel != -1) {
|
||||
if (channel) {
|
||||
struct ieee80211_channel *chan;
|
||||
u8 band;
|
||||
|
||||
@ -1736,8 +1731,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
& (BIT(0) | BIT(1)));
|
||||
}
|
||||
|
||||
cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
|
||||
priv, (u8)band, (u16)channel);
|
||||
cfp = mwifiex_get_cfp(priv, band, channel, 0);
|
||||
|
||||
freq = cfp ? cfp->freq : 0;
|
||||
|
||||
@ -1751,13 +1745,15 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
*(u8 *)bss->priv = band;
|
||||
cfg80211_put_bss(bss);
|
||||
|
||||
if (priv->media_connected && !memcmp(bssid,
|
||||
priv->curr_bss_params.bss_descriptor
|
||||
.mac_address, ETH_ALEN))
|
||||
mwifiex_update_curr_bss_params(priv,
|
||||
bssid, rssi, ie_buf,
|
||||
ie_len, beacon_period,
|
||||
cap_info_bitmap, band);
|
||||
if (priv->media_connected &&
|
||||
!memcmp(bssid,
|
||||
priv->curr_bss_params.bss_descriptor
|
||||
.mac_address, ETH_ALEN))
|
||||
mwifiex_update_curr_bss_params
|
||||
(priv, bssid, rssi,
|
||||
ie_buf, ie_len,
|
||||
beacon_period,
|
||||
cap_info_bitmap, band);
|
||||
}
|
||||
} else {
|
||||
dev_dbg(adapter->dev, "missing BSS channel IE\n");
|
||||
@ -1784,8 +1780,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
if (priv->user_scan_cfg) {
|
||||
dev_dbg(priv->adapter->dev, "info: %s: sending scan "
|
||||
"results\n", __func__);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: %s: sending scan results\n", __func__);
|
||||
cfg80211_scan_done(priv->scan_request, 0);
|
||||
priv->scan_request = NULL;
|
||||
kfree(priv->user_scan_cfg);
|
||||
@ -1901,7 +1897,7 @@ int mwifiex_request_scan(struct mwifiex_private *priv,
|
||||
|
||||
if (down_interruptible(&priv->async_sem)) {
|
||||
dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
priv->scan_pending_on_block = true;
|
||||
@ -1986,21 +1982,21 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
|
||||
|
||||
/* allocate beacon buffer at 1st time; or if it's size has changed */
|
||||
if (!priv->curr_bcn_buf ||
|
||||
priv->curr_bcn_size != curr_bss->beacon_buf_size) {
|
||||
priv->curr_bcn_size != curr_bss->beacon_buf_size) {
|
||||
priv->curr_bcn_size = curr_bss->beacon_buf_size;
|
||||
|
||||
kfree(priv->curr_bcn_buf);
|
||||
priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
|
||||
GFP_ATOMIC);
|
||||
GFP_ATOMIC);
|
||||
if (!priv->curr_bcn_buf) {
|
||||
dev_err(priv->adapter->dev,
|
||||
"failed to alloc curr_bcn_buf\n");
|
||||
"failed to alloc curr_bcn_buf\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
|
||||
curr_bss->beacon_buf_size);
|
||||
curr_bss->beacon_buf_size);
|
||||
dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
|
||||
priv->curr_bcn_size);
|
||||
|
||||
|
@ -67,7 +67,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
|
||||
struct sdio_mmc_card *card = NULL;
|
||||
|
||||
pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
|
||||
func->vendor, func->device, func->class, func->num);
|
||||
func->vendor, func->device, func->class, func->num);
|
||||
|
||||
card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
|
||||
if (!card)
|
||||
@ -110,6 +110,7 @@ mwifiex_sdio_remove(struct sdio_func *func)
|
||||
{
|
||||
struct sdio_mmc_card *card;
|
||||
struct mwifiex_adapter *adapter;
|
||||
struct mwifiex_private *priv;
|
||||
int i;
|
||||
|
||||
pr_debug("info: SDIO func num=%d\n", func->num);
|
||||
@ -129,15 +130,12 @@ mwifiex_sdio_remove(struct sdio_func *func)
|
||||
for (i = 0; i < adapter->priv_num; i++)
|
||||
if ((GET_BSS_ROLE(adapter->priv[i]) ==
|
||||
MWIFIEX_BSS_ROLE_STA) &&
|
||||
adapter->priv[i]->media_connected)
|
||||
adapter->priv[i]->media_connected)
|
||||
mwifiex_deauthenticate(adapter->priv[i], NULL);
|
||||
|
||||
mwifiex_disable_auto_ds(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_ANY));
|
||||
|
||||
mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_ANY),
|
||||
MWIFIEX_FUNC_SHUTDOWN);
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
mwifiex_disable_auto_ds(priv);
|
||||
mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
|
||||
}
|
||||
|
||||
mwifiex_remove_card(card->adapter, &add_remove_card_sem);
|
||||
@ -167,7 +165,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
|
||||
if (func) {
|
||||
pm_flag = sdio_get_host_pm_caps(func);
|
||||
pr_debug("cmd: %s: suspend: PM flag = 0x%x\n",
|
||||
sdio_func_id(func), pm_flag);
|
||||
sdio_func_id(func), pm_flag);
|
||||
if (!(pm_flag & MMC_PM_KEEP_POWER)) {
|
||||
pr_err("%s: cannot remain alive while host is"
|
||||
" suspended\n", sdio_func_id(func));
|
||||
@ -361,12 +359,11 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
|
||||
{
|
||||
struct sdio_mmc_card *card = adapter->card;
|
||||
int ret = -1;
|
||||
u8 blk_mode =
|
||||
(port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
|
||||
u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE
|
||||
: BLOCK_MODE;
|
||||
u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
|
||||
u32 blk_cnt =
|
||||
(blk_mode ==
|
||||
BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len;
|
||||
u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE)
|
||||
: len;
|
||||
u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
|
||||
|
||||
if (claim)
|
||||
@ -470,8 +467,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
|
||||
i++;
|
||||
dev_err(adapter->dev, "host_to_card, write iomem"
|
||||
" (%d) failed: %d\n", i, ret);
|
||||
if (mwifiex_write_reg(adapter,
|
||||
CONFIGURATION_REG, 0x04))
|
||||
if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))
|
||||
dev_err(adapter->dev, "write CFG reg failed\n");
|
||||
|
||||
ret = -1;
|
||||
@ -505,11 +501,11 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
|
||||
card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK);
|
||||
*port = CTRL_PORT;
|
||||
dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n",
|
||||
*port, card->mp_rd_bitmap);
|
||||
*port, card->mp_rd_bitmap);
|
||||
} else {
|
||||
if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) {
|
||||
card->mp_rd_bitmap &=
|
||||
(u16) (~(1 << card->curr_rd_port));
|
||||
card->mp_rd_bitmap &= (u16)
|
||||
(~(1 << card->curr_rd_port));
|
||||
*port = card->curr_rd_port;
|
||||
|
||||
if (++card->curr_rd_port == MAX_PORT)
|
||||
@ -520,7 +516,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
|
||||
|
||||
dev_dbg(adapter->dev,
|
||||
"data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
|
||||
*port, rd_bitmap, card->mp_rd_bitmap);
|
||||
*port, rd_bitmap, card->mp_rd_bitmap);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -554,14 +550,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
|
||||
|
||||
if (*port == CTRL_PORT) {
|
||||
dev_err(adapter->dev, "invalid data port=%d cur port=%d"
|
||||
" mp_wr_bitmap=0x%04x -> 0x%04x\n",
|
||||
*port, card->curr_wr_port, wr_bitmap,
|
||||
card->mp_wr_bitmap);
|
||||
" mp_wr_bitmap=0x%04x -> 0x%04x\n",
|
||||
*port, card->curr_wr_port, wr_bitmap,
|
||||
card->mp_wr_bitmap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
|
||||
*port, wr_bitmap, card->mp_wr_bitmap);
|
||||
*port, wr_bitmap, card->mp_wr_bitmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -581,11 +577,11 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
|
||||
else if ((cs & bits) == bits)
|
||||
return 0;
|
||||
|
||||
udelay(10);
|
||||
usleep_range(10, 20);
|
||||
}
|
||||
|
||||
dev_err(adapter->dev, "poll card status failed, tries = %d\n",
|
||||
tries);
|
||||
dev_err(adapter->dev, "poll card status failed, tries = %d\n", tries);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -668,14 +664,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
|
||||
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__,
|
||||
ret);
|
||||
ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nb = le16_to_cpu(*(__le16 *) (buffer));
|
||||
if (nb > npayload) {
|
||||
dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n",
|
||||
__func__, nb, npayload);
|
||||
dev_err(adapter->dev, "%s: invalid packet, nb=%d npayload=%d\n",
|
||||
__func__, nb, npayload);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -705,19 +701,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
u32 i = 0;
|
||||
|
||||
if (!firmware_len) {
|
||||
dev_err(adapter->dev, "firmware image not found!"
|
||||
" Terminating download\n");
|
||||
dev_err(adapter->dev,
|
||||
"firmware image not found! Terminating download\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n",
|
||||
firmware_len);
|
||||
firmware_len);
|
||||
|
||||
/* Assume that the allocated buffer is 8-byte aligned */
|
||||
fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL);
|
||||
if (!fwbuf) {
|
||||
dev_err(adapter->dev, "unable to alloc buffer for firmware."
|
||||
" Terminating download\n");
|
||||
dev_err(adapter->dev,
|
||||
"unable to alloc buffer for FW. Terminating dnld\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -729,7 +725,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
DN_LD_CARD_RDY);
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "FW download with helper:"
|
||||
" poll status timeout @ %d\n", offset);
|
||||
" poll status timeout @ %d\n", offset);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -741,17 +737,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0,
|
||||
&base0);
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "dev BASE0 register read"
|
||||
" failed: base0=0x%04X(%d). Terminating "
|
||||
"download\n", base0, base0);
|
||||
dev_err(adapter->dev,
|
||||
"dev BASE0 register read failed: "
|
||||
"base0=%#04X(%d). Terminating dnld\n",
|
||||
base0, base0);
|
||||
goto done;
|
||||
}
|
||||
ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1,
|
||||
&base1);
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "dev BASE1 register read"
|
||||
" failed: base1=0x%04X(%d). Terminating "
|
||||
"download\n", base1, base1);
|
||||
dev_err(adapter->dev,
|
||||
"dev BASE1 register read failed: "
|
||||
"base1=%#04X(%d). Terminating dnld\n",
|
||||
base1, base1);
|
||||
goto done;
|
||||
}
|
||||
len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff));
|
||||
@ -759,14 +757,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
if (len)
|
||||
break;
|
||||
|
||||
udelay(10);
|
||||
usleep_range(10, 20);
|
||||
}
|
||||
|
||||
if (!len) {
|
||||
break;
|
||||
} else if (len > MWIFIEX_UPLD_SIZE) {
|
||||
dev_err(adapter->dev, "FW download failed @ %d,"
|
||||
" invalid length %d\n", offset, len);
|
||||
dev_err(adapter->dev,
|
||||
"FW dnld failed @ %d, invalid length %d\n",
|
||||
offset, len);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
@ -776,13 +775,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
if (len & BIT(0)) {
|
||||
i++;
|
||||
if (i > MAX_WRITE_IOMEM_RETRY) {
|
||||
dev_err(adapter->dev, "FW download failed @"
|
||||
" %d, over max retry count\n", offset);
|
||||
dev_err(adapter->dev,
|
||||
"FW dnld failed @ %d, over max retry\n",
|
||||
offset);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
dev_err(adapter->dev, "CRC indicated by the helper:"
|
||||
" len = 0x%04X, txlen = %d\n", len, txlen);
|
||||
" len = 0x%04X, txlen = %d\n", len, txlen);
|
||||
len &= ~BIT(0);
|
||||
/* Setting this to 0 to resend from same offset */
|
||||
txlen = 0;
|
||||
@ -794,8 +794,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
if (firmware_len - offset < txlen)
|
||||
txlen = firmware_len - offset;
|
||||
|
||||
tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE -
|
||||
1) / MWIFIEX_SDIO_BLOCK_SIZE;
|
||||
tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1)
|
||||
/ MWIFIEX_SDIO_BLOCK_SIZE;
|
||||
|
||||
/* Copy payload to buffer */
|
||||
memmove(fwbuf, &firmware[offset], txlen);
|
||||
@ -805,8 +805,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
MWIFIEX_SDIO_BLOCK_SIZE,
|
||||
adapter->ioport);
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "FW download, write iomem (%d)"
|
||||
" failed @ %d\n", i, offset);
|
||||
dev_err(adapter->dev,
|
||||
"FW download, write iomem (%d) failed @ %d\n",
|
||||
i, offset);
|
||||
if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))
|
||||
dev_err(adapter->dev, "write CFG reg failed\n");
|
||||
|
||||
@ -818,7 +819,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
|
||||
} while (true);
|
||||
|
||||
dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n",
|
||||
offset);
|
||||
offset);
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
@ -910,7 +911,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func)
|
||||
card = sdio_get_drvdata(func);
|
||||
if (!card || !card->adapter) {
|
||||
pr_debug("int: func=%p card=%p adapter=%p\n",
|
||||
func, card, card ? card->adapter : NULL);
|
||||
func, card, card ? card->adapter : NULL);
|
||||
return;
|
||||
}
|
||||
adapter = card->adapter;
|
||||
@ -953,10 +954,12 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
|
||||
|
||||
if (adapter->ps_state == PS_STATE_SLEEP_CFM)
|
||||
mwifiex_process_sleep_confirm_resp(adapter,
|
||||
skb->data, skb->len);
|
||||
skb->data,
|
||||
skb->len);
|
||||
|
||||
memcpy(cmd_buf, skb->data, min_t(u32,
|
||||
MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
|
||||
memcpy(cmd_buf, skb->data,
|
||||
min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER,
|
||||
skb->len));
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
} else {
|
||||
@ -1014,7 +1017,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
if (port == CTRL_PORT) {
|
||||
/* Read the command Resp without aggr */
|
||||
dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
|
||||
"response\n", __func__);
|
||||
"response\n", __func__);
|
||||
|
||||
f_do_rx_cur = 1;
|
||||
goto rx_curr_single;
|
||||
@ -1022,7 +1025,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
|
||||
if (!card->mpa_rx.enabled) {
|
||||
dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n",
|
||||
__func__);
|
||||
__func__);
|
||||
|
||||
f_do_rx_cur = 1;
|
||||
goto rx_curr_single;
|
||||
@ -1069,7 +1072,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
|
||||
MP_RX_AGGR_PORT_LIMIT_REACHED(card)) {
|
||||
dev_dbg(adapter->dev, "info: %s: aggregated packet "
|
||||
"limit reached\n", __func__);
|
||||
"limit reached\n", __func__);
|
||||
/* No more pkts allowed in Aggr buf, rx it */
|
||||
f_do_rx_aggr = 1;
|
||||
}
|
||||
@ -1078,7 +1081,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
if (f_do_rx_aggr) {
|
||||
/* do aggr RX now */
|
||||
dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
|
||||
card->mpa_rx.pkt_cnt);
|
||||
card->mpa_rx.pkt_cnt);
|
||||
|
||||
if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
|
||||
card->mpa_rx.buf_len,
|
||||
@ -1192,7 +1195,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8;
|
||||
card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L];
|
||||
dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n",
|
||||
card->mp_wr_bitmap);
|
||||
card->mp_wr_bitmap);
|
||||
if (adapter->data_sent &&
|
||||
(card->mp_wr_bitmap & card->mp_data_port_mask)) {
|
||||
dev_dbg(adapter->dev,
|
||||
@ -1214,12 +1217,12 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
|
||||
adapter->cmd_sent, adapter->data_sent);
|
||||
adapter->cmd_sent, adapter->data_sent);
|
||||
if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
|
||||
card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8;
|
||||
card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L];
|
||||
dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n",
|
||||
card->mp_rd_bitmap);
|
||||
card->mp_rd_bitmap);
|
||||
|
||||
while (true) {
|
||||
ret = mwifiex_get_rd_port(adapter, &port);
|
||||
@ -1233,15 +1236,15 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
|
||||
rx_len |= (u16) card->mp_regs[len_reg_l];
|
||||
dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
|
||||
port, rx_len);
|
||||
port, rx_len);
|
||||
rx_blocks =
|
||||
(rx_len + MWIFIEX_SDIO_BLOCK_SIZE -
|
||||
1) / MWIFIEX_SDIO_BLOCK_SIZE;
|
||||
if (rx_len <= INTF_HEADER_LEN
|
||||
|| (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
|
||||
MWIFIEX_RX_DATA_BUF_SIZE) {
|
||||
if (rx_len <= INTF_HEADER_LEN ||
|
||||
(rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
|
||||
MWIFIEX_RX_DATA_BUF_SIZE) {
|
||||
dev_err(adapter->dev, "invalid rx_len=%d\n",
|
||||
rx_len);
|
||||
rx_len);
|
||||
return -1;
|
||||
}
|
||||
rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
|
||||
@ -1250,42 +1253,42 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
|
||||
|
||||
if (!skb) {
|
||||
dev_err(adapter->dev, "%s: failed to alloc skb",
|
||||
__func__);
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
skb_put(skb, rx_len);
|
||||
|
||||
dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
|
||||
rx_len, skb->len);
|
||||
rx_len, skb->len);
|
||||
|
||||
if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
|
||||
port)) {
|
||||
u32 cr = 0;
|
||||
|
||||
dev_err(adapter->dev, "card_to_host_mpa failed:"
|
||||
" int status=%#x\n", sdio_ireg);
|
||||
" int status=%#x\n", sdio_ireg);
|
||||
if (mwifiex_read_reg(adapter,
|
||||
CONFIGURATION_REG, &cr))
|
||||
dev_err(adapter->dev,
|
||||
"read CFG reg failed\n");
|
||||
"read CFG reg failed\n");
|
||||
|
||||
dev_dbg(adapter->dev,
|
||||
"info: CFG reg val = %d\n", cr);
|
||||
"info: CFG reg val = %d\n", cr);
|
||||
if (mwifiex_write_reg(adapter,
|
||||
CONFIGURATION_REG,
|
||||
(cr | 0x04)))
|
||||
dev_err(adapter->dev,
|
||||
"write CFG reg failed\n");
|
||||
"write CFG reg failed\n");
|
||||
|
||||
dev_dbg(adapter->dev, "info: write success\n");
|
||||
if (mwifiex_read_reg(adapter,
|
||||
CONFIGURATION_REG, &cr))
|
||||
dev_err(adapter->dev,
|
||||
"read CFG reg failed\n");
|
||||
"read CFG reg failed\n");
|
||||
|
||||
dev_dbg(adapter->dev,
|
||||
"info: CFG reg val =%x\n", cr);
|
||||
"info: CFG reg val =%x\n", cr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1321,7 +1324,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
|
||||
if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) {
|
||||
dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
|
||||
__func__);
|
||||
__func__);
|
||||
|
||||
f_send_cur_buf = 1;
|
||||
goto tx_curr_single;
|
||||
@ -1330,7 +1333,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
if (next_pkt_len) {
|
||||
/* More pkt in TX queue */
|
||||
dev_dbg(adapter->dev, "info: %s: more packets in queue.\n",
|
||||
__func__);
|
||||
__func__);
|
||||
|
||||
if (MP_TX_AGGR_IN_PROGRESS(card)) {
|
||||
if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) &&
|
||||
@ -1338,9 +1341,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
f_precopy_cur_buf = 1;
|
||||
|
||||
if (!(card->mp_wr_bitmap &
|
||||
(1 << card->curr_wr_port))
|
||||
|| !MP_TX_AGGR_BUF_HAS_ROOM(
|
||||
card, pkt_len + next_pkt_len))
|
||||
(1 << card->curr_wr_port)) ||
|
||||
!MP_TX_AGGR_BUF_HAS_ROOM(
|
||||
card, pkt_len + next_pkt_len))
|
||||
f_send_aggr_buf = 1;
|
||||
} else {
|
||||
/* No room in Aggr buf, send it */
|
||||
@ -1354,8 +1357,8 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
f_postcopy_cur_buf = 1;
|
||||
}
|
||||
} else {
|
||||
if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)
|
||||
&& (card->mp_wr_bitmap & (1 << card->curr_wr_port)))
|
||||
if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) &&
|
||||
(card->mp_wr_bitmap & (1 << card->curr_wr_port)))
|
||||
f_precopy_cur_buf = 1;
|
||||
else
|
||||
f_send_cur_buf = 1;
|
||||
@ -1363,7 +1366,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
} else {
|
||||
/* Last pkt in TX queue */
|
||||
dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n",
|
||||
__func__);
|
||||
__func__);
|
||||
|
||||
if (MP_TX_AGGR_IN_PROGRESS(card)) {
|
||||
/* some packs in Aggr buf already */
|
||||
@ -1381,7 +1384,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
|
||||
if (f_precopy_cur_buf) {
|
||||
dev_dbg(adapter->dev, "data: %s: precopy current buffer\n",
|
||||
__func__);
|
||||
__func__);
|
||||
MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
|
||||
|
||||
if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
|
||||
@ -1392,7 +1395,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
|
||||
if (f_send_aggr_buf) {
|
||||
dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
|
||||
__func__,
|
||||
__func__,
|
||||
card->mpa_tx.start_port, card->mpa_tx.ports);
|
||||
ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
|
||||
card->mpa_tx.buf_len,
|
||||
@ -1406,14 +1409,14 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
|
||||
tx_curr_single:
|
||||
if (f_send_cur_buf) {
|
||||
dev_dbg(adapter->dev, "data: %s: send current buffer %d\n",
|
||||
__func__, port);
|
||||
__func__, port);
|
||||
ret = mwifiex_write_data_to_card(adapter, payload, pkt_len,
|
||||
adapter->ioport + port);
|
||||
}
|
||||
|
||||
if (f_postcopy_cur_buf) {
|
||||
dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n",
|
||||
__func__);
|
||||
__func__);
|
||||
MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
|
||||
}
|
||||
|
||||
@ -1458,7 +1461,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
|
||||
ret = mwifiex_get_wr_port_data(adapter, &port);
|
||||
if (ret) {
|
||||
dev_err(adapter->dev, "%s: no wr_port available\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
@ -1468,7 +1471,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
|
||||
if (pkt_len <= INTF_HEADER_LEN ||
|
||||
pkt_len > MWIFIEX_UPLD_SIZE)
|
||||
dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
|
||||
__func__, payload, pkt_len);
|
||||
__func__, payload, pkt_len);
|
||||
}
|
||||
|
||||
/* Transfer data to card */
|
||||
@ -1476,10 +1479,11 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
|
||||
|
||||
if (tx_param)
|
||||
ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
|
||||
port, tx_param->next_pkt_len);
|
||||
port, tx_param->next_pkt_len
|
||||
);
|
||||
else
|
||||
ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
|
||||
port, 0);
|
||||
port, 0);
|
||||
|
||||
if (ret) {
|
||||
if (type == MWIFIEX_TYPE_CMD)
|
||||
@ -1732,7 +1736,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
|
||||
card->curr_wr_port = 1;
|
||||
|
||||
dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
|
||||
port, card->mp_data_port_mask);
|
||||
port, card->mp_data_port_mask);
|
||||
}
|
||||
|
||||
static struct mwifiex_if_ops sdio_ops = {
|
||||
|
@ -110,7 +110,7 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
|
||||
dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
|
||||
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
|
||||
- 1 + S_DS_GEN);
|
||||
- 1 + S_DS_GEN);
|
||||
|
||||
snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
|
||||
if (cmd_action == HostCmd_ACT_GEN_GET) {
|
||||
@ -127,8 +127,8 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x,"
|
||||
" Value=0x%x\n",
|
||||
cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
|
||||
le16_to_cpu(*(__le16 *) snmp_mib->value));
|
||||
cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
|
||||
le16_to_cpu(*(__le16 *) snmp_mib->value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -174,8 +174,8 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
|
||||
rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg +
|
||||
sizeof(struct host_cmd_ds_tx_rate_cfg));
|
||||
rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE);
|
||||
rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) -
|
||||
sizeof(struct mwifiex_ie_types_header));
|
||||
rate_scope->length = cpu_to_le16
|
||||
(sizeof(*rate_scope) - sizeof(struct mwifiex_ie_types_header));
|
||||
if (pbitmap_rates != NULL) {
|
||||
rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]);
|
||||
rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]);
|
||||
@ -197,7 +197,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope +
|
||||
sizeof(struct mwifiex_rate_scope));
|
||||
sizeof(struct mwifiex_rate_scope));
|
||||
rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL);
|
||||
rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
|
||||
rate_drop->rate_drop_mode = 0;
|
||||
@ -284,22 +284,22 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
|
||||
|
||||
if (!hs_activate &&
|
||||
(hscfg_param->conditions
|
||||
!= cpu_to_le32(HOST_SLEEP_CFG_CANCEL))
|
||||
&& ((adapter->arp_filter_size > 0)
|
||||
&& (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
|
||||
(hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) &&
|
||||
((adapter->arp_filter_size > 0) &&
|
||||
(adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: Attach %d bytes ArpFilter to HSCfg cmd\n",
|
||||
adapter->arp_filter_size);
|
||||
adapter->arp_filter_size);
|
||||
memcpy(((u8 *) hs_cfg) +
|
||||
sizeof(struct host_cmd_ds_802_11_hs_cfg_enh),
|
||||
adapter->arp_filter, adapter->arp_filter_size);
|
||||
cmd->size = cpu_to_le16(adapter->arp_filter_size +
|
||||
sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
|
||||
+ S_DS_GEN);
|
||||
cmd->size = cpu_to_le16
|
||||
(adapter->arp_filter_size +
|
||||
sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
|
||||
+ S_DS_GEN);
|
||||
} else {
|
||||
cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct
|
||||
host_cmd_ds_802_11_hs_cfg_enh));
|
||||
host_cmd_ds_802_11_hs_cfg_enh));
|
||||
}
|
||||
if (hs_activate) {
|
||||
hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
|
||||
@ -467,7 +467,7 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
|
||||
key_param_set =
|
||||
(struct mwifiex_ie_type_key_param_set *)
|
||||
((u8 *)key_param_set +
|
||||
cur_key_param_len);
|
||||
cur_key_param_len);
|
||||
} else if (!priv->wep_key[i].key_length) {
|
||||
continue;
|
||||
} else {
|
||||
@ -527,13 +527,13 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
|
||||
if (enc_key->is_wapi_key) {
|
||||
dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n");
|
||||
key_material->key_param_set.key_type_id =
|
||||
cpu_to_le16(KEY_TYPE_ID_WAPI);
|
||||
cpu_to_le16(KEY_TYPE_ID_WAPI);
|
||||
if (cmd_oid == KEY_INFO_ENABLED)
|
||||
key_material->key_param_set.key_info =
|
||||
cpu_to_le16(KEY_ENABLED);
|
||||
cpu_to_le16(KEY_ENABLED);
|
||||
else
|
||||
key_material->key_param_set.key_info =
|
||||
cpu_to_le16(!KEY_ENABLED);
|
||||
cpu_to_le16(!KEY_ENABLED);
|
||||
|
||||
key_material->key_param_set.key[0] = enc_key->key_index;
|
||||
if (!priv->sec_info.wapi_key_on)
|
||||
@ -553,9 +553,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
key_material->key_param_set.type =
|
||||
cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
|
||||
cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
|
||||
key_material->key_param_set.key_len =
|
||||
cpu_to_le16(WAPI_KEY_LEN);
|
||||
cpu_to_le16(WAPI_KEY_LEN);
|
||||
memcpy(&key_material->key_param_set.key[2],
|
||||
enc_key->key_material, enc_key->key_len);
|
||||
memcpy(&key_material->key_param_set.key[2 + enc_key->key_len],
|
||||
@ -565,49 +565,49 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
|
||||
|
||||
key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
|
||||
sizeof(struct mwifiex_ie_types_header);
|
||||
cmd->size = cpu_to_le16(key_param_len +
|
||||
sizeof(key_material->action) + S_DS_GEN);
|
||||
cmd->size = cpu_to_le16(sizeof(key_material->action)
|
||||
+ S_DS_GEN + key_param_len);
|
||||
return ret;
|
||||
}
|
||||
if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
|
||||
dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
|
||||
key_material->key_param_set.key_type_id =
|
||||
cpu_to_le16(KEY_TYPE_ID_AES);
|
||||
cpu_to_le16(KEY_TYPE_ID_AES);
|
||||
if (cmd_oid == KEY_INFO_ENABLED)
|
||||
key_material->key_param_set.key_info =
|
||||
cpu_to_le16(KEY_ENABLED);
|
||||
cpu_to_le16(KEY_ENABLED);
|
||||
else
|
||||
key_material->key_param_set.key_info =
|
||||
cpu_to_le16(!KEY_ENABLED);
|
||||
cpu_to_le16(!KEY_ENABLED);
|
||||
|
||||
if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
|
||||
/* AES pairwise key: unicast */
|
||||
key_material->key_param_set.key_info |=
|
||||
cpu_to_le16(KEY_UNICAST);
|
||||
cpu_to_le16(KEY_UNICAST);
|
||||
else /* AES group key: multicast */
|
||||
key_material->key_param_set.key_info |=
|
||||
cpu_to_le16(KEY_MCAST);
|
||||
cpu_to_le16(KEY_MCAST);
|
||||
} else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
|
||||
dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
|
||||
key_material->key_param_set.key_type_id =
|
||||
cpu_to_le16(KEY_TYPE_ID_TKIP);
|
||||
cpu_to_le16(KEY_TYPE_ID_TKIP);
|
||||
key_material->key_param_set.key_info =
|
||||
cpu_to_le16(KEY_ENABLED);
|
||||
cpu_to_le16(KEY_ENABLED);
|
||||
|
||||
if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
|
||||
/* TKIP pairwise key: unicast */
|
||||
key_material->key_param_set.key_info |=
|
||||
cpu_to_le16(KEY_UNICAST);
|
||||
cpu_to_le16(KEY_UNICAST);
|
||||
else /* TKIP group key: multicast */
|
||||
key_material->key_param_set.key_info |=
|
||||
cpu_to_le16(KEY_MCAST);
|
||||
cpu_to_le16(KEY_MCAST);
|
||||
}
|
||||
|
||||
if (key_material->key_param_set.key_type_id) {
|
||||
key_material->key_param_set.type =
|
||||
cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
|
||||
cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
|
||||
key_material->key_param_set.key_len =
|
||||
cpu_to_le16((u16) enc_key->key_len);
|
||||
cpu_to_le16((u16) enc_key->key_len);
|
||||
memcpy(key_material->key_param_set.key, enc_key->key_material,
|
||||
enc_key->key_len);
|
||||
key_material->key_param_set.length =
|
||||
@ -615,10 +615,10 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
|
||||
KEYPARAMSET_FIXED_LEN);
|
||||
|
||||
key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN)
|
||||
+ sizeof(struct mwifiex_ie_types_header);
|
||||
+ sizeof(struct mwifiex_ie_types_header);
|
||||
|
||||
cmd->size = cpu_to_le16(key_param_len +
|
||||
sizeof(key_material->action) + S_DS_GEN);
|
||||
cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
|
||||
+ key_param_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -655,21 +655,22 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv,
|
||||
/* Set domain info fields */
|
||||
domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY);
|
||||
memcpy(domain->country_code, adapter->domain_reg.country_code,
|
||||
sizeof(domain->country_code));
|
||||
sizeof(domain->country_code));
|
||||
|
||||
domain->header.len = cpu_to_le16((no_of_triplet *
|
||||
sizeof(struct ieee80211_country_ie_triplet)) +
|
||||
sizeof(domain->country_code));
|
||||
domain->header.len =
|
||||
cpu_to_le16((no_of_triplet *
|
||||
sizeof(struct ieee80211_country_ie_triplet))
|
||||
+ sizeof(domain->country_code));
|
||||
|
||||
if (no_of_triplet) {
|
||||
memcpy(domain->triplet, adapter->domain_reg.triplet,
|
||||
no_of_triplet *
|
||||
sizeof(struct ieee80211_country_ie_triplet));
|
||||
no_of_triplet * sizeof(struct
|
||||
ieee80211_country_ie_triplet));
|
||||
|
||||
cmd->size = cpu_to_le16(sizeof(domain_info->action) +
|
||||
le16_to_cpu(domain->header.len) +
|
||||
sizeof(struct mwifiex_ie_types_header)
|
||||
+ S_DS_GEN);
|
||||
le16_to_cpu(domain->header.len) +
|
||||
sizeof(struct mwifiex_ie_types_header)
|
||||
+ S_DS_GEN);
|
||||
} else {
|
||||
cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
|
||||
}
|
||||
@ -698,8 +699,8 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv,
|
||||
+ S_DS_GEN);
|
||||
|
||||
if (cmd_action == HostCmd_ACT_GEN_SET) {
|
||||
if ((priv->adapter->adhoc_start_band & BAND_A)
|
||||
|| (priv->adapter->adhoc_start_band & BAND_AN))
|
||||
if ((priv->adapter->adhoc_start_band & BAND_A) ||
|
||||
(priv->adapter->adhoc_start_band & BAND_AN))
|
||||
rf_chan->rf_type =
|
||||
cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A);
|
||||
|
||||
@ -777,7 +778,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
|
||||
|
||||
cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
|
||||
mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd->
|
||||
params.mac_reg;
|
||||
params.mac_reg;
|
||||
mac_reg->action = cpu_to_le16(cmd_action);
|
||||
mac_reg->offset =
|
||||
cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
@ -789,8 +790,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
|
||||
struct host_cmd_ds_bbp_reg_access *bbp_reg;
|
||||
|
||||
cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
|
||||
bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd->
|
||||
params.bbp_reg;
|
||||
bbp_reg = (struct host_cmd_ds_bbp_reg_access *)
|
||||
&cmd->params.bbp_reg;
|
||||
bbp_reg->action = cpu_to_le16(cmd_action);
|
||||
bbp_reg->offset =
|
||||
cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
@ -802,11 +803,10 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
|
||||
struct host_cmd_ds_rf_reg_access *rf_reg;
|
||||
|
||||
cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
|
||||
rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
|
||||
params.rf_reg;
|
||||
rf_reg = (struct host_cmd_ds_rf_reg_access *)
|
||||
&cmd->params.rf_reg;
|
||||
rf_reg->action = cpu_to_le16(cmd_action);
|
||||
rf_reg->offset =
|
||||
cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
|
||||
break;
|
||||
}
|
||||
@ -819,7 +819,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
|
||||
params.pmic_reg;
|
||||
pmic_reg->action = cpu_to_le16(cmd_action);
|
||||
pmic_reg->offset =
|
||||
cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
|
||||
break;
|
||||
}
|
||||
@ -828,11 +828,11 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
|
||||
struct host_cmd_ds_rf_reg_access *cau_reg;
|
||||
|
||||
cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
|
||||
cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
|
||||
params.rf_reg;
|
||||
cau_reg = (struct host_cmd_ds_rf_reg_access *)
|
||||
&cmd->params.rf_reg;
|
||||
cau_reg->action = cpu_to_le16(cmd_action);
|
||||
cau_reg->offset =
|
||||
cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
|
||||
cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
|
||||
break;
|
||||
}
|
||||
@ -868,7 +868,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
|
||||
*/
|
||||
static int
|
||||
mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *cmd, u16 action)
|
||||
struct host_cmd_ds_command *cmd, u16 action)
|
||||
{
|
||||
struct host_cmd_ds_pcie_details *host_spec =
|
||||
&cmd->params.pcie_host_spec;
|
||||
@ -882,29 +882,25 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
|
||||
|
||||
memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details));
|
||||
|
||||
if (action == HostCmd_ACT_GEN_SET) {
|
||||
/* Send the ring base addresses and count to firmware */
|
||||
host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase);
|
||||
host_spec->txbd_addr_hi =
|
||||
(u32)(((u64)card->txbd_ring_pbase)>>32);
|
||||
host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD;
|
||||
host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase);
|
||||
host_spec->rxbd_addr_hi =
|
||||
(u32)(((u64)card->rxbd_ring_pbase)>>32);
|
||||
host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD;
|
||||
host_spec->evtbd_addr_lo =
|
||||
(u32)(card->evtbd_ring_pbase);
|
||||
host_spec->evtbd_addr_hi =
|
||||
(u32)(((u64)card->evtbd_ring_pbase)>>32);
|
||||
host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
|
||||
if (card->sleep_cookie) {
|
||||
buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie);
|
||||
host_spec->sleep_cookie_addr_lo = (u32) *buf_pa;
|
||||
host_spec->sleep_cookie_addr_hi =
|
||||
(u32) (((u64)*buf_pa) >> 32);
|
||||
dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: "
|
||||
"0x%x\n", host_spec->sleep_cookie_addr_lo);
|
||||
}
|
||||
if (action != HostCmd_ACT_GEN_SET)
|
||||
return 0;
|
||||
|
||||
/* Send the ring base addresses and count to firmware */
|
||||
host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase);
|
||||
host_spec->txbd_addr_hi = (u32)(((u64)card->txbd_ring_pbase)>>32);
|
||||
host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD;
|
||||
host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase);
|
||||
host_spec->rxbd_addr_hi = (u32)(((u64)card->rxbd_ring_pbase)>>32);
|
||||
host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD;
|
||||
host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase);
|
||||
host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32);
|
||||
host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD;
|
||||
if (card->sleep_cookie) {
|
||||
buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie);
|
||||
host_spec->sleep_cookie_addr_lo = (u32) *buf_pa;
|
||||
host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32);
|
||||
dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n",
|
||||
host_spec->sleep_cookie_addr_lo);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1036,12 +1032,12 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
|
||||
break;
|
||||
case HostCmd_CMD_802_11_KEY_MATERIAL:
|
||||
ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr,
|
||||
cmd_action, cmd_oid,
|
||||
data_buf);
|
||||
cmd_action, cmd_oid,
|
||||
data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_802_11D_DOMAIN_INFO:
|
||||
ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr,
|
||||
cmd_action);
|
||||
cmd_action);
|
||||
break;
|
||||
case HostCmd_CMD_RECONFIGURE_TX_BUFF:
|
||||
ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action,
|
||||
@ -1052,8 +1048,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
|
||||
data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_11N_CFG:
|
||||
ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action,
|
||||
data_buf);
|
||||
ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_WMM_GET_STATUS:
|
||||
dev_dbg(priv->adapter->dev,
|
||||
@ -1131,8 +1126,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
|
||||
if (first_sta) {
|
||||
if (priv->adapter->iface_type == MWIFIEX_PCIE) {
|
||||
ret = mwifiex_send_cmd_async(priv,
|
||||
HostCmd_CMD_PCIE_DESC_DETAILS,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL);
|
||||
HostCmd_CMD_PCIE_DESC_DETAILS,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL);
|
||||
if (ret)
|
||||
return -1;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
|
||||
unsigned long flags;
|
||||
|
||||
dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n",
|
||||
resp->command, resp->result);
|
||||
resp->command, resp->result);
|
||||
|
||||
if (adapter->curr_cmd->wait_q_enabled)
|
||||
adapter->cmd_wait_q.status = -1;
|
||||
@ -57,13 +57,13 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
|
||||
switch (le16_to_cpu(resp->command)) {
|
||||
case HostCmd_CMD_802_11_PS_MODE_ENH:
|
||||
pm = &resp->params.psmode_enh;
|
||||
dev_err(adapter->dev, "PS_MODE_ENH cmd failed: "
|
||||
"result=0x%x action=0x%X\n",
|
||||
resp->result, le16_to_cpu(pm->action));
|
||||
dev_err(adapter->dev,
|
||||
"PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n",
|
||||
resp->result, le16_to_cpu(pm->action));
|
||||
/* We do not re-try enter-ps command in ad-hoc mode. */
|
||||
if (le16_to_cpu(pm->action) == EN_AUTO_PS &&
|
||||
(le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
|
||||
priv->bss_mode == NL80211_IFTYPE_ADHOC)
|
||||
(le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
|
||||
priv->bss_mode == NL80211_IFTYPE_ADHOC)
|
||||
adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
|
||||
|
||||
break;
|
||||
@ -123,7 +123,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
|
||||
struct mwifiex_ds_get_signal *signal)
|
||||
{
|
||||
struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
|
||||
&resp->params.rssi_info_rsp;
|
||||
&resp->params.rssi_info_rsp;
|
||||
|
||||
priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
|
||||
priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
|
||||
@ -191,8 +191,8 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
|
||||
u32 ul_temp;
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x,"
|
||||
" query_type = %#x, buf size = %#x\n",
|
||||
oid, query_type, le16_to_cpu(smib->buf_size));
|
||||
" query_type = %#x, buf size = %#x\n",
|
||||
oid, query_type, le16_to_cpu(smib->buf_size));
|
||||
if (query_type == HostCmd_ACT_GEN_GET) {
|
||||
ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
|
||||
if (data_buf)
|
||||
@ -327,31 +327,26 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
|
||||
HostCmd_CMD_802_11_TX_RATE_QUERY,
|
||||
HostCmd_ACT_GEN_GET, 0, NULL);
|
||||
|
||||
if (ds_rate) {
|
||||
if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) {
|
||||
if (priv->is_data_rate_auto) {
|
||||
ds_rate->is_rate_auto = 1;
|
||||
} else {
|
||||
ds_rate->rate = mwifiex_get_rate_index(priv->
|
||||
bitmap_rates,
|
||||
sizeof(priv->
|
||||
bitmap_rates));
|
||||
if (ds_rate->rate >=
|
||||
MWIFIEX_RATE_BITMAP_OFDM0
|
||||
&& ds_rate->rate <=
|
||||
MWIFIEX_RATE_BITMAP_OFDM7)
|
||||
ds_rate->rate -=
|
||||
(MWIFIEX_RATE_BITMAP_OFDM0 -
|
||||
MWIFIEX_RATE_INDEX_OFDM0);
|
||||
if (ds_rate->rate >=
|
||||
MWIFIEX_RATE_BITMAP_MCS0
|
||||
&& ds_rate->rate <=
|
||||
MWIFIEX_RATE_BITMAP_MCS127)
|
||||
ds_rate->rate -=
|
||||
(MWIFIEX_RATE_BITMAP_MCS0 -
|
||||
MWIFIEX_RATE_INDEX_MCS0);
|
||||
}
|
||||
}
|
||||
if (!ds_rate)
|
||||
return ret;
|
||||
|
||||
if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) {
|
||||
if (priv->is_data_rate_auto) {
|
||||
ds_rate->is_rate_auto = 1;
|
||||
return ret;
|
||||
}
|
||||
ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates,
|
||||
sizeof(priv->bitmap_rates));
|
||||
|
||||
if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 &&
|
||||
ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7)
|
||||
ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 -
|
||||
MWIFIEX_RATE_INDEX_OFDM0);
|
||||
|
||||
if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 &&
|
||||
ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127)
|
||||
ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 -
|
||||
MWIFIEX_RATE_INDEX_MCS0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -369,34 +364,32 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
|
||||
struct mwifiex_types_power_group *pg_tlv_hdr;
|
||||
struct mwifiex_power_group *pg;
|
||||
|
||||
if (data_buf) {
|
||||
pg_tlv_hdr =
|
||||
(struct mwifiex_types_power_group *) ((u8 *) data_buf
|
||||
+ sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr +
|
||||
sizeof(struct mwifiex_types_power_group));
|
||||
length = pg_tlv_hdr->length;
|
||||
if (length > 0) {
|
||||
max_power = pg->power_max;
|
||||
min_power = pg->power_min;
|
||||
length -= sizeof(struct mwifiex_power_group);
|
||||
}
|
||||
while (length) {
|
||||
pg++;
|
||||
if (max_power < pg->power_max)
|
||||
max_power = pg->power_max;
|
||||
|
||||
if (min_power > pg->power_min)
|
||||
min_power = pg->power_min;
|
||||
|
||||
length -= sizeof(struct mwifiex_power_group);
|
||||
}
|
||||
if (pg_tlv_hdr->length > 0) {
|
||||
priv->min_tx_power_level = (u8) min_power;
|
||||
priv->max_tx_power_level = (u8) max_power;
|
||||
}
|
||||
} else {
|
||||
if (!data_buf)
|
||||
return -1;
|
||||
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)
|
||||
((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
pg = (struct mwifiex_power_group *)
|
||||
((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
|
||||
length = pg_tlv_hdr->length;
|
||||
if (length > 0) {
|
||||
max_power = pg->power_max;
|
||||
min_power = pg->power_min;
|
||||
length -= sizeof(struct mwifiex_power_group);
|
||||
}
|
||||
while (length) {
|
||||
pg++;
|
||||
if (max_power < pg->power_max)
|
||||
max_power = pg->power_max;
|
||||
|
||||
if (min_power > pg->power_min)
|
||||
min_power = pg->power_min;
|
||||
|
||||
length -= sizeof(struct mwifiex_power_group);
|
||||
}
|
||||
if (pg_tlv_hdr->length > 0) {
|
||||
priv->min_tx_power_level = (u8) min_power;
|
||||
priv->max_tx_power_level = (u8) max_power;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -420,42 +413,38 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
|
||||
|
||||
switch (action) {
|
||||
case HostCmd_ACT_GEN_GET:
|
||||
{
|
||||
pg_tlv_hdr =
|
||||
(struct mwifiex_types_power_group *) ((u8 *)
|
||||
txp_cfg +
|
||||
sizeof
|
||||
(struct
|
||||
host_cmd_ds_txpwr_cfg));
|
||||
pg = (struct mwifiex_power_group *) ((u8 *)
|
||||
pg_tlv_hdr +
|
||||
sizeof(struct
|
||||
mwifiex_types_power_group));
|
||||
if (adapter->hw_status ==
|
||||
MWIFIEX_HW_STATUS_INITIALIZING)
|
||||
mwifiex_get_power_level(priv, txp_cfg);
|
||||
priv->tx_power_level = (u16) pg->power_min;
|
||||
break;
|
||||
}
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)
|
||||
((u8 *) txp_cfg +
|
||||
sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
|
||||
pg = (struct mwifiex_power_group *)
|
||||
((u8 *) pg_tlv_hdr +
|
||||
sizeof(struct mwifiex_types_power_group));
|
||||
|
||||
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
|
||||
mwifiex_get_power_level(priv, txp_cfg);
|
||||
|
||||
priv->tx_power_level = (u16) pg->power_min;
|
||||
break;
|
||||
|
||||
case HostCmd_ACT_GEN_SET:
|
||||
if (le32_to_cpu(txp_cfg->mode)) {
|
||||
pg_tlv_hdr =
|
||||
(struct mwifiex_types_power_group *) ((u8 *)
|
||||
txp_cfg +
|
||||
sizeof
|
||||
(struct
|
||||
host_cmd_ds_txpwr_cfg));
|
||||
pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr
|
||||
+
|
||||
sizeof(struct
|
||||
mwifiex_types_power_group));
|
||||
if (pg->power_max == pg->power_min)
|
||||
priv->tx_power_level = (u16) pg->power_min;
|
||||
}
|
||||
if (!le32_to_cpu(txp_cfg->mode))
|
||||
break;
|
||||
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)
|
||||
((u8 *) txp_cfg +
|
||||
sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
|
||||
pg = (struct mwifiex_power_group *)
|
||||
((u8 *) pg_tlv_hdr +
|
||||
sizeof(struct mwifiex_types_power_group));
|
||||
|
||||
if (pg->power_max == pg->power_min)
|
||||
priv->tx_power_level = (u16) pg->power_min;
|
||||
break;
|
||||
default:
|
||||
dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n",
|
||||
action);
|
||||
action);
|
||||
return 0;
|
||||
}
|
||||
dev_dbg(adapter->dev,
|
||||
@ -475,7 +464,7 @@ static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp)
|
||||
{
|
||||
struct host_cmd_ds_802_11_mac_address *cmd_mac_addr =
|
||||
&resp->params.mac_addr;
|
||||
&resp->params.mac_addr;
|
||||
|
||||
memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN);
|
||||
|
||||
@ -560,7 +549,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp)
|
||||
{
|
||||
struct host_cmd_ds_802_11_key_material *key =
|
||||
&resp->params.key_material;
|
||||
&resp->params.key_material;
|
||||
|
||||
if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
|
||||
if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
|
||||
@ -591,17 +580,18 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
|
||||
u16 action = le16_to_cpu(domain_info->action);
|
||||
u8 no_of_triplet;
|
||||
|
||||
no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) -
|
||||
IEEE80211_COUNTRY_STRING_LEN) /
|
||||
sizeof(struct ieee80211_country_ie_triplet));
|
||||
no_of_triplet = (u8) ((le16_to_cpu(domain->header.len)
|
||||
- IEEE80211_COUNTRY_STRING_LEN)
|
||||
/ sizeof(struct ieee80211_country_ie_triplet));
|
||||
|
||||
dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:"
|
||||
" no_of_triplet=%d\n", no_of_triplet);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: 11D Domain Info Resp: no_of_triplet=%d\n",
|
||||
no_of_triplet);
|
||||
|
||||
if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) {
|
||||
dev_warn(priv->adapter->dev,
|
||||
"11D: invalid number of triplets %d "
|
||||
"returned!!\n", no_of_triplet);
|
||||
"11D: invalid number of triplets %d returned\n",
|
||||
no_of_triplet);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -635,8 +625,8 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv,
|
||||
|
||||
if (priv->curr_bss_params.bss_descriptor.channel != new_channel) {
|
||||
dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n",
|
||||
priv->curr_bss_params.bss_descriptor.channel,
|
||||
new_channel);
|
||||
priv->curr_bss_params.bss_descriptor.channel,
|
||||
new_channel);
|
||||
/* Update the channel again */
|
||||
priv->curr_bss_params.bss_descriptor.channel = new_channel;
|
||||
}
|
||||
@ -679,90 +669,70 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp,
|
||||
{
|
||||
struct mwifiex_ds_reg_rw *reg_rw;
|
||||
struct mwifiex_ds_read_eeprom *eeprom;
|
||||
union reg {
|
||||
struct host_cmd_ds_mac_reg_access *mac;
|
||||
struct host_cmd_ds_bbp_reg_access *bbp;
|
||||
struct host_cmd_ds_rf_reg_access *rf;
|
||||
struct host_cmd_ds_pmic_reg_access *pmic;
|
||||
struct host_cmd_ds_802_11_eeprom_access *eeprom;
|
||||
} r;
|
||||
|
||||
if (data_buf) {
|
||||
reg_rw = data_buf;
|
||||
eeprom = data_buf;
|
||||
switch (type) {
|
||||
case HostCmd_CMD_MAC_REG_ACCESS:
|
||||
{
|
||||
struct host_cmd_ds_mac_reg_access *reg;
|
||||
reg = (struct host_cmd_ds_mac_reg_access *)
|
||||
&resp->params.mac_reg;
|
||||
reg_rw->offset = cpu_to_le32(
|
||||
(u32) le16_to_cpu(reg->offset));
|
||||
reg_rw->value = reg->value;
|
||||
break;
|
||||
}
|
||||
case HostCmd_CMD_BBP_REG_ACCESS:
|
||||
{
|
||||
struct host_cmd_ds_bbp_reg_access *reg;
|
||||
reg = (struct host_cmd_ds_bbp_reg_access *)
|
||||
&resp->params.bbp_reg;
|
||||
reg_rw->offset = cpu_to_le32(
|
||||
(u32) le16_to_cpu(reg->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) reg->value);
|
||||
break;
|
||||
}
|
||||
if (!data_buf)
|
||||
return 0;
|
||||
|
||||
case HostCmd_CMD_RF_REG_ACCESS:
|
||||
{
|
||||
struct host_cmd_ds_rf_reg_access *reg;
|
||||
reg = (struct host_cmd_ds_rf_reg_access *)
|
||||
&resp->params.rf_reg;
|
||||
reg_rw->offset = cpu_to_le32(
|
||||
(u32) le16_to_cpu(reg->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) reg->value);
|
||||
break;
|
||||
}
|
||||
case HostCmd_CMD_PMIC_REG_ACCESS:
|
||||
{
|
||||
struct host_cmd_ds_pmic_reg_access *reg;
|
||||
reg = (struct host_cmd_ds_pmic_reg_access *)
|
||||
&resp->params.pmic_reg;
|
||||
reg_rw->offset = cpu_to_le32(
|
||||
(u32) le16_to_cpu(reg->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) reg->value);
|
||||
break;
|
||||
}
|
||||
case HostCmd_CMD_CAU_REG_ACCESS:
|
||||
{
|
||||
struct host_cmd_ds_rf_reg_access *reg;
|
||||
reg = (struct host_cmd_ds_rf_reg_access *)
|
||||
&resp->params.rf_reg;
|
||||
reg_rw->offset = cpu_to_le32(
|
||||
(u32) le16_to_cpu(reg->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) reg->value);
|
||||
break;
|
||||
}
|
||||
case HostCmd_CMD_802_11_EEPROM_ACCESS:
|
||||
{
|
||||
struct host_cmd_ds_802_11_eeprom_access
|
||||
*cmd_eeprom =
|
||||
(struct host_cmd_ds_802_11_eeprom_access
|
||||
*) &resp->params.eeprom;
|
||||
pr_debug("info: EEPROM read len=%x\n",
|
||||
cmd_eeprom->byte_count);
|
||||
if (le16_to_cpu(eeprom->byte_count) <
|
||||
le16_to_cpu(
|
||||
cmd_eeprom->byte_count)) {
|
||||
eeprom->byte_count = cpu_to_le16(0);
|
||||
pr_debug("info: EEPROM read "
|
||||
"length is too big\n");
|
||||
return -1;
|
||||
}
|
||||
eeprom->offset = cmd_eeprom->offset;
|
||||
eeprom->byte_count = cmd_eeprom->byte_count;
|
||||
if (le16_to_cpu(eeprom->byte_count) > 0)
|
||||
memcpy(&eeprom->value,
|
||||
&cmd_eeprom->value,
|
||||
le16_to_cpu(eeprom->byte_count));
|
||||
reg_rw = data_buf;
|
||||
eeprom = data_buf;
|
||||
switch (type) {
|
||||
case HostCmd_CMD_MAC_REG_ACCESS:
|
||||
r.mac = (struct host_cmd_ds_mac_reg_access *)
|
||||
&resp->params.mac_reg;
|
||||
reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset));
|
||||
reg_rw->value = r.mac->value;
|
||||
break;
|
||||
case HostCmd_CMD_BBP_REG_ACCESS:
|
||||
r.bbp = (struct host_cmd_ds_bbp_reg_access *)
|
||||
&resp->params.bbp_reg;
|
||||
reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) r.bbp->value);
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case HostCmd_CMD_RF_REG_ACCESS:
|
||||
r.rf = (struct host_cmd_ds_rf_reg_access *)
|
||||
&resp->params.rf_reg;
|
||||
reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) r.bbp->value);
|
||||
break;
|
||||
case HostCmd_CMD_PMIC_REG_ACCESS:
|
||||
r.pmic = (struct host_cmd_ds_pmic_reg_access *)
|
||||
&resp->params.pmic_reg;
|
||||
reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) r.pmic->value);
|
||||
break;
|
||||
case HostCmd_CMD_CAU_REG_ACCESS:
|
||||
r.rf = (struct host_cmd_ds_rf_reg_access *)
|
||||
&resp->params.rf_reg;
|
||||
reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
|
||||
reg_rw->value = cpu_to_le32((u32) r.rf->value);
|
||||
break;
|
||||
case HostCmd_CMD_802_11_EEPROM_ACCESS:
|
||||
r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *)
|
||||
&resp->params.eeprom;
|
||||
pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count);
|
||||
if (le16_to_cpu(eeprom->byte_count) <
|
||||
le16_to_cpu(r.eeprom->byte_count)) {
|
||||
eeprom->byte_count = cpu_to_le16(0);
|
||||
pr_debug("info: EEPROM read length is too big\n");
|
||||
return -1;
|
||||
}
|
||||
eeprom->offset = r.eeprom->offset;
|
||||
eeprom->byte_count = r.eeprom->byte_count;
|
||||
if (le16_to_cpu(eeprom->byte_count) > 0)
|
||||
memcpy(&eeprom->value, &r.eeprom->value,
|
||||
le16_to_cpu(r.eeprom->byte_count));
|
||||
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -778,7 +748,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp)
|
||||
{
|
||||
struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp =
|
||||
&(resp->params.ibss_coalescing);
|
||||
&(resp->params.ibss_coalescing);
|
||||
u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET)
|
||||
@ -918,20 +888,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
|
||||
case HostCmd_CMD_RECONFIGURE_TX_BUFF:
|
||||
adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
|
||||
tx_buf.buff_size);
|
||||
adapter->tx_buf_size = (adapter->tx_buf_size /
|
||||
MWIFIEX_SDIO_BLOCK_SIZE) *
|
||||
MWIFIEX_SDIO_BLOCK_SIZE;
|
||||
adapter->tx_buf_size = (adapter->tx_buf_size
|
||||
/ MWIFIEX_SDIO_BLOCK_SIZE)
|
||||
* MWIFIEX_SDIO_BLOCK_SIZE;
|
||||
adapter->curr_tx_buf_size = adapter->tx_buf_size;
|
||||
dev_dbg(adapter->dev,
|
||||
"cmd: max_tx_buf_size=%d, tx_buf_size=%d\n",
|
||||
adapter->max_tx_buf_size, adapter->tx_buf_size);
|
||||
adapter->max_tx_buf_size, adapter->tx_buf_size);
|
||||
|
||||
if (adapter->if_ops.update_mp_end_port)
|
||||
adapter->if_ops.update_mp_end_port(adapter,
|
||||
le16_to_cpu(resp->
|
||||
params.
|
||||
tx_buf.
|
||||
mp_end_port));
|
||||
le16_to_cpu(resp->params.tx_buf.mp_end_port));
|
||||
break;
|
||||
case HostCmd_CMD_AMSDU_AGGR_CTRL:
|
||||
ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf);
|
||||
@ -959,7 +926,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
|
||||
break;
|
||||
default:
|
||||
dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
|
||||
resp->command);
|
||||
resp->command);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -93,11 +93,11 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
|
||||
*/
|
||||
|
||||
dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n",
|
||||
priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
|
||||
priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
|
||||
|
||||
dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n",
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid,
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid,
|
||||
priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
|
||||
|
||||
memcpy(&priv->prev_ssid,
|
||||
&priv->curr_bss_params.bss_descriptor.ssid,
|
||||
@ -115,9 +115,9 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
|
||||
if (adapter->num_cmd_timeout && adapter->curr_cmd)
|
||||
return;
|
||||
priv->media_connected = false;
|
||||
dev_dbg(adapter->dev, "info: successfully disconnected from"
|
||||
" %pM: reason code %d\n", priv->cfg_bssid,
|
||||
WLAN_REASON_DEAUTH_LEAVING);
|
||||
dev_dbg(adapter->dev,
|
||||
"info: successfully disconnected from %pM: reason code %d\n",
|
||||
priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING);
|
||||
if (priv->bss_mode == NL80211_IFTYPE_STATION) {
|
||||
cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING,
|
||||
NULL, 0, GFP_KERNEL);
|
||||
@ -192,8 +192,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||
|
||||
switch (eventcause) {
|
||||
case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
|
||||
dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL,"
|
||||
" ignoring it\n");
|
||||
dev_err(adapter->dev,
|
||||
"invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n");
|
||||
break;
|
||||
case EVENT_LINK_SENSED:
|
||||
dev_dbg(adapter->dev, "event: LINK_SENSED\n");
|
||||
@ -235,8 +235,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||
case EVENT_PS_AWAKE:
|
||||
dev_dbg(adapter->dev, "info: EVENT: AWAKE\n");
|
||||
if (!adapter->pps_uapsd_mode &&
|
||||
priv->media_connected &&
|
||||
adapter->sleep_period.period) {
|
||||
priv->media_connected && adapter->sleep_period.period) {
|
||||
adapter->pps_uapsd_mode = true;
|
||||
dev_dbg(adapter->dev,
|
||||
"event: PPS/UAPSD mode activated\n");
|
||||
@ -244,15 +243,19 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||
adapter->tx_lock_flag = false;
|
||||
if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
|
||||
if (mwifiex_check_last_packet_indication(priv)) {
|
||||
if (!adapter->data_sent) {
|
||||
if (!mwifiex_send_null_packet(priv,
|
||||
MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET
|
||||
|
|
||||
MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
|
||||
if (adapter->data_sent) {
|
||||
adapter->ps_state = PS_STATE_AWAKE;
|
||||
adapter->pm_wakeup_card_req = false;
|
||||
adapter->pm_wakeup_fw_try = false;
|
||||
break;
|
||||
}
|
||||
if (!mwifiex_send_null_packet
|
||||
(priv,
|
||||
MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
|
||||
MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
|
||||
adapter->ps_state =
|
||||
PS_STATE_SLEEP;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
adapter->ps_state = PS_STATE_AWAKE;
|
||||
@ -371,12 +374,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||
break;
|
||||
case EVENT_AMSDU_AGGR_CTRL:
|
||||
dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n",
|
||||
*(u16 *) adapter->event_body);
|
||||
*(u16 *) adapter->event_body);
|
||||
adapter->tx_buf_size =
|
||||
min(adapter->curr_tx_buf_size,
|
||||
le16_to_cpu(*(__le16 *) adapter->event_body));
|
||||
dev_dbg(adapter->dev, "event: tx_buf_size %d\n",
|
||||
adapter->tx_buf_size);
|
||||
adapter->tx_buf_size);
|
||||
break;
|
||||
|
||||
case EVENT_WEP_ICV_ERR:
|
||||
@ -392,7 +395,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||
break;
|
||||
default:
|
||||
dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
|
||||
eventcause);
|
||||
eventcause);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
|
||||
|
||||
/* Wait for completion */
|
||||
wait_event_interruptible(adapter->cmd_wait_q.wait,
|
||||
*(cmd_queued->condition));
|
||||
*(cmd_queued->condition));
|
||||
if (!*(cmd_queued->condition))
|
||||
cancel_flag = true;
|
||||
|
||||
@ -266,9 +266,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
||||
/* Adhoc mode */
|
||||
/* If the requested SSID matches current SSID, return */
|
||||
if (bss_desc && bss_desc->ssid.ssid_len &&
|
||||
(!mwifiex_ssid_cmp
|
||||
(&priv->curr_bss_params.bss_descriptor.ssid,
|
||||
&bss_desc->ssid))) {
|
||||
(!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor.
|
||||
ssid, &bss_desc->ssid))) {
|
||||
kfree(bss_desc);
|
||||
kfree(beacon_ie);
|
||||
return 0;
|
||||
@ -350,9 +349,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
|
||||
adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
|
||||
if (hs_cfg->gap)
|
||||
adapter->hs_cfg.gap = (u8)hs_cfg->gap;
|
||||
} else if (adapter->hs_cfg.conditions ==
|
||||
cpu_to_le32(
|
||||
HOST_SLEEP_CFG_CANCEL)) {
|
||||
} else if (adapter->hs_cfg.conditions
|
||||
== cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) {
|
||||
/* Return failure if no parameters for HS
|
||||
enable */
|
||||
status = -1;
|
||||
@ -374,7 +372,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
|
||||
cpu_to_le32(prev_cond);
|
||||
} else {
|
||||
adapter->hs_cfg.conditions =
|
||||
cpu_to_le32(hs_cfg->conditions);
|
||||
cpu_to_le32(hs_cfg->conditions);
|
||||
adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
|
||||
adapter->hs_cfg.gap = (u8)hs_cfg->gap;
|
||||
}
|
||||
@ -427,11 +425,11 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
|
||||
|
||||
adapter->hs_activate_wait_q_woken = false;
|
||||
|
||||
memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param));
|
||||
memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
|
||||
hscfg.is_invoke_hostcmd = true;
|
||||
|
||||
if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
|
||||
MWIFIEX_BSS_ROLE_STA),
|
||||
MWIFIEX_BSS_ROLE_STA),
|
||||
HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
|
||||
&hscfg)) {
|
||||
dev_err(adapter->dev, "IOCTL request HS enable failed\n");
|
||||
@ -439,7 +437,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
|
||||
wait_event_interruptible(adapter->hs_activate_wait_q,
|
||||
adapter->hs_activate_wait_q_woken);
|
||||
adapter->hs_activate_wait_q_woken);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -529,30 +527,27 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv,
|
||||
adapter->adhoc_start_band = BAND_G | BAND_B;
|
||||
if (chan->channel) {
|
||||
if (chan->channel <= MAX_CHANNEL_BAND_BG)
|
||||
cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
|
||||
(priv, 0, (u16) chan->channel);
|
||||
cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0);
|
||||
if (!cfp) {
|
||||
cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
|
||||
(priv, BAND_A, (u16) chan->channel);
|
||||
cfp = mwifiex_get_cfp(priv, BAND_A,
|
||||
(u16) chan->channel, 0);
|
||||
if (cfp) {
|
||||
if (adapter->adhoc_11n_enabled)
|
||||
adapter->adhoc_start_band = BAND_A
|
||||
| BAND_AN;
|
||||
| BAND_AN;
|
||||
else
|
||||
adapter->adhoc_start_band = BAND_A;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (chan->freq <= MAX_FREQUENCY_BAND_BG)
|
||||
cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
|
||||
priv, 0, chan->freq);
|
||||
cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq);
|
||||
if (!cfp) {
|
||||
cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211
|
||||
(priv, BAND_A, chan->freq);
|
||||
cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq);
|
||||
if (cfp) {
|
||||
if (adapter->adhoc_11n_enabled)
|
||||
adapter->adhoc_start_band = BAND_A
|
||||
| BAND_AN;
|
||||
| BAND_AN;
|
||||
else
|
||||
adapter->adhoc_start_band = BAND_A;
|
||||
}
|
||||
@ -588,7 +583,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
|
||||
}
|
||||
|
||||
return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL,
|
||||
action, 0, channel);
|
||||
action, 0, channel);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -634,7 +629,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel)
|
||||
goto done;
|
||||
}
|
||||
dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n",
|
||||
curr_chan, channel);
|
||||
curr_chan, channel);
|
||||
|
||||
if (!bss_info.media_connected) {
|
||||
ret = 0;
|
||||
@ -656,7 +651,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel)
|
||||
|
||||
band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
|
||||
chan = __ieee80211_get_channel(priv->wdev->wiphy,
|
||||
ieee80211_channel_to_frequency(channel, band));
|
||||
ieee80211_channel_to_frequency(channel,
|
||||
band));
|
||||
|
||||
/* Find the BSS we want using available scan results */
|
||||
bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid,
|
||||
@ -664,7 +660,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel)
|
||||
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
|
||||
if (!bss)
|
||||
wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n",
|
||||
bss_info.bssid);
|
||||
bss_info.bssid);
|
||||
|
||||
ret = mwifiex_bss_start(priv, bss, &bss_info.ssid);
|
||||
done:
|
||||
@ -793,7 +789,9 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
|
||||
if (!ret) {
|
||||
if (rate->is_rate_auto)
|
||||
rate->rate = mwifiex_index_to_data_rate(priv,
|
||||
priv->tx_rate, priv->tx_htinfo);
|
||||
priv->tx_rate,
|
||||
priv->tx_htinfo
|
||||
);
|
||||
else
|
||||
rate->rate = priv->data_rate;
|
||||
} else {
|
||||
@ -830,16 +828,16 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
|
||||
if ((dbm < priv->min_tx_power_level) ||
|
||||
(dbm > priv->max_tx_power_level)) {
|
||||
dev_err(priv->adapter->dev, "txpower value %d dBm"
|
||||
" is out of range (%d dBm-%d dBm)\n",
|
||||
dbm, priv->min_tx_power_level,
|
||||
priv->max_tx_power_level);
|
||||
" is out of range (%d dBm-%d dBm)\n",
|
||||
dbm, priv->min_tx_power_level,
|
||||
priv->max_tx_power_level);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
|
||||
__func__);
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -847,13 +845,13 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
|
||||
txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
|
||||
if (!power_cfg->is_power_auto) {
|
||||
txp_cfg->mode = cpu_to_le32(1);
|
||||
pg_tlv = (struct mwifiex_types_power_group *) (buf +
|
||||
sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
pg_tlv = (struct mwifiex_types_power_group *)
|
||||
(buf + sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
pg_tlv->type = TLV_TYPE_POWER_GROUP;
|
||||
pg_tlv->length = 4 * sizeof(struct mwifiex_power_group);
|
||||
pg = (struct mwifiex_power_group *) (buf +
|
||||
sizeof(struct host_cmd_ds_txpwr_cfg) +
|
||||
sizeof(struct mwifiex_types_power_group));
|
||||
pg = (struct mwifiex_power_group *)
|
||||
(buf + sizeof(struct host_cmd_ds_txpwr_cfg)
|
||||
+ sizeof(struct mwifiex_types_power_group));
|
||||
/* Power group for modulation class HR/DSSS */
|
||||
pg->first_rate_code = 0x00;
|
||||
pg->last_rate_code = 0x03;
|
||||
@ -916,8 +914,8 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
|
||||
sub_cmd, BITMAP_STA_PS, NULL);
|
||||
if ((!ret) && (sub_cmd == DIS_AUTO_PS))
|
||||
ret = mwifiex_send_cmd_async(priv,
|
||||
HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS,
|
||||
0, NULL);
|
||||
HostCmd_CMD_802_11_PS_MODE_ENH,
|
||||
GET_PS, 0, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -941,7 +939,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv,
|
||||
memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
|
||||
priv->wpa_ie_len = (u8) ie_len;
|
||||
dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n",
|
||||
priv->wpa_ie_len, priv->wpa_ie[0]);
|
||||
priv->wpa_ie_len, priv->wpa_ie[0]);
|
||||
|
||||
if (priv->wpa_ie[0] == WLAN_EID_WPA) {
|
||||
priv->sec_info.wpa_enabled = true;
|
||||
@ -982,7 +980,7 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
|
||||
memcpy(priv->wapi_ie, ie_data_ptr, ie_len);
|
||||
priv->wapi_ie_len = ie_len;
|
||||
dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n",
|
||||
priv->wapi_ie_len, priv->wapi_ie[0]);
|
||||
priv->wapi_ie_len, priv->wapi_ie[0]);
|
||||
|
||||
if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY)
|
||||
priv->sec_info.wapi_enabled = true;
|
||||
@ -1008,8 +1006,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
|
||||
{
|
||||
|
||||
return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
|
||||
HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
|
||||
encrypt_key);
|
||||
HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
|
||||
encrypt_key);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1103,9 +1101,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
|
||||
/* Send the key as PTK to firmware */
|
||||
encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
|
||||
ret = mwifiex_send_cmd_async(priv,
|
||||
HostCmd_CMD_802_11_KEY_MATERIAL,
|
||||
HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
|
||||
encrypt_key);
|
||||
HostCmd_CMD_802_11_KEY_MATERIAL,
|
||||
HostCmd_ACT_GEN_SET,
|
||||
KEY_INFO_ENABLED, encrypt_key);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1130,14 +1128,14 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
|
||||
|
||||
if (remove_key)
|
||||
ret = mwifiex_send_cmd_sync(priv,
|
||||
HostCmd_CMD_802_11_KEY_MATERIAL,
|
||||
HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED),
|
||||
encrypt_key);
|
||||
HostCmd_CMD_802_11_KEY_MATERIAL,
|
||||
HostCmd_ACT_GEN_SET,
|
||||
!KEY_INFO_ENABLED, encrypt_key);
|
||||
else
|
||||
ret = mwifiex_send_cmd_sync(priv,
|
||||
HostCmd_CMD_802_11_KEY_MATERIAL,
|
||||
HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
|
||||
encrypt_key);
|
||||
HostCmd_CMD_802_11_KEY_MATERIAL,
|
||||
HostCmd_ACT_GEN_SET,
|
||||
KEY_INFO_ENABLED, encrypt_key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1256,7 +1254,7 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv)
|
||||
|
||||
memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
|
||||
if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT,
|
||||
HostCmd_ACT_GEN_GET, 0, &ver_ext))
|
||||
HostCmd_ACT_GEN_GET, 0, &ver_ext))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@ -1273,7 +1271,7 @@ mwifiex_get_stats_info(struct mwifiex_private *priv,
|
||||
struct mwifiex_ds_get_stats *log)
|
||||
{
|
||||
return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
|
||||
HostCmd_ACT_GEN_GET, 0, log);
|
||||
HostCmd_ACT_GEN_GET, 0, log);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1413,9 +1411,9 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
|
||||
}
|
||||
pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
|
||||
/* Test to see if it is a WPA IE, if not, then it is a gen IE */
|
||||
if (((pvendor_ie->element_id == WLAN_EID_WPA)
|
||||
&& (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui))))
|
||||
|| (pvendor_ie->element_id == WLAN_EID_RSN)) {
|
||||
if (((pvendor_ie->element_id == WLAN_EID_WPA) &&
|
||||
(!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) ||
|
||||
(pvendor_ie->element_id == WLAN_EID_RSN)) {
|
||||
|
||||
/* IE is a WPA/WPA2 IE so call set_wpa function */
|
||||
ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
|
||||
@ -1438,9 +1436,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
|
||||
* wps session flag
|
||||
*/
|
||||
pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
|
||||
if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC)
|
||||
&& (!memcmp(pvendor_ie->oui, wps_oui,
|
||||
sizeof(wps_oui)))) {
|
||||
if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) &&
|
||||
(!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) {
|
||||
priv->wps.session_enable = true;
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: WPS Session Enabled.\n");
|
||||
@ -1449,7 +1446,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
|
||||
/* Append the passed data to the end of the
|
||||
genIeBuffer */
|
||||
memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr,
|
||||
ie_len);
|
||||
ie_len);
|
||||
/* Increment the stored buffer length by the
|
||||
size passed */
|
||||
priv->gen_ie_buf_len += ie_len;
|
||||
@ -1493,7 +1490,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(adapter->arp_filter, gen_ie->ie_data,
|
||||
gen_ie->len);
|
||||
gen_ie->len);
|
||||
adapter->arp_filter_size = gen_ie->len;
|
||||
}
|
||||
break;
|
||||
|
@ -43,8 +43,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
|
||||
{
|
||||
int ret;
|
||||
struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
|
||||
struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
|
||||
rx_info->bss_num, rx_info->bss_type);
|
||||
struct mwifiex_private *priv =
|
||||
mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
|
||||
rx_info->bss_type);
|
||||
struct rx_packet_hdr *rx_pkt_hdr;
|
||||
struct rxpd *local_rx_pd;
|
||||
int hdr_chop;
|
||||
@ -125,8 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
|
||||
struct rx_packet_hdr *rx_pkt_hdr;
|
||||
u8 ta[ETH_ALEN];
|
||||
u16 rx_pkt_type;
|
||||
struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
|
||||
rx_info->bss_num, rx_info->bss_type);
|
||||
struct mwifiex_private *priv =
|
||||
mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
|
||||
rx_info->bss_type);
|
||||
|
||||
if (!priv)
|
||||
return -1;
|
||||
@ -157,7 +159,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
|
||||
skb_trim(skb, local_rx_pd->rx_pkt_length);
|
||||
|
||||
ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
|
||||
priv->wdev->iftype, 0, false);
|
||||
priv->wdev->iftype, 0, false);
|
||||
|
||||
while (!skb_queue_empty(&list)) {
|
||||
rx_skb = __skb_dequeue(&list);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user