mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
This commit is contained in:
commit
8732baafc3
@ -1595,6 +1595,7 @@ M: Arend van Spriel <arend@broadcom.com>
|
||||
M: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
M: Kan Yan <kanyan@broadcom.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: brcm80211-dev-list@broadcom.com
|
||||
S: Supported
|
||||
F: drivers/net/wireless/brcm80211/
|
||||
|
||||
|
@ -28,6 +28,12 @@ static const struct bcma_device_id_name bcma_arm_device_names[] = {
|
||||
|
||||
static const struct bcma_device_id_name bcma_bcm_device_names[] = {
|
||||
{ BCMA_CORE_OOB_ROUTER, "OOB Router" },
|
||||
{ BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" },
|
||||
{ BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" },
|
||||
{ BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" },
|
||||
{ BCMA_CORE_AMEMC, "AMEMC (DDR)" },
|
||||
{ BCMA_CORE_ALTA, "ALTA (I2S)" },
|
||||
{ BCMA_CORE_4706_MAC_GBIT_COMMON, "BCM4706 GBit MAC Common" },
|
||||
{ BCMA_CORE_INVALID, "Invalid" },
|
||||
{ BCMA_CORE_CHIPCOMMON, "ChipCommon" },
|
||||
{ BCMA_CORE_ILINE20, "ILine 20" },
|
||||
|
@ -53,6 +53,11 @@
|
||||
|
||||
#define DEFAULT_BG_SCAN_PERIOD 60
|
||||
|
||||
struct ath6kl_cfg80211_match_probe_ssid {
|
||||
struct cfg80211_ssid ssid;
|
||||
u8 flag;
|
||||
};
|
||||
|
||||
static struct ieee80211_rate ath6kl_rates[] = {
|
||||
RATETAB_ENT(10, 0x1, 0),
|
||||
RATETAB_ENT(20, 0x2, 0),
|
||||
@ -576,6 +581,9 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
vif->nw_type = vif->next_mode;
|
||||
|
||||
/* enable enhanced bmiss detection if applicable */
|
||||
ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
|
||||
|
||||
if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
|
||||
nw_subtype = SUBTYPE_P2PCLIENT;
|
||||
|
||||
@ -852,20 +860,6 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a disconnect command to target when a disconnect event is
|
||||
* received with reason code other than 3 (DISCONNECT_CMD - disconnect
|
||||
* request from host) to make the firmware stop trying to connect even
|
||||
* after giving disconnect event. There will be one more disconnect
|
||||
* event for this disconnect command with reason code DISCONNECT_CMD
|
||||
* which will be notified to cfg80211.
|
||||
*/
|
||||
|
||||
if (reason != DISCONNECT_CMD) {
|
||||
ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
clear_bit(CONNECT_PEND, &vif->flags);
|
||||
|
||||
if (vif->sme_state == SME_CONNECTING) {
|
||||
@ -875,32 +869,96 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
|
||||
WLAN_STATUS_UNSPECIFIED_FAILURE,
|
||||
GFP_KERNEL);
|
||||
} else if (vif->sme_state == SME_CONNECTED) {
|
||||
cfg80211_disconnected(vif->ndev, reason,
|
||||
cfg80211_disconnected(vif->ndev, proto_reason,
|
||||
NULL, 0, GFP_KERNEL);
|
||||
}
|
||||
|
||||
vif->sme_state = SME_DISCONNECTED;
|
||||
|
||||
/*
|
||||
* Send a disconnect command to target when a disconnect event is
|
||||
* received with reason code other than 3 (DISCONNECT_CMD - disconnect
|
||||
* request from host) to make the firmware stop trying to connect even
|
||||
* after giving disconnect event. There will be one more disconnect
|
||||
* event for this disconnect command with reason code DISCONNECT_CMD
|
||||
* which won't be notified to cfg80211.
|
||||
*/
|
||||
if (reason != DISCONNECT_CMD)
|
||||
ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
|
||||
}
|
||||
|
||||
static int ath6kl_set_probed_ssids(struct ath6kl *ar,
|
||||
struct ath6kl_vif *vif,
|
||||
struct cfg80211_ssid *ssids, int n_ssids)
|
||||
struct cfg80211_ssid *ssids, int n_ssids,
|
||||
struct cfg80211_match_set *match_set,
|
||||
int n_match_ssid)
|
||||
{
|
||||
u8 i;
|
||||
u8 i, j, index_to_add, ssid_found = false;
|
||||
struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
|
||||
|
||||
if (n_ssids > MAX_PROBED_SSID_INDEX)
|
||||
memset(ssid_list, 0, sizeof(ssid_list));
|
||||
|
||||
if (n_ssids > MAX_PROBED_SSIDS ||
|
||||
n_match_ssid > MAX_PROBED_SSIDS)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < n_ssids; i++) {
|
||||
memcpy(ssid_list[i].ssid.ssid,
|
||||
ssids[i].ssid,
|
||||
ssids[i].ssid_len);
|
||||
ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
|
||||
|
||||
if (ssids[i].ssid_len)
|
||||
ssid_list[i].flag = SPECIFIC_SSID_FLAG;
|
||||
else
|
||||
ssid_list[i].flag = ANY_SSID_FLAG;
|
||||
|
||||
if (n_match_ssid == 0)
|
||||
ssid_list[i].flag |= MATCH_SSID_FLAG;
|
||||
}
|
||||
|
||||
index_to_add = i;
|
||||
|
||||
for (i = 0; i < n_match_ssid; i++) {
|
||||
ssid_found = false;
|
||||
|
||||
for (j = 0; j < n_ssids; j++) {
|
||||
if ((match_set[i].ssid.ssid_len ==
|
||||
ssid_list[j].ssid.ssid_len) &&
|
||||
(!memcmp(ssid_list[j].ssid.ssid,
|
||||
match_set[i].ssid.ssid,
|
||||
match_set[i].ssid.ssid_len))) {
|
||||
ssid_list[j].flag |= MATCH_SSID_FLAG;
|
||||
ssid_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ssid_found)
|
||||
continue;
|
||||
|
||||
if (index_to_add >= MAX_PROBED_SSIDS)
|
||||
continue;
|
||||
|
||||
ssid_list[index_to_add].ssid.ssid_len =
|
||||
match_set[i].ssid.ssid_len;
|
||||
memcpy(ssid_list[index_to_add].ssid.ssid,
|
||||
match_set[i].ssid.ssid,
|
||||
match_set[i].ssid.ssid_len);
|
||||
ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
|
||||
index_to_add++;
|
||||
}
|
||||
|
||||
for (i = 0; i < index_to_add; i++) {
|
||||
ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
|
||||
ssids[i].ssid_len ?
|
||||
SPECIFIC_SSID_FLAG : ANY_SSID_FLAG,
|
||||
ssids[i].ssid_len,
|
||||
ssids[i].ssid);
|
||||
ssid_list[i].flag,
|
||||
ssid_list[i].ssid.ssid_len,
|
||||
ssid_list[i].ssid.ssid);
|
||||
|
||||
}
|
||||
|
||||
/* Make sure no old entries are left behind */
|
||||
for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) {
|
||||
for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
|
||||
ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
|
||||
DISABLE_SSID_FLAG, 0, NULL);
|
||||
}
|
||||
@ -934,7 +992,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
}
|
||||
|
||||
ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
|
||||
request->n_ssids);
|
||||
request->n_ssids, NULL, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -943,7 +1001,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
WMI_FRAME_PROBE_REQ,
|
||||
request->ie, request->ie_len);
|
||||
if (ret) {
|
||||
ath6kl_err("failed to set Probe Request appie for scan");
|
||||
ath6kl_err("failed to set Probe Request appie for scan\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1512,6 +1570,9 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
|
||||
}
|
||||
}
|
||||
|
||||
/* need to clean up enhanced bmiss detection fw state */
|
||||
ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
|
||||
|
||||
set_iface_type:
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@ -2074,7 +2135,9 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
||||
if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
|
||||
return -EINVAL;
|
||||
|
||||
if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) {
|
||||
if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
|
||||
test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
|
||||
ar->fw_capabilities)) {
|
||||
ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
|
||||
vif->fw_vif_idx, false);
|
||||
if (ret)
|
||||
@ -2209,7 +2272,9 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
|
||||
|
||||
ar->state = ATH6KL_STATE_ON;
|
||||
|
||||
if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) {
|
||||
if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
|
||||
test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
|
||||
ar->fw_capabilities)) {
|
||||
ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
|
||||
vif->fw_vif_idx, true);
|
||||
if (ret)
|
||||
@ -2475,7 +2540,7 @@ void ath6kl_check_wow_status(struct ath6kl *ar)
|
||||
static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
|
||||
bool ht_enable)
|
||||
{
|
||||
struct ath6kl_htcap *htcap = &vif->htcap;
|
||||
struct ath6kl_htcap *htcap = &vif->htcap[band];
|
||||
|
||||
if (htcap->ht_enable == ht_enable)
|
||||
return 0;
|
||||
@ -2585,6 +2650,30 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
|
||||
return;
|
||||
|
||||
if (vif->nw_type != INFRA_NETWORK)
|
||||
return;
|
||||
|
||||
if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
|
||||
vif->ar->fw_capabilities))
|
||||
return;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
|
||||
enable ? "enable" : "disable");
|
||||
|
||||
err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
|
||||
vif->fw_vif_idx, enable);
|
||||
if (err)
|
||||
ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
|
||||
enable ? "enable" : "disable", err);
|
||||
}
|
||||
|
||||
static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
|
||||
u8 *rsn_capab)
|
||||
{
|
||||
@ -2665,9 +2754,15 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
/* TODO:
|
||||
* info->interval
|
||||
* info->dtim_period
|
||||
*/
|
||||
|
||||
ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
info->dtim_period);
|
||||
|
||||
/* ignore error, just print a warning and continue normally */
|
||||
if (ret)
|
||||
ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
|
||||
|
||||
if (info->beacon.head == NULL)
|
||||
return -EINVAL;
|
||||
mgmt = (struct ieee80211_mgmt *) info->beacon.head;
|
||||
@ -3131,10 +3226,24 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
|
||||
ath6kl_cfg80211_scan_complete_event(vif, true);
|
||||
|
||||
ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
|
||||
request->n_ssids);
|
||||
request->n_ssids,
|
||||
request->match_sets,
|
||||
request->n_match_sets);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!request->n_match_sets) {
|
||||
ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
ALL_BSS_FILTER, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
MATCHED_SSID_FILTER, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* fw uses seconds, also make sure that it's >0 */
|
||||
interval = max_t(u16, 1, request->interval / 1000);
|
||||
|
||||
@ -3156,7 +3265,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
|
||||
WMI_FRAME_PROBE_REQ,
|
||||
request->ie, request->ie_len);
|
||||
if (ret) {
|
||||
ath6kl_warn("Failed to set probe request IE for scheduled scan: %d",
|
||||
ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
@ -3188,6 +3297,18 @@ static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
const u8 *addr,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct ath6kl *ar = ath6kl_priv(dev);
|
||||
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||
|
||||
return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
|
||||
mask);
|
||||
}
|
||||
|
||||
static const struct ieee80211_txrx_stypes
|
||||
ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
||||
[NL80211_IFTYPE_STATION] = {
|
||||
@ -3253,6 +3374,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
|
||||
.mgmt_frame_register = ath6kl_mgmt_frame_register,
|
||||
.sched_scan_start = ath6kl_cfg80211_sscan_start,
|
||||
.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
|
||||
.set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
|
||||
};
|
||||
|
||||
void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
|
||||
@ -3380,7 +3502,8 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
|
||||
vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
|
||||
vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
|
||||
vif->bg_scan_period = 0;
|
||||
vif->htcap.ht_enable = true;
|
||||
vif->htcap[IEEE80211_BAND_2GHZ].ht_enable = true;
|
||||
vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true;
|
||||
|
||||
memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
|
||||
if (fw_vif_idx != 0)
|
||||
@ -3440,7 +3563,13 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||
}
|
||||
|
||||
/* max num of ssids that can be probed during scanning */
|
||||
wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
|
||||
wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
|
||||
|
||||
/* max num of ssids that can be matched after scan */
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
|
||||
ar->fw_capabilities))
|
||||
wiphy->max_match_sets = MAX_PROBED_SSIDS;
|
||||
|
||||
wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
|
||||
switch (ar->hw.cap) {
|
||||
case WMI_11AN_CAP:
|
||||
@ -3477,6 +3606,17 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||
ath6kl_band_5ghz.ht_cap.cap = 0;
|
||||
ath6kl_band_5ghz.ht_cap.ht_supported = false;
|
||||
}
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) {
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||
} else {
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
}
|
||||
|
||||
if (band_2gig)
|
||||
wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
|
||||
if (band_5gig)
|
||||
@ -3497,7 +3637,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||
wiphy->wowlan.pattern_min_len = 1;
|
||||
wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
|
||||
|
||||
wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX;
|
||||
wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
|
||||
|
||||
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
|
||||
WIPHY_FLAG_HAVE_AP_SME |
|
||||
|
@ -62,5 +62,7 @@ void ath6kl_cfg80211_cleanup(struct ath6kl *ar);
|
||||
|
||||
struct ath6kl *ath6kl_cfg80211_create(void);
|
||||
void ath6kl_cfg80211_destroy(struct ath6kl *ar);
|
||||
/* TODO: remove this once ath6kl_vif_cleanup() is moved to cfg80211.c */
|
||||
void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable);
|
||||
|
||||
#endif /* ATH6KL_CFG80211_H */
|
||||
|
@ -100,6 +100,21 @@ enum ath6kl_fw_capability {
|
||||
/* Firmware has support to override rsn cap of rsn ie */
|
||||
ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
|
||||
|
||||
/*
|
||||
* Multicast support in WOW and host awake mode.
|
||||
* Allow all multicast in host awake mode.
|
||||
* Apply multicast filter in WOW mode.
|
||||
*/
|
||||
ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
|
||||
|
||||
/* Firmware supports enhanced bmiss detection */
|
||||
ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
|
||||
|
||||
/*
|
||||
* FW supports matching of ssid in schedule scan
|
||||
*/
|
||||
ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
|
||||
|
||||
/* this needs to be last */
|
||||
ATH6KL_FW_CAPABILITY_MAX,
|
||||
};
|
||||
@ -112,6 +127,10 @@ struct ath6kl_fw_ie {
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
enum ath6kl_hw_flags {
|
||||
ATH6KL_HW_FLAG_64BIT_RATES = BIT(0),
|
||||
};
|
||||
|
||||
#define ATH6KL_FW_API2_FILE "fw-2.bin"
|
||||
#define ATH6KL_FW_API3_FILE "fw-3.bin"
|
||||
|
||||
@ -196,7 +215,7 @@ struct ath6kl_fw_ie {
|
||||
|
||||
#define AGGR_NUM_OF_FREE_NETBUFS 16
|
||||
|
||||
#define AGGR_RX_TIMEOUT 400 /* in ms */
|
||||
#define AGGR_RX_TIMEOUT 100 /* in ms */
|
||||
|
||||
#define WMI_TIMEOUT (2 * HZ)
|
||||
|
||||
@ -245,7 +264,6 @@ struct skb_hold_q {
|
||||
|
||||
struct rxtid {
|
||||
bool aggr;
|
||||
bool progress;
|
||||
bool timer_mon;
|
||||
u16 win_sz;
|
||||
u16 seq_next;
|
||||
@ -254,9 +272,15 @@ struct rxtid {
|
||||
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.
|
||||
* lock mainly protects seq_next and hold_q. Movement of seq_next
|
||||
* needs to be protected between aggr_timeout() and
|
||||
* aggr_process_recv_frm(). hold_q will be holding the pending
|
||||
* reorder frames and it's access should also be protected.
|
||||
* Some of the other fields like hold_q_sz, win_sz and aggr are
|
||||
* initialized/reset when receiving addba/delba req, also while
|
||||
* deleting aggr state all the pending buffers are flushed before
|
||||
* resetting these fields, so there should not be any race in accessing
|
||||
* these fields.
|
||||
*/
|
||||
spinlock_t lock;
|
||||
};
|
||||
@ -541,7 +565,7 @@ struct ath6kl_vif {
|
||||
struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
|
||||
struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
|
||||
struct aggr_info *aggr_cntxt;
|
||||
struct ath6kl_htcap htcap;
|
||||
struct ath6kl_htcap htcap[IEEE80211_NUM_BANDS];
|
||||
|
||||
struct timer_list disconnect_timer;
|
||||
struct timer_list sched_scan_timer;
|
||||
@ -684,6 +708,8 @@ struct ath6kl {
|
||||
u32 testscript_addr;
|
||||
enum wmi_phy_cap cap;
|
||||
|
||||
u32 flags;
|
||||
|
||||
struct ath6kl_hw_fw {
|
||||
const char *dir;
|
||||
const char *otp;
|
||||
|
@ -1309,7 +1309,7 @@ static int ath6kl_htc_rx_packet(struct htc_target *target,
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_HTC,
|
||||
"htc rx 0x%p hdr x%x len %d mbox 0x%x\n",
|
||||
"htc rx 0x%p hdr 0x%x len %d mbox 0x%x\n",
|
||||
packet, packet->info.rx.exp_hdr,
|
||||
padded_len, dev->ar->mbox_info.htc_addr);
|
||||
|
||||
|
@ -42,6 +42,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.reserved_ram_size = 6912,
|
||||
.refclk_hz = 26000000,
|
||||
.uarttx_pin = 8,
|
||||
.flags = 0,
|
||||
|
||||
/* hw2.0 needs override address hardcoded */
|
||||
.app_start_override_addr = 0x944C00,
|
||||
@ -67,6 +68,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.refclk_hz = 26000000,
|
||||
.uarttx_pin = 8,
|
||||
.testscript_addr = 0x57ef74,
|
||||
.flags = 0,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6003_HW_2_1_1_FW_DIR,
|
||||
@ -91,6 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.board_addr = 0x433900,
|
||||
.refclk_hz = 26000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_FLAG_64BIT_RATES,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_0_FW_DIR,
|
||||
@ -110,6 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.board_addr = 0x43d400,
|
||||
.refclk_hz = 40000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_FLAG_64BIT_RATES,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_1_FW_DIR,
|
||||
@ -129,6 +133,7 @@ static const struct ath6kl_hw hw_list[] = {
|
||||
.board_addr = 0x435c00,
|
||||
.refclk_hz = 40000000,
|
||||
.uarttx_pin = 11,
|
||||
.flags = ATH6KL_HW_FLAG_64BIT_RATES,
|
||||
|
||||
.fw = {
|
||||
.dir = AR6004_HW_1_2_FW_DIR,
|
||||
@ -938,6 +943,14 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
}
|
||||
|
||||
switch (ie_id) {
|
||||
case ATH6KL_FW_IE_FW_VERSION:
|
||||
strlcpy(ar->wiphy->fw_version, data,
|
||||
sizeof(ar->wiphy->fw_version));
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT,
|
||||
"found fw version %s\n",
|
||||
ar->wiphy->fw_version);
|
||||
break;
|
||||
case ATH6KL_FW_IE_OTP_IMAGE:
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
|
||||
ie_len);
|
||||
@ -991,9 +1004,6 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
ar->hw.reserved_ram_size);
|
||||
break;
|
||||
case ATH6KL_FW_IE_CAPABILITIES:
|
||||
if (ie_len < DIV_ROUND_UP(ATH6KL_FW_CAPABILITY_MAX, 8))
|
||||
break;
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT,
|
||||
"found firmware capabilities ie (%zd B)\n",
|
||||
ie_len);
|
||||
@ -1002,6 +1012,9 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
index = i / 8;
|
||||
bit = i % 8;
|
||||
|
||||
if (index == ie_len)
|
||||
break;
|
||||
|
||||
if (data[index] & (1 << bit))
|
||||
__set_bit(i, ar->fw_capabilities);
|
||||
}
|
||||
@ -1392,6 +1405,12 @@ static int ath6kl_init_upload(struct ath6kl *ar)
|
||||
ar->version.target_ver == AR6003_HW_2_1_1_VERSION) {
|
||||
ath6kl_err("temporary war to avoid sdio crc error\n");
|
||||
|
||||
param = 0x28;
|
||||
address = GPIO_BASE_ADDRESS + GPIO_PIN9_ADDRESS;
|
||||
status = ath6kl_bmi_reg_write(ar, address, param);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
param = 0x20;
|
||||
|
||||
address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
|
||||
@ -1659,6 +1678,9 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
|
||||
cfg80211_scan_done(vif->scan_req, true);
|
||||
vif->scan_req = NULL;
|
||||
}
|
||||
|
||||
/* need to clean up enhanced bmiss detection fw state */
|
||||
ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
|
||||
}
|
||||
|
||||
void ath6kl_stop_txrx(struct ath6kl *ar)
|
||||
|
@ -554,20 +554,24 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,
|
||||
struct ath6kl *ar = devt;
|
||||
|
||||
memcpy(ar->mac_addr, datap, ETH_ALEN);
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
|
||||
__func__, ar->mac_addr);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT,
|
||||
"ready event mac addr %pM sw_ver 0x%x abi_ver 0x%x cap 0x%x\n",
|
||||
ar->mac_addr, sw_ver, abi_ver, cap);
|
||||
|
||||
ar->version.wlan_ver = sw_ver;
|
||||
ar->version.abi_ver = abi_ver;
|
||||
ar->hw.cap = cap;
|
||||
|
||||
snprintf(ar->wiphy->fw_version,
|
||||
sizeof(ar->wiphy->fw_version),
|
||||
"%u.%u.%u.%u",
|
||||
(ar->version.wlan_ver & 0xf0000000) >> 28,
|
||||
(ar->version.wlan_ver & 0x0f000000) >> 24,
|
||||
(ar->version.wlan_ver & 0x00ff0000) >> 16,
|
||||
(ar->version.wlan_ver & 0x0000ffff));
|
||||
if (strlen(ar->wiphy->fw_version) == 0) {
|
||||
snprintf(ar->wiphy->fw_version,
|
||||
sizeof(ar->wiphy->fw_version),
|
||||
"%u.%u.%u.%u",
|
||||
(ar->version.wlan_ver & 0xf0000000) >> 28,
|
||||
(ar->version.wlan_ver & 0x0f000000) >> 24,
|
||||
(ar->version.wlan_ver & 0x00ff0000) >> 16,
|
||||
(ar->version.wlan_ver & 0x0000ffff));
|
||||
}
|
||||
|
||||
/* indicate to the waiting thread that the ready event was received */
|
||||
set_bit(WMI_READY, &ar->flag);
|
||||
@ -1166,7 +1170,10 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
else
|
||||
clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
|
||||
|
||||
mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
|
||||
vif->ar->fw_capabilities)) {
|
||||
mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
|
||||
}
|
||||
|
||||
if (!(ndev->flags & IFF_MULTICAST)) {
|
||||
mc_all_on = false;
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define LPO_CAL_ENABLE_S 20
|
||||
#define LPO_CAL_ENABLE 0x00100000
|
||||
|
||||
#define GPIO_PIN9_ADDRESS 0x0000004c
|
||||
#define GPIO_PIN10_ADDRESS 0x00000050
|
||||
#define GPIO_PIN11_ADDRESS 0x00000054
|
||||
#define GPIO_PIN12_ADDRESS 0x00000058
|
||||
|
@ -1036,6 +1036,7 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
|
||||
rxtid = &agg_conn->rx_tid[tid];
|
||||
stats = &agg_conn->stat[tid];
|
||||
|
||||
spin_lock_bh(&rxtid->lock);
|
||||
idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
|
||||
|
||||
/*
|
||||
@ -1054,8 +1055,6 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
|
||||
seq_end = seq_no ? seq_no : rxtid->seq_next;
|
||||
idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
|
||||
|
||||
spin_lock_bh(&rxtid->lock);
|
||||
|
||||
do {
|
||||
node = &rxtid->hold_q[idx];
|
||||
if ((order == 1) && (!node->skb))
|
||||
@ -1127,11 +1126,13 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
|
||||
((end > extended_end) && (cur > extended_end) &&
|
||||
(cur < end))) {
|
||||
aggr_deque_frms(agg_conn, tid, 0, 0);
|
||||
spin_lock_bh(&rxtid->lock);
|
||||
if (cur >= rxtid->hold_q_sz - 1)
|
||||
rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
|
||||
else
|
||||
rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
|
||||
(rxtid->hold_q_sz - 2 - cur);
|
||||
spin_unlock_bh(&rxtid->lock);
|
||||
} else {
|
||||
/*
|
||||
* Dequeue only those frames that are outside the
|
||||
@ -1185,25 +1186,25 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
|
||||
aggr_deque_frms(agg_conn, tid, 0, 1);
|
||||
|
||||
if (agg_conn->timer_scheduled)
|
||||
rxtid->progress = true;
|
||||
else
|
||||
for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
|
||||
if (rxtid->hold_q[idx].skb) {
|
||||
/*
|
||||
* There is a frame in the queue and no
|
||||
* timer so start a timer to ensure that
|
||||
* the frame doesn't remain stuck
|
||||
* forever.
|
||||
*/
|
||||
agg_conn->timer_scheduled = true;
|
||||
mod_timer(&agg_conn->timer,
|
||||
(jiffies +
|
||||
HZ * (AGGR_RX_TIMEOUT) / 1000));
|
||||
rxtid->progress = false;
|
||||
rxtid->timer_mon = true;
|
||||
break;
|
||||
}
|
||||
return is_queued;
|
||||
|
||||
spin_lock_bh(&rxtid->lock);
|
||||
for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
|
||||
if (rxtid->hold_q[idx].skb) {
|
||||
/*
|
||||
* There is a frame in the queue and no
|
||||
* timer so start a timer to ensure that
|
||||
* the frame doesn't remain stuck
|
||||
* forever.
|
||||
*/
|
||||
agg_conn->timer_scheduled = true;
|
||||
mod_timer(&agg_conn->timer,
|
||||
(jiffies + (HZ * AGGR_RX_TIMEOUT) / 1000));
|
||||
rxtid->timer_mon = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&rxtid->lock);
|
||||
|
||||
return is_queued;
|
||||
}
|
||||
@ -1608,7 +1609,7 @@ static void aggr_timeout(unsigned long arg)
|
||||
rxtid = &aggr_conn->rx_tid[i];
|
||||
stats = &aggr_conn->stat[i];
|
||||
|
||||
if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
|
||||
if (!rxtid->aggr || !rxtid->timer_mon)
|
||||
continue;
|
||||
|
||||
stats->num_timeouts++;
|
||||
@ -1626,14 +1627,15 @@ static void aggr_timeout(unsigned long arg)
|
||||
rxtid = &aggr_conn->rx_tid[i];
|
||||
|
||||
if (rxtid->aggr && rxtid->hold_q) {
|
||||
spin_lock_bh(&rxtid->lock);
|
||||
for (j = 0; j < rxtid->hold_q_sz; j++) {
|
||||
if (rxtid->hold_q[j].skb) {
|
||||
aggr_conn->timer_scheduled = true;
|
||||
rxtid->timer_mon = true;
|
||||
rxtid->progress = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&rxtid->lock);
|
||||
|
||||
if (j >= rxtid->hold_q_sz)
|
||||
rxtid->timer_mon = false;
|
||||
@ -1660,7 +1662,6 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)
|
||||
aggr_deque_frms(aggr_conn, tid, 0, 0);
|
||||
|
||||
rxtid->aggr = false;
|
||||
rxtid->progress = false;
|
||||
rxtid->timer_mon = false;
|
||||
rxtid->win_sz = 0;
|
||||
rxtid->seq_next = 0;
|
||||
@ -1739,7 +1740,6 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
|
||||
for (i = 0; i < NUM_OF_TIDS; i++) {
|
||||
rxtid = &aggr_conn->rx_tid[i];
|
||||
rxtid->aggr = false;
|
||||
rxtid->progress = false;
|
||||
rxtid->timer_mon = false;
|
||||
skb_queue_head_init(&rxtid->q);
|
||||
spin_lock_init(&rxtid->lock);
|
||||
|
@ -743,7 +743,6 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct roam_ctrl_cmd *) skb->data;
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
memcpy(cmd->info.bssid, bssid, ETH_ALEN);
|
||||
cmd->roam_ctrl = WMI_FORCE_ROAM;
|
||||
@ -753,6 +752,22 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
|
||||
NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct set_dtim_cmd *cmd;
|
||||
|
||||
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct set_dtim_cmd *) skb->data;
|
||||
|
||||
cmd->dtim_period = cpu_to_le32(dtim_period);
|
||||
return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
|
||||
WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG);
|
||||
}
|
||||
|
||||
int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@ -763,7 +778,6 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct roam_ctrl_cmd *) skb->data;
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
cmd->info.roam_mode = mode;
|
||||
cmd->roam_ctrl = WMI_SET_ROAM_MODE;
|
||||
@ -1995,7 +2009,7 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
|
||||
struct wmi_probed_ssid_cmd *cmd;
|
||||
int ret;
|
||||
|
||||
if (index > MAX_PROBED_SSID_INDEX)
|
||||
if (index >= MAX_PROBED_SSIDS)
|
||||
return -EINVAL;
|
||||
|
||||
if (ssid_len > sizeof(cmd->ssid))
|
||||
@ -2599,6 +2613,115 @@ static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi)
|
||||
spin_unlock_bh(&wmi->lock);
|
||||
}
|
||||
|
||||
static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret, mode, band;
|
||||
u64 mcsrate, ratemask[IEEE80211_NUM_BANDS];
|
||||
struct wmi_set_tx_select_rates64_cmd *cmd;
|
||||
|
||||
memset(&ratemask, 0, sizeof(ratemask));
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
/* copy legacy rate mask */
|
||||
ratemask[band] = mask->control[band].legacy;
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
ratemask[band] =
|
||||
mask->control[band].legacy << 4;
|
||||
|
||||
/* copy mcs rate mask */
|
||||
mcsrate = mask->control[band].mcs[1];
|
||||
mcsrate <<= 8;
|
||||
mcsrate |= mask->control[band].mcs[0];
|
||||
ratemask[band] |= mcsrate << 12;
|
||||
ratemask[band] |= mcsrate << 28;
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"Ratemask 64 bit: 2.4:%llx 5:%llx\n",
|
||||
ratemask[0], ratemask[1]);
|
||||
|
||||
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_set_tx_select_rates64_cmd *) skb->data;
|
||||
for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) {
|
||||
/* A mode operate in 5GHZ band */
|
||||
if (mode == WMI_RATES_MODE_11A ||
|
||||
mode == WMI_RATES_MODE_11A_HT20 ||
|
||||
mode == WMI_RATES_MODE_11A_HT40)
|
||||
band = IEEE80211_BAND_5GHZ;
|
||||
else
|
||||
band = IEEE80211_BAND_2GHZ;
|
||||
cmd->ratemask[mode] = cpu_to_le64(ratemask[band]);
|
||||
}
|
||||
|
||||
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
|
||||
WMI_SET_TX_SELECT_RATES_CMDID,
|
||||
NO_SYNC_WMIFLAG);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret, mode, band;
|
||||
u32 mcsrate, ratemask[IEEE80211_NUM_BANDS];
|
||||
struct wmi_set_tx_select_rates32_cmd *cmd;
|
||||
|
||||
memset(&ratemask, 0, sizeof(ratemask));
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
/* copy legacy rate mask */
|
||||
ratemask[band] = mask->control[band].legacy;
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
ratemask[band] =
|
||||
mask->control[band].legacy << 4;
|
||||
|
||||
/* copy mcs rate mask */
|
||||
mcsrate = mask->control[band].mcs[0];
|
||||
ratemask[band] |= mcsrate << 12;
|
||||
ratemask[band] |= mcsrate << 20;
|
||||
}
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI,
|
||||
"Ratemask 32 bit: 2.4:%x 5:%x\n",
|
||||
ratemask[0], ratemask[1]);
|
||||
|
||||
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_set_tx_select_rates32_cmd *) skb->data;
|
||||
for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) {
|
||||
/* A mode operate in 5GHZ band */
|
||||
if (mode == WMI_RATES_MODE_11A ||
|
||||
mode == WMI_RATES_MODE_11A_HT20 ||
|
||||
mode == WMI_RATES_MODE_11A_HT40)
|
||||
band = IEEE80211_BAND_5GHZ;
|
||||
else
|
||||
band = IEEE80211_BAND_2GHZ;
|
||||
cmd->ratemask[mode] = cpu_to_le32(ratemask[band]);
|
||||
}
|
||||
|
||||
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
|
||||
WMI_SET_TX_SELECT_RATES_CMDID,
|
||||
NO_SYNC_WMIFLAG);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct ath6kl *ar = wmi->parent_dev;
|
||||
|
||||
if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES)
|
||||
return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
|
||||
else
|
||||
return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
|
||||
}
|
||||
|
||||
int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
|
||||
enum ath6kl_host_mode host_mode)
|
||||
{
|
||||
@ -2997,6 +3120,25 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct wmi_sta_bmiss_enhance_cmd *cmd;
|
||||
int ret;
|
||||
|
||||
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_sta_bmiss_enhance_cmd *) skb->data;
|
||||
cmd->enable = enhance ? 1 : 0;
|
||||
|
||||
ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
|
||||
WMI_STA_BMISS_ENHANCE_CMDID,
|
||||
NO_SYNC_WMIFLAG);
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 ath6kl_wmi_get_rate(s8 rate_index)
|
||||
{
|
||||
if (rate_index == RATE_AUTO)
|
||||
|
@ -624,6 +624,10 @@ enum wmi_cmd_id {
|
||||
WMI_SEND_MGMT_CMDID,
|
||||
WMI_BEGIN_SCAN_CMDID,
|
||||
|
||||
WMI_SET_BLACK_LIST,
|
||||
WMI_SET_MCASTRATE,
|
||||
|
||||
WMI_STA_BMISS_ENHANCE_CMDID,
|
||||
};
|
||||
|
||||
enum wmi_mgmt_frame_type {
|
||||
@ -960,6 +964,9 @@ enum wmi_bss_filter {
|
||||
/* beacons matching probed ssid */
|
||||
PROBED_SSID_FILTER,
|
||||
|
||||
/* beacons matching matched ssid */
|
||||
MATCHED_SSID_FILTER,
|
||||
|
||||
/* marker only */
|
||||
LAST_BSS_FILTER,
|
||||
};
|
||||
@ -978,7 +985,7 @@ struct wmi_bss_filter_cmd {
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_PROBED_SSID_CMDID */
|
||||
#define MAX_PROBED_SSID_INDEX 9
|
||||
#define MAX_PROBED_SSIDS 16
|
||||
|
||||
enum wmi_ssid_flag {
|
||||
/* disables entry */
|
||||
@ -989,10 +996,13 @@ enum wmi_ssid_flag {
|
||||
|
||||
/* probes for any ssid */
|
||||
ANY_SSID_FLAG = 0x02,
|
||||
|
||||
/* match for ssid */
|
||||
MATCH_SSID_FLAG = 0x08,
|
||||
};
|
||||
|
||||
struct wmi_probed_ssid_cmd {
|
||||
/* 0 to MAX_PROBED_SSID_INDEX */
|
||||
/* 0 to MAX_PROBED_SSIDS - 1 */
|
||||
u8 entry_index;
|
||||
|
||||
/* see, enum wmi_ssid_flg */
|
||||
@ -1017,6 +1027,11 @@ struct wmi_bmiss_time_cmd {
|
||||
__le16 num_beacons;
|
||||
};
|
||||
|
||||
/* WMI_STA_ENHANCE_BMISS_CMDID */
|
||||
struct wmi_sta_bmiss_enhance_cmd {
|
||||
u8 enable;
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_POWER_MODE_CMDID */
|
||||
enum wmi_power_mode {
|
||||
REC_POWER = 0x01,
|
||||
@ -1048,6 +1063,36 @@ struct wmi_power_params_cmd {
|
||||
__le16 ps_fail_event_policy;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Ratemask for below modes should be passed
|
||||
* to WMI_SET_TX_SELECT_RATES_CMDID.
|
||||
* AR6003 has 32 bit mask for each modes.
|
||||
* First 12 bits for legacy rates, 13 to 20
|
||||
* bits for HT 20 rates and 21 to 28 bits for
|
||||
* HT 40 rates
|
||||
*/
|
||||
enum wmi_mode_phy {
|
||||
WMI_RATES_MODE_11A = 0,
|
||||
WMI_RATES_MODE_11G,
|
||||
WMI_RATES_MODE_11B,
|
||||
WMI_RATES_MODE_11GONLY,
|
||||
WMI_RATES_MODE_11A_HT20,
|
||||
WMI_RATES_MODE_11G_HT20,
|
||||
WMI_RATES_MODE_11A_HT40,
|
||||
WMI_RATES_MODE_11G_HT40,
|
||||
WMI_RATES_MODE_MAX
|
||||
};
|
||||
|
||||
/* WMI_SET_TX_SELECT_RATES_CMDID */
|
||||
struct wmi_set_tx_select_rates32_cmd {
|
||||
__le32 ratemask[WMI_RATES_MODE_MAX];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_TX_SELECT_RATES_CMDID */
|
||||
struct wmi_set_tx_select_rates64_cmd {
|
||||
__le64 ratemask[WMI_RATES_MODE_MAX];
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_DISC_TIMEOUT_CMDID */
|
||||
struct wmi_disc_timeout_cmd {
|
||||
/* seconds */
|
||||
@ -1572,6 +1617,10 @@ struct roam_ctrl_cmd {
|
||||
u8 roam_ctrl;
|
||||
} __packed;
|
||||
|
||||
struct set_dtim_cmd {
|
||||
__le32 dtim_period;
|
||||
} __packed;
|
||||
|
||||
/* BSS INFO HDR version 2.0 */
|
||||
struct wmi_bss_info_hdr2 {
|
||||
__le16 ch; /* frequency in MHz */
|
||||
@ -2532,6 +2581,8 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
|
||||
__be32 ips0, __be32 ips1);
|
||||
int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
|
||||
enum ath6kl_host_mode host_mode);
|
||||
int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
|
||||
const struct cfg80211_bitrate_mask *mask);
|
||||
int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
|
||||
enum ath6kl_wow_mode wow_mode,
|
||||
u32 filter, u16 host_req_delay);
|
||||
@ -2542,11 +2593,14 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
|
||||
int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
|
||||
u16 list_id, u16 filter_id);
|
||||
int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
|
||||
int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period);
|
||||
int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
|
||||
int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
|
||||
int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
|
||||
int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
|
||||
u8 *filter, bool add_filter);
|
||||
int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable);
|
||||
|
||||
/* AP mode uAPSD */
|
||||
int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
|
||||
|
||||
|
@ -104,11 +104,6 @@ static const struct ani_cck_level_entry cck_level_table[] = {
|
||||
#define ATH9K_ANI_CCK_DEF_LEVEL \
|
||||
2 /* default level - matches the INI settings */
|
||||
|
||||
static bool use_new_ani(struct ath_hw *ah)
|
||||
{
|
||||
return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
|
||||
}
|
||||
|
||||
static void ath9k_hw_update_mibstats(struct ath_hw *ah,
|
||||
struct ath9k_mib_stats *stats)
|
||||
{
|
||||
@ -122,8 +117,6 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
|
||||
static void ath9k_ani_restart(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 ofdm_base = 0, cck_base = 0;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
@ -131,18 +124,10 @@ static void ath9k_ani_restart(struct ath_hw *ah)
|
||||
aniState = &ah->curchan->ani;
|
||||
aniState->listenTime = 0;
|
||||
|
||||
if (!use_new_ani(ah)) {
|
||||
ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
|
||||
cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
|
||||
}
|
||||
|
||||
ath_dbg(common, ANI, "Writing ofdmbase=%u cckbase=%u\n",
|
||||
ofdm_base, cck_base);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, 0);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, 0);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
@ -154,129 +139,23 @@ static void ath9k_ani_restart(struct ath_hw *ah)
|
||||
aniState->cckPhyErrCount = 0;
|
||||
}
|
||||
|
||||
static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
|
||||
{
|
||||
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
|
||||
struct ar5416AniState *aniState;
|
||||
int32_t rssi;
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
|
||||
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel + 1)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
|
||||
if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel + 1)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ah->opmode == NL80211_IFTYPE_AP) {
|
||||
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
rssi = BEACON_RSSI(ah);
|
||||
if (rssi > aniState->rssiThrHigh) {
|
||||
if (!aniState->ofdmWeakSigDetectOff) {
|
||||
if (ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
false)) {
|
||||
ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
return;
|
||||
}
|
||||
} else if (rssi > aniState->rssiThrLow) {
|
||||
if (aniState->ofdmWeakSigDetectOff)
|
||||
ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
true);
|
||||
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
return;
|
||||
} else {
|
||||
if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
|
||||
!conf_is_ht(conf)) {
|
||||
if (!aniState->ofdmWeakSigDetectOff)
|
||||
ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
false);
|
||||
if (aniState->firstepLevel > 0)
|
||||
ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_FIRSTEP_LEVEL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
|
||||
{
|
||||
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
|
||||
struct ar5416AniState *aniState;
|
||||
int32_t rssi;
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
|
||||
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel + 1)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ah->opmode == NL80211_IFTYPE_AP) {
|
||||
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
rssi = BEACON_RSSI(ah);
|
||||
if (rssi > aniState->rssiThrLow) {
|
||||
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel + 1);
|
||||
} else {
|
||||
if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
|
||||
!conf_is_ht(conf)) {
|
||||
if (aniState->firstepLevel > 0)
|
||||
ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_FIRSTEP_LEVEL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust the OFDM Noise Immunity Level */
|
||||
static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
|
||||
static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
|
||||
bool scan)
|
||||
{
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
const struct ani_ofdm_level_entry *entry_ofdm;
|
||||
const struct ani_cck_level_entry *entry_cck;
|
||||
|
||||
aniState->noiseFloor = BEACON_RSSI(ah);
|
||||
bool weak_sig;
|
||||
|
||||
ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
|
||||
aniState->ofdmNoiseImmunityLevel,
|
||||
immunityLevel, aniState->noiseFloor,
|
||||
immunityLevel, BEACON_RSSI(ah),
|
||||
aniState->rssiThrLow, aniState->rssiThrHigh);
|
||||
|
||||
if (aniState->update_ani)
|
||||
aniState->ofdmNoiseImmunityLevel =
|
||||
(immunityLevel > ATH9K_ANI_OFDM_DEF_LEVEL) ?
|
||||
immunityLevel : ATH9K_ANI_OFDM_DEF_LEVEL;
|
||||
if (!scan)
|
||||
aniState->ofdmNoiseImmunityLevel = immunityLevel;
|
||||
|
||||
entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
|
||||
entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
|
||||
@ -292,12 +171,22 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
|
||||
ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
entry_ofdm->fir_step_level);
|
||||
|
||||
if ((aniState->noiseFloor >= aniState->rssiThrHigh) &&
|
||||
(!aniState->ofdmWeakSigDetectOff !=
|
||||
entry_ofdm->ofdm_weak_signal_on)) {
|
||||
weak_sig = entry_ofdm->ofdm_weak_signal_on;
|
||||
if (ah->opmode == NL80211_IFTYPE_STATION &&
|
||||
BEACON_RSSI(ah) <= aniState->rssiThrHigh)
|
||||
weak_sig = true;
|
||||
|
||||
if (aniState->ofdmWeakSigDetect != weak_sig)
|
||||
ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
entry_ofdm->ofdm_weak_signal_on);
|
||||
|
||||
if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
|
||||
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
|
||||
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI;
|
||||
} else {
|
||||
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI;
|
||||
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,43 +197,35 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
if (!use_new_ani(ah)) {
|
||||
ath9k_hw_ani_ofdm_err_trigger_old(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
|
||||
ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
|
||||
ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the ANI settings to match an CCK level.
|
||||
*/
|
||||
static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
|
||||
static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
|
||||
bool scan)
|
||||
{
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
const struct ani_ofdm_level_entry *entry_ofdm;
|
||||
const struct ani_cck_level_entry *entry_cck;
|
||||
|
||||
aniState->noiseFloor = BEACON_RSSI(ah);
|
||||
ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
|
||||
aniState->cckNoiseImmunityLevel, immunityLevel,
|
||||
aniState->noiseFloor, aniState->rssiThrLow,
|
||||
BEACON_RSSI(ah), aniState->rssiThrLow,
|
||||
aniState->rssiThrHigh);
|
||||
|
||||
if ((ah->opmode == NL80211_IFTYPE_STATION ||
|
||||
ah->opmode == NL80211_IFTYPE_ADHOC) &&
|
||||
aniState->noiseFloor <= aniState->rssiThrLow &&
|
||||
if (ah->opmode == NL80211_IFTYPE_STATION &&
|
||||
BEACON_RSSI(ah) <= aniState->rssiThrLow &&
|
||||
immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
|
||||
immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
|
||||
|
||||
if (aniState->update_ani)
|
||||
aniState->cckNoiseImmunityLevel =
|
||||
(immunityLevel > ATH9K_ANI_CCK_DEF_LEVEL) ?
|
||||
immunityLevel : ATH9K_ANI_CCK_DEF_LEVEL;
|
||||
if (!scan)
|
||||
aniState->cckNoiseImmunityLevel = immunityLevel;
|
||||
|
||||
entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
|
||||
entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
|
||||
@ -359,7 +240,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel)
|
||||
if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah))
|
||||
return;
|
||||
|
||||
if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
|
||||
if (aniState->mrcCCK != entry_cck->mrc_cck_on)
|
||||
ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_MRC_CCK,
|
||||
entry_cck->mrc_cck_on);
|
||||
@ -372,68 +253,11 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
if (!use_new_ani(ah)) {
|
||||
ath9k_hw_ani_cck_err_trigger_old(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
|
||||
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
|
||||
}
|
||||
|
||||
static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
int32_t rssi;
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (ah->opmode == NL80211_IFTYPE_AP) {
|
||||
if (aniState->firstepLevel > 0) {
|
||||
if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel - 1))
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
rssi = BEACON_RSSI(ah);
|
||||
if (rssi > aniState->rssiThrHigh) {
|
||||
/* XXX: Handle me */
|
||||
} else if (rssi > aniState->rssiThrLow) {
|
||||
if (aniState->ofdmWeakSigDetectOff) {
|
||||
if (ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
true))
|
||||
return;
|
||||
}
|
||||
if (aniState->firstepLevel > 0) {
|
||||
if (ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel - 1))
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (aniState->firstepLevel > 0) {
|
||||
if (ath9k_hw_ani_control(ah,
|
||||
ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel - 1))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aniState->spurImmunityLevel > 0) {
|
||||
if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel - 1))
|
||||
return;
|
||||
}
|
||||
|
||||
if (aniState->noiseImmunityLevel > 0) {
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel - 1);
|
||||
return;
|
||||
}
|
||||
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
|
||||
false);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -446,87 +270,18 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (!use_new_ani(ah)) {
|
||||
ath9k_hw_ani_lower_immunity_old(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
/* lower OFDM noise immunity */
|
||||
if (aniState->ofdmNoiseImmunityLevel > 0 &&
|
||||
(aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
|
||||
ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1);
|
||||
ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1,
|
||||
false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* lower CCK noise immunity */
|
||||
if (aniState->cckNoiseImmunityLevel > 0)
|
||||
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
|
||||
}
|
||||
|
||||
static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
{
|
||||
struct ar5416AniState *aniState;
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
aniState = &ah->curchan->ani;
|
||||
|
||||
if (ah->opmode != NL80211_IFTYPE_STATION
|
||||
&& ah->opmode != NL80211_IFTYPE_ADHOC) {
|
||||
ath_dbg(common, ANI, "Reset ANI state opmode %u\n", ah->opmode);
|
||||
ah->stats.ast_ani_reset++;
|
||||
|
||||
if (ah->opmode == NL80211_IFTYPE_AP) {
|
||||
/*
|
||||
* ath9k_hw_ani_control() will only process items set on
|
||||
* ah->ani_function
|
||||
*/
|
||||
if (IS_CHAN_2GHZ(chan))
|
||||
ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
|
||||
ATH9K_ANI_FIRSTEP_LEVEL);
|
||||
else
|
||||
ah->ani_function = 0;
|
||||
}
|
||||
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
!ATH9K_ANI_USE_OFDM_WEAK_SIG);
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
|
||||
ATH9K_ANI_CCK_WEAK_SIG_THR);
|
||||
|
||||
ath9k_ani_restart(ah);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aniState->noiseImmunityLevel != 0)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
|
||||
aniState->noiseImmunityLevel);
|
||||
if (aniState->spurImmunityLevel != 0)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
|
||||
aniState->spurImmunityLevel);
|
||||
if (aniState->ofdmWeakSigDetectOff)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
|
||||
!aniState->ofdmWeakSigDetectOff);
|
||||
if (aniState->cckWeakSigThreshold)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
|
||||
aniState->cckWeakSigThreshold);
|
||||
if (aniState->firstepLevel != 0)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel);
|
||||
|
||||
ath9k_ani_restart(ah);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1,
|
||||
false);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -539,13 +294,11 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int ofdm_nil, cck_nil;
|
||||
|
||||
if (!DO_ANI(ah))
|
||||
return;
|
||||
|
||||
if (!use_new_ani(ah))
|
||||
return ath9k_ani_reset_old(ah, is_scanning);
|
||||
|
||||
BUG_ON(aniState == NULL);
|
||||
ah->stats.ast_ani_reset++;
|
||||
|
||||
@ -563,6 +316,11 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
|
||||
/* always allow mode (on/off) to be controlled */
|
||||
ah->ani_function |= ATH9K_ANI_MODE;
|
||||
|
||||
ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL,
|
||||
aniState->ofdmNoiseImmunityLevel);
|
||||
cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL,
|
||||
aniState->cckNoiseImmunityLevel);
|
||||
|
||||
if (is_scanning ||
|
||||
(ah->opmode != NL80211_IFTYPE_STATION &&
|
||||
ah->opmode != NL80211_IFTYPE_ADHOC)) {
|
||||
@ -585,9 +343,8 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
|
||||
aniState->ofdmNoiseImmunityLevel,
|
||||
aniState->cckNoiseImmunityLevel);
|
||||
|
||||
aniState->update_ani = false;
|
||||
ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
|
||||
ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
|
||||
ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL;
|
||||
cck_nil = ATH9K_ANI_CCK_DEF_LEVEL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -601,13 +358,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
|
||||
is_scanning,
|
||||
aniState->ofdmNoiseImmunityLevel,
|
||||
aniState->cckNoiseImmunityLevel);
|
||||
|
||||
aniState->update_ani = true;
|
||||
ath9k_hw_set_ofdm_nil(ah,
|
||||
aniState->ofdmNoiseImmunityLevel);
|
||||
ath9k_hw_set_cck_nil(ah,
|
||||
aniState->cckNoiseImmunityLevel);
|
||||
}
|
||||
ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning);
|
||||
ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning);
|
||||
|
||||
/*
|
||||
* enable phy counters if hw supports or if not, enable phy
|
||||
@ -627,9 +380,6 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
u32 ofdm_base = 0;
|
||||
u32 cck_base = 0;
|
||||
u32 ofdmPhyErrCnt, cckPhyErrCnt;
|
||||
u32 phyCnt1, phyCnt2;
|
||||
int32_t listenTime;
|
||||
|
||||
@ -642,11 +392,6 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!use_new_ani(ah)) {
|
||||
ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
|
||||
cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
|
||||
}
|
||||
|
||||
aniState->listenTime += listenTime;
|
||||
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
@ -654,35 +399,12 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
|
||||
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
|
||||
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
||||
|
||||
if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
|
||||
if (phyCnt1 < ofdm_base) {
|
||||
ath_dbg(common, ANI,
|
||||
"phyCnt1 0x%x, resetting counter value to 0x%x\n",
|
||||
phyCnt1, ofdm_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_1,
|
||||
AR_PHY_ERR_OFDM_TIMING);
|
||||
}
|
||||
if (phyCnt2 < cck_base) {
|
||||
ath_dbg(common, ANI,
|
||||
"phyCnt2 0x%x, resetting counter value to 0x%x\n",
|
||||
phyCnt2, cck_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
|
||||
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
|
||||
AR_PHY_ERR_CCK_TIMING);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ah->stats.ast_ani_ofdmerrs += phyCnt1 - aniState->ofdmPhyErrCount;
|
||||
aniState->ofdmPhyErrCount = phyCnt1;
|
||||
|
||||
ofdmPhyErrCnt = phyCnt1 - ofdm_base;
|
||||
ah->stats.ast_ani_ofdmerrs +=
|
||||
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
|
||||
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
|
||||
ah->stats.ast_ani_cckerrs += phyCnt2 - aniState->cckPhyErrCount;
|
||||
aniState->cckPhyErrCount = phyCnt2;
|
||||
|
||||
cckPhyErrCnt = phyCnt2 - cck_base;
|
||||
ah->stats.ast_ani_cckerrs +=
|
||||
cckPhyErrCnt - aniState->cckPhyErrCount;
|
||||
aniState->cckPhyErrCount = cckPhyErrCnt;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -716,21 +438,10 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
|
||||
if (aniState->listenTime > ah->aniperiod) {
|
||||
if (cckPhyErrRate < ah->config.cck_trig_low &&
|
||||
((ofdmPhyErrRate < ah->config.ofdm_trig_low &&
|
||||
aniState->ofdmNoiseImmunityLevel <
|
||||
ATH9K_ANI_OFDM_DEF_LEVEL) ||
|
||||
(ofdmPhyErrRate < ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI &&
|
||||
aniState->ofdmNoiseImmunityLevel >=
|
||||
ATH9K_ANI_OFDM_DEF_LEVEL))) {
|
||||
ofdmPhyErrRate < ah->config.ofdm_trig_low) {
|
||||
ath9k_hw_ani_lower_immunity(ah);
|
||||
aniState->ofdmsTurn = !aniState->ofdmsTurn;
|
||||
} else if ((ofdmPhyErrRate > ah->config.ofdm_trig_high &&
|
||||
aniState->ofdmNoiseImmunityLevel >=
|
||||
ATH9K_ANI_OFDM_DEF_LEVEL) ||
|
||||
(ofdmPhyErrRate >
|
||||
ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI &&
|
||||
aniState->ofdmNoiseImmunityLevel <
|
||||
ATH9K_ANI_OFDM_DEF_LEVEL)) {
|
||||
} else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) {
|
||||
ath9k_hw_ani_ofdm_err_trigger(ah);
|
||||
aniState->ofdmsTurn = false;
|
||||
} else if (cckPhyErrRate > ah->config.cck_trig_high) {
|
||||
@ -778,49 +489,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
|
||||
|
||||
/*
|
||||
* Process a MIB interrupt. We may potentially be invoked because
|
||||
* any of the MIB counters overflow/trigger so don't assume we're
|
||||
* here because a PHY error counter triggered.
|
||||
*/
|
||||
void ath9k_hw_proc_mib_event(struct ath_hw *ah)
|
||||
{
|
||||
u32 phyCnt1, phyCnt2;
|
||||
|
||||
/* Reset these counters regardless */
|
||||
REG_WRITE(ah, AR_FILT_OFDM, 0);
|
||||
REG_WRITE(ah, AR_FILT_CCK, 0);
|
||||
if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
|
||||
REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
|
||||
|
||||
/* Clear the mib counters and save them in the stats */
|
||||
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
|
||||
|
||||
if (!DO_ANI(ah)) {
|
||||
/*
|
||||
* We must always clear the interrupt cause by
|
||||
* resetting the phy error regs.
|
||||
*/
|
||||
REG_WRITE(ah, AR_PHY_ERR_1, 0);
|
||||
REG_WRITE(ah, AR_PHY_ERR_2, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* NB: these are not reset-on-read */
|
||||
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
|
||||
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
|
||||
if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
|
||||
((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
|
||||
|
||||
if (!use_new_ani(ah))
|
||||
ath9k_hw_ani_read_counters(ah);
|
||||
|
||||
/* NB: always restart to insure the h/w counters are reset */
|
||||
ath9k_ani_restart(ah);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_proc_mib_event);
|
||||
|
||||
void ath9k_hw_ani_setup(struct ath_hw *ah)
|
||||
{
|
||||
int i;
|
||||
@ -845,66 +513,37 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
|
||||
|
||||
ath_dbg(common, ANI, "Initialize ANI\n");
|
||||
|
||||
if (use_new_ani(ah)) {
|
||||
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
|
||||
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
|
||||
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
|
||||
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
|
||||
|
||||
ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
|
||||
ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
|
||||
} else {
|
||||
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
|
||||
ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
|
||||
|
||||
ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
|
||||
ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
|
||||
}
|
||||
ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
|
||||
ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
|
||||
struct ath9k_channel *chan = &ah->channels[i];
|
||||
struct ar5416AniState *ani = &chan->ani;
|
||||
|
||||
if (use_new_ani(ah)) {
|
||||
ani->spurImmunityLevel =
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
|
||||
ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
|
||||
|
||||
ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
||||
ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
ani->mrcCCKOff =
|
||||
!ATH9K_ANI_ENABLE_MRC_CCK;
|
||||
else
|
||||
ani->mrcCCKOff = true;
|
||||
ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
|
||||
|
||||
ani->ofdmsTurn = true;
|
||||
} else {
|
||||
ani->spurImmunityLevel =
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
|
||||
ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
|
||||
|
||||
ani->cckWeakSigThreshold =
|
||||
ATH9K_ANI_CCK_WEAK_SIG_THR;
|
||||
}
|
||||
ani->ofdmsTurn = true;
|
||||
|
||||
ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
|
||||
ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
|
||||
ani->ofdmWeakSigDetectOff =
|
||||
!ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
|
||||
ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
|
||||
ani->update_ani = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* since we expect some ongoing maintenance on the tables, let's sanity
|
||||
* check here default level should not modify INI setting.
|
||||
*/
|
||||
if (use_new_ani(ah)) {
|
||||
ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
|
||||
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
|
||||
} else {
|
||||
ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
|
||||
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
|
||||
}
|
||||
ah->aniperiod = ATH9K_ANI_PERIOD;
|
||||
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
|
||||
|
||||
if (ah->config.enable_ani)
|
||||
ah->proc_phyerr |= HAL_PROCESS_ANI;
|
||||
|
@ -24,42 +24,34 @@
|
||||
#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
|
||||
|
||||
/* units are errors per second */
|
||||
#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
|
||||
#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 3500
|
||||
#define ATH9K_ANI_OFDM_TRIG_HIGH 3500
|
||||
#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
|
||||
|
||||
/* units are errors per second */
|
||||
#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
|
||||
#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400
|
||||
#define ATH9K_ANI_OFDM_TRIG_LOW 400
|
||||
#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
|
||||
|
||||
/* units are errors per second */
|
||||
#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
|
||||
#define ATH9K_ANI_CCK_TRIG_HIGH_NEW 600
|
||||
#define ATH9K_ANI_CCK_TRIG_HIGH 600
|
||||
|
||||
/* units are errors per second */
|
||||
#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
|
||||
#define ATH9K_ANI_CCK_TRIG_LOW_NEW 300
|
||||
#define ATH9K_ANI_CCK_TRIG_LOW 300
|
||||
|
||||
#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
|
||||
#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
|
||||
#define ATH9K_ANI_CCK_WEAK_SIG_THR false
|
||||
|
||||
#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD 7
|
||||
#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW 3
|
||||
#define ATH9K_ANI_SPUR_IMMUNE_LVL 3
|
||||
|
||||
#define ATH9K_ANI_FIRSTEP_LVL_OLD 0
|
||||
#define ATH9K_ANI_FIRSTEP_LVL_NEW 2
|
||||
#define ATH9K_ANI_FIRSTEP_LVL 2
|
||||
|
||||
#define ATH9K_ANI_RSSI_THR_HIGH 40
|
||||
#define ATH9K_ANI_RSSI_THR_LOW 7
|
||||
|
||||
#define ATH9K_ANI_PERIOD_OLD 100
|
||||
#define ATH9K_ANI_PERIOD_NEW 300
|
||||
#define ATH9K_ANI_PERIOD 300
|
||||
|
||||
/* in ms */
|
||||
#define ATH9K_ANI_POLLINTERVAL_OLD 100
|
||||
#define ATH9K_ANI_POLLINTERVAL_NEW 1000
|
||||
#define ATH9K_ANI_POLLINTERVAL 1000
|
||||
|
||||
#define HAL_NOISE_IMMUNE_MAX 4
|
||||
#define HAL_SPUR_IMMUNE_MAX 7
|
||||
@ -70,8 +62,6 @@
|
||||
#define ATH9K_SIG_SPUR_IMM_SETTING_MIN 0
|
||||
#define ATH9K_SIG_SPUR_IMM_SETTING_MAX 22
|
||||
|
||||
#define ATH9K_ANI_ENABLE_MRC_CCK true
|
||||
|
||||
/* values here are relative to the INI */
|
||||
|
||||
enum ath9k_ani_cmd {
|
||||
@ -119,16 +109,14 @@ struct ar5416AniState {
|
||||
u8 ofdmNoiseImmunityLevel;
|
||||
u8 cckNoiseImmunityLevel;
|
||||
bool ofdmsTurn;
|
||||
u8 mrcCCKOff;
|
||||
u8 mrcCCK;
|
||||
u8 spurImmunityLevel;
|
||||
u8 firstepLevel;
|
||||
u8 ofdmWeakSigDetectOff;
|
||||
u8 ofdmWeakSigDetect;
|
||||
u8 cckWeakSigThreshold;
|
||||
bool update_ani;
|
||||
u32 listenTime;
|
||||
int32_t rssiThrLow;
|
||||
int32_t rssiThrHigh;
|
||||
u32 noiseFloor;
|
||||
u32 ofdmPhyErrCount;
|
||||
u32 cckPhyErrCount;
|
||||
int16_t pktRssi[2];
|
||||
|
@ -995,141 +995,6 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,
|
||||
return pll;
|
||||
}
|
||||
|
||||
static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
|
||||
enum ath9k_ani_cmd cmd,
|
||||
int param)
|
||||
{
|
||||
struct ar5416AniState *aniState = &ah->curchan->ani;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
switch (cmd & ah->ani_function) {
|
||||
case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
|
||||
u32 level = param;
|
||||
|
||||
if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
|
||||
ath_dbg(common, ANI, "level out of range (%u > %zu)\n",
|
||||
level, ARRAY_SIZE(ah->totalSizeDesired));
|
||||
return false;
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
|
||||
AR_PHY_DESIRED_SZ_TOT_DES,
|
||||
ah->totalSizeDesired[level]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
||||
AR_PHY_AGC_CTL1_COARSE_LOW,
|
||||
ah->coarse_low[level]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
|
||||
AR_PHY_AGC_CTL1_COARSE_HIGH,
|
||||
ah->coarse_high[level]);
|
||||
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
||||
AR_PHY_FIND_SIG_FIRPWR,
|
||||
ah->firpwr[level]);
|
||||
|
||||
if (level > aniState->noiseImmunityLevel)
|
||||
ah->stats.ast_ani_niup++;
|
||||
else if (level < aniState->noiseImmunityLevel)
|
||||
ah->stats.ast_ani_nidown++;
|
||||
aniState->noiseImmunityLevel = level;
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
|
||||
u32 on = param ? 1 : 0;
|
||||
|
||||
if (on)
|
||||
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
else
|
||||
REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
|
||||
if (!on != aniState->ofdmWeakSigDetectOff) {
|
||||
if (on)
|
||||
ah->stats.ast_ani_ofdmon++;
|
||||
else
|
||||
ah->stats.ast_ani_ofdmoff++;
|
||||
aniState->ofdmWeakSigDetectOff = !on;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
|
||||
static const int weakSigThrCck[] = { 8, 6 };
|
||||
u32 high = param ? 1 : 0;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
|
||||
AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
|
||||
weakSigThrCck[high]);
|
||||
if (high != aniState->cckWeakSigThreshold) {
|
||||
if (high)
|
||||
ah->stats.ast_ani_cckhigh++;
|
||||
else
|
||||
ah->stats.ast_ani_ccklow++;
|
||||
aniState->cckWeakSigThreshold = high;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_FIRSTEP_LEVEL:{
|
||||
static const int firstep[] = { 0, 4, 8 };
|
||||
u32 level = param;
|
||||
|
||||
if (level >= ARRAY_SIZE(firstep)) {
|
||||
ath_dbg(common, ANI, "level out of range (%u > %zu)\n",
|
||||
level, ARRAY_SIZE(firstep));
|
||||
return false;
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
|
||||
AR_PHY_FIND_SIG_FIRSTEP,
|
||||
firstep[level]);
|
||||
if (level > aniState->firstepLevel)
|
||||
ah->stats.ast_ani_stepup++;
|
||||
else if (level < aniState->firstepLevel)
|
||||
ah->stats.ast_ani_stepdown++;
|
||||
aniState->firstepLevel = level;
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
|
||||
static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
|
||||
u32 level = param;
|
||||
|
||||
if (level >= ARRAY_SIZE(cycpwrThr1)) {
|
||||
ath_dbg(common, ANI, "level out of range (%u > %zu)\n",
|
||||
level, ARRAY_SIZE(cycpwrThr1));
|
||||
return false;
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING5,
|
||||
AR_PHY_TIMING5_CYCPWR_THR1,
|
||||
cycpwrThr1[level]);
|
||||
if (level > aniState->spurImmunityLevel)
|
||||
ah->stats.ast_ani_spurup++;
|
||||
else if (level < aniState->spurImmunityLevel)
|
||||
ah->stats.ast_ani_spurdown++;
|
||||
aniState->spurImmunityLevel = level;
|
||||
break;
|
||||
}
|
||||
case ATH9K_ANI_PRESENT:
|
||||
break;
|
||||
default:
|
||||
ath_dbg(common, ANI, "invalid cmd %u\n", cmd);
|
||||
return false;
|
||||
}
|
||||
|
||||
ath_dbg(common, ANI, "ANI parameters:\n");
|
||||
ath_dbg(common, ANI,
|
||||
"noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n",
|
||||
aniState->noiseImmunityLevel,
|
||||
aniState->spurImmunityLevel,
|
||||
!aniState->ofdmWeakSigDetectOff);
|
||||
ath_dbg(common, ANI,
|
||||
"cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n",
|
||||
aniState->cckWeakSigThreshold,
|
||||
aniState->firstepLevel,
|
||||
aniState->listenTime);
|
||||
ath_dbg(common, ANI, "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
|
||||
aniState->ofdmPhyErrCount,
|
||||
aniState->cckPhyErrCount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
enum ath9k_ani_cmd cmd,
|
||||
int param)
|
||||
@ -1206,18 +1071,18 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
|
||||
if (!on != aniState->ofdmWeakSigDetectOff) {
|
||||
if (on != aniState->ofdmWeakSigDetect) {
|
||||
ath_dbg(common, ANI,
|
||||
"** ch %d: ofdm weak signal: %s=>%s\n",
|
||||
chan->channel,
|
||||
!aniState->ofdmWeakSigDetectOff ?
|
||||
aniState->ofdmWeakSigDetect ?
|
||||
"on" : "off",
|
||||
on ? "on" : "off");
|
||||
if (on)
|
||||
ah->stats.ast_ani_ofdmon++;
|
||||
else
|
||||
ah->stats.ast_ani_ofdmoff++;
|
||||
aniState->ofdmWeakSigDetectOff = !on;
|
||||
aniState->ofdmWeakSigDetect = on;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1236,7 +1101,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value = firstep_table[level] -
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
||||
aniState->iniDef.firstep;
|
||||
if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
||||
value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
||||
@ -1251,7 +1116,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value2 = firstep_table[level] -
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
||||
aniState->iniDef.firstepLow;
|
||||
if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
||||
value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
||||
@ -1267,7 +1132,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->firstepLevel,
|
||||
level,
|
||||
ATH9K_ANI_FIRSTEP_LVL_NEW,
|
||||
ATH9K_ANI_FIRSTEP_LVL,
|
||||
value,
|
||||
aniState->iniDef.firstep);
|
||||
ath_dbg(common, ANI,
|
||||
@ -1275,7 +1140,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->firstepLevel,
|
||||
level,
|
||||
ATH9K_ANI_FIRSTEP_LVL_NEW,
|
||||
ATH9K_ANI_FIRSTEP_LVL,
|
||||
value2,
|
||||
aniState->iniDef.firstepLow);
|
||||
if (level > aniState->firstepLevel)
|
||||
@ -1300,7 +1165,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value = cycpwrThr1_table[level] -
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
||||
aniState->iniDef.cycpwrThr1;
|
||||
if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
||||
value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
||||
@ -1316,7 +1181,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value2 = cycpwrThr1_table[level] -
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
||||
aniState->iniDef.cycpwrThr1Ext;
|
||||
if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
||||
value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
||||
@ -1331,7 +1196,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->spurImmunityLevel,
|
||||
level,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL,
|
||||
value,
|
||||
aniState->iniDef.cycpwrThr1);
|
||||
ath_dbg(common, ANI,
|
||||
@ -1339,7 +1204,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->spurImmunityLevel,
|
||||
level,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL,
|
||||
value2,
|
||||
aniState->iniDef.cycpwrThr1Ext);
|
||||
if (level > aniState->spurImmunityLevel)
|
||||
@ -1367,9 +1232,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
|
||||
ath_dbg(common, ANI,
|
||||
"ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
|
||||
aniState->spurImmunityLevel,
|
||||
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
|
||||
aniState->ofdmWeakSigDetect ? "on" : "off",
|
||||
aniState->firstepLevel,
|
||||
!aniState->mrcCCKOff ? "on" : "off",
|
||||
aniState->mrcCCK ? "on" : "off",
|
||||
aniState->listenTime,
|
||||
aniState->ofdmPhyErrCount,
|
||||
aniState->cckPhyErrCount);
|
||||
@ -1454,10 +1319,10 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
|
||||
AR_PHY_EXT_TIMING5_CYCPWR_THR1);
|
||||
|
||||
/* these levels just got reset to defaults by the INI */
|
||||
aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
|
||||
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
||||
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
aniState->mrcCCKOff = true; /* not available on pre AR9003 */
|
||||
aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
|
||||
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
|
||||
aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
aniState->mrcCCK = false; /* not available on pre AR9003 */
|
||||
}
|
||||
|
||||
static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
|
||||
@ -1545,11 +1410,8 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
priv_ops->do_getnf = ar5008_hw_do_getnf;
|
||||
priv_ops->set_radar_params = ar5008_hw_set_radar_params;
|
||||
|
||||
if (modparam_force_new_ani) {
|
||||
priv_ops->ani_control = ar5008_hw_ani_control_new;
|
||||
priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
|
||||
} else
|
||||
priv_ops->ani_control = ar5008_hw_ani_control_old;
|
||||
priv_ops->ani_control = ar5008_hw_ani_control_new;
|
||||
priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;
|
||||
|
||||
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
|
||||
priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
|
||||
|
@ -21,10 +21,6 @@
|
||||
#include "ar9002_initvals.h"
|
||||
#include "ar9002_phy.h"
|
||||
|
||||
int modparam_force_new_ani;
|
||||
module_param_named(force_new_ani, modparam_force_new_ani, int, 0444);
|
||||
MODULE_PARM_DESC(force_new_ani, "Force new ANI for AR5008, AR9001, AR9002");
|
||||
|
||||
/* General hardware code for the A5008/AR9001/AR9002 hadware families */
|
||||
|
||||
static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
@ -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
|
||||
|
@ -767,10 +767,6 @@ static void ar9003_mci_mute_bt(struct ath_hw *ah)
|
||||
{
|
||||
/* disable all MCI messages */
|
||||
REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
|
||||
REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
|
||||
REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
|
||||
REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
|
||||
REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
|
||||
REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
|
||||
|
||||
/* wait pending HW messages to flush out */
|
||||
@ -1019,9 +1015,14 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force)
|
||||
return;
|
||||
|
||||
if (mci->is_2g) {
|
||||
ar9003_mci_send_2g5g_status(ah, true);
|
||||
if (!force) {
|
||||
ar9003_mci_send_2g5g_status(ah, true);
|
||||
|
||||
REG_SET_BIT(ah, AR_MCI_TX_CTRL,
|
||||
ar9003_mci_send_lna_transfer(ah, true);
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
|
||||
AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
|
||||
REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
|
||||
AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
|
||||
@ -1029,6 +1030,11 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force)
|
||||
if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
|
||||
ar9003_mci_osla_setup(ah, true);
|
||||
} else {
|
||||
if (!force) {
|
||||
ar9003_mci_send_lna_take(ah, true);
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
REG_SET_BIT(ah, AR_MCI_TX_CTRL,
|
||||
AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
|
||||
REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
|
||||
@ -1255,6 +1261,9 @@ void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
|
||||
|
||||
ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n");
|
||||
|
||||
ar9003_mci_send_lna_take(ah, true);
|
||||
udelay(50);
|
||||
|
||||
REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
|
||||
mci->is_2g = false;
|
||||
mci->update_2g5g = true;
|
||||
|
@ -173,7 +173,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
||||
int cur_bb_spur, negative = 0, cck_spur_freq;
|
||||
int i;
|
||||
int range, max_spur_cnts, synth_freq;
|
||||
u8 *spur_fbin_ptr = NULL;
|
||||
u8 *spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, IS_CHAN_2GHZ(chan));
|
||||
|
||||
/*
|
||||
* Need to verify range +/- 10 MHz in control channel, otherwise spur
|
||||
@ -181,8 +181,6 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
||||
*/
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) {
|
||||
spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
|
||||
IS_CHAN_2GHZ(chan));
|
||||
if (spur_fbin_ptr[0] == 0) /* No spur */
|
||||
return;
|
||||
max_spur_cnts = 5;
|
||||
@ -825,18 +823,18 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
||||
|
||||
if (!on != aniState->ofdmWeakSigDetectOff) {
|
||||
if (on != aniState->ofdmWeakSigDetect) {
|
||||
ath_dbg(common, ANI,
|
||||
"** ch %d: ofdm weak signal: %s=>%s\n",
|
||||
chan->channel,
|
||||
!aniState->ofdmWeakSigDetectOff ?
|
||||
aniState->ofdmWeakSigDetect ?
|
||||
"on" : "off",
|
||||
on ? "on" : "off");
|
||||
if (on)
|
||||
ah->stats.ast_ani_ofdmon++;
|
||||
else
|
||||
ah->stats.ast_ani_ofdmoff++;
|
||||
aniState->ofdmWeakSigDetectOff = !on;
|
||||
aniState->ofdmWeakSigDetect = on;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -855,7 +853,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value = firstep_table[level] -
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
||||
aniState->iniDef.firstep;
|
||||
if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
||||
value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
||||
@ -870,7 +868,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value2 = firstep_table[level] -
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
|
||||
firstep_table[ATH9K_ANI_FIRSTEP_LVL] +
|
||||
aniState->iniDef.firstepLow;
|
||||
if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
|
||||
value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
|
||||
@ -886,7 +884,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->firstepLevel,
|
||||
level,
|
||||
ATH9K_ANI_FIRSTEP_LVL_NEW,
|
||||
ATH9K_ANI_FIRSTEP_LVL,
|
||||
value,
|
||||
aniState->iniDef.firstep);
|
||||
ath_dbg(common, ANI,
|
||||
@ -894,7 +892,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->firstepLevel,
|
||||
level,
|
||||
ATH9K_ANI_FIRSTEP_LVL_NEW,
|
||||
ATH9K_ANI_FIRSTEP_LVL,
|
||||
value2,
|
||||
aniState->iniDef.firstepLow);
|
||||
if (level > aniState->firstepLevel)
|
||||
@ -919,7 +917,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value = cycpwrThr1_table[level] -
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
||||
aniState->iniDef.cycpwrThr1;
|
||||
if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
||||
value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
||||
@ -935,7 +933,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
* from INI file & cap value
|
||||
*/
|
||||
value2 = cycpwrThr1_table[level] -
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
|
||||
cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] +
|
||||
aniState->iniDef.cycpwrThr1Ext;
|
||||
if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
|
||||
value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
|
||||
@ -950,7 +948,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->spurImmunityLevel,
|
||||
level,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL,
|
||||
value,
|
||||
aniState->iniDef.cycpwrThr1);
|
||||
ath_dbg(common, ANI,
|
||||
@ -958,7 +956,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
chan->channel,
|
||||
aniState->spurImmunityLevel,
|
||||
level,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
|
||||
ATH9K_ANI_SPUR_IMMUNE_LVL,
|
||||
value2,
|
||||
aniState->iniDef.cycpwrThr1Ext);
|
||||
if (level > aniState->spurImmunityLevel)
|
||||
@ -979,16 +977,16 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
AR_PHY_MRC_CCK_ENABLE, is_on);
|
||||
REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
|
||||
AR_PHY_MRC_CCK_MUX_REG, is_on);
|
||||
if (!is_on != aniState->mrcCCKOff) {
|
||||
if (is_on != aniState->mrcCCK) {
|
||||
ath_dbg(common, ANI, "** ch %d: MRC CCK: %s=>%s\n",
|
||||
chan->channel,
|
||||
!aniState->mrcCCKOff ? "on" : "off",
|
||||
aniState->mrcCCK ? "on" : "off",
|
||||
is_on ? "on" : "off");
|
||||
if (is_on)
|
||||
ah->stats.ast_ani_ccklow++;
|
||||
else
|
||||
ah->stats.ast_ani_cckhigh++;
|
||||
aniState->mrcCCKOff = !is_on;
|
||||
aniState->mrcCCK = is_on;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1002,9 +1000,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
||||
ath_dbg(common, ANI,
|
||||
"ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",
|
||||
aniState->spurImmunityLevel,
|
||||
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
|
||||
aniState->ofdmWeakSigDetect ? "on" : "off",
|
||||
aniState->firstepLevel,
|
||||
!aniState->mrcCCKOff ? "on" : "off",
|
||||
aniState->mrcCCK ? "on" : "off",
|
||||
aniState->listenTime,
|
||||
aniState->ofdmPhyErrCount,
|
||||
aniState->cckPhyErrCount);
|
||||
@ -1111,10 +1109,10 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
|
||||
AR_PHY_EXT_CYCPWR_THR1);
|
||||
|
||||
/* these levels just got reset to defaults by the INI */
|
||||
aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
|
||||
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
|
||||
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
|
||||
aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
|
||||
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
|
||||
aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
|
||||
aniState->mrcCCK = true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set_radar_params(struct ath_hw *ah,
|
||||
|
@ -337,12 +337,7 @@ static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = {
|
||||
{0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000},
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p1_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a398, 0x00000000},
|
||||
{0x0000a39c, 0x6f7f0301},
|
||||
{0x0000a3a0, 0xca9228ee},
|
||||
};
|
||||
#define ar9331_1p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
static const u32 ar9331_1p1_xtal_25M[][2] = {
|
||||
/* Addr allmodes */
|
||||
@ -783,17 +778,7 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = {
|
||||
{0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000},
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p1_mac_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
|
||||
{0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
|
||||
{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
|
||||
};
|
||||
#define ar9331_1p1_mac_postamble ar9300_2p2_mac_postamble
|
||||
|
||||
static const u32 ar9331_1p1_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
@ -1112,38 +1097,4 @@ static const u32 ar9331_common_tx_gain_offset1_1[][1] = {
|
||||
{0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p1_chansel_xtal_25M[] = {
|
||||
0x0101479e,
|
||||
0x0101d027,
|
||||
0x010258af,
|
||||
0x0102e138,
|
||||
0x010369c0,
|
||||
0x0103f249,
|
||||
0x01047ad1,
|
||||
0x0105035a,
|
||||
0x01058be2,
|
||||
0x0106146b,
|
||||
0x01069cf3,
|
||||
0x0107257c,
|
||||
0x0107ae04,
|
||||
0x0108f5b2,
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p1_chansel_xtal_40M[] = {
|
||||
0x00a0ccbe,
|
||||
0x00a12213,
|
||||
0x00a17769,
|
||||
0x00a1ccbe,
|
||||
0x00a22213,
|
||||
0x00a27769,
|
||||
0x00a2ccbe,
|
||||
0x00a32213,
|
||||
0x00a37769,
|
||||
0x00a3ccbe,
|
||||
0x00a42213,
|
||||
0x00a47769,
|
||||
0x00a4ccbe,
|
||||
0x00a5998b,
|
||||
};
|
||||
|
||||
#endif /* INITVALS_9330_1P1_H */
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Atheros Communications Inc.
|
||||
* 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
|
||||
@ -17,8 +18,8 @@
|
||||
#ifndef INITVALS_9330_1P2_H
|
||||
#define INITVALS_9330_1P2_H
|
||||
|
||||
static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p2[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7},
|
||||
{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
|
||||
@ -102,8 +103,14 @@ static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p2[][5] = {
|
||||
{0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
};
|
||||
|
||||
#define ar9331_modes_high_power_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2
|
||||
|
||||
#define ar9331_modes_low_ob_db_tx_gain_1p2 ar9331_modes_high_power_tx_gain_1p2
|
||||
|
||||
#define ar9331_modes_lowest_ob_db_tx_gain_1p2 ar9331_modes_low_ob_db_tx_gain_1p2
|
||||
|
||||
static const u32 ar9331_1p2_baseband_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
|
||||
{0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
|
||||
{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
|
||||
@ -147,191 +154,6 @@ static const u32 ar9331_1p2_baseband_postamble[][5] = {
|
||||
{0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7},
|
||||
{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
|
||||
{0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
|
||||
{0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
|
||||
{0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
|
||||
{0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
|
||||
{0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00},
|
||||
{0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02},
|
||||
{0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04},
|
||||
{0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620},
|
||||
{0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621},
|
||||
{0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640},
|
||||
{0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641},
|
||||
{0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642},
|
||||
{0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644},
|
||||
{0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81},
|
||||
{0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83},
|
||||
{0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84},
|
||||
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3},
|
||||
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5},
|
||||
{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9},
|
||||
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec},
|
||||
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec},
|
||||
{0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
|
||||
{0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
|
||||
{0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
|
||||
{0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200},
|
||||
{0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202},
|
||||
{0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400},
|
||||
{0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402},
|
||||
{0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404},
|
||||
{0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603},
|
||||
{0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02},
|
||||
{0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04},
|
||||
{0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20},
|
||||
{0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20},
|
||||
{0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22},
|
||||
{0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24},
|
||||
{0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640},
|
||||
{0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660},
|
||||
{0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861},
|
||||
{0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81},
|
||||
{0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83},
|
||||
{0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84},
|
||||
{0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3},
|
||||
{0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5},
|
||||
{0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9},
|
||||
{0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb},
|
||||
{0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501},
|
||||
{0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802},
|
||||
{0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03},
|
||||
{0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
};
|
||||
|
||||
static const u32 ar9331_modes_low_ob_db_tx_gain_1p2[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7},
|
||||
{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
|
||||
{0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
|
||||
{0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
|
||||
{0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
|
||||
{0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
|
||||
{0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00},
|
||||
{0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02},
|
||||
{0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04},
|
||||
{0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620},
|
||||
{0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621},
|
||||
{0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640},
|
||||
{0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641},
|
||||
{0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642},
|
||||
{0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644},
|
||||
{0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81},
|
||||
{0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83},
|
||||
{0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84},
|
||||
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3},
|
||||
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5},
|
||||
{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9},
|
||||
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec},
|
||||
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec},
|
||||
{0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
|
||||
{0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
|
||||
{0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
|
||||
{0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200},
|
||||
{0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202},
|
||||
{0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400},
|
||||
{0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402},
|
||||
{0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404},
|
||||
{0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603},
|
||||
{0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02},
|
||||
{0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04},
|
||||
{0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20},
|
||||
{0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20},
|
||||
{0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22},
|
||||
{0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24},
|
||||
{0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640},
|
||||
{0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660},
|
||||
{0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861},
|
||||
{0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81},
|
||||
{0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83},
|
||||
{0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84},
|
||||
{0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3},
|
||||
{0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5},
|
||||
{0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9},
|
||||
{0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb},
|
||||
{0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501},
|
||||
{0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802},
|
||||
{0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03},
|
||||
{0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p2_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a398, 0x00000000},
|
||||
{0x0000a39c, 0x6f7f0301},
|
||||
{0x0000a3a0, 0xca9228ee},
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p2_xtal_25M[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00007038, 0x000002f8},
|
||||
{0x00008244, 0x0010f3d7},
|
||||
{0x0000824c, 0x0001e7ae},
|
||||
{0x0001609c, 0x0f508f29},
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p2_radio_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00016000, 0x36db6db6},
|
||||
@ -397,684 +219,24 @@ static const u32 ar9331_1p2_radio_core[][2] = {
|
||||
{0x000163d4, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9331_1p2_soc_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022},
|
||||
};
|
||||
#define ar9331_1p2_baseband_core_txfir_coeff_japan_2484 ar9331_1p1_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
static const u32 ar9331_common_wo_xlna_rx_gain_1p2[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00060005},
|
||||
{0x0000a004, 0x00810080},
|
||||
{0x0000a008, 0x00830082},
|
||||
{0x0000a00c, 0x00850084},
|
||||
{0x0000a010, 0x01820181},
|
||||
{0x0000a014, 0x01840183},
|
||||
{0x0000a018, 0x01880185},
|
||||
{0x0000a01c, 0x018a0189},
|
||||
{0x0000a020, 0x02850284},
|
||||
{0x0000a024, 0x02890288},
|
||||
{0x0000a028, 0x028b028a},
|
||||
{0x0000a02c, 0x03850384},
|
||||
{0x0000a030, 0x03890388},
|
||||
{0x0000a034, 0x038b038a},
|
||||
{0x0000a038, 0x038d038c},
|
||||
{0x0000a03c, 0x03910390},
|
||||
{0x0000a040, 0x03930392},
|
||||
{0x0000a044, 0x03950394},
|
||||
{0x0000a048, 0x00000396},
|
||||
{0x0000a04c, 0x00000000},
|
||||
{0x0000a050, 0x00000000},
|
||||
{0x0000a054, 0x00000000},
|
||||
{0x0000a058, 0x00000000},
|
||||
{0x0000a05c, 0x00000000},
|
||||
{0x0000a060, 0x00000000},
|
||||
{0x0000a064, 0x00000000},
|
||||
{0x0000a068, 0x00000000},
|
||||
{0x0000a06c, 0x00000000},
|
||||
{0x0000a070, 0x00000000},
|
||||
{0x0000a074, 0x00000000},
|
||||
{0x0000a078, 0x00000000},
|
||||
{0x0000a07c, 0x00000000},
|
||||
{0x0000a080, 0x28282828},
|
||||
{0x0000a084, 0x28282828},
|
||||
{0x0000a088, 0x28282828},
|
||||
{0x0000a08c, 0x28282828},
|
||||
{0x0000a090, 0x28282828},
|
||||
{0x0000a094, 0x24242428},
|
||||
{0x0000a098, 0x171e1e1e},
|
||||
{0x0000a09c, 0x02020b0b},
|
||||
{0x0000a0a0, 0x02020202},
|
||||
{0x0000a0a4, 0x00000000},
|
||||
{0x0000a0a8, 0x00000000},
|
||||
{0x0000a0ac, 0x00000000},
|
||||
{0x0000a0b0, 0x00000000},
|
||||
{0x0000a0b4, 0x00000000},
|
||||
{0x0000a0b8, 0x00000000},
|
||||
{0x0000a0bc, 0x00000000},
|
||||
{0x0000a0c0, 0x22072208},
|
||||
{0x0000a0c4, 0x22052206},
|
||||
{0x0000a0c8, 0x22032204},
|
||||
{0x0000a0cc, 0x22012202},
|
||||
{0x0000a0d0, 0x221f2200},
|
||||
{0x0000a0d4, 0x221d221e},
|
||||
{0x0000a0d8, 0x33023303},
|
||||
{0x0000a0dc, 0x33003301},
|
||||
{0x0000a0e0, 0x331e331f},
|
||||
{0x0000a0e4, 0x4402331d},
|
||||
{0x0000a0e8, 0x44004401},
|
||||
{0x0000a0ec, 0x441e441f},
|
||||
{0x0000a0f0, 0x55025503},
|
||||
{0x0000a0f4, 0x55005501},
|
||||
{0x0000a0f8, 0x551e551f},
|
||||
{0x0000a0fc, 0x6602551d},
|
||||
{0x0000a100, 0x66006601},
|
||||
{0x0000a104, 0x661e661f},
|
||||
{0x0000a108, 0x7703661d},
|
||||
{0x0000a10c, 0x77017702},
|
||||
{0x0000a110, 0x00007700},
|
||||
{0x0000a114, 0x00000000},
|
||||
{0x0000a118, 0x00000000},
|
||||
{0x0000a11c, 0x00000000},
|
||||
{0x0000a120, 0x00000000},
|
||||
{0x0000a124, 0x00000000},
|
||||
{0x0000a128, 0x00000000},
|
||||
{0x0000a12c, 0x00000000},
|
||||
{0x0000a130, 0x00000000},
|
||||
{0x0000a134, 0x00000000},
|
||||
{0x0000a138, 0x00000000},
|
||||
{0x0000a13c, 0x00000000},
|
||||
{0x0000a140, 0x001f0000},
|
||||
{0x0000a144, 0x111f1100},
|
||||
{0x0000a148, 0x111d111e},
|
||||
{0x0000a14c, 0x111b111c},
|
||||
{0x0000a150, 0x22032204},
|
||||
{0x0000a154, 0x22012202},
|
||||
{0x0000a158, 0x221f2200},
|
||||
{0x0000a15c, 0x221d221e},
|
||||
{0x0000a160, 0x33013302},
|
||||
{0x0000a164, 0x331f3300},
|
||||
{0x0000a168, 0x4402331e},
|
||||
{0x0000a16c, 0x44004401},
|
||||
{0x0000a170, 0x441e441f},
|
||||
{0x0000a174, 0x55015502},
|
||||
{0x0000a178, 0x551f5500},
|
||||
{0x0000a17c, 0x6602551e},
|
||||
{0x0000a180, 0x66006601},
|
||||
{0x0000a184, 0x661e661f},
|
||||
{0x0000a188, 0x7703661d},
|
||||
{0x0000a18c, 0x77017702},
|
||||
{0x0000a190, 0x00007700},
|
||||
{0x0000a194, 0x00000000},
|
||||
{0x0000a198, 0x00000000},
|
||||
{0x0000a19c, 0x00000000},
|
||||
{0x0000a1a0, 0x00000000},
|
||||
{0x0000a1a4, 0x00000000},
|
||||
{0x0000a1a8, 0x00000000},
|
||||
{0x0000a1ac, 0x00000000},
|
||||
{0x0000a1b0, 0x00000000},
|
||||
{0x0000a1b4, 0x00000000},
|
||||
{0x0000a1b8, 0x00000000},
|
||||
{0x0000a1bc, 0x00000000},
|
||||
{0x0000a1c0, 0x00000000},
|
||||
{0x0000a1c4, 0x00000000},
|
||||
{0x0000a1c8, 0x00000000},
|
||||
{0x0000a1cc, 0x00000000},
|
||||
{0x0000a1d0, 0x00000000},
|
||||
{0x0000a1d4, 0x00000000},
|
||||
{0x0000a1d8, 0x00000000},
|
||||
{0x0000a1dc, 0x00000000},
|
||||
{0x0000a1e0, 0x00000000},
|
||||
{0x0000a1e4, 0x00000000},
|
||||
{0x0000a1e8, 0x00000000},
|
||||
{0x0000a1ec, 0x00000000},
|
||||
{0x0000a1f0, 0x00000396},
|
||||
{0x0000a1f4, 0x00000396},
|
||||
{0x0000a1f8, 0x00000396},
|
||||
{0x0000a1fc, 0x00000296},
|
||||
};
|
||||
#define ar9331_1p2_xtal_25M ar9331_1p1_xtal_25M
|
||||
|
||||
static const u32 ar9331_1p2_baseband_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00009800, 0xafe68e30},
|
||||
{0x00009804, 0xfd14e000},
|
||||
{0x00009808, 0x9c0a8f6b},
|
||||
{0x0000980c, 0x04800000},
|
||||
{0x00009814, 0x9280c00a},
|
||||
{0x00009818, 0x00000000},
|
||||
{0x0000981c, 0x00020028},
|
||||
{0x00009834, 0x5f3ca3de},
|
||||
{0x00009838, 0x0108ecff},
|
||||
{0x0000983c, 0x14750600},
|
||||
{0x00009880, 0x201fff00},
|
||||
{0x00009884, 0x00001042},
|
||||
{0x000098a4, 0x00200400},
|
||||
{0x000098b0, 0x32840bbe},
|
||||
{0x000098d0, 0x004b6a8e},
|
||||
{0x000098d4, 0x00000820},
|
||||
{0x000098dc, 0x00000000},
|
||||
{0x000098f0, 0x00000000},
|
||||
{0x000098f4, 0x00000000},
|
||||
{0x00009c04, 0x00000000},
|
||||
{0x00009c08, 0x03200000},
|
||||
{0x00009c0c, 0x00000000},
|
||||
{0x00009c10, 0x00000000},
|
||||
{0x00009c14, 0x00046384},
|
||||
{0x00009c18, 0x05b6b440},
|
||||
{0x00009c1c, 0x00b6b440},
|
||||
{0x00009d00, 0xc080a333},
|
||||
{0x00009d04, 0x40206c10},
|
||||
{0x00009d08, 0x009c4060},
|
||||
{0x00009d0c, 0x1883800a},
|
||||
{0x00009d10, 0x01834061},
|
||||
{0x00009d14, 0x00c00400},
|
||||
{0x00009d18, 0x00000000},
|
||||
{0x00009e08, 0x0038233c},
|
||||
{0x00009e24, 0x9927b515},
|
||||
{0x00009e28, 0x12ef0200},
|
||||
{0x00009e30, 0x06336f77},
|
||||
{0x00009e34, 0x6af6532f},
|
||||
{0x00009e38, 0x0cc80c00},
|
||||
{0x00009e40, 0x0d261820},
|
||||
{0x00009e4c, 0x00001004},
|
||||
{0x00009e50, 0x00ff03f1},
|
||||
{0x00009fc0, 0x803e4788},
|
||||
{0x00009fc4, 0x0001efb5},
|
||||
{0x00009fcc, 0x40000014},
|
||||
{0x0000a20c, 0x00000000},
|
||||
{0x0000a220, 0x00000000},
|
||||
{0x0000a224, 0x00000000},
|
||||
{0x0000a228, 0x10002310},
|
||||
{0x0000a23c, 0x00000000},
|
||||
{0x0000a244, 0x0c000000},
|
||||
{0x0000a2a0, 0x00000001},
|
||||
{0x0000a2c0, 0x00000001},
|
||||
{0x0000a2c8, 0x00000000},
|
||||
{0x0000a2cc, 0x18c43433},
|
||||
{0x0000a2d4, 0x00000000},
|
||||
{0x0000a2dc, 0x00000000},
|
||||
{0x0000a2e0, 0x00000000},
|
||||
{0x0000a2e4, 0x00000000},
|
||||
{0x0000a2e8, 0x00000000},
|
||||
{0x0000a2ec, 0x00000000},
|
||||
{0x0000a2f0, 0x00000000},
|
||||
{0x0000a2f4, 0x00000000},
|
||||
{0x0000a2f8, 0x00000000},
|
||||
{0x0000a344, 0x00000000},
|
||||
{0x0000a34c, 0x00000000},
|
||||
{0x0000a350, 0x0000a000},
|
||||
{0x0000a364, 0x00000000},
|
||||
{0x0000a370, 0x00000000},
|
||||
{0x0000a390, 0x00000001},
|
||||
{0x0000a394, 0x00000444},
|
||||
{0x0000a398, 0x001f0e0f},
|
||||
{0x0000a39c, 0x0075393f},
|
||||
{0x0000a3a0, 0xb79f6427},
|
||||
{0x0000a3a4, 0x00000000},
|
||||
{0x0000a3a8, 0xaaaaaaaa},
|
||||
{0x0000a3ac, 0x3c466478},
|
||||
{0x0000a3c0, 0x20202020},
|
||||
{0x0000a3c4, 0x22222220},
|
||||
{0x0000a3c8, 0x20200020},
|
||||
{0x0000a3cc, 0x20202020},
|
||||
{0x0000a3d0, 0x20202020},
|
||||
{0x0000a3d4, 0x20202020},
|
||||
{0x0000a3d8, 0x20202020},
|
||||
{0x0000a3dc, 0x20202020},
|
||||
{0x0000a3e0, 0x20202020},
|
||||
{0x0000a3e4, 0x20202020},
|
||||
{0x0000a3e8, 0x20202020},
|
||||
{0x0000a3ec, 0x20202020},
|
||||
{0x0000a3f0, 0x00000000},
|
||||
{0x0000a3f4, 0x00000006},
|
||||
{0x0000a3f8, 0x0cdbd380},
|
||||
{0x0000a3fc, 0x000f0f01},
|
||||
{0x0000a400, 0x8fa91f01},
|
||||
{0x0000a404, 0x00000000},
|
||||
{0x0000a408, 0x0e79e5c6},
|
||||
{0x0000a40c, 0x00820820},
|
||||
{0x0000a414, 0x1ce739ce},
|
||||
{0x0000a418, 0x2d001dce},
|
||||
{0x0000a41c, 0x1ce739ce},
|
||||
{0x0000a420, 0x000001ce},
|
||||
{0x0000a424, 0x1ce739ce},
|
||||
{0x0000a428, 0x000001ce},
|
||||
{0x0000a42c, 0x1ce739ce},
|
||||
{0x0000a430, 0x1ce739ce},
|
||||
{0x0000a434, 0x00000000},
|
||||
{0x0000a438, 0x00001801},
|
||||
{0x0000a43c, 0x00000000},
|
||||
{0x0000a440, 0x00000000},
|
||||
{0x0000a444, 0x00000000},
|
||||
{0x0000a448, 0x04000000},
|
||||
{0x0000a44c, 0x00000001},
|
||||
{0x0000a450, 0x00010000},
|
||||
{0x0000a458, 0x00000000},
|
||||
{0x0000a640, 0x00000000},
|
||||
{0x0000a644, 0x3fad9d74},
|
||||
{0x0000a648, 0x0048060a},
|
||||
{0x0000a64c, 0x00003c37},
|
||||
{0x0000a670, 0x03020100},
|
||||
{0x0000a674, 0x09080504},
|
||||
{0x0000a678, 0x0d0c0b0a},
|
||||
{0x0000a67c, 0x13121110},
|
||||
{0x0000a680, 0x31301514},
|
||||
{0x0000a684, 0x35343332},
|
||||
{0x0000a688, 0x00000036},
|
||||
{0x0000a690, 0x00000838},
|
||||
{0x0000a7c0, 0x00000000},
|
||||
{0x0000a7c4, 0xfffffffc},
|
||||
{0x0000a7c8, 0x00000000},
|
||||
{0x0000a7cc, 0x00000000},
|
||||
{0x0000a7d0, 0x00000000},
|
||||
{0x0000a7d4, 0x00000004},
|
||||
{0x0000a7dc, 0x00000001},
|
||||
};
|
||||
#define ar9331_1p2_xtal_40M ar9331_1p1_xtal_40M
|
||||
|
||||
static const u32 ar9331_modes_high_power_tx_gain_1p2[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7},
|
||||
{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
|
||||
{0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
|
||||
{0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
|
||||
{0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
|
||||
{0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
|
||||
{0x0000a520, 0x2f001f04, 0x2f001f04, 0x23000a00, 0x23000a00},
|
||||
{0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02},
|
||||
{0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04},
|
||||
{0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620},
|
||||
{0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621},
|
||||
{0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640},
|
||||
{0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641},
|
||||
{0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642},
|
||||
{0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644},
|
||||
{0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81},
|
||||
{0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83},
|
||||
{0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84},
|
||||
{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3},
|
||||
{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5},
|
||||
{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9},
|
||||
{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec},
|
||||
{0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec},
|
||||
{0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec},
|
||||
{0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
|
||||
{0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
|
||||
{0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
|
||||
{0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200},
|
||||
{0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202},
|
||||
{0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400},
|
||||
{0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402},
|
||||
{0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404},
|
||||
{0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603},
|
||||
{0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02},
|
||||
{0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04},
|
||||
{0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20},
|
||||
{0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20},
|
||||
{0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22},
|
||||
{0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24},
|
||||
{0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640},
|
||||
{0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660},
|
||||
{0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861},
|
||||
{0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81},
|
||||
{0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83},
|
||||
{0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84},
|
||||
{0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3},
|
||||
{0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5},
|
||||
{0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9},
|
||||
{0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb},
|
||||
{0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501},
|
||||
{0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802},
|
||||
{0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03},
|
||||
{0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
{0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004},
|
||||
};
|
||||
#define ar9331_1p2_baseband_core ar9331_1p1_baseband_core
|
||||
|
||||
static const u32 ar9331_1p2_mac_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
|
||||
{0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
|
||||
{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
|
||||
};
|
||||
#define ar9331_1p2_soc_postamble ar9331_1p1_soc_postamble
|
||||
|
||||
static const u32 ar9331_1p2_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00007020, 0x00000000},
|
||||
{0x00007034, 0x00000002},
|
||||
{0x00007038, 0x000002f8},
|
||||
};
|
||||
#define ar9331_1p2_mac_postamble ar9331_1p1_mac_postamble
|
||||
|
||||
static const u32 ar9331_1p2_xtal_40M[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00007038, 0x000004c2},
|
||||
{0x00008244, 0x0010f400},
|
||||
{0x0000824c, 0x0001e800},
|
||||
{0x0001609c, 0x0b283f31},
|
||||
};
|
||||
#define ar9331_1p2_soc_preamble ar9331_1p1_soc_preamble
|
||||
|
||||
static const u32 ar9331_1p2_mac_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00000008, 0x00000000},
|
||||
{0x00000030, 0x00020085},
|
||||
{0x00000034, 0x00000005},
|
||||
{0x00000040, 0x00000000},
|
||||
{0x00000044, 0x00000000},
|
||||
{0x00000048, 0x00000008},
|
||||
{0x0000004c, 0x00000010},
|
||||
{0x00000050, 0x00000000},
|
||||
{0x00001040, 0x002ffc0f},
|
||||
{0x00001044, 0x002ffc0f},
|
||||
{0x00001048, 0x002ffc0f},
|
||||
{0x0000104c, 0x002ffc0f},
|
||||
{0x00001050, 0x002ffc0f},
|
||||
{0x00001054, 0x002ffc0f},
|
||||
{0x00001058, 0x002ffc0f},
|
||||
{0x0000105c, 0x002ffc0f},
|
||||
{0x00001060, 0x002ffc0f},
|
||||
{0x00001064, 0x002ffc0f},
|
||||
{0x000010f0, 0x00000100},
|
||||
{0x00001270, 0x00000000},
|
||||
{0x000012b0, 0x00000000},
|
||||
{0x000012f0, 0x00000000},
|
||||
{0x0000143c, 0x00000000},
|
||||
{0x0000147c, 0x00000000},
|
||||
{0x00008000, 0x00000000},
|
||||
{0x00008004, 0x00000000},
|
||||
{0x00008008, 0x00000000},
|
||||
{0x0000800c, 0x00000000},
|
||||
{0x00008018, 0x00000000},
|
||||
{0x00008020, 0x00000000},
|
||||
{0x00008038, 0x00000000},
|
||||
{0x0000803c, 0x00000000},
|
||||
{0x00008040, 0x00000000},
|
||||
{0x00008044, 0x00000000},
|
||||
{0x00008048, 0x00000000},
|
||||
{0x0000804c, 0xffffffff},
|
||||
{0x00008054, 0x00000000},
|
||||
{0x00008058, 0x00000000},
|
||||
{0x0000805c, 0x000fc78f},
|
||||
{0x00008060, 0x0000000f},
|
||||
{0x00008064, 0x00000000},
|
||||
{0x00008070, 0x00000310},
|
||||
{0x00008074, 0x00000020},
|
||||
{0x00008078, 0x00000000},
|
||||
{0x0000809c, 0x0000000f},
|
||||
{0x000080a0, 0x00000000},
|
||||
{0x000080a4, 0x02ff0000},
|
||||
{0x000080a8, 0x0e070605},
|
||||
{0x000080ac, 0x0000000d},
|
||||
{0x000080b0, 0x00000000},
|
||||
{0x000080b4, 0x00000000},
|
||||
{0x000080b8, 0x00000000},
|
||||
{0x000080bc, 0x00000000},
|
||||
{0x000080c0, 0x2a800000},
|
||||
{0x000080c4, 0x06900168},
|
||||
{0x000080c8, 0x13881c20},
|
||||
{0x000080cc, 0x01f40000},
|
||||
{0x000080d0, 0x00252500},
|
||||
{0x000080d4, 0x00a00000},
|
||||
{0x000080d8, 0x00400000},
|
||||
{0x000080dc, 0x00000000},
|
||||
{0x000080e0, 0xffffffff},
|
||||
{0x000080e4, 0x0000ffff},
|
||||
{0x000080e8, 0x3f3f3f3f},
|
||||
{0x000080ec, 0x00000000},
|
||||
{0x000080f0, 0x00000000},
|
||||
{0x000080f4, 0x00000000},
|
||||
{0x000080fc, 0x00020000},
|
||||
{0x00008100, 0x00000000},
|
||||
{0x00008108, 0x00000052},
|
||||
{0x0000810c, 0x00000000},
|
||||
{0x00008110, 0x00000000},
|
||||
{0x00008114, 0x000007ff},
|
||||
{0x00008118, 0x000000aa},
|
||||
{0x0000811c, 0x00003210},
|
||||
{0x00008124, 0x00000000},
|
||||
{0x00008128, 0x00000000},
|
||||
{0x0000812c, 0x00000000},
|
||||
{0x00008130, 0x00000000},
|
||||
{0x00008134, 0x00000000},
|
||||
{0x00008138, 0x00000000},
|
||||
{0x0000813c, 0x0000ffff},
|
||||
{0x00008144, 0xffffffff},
|
||||
{0x00008168, 0x00000000},
|
||||
{0x0000816c, 0x00000000},
|
||||
{0x00008170, 0x18486200},
|
||||
{0x00008174, 0x33332210},
|
||||
{0x00008178, 0x00000000},
|
||||
{0x0000817c, 0x00020000},
|
||||
{0x000081c0, 0x00000000},
|
||||
{0x000081c4, 0x33332210},
|
||||
{0x000081c8, 0x00000000},
|
||||
{0x000081cc, 0x00000000},
|
||||
{0x000081d4, 0x00000000},
|
||||
{0x000081ec, 0x00000000},
|
||||
{0x000081f0, 0x00000000},
|
||||
{0x000081f4, 0x00000000},
|
||||
{0x000081f8, 0x00000000},
|
||||
{0x000081fc, 0x00000000},
|
||||
{0x00008240, 0x00100000},
|
||||
{0x00008248, 0x00000800},
|
||||
{0x00008250, 0x00000000},
|
||||
{0x00008254, 0x00000000},
|
||||
{0x00008258, 0x00000000},
|
||||
{0x0000825c, 0x40000000},
|
||||
{0x00008260, 0x00080922},
|
||||
{0x00008264, 0x9d400010},
|
||||
{0x00008268, 0xffffffff},
|
||||
{0x0000826c, 0x0000ffff},
|
||||
{0x00008270, 0x00000000},
|
||||
{0x00008274, 0x40000000},
|
||||
{0x00008278, 0x003e4180},
|
||||
{0x0000827c, 0x00000004},
|
||||
{0x00008284, 0x0000002c},
|
||||
{0x00008288, 0x0000002c},
|
||||
{0x0000828c, 0x000000ff},
|
||||
{0x00008294, 0x00000000},
|
||||
{0x00008298, 0x00000000},
|
||||
{0x0000829c, 0x00000000},
|
||||
{0x00008300, 0x00000140},
|
||||
{0x00008314, 0x00000000},
|
||||
{0x0000831c, 0x0000010d},
|
||||
{0x00008328, 0x00000000},
|
||||
{0x0000832c, 0x00000007},
|
||||
{0x00008330, 0x00000302},
|
||||
{0x00008334, 0x00000700},
|
||||
{0x00008338, 0x00ff0000},
|
||||
{0x0000833c, 0x02400000},
|
||||
{0x00008340, 0x000107ff},
|
||||
{0x00008344, 0xaa48105b},
|
||||
{0x00008348, 0x008f0000},
|
||||
{0x0000835c, 0x00000000},
|
||||
{0x00008360, 0xffffffff},
|
||||
{0x00008364, 0xffffffff},
|
||||
{0x00008368, 0x00000000},
|
||||
{0x00008370, 0x00000000},
|
||||
{0x00008374, 0x000000ff},
|
||||
{0x00008378, 0x00000000},
|
||||
{0x0000837c, 0x00000000},
|
||||
{0x00008380, 0xffffffff},
|
||||
{0x00008384, 0xffffffff},
|
||||
{0x00008390, 0xffffffff},
|
||||
{0x00008394, 0xffffffff},
|
||||
{0x00008398, 0x00000000},
|
||||
{0x0000839c, 0x00000000},
|
||||
{0x000083a0, 0x00000000},
|
||||
{0x000083a4, 0x0000fa14},
|
||||
{0x000083a8, 0x000f0c00},
|
||||
{0x000083ac, 0x33332210},
|
||||
{0x000083b0, 0x33332210},
|
||||
{0x000083b4, 0x33332210},
|
||||
{0x000083b8, 0x33332210},
|
||||
{0x000083bc, 0x00000000},
|
||||
{0x000083c0, 0x00000000},
|
||||
{0x000083c4, 0x00000000},
|
||||
{0x000083c8, 0x00000000},
|
||||
{0x000083cc, 0x00000200},
|
||||
{0x000083d0, 0x000301ff},
|
||||
};
|
||||
#define ar9331_1p2_mac_core ar9331_1p1_mac_core
|
||||
|
||||
static const u32 ar9331_common_rx_gain_1p2[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
{0x0000a008, 0x00050004},
|
||||
{0x0000a00c, 0x00810080},
|
||||
{0x0000a010, 0x01800082},
|
||||
{0x0000a014, 0x01820181},
|
||||
{0x0000a018, 0x01840183},
|
||||
{0x0000a01c, 0x01880185},
|
||||
{0x0000a020, 0x018a0189},
|
||||
{0x0000a024, 0x02850284},
|
||||
{0x0000a028, 0x02890288},
|
||||
{0x0000a02c, 0x03850384},
|
||||
{0x0000a030, 0x03890388},
|
||||
{0x0000a034, 0x038b038a},
|
||||
{0x0000a038, 0x038d038c},
|
||||
{0x0000a03c, 0x03910390},
|
||||
{0x0000a040, 0x03930392},
|
||||
{0x0000a044, 0x03950394},
|
||||
{0x0000a048, 0x00000396},
|
||||
{0x0000a04c, 0x00000000},
|
||||
{0x0000a050, 0x00000000},
|
||||
{0x0000a054, 0x00000000},
|
||||
{0x0000a058, 0x00000000},
|
||||
{0x0000a05c, 0x00000000},
|
||||
{0x0000a060, 0x00000000},
|
||||
{0x0000a064, 0x00000000},
|
||||
{0x0000a068, 0x00000000},
|
||||
{0x0000a06c, 0x00000000},
|
||||
{0x0000a070, 0x00000000},
|
||||
{0x0000a074, 0x00000000},
|
||||
{0x0000a078, 0x00000000},
|
||||
{0x0000a07c, 0x00000000},
|
||||
{0x0000a080, 0x28282828},
|
||||
{0x0000a084, 0x28282828},
|
||||
{0x0000a088, 0x28282828},
|
||||
{0x0000a08c, 0x28282828},
|
||||
{0x0000a090, 0x28282828},
|
||||
{0x0000a094, 0x21212128},
|
||||
{0x0000a098, 0x171c1c1c},
|
||||
{0x0000a09c, 0x02020212},
|
||||
{0x0000a0a0, 0x00000202},
|
||||
{0x0000a0a4, 0x00000000},
|
||||
{0x0000a0a8, 0x00000000},
|
||||
{0x0000a0ac, 0x00000000},
|
||||
{0x0000a0b0, 0x00000000},
|
||||
{0x0000a0b4, 0x00000000},
|
||||
{0x0000a0b8, 0x00000000},
|
||||
{0x0000a0bc, 0x00000000},
|
||||
{0x0000a0c0, 0x001f0000},
|
||||
{0x0000a0c4, 0x111f1100},
|
||||
{0x0000a0c8, 0x111d111e},
|
||||
{0x0000a0cc, 0x111b111c},
|
||||
{0x0000a0d0, 0x22032204},
|
||||
{0x0000a0d4, 0x22012202},
|
||||
{0x0000a0d8, 0x221f2200},
|
||||
{0x0000a0dc, 0x221d221e},
|
||||
{0x0000a0e0, 0x33013302},
|
||||
{0x0000a0e4, 0x331f3300},
|
||||
{0x0000a0e8, 0x4402331e},
|
||||
{0x0000a0ec, 0x44004401},
|
||||
{0x0000a0f0, 0x441e441f},
|
||||
{0x0000a0f4, 0x55015502},
|
||||
{0x0000a0f8, 0x551f5500},
|
||||
{0x0000a0fc, 0x6602551e},
|
||||
{0x0000a100, 0x66006601},
|
||||
{0x0000a104, 0x661e661f},
|
||||
{0x0000a108, 0x7703661d},
|
||||
{0x0000a10c, 0x77017702},
|
||||
{0x0000a110, 0x00007700},
|
||||
{0x0000a114, 0x00000000},
|
||||
{0x0000a118, 0x00000000},
|
||||
{0x0000a11c, 0x00000000},
|
||||
{0x0000a120, 0x00000000},
|
||||
{0x0000a124, 0x00000000},
|
||||
{0x0000a128, 0x00000000},
|
||||
{0x0000a12c, 0x00000000},
|
||||
{0x0000a130, 0x00000000},
|
||||
{0x0000a134, 0x00000000},
|
||||
{0x0000a138, 0x00000000},
|
||||
{0x0000a13c, 0x00000000},
|
||||
{0x0000a140, 0x001f0000},
|
||||
{0x0000a144, 0x111f1100},
|
||||
{0x0000a148, 0x111d111e},
|
||||
{0x0000a14c, 0x111b111c},
|
||||
{0x0000a150, 0x22032204},
|
||||
{0x0000a154, 0x22012202},
|
||||
{0x0000a158, 0x221f2200},
|
||||
{0x0000a15c, 0x221d221e},
|
||||
{0x0000a160, 0x33013302},
|
||||
{0x0000a164, 0x331f3300},
|
||||
{0x0000a168, 0x4402331e},
|
||||
{0x0000a16c, 0x44004401},
|
||||
{0x0000a170, 0x441e441f},
|
||||
{0x0000a174, 0x55015502},
|
||||
{0x0000a178, 0x551f5500},
|
||||
{0x0000a17c, 0x6602551e},
|
||||
{0x0000a180, 0x66006601},
|
||||
{0x0000a184, 0x661e661f},
|
||||
{0x0000a188, 0x7703661d},
|
||||
{0x0000a18c, 0x77017702},
|
||||
{0x0000a190, 0x00007700},
|
||||
{0x0000a194, 0x00000000},
|
||||
{0x0000a198, 0x00000000},
|
||||
{0x0000a19c, 0x00000000},
|
||||
{0x0000a1a0, 0x00000000},
|
||||
{0x0000a1a4, 0x00000000},
|
||||
{0x0000a1a8, 0x00000000},
|
||||
{0x0000a1ac, 0x00000000},
|
||||
{0x0000a1b0, 0x00000000},
|
||||
{0x0000a1b4, 0x00000000},
|
||||
{0x0000a1b8, 0x00000000},
|
||||
{0x0000a1bc, 0x00000000},
|
||||
{0x0000a1c0, 0x00000000},
|
||||
{0x0000a1c4, 0x00000000},
|
||||
{0x0000a1c8, 0x00000000},
|
||||
{0x0000a1cc, 0x00000000},
|
||||
{0x0000a1d0, 0x00000000},
|
||||
{0x0000a1d4, 0x00000000},
|
||||
{0x0000a1d8, 0x00000000},
|
||||
{0x0000a1dc, 0x00000000},
|
||||
{0x0000a1e0, 0x00000000},
|
||||
{0x0000a1e4, 0x00000000},
|
||||
{0x0000a1e8, 0x00000000},
|
||||
{0x0000a1ec, 0x00000000},
|
||||
{0x0000a1f0, 0x00000396},
|
||||
{0x0000a1f4, 0x00000396},
|
||||
{0x0000a1f8, 0x00000396},
|
||||
{0x0000a1fc, 0x00000296},
|
||||
};
|
||||
#define ar9331_common_wo_xlna_rx_gain_1p2 ar9331_common_wo_xlna_rx_gain_1p1
|
||||
|
||||
#define ar9331_common_rx_gain_1p2 ar9485_common_rx_gain_1_1
|
||||
|
||||
#endif /* INITVALS_9330_1P2_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Atheros Communications Inc.
|
||||
* 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
|
||||
@ -61,7 +62,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
|
||||
{0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
|
||||
{0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
|
||||
{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
|
||||
{0x0000a204, 0x013187c0, 0x013187c4, 0x013187c4, 0x013187c0},
|
||||
{0x0000a204, 0x01318fc0, 0x01318fc4, 0x01318fc4, 0x01318fc0},
|
||||
{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
|
||||
{0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f},
|
||||
{0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
|
||||
@ -1007,7 +1008,7 @@ static const u32 ar9462_2p0_radio_core[][2] = {
|
||||
|
||||
static const u32 ar9462_2p0_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000040a4 ,0x00a0c1c9},
|
||||
{0x000040a4, 0x00a0c1c9},
|
||||
{0x00007020, 0x00000000},
|
||||
{0x00007034, 0x00000002},
|
||||
{0x00007038, 0x000004c2},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Atheros Communications Inc.
|
||||
* 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
|
||||
@ -19,18 +20,7 @@
|
||||
|
||||
/* AR9580 1.0 */
|
||||
|
||||
static const u32 ar9580_1p0_modes_fast_clock[][3] = {
|
||||
/* Addr 5G_HT20 5G_HT40 */
|
||||
{0x00001030, 0x00000268, 0x000004d0},
|
||||
{0x00001070, 0x0000018c, 0x00000318},
|
||||
{0x000010b0, 0x00000fd0, 0x00001fa0},
|
||||
{0x00008014, 0x044c044c, 0x08980898},
|
||||
{0x0000801c, 0x148ec02b, 0x148ec057},
|
||||
{0x00008318, 0x000044c0, 0x00008980},
|
||||
{0x00009e00, 0x0372131c, 0x0372131c},
|
||||
{0x0000a230, 0x0000000b, 0x00000016},
|
||||
{0x0000a254, 0x00000898, 0x00001130},
|
||||
};
|
||||
#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2
|
||||
|
||||
static const u32 ar9580_1p0_radio_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
@ -208,17 +198,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
|
||||
{0x0000c420, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_mac_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
|
||||
{0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
|
||||
{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
|
||||
};
|
||||
#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
|
||||
|
||||
static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
@ -326,111 +306,7 @@ static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
|
||||
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
|
||||
{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
|
||||
{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
|
||||
{0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
|
||||
{0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
|
||||
{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
|
||||
{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
|
||||
{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
|
||||
{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
|
||||
{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
|
||||
{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
|
||||
{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
|
||||
{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
|
||||
{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
|
||||
{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
|
||||
{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
|
||||
{0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
|
||||
{0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
|
||||
{0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
|
||||
{0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
|
||||
{0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
|
||||
{0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
|
||||
{0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
|
||||
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
|
||||
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
|
||||
{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
|
||||
{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
|
||||
{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
|
||||
{0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
|
||||
{0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
|
||||
{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
|
||||
{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
|
||||
{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
|
||||
{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
|
||||
{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
|
||||
{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
|
||||
{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
|
||||
{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
|
||||
{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
|
||||
{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
|
||||
{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
|
||||
{0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
|
||||
{0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
|
||||
{0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
|
||||
{0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
|
||||
{0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
|
||||
{0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
|
||||
{0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
|
||||
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
|
||||
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table
|
||||
|
||||
static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
@ -538,12 +414,7 @@ static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a398, 0x00000000},
|
||||
{0x0000a39c, 0x6f7f0301},
|
||||
{0x0000a3a0, 0xca9228ee},
|
||||
};
|
||||
#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
static const u32 ar9580_1p0_mac_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
@ -808,376 +679,11 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = {
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_wo_xlna_rx_gain_table[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
{0x0000a008, 0x00050004},
|
||||
{0x0000a00c, 0x00810080},
|
||||
{0x0000a010, 0x00830082},
|
||||
{0x0000a014, 0x01810180},
|
||||
{0x0000a018, 0x01830182},
|
||||
{0x0000a01c, 0x01850184},
|
||||
{0x0000a020, 0x01890188},
|
||||
{0x0000a024, 0x018b018a},
|
||||
{0x0000a028, 0x018d018c},
|
||||
{0x0000a02c, 0x03820190},
|
||||
{0x0000a030, 0x03840383},
|
||||
{0x0000a034, 0x03880385},
|
||||
{0x0000a038, 0x038a0389},
|
||||
{0x0000a03c, 0x038c038b},
|
||||
{0x0000a040, 0x0390038d},
|
||||
{0x0000a044, 0x03920391},
|
||||
{0x0000a048, 0x03940393},
|
||||
{0x0000a04c, 0x03960395},
|
||||
{0x0000a050, 0x00000000},
|
||||
{0x0000a054, 0x00000000},
|
||||
{0x0000a058, 0x00000000},
|
||||
{0x0000a05c, 0x00000000},
|
||||
{0x0000a060, 0x00000000},
|
||||
{0x0000a064, 0x00000000},
|
||||
{0x0000a068, 0x00000000},
|
||||
{0x0000a06c, 0x00000000},
|
||||
{0x0000a070, 0x00000000},
|
||||
{0x0000a074, 0x00000000},
|
||||
{0x0000a078, 0x00000000},
|
||||
{0x0000a07c, 0x00000000},
|
||||
{0x0000a080, 0x29292929},
|
||||
{0x0000a084, 0x29292929},
|
||||
{0x0000a088, 0x29292929},
|
||||
{0x0000a08c, 0x29292929},
|
||||
{0x0000a090, 0x22292929},
|
||||
{0x0000a094, 0x1d1d2222},
|
||||
{0x0000a098, 0x0c111117},
|
||||
{0x0000a09c, 0x00030303},
|
||||
{0x0000a0a0, 0x00000000},
|
||||
{0x0000a0a4, 0x00000000},
|
||||
{0x0000a0a8, 0x00000000},
|
||||
{0x0000a0ac, 0x00000000},
|
||||
{0x0000a0b0, 0x00000000},
|
||||
{0x0000a0b4, 0x00000000},
|
||||
{0x0000a0b8, 0x00000000},
|
||||
{0x0000a0bc, 0x00000000},
|
||||
{0x0000a0c0, 0x001f0000},
|
||||
{0x0000a0c4, 0x01000101},
|
||||
{0x0000a0c8, 0x011e011f},
|
||||
{0x0000a0cc, 0x011c011d},
|
||||
{0x0000a0d0, 0x02030204},
|
||||
{0x0000a0d4, 0x02010202},
|
||||
{0x0000a0d8, 0x021f0200},
|
||||
{0x0000a0dc, 0x0302021e},
|
||||
{0x0000a0e0, 0x03000301},
|
||||
{0x0000a0e4, 0x031e031f},
|
||||
{0x0000a0e8, 0x0402031d},
|
||||
{0x0000a0ec, 0x04000401},
|
||||
{0x0000a0f0, 0x041e041f},
|
||||
{0x0000a0f4, 0x0502041d},
|
||||
{0x0000a0f8, 0x05000501},
|
||||
{0x0000a0fc, 0x051e051f},
|
||||
{0x0000a100, 0x06010602},
|
||||
{0x0000a104, 0x061f0600},
|
||||
{0x0000a108, 0x061d061e},
|
||||
{0x0000a10c, 0x07020703},
|
||||
{0x0000a110, 0x07000701},
|
||||
{0x0000a114, 0x00000000},
|
||||
{0x0000a118, 0x00000000},
|
||||
{0x0000a11c, 0x00000000},
|
||||
{0x0000a120, 0x00000000},
|
||||
{0x0000a124, 0x00000000},
|
||||
{0x0000a128, 0x00000000},
|
||||
{0x0000a12c, 0x00000000},
|
||||
{0x0000a130, 0x00000000},
|
||||
{0x0000a134, 0x00000000},
|
||||
{0x0000a138, 0x00000000},
|
||||
{0x0000a13c, 0x00000000},
|
||||
{0x0000a140, 0x001f0000},
|
||||
{0x0000a144, 0x01000101},
|
||||
{0x0000a148, 0x011e011f},
|
||||
{0x0000a14c, 0x011c011d},
|
||||
{0x0000a150, 0x02030204},
|
||||
{0x0000a154, 0x02010202},
|
||||
{0x0000a158, 0x021f0200},
|
||||
{0x0000a15c, 0x0302021e},
|
||||
{0x0000a160, 0x03000301},
|
||||
{0x0000a164, 0x031e031f},
|
||||
{0x0000a168, 0x0402031d},
|
||||
{0x0000a16c, 0x04000401},
|
||||
{0x0000a170, 0x041e041f},
|
||||
{0x0000a174, 0x0502041d},
|
||||
{0x0000a178, 0x05000501},
|
||||
{0x0000a17c, 0x051e051f},
|
||||
{0x0000a180, 0x06010602},
|
||||
{0x0000a184, 0x061f0600},
|
||||
{0x0000a188, 0x061d061e},
|
||||
{0x0000a18c, 0x07020703},
|
||||
{0x0000a190, 0x07000701},
|
||||
{0x0000a194, 0x00000000},
|
||||
{0x0000a198, 0x00000000},
|
||||
{0x0000a19c, 0x00000000},
|
||||
{0x0000a1a0, 0x00000000},
|
||||
{0x0000a1a4, 0x00000000},
|
||||
{0x0000a1a8, 0x00000000},
|
||||
{0x0000a1ac, 0x00000000},
|
||||
{0x0000a1b0, 0x00000000},
|
||||
{0x0000a1b4, 0x00000000},
|
||||
{0x0000a1b8, 0x00000000},
|
||||
{0x0000a1bc, 0x00000000},
|
||||
{0x0000a1c0, 0x00000000},
|
||||
{0x0000a1c4, 0x00000000},
|
||||
{0x0000a1c8, 0x00000000},
|
||||
{0x0000a1cc, 0x00000000},
|
||||
{0x0000a1d0, 0x00000000},
|
||||
{0x0000a1d4, 0x00000000},
|
||||
{0x0000a1d8, 0x00000000},
|
||||
{0x0000a1dc, 0x00000000},
|
||||
{0x0000a1e0, 0x00000000},
|
||||
{0x0000a1e4, 0x00000000},
|
||||
{0x0000a1e8, 0x00000000},
|
||||
{0x0000a1ec, 0x00000000},
|
||||
{0x0000a1f0, 0x00000396},
|
||||
{0x0000a1f4, 0x00000396},
|
||||
{0x0000a1f8, 0x00000396},
|
||||
{0x0000a1fc, 0x00000196},
|
||||
{0x0000b000, 0x00010000},
|
||||
{0x0000b004, 0x00030002},
|
||||
{0x0000b008, 0x00050004},
|
||||
{0x0000b00c, 0x00810080},
|
||||
{0x0000b010, 0x00830082},
|
||||
{0x0000b014, 0x01810180},
|
||||
{0x0000b018, 0x01830182},
|
||||
{0x0000b01c, 0x01850184},
|
||||
{0x0000b020, 0x02810280},
|
||||
{0x0000b024, 0x02830282},
|
||||
{0x0000b028, 0x02850284},
|
||||
{0x0000b02c, 0x02890288},
|
||||
{0x0000b030, 0x028b028a},
|
||||
{0x0000b034, 0x0388028c},
|
||||
{0x0000b038, 0x038a0389},
|
||||
{0x0000b03c, 0x038c038b},
|
||||
{0x0000b040, 0x0390038d},
|
||||
{0x0000b044, 0x03920391},
|
||||
{0x0000b048, 0x03940393},
|
||||
{0x0000b04c, 0x03960395},
|
||||
{0x0000b050, 0x00000000},
|
||||
{0x0000b054, 0x00000000},
|
||||
{0x0000b058, 0x00000000},
|
||||
{0x0000b05c, 0x00000000},
|
||||
{0x0000b060, 0x00000000},
|
||||
{0x0000b064, 0x00000000},
|
||||
{0x0000b068, 0x00000000},
|
||||
{0x0000b06c, 0x00000000},
|
||||
{0x0000b070, 0x00000000},
|
||||
{0x0000b074, 0x00000000},
|
||||
{0x0000b078, 0x00000000},
|
||||
{0x0000b07c, 0x00000000},
|
||||
{0x0000b080, 0x32323232},
|
||||
{0x0000b084, 0x2f2f3232},
|
||||
{0x0000b088, 0x23282a2d},
|
||||
{0x0000b08c, 0x1c1e2123},
|
||||
{0x0000b090, 0x14171919},
|
||||
{0x0000b094, 0x0e0e1214},
|
||||
{0x0000b098, 0x03050707},
|
||||
{0x0000b09c, 0x00030303},
|
||||
{0x0000b0a0, 0x00000000},
|
||||
{0x0000b0a4, 0x00000000},
|
||||
{0x0000b0a8, 0x00000000},
|
||||
{0x0000b0ac, 0x00000000},
|
||||
{0x0000b0b0, 0x00000000},
|
||||
{0x0000b0b4, 0x00000000},
|
||||
{0x0000b0b8, 0x00000000},
|
||||
{0x0000b0bc, 0x00000000},
|
||||
{0x0000b0c0, 0x003f0020},
|
||||
{0x0000b0c4, 0x00400041},
|
||||
{0x0000b0c8, 0x0140005f},
|
||||
{0x0000b0cc, 0x0160015f},
|
||||
{0x0000b0d0, 0x017e017f},
|
||||
{0x0000b0d4, 0x02410242},
|
||||
{0x0000b0d8, 0x025f0240},
|
||||
{0x0000b0dc, 0x027f0260},
|
||||
{0x0000b0e0, 0x0341027e},
|
||||
{0x0000b0e4, 0x035f0340},
|
||||
{0x0000b0e8, 0x037f0360},
|
||||
{0x0000b0ec, 0x04400441},
|
||||
{0x0000b0f0, 0x0460045f},
|
||||
{0x0000b0f4, 0x0541047f},
|
||||
{0x0000b0f8, 0x055f0540},
|
||||
{0x0000b0fc, 0x057f0560},
|
||||
{0x0000b100, 0x06400641},
|
||||
{0x0000b104, 0x0660065f},
|
||||
{0x0000b108, 0x067e067f},
|
||||
{0x0000b10c, 0x07410742},
|
||||
{0x0000b110, 0x075f0740},
|
||||
{0x0000b114, 0x077f0760},
|
||||
{0x0000b118, 0x07800781},
|
||||
{0x0000b11c, 0x07a0079f},
|
||||
{0x0000b120, 0x07c107bf},
|
||||
{0x0000b124, 0x000007c0},
|
||||
{0x0000b128, 0x00000000},
|
||||
{0x0000b12c, 0x00000000},
|
||||
{0x0000b130, 0x00000000},
|
||||
{0x0000b134, 0x00000000},
|
||||
{0x0000b138, 0x00000000},
|
||||
{0x0000b13c, 0x00000000},
|
||||
{0x0000b140, 0x003f0020},
|
||||
{0x0000b144, 0x00400041},
|
||||
{0x0000b148, 0x0140005f},
|
||||
{0x0000b14c, 0x0160015f},
|
||||
{0x0000b150, 0x017e017f},
|
||||
{0x0000b154, 0x02410242},
|
||||
{0x0000b158, 0x025f0240},
|
||||
{0x0000b15c, 0x027f0260},
|
||||
{0x0000b160, 0x0341027e},
|
||||
{0x0000b164, 0x035f0340},
|
||||
{0x0000b168, 0x037f0360},
|
||||
{0x0000b16c, 0x04400441},
|
||||
{0x0000b170, 0x0460045f},
|
||||
{0x0000b174, 0x0541047f},
|
||||
{0x0000b178, 0x055f0540},
|
||||
{0x0000b17c, 0x057f0560},
|
||||
{0x0000b180, 0x06400641},
|
||||
{0x0000b184, 0x0660065f},
|
||||
{0x0000b188, 0x067e067f},
|
||||
{0x0000b18c, 0x07410742},
|
||||
{0x0000b190, 0x075f0740},
|
||||
{0x0000b194, 0x077f0760},
|
||||
{0x0000b198, 0x07800781},
|
||||
{0x0000b19c, 0x07a0079f},
|
||||
{0x0000b1a0, 0x07c107bf},
|
||||
{0x0000b1a4, 0x000007c0},
|
||||
{0x0000b1a8, 0x00000000},
|
||||
{0x0000b1ac, 0x00000000},
|
||||
{0x0000b1b0, 0x00000000},
|
||||
{0x0000b1b4, 0x00000000},
|
||||
{0x0000b1b8, 0x00000000},
|
||||
{0x0000b1bc, 0x00000000},
|
||||
{0x0000b1c0, 0x00000000},
|
||||
{0x0000b1c4, 0x00000000},
|
||||
{0x0000b1c8, 0x00000000},
|
||||
{0x0000b1cc, 0x00000000},
|
||||
{0x0000b1d0, 0x00000000},
|
||||
{0x0000b1d4, 0x00000000},
|
||||
{0x0000b1d8, 0x00000000},
|
||||
{0x0000b1dc, 0x00000000},
|
||||
{0x0000b1e0, 0x00000000},
|
||||
{0x0000b1e4, 0x00000000},
|
||||
{0x0000b1e8, 0x00000000},
|
||||
{0x0000b1ec, 0x00000000},
|
||||
{0x0000b1f0, 0x00000396},
|
||||
{0x0000b1f4, 0x00000396},
|
||||
{0x0000b1f8, 0x00000396},
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
|
||||
|
||||
static const u32 ar9580_1p0_soc_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
|
||||
};
|
||||
#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
|
||||
|
||||
static const u32 ar9580_1p0_high_ob_db_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
|
||||
{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
|
||||
{0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
|
||||
{0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
|
||||
{0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
|
||||
{0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
|
||||
{0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
|
||||
{0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
|
||||
{0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
|
||||
{0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
|
||||
{0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
|
||||
{0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
|
||||
{0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
|
||||
{0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
|
||||
{0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
|
||||
{0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
|
||||
{0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
|
||||
{0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
|
||||
{0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
|
||||
{0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
|
||||
{0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
|
||||
{0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
|
||||
{0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
|
||||
{0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
|
||||
{0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
|
||||
{0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
|
||||
{0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
|
||||
{0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
|
||||
{0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
|
||||
{0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
|
||||
{0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
|
||||
{0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
|
||||
{0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
|
||||
{0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
|
||||
{0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
|
||||
{0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
|
||||
{0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
|
||||
{0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
|
||||
{0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
|
||||
{0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
|
||||
{0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
|
||||
{0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
|
||||
{0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
|
||||
{0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
|
||||
{0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
|
||||
{0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
|
||||
{0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
|
||||
{0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
|
||||
{0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
|
||||
{0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
|
||||
{0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
|
||||
{0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
|
||||
{0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
|
||||
{0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
|
||||
{0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
|
||||
{0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
|
||||
{0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
|
||||
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
|
||||
{0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
|
||||
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
|
||||
{0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
|
||||
|
||||
static const u32 ar9580_1p0_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
@ -1189,265 +695,7 @@ static const u32 ar9580_1p0_soc_preamble[][2] = {
|
||||
{0x00007048, 0x00000008},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_rx_gain_table[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
{0x0000a008, 0x00050004},
|
||||
{0x0000a00c, 0x00810080},
|
||||
{0x0000a010, 0x00830082},
|
||||
{0x0000a014, 0x01810180},
|
||||
{0x0000a018, 0x01830182},
|
||||
{0x0000a01c, 0x01850184},
|
||||
{0x0000a020, 0x01890188},
|
||||
{0x0000a024, 0x018b018a},
|
||||
{0x0000a028, 0x018d018c},
|
||||
{0x0000a02c, 0x01910190},
|
||||
{0x0000a030, 0x01930192},
|
||||
{0x0000a034, 0x01950194},
|
||||
{0x0000a038, 0x038a0196},
|
||||
{0x0000a03c, 0x038c038b},
|
||||
{0x0000a040, 0x0390038d},
|
||||
{0x0000a044, 0x03920391},
|
||||
{0x0000a048, 0x03940393},
|
||||
{0x0000a04c, 0x03960395},
|
||||
{0x0000a050, 0x00000000},
|
||||
{0x0000a054, 0x00000000},
|
||||
{0x0000a058, 0x00000000},
|
||||
{0x0000a05c, 0x00000000},
|
||||
{0x0000a060, 0x00000000},
|
||||
{0x0000a064, 0x00000000},
|
||||
{0x0000a068, 0x00000000},
|
||||
{0x0000a06c, 0x00000000},
|
||||
{0x0000a070, 0x00000000},
|
||||
{0x0000a074, 0x00000000},
|
||||
{0x0000a078, 0x00000000},
|
||||
{0x0000a07c, 0x00000000},
|
||||
{0x0000a080, 0x22222229},
|
||||
{0x0000a084, 0x1d1d1d1d},
|
||||
{0x0000a088, 0x1d1d1d1d},
|
||||
{0x0000a08c, 0x1d1d1d1d},
|
||||
{0x0000a090, 0x171d1d1d},
|
||||
{0x0000a094, 0x11111717},
|
||||
{0x0000a098, 0x00030311},
|
||||
{0x0000a09c, 0x00000000},
|
||||
{0x0000a0a0, 0x00000000},
|
||||
{0x0000a0a4, 0x00000000},
|
||||
{0x0000a0a8, 0x00000000},
|
||||
{0x0000a0ac, 0x00000000},
|
||||
{0x0000a0b0, 0x00000000},
|
||||
{0x0000a0b4, 0x00000000},
|
||||
{0x0000a0b8, 0x00000000},
|
||||
{0x0000a0bc, 0x00000000},
|
||||
{0x0000a0c0, 0x001f0000},
|
||||
{0x0000a0c4, 0x01000101},
|
||||
{0x0000a0c8, 0x011e011f},
|
||||
{0x0000a0cc, 0x011c011d},
|
||||
{0x0000a0d0, 0x02030204},
|
||||
{0x0000a0d4, 0x02010202},
|
||||
{0x0000a0d8, 0x021f0200},
|
||||
{0x0000a0dc, 0x0302021e},
|
||||
{0x0000a0e0, 0x03000301},
|
||||
{0x0000a0e4, 0x031e031f},
|
||||
{0x0000a0e8, 0x0402031d},
|
||||
{0x0000a0ec, 0x04000401},
|
||||
{0x0000a0f0, 0x041e041f},
|
||||
{0x0000a0f4, 0x0502041d},
|
||||
{0x0000a0f8, 0x05000501},
|
||||
{0x0000a0fc, 0x051e051f},
|
||||
{0x0000a100, 0x06010602},
|
||||
{0x0000a104, 0x061f0600},
|
||||
{0x0000a108, 0x061d061e},
|
||||
{0x0000a10c, 0x07020703},
|
||||
{0x0000a110, 0x07000701},
|
||||
{0x0000a114, 0x00000000},
|
||||
{0x0000a118, 0x00000000},
|
||||
{0x0000a11c, 0x00000000},
|
||||
{0x0000a120, 0x00000000},
|
||||
{0x0000a124, 0x00000000},
|
||||
{0x0000a128, 0x00000000},
|
||||
{0x0000a12c, 0x00000000},
|
||||
{0x0000a130, 0x00000000},
|
||||
{0x0000a134, 0x00000000},
|
||||
{0x0000a138, 0x00000000},
|
||||
{0x0000a13c, 0x00000000},
|
||||
{0x0000a140, 0x001f0000},
|
||||
{0x0000a144, 0x01000101},
|
||||
{0x0000a148, 0x011e011f},
|
||||
{0x0000a14c, 0x011c011d},
|
||||
{0x0000a150, 0x02030204},
|
||||
{0x0000a154, 0x02010202},
|
||||
{0x0000a158, 0x021f0200},
|
||||
{0x0000a15c, 0x0302021e},
|
||||
{0x0000a160, 0x03000301},
|
||||
{0x0000a164, 0x031e031f},
|
||||
{0x0000a168, 0x0402031d},
|
||||
{0x0000a16c, 0x04000401},
|
||||
{0x0000a170, 0x041e041f},
|
||||
{0x0000a174, 0x0502041d},
|
||||
{0x0000a178, 0x05000501},
|
||||
{0x0000a17c, 0x051e051f},
|
||||
{0x0000a180, 0x06010602},
|
||||
{0x0000a184, 0x061f0600},
|
||||
{0x0000a188, 0x061d061e},
|
||||
{0x0000a18c, 0x07020703},
|
||||
{0x0000a190, 0x07000701},
|
||||
{0x0000a194, 0x00000000},
|
||||
{0x0000a198, 0x00000000},
|
||||
{0x0000a19c, 0x00000000},
|
||||
{0x0000a1a0, 0x00000000},
|
||||
{0x0000a1a4, 0x00000000},
|
||||
{0x0000a1a8, 0x00000000},
|
||||
{0x0000a1ac, 0x00000000},
|
||||
{0x0000a1b0, 0x00000000},
|
||||
{0x0000a1b4, 0x00000000},
|
||||
{0x0000a1b8, 0x00000000},
|
||||
{0x0000a1bc, 0x00000000},
|
||||
{0x0000a1c0, 0x00000000},
|
||||
{0x0000a1c4, 0x00000000},
|
||||
{0x0000a1c8, 0x00000000},
|
||||
{0x0000a1cc, 0x00000000},
|
||||
{0x0000a1d0, 0x00000000},
|
||||
{0x0000a1d4, 0x00000000},
|
||||
{0x0000a1d8, 0x00000000},
|
||||
{0x0000a1dc, 0x00000000},
|
||||
{0x0000a1e0, 0x00000000},
|
||||
{0x0000a1e4, 0x00000000},
|
||||
{0x0000a1e8, 0x00000000},
|
||||
{0x0000a1ec, 0x00000000},
|
||||
{0x0000a1f0, 0x00000396},
|
||||
{0x0000a1f4, 0x00000396},
|
||||
{0x0000a1f8, 0x00000396},
|
||||
{0x0000a1fc, 0x00000196},
|
||||
{0x0000b000, 0x00010000},
|
||||
{0x0000b004, 0x00030002},
|
||||
{0x0000b008, 0x00050004},
|
||||
{0x0000b00c, 0x00810080},
|
||||
{0x0000b010, 0x00830082},
|
||||
{0x0000b014, 0x01810180},
|
||||
{0x0000b018, 0x01830182},
|
||||
{0x0000b01c, 0x01850184},
|
||||
{0x0000b020, 0x02810280},
|
||||
{0x0000b024, 0x02830282},
|
||||
{0x0000b028, 0x02850284},
|
||||
{0x0000b02c, 0x02890288},
|
||||
{0x0000b030, 0x028b028a},
|
||||
{0x0000b034, 0x0388028c},
|
||||
{0x0000b038, 0x038a0389},
|
||||
{0x0000b03c, 0x038c038b},
|
||||
{0x0000b040, 0x0390038d},
|
||||
{0x0000b044, 0x03920391},
|
||||
{0x0000b048, 0x03940393},
|
||||
{0x0000b04c, 0x03960395},
|
||||
{0x0000b050, 0x00000000},
|
||||
{0x0000b054, 0x00000000},
|
||||
{0x0000b058, 0x00000000},
|
||||
{0x0000b05c, 0x00000000},
|
||||
{0x0000b060, 0x00000000},
|
||||
{0x0000b064, 0x00000000},
|
||||
{0x0000b068, 0x00000000},
|
||||
{0x0000b06c, 0x00000000},
|
||||
{0x0000b070, 0x00000000},
|
||||
{0x0000b074, 0x00000000},
|
||||
{0x0000b078, 0x00000000},
|
||||
{0x0000b07c, 0x00000000},
|
||||
{0x0000b080, 0x2a2d2f32},
|
||||
{0x0000b084, 0x21232328},
|
||||
{0x0000b088, 0x19191c1e},
|
||||
{0x0000b08c, 0x12141417},
|
||||
{0x0000b090, 0x07070e0e},
|
||||
{0x0000b094, 0x03030305},
|
||||
{0x0000b098, 0x00000003},
|
||||
{0x0000b09c, 0x00000000},
|
||||
{0x0000b0a0, 0x00000000},
|
||||
{0x0000b0a4, 0x00000000},
|
||||
{0x0000b0a8, 0x00000000},
|
||||
{0x0000b0ac, 0x00000000},
|
||||
{0x0000b0b0, 0x00000000},
|
||||
{0x0000b0b4, 0x00000000},
|
||||
{0x0000b0b8, 0x00000000},
|
||||
{0x0000b0bc, 0x00000000},
|
||||
{0x0000b0c0, 0x003f0020},
|
||||
{0x0000b0c4, 0x00400041},
|
||||
{0x0000b0c8, 0x0140005f},
|
||||
{0x0000b0cc, 0x0160015f},
|
||||
{0x0000b0d0, 0x017e017f},
|
||||
{0x0000b0d4, 0x02410242},
|
||||
{0x0000b0d8, 0x025f0240},
|
||||
{0x0000b0dc, 0x027f0260},
|
||||
{0x0000b0e0, 0x0341027e},
|
||||
{0x0000b0e4, 0x035f0340},
|
||||
{0x0000b0e8, 0x037f0360},
|
||||
{0x0000b0ec, 0x04400441},
|
||||
{0x0000b0f0, 0x0460045f},
|
||||
{0x0000b0f4, 0x0541047f},
|
||||
{0x0000b0f8, 0x055f0540},
|
||||
{0x0000b0fc, 0x057f0560},
|
||||
{0x0000b100, 0x06400641},
|
||||
{0x0000b104, 0x0660065f},
|
||||
{0x0000b108, 0x067e067f},
|
||||
{0x0000b10c, 0x07410742},
|
||||
{0x0000b110, 0x075f0740},
|
||||
{0x0000b114, 0x077f0760},
|
||||
{0x0000b118, 0x07800781},
|
||||
{0x0000b11c, 0x07a0079f},
|
||||
{0x0000b120, 0x07c107bf},
|
||||
{0x0000b124, 0x000007c0},
|
||||
{0x0000b128, 0x00000000},
|
||||
{0x0000b12c, 0x00000000},
|
||||
{0x0000b130, 0x00000000},
|
||||
{0x0000b134, 0x00000000},
|
||||
{0x0000b138, 0x00000000},
|
||||
{0x0000b13c, 0x00000000},
|
||||
{0x0000b140, 0x003f0020},
|
||||
{0x0000b144, 0x00400041},
|
||||
{0x0000b148, 0x0140005f},
|
||||
{0x0000b14c, 0x0160015f},
|
||||
{0x0000b150, 0x017e017f},
|
||||
{0x0000b154, 0x02410242},
|
||||
{0x0000b158, 0x025f0240},
|
||||
{0x0000b15c, 0x027f0260},
|
||||
{0x0000b160, 0x0341027e},
|
||||
{0x0000b164, 0x035f0340},
|
||||
{0x0000b168, 0x037f0360},
|
||||
{0x0000b16c, 0x04400441},
|
||||
{0x0000b170, 0x0460045f},
|
||||
{0x0000b174, 0x0541047f},
|
||||
{0x0000b178, 0x055f0540},
|
||||
{0x0000b17c, 0x057f0560},
|
||||
{0x0000b180, 0x06400641},
|
||||
{0x0000b184, 0x0660065f},
|
||||
{0x0000b188, 0x067e067f},
|
||||
{0x0000b18c, 0x07410742},
|
||||
{0x0000b190, 0x075f0740},
|
||||
{0x0000b194, 0x077f0760},
|
||||
{0x0000b198, 0x07800781},
|
||||
{0x0000b19c, 0x07a0079f},
|
||||
{0x0000b1a0, 0x07c107bf},
|
||||
{0x0000b1a4, 0x000007c0},
|
||||
{0x0000b1a8, 0x00000000},
|
||||
{0x0000b1ac, 0x00000000},
|
||||
{0x0000b1b0, 0x00000000},
|
||||
{0x0000b1b4, 0x00000000},
|
||||
{0x0000b1b8, 0x00000000},
|
||||
{0x0000b1bc, 0x00000000},
|
||||
{0x0000b1c0, 0x00000000},
|
||||
{0x0000b1c4, 0x00000000},
|
||||
{0x0000b1c8, 0x00000000},
|
||||
{0x0000b1cc, 0x00000000},
|
||||
{0x0000b1d0, 0x00000000},
|
||||
{0x0000b1d4, 0x00000000},
|
||||
{0x0000b1d8, 0x00000000},
|
||||
{0x0000b1dc, 0x00000000},
|
||||
{0x0000b1e0, 0x00000000},
|
||||
{0x0000b1e4, 0x00000000},
|
||||
{0x0000b1e8, 0x00000000},
|
||||
{0x0000b1ec, 0x00000000},
|
||||
{0x0000b1f0, 0x00000396},
|
||||
{0x0000b1f4, 0x00000396},
|
||||
{0x0000b1f8, 0x00000396},
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0
|
||||
|
||||
static const u32 ar9580_1p0_radio_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
|
@ -722,6 +722,7 @@ extern int ath9k_modparam_nohwcrypt;
|
||||
extern int led_blink;
|
||||
extern bool is_ath9k_unloaded;
|
||||
|
||||
u8 ath9k_parse_mpdudensity(u8 mpdudensity);
|
||||
irqreturn_t ath_isr(int irq, void *dev);
|
||||
int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||
const struct ath_bus_ops *bus_ops);
|
||||
|
@ -348,8 +348,6 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
|
||||
sc->debug.stats.istats.txok++;
|
||||
if (status & ATH9K_INT_TXURN)
|
||||
sc->debug.stats.istats.txurn++;
|
||||
if (status & ATH9K_INT_MIB)
|
||||
sc->debug.stats.istats.mib++;
|
||||
if (status & ATH9K_INT_RXPHY)
|
||||
sc->debug.stats.istats.rxphyerr++;
|
||||
if (status & ATH9K_INT_RXKCM)
|
||||
|
@ -416,7 +416,7 @@ int ath9k_init_btcoex(struct ath_softc *sc)
|
||||
txq = sc->tx.txq_map[WME_AC_BE];
|
||||
ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
|
||||
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (ath9k_hw_mci_is_enabled(ah)) {
|
||||
sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
|
||||
INIT_LIST_HEAD(&sc->btcoex.mci.info);
|
||||
|
||||
|
@ -453,7 +453,6 @@ struct ath9k_htc_priv {
|
||||
u8 num_sta_assoc_vif;
|
||||
u8 num_ap_vif;
|
||||
|
||||
u16 op_flags;
|
||||
u16 curtxpow;
|
||||
u16 txpowlimit;
|
||||
u16 nvifs;
|
||||
@ -461,6 +460,7 @@ struct ath9k_htc_priv {
|
||||
bool rearm_ani;
|
||||
bool reconfig_beacon;
|
||||
unsigned int rxfilter;
|
||||
unsigned long op_flags;
|
||||
|
||||
struct ath9k_hw_cal_data caldata;
|
||||
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
|
||||
@ -572,8 +572,6 @@ bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
|
||||
|
||||
void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
|
||||
void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
|
||||
void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
|
||||
void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
void ath9k_init_leds(struct ath9k_htc_priv *priv);
|
||||
|
@ -207,9 +207,9 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
|
||||
else
|
||||
priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
|
||||
|
||||
if (priv->op_flags & OP_TSF_RESET) {
|
||||
if (test_bit(OP_TSF_RESET, &priv->op_flags)) {
|
||||
ath9k_hw_reset_tsf(priv->ah);
|
||||
priv->op_flags &= ~OP_TSF_RESET;
|
||||
clear_bit(OP_TSF_RESET, &priv->op_flags);
|
||||
} else {
|
||||
/*
|
||||
* Pull nexttbtt forward to reflect the current TSF.
|
||||
@ -221,7 +221,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
|
||||
} while (nexttbtt < tsftu);
|
||||
}
|
||||
|
||||
if (priv->op_flags & OP_ENABLE_BEACON)
|
||||
if (test_bit(OP_ENABLE_BEACON, &priv->op_flags))
|
||||
imask |= ATH9K_INT_SWBA;
|
||||
|
||||
ath_dbg(common, CONFIG,
|
||||
@ -269,7 +269,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
|
||||
else
|
||||
priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
|
||||
|
||||
if (priv->op_flags & OP_ENABLE_BEACON)
|
||||
if (test_bit(OP_ENABLE_BEACON, &priv->op_flags))
|
||||
imask |= ATH9K_INT_SWBA;
|
||||
|
||||
ath_dbg(common, CONFIG,
|
||||
@ -365,7 +365,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
|
||||
vif = priv->cur_beacon_conf.bslot[slot];
|
||||
avp = (struct ath9k_htc_vif *)vif->drv_priv;
|
||||
|
||||
if (unlikely(priv->op_flags & OP_SCANNING)) {
|
||||
if (unlikely(test_bit(OP_SCANNING, &priv->op_flags))) {
|
||||
spin_unlock_bh(&priv->beacon_lock);
|
||||
return;
|
||||
}
|
||||
|
@ -37,17 +37,18 @@ static void ath_detect_bt_priority(struct ath9k_htc_priv *priv)
|
||||
|
||||
if (time_after(jiffies, btcoex->bt_priority_time +
|
||||
msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
|
||||
priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
|
||||
clear_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags);
|
||||
clear_bit(OP_BT_SCAN, &priv->op_flags);
|
||||
/* Detect if colocated bt started scanning */
|
||||
if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {
|
||||
ath_dbg(ath9k_hw_common(ah), BTCOEX,
|
||||
"BT scan detected\n");
|
||||
priv->op_flags |= (OP_BT_SCAN |
|
||||
OP_BT_PRIORITY_DETECTED);
|
||||
set_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags);
|
||||
set_bit(OP_BT_SCAN, &priv->op_flags);
|
||||
} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
|
||||
ath_dbg(ath9k_hw_common(ah), BTCOEX,
|
||||
"BT priority traffic detected\n");
|
||||
priv->op_flags |= OP_BT_PRIORITY_DETECTED;
|
||||
set_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags);
|
||||
}
|
||||
|
||||
btcoex->bt_priority_cnt = 0;
|
||||
@ -67,26 +68,23 @@ static void ath_btcoex_period_work(struct work_struct *work)
|
||||
struct ath_btcoex *btcoex = &priv->btcoex;
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
u32 timer_period;
|
||||
bool is_btscan;
|
||||
int ret;
|
||||
|
||||
ath_detect_bt_priority(priv);
|
||||
|
||||
is_btscan = !!(priv->op_flags & OP_BT_SCAN);
|
||||
|
||||
ret = ath9k_htc_update_cap_target(priv,
|
||||
!!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
|
||||
test_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags));
|
||||
if (ret) {
|
||||
ath_err(common, "Unable to set BTCOEX parameters\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
|
||||
btcoex->bt_stomp_type);
|
||||
ath9k_hw_btcoex_bt_stomp(priv->ah, test_bit(OP_BT_SCAN, &priv->op_flags) ?
|
||||
ATH_BTCOEX_STOMP_ALL : btcoex->bt_stomp_type);
|
||||
|
||||
ath9k_hw_btcoex_enable(priv->ah);
|
||||
timer_period = is_btscan ? btcoex->btscan_no_stomp :
|
||||
btcoex->btcoex_no_stomp;
|
||||
timer_period = test_bit(OP_BT_SCAN, &priv->op_flags) ?
|
||||
btcoex->btscan_no_stomp : btcoex->btcoex_no_stomp;
|
||||
ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work,
|
||||
msecs_to_jiffies(timer_period));
|
||||
ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work,
|
||||
@ -104,14 +102,15 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
|
||||
struct ath_hw *ah = priv->ah;
|
||||
struct ath_btcoex *btcoex = &priv->btcoex;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
bool is_btscan = priv->op_flags & OP_BT_SCAN;
|
||||
|
||||
ath_dbg(common, BTCOEX, "time slice work for bt and wlan\n");
|
||||
|
||||
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
|
||||
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW ||
|
||||
test_bit(OP_BT_SCAN, &priv->op_flags))
|
||||
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
|
||||
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
|
||||
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
|
||||
|
||||
ath9k_hw_btcoex_enable(priv->ah);
|
||||
}
|
||||
|
||||
@ -141,7 +140,8 @@ static void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv)
|
||||
|
||||
btcoex->bt_priority_cnt = 0;
|
||||
btcoex->bt_priority_time = jiffies;
|
||||
priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN);
|
||||
clear_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags);
|
||||
clear_bit(OP_BT_SCAN, &priv->op_flags);
|
||||
ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0);
|
||||
}
|
||||
|
||||
@ -310,95 +310,3 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
|
||||
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
|
||||
wiphy_rfkill_start_polling(priv->hw->wiphy);
|
||||
}
|
||||
|
||||
void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath_hw *ah = priv->ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int ret;
|
||||
u8 cmd_rsp;
|
||||
|
||||
if (!ah->curchan)
|
||||
ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
|
||||
|
||||
/* Reset the HW */
|
||||
ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
|
||||
if (ret) {
|
||||
ath_err(common,
|
||||
"Unable to reset hardware; reset status %d (freq %u MHz)\n",
|
||||
ret, ah->curchan->channel);
|
||||
}
|
||||
|
||||
ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
|
||||
&priv->curtxpow);
|
||||
|
||||
/* Start RX */
|
||||
WMI_CMD(WMI_START_RECV_CMDID);
|
||||
ath9k_host_rx_init(priv);
|
||||
|
||||
/* Start TX */
|
||||
htc_start(priv->htc);
|
||||
spin_lock_bh(&priv->tx.tx_lock);
|
||||
priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
|
||||
spin_unlock_bh(&priv->tx.tx_lock);
|
||||
ieee80211_wake_queues(hw);
|
||||
|
||||
WMI_CMD(WMI_ENABLE_INTR_CMDID);
|
||||
|
||||
/* Enable LED */
|
||||
ath9k_hw_cfg_output(ah, ah->led_pin,
|
||||
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
ath9k_hw_set_gpio(ah, ah->led_pin, 0);
|
||||
}
|
||||
|
||||
void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath_hw *ah = priv->ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int ret;
|
||||
u8 cmd_rsp;
|
||||
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
|
||||
/* Disable LED */
|
||||
ath9k_hw_set_gpio(ah, ah->led_pin, 1);
|
||||
ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
|
||||
|
||||
WMI_CMD(WMI_DISABLE_INTR_CMDID);
|
||||
|
||||
/* Stop TX */
|
||||
ieee80211_stop_queues(hw);
|
||||
ath9k_htc_tx_drain(priv);
|
||||
WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
|
||||
|
||||
/* Stop RX */
|
||||
WMI_CMD(WMI_STOP_RECV_CMDID);
|
||||
|
||||
/* Clear the WMI event queue */
|
||||
ath9k_wmi_event_drain(priv);
|
||||
|
||||
/*
|
||||
* The MIB counters have to be disabled here,
|
||||
* since the target doesn't do it.
|
||||
*/
|
||||
ath9k_hw_disable_mib_counters(ah);
|
||||
|
||||
if (!ah->curchan)
|
||||
ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
|
||||
|
||||
/* Reset the HW */
|
||||
ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
|
||||
if (ret) {
|
||||
ath_err(common,
|
||||
"Unable to reset hardware; reset status %d (freq %u MHz)\n",
|
||||
ret, ah->curchan->channel);
|
||||
}
|
||||
|
||||
/* Disable the PHY */
|
||||
ath9k_hw_phy_disable(ah);
|
||||
|
||||
ath9k_htc_ps_restore(priv);
|
||||
ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
|
||||
}
|
||||
|
@ -611,7 +611,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
|
||||
struct ath_common *common;
|
||||
int i, ret = 0, csz = 0;
|
||||
|
||||
priv->op_flags |= OP_INVALID;
|
||||
set_bit(OP_INVALID, &priv->op_flags);
|
||||
|
||||
ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
|
||||
if (!ah)
|
||||
@ -718,7 +718,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
|
||||
|
||||
hw->queues = 4;
|
||||
hw->channel_change_time = 5000;
|
||||
hw->max_listen_interval = 10;
|
||||
hw->max_listen_interval = 1;
|
||||
|
||||
hw->vif_data_size = sizeof(struct ath9k_htc_vif);
|
||||
hw->sta_data_size = sizeof(struct ath9k_htc_sta);
|
||||
|
@ -75,14 +75,19 @@ unlock:
|
||||
|
||||
void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
bool reset;
|
||||
|
||||
mutex_lock(&priv->htc_pm_lock);
|
||||
if (--priv->ps_usecount != 0)
|
||||
goto unlock;
|
||||
|
||||
if (priv->ps_idle)
|
||||
if (priv->ps_idle) {
|
||||
ath9k_hw_setrxabort(priv->ah, true);
|
||||
ath9k_hw_stopdmarecv(priv->ah, &reset);
|
||||
ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
|
||||
else if (priv->ps_enabled)
|
||||
} else if (priv->ps_enabled) {
|
||||
ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&priv->htc_pm_lock);
|
||||
@ -250,7 +255,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
|
||||
u8 cmd_rsp;
|
||||
int ret;
|
||||
|
||||
if (priv->op_flags & OP_INVALID)
|
||||
if (test_bit(OP_INVALID, &priv->op_flags))
|
||||
return -EIO;
|
||||
|
||||
fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
|
||||
@ -304,7 +309,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
|
||||
|
||||
htc_start(priv->htc);
|
||||
|
||||
if (!(priv->op_flags & OP_SCANNING) &&
|
||||
if (!test_bit(OP_SCANNING, &priv->op_flags) &&
|
||||
!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
|
||||
ath9k_htc_vif_reconfig(priv);
|
||||
|
||||
@ -750,7 +755,7 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
|
||||
common->ani.shortcal_timer = timestamp;
|
||||
common->ani.checkani_timer = timestamp;
|
||||
|
||||
priv->op_flags |= OP_ANI_RUNNING;
|
||||
set_bit(OP_ANI_RUNNING, &priv->op_flags);
|
||||
|
||||
ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
|
||||
msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
|
||||
@ -759,7 +764,7 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
|
||||
void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
cancel_delayed_work_sync(&priv->ani_work);
|
||||
priv->op_flags &= ~OP_ANI_RUNNING;
|
||||
clear_bit(OP_ANI_RUNNING, &priv->op_flags);
|
||||
}
|
||||
|
||||
void ath9k_htc_ani_work(struct work_struct *work)
|
||||
@ -944,7 +949,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
|
||||
ath_dbg(common, CONFIG,
|
||||
"Failed to update capability in target\n");
|
||||
|
||||
priv->op_flags &= ~OP_INVALID;
|
||||
clear_bit(OP_INVALID, &priv->op_flags);
|
||||
htc_start(priv->htc);
|
||||
|
||||
spin_lock_bh(&priv->tx.tx_lock);
|
||||
@ -973,7 +978,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (priv->op_flags & OP_INVALID) {
|
||||
if (test_bit(OP_INVALID, &priv->op_flags)) {
|
||||
ath_dbg(common, ANY, "Device not present\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
@ -1015,7 +1020,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
||||
ath9k_htc_ps_restore(priv);
|
||||
ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
|
||||
|
||||
priv->op_flags |= OP_INVALID;
|
||||
set_bit(OP_INVALID, &priv->op_flags);
|
||||
|
||||
ath_dbg(common, CONFIG, "Driver halt\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
@ -1105,7 +1110,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
|
||||
ath9k_htc_set_opmode(priv);
|
||||
|
||||
if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
|
||||
!(priv->op_flags & OP_ANI_RUNNING)) {
|
||||
!test_bit(OP_ANI_RUNNING, &priv->op_flags)) {
|
||||
ath9k_hw_set_tsfadjust(priv->ah, 1);
|
||||
ath9k_htc_start_ani(priv);
|
||||
}
|
||||
@ -1178,24 +1183,20 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
bool chip_reset = false;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_IDLE) {
|
||||
bool enable_radio = false;
|
||||
bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
|
||||
|
||||
mutex_lock(&priv->htc_pm_lock);
|
||||
if (!idle && priv->ps_idle)
|
||||
enable_radio = true;
|
||||
priv->ps_idle = idle;
|
||||
mutex_unlock(&priv->htc_pm_lock);
|
||||
|
||||
if (enable_radio) {
|
||||
ath_dbg(common, CONFIG, "not-idle: enabling radio\n");
|
||||
ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
|
||||
ath9k_htc_radio_enable(hw);
|
||||
}
|
||||
priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
|
||||
if (priv->ps_idle)
|
||||
chip_reset = true;
|
||||
|
||||
mutex_unlock(&priv->htc_pm_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1210,7 +1211,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
|
||||
ath9k_htc_remove_monitor_interface(priv);
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
||||
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) {
|
||||
struct ieee80211_channel *curchan = hw->conf.channel;
|
||||
int pos = curchan->hw_value;
|
||||
|
||||
@ -1223,8 +1224,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
|
||||
|
||||
if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
|
||||
ath_err(common, "Unable to set channel\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1246,21 +1247,10 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
|
||||
priv->txpowlimit, &priv->curtxpow);
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_IDLE) {
|
||||
mutex_lock(&priv->htc_pm_lock);
|
||||
if (!priv->ps_idle) {
|
||||
mutex_unlock(&priv->htc_pm_lock);
|
||||
goto out;
|
||||
}
|
||||
mutex_unlock(&priv->htc_pm_lock);
|
||||
|
||||
ath_dbg(common, CONFIG, "idle: disabling radio\n");
|
||||
ath9k_htc_radio_disable(hw);
|
||||
}
|
||||
|
||||
out:
|
||||
ath9k_htc_ps_restore(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SUPPORTED_FILTERS \
|
||||
@ -1285,7 +1275,7 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
|
||||
changed_flags &= SUPPORTED_FILTERS;
|
||||
*total_flags &= SUPPORTED_FILTERS;
|
||||
|
||||
if (priv->op_flags & OP_INVALID) {
|
||||
if (test_bit(OP_INVALID, &priv->op_flags)) {
|
||||
ath_dbg(ath9k_hw_common(priv->ah), ANY,
|
||||
"Unable to configure filter on invalid state\n");
|
||||
mutex_unlock(&priv->mutex);
|
||||
@ -1516,7 +1506,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
|
||||
ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n",
|
||||
bss_conf->bssid);
|
||||
ath9k_htc_set_tsfadjust(priv, vif);
|
||||
priv->op_flags |= OP_ENABLE_BEACON;
|
||||
set_bit(OP_ENABLE_BEACON, &priv->op_flags);
|
||||
ath9k_htc_beacon_config(priv, vif);
|
||||
}
|
||||
|
||||
@ -1529,7 +1519,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
|
||||
ath_dbg(common, CONFIG,
|
||||
"Beacon disabled for BSS: %pM\n",
|
||||
bss_conf->bssid);
|
||||
priv->op_flags &= ~OP_ENABLE_BEACON;
|
||||
clear_bit(OP_ENABLE_BEACON, &priv->op_flags);
|
||||
ath9k_htc_beacon_config(priv, vif);
|
||||
}
|
||||
}
|
||||
@ -1542,7 +1532,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
|
||||
(priv->nvifs == 1) &&
|
||||
(priv->num_ap_vif == 1) &&
|
||||
(vif->type == NL80211_IFTYPE_AP)) {
|
||||
priv->op_flags |= OP_TSF_RESET;
|
||||
set_bit(OP_TSF_RESET, &priv->op_flags);
|
||||
}
|
||||
ath_dbg(common, CONFIG,
|
||||
"Beacon interval changed for BSS: %pM\n",
|
||||
@ -1654,7 +1644,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
spin_lock_bh(&priv->beacon_lock);
|
||||
priv->op_flags |= OP_SCANNING;
|
||||
set_bit(OP_SCANNING, &priv->op_flags);
|
||||
spin_unlock_bh(&priv->beacon_lock);
|
||||
cancel_work_sync(&priv->ps_work);
|
||||
ath9k_htc_stop_ani(priv);
|
||||
@ -1667,7 +1657,7 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
spin_lock_bh(&priv->beacon_lock);
|
||||
priv->op_flags &= ~OP_SCANNING;
|
||||
clear_bit(OP_SCANNING, &priv->op_flags);
|
||||
spin_unlock_bh(&priv->beacon_lock);
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
ath9k_htc_vif_reconfig(priv);
|
||||
|
@ -916,7 +916,7 @@ void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
ath9k_hw_rxena(priv->ah);
|
||||
ath9k_htc_opmode_init(priv);
|
||||
ath9k_hw_startpcureceive(priv->ah, (priv->op_flags & OP_SCANNING));
|
||||
ath9k_hw_startpcureceive(priv->ah, test_bit(OP_SCANNING, &priv->op_flags));
|
||||
priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;
|
||||
}
|
||||
|
||||
|
@ -1019,16 +1019,8 @@ void ar9002_hw_attach_ops(struct ath_hw *ah);
|
||||
void ar9003_hw_attach_ops(struct ath_hw *ah);
|
||||
|
||||
void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
/*
|
||||
* ANI work can be shared between all families but a next
|
||||
* generation implementation of ANI will be used only for AR9003 only
|
||||
* for now as the other families still need to be tested with the same
|
||||
* next generation ANI. Feel free to start testing it though for the
|
||||
* older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
|
||||
*/
|
||||
extern int modparam_force_new_ani;
|
||||
|
||||
void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
|
||||
void ath9k_hw_proc_mib_event(struct ath_hw *ah);
|
||||
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
|
||||
@ -1038,7 +1030,8 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
|
||||
}
|
||||
static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah)
|
||||
{
|
||||
return ah->btcoex_hw.enabled && (ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
|
||||
return ah->common.btcoex_enabled &&
|
||||
(ah->caps.hw_caps & ATH9K_HW_CAP_MCI);
|
||||
|
||||
}
|
||||
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
|
||||
|
@ -407,6 +407,7 @@ void ath_ani_calibrate(unsigned long data)
|
||||
longcal ? "long" : "", shortcal ? "short" : "",
|
||||
aniflag ? "ani" : "", common->ani.caldone ? "true" : "false");
|
||||
|
||||
ath9k_debug_samp_bb_mac(sc);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
set_timer:
|
||||
@ -415,7 +416,6 @@ set_timer:
|
||||
* The interval must be the shortest necessary to satisfy ANI,
|
||||
* short calibration and long calibration.
|
||||
*/
|
||||
ath9k_debug_samp_bb_mac(sc);
|
||||
cal_interval = ATH_LONG_CALINTERVAL;
|
||||
if (sc->sc_ah->config.enable_ani)
|
||||
cal_interval = min(cal_interval,
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "ath9k.h"
|
||||
#include "btcoex.h"
|
||||
|
||||
static u8 parse_mpdudensity(u8 mpdudensity)
|
||||
u8 ath9k_parse_mpdudensity(u8 mpdudensity)
|
||||
{
|
||||
/*
|
||||
* 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
|
||||
@ -150,8 +150,10 @@ static void __ath_cancel_work(struct ath_softc *sc)
|
||||
cancel_work_sync(&sc->hw_check_work);
|
||||
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
cancel_delayed_work_sync(&sc->hw_pll_work);
|
||||
|
||||
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
|
||||
cancel_work_sync(&sc->mci_work);
|
||||
if (ath9k_hw_mci_is_enabled(sc->sc_ah))
|
||||
cancel_work_sync(&sc->mci_work);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -320,6 +322,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath_node *an;
|
||||
u8 density;
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
|
||||
#ifdef CONFIG_ATH9K_DEBUGFS
|
||||
@ -334,7 +337,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
ath_tx_node_init(sc, an);
|
||||
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
sta->ht_cap.ampdu_factor);
|
||||
an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
|
||||
density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
|
||||
an->mpdudensity = density;
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,24 +520,6 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
}
|
||||
|
||||
if (status & ATH9K_INT_MIB) {
|
||||
/*
|
||||
* Disable interrupts until we service the MIB
|
||||
* interrupt; otherwise it will continue to
|
||||
* fire.
|
||||
*/
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
/*
|
||||
* Let the hal handle the event. We assume
|
||||
* it will clear whatever condition caused
|
||||
* the interrupt.
|
||||
*/
|
||||
spin_lock(&common->cc_lock);
|
||||
ath9k_hw_proc_mib_event(ah);
|
||||
spin_unlock(&common->cc_lock);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
|
||||
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
||||
if (status & ATH9K_INT_TIM_TIMER) {
|
||||
if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle))
|
||||
@ -959,14 +945,10 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
|
||||
/*
|
||||
* Enable MIB interrupts when there are hardware phy counters.
|
||||
*/
|
||||
if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) {
|
||||
if (ah->config.enable_ani)
|
||||
ah->imask |= ATH9K_INT_MIB;
|
||||
if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
|
||||
ah->imask |= ATH9K_INT_TSFOOR;
|
||||
} else {
|
||||
ah->imask &= ~ATH9K_INT_MIB;
|
||||
else
|
||||
ah->imask &= ~ATH9K_INT_TSFOOR;
|
||||
}
|
||||
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
|
||||
|
@ -233,8 +233,21 @@ static void ath_mci_process_profile(struct ath_softc *sc,
|
||||
struct ath_mci_profile_info *entry = NULL;
|
||||
|
||||
entry = ath_mci_find_profile(mci, info);
|
||||
if (entry)
|
||||
if (entry) {
|
||||
/*
|
||||
* Two MCI interrupts are generated while connecting to
|
||||
* headset and A2DP profile, but only one MCI interrupt
|
||||
* is generated with last added profile type while disconnecting
|
||||
* both profiles.
|
||||
* So while adding second profile type decrement
|
||||
* the first one.
|
||||
*/
|
||||
if (entry->type != info->type) {
|
||||
DEC_PROF(mci, entry);
|
||||
INC_PROF(mci, info);
|
||||
}
|
||||
memcpy(entry, info, 10);
|
||||
}
|
||||
|
||||
if (info->start) {
|
||||
if (!entry && !ath_mci_add_profile(common, mci, info))
|
||||
@ -335,7 +348,7 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
|
||||
|
||||
seq_num = *((u32 *)(rx_payload + 12));
|
||||
ath_dbg(common, MCI,
|
||||
"BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n",
|
||||
"BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%u\n",
|
||||
profile_status.is_link, profile_status.conn_handle,
|
||||
profile_status.is_critical, seq_num);
|
||||
|
||||
|
@ -2162,10 +2162,6 @@ enum {
|
||||
#define AR_BTCOEX_CTRL_SPDT_POLARITY 0x80000000
|
||||
#define AR_BTCOEX_CTRL_SPDT_POLARITY_S 31
|
||||
|
||||
#define AR_BTCOEX_WL_WEIGHTS0 0x18b0
|
||||
#define AR_BTCOEX_WL_WEIGHTS1 0x18b4
|
||||
#define AR_BTCOEX_WL_WEIGHTS2 0x18b8
|
||||
#define AR_BTCOEX_WL_WEIGHTS3 0x18bc
|
||||
#define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2))
|
||||
#define AR_BTCOEX_WL_LNA 0x1940
|
||||
#define AR_BTCOEX_RFGAIN_CTRL 0x1944
|
||||
|
@ -1165,6 +1165,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
{
|
||||
struct ath_atx_tid *txtid;
|
||||
struct ath_node *an;
|
||||
u8 density;
|
||||
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
txtid = ATH_AN_2_TID(an, tid);
|
||||
@ -1172,6 +1173,17 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE))
|
||||
return -EAGAIN;
|
||||
|
||||
/* update ampdu factor/density, they may have changed. This may happen
|
||||
* in HT IBSS when a beacon with HT-info is received after the station
|
||||
* has already been added.
|
||||
*/
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
|
||||
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
sta->ht_cap.ampdu_factor);
|
||||
density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density);
|
||||
an->mpdudensity = density;
|
||||
}
|
||||
|
||||
txtid->state |= AGGR_ADDBA_PROGRESS;
|
||||
txtid->paused = true;
|
||||
*ssn = txtid->seq_start = txtid->seq_next;
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
|
||||
|
||||
#define SDIO_FUNC1_BLOCKSIZE 64
|
||||
#define SDIO_FUNC2_BLOCKSIZE 512
|
||||
@ -52,6 +53,7 @@
|
||||
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||
|
@ -36,6 +36,13 @@ struct dngl_stats {
|
||||
unsigned long multicast; /* multicast packets received */
|
||||
};
|
||||
|
||||
struct brcmf_bus_dcmd {
|
||||
char *name;
|
||||
char *param;
|
||||
int param_len;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* interface structure between common and bus layer */
|
||||
struct brcmf_bus {
|
||||
u8 type; /* bus type */
|
||||
@ -50,6 +57,7 @@ struct brcmf_bus {
|
||||
unsigned long tx_realloc; /* Tx packets realloced for headroom */
|
||||
struct dngl_stats dstats; /* Stats for dongle-based data */
|
||||
u8 align; /* bus alignment requirement */
|
||||
struct list_head dcmd_list;
|
||||
|
||||
/* interface functions pointers */
|
||||
/* Stop bus module: clear pending frames, disable data flow */
|
||||
|
@ -800,13 +800,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
|
||||
char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for
|
||||
"event_msgs" + '\0' + bitvec */
|
||||
char buf[128], *ptr;
|
||||
u32 dongle_align = drvr->bus_if->align;
|
||||
u32 glom = 0;
|
||||
u32 roaming = 1;
|
||||
uint bcn_timeout = 3;
|
||||
int scan_assoc_time = 40;
|
||||
int scan_unassoc_time = 40;
|
||||
int i;
|
||||
struct brcmf_bus_dcmd *cmdlst;
|
||||
struct list_head *cur, *q;
|
||||
|
||||
mutex_lock(&drvr->proto_block);
|
||||
|
||||
@ -827,17 +827,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
|
||||
/* Print fw version info */
|
||||
brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
|
||||
|
||||
/* Match Host and Dongle rx alignment */
|
||||
brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
|
||||
/* disable glom option per default */
|
||||
brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
|
||||
/* Setup timeout if Beacons are lost and roam is off to report
|
||||
link down */
|
||||
brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
|
||||
@ -874,6 +863,20 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
|
||||
0, true);
|
||||
}
|
||||
|
||||
/* set bus specific command if there is any */
|
||||
list_for_each_safe(cur, q, &drvr->bus_if->dcmd_list) {
|
||||
cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
|
||||
if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
|
||||
brcmf_c_mkiovar(cmdlst->name, cmdlst->param,
|
||||
cmdlst->param_len, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
|
||||
iovbuf, sizeof(iovbuf));
|
||||
}
|
||||
list_del(cur);
|
||||
kfree(cmdlst);
|
||||
}
|
||||
|
||||
mutex_unlock(&drvr->proto_block);
|
||||
|
||||
return 0;
|
||||
|
@ -1020,6 +1020,8 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
|
||||
INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address);
|
||||
INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list);
|
||||
|
||||
INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <defs.h>
|
||||
#include <brcmu_wifi.h>
|
||||
@ -48,6 +50,9 @@
|
||||
|
||||
#define CBUF_LEN (128)
|
||||
|
||||
/* Device console log buffer state */
|
||||
#define CONSOLE_BUFFER_MAX 2024
|
||||
|
||||
struct rte_log_le {
|
||||
__le32 buf; /* Can't be pointer on (64-bit) hosts */
|
||||
__le32 buf_size;
|
||||
@ -281,7 +286,7 @@ struct rte_console {
|
||||
* Shared structure between dongle and the host.
|
||||
* The structure contains pointers to trap or assert information.
|
||||
*/
|
||||
#define SDPCM_SHARED_VERSION 0x0002
|
||||
#define SDPCM_SHARED_VERSION 0x0003
|
||||
#define SDPCM_SHARED_VERSION_MASK 0x00FF
|
||||
#define SDPCM_SHARED_ASSERT_BUILT 0x0100
|
||||
#define SDPCM_SHARED_ASSERT 0x0200
|
||||
@ -428,6 +433,29 @@ struct brcmf_console {
|
||||
u8 *buf; /* Log buffer (host copy) */
|
||||
uint last; /* Last buffer read index */
|
||||
};
|
||||
|
||||
struct brcmf_trap_info {
|
||||
__le32 type;
|
||||
__le32 epc;
|
||||
__le32 cpsr;
|
||||
__le32 spsr;
|
||||
__le32 r0; /* a1 */
|
||||
__le32 r1; /* a2 */
|
||||
__le32 r2; /* a3 */
|
||||
__le32 r3; /* a4 */
|
||||
__le32 r4; /* v1 */
|
||||
__le32 r5; /* v2 */
|
||||
__le32 r6; /* v3 */
|
||||
__le32 r7; /* v4 */
|
||||
__le32 r8; /* v5 */
|
||||
__le32 r9; /* sb/v6 */
|
||||
__le32 r10; /* sl/v7 */
|
||||
__le32 r11; /* fp/v8 */
|
||||
__le32 r12; /* ip */
|
||||
__le32 r13; /* sp */
|
||||
__le32 r14; /* lr */
|
||||
__le32 pc; /* r15 */
|
||||
};
|
||||
#endif /* DEBUG */
|
||||
|
||||
struct sdpcm_shared {
|
||||
@ -439,6 +467,7 @@ struct sdpcm_shared {
|
||||
u32 console_addr; /* Address of struct rte_console */
|
||||
u32 msgtrace_addr;
|
||||
u8 tag[32];
|
||||
u32 brpt_addr;
|
||||
};
|
||||
|
||||
struct sdpcm_shared_le {
|
||||
@ -450,6 +479,7 @@ struct sdpcm_shared_le {
|
||||
__le32 console_addr; /* Address of struct rte_console */
|
||||
__le32 msgtrace_addr;
|
||||
u8 tag[32];
|
||||
__le32 brpt_addr;
|
||||
};
|
||||
|
||||
|
||||
@ -2953,13 +2983,311 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static inline bool brcmf_sdio_valid_shared_address(u32 addr)
|
||||
{
|
||||
return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
|
||||
}
|
||||
|
||||
static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh)
|
||||
{
|
||||
u32 addr;
|
||||
int rv;
|
||||
u32 shaddr = 0;
|
||||
struct sdpcm_shared_le sh_le;
|
||||
__le32 addr_le;
|
||||
|
||||
shaddr = bus->ramsize - 4;
|
||||
|
||||
/*
|
||||
* Read last word in socram to determine
|
||||
* address of sdpcm_shared structure
|
||||
*/
|
||||
rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
|
||||
(u8 *)&addr_le, 4);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
addr = le32_to_cpu(addr_le);
|
||||
|
||||
brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr);
|
||||
|
||||
/*
|
||||
* Check if addr is valid.
|
||||
* NVRAM length at the end of memory should have been overwritten.
|
||||
*/
|
||||
if (!brcmf_sdio_valid_shared_address(addr)) {
|
||||
brcmf_dbg(ERROR, "invalid sdpcm_shared address 0x%08X\n",
|
||||
addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Read hndrte_shared structure */
|
||||
rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
|
||||
sizeof(struct sdpcm_shared_le));
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
/* Endianness */
|
||||
sh->flags = le32_to_cpu(sh_le.flags);
|
||||
sh->trap_addr = le32_to_cpu(sh_le.trap_addr);
|
||||
sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr);
|
||||
sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr);
|
||||
sh->assert_line = le32_to_cpu(sh_le.assert_line);
|
||||
sh->console_addr = le32_to_cpu(sh_le.console_addr);
|
||||
sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr);
|
||||
|
||||
if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
|
||||
brcmf_dbg(ERROR,
|
||||
"sdpcm_shared version mismatch: dhd %d dongle %d\n",
|
||||
SDPCM_SHARED_VERSION,
|
||||
sh->flags & SDPCM_SHARED_VERSION_MASK);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh, char __user *data,
|
||||
size_t count)
|
||||
{
|
||||
u32 addr, console_ptr, console_size, console_index;
|
||||
char *conbuf = NULL;
|
||||
__le32 sh_val;
|
||||
int rv;
|
||||
loff_t pos = 0;
|
||||
int nbytes = 0;
|
||||
|
||||
/* obtain console information from device memory */
|
||||
addr = sh->console_addr + offsetof(struct rte_console, log_le);
|
||||
rv = brcmf_sdbrcm_membytes(bus, false, addr,
|
||||
(u8 *)&sh_val, sizeof(u32));
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
console_ptr = le32_to_cpu(sh_val);
|
||||
|
||||
addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size);
|
||||
rv = brcmf_sdbrcm_membytes(bus, false, addr,
|
||||
(u8 *)&sh_val, sizeof(u32));
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
console_size = le32_to_cpu(sh_val);
|
||||
|
||||
addr = sh->console_addr + offsetof(struct rte_console, log_le.idx);
|
||||
rv = brcmf_sdbrcm_membytes(bus, false, addr,
|
||||
(u8 *)&sh_val, sizeof(u32));
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
console_index = le32_to_cpu(sh_val);
|
||||
|
||||
/* allocate buffer for console data */
|
||||
if (console_size <= CONSOLE_BUFFER_MAX)
|
||||
conbuf = vzalloc(console_size+1);
|
||||
|
||||
if (!conbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* obtain the console data from device */
|
||||
conbuf[console_size] = '\0';
|
||||
rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf,
|
||||
console_size);
|
||||
if (rv < 0)
|
||||
goto done;
|
||||
|
||||
rv = simple_read_from_buffer(data, count, &pos,
|
||||
conbuf + console_index,
|
||||
console_size - console_index);
|
||||
if (rv < 0)
|
||||
goto done;
|
||||
|
||||
nbytes = rv;
|
||||
if (console_index > 0) {
|
||||
pos = 0;
|
||||
rv = simple_read_from_buffer(data+nbytes, count, &pos,
|
||||
conbuf, console_index - 1);
|
||||
if (rv < 0)
|
||||
goto done;
|
||||
rv += nbytes;
|
||||
}
|
||||
done:
|
||||
vfree(conbuf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
|
||||
char __user *data, size_t count)
|
||||
{
|
||||
int error, res;
|
||||
char buf[350];
|
||||
struct brcmf_trap_info tr;
|
||||
int nbytes;
|
||||
loff_t pos = 0;
|
||||
|
||||
if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
|
||||
return 0;
|
||||
|
||||
error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
|
||||
sizeof(struct brcmf_trap_info));
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
|
||||
if (nbytes < 0)
|
||||
return nbytes;
|
||||
|
||||
res = scnprintf(buf, sizeof(buf),
|
||||
"dongle trap info: type 0x%x @ epc 0x%08x\n"
|
||||
" cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
|
||||
" lr 0x%08x pc 0x%08x offset 0x%x\n"
|
||||
" r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
|
||||
" r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
|
||||
le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
|
||||
le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
|
||||
le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
|
||||
le32_to_cpu(tr.pc), sh->trap_addr,
|
||||
le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
|
||||
le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
|
||||
le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
|
||||
le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
|
||||
|
||||
error = simple_read_from_buffer(data+nbytes, count, &pos, buf, res);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
nbytes += error;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
|
||||
struct sdpcm_shared *sh, char __user *data,
|
||||
size_t count)
|
||||
{
|
||||
int error = 0;
|
||||
char buf[200];
|
||||
char file[80] = "?";
|
||||
char expr[80] = "<???>";
|
||||
int res;
|
||||
loff_t pos = 0;
|
||||
|
||||
if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) {
|
||||
brcmf_dbg(INFO, "firmware not built with -assert\n");
|
||||
return 0;
|
||||
} else if ((sh->flags & SDPCM_SHARED_ASSERT) == 0) {
|
||||
brcmf_dbg(INFO, "no assert in dongle\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sh->assert_file_addr != 0) {
|
||||
error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
|
||||
(u8 *)file, 80);
|
||||
if (error < 0)
|
||||
return error;
|
||||
}
|
||||
if (sh->assert_exp_addr != 0) {
|
||||
error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr,
|
||||
(u8 *)expr, 80);
|
||||
if (error < 0)
|
||||
return error;
|
||||
}
|
||||
|
||||
res = scnprintf(buf, sizeof(buf),
|
||||
"dongle assert: %s:%d: assert(%s)\n",
|
||||
file, sh->assert_line, expr);
|
||||
return simple_read_from_buffer(data, count, &pos, buf, res);
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
|
||||
{
|
||||
int error;
|
||||
struct sdpcm_shared sh;
|
||||
|
||||
down(&bus->sdsem);
|
||||
error = brcmf_sdio_readshared(bus, &sh);
|
||||
up(&bus->sdsem);
|
||||
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if ((sh.flags & SDPCM_SHARED_ASSERT_BUILT) == 0)
|
||||
brcmf_dbg(INFO, "firmware not built with -assert\n");
|
||||
else if (sh.flags & SDPCM_SHARED_ASSERT)
|
||||
brcmf_dbg(ERROR, "assertion in dongle\n");
|
||||
|
||||
if (sh.flags & SDPCM_SHARED_TRAP)
|
||||
brcmf_dbg(ERROR, "firmware trap in dongle\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
int error = 0;
|
||||
struct sdpcm_shared sh;
|
||||
int nbytes = 0;
|
||||
loff_t pos = *ppos;
|
||||
|
||||
if (pos != 0)
|
||||
return 0;
|
||||
|
||||
down(&bus->sdsem);
|
||||
error = brcmf_sdio_readshared(bus, &sh);
|
||||
if (error < 0)
|
||||
goto done;
|
||||
|
||||
error = brcmf_sdio_assert_info(bus, &sh, data, count);
|
||||
if (error < 0)
|
||||
goto done;
|
||||
|
||||
nbytes = error;
|
||||
error = brcmf_sdio_trap_info(bus, &sh, data, count);
|
||||
if (error < 0)
|
||||
goto done;
|
||||
|
||||
error += nbytes;
|
||||
*ppos += error;
|
||||
done:
|
||||
up(&bus->sdsem);
|
||||
return error;
|
||||
}
|
||||
|
||||
static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct brcmf_sdio *bus = f->private_data;
|
||||
int res;
|
||||
|
||||
res = brcmf_sdbrcm_died_dump(bus, data, count, ppos);
|
||||
if (res > 0)
|
||||
*ppos += res;
|
||||
return (ssize_t)res;
|
||||
}
|
||||
|
||||
static const struct file_operations brcmf_sdio_forensic_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = brcmf_sdio_forensic_read
|
||||
};
|
||||
|
||||
static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
|
||||
{
|
||||
struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr;
|
||||
struct dentry *dentry = brcmf_debugfs_get_devdir(drvr);
|
||||
|
||||
if (IS_ERR_OR_NULL(dentry))
|
||||
return;
|
||||
|
||||
debugfs_create_file("forensics", S_IRUGO, dentry, bus,
|
||||
&brcmf_sdio_forensic_ops);
|
||||
brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt);
|
||||
}
|
||||
#else
|
||||
static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus)
|
||||
{
|
||||
}
|
||||
@ -2991,11 +3319,13 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
|
||||
rxlen, msglen);
|
||||
} else if (timeleft == 0) {
|
||||
brcmf_dbg(ERROR, "resumed on timeout\n");
|
||||
brcmf_sdbrcm_checkdied(bus);
|
||||
} else if (pending) {
|
||||
brcmf_dbg(CTL, "cancelled\n");
|
||||
return -ERESTARTSYS;
|
||||
} else {
|
||||
brcmf_dbg(CTL, "resumed for unknown reason?\n");
|
||||
brcmf_sdbrcm_checkdied(bus);
|
||||
}
|
||||
|
||||
if (rxlen)
|
||||
@ -3006,45 +3336,10 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
|
||||
return rxlen ? (int)rxlen : -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len)
|
||||
{
|
||||
int bcmerror = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
/* Basic sanity checks */
|
||||
if (bus->sdiodev->bus_if->drvr_up) {
|
||||
bcmerror = -EISCONN;
|
||||
goto err;
|
||||
}
|
||||
if (!len) {
|
||||
bcmerror = -EOVERFLOW;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Free the old ones and replace with passed variables */
|
||||
kfree(bus->vars);
|
||||
|
||||
bus->vars = kmalloc(len, GFP_ATOMIC);
|
||||
bus->varsz = bus->vars ? len : 0;
|
||||
if (bus->vars == NULL) {
|
||||
bcmerror = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Copy the passed variables, which should include the
|
||||
terminating double-null */
|
||||
memcpy(bus->vars, arg, bus->varsz);
|
||||
err:
|
||||
return bcmerror;
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
|
||||
{
|
||||
int bcmerror = 0;
|
||||
u32 varsize;
|
||||
u32 varaddr;
|
||||
u8 *vbuffer;
|
||||
u32 varsizew;
|
||||
__le32 varsizew_le;
|
||||
#ifdef DEBUG
|
||||
@ -3053,56 +3348,44 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
|
||||
|
||||
/* Even if there are no vars are to be written, we still
|
||||
need to set the ramsize. */
|
||||
varsize = bus->varsz ? roundup(bus->varsz, 4) : 0;
|
||||
varaddr = (bus->ramsize - 4) - varsize;
|
||||
varaddr = (bus->ramsize - 4) - bus->varsz;
|
||||
|
||||
if (bus->vars) {
|
||||
vbuffer = kzalloc(varsize, GFP_ATOMIC);
|
||||
if (!vbuffer)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(vbuffer, bus->vars, bus->varsz);
|
||||
|
||||
/* Write the vars list */
|
||||
bcmerror =
|
||||
brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
|
||||
bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr,
|
||||
bus->vars, bus->varsz);
|
||||
#ifdef DEBUG
|
||||
/* Verify NVRAM bytes */
|
||||
brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
|
||||
nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
|
||||
if (!nvram_ularray) {
|
||||
kfree(vbuffer);
|
||||
brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n",
|
||||
bus->varsz);
|
||||
nvram_ularray = kmalloc(bus->varsz, GFP_ATOMIC);
|
||||
if (!nvram_ularray)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Upload image to verify downloaded contents. */
|
||||
memset(nvram_ularray, 0xaa, varsize);
|
||||
memset(nvram_ularray, 0xaa, bus->varsz);
|
||||
|
||||
/* Read the vars list to temp buffer for comparison */
|
||||
bcmerror =
|
||||
brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray,
|
||||
varsize);
|
||||
bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr,
|
||||
nvram_ularray, bus->varsz);
|
||||
if (bcmerror) {
|
||||
brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n",
|
||||
bcmerror, varsize, varaddr);
|
||||
bcmerror, bus->varsz, varaddr);
|
||||
}
|
||||
/* Compare the org NVRAM with the one read from RAM */
|
||||
if (memcmp(vbuffer, nvram_ularray, varsize))
|
||||
if (memcmp(bus->vars, nvram_ularray, bus->varsz))
|
||||
brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n");
|
||||
else
|
||||
brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
|
||||
|
||||
kfree(nvram_ularray);
|
||||
#endif /* DEBUG */
|
||||
|
||||
kfree(vbuffer);
|
||||
}
|
||||
|
||||
/* adjust to the user specified RAM */
|
||||
brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize);
|
||||
brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n",
|
||||
varaddr, varsize);
|
||||
varsize = ((bus->ramsize - 4) - varaddr);
|
||||
varaddr, bus->varsz);
|
||||
|
||||
/*
|
||||
* Determine the length token:
|
||||
@ -3113,13 +3396,13 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
|
||||
varsizew = 0;
|
||||
varsizew_le = cpu_to_le32(0);
|
||||
} else {
|
||||
varsizew = varsize / 4;
|
||||
varsizew = bus->varsz / 4;
|
||||
varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
|
||||
varsizew_le = cpu_to_le32(varsizew);
|
||||
}
|
||||
|
||||
brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n",
|
||||
varsize, varsizew);
|
||||
bus->varsz, varsizew);
|
||||
|
||||
/* Write the length token to the last word */
|
||||
bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4),
|
||||
@ -3243,13 +3526,21 @@ err:
|
||||
* by two NULs.
|
||||
*/
|
||||
|
||||
static uint brcmf_process_nvram_vars(char *varbuf, uint len)
|
||||
static int brcmf_process_nvram_vars(struct brcmf_sdio *bus)
|
||||
{
|
||||
char *varbuf;
|
||||
char *dp;
|
||||
bool findNewline;
|
||||
int column;
|
||||
uint buf_len, n;
|
||||
int ret = 0;
|
||||
uint buf_len, n, len;
|
||||
|
||||
len = bus->firmware->size;
|
||||
varbuf = vmalloc(len);
|
||||
if (!varbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(varbuf, bus->firmware->data, len);
|
||||
dp = varbuf;
|
||||
|
||||
findNewline = false;
|
||||
@ -3278,56 +3569,44 @@ static uint brcmf_process_nvram_vars(char *varbuf, uint len)
|
||||
column++;
|
||||
}
|
||||
buf_len = dp - varbuf;
|
||||
|
||||
while (dp < varbuf + n)
|
||||
*dp++ = 0;
|
||||
|
||||
return buf_len;
|
||||
kfree(bus->vars);
|
||||
/* roundup needed for download to device */
|
||||
bus->varsz = roundup(buf_len + 1, 4);
|
||||
bus->vars = kmalloc(bus->varsz, GFP_KERNEL);
|
||||
if (bus->vars == NULL) {
|
||||
bus->varsz = 0;
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* copy the processed variables and add null termination */
|
||||
memcpy(bus->vars, varbuf, buf_len);
|
||||
bus->vars[buf_len] = 0;
|
||||
err:
|
||||
vfree(varbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
|
||||
{
|
||||
uint len;
|
||||
char *memblock = NULL;
|
||||
char *bufp;
|
||||
int ret;
|
||||
|
||||
if (bus->sdiodev->bus_if->drvr_up)
|
||||
return -EISCONN;
|
||||
|
||||
ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME,
|
||||
&bus->sdiodev->func[2]->dev);
|
||||
if (ret) {
|
||||
brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
bus->fw_ptr = 0;
|
||||
|
||||
memblock = kmalloc(MEMBLOCK, GFP_ATOMIC);
|
||||
if (memblock == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus);
|
||||
|
||||
if (len > 0 && len < MEMBLOCK) {
|
||||
bufp = memblock;
|
||||
bufp[len] = 0;
|
||||
len = brcmf_process_nvram_vars(bufp, len);
|
||||
bufp += len;
|
||||
*bufp++ = 0;
|
||||
if (len)
|
||||
ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1);
|
||||
if (ret)
|
||||
brcmf_dbg(ERROR, "error downloading vars: %d\n", ret);
|
||||
} else {
|
||||
brcmf_dbg(ERROR, "error reading nvram file: %d\n", len);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
err:
|
||||
kfree(memblock);
|
||||
ret = brcmf_process_nvram_vars(bus);
|
||||
|
||||
release_firmware(bus->firmware);
|
||||
bus->fw_ptr = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -3606,6 +3885,8 @@ static bool brcmf_sdbrcm_chipmatch(u16 chipid)
|
||||
return true;
|
||||
if (chipid == BCM4330_CHIP_ID)
|
||||
return true;
|
||||
if (chipid == BCM4334_CHIP_ID)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3817,6 +4098,7 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
|
||||
static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (bus) {
|
||||
/* De-register interrupt handler */
|
||||
brcmf_sdio_intr_unregister(bus->sdiodev);
|
||||
@ -3838,6 +4120,10 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret;
|
||||
struct brcmf_sdio *bus;
|
||||
struct brcmf_bus_dcmd *dlst;
|
||||
u32 dngl_txglom;
|
||||
u32 dngl_txglomalign;
|
||||
u8 idx;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
@ -3923,6 +4209,26 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||
brcmf_sdio_debugfs_create(bus);
|
||||
brcmf_dbg(INFO, "completed!!\n");
|
||||
|
||||
/* sdio bus core specific dcmd */
|
||||
idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
|
||||
if (dlst) {
|
||||
if (bus->ci->c_inf[idx].rev < 12) {
|
||||
/* for sdio core rev < 12, disable txgloming */
|
||||
dngl_txglom = 0;
|
||||
dlst->name = "bus:txglom";
|
||||
dlst->param = (char *)&dngl_txglom;
|
||||
dlst->param_len = sizeof(u32);
|
||||
} else {
|
||||
/* otherwise, set txglomalign */
|
||||
dngl_txglomalign = bus->sdiodev->bus_if->align;
|
||||
dlst->name = "bus:txglomalign";
|
||||
dlst->param = (char *)&dngl_txglomalign;
|
||||
dlst->param_len = sizeof(u32);
|
||||
}
|
||||
list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
|
||||
}
|
||||
|
||||
/* if firmware path present try to download and bring up bus */
|
||||
ret = brcmf_bus_start(bus->sdiodev->dev);
|
||||
if (ret != 0) {
|
||||
|
@ -403,6 +403,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
|
||||
ci->c_inf[3].cib = 0x03004211;
|
||||
ci->ramsize = 0x48000;
|
||||
break;
|
||||
case BCM4334_CHIP_ID:
|
||||
ci->c_inf[0].wrapbase = 0x18100000;
|
||||
ci->c_inf[0].cib = 0x29004211;
|
||||
ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
|
||||
ci->c_inf[1].base = 0x18002000;
|
||||
ci->c_inf[1].wrapbase = 0x18102000;
|
||||
ci->c_inf[1].cib = 0x0d004211;
|
||||
ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
|
||||
ci->c_inf[2].base = 0x18004000;
|
||||
ci->c_inf[2].wrapbase = 0x18104000;
|
||||
ci->c_inf[2].cib = 0x13080401;
|
||||
ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
|
||||
ci->c_inf[3].base = 0x18003000;
|
||||
ci->c_inf[3].wrapbase = 0x18103000;
|
||||
ci->c_inf[3].cib = 0x07004211;
|
||||
ci->ramsize = 0x80000;
|
||||
break;
|
||||
default:
|
||||
brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
|
||||
return -ENODEV;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,9 +37,6 @@ brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
|
||||
|
||||
extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
|
||||
uint bandunit);
|
||||
|
||||
extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
|
||||
u16 chspec);
|
||||
|
||||
@ -49,5 +46,6 @@ extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
|
||||
extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
|
||||
u16 chanspec,
|
||||
u8 local_constraint_qdbm);
|
||||
extern void brcms_c_regd_init(struct brcms_c_info *wlc);
|
||||
|
||||
#endif /* _WLC_CHANNEL_H */
|
||||
|
@ -1050,6 +1050,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
brcms_c_regd_init(wl->wlc);
|
||||
|
||||
memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
|
||||
if (WARN_ON(!is_valid_ether_addr(perm)))
|
||||
goto fail;
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <aiutils.h>
|
||||
@ -3139,20 +3140,6 @@ void brcms_c_reset(struct brcms_c_info *wlc)
|
||||
brcms_b_reset(wlc->hw);
|
||||
}
|
||||
|
||||
/* Return the channel the driver should initialize during brcms_c_init.
|
||||
* the channel may have to be changed from the currently configured channel
|
||||
* if other configurations are in conflict (bandlocked, 11n mode disabled,
|
||||
* invalid channel for current country, etc.)
|
||||
*/
|
||||
static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc)
|
||||
{
|
||||
u16 chanspec =
|
||||
1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
|
||||
WL_CHANSPEC_BAND_2G;
|
||||
|
||||
return chanspec;
|
||||
}
|
||||
|
||||
void brcms_c_init_scb(struct scb *scb)
|
||||
{
|
||||
int i;
|
||||
@ -5129,6 +5116,8 @@ static void brcms_c_wme_retries_write(struct brcms_c_info *wlc)
|
||||
/* make interface operational */
|
||||
int brcms_c_up(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct ieee80211_channel *ch;
|
||||
|
||||
BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
|
||||
|
||||
/* HW is turned off so don't try to access it */
|
||||
@ -5195,8 +5184,9 @@ int brcms_c_up(struct brcms_c_info *wlc)
|
||||
wlc->pub->up = true;
|
||||
|
||||
if (wlc->bandinit_pending) {
|
||||
ch = wlc->pub->ieee_hw->conf.channel;
|
||||
brcms_c_suspend_mac_and_wait(wlc);
|
||||
brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec);
|
||||
brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value));
|
||||
wlc->bandinit_pending = false;
|
||||
brcms_c_enable_mac(wlc);
|
||||
}
|
||||
@ -5397,11 +5387,6 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
/* Legacy or bust when no OFDM is supported by regulatory */
|
||||
if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
|
||||
BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B))
|
||||
return -EINVAL;
|
||||
|
||||
/* update configuration value */
|
||||
if (config)
|
||||
brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
|
||||
@ -8201,19 +8186,12 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
|
||||
void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
|
||||
{
|
||||
struct bcma_device *core = wlc->hw->d11core;
|
||||
struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel;
|
||||
u16 chanspec;
|
||||
|
||||
BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
|
||||
|
||||
/*
|
||||
* This will happen if a big-hammer was executed. In
|
||||
* that case, we want to go back to the channel that
|
||||
* we were on and not new channel
|
||||
*/
|
||||
if (wlc->pub->associated)
|
||||
chanspec = wlc->home_chanspec;
|
||||
else
|
||||
chanspec = brcms_c_init_chanspec(wlc);
|
||||
chanspec = ch20mhz_chspec(ch->hw_value);
|
||||
|
||||
brcms_b_init(wlc->hw, chanspec);
|
||||
|
||||
|
@ -37,5 +37,6 @@
|
||||
#define BCM4329_CHIP_ID 0x4329
|
||||
#define BCM4330_CHIP_ID 0x4330
|
||||
#define BCM4331_CHIP_ID 0x4331
|
||||
#define BCM4334_CHIP_ID 0x4334
|
||||
|
||||
#endif /* _BRCM_HW_IDS_H_ */
|
||||
|
@ -4717,10 +4717,11 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
|
||||
struct il_tx_queue *txq = &il->txq[cnt];
|
||||
struct il_queue *q = &txq->q;
|
||||
unsigned long timeout;
|
||||
unsigned long now = jiffies;
|
||||
int ret;
|
||||
|
||||
if (q->read_ptr == q->write_ptr) {
|
||||
txq->time_stamp = jiffies;
|
||||
txq->time_stamp = now;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4728,9 +4729,9 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
|
||||
txq->time_stamp +
|
||||
msecs_to_jiffies(il->cfg->wd_timeout);
|
||||
|
||||
if (time_after(jiffies, timeout)) {
|
||||
if (time_after(now, timeout)) {
|
||||
IL_ERR("Queue %d stuck for %u ms.\n", q->id,
|
||||
il->cfg->wd_timeout);
|
||||
jiffies_to_msecs(now - txq->time_stamp));
|
||||
ret = il_force_reset(il, false);
|
||||
return (ret == -EAGAIN) ? 0 : 1;
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ void iwl_scan_offchannel_skb_status(struct iwl_priv *priv);
|
||||
#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
|
||||
#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
|
||||
|
||||
#define IWL_SCAN_CHECK_WATCHDOG (HZ * 7)
|
||||
#define IWL_SCAN_CHECK_WATCHDOG (HZ * 15)
|
||||
|
||||
|
||||
/* bt coex */
|
||||
|
@ -568,7 +568,6 @@ enum iwl_scan_type {
|
||||
*
|
||||
* @tx_chains_num: Number of TX chains
|
||||
* @rx_chains_num: Number of RX chains
|
||||
* @sku: sku read from EEPROM
|
||||
* @ct_kill_threshold: temperature threshold - in hw dependent unit
|
||||
* @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit
|
||||
* relevant for 1000, 6000 and up
|
||||
@ -579,7 +578,6 @@ struct iwl_hw_params {
|
||||
u8 tx_chains_num;
|
||||
u8 rx_chains_num;
|
||||
bool use_rts_for_aggregation;
|
||||
u16 sku;
|
||||
u32 ct_kill_threshold;
|
||||
u32 ct_kill_exit_threshold;
|
||||
|
||||
|
@ -250,17 +250,6 @@ struct iwl_lib_ops iwl2030_lib = {
|
||||
*/
|
||||
|
||||
/* NIC configuration for 5000 series */
|
||||
static void iwl5000_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
/* W/A : NIC is stuck in a reset state after Early PCIe power off
|
||||
* (PCIe power is lost before PERST# is asserted),
|
||||
* causing ME FW to lose ownership and not being able to obtain it back.
|
||||
*/
|
||||
iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
|
||||
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
|
||||
}
|
||||
|
||||
static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
|
||||
.min_nrg_cck = 100,
|
||||
.auto_corr_min_ofdm = 90,
|
||||
@ -433,14 +422,12 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
|
||||
struct iwl_lib_ops iwl5000_lib = {
|
||||
.set_hw_params = iwl5000_hw_set_hw_params,
|
||||
.set_channel_switch = iwl5000_hw_channel_switch,
|
||||
.nic_config = iwl5000_nic_config,
|
||||
.temperature = iwlagn_temperature,
|
||||
};
|
||||
|
||||
struct iwl_lib_ops iwl5150_lib = {
|
||||
.set_hw_params = iwl5150_hw_set_hw_params,
|
||||
.set_channel_switch = iwl5000_hw_channel_switch,
|
||||
.nic_config = iwl5000_nic_config,
|
||||
.temperature = iwl5150_temperature,
|
||||
};
|
||||
|
||||
|
@ -160,7 +160,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
|
||||
IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
|
||||
IWL_PAN_SCD_MULTICAST_MSK;
|
||||
|
||||
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||
if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||
flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
|
||||
|
@ -164,7 +164,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
||||
*/
|
||||
|
||||
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||
if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE)
|
||||
hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
|
||||
IEEE80211_HW_SUPPORTS_STATIC_SMPS;
|
||||
|
||||
@ -649,7 +649,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
|
||||
sta->addr, tid);
|
||||
|
||||
if (!(priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE))
|
||||
if (!(priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE))
|
||||
return -EACCES;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
@ -1048,8 +1048,18 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
/* mac80211 should not scan while ROC or ROC while scanning */
|
||||
if (WARN_ON_ONCE(priv->scan_type != IWL_SCAN_RADIO_RESET)) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iwl_scan_cancel_timeout(priv, 100);
|
||||
|
||||
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
priv->hw_roc_channel = channel;
|
||||
@ -1413,13 +1423,11 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum nl80211_iftype newtype, bool newp2p)
|
||||
struct ieee80211_vif *vif,
|
||||
enum nl80211_iftype newtype, bool newp2p)
|
||||
{
|
||||
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
||||
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
|
||||
struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
struct iwl_rxon_context *tmp;
|
||||
struct iwl_rxon_context *ctx, *tmp;
|
||||
enum nl80211_iftype newviftype = newtype;
|
||||
u32 interface_modes;
|
||||
int err;
|
||||
@ -1430,6 +1438,18 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
ctx = iwl_rxon_ctx_from_vif(vif);
|
||||
|
||||
/*
|
||||
* To simplify this code, only support changes on the
|
||||
* BSS context. The PAN context is usually reassigned
|
||||
* by creating/removing P2P interfaces anyway.
|
||||
*/
|
||||
if (ctx->ctxid != IWL_RXON_CTX_BSS) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ctx->vif || !iwl_is_ready_rf(priv)) {
|
||||
/*
|
||||
* Huh? But wait ... this can maybe happen when
|
||||
@ -1439,32 +1459,19 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check if the switch is supported in the same context */
|
||||
interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
|
||||
|
||||
if (!(interface_modes & BIT(newtype))) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refuse a change that should be done by moving from the PAN
|
||||
* context to the BSS context instead, if the BSS context is
|
||||
* available and can support the new interface type.
|
||||
*/
|
||||
if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
|
||||
(bss_ctx->interface_modes & BIT(newtype) ||
|
||||
bss_ctx->exclusive_interface_modes & BIT(newtype))) {
|
||||
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ctx->exclusive_interface_modes & BIT(newtype)) {
|
||||
for_each_context(priv, tmp) {
|
||||
if (ctx == tmp)
|
||||
continue;
|
||||
|
||||
if (!tmp->vif)
|
||||
if (!tmp->is_active)
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
@ -51,11 +51,13 @@
|
||||
#include "iwl-op-mode.h"
|
||||
#include "iwl-drv.h"
|
||||
#include "iwl-modparams.h"
|
||||
#include "iwl-prph.h"
|
||||
|
||||
#include "dev.h"
|
||||
#include "calib.h"
|
||||
#include "agn.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* module boiler plate
|
||||
@ -1185,9 +1187,6 @@ static void iwl_set_hw_params(struct iwl_priv *priv)
|
||||
priv->hw_params.use_rts_for_aggregation =
|
||||
priv->cfg->ht_params->use_rts_for_aggregation;
|
||||
|
||||
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
|
||||
priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
|
||||
|
||||
/* Device-specific setup */
|
||||
priv->lib->set_hw_params(priv);
|
||||
}
|
||||
@ -1232,20 +1231,20 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
u16 radio_cfg;
|
||||
|
||||
priv->hw_params.sku = priv->eeprom_data->sku;
|
||||
priv->eeprom_data->sku = priv->eeprom_data->sku;
|
||||
|
||||
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE &&
|
||||
if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE &&
|
||||
!priv->cfg->ht_params) {
|
||||
IWL_ERR(priv, "Invalid 11n configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!priv->hw_params.sku) {
|
||||
if (!priv->eeprom_data->sku) {
|
||||
IWL_ERR(priv, "Invalid device sku\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku);
|
||||
IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku);
|
||||
|
||||
radio_cfg = priv->eeprom_data->radio_cfg;
|
||||
|
||||
@ -1352,6 +1351,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
|
||||
trans_cfg.command_names = iwl_dvm_cmd_strings;
|
||||
|
||||
WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
|
||||
priv->cfg->base_params->num_of_queues);
|
||||
|
||||
ucode_flags = fw->ucode_capa.flags;
|
||||
|
||||
#ifndef CONFIG_IWLWIFI_P2P
|
||||
@ -1448,7 +1450,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
************************/
|
||||
iwl_set_hw_params(priv);
|
||||
|
||||
if (!(priv->hw_params.sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
|
||||
if (!(priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) {
|
||||
IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN");
|
||||
ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
|
||||
/*
|
||||
@ -2073,7 +2075,16 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)
|
||||
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
|
||||
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
|
||||
|
||||
priv->lib->nic_config(priv);
|
||||
/* W/A : NIC is stuck in a reset state after Early PCIe power off
|
||||
* (PCIe power is lost before PERST# is asserted),
|
||||
* causing ME FW to lose ownership and not being able to obtain it back.
|
||||
*/
|
||||
iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
|
||||
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
|
||||
|
||||
if (priv->lib->nic_config)
|
||||
priv->lib->nic_config(priv);
|
||||
}
|
||||
|
||||
static void iwl_wimax_active(struct iwl_op_mode *op_mode)
|
||||
|
@ -51,6 +51,9 @@
|
||||
#define IWL_CHANNEL_TUNE_TIME 5
|
||||
#define MAX_SCAN_CHANNEL 50
|
||||
|
||||
/* For reset radio, need minimal dwell time only */
|
||||
#define IWL_RADIO_RESET_DWELL_TIME 5
|
||||
|
||||
static int iwl_send_scan_abort(struct iwl_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
@ -469,45 +472,39 @@ static u8 iwl_get_single_channel_number(struct iwl_priv *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_band band,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
static int iwl_get_channel_for_reset_scan(struct iwl_priv *priv,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_band band,
|
||||
struct iwl_scan_channel *scan_ch)
|
||||
{
|
||||
const struct ieee80211_supported_band *sband;
|
||||
u16 passive_dwell = 0;
|
||||
u16 active_dwell = 0;
|
||||
int added = 0;
|
||||
u16 channel = 0;
|
||||
u16 channel;
|
||||
|
||||
sband = iwl_get_hw_mode(priv, band);
|
||||
if (!sband) {
|
||||
IWL_ERR(priv, "invalid band\n");
|
||||
return added;
|
||||
return 0;
|
||||
}
|
||||
|
||||
active_dwell = iwl_get_active_dwell_time(priv, band, 0);
|
||||
passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
||||
|
||||
if (passive_dwell <= active_dwell)
|
||||
passive_dwell = active_dwell + 1;
|
||||
|
||||
channel = iwl_get_single_channel_number(priv, band);
|
||||
if (channel) {
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
scan_ch->active_dwell = cpu_to_le16(active_dwell);
|
||||
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
scan_ch->active_dwell =
|
||||
cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME);
|
||||
scan_ch->passive_dwell =
|
||||
cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME);
|
||||
/* Set txpower levels to defaults */
|
||||
scan_ch->dsp_atten = 110;
|
||||
if (band == IEEE80211_BAND_5GHZ)
|
||||
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
|
||||
else
|
||||
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
|
||||
added++;
|
||||
} else
|
||||
IWL_ERR(priv, "no valid channel found\n");
|
||||
return added;
|
||||
return 1;
|
||||
}
|
||||
|
||||
IWL_ERR(priv, "no valid channel found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
||||
@ -723,6 +720,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
switch (priv->scan_type) {
|
||||
case IWL_SCAN_RADIO_RESET:
|
||||
IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
|
||||
/*
|
||||
* Override quiet time as firmware checks that active
|
||||
* dwell is >= quiet; since we use passive scan it'll
|
||||
* not actually be used.
|
||||
*/
|
||||
scan->quiet_time = cpu_to_le16(IWL_RADIO_RESET_DWELL_TIME);
|
||||
break;
|
||||
case IWL_SCAN_NORMAL:
|
||||
if (priv->scan_request->n_ssids) {
|
||||
@ -896,7 +899,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
switch (priv->scan_type) {
|
||||
case IWL_SCAN_RADIO_RESET:
|
||||
scan->channel_count =
|
||||
iwl_get_single_channel_for_scan(priv, vif, band,
|
||||
iwl_get_channel_for_reset_scan(priv, vif, band,
|
||||
(void *)&scan->data[cmd_len]);
|
||||
break;
|
||||
case IWL_SCAN_NORMAL:
|
||||
|
@ -853,6 +853,9 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
EEPROM_RADIO_CONFIG);
|
||||
data->sku = iwl_eeprom_query16(eeprom, eeprom_size,
|
||||
EEPROM_SKU_CAP);
|
||||
if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
|
||||
data->sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
|
||||
|
||||
data->eeprom_version = iwl_eeprom_query16(eeprom, eeprom_size,
|
||||
EEPROM_VERSION);
|
||||
|
||||
|
@ -121,13 +121,12 @@ EXPORT_SYMBOL_GPL(iwl_notification_wait_notify);
|
||||
|
||||
void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct iwl_notification_wait *wait_entry;
|
||||
|
||||
spin_lock_irqsave(¬if_wait->notif_wait_lock, flags);
|
||||
spin_lock(¬if_wait->notif_wait_lock);
|
||||
list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list)
|
||||
wait_entry->aborted = true;
|
||||
spin_unlock_irqrestore(¬if_wait->notif_wait_lock, flags);
|
||||
spin_unlock(¬if_wait->notif_wait_lock);
|
||||
|
||||
wake_up_all(¬if_wait->notif_waitq);
|
||||
}
|
||||
|
@ -111,22 +111,25 @@ struct iwl_cfg;
|
||||
* May sleep
|
||||
* @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the
|
||||
* HCMD the this Rx responds to.
|
||||
* Must be atomic.
|
||||
* Must be atomic and called with BH disabled.
|
||||
* @queue_full: notifies that a HW queue is full.
|
||||
* Must be atomic
|
||||
* Must be atomic and called with BH disabled.
|
||||
* @queue_not_full: notifies that a HW queue is not full any more.
|
||||
* Must be atomic
|
||||
* Must be atomic and called with BH disabled.
|
||||
* @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that
|
||||
* the radio is killed. Must be atomic.
|
||||
* @free_skb: allows the transport layer to free skbs that haven't been
|
||||
* reclaimed by the op_mode. This can happen when the driver is freed and
|
||||
* there are Tx packets pending in the transport layer.
|
||||
* Must be atomic
|
||||
* @nic_error: error notification. Must be atomic
|
||||
* @cmd_queue_full: Called when the command queue gets full. Must be atomic.
|
||||
* @nic_error: error notification. Must be atomic and must be called with BH
|
||||
* disabled.
|
||||
* @cmd_queue_full: Called when the command queue gets full. Must be atomic and
|
||||
* called with BH disabled.
|
||||
* @nic_config: configure NIC, called before firmware is started.
|
||||
* May sleep
|
||||
* @wimax_active: invoked when WiMax becomes active. Must be atomic.
|
||||
* @wimax_active: invoked when WiMax becomes active. Must be atomic and called
|
||||
* with BH disabled.
|
||||
*/
|
||||
struct iwl_op_mode_ops {
|
||||
struct iwl_op_mode *(*start)(struct iwl_trans *trans,
|
||||
@ -165,7 +168,6 @@ struct iwl_op_mode {
|
||||
static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
op_mode->ops->stop(op_mode);
|
||||
}
|
||||
|
||||
|
@ -867,24 +867,23 @@ void iwl_disable_ict(struct iwl_trans *trans)
|
||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||
}
|
||||
|
||||
/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */
|
||||
static irqreturn_t iwl_isr(int irq, void *data)
|
||||
{
|
||||
struct iwl_trans *trans = data;
|
||||
struct iwl_trans_pcie *trans_pcie;
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
u32 inta, inta_mask;
|
||||
unsigned long flags;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
u32 inta_fh;
|
||||
#endif
|
||||
|
||||
lockdep_assert_held(&trans_pcie->irq_lock);
|
||||
|
||||
if (!trans)
|
||||
return IRQ_NONE;
|
||||
|
||||
trace_iwlwifi_dev_irq(trans->dev);
|
||||
|
||||
trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
||||
|
||||
/* Disable (but don't clear!) interrupts here to avoid
|
||||
* back-to-back ISRs and sporadic interrupts from our NIC.
|
||||
* If we have something to service, the tasklet will re-enable ints.
|
||||
@ -907,7 +906,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
|
||||
/* Hardware disappeared. It might have already raised
|
||||
* an interrupt */
|
||||
IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
|
||||
goto unplugged;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
@ -926,18 +925,13 @@ static irqreturn_t iwl_isr(int irq, void *data)
|
||||
!trans_pcie->inta)
|
||||
iwl_enable_interrupts(trans);
|
||||
|
||||
unplugged:
|
||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
|
||||
none:
|
||||
none:
|
||||
/* re-enable interrupts here since we don't have anything to service. */
|
||||
/* only Re-enable if disabled by irq and no schedules tasklet. */
|
||||
if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
|
||||
!trans_pcie->inta)
|
||||
iwl_enable_interrupts(trans);
|
||||
|
||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
@ -963,15 +957,19 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
|
||||
|
||||
trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
||||
|
||||
/* dram interrupt table not set yet,
|
||||
* use legacy interrupt.
|
||||
*/
|
||||
if (!trans_pcie->use_ict)
|
||||
return iwl_isr(irq, data);
|
||||
if (unlikely(!trans_pcie->use_ict)) {
|
||||
irqreturn_t ret = iwl_isr(irq, data);
|
||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
trace_iwlwifi_dev_irq(trans->dev);
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
||||
|
||||
/* Disable (but don't clear!) interrupts here to avoid
|
||||
* back-to-back ISRs and sporadic interrupts from our NIC.
|
||||
|
@ -296,6 +296,7 @@ static void iwlagn_free_dma_ptr(struct iwl_trans *trans,
|
||||
static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
|
||||
{
|
||||
struct iwl_tx_queue *txq = (void *)data;
|
||||
struct iwl_queue *q = &txq->q;
|
||||
struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
|
||||
struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
|
||||
u32 scd_sram_addr = trans_pcie->scd_base_addr +
|
||||
@ -346,6 +347,14 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data)
|
||||
iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
|
||||
}
|
||||
|
||||
for (i = q->read_ptr; i != q->write_ptr;
|
||||
i = iwl_queue_inc_wrap(i, q->n_bd)) {
|
||||
struct iwl_tx_cmd *tx_cmd =
|
||||
(struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
|
||||
IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
|
||||
get_unaligned_le32(&tx_cmd->scratch));
|
||||
}
|
||||
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
}
|
||||
|
||||
@ -1037,15 +1046,12 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
||||
|
||||
/*
|
||||
* Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
|
||||
* must be called under the irq lock and with MAC access
|
||||
*/
|
||||
static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
|
||||
{
|
||||
struct iwl_trans_pcie __maybe_unused *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
lockdep_assert_held(&trans_pcie->irq_lock);
|
||||
|
||||
iwl_write_prph(trans, SCD_TXFACT, mask);
|
||||
}
|
||||
|
||||
@ -1053,12 +1059,9 @@ static void iwl_tx_start(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
u32 a;
|
||||
unsigned long flags;
|
||||
int i, chan;
|
||||
u32 reg_val;
|
||||
|
||||
spin_lock_irqsave(&trans_pcie->irq_lock, flags);
|
||||
|
||||
/* make sure all queue are not stopped/used */
|
||||
memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped));
|
||||
memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used));
|
||||
@ -1109,8 +1112,6 @@ static void iwl_tx_start(struct iwl_trans *trans)
|
||||
iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
|
||||
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
|
||||
|
||||
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
|
||||
|
||||
/* Enable L1-Active */
|
||||
iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
|
||||
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||
@ -2017,7 +2018,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
|
||||
if (!trans->op_mode)
|
||||
return -EAGAIN;
|
||||
|
||||
local_bh_disable();
|
||||
iwl_op_mode_nic_error(trans->op_mode);
|
||||
local_bh_enable();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -678,8 +678,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
||||
continue;
|
||||
|
||||
if (data2->idle || !data2->started ||
|
||||
!hwsim_ps_rx_ok(data2, skb) ||
|
||||
!data->channel || !data2->channel ||
|
||||
!hwsim_ps_rx_ok(data2, skb) || !data2->channel ||
|
||||
data->channel->center_freq != data2->channel->center_freq ||
|
||||
!(data->group & data2->group))
|
||||
continue;
|
||||
@ -1486,7 +1485,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
|
||||
struct mac80211_hwsim_data *data2;
|
||||
struct ieee80211_tx_info *txi;
|
||||
struct hwsim_tx_rate *tx_attempts;
|
||||
struct sk_buff __user *ret_skb;
|
||||
unsigned long ret_skb_ptr;
|
||||
struct sk_buff *skb, *tmp;
|
||||
struct mac_address *src;
|
||||
unsigned int hwsim_flags;
|
||||
@ -1504,8 +1503,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
|
||||
info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]);
|
||||
hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]);
|
||||
|
||||
ret_skb = (struct sk_buff __user *)
|
||||
(unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
|
||||
ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]);
|
||||
|
||||
data2 = get_hwsim_data_ref_from_addr(src);
|
||||
|
||||
@ -1514,7 +1512,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
|
||||
|
||||
/* look for the skb matching the cookie passed back from user */
|
||||
skb_queue_walk_safe(&data2->pending, skb, tmp) {
|
||||
if (skb == ret_skb) {
|
||||
if ((unsigned long)skb == ret_skb_ptr) {
|
||||
skb_unlink(skb, &data2->pending);
|
||||
found = true;
|
||||
break;
|
||||
|
@ -170,7 +170,9 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
if (!priv->sec_info.wep_enabled)
|
||||
return 0;
|
||||
|
||||
if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
|
||||
if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
|
||||
priv->wep_key_curr_index = key_index;
|
||||
} else if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
|
||||
wiphy_err(wiphy, "set default Tx key index\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
@ -187,9 +189,25 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct key_params *params)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
|
||||
struct mwifiex_wep_key *wep_key;
|
||||
const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
|
||||
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
|
||||
(params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
|
||||
params->cipher == WLAN_CIPHER_SUITE_WEP104)) {
|
||||
if (params->key && params->key_len) {
|
||||
wep_key = &priv->wep_key[key_index];
|
||||
memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
|
||||
memcpy(wep_key->key_material, params->key,
|
||||
params->key_len);
|
||||
wep_key->key_index = key_index;
|
||||
wep_key->key_length = params->key_len;
|
||||
priv->sec_info.wep_enabled = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mwifiex_set_encode(priv, params->key, params->key_len,
|
||||
key_index, peer_mac, 0)) {
|
||||
wiphy_err(wiphy, "crypto keys added\n");
|
||||
@ -242,13 +260,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
|
||||
flag = 1;
|
||||
first_chan = (u32) ch->hw_value;
|
||||
next_chan = first_chan;
|
||||
max_pwr = ch->max_power;
|
||||
max_pwr = ch->max_reg_power;
|
||||
no_of_parsed_chan = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch->hw_value == next_chan + 1 &&
|
||||
ch->max_power == max_pwr) {
|
||||
ch->max_reg_power == max_pwr) {
|
||||
next_chan++;
|
||||
no_of_parsed_chan++;
|
||||
} else {
|
||||
@ -259,7 +277,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
|
||||
no_of_triplet++;
|
||||
first_chan = (u32) ch->hw_value;
|
||||
next_chan = first_chan;
|
||||
max_pwr = ch->max_power;
|
||||
max_pwr = ch->max_reg_power;
|
||||
no_of_parsed_chan = 1;
|
||||
}
|
||||
}
|
||||
@ -384,13 +402,13 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
|
||||
cfp.freq = chan->center_freq;
|
||||
cfp.channel = ieee80211_frequency_to_channel(chan->center_freq);
|
||||
|
||||
if (mwifiex_bss_set_channel(priv, &cfp))
|
||||
return -EFAULT;
|
||||
|
||||
if (priv->bss_type == MWIFIEX_BSS_TYPE_STA)
|
||||
if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
|
||||
if (mwifiex_bss_set_channel(priv, &cfp))
|
||||
return -EFAULT;
|
||||
return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
|
||||
else
|
||||
return mwifiex_uap_set_channel(priv, cfp.channel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -961,12 +979,25 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bss_cfg->channel =
|
||||
(u8)ieee80211_frequency_to_channel(params->channel->center_freq);
|
||||
bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
|
||||
|
||||
if (mwifiex_set_rf_channel(priv, params->channel,
|
||||
params->channel_type)) {
|
||||
kfree(bss_cfg);
|
||||
wiphy_err(wiphy, "Failed to set band config information!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
|
||||
kfree(bss_cfg);
|
||||
wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mwifiex_set_ht_params(priv, bss_cfg, params);
|
||||
|
||||
if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL)) {
|
||||
wiphy_err(wiphy, "Failed to stop the BSS\n");
|
||||
@ -990,6 +1021,16 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (priv->sec_info.wep_enabled)
|
||||
priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
|
||||
else
|
||||
priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
|
||||
|
||||
if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
|
||||
HostCmd_ACT_GEN_SET, 0,
|
||||
&priv->curr_pkt_filter))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1381,7 +1422,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
priv->user_scan_cfg->chan_list[i].scan_time = 0;
|
||||
}
|
||||
if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg))
|
||||
if (mwifiex_scan_networks(priv, priv->user_scan_cfg))
|
||||
return -EFAULT;
|
||||
|
||||
if (request->ie && request->ie_len) {
|
||||
@ -1702,7 +1743,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
|
||||
memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
|
||||
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
|
||||
|
||||
/* Reserve space for mwifiex specific private data for BSS */
|
||||
wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv);
|
||||
|
@ -578,6 +578,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
|
||||
} else {
|
||||
adapter->cmd_queued = cmd_node;
|
||||
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
|
||||
queue_work(adapter->workqueue, &adapter->main_work);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1102,7 +1103,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
|
||||
&resp->params.opt_hs_cfg;
|
||||
uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions);
|
||||
|
||||
if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) {
|
||||
if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) &&
|
||||
adapter->iface_type == MWIFIEX_SDIO) {
|
||||
mwifiex_hs_activated_event(priv, true);
|
||||
return 0;
|
||||
} else {
|
||||
@ -1114,6 +1116,9 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
|
||||
}
|
||||
if (conditions != HOST_SLEEP_CFG_CANCEL) {
|
||||
adapter->is_hs_configured = true;
|
||||
if (adapter->iface_type == MWIFIEX_USB ||
|
||||
adapter->iface_type == MWIFIEX_PCIE)
|
||||
mwifiex_hs_activated_event(priv, true);
|
||||
} else {
|
||||
adapter->is_hs_configured = false;
|
||||
if (adapter->hs_activated)
|
||||
|
@ -124,6 +124,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
|
||||
#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
|
||||
#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
|
||||
#define TLV_TYPE_UAP_WEP_KEY (PROPRIETARY_TLV_BASE_ID + 59)
|
||||
#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
|
||||
#define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
|
||||
#define TLV_TYPE_UAP_AKMP (PROPRIETARY_TLV_BASE_ID + 65)
|
||||
@ -162,6 +163,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
|
||||
#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
|
||||
|
||||
#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
|
||||
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
|
||||
IEEE80211_HT_CAP_SM_PS)
|
||||
|
||||
#define MWIFIEX_DEF_AMPDU IEEE80211_HT_AMPDU_PARM_FACTOR
|
||||
|
||||
/* dev_cap bitmap
|
||||
* BIT
|
||||
* 0-16 reserved
|
||||
@ -219,6 +226,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define HostCmd_CMD_RF_REG_ACCESS 0x001b
|
||||
#define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad
|
||||
#define HostCmd_CMD_802_11_RF_CHANNEL 0x001d
|
||||
#define HostCmd_CMD_RF_TX_PWR 0x001e
|
||||
#define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024
|
||||
#define HostCmd_CMD_MAC_CONTROL 0x0028
|
||||
#define HostCmd_CMD_802_11_AD_HOC_START 0x002b
|
||||
@ -869,6 +877,13 @@ struct host_cmd_ds_txpwr_cfg {
|
||||
__le32 mode;
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_ds_rf_tx_pwr {
|
||||
__le16 action;
|
||||
__le16 cur_level;
|
||||
u8 max_power;
|
||||
u8 min_power;
|
||||
} __packed;
|
||||
|
||||
struct mwifiex_bcn_param {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 rssi;
|
||||
@ -1195,6 +1210,13 @@ struct host_cmd_tlv_passphrase {
|
||||
u8 passphrase[0];
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_tlv_wep_key {
|
||||
struct host_cmd_tlv tlv;
|
||||
u8 key_index;
|
||||
u8 is_default;
|
||||
u8 key[1];
|
||||
};
|
||||
|
||||
struct host_cmd_tlv_auth_type {
|
||||
struct host_cmd_tlv tlv;
|
||||
u8 auth_type;
|
||||
@ -1347,6 +1369,7 @@ struct host_cmd_ds_command {
|
||||
struct host_cmd_ds_tx_rate_query tx_rate;
|
||||
struct host_cmd_ds_tx_rate_cfg tx_rate_cfg;
|
||||
struct host_cmd_ds_txpwr_cfg txp_cfg;
|
||||
struct host_cmd_ds_rf_tx_pwr txp;
|
||||
struct host_cmd_ds_802_11_ps_mode_enh psmode_enh;
|
||||
struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg;
|
||||
struct host_cmd_ds_802_11_scan scan;
|
||||
|
@ -225,29 +225,46 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
|
||||
struct cfg80211_ap_settings *params)
|
||||
{
|
||||
struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL;
|
||||
struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL;
|
||||
struct ieee_types_header *ie = NULL;
|
||||
struct mwifiex_ie *ar_ie = NULL, *gen_ie = NULL;
|
||||
struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL;
|
||||
u16 beacon_idx = MWIFIEX_AUTO_IDX_MASK, pr_idx = MWIFIEX_AUTO_IDX_MASK;
|
||||
u16 ar_idx = MWIFIEX_AUTO_IDX_MASK, rsn_idx = MWIFIEX_AUTO_IDX_MASK;
|
||||
u16 mask;
|
||||
u16 mask, ie_len = 0;
|
||||
const u8 *vendor_ie;
|
||||
int ret = 0;
|
||||
|
||||
if (params->beacon.tail && params->beacon.tail_len) {
|
||||
ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, params->beacon.tail,
|
||||
params->beacon.tail_len);
|
||||
if (ie) {
|
||||
rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
|
||||
if (!rsn_ie)
|
||||
return -ENOMEM;
|
||||
gen_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL);
|
||||
if (!gen_ie)
|
||||
return -ENOMEM;
|
||||
gen_ie->ie_index = cpu_to_le16(rsn_idx);
|
||||
mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP |
|
||||
MGMT_MASK_ASSOC_RESP;
|
||||
gen_ie->mgmt_subtype_mask = cpu_to_le16(mask);
|
||||
|
||||
rsn_ie->ie_index = cpu_to_le16(rsn_idx);
|
||||
mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP |
|
||||
MGMT_MASK_ASSOC_RESP;
|
||||
rsn_ie->mgmt_subtype_mask = cpu_to_le16(mask);
|
||||
rsn_ie->ie_length = cpu_to_le16(ie->len + 2);
|
||||
memcpy(rsn_ie->ie_buffer, ie, ie->len + 2);
|
||||
rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN,
|
||||
params->beacon.tail,
|
||||
params->beacon.tail_len);
|
||||
if (rsn_ie) {
|
||||
memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2);
|
||||
ie_len = rsn_ie->len + 2;
|
||||
gen_ie->ie_length = cpu_to_le16(ie_len);
|
||||
}
|
||||
|
||||
if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &rsn_idx,
|
||||
vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
|
||||
WLAN_OUI_TYPE_MICROSOFT_WPA,
|
||||
params->beacon.tail,
|
||||
params->beacon.tail_len);
|
||||
if (vendor_ie) {
|
||||
wpa_ie = (struct ieee_types_header *)vendor_ie;
|
||||
memcpy(gen_ie->ie_buffer + ie_len,
|
||||
wpa_ie, wpa_ie->len + 2);
|
||||
ie_len += wpa_ie->len + 2;
|
||||
gen_ie->ie_length = cpu_to_le16(ie_len);
|
||||
}
|
||||
|
||||
if (rsn_ie || wpa_ie) {
|
||||
if (mwifiex_update_uap_custom_ie(priv, gen_ie, &rsn_idx,
|
||||
NULL, NULL,
|
||||
NULL, NULL)) {
|
||||
ret = -1;
|
||||
@ -320,7 +337,7 @@ done:
|
||||
kfree(beacon_ie);
|
||||
kfree(pr_ie);
|
||||
kfree(ar_ie);
|
||||
kfree(rsn_ie);
|
||||
kfree(gen_ie);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ static void scan_delay_timer_fn(unsigned long data)
|
||||
msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
|
||||
adapter->scan_delay_cnt++;
|
||||
}
|
||||
queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
|
||||
} else {
|
||||
/*
|
||||
* Tx data queue is empty. Get scan command from scan_pending_q
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define _MWIFIEX_IOCTL_H_
|
||||
|
||||
#include <net/mac80211.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
enum {
|
||||
MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
|
||||
@ -71,6 +72,13 @@ struct wpa_param {
|
||||
u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN];
|
||||
};
|
||||
|
||||
struct wep_key {
|
||||
u8 key_index;
|
||||
u8 is_default;
|
||||
u16 length;
|
||||
u8 key[WLAN_KEY_LEN_WEP104];
|
||||
};
|
||||
|
||||
#define KEY_MGMT_ON_HOST 0x03
|
||||
#define MWIFIEX_AUTH_MODE_AUTO 0xFF
|
||||
#define BAND_CONFIG_MANUAL 0x00
|
||||
@ -90,6 +98,8 @@ struct mwifiex_uap_bss_param {
|
||||
u16 key_mgmt;
|
||||
u16 key_mgmt_operation;
|
||||
struct wpa_param wpa_cfg;
|
||||
struct wep_key wep_cfg[NUM_WEP_KEYS];
|
||||
struct ieee80211_ht_cap ht_cap;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -190,7 +190,8 @@ process_start:
|
||||
adapter->tx_lock_flag)
|
||||
break;
|
||||
|
||||
if (adapter->scan_processing || adapter->data_sent ||
|
||||
if ((adapter->scan_processing &&
|
||||
!adapter->scan_delay_cnt) || adapter->data_sent ||
|
||||
mwifiex_wmm_lists_empty(adapter)) {
|
||||
if (adapter->cmd_sent || adapter->curr_cmd ||
|
||||
(!is_command_pending(adapter)))
|
||||
|
@ -840,6 +840,9 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
|
||||
int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
struct mwifiex_uap_bss_param *bss_config,
|
||||
struct cfg80211_ap_settings *params);
|
||||
void mwifiex_set_ht_params(struct mwifiex_private *priv,
|
||||
struct mwifiex_uap_bss_param *bss_cfg,
|
||||
struct cfg80211_ap_settings *params);
|
||||
|
||||
/*
|
||||
* This function checks if the queuing is RA based or not.
|
||||
@ -946,8 +949,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
|
||||
struct mwifiex_rate_cfg *rate);
|
||||
int mwifiex_request_scan(struct mwifiex_private *priv,
|
||||
struct cfg80211_ssid *req_ssid);
|
||||
int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
|
||||
struct mwifiex_user_scan_cfg *scan_req);
|
||||
int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
const struct mwifiex_user_scan_cfg *user_scan_in);
|
||||
int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
|
||||
|
||||
int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
|
||||
@ -990,7 +993,6 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
|
||||
|
||||
int mwifiex_main_process(struct mwifiex_adapter *);
|
||||
|
||||
int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel);
|
||||
int mwifiex_bss_set_channel(struct mwifiex_private *,
|
||||
struct mwifiex_chan_freq_power *cfp);
|
||||
int mwifiex_get_bss_info(struct mwifiex_private *,
|
||||
|
@ -1294,8 +1294,8 @@ mwifiex_radio_type_to_band(u8 radio_type)
|
||||
* order to send the appropriate scan commands to firmware to populate or
|
||||
* update the internal driver scan table.
|
||||
*/
|
||||
static int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
const struct mwifiex_user_scan_cfg *user_scan_in)
|
||||
int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
const struct mwifiex_user_scan_cfg *user_scan_in)
|
||||
{
|
||||
int ret = 0;
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
@ -1360,6 +1360,7 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
adapter->cmd_queued = cmd_node;
|
||||
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
|
||||
true);
|
||||
queue_work(adapter->workqueue, &adapter->main_work);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
|
||||
flags);
|
||||
@ -1375,26 +1376,6 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends IOCTL request to start a scan with user configurations.
|
||||
*
|
||||
* This function allocates the IOCTL request buffer, fills it
|
||||
* with requisite parameters and calls the IOCTL handler.
|
||||
*
|
||||
* Upon completion, it also generates a wireless event to notify
|
||||
* applications.
|
||||
*/
|
||||
int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
|
||||
struct mwifiex_user_scan_cfg *scan_req)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = mwifiex_scan_networks(priv, scan_req);
|
||||
queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares a scan command to be sent to the firmware.
|
||||
*
|
||||
|
@ -259,6 +259,23 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares command to get RF Tx power.
|
||||
*/
|
||||
static int mwifiex_cmd_rf_tx_power(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *data_buf)
|
||||
{
|
||||
struct host_cmd_ds_rf_tx_pwr *txp = &cmd->params.txp;
|
||||
|
||||
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_tx_pwr)
|
||||
+ S_DS_GEN);
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_RF_TX_PWR);
|
||||
txp->action = cpu_to_le16(cmd_action);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares command to set Host Sleep configuration.
|
||||
*
|
||||
@ -1049,6 +1066,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
|
||||
ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action,
|
||||
data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_RF_TX_PWR:
|
||||
ret = mwifiex_cmd_rf_tx_power(priv, cmd_ptr, cmd_action,
|
||||
data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_802_11_PS_MODE_ENH:
|
||||
ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action,
|
||||
(uint16_t)cmd_oid, data_buf);
|
||||
@ -1277,7 +1298,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
|
||||
priv->data_rate = 0;
|
||||
|
||||
/* get tx power */
|
||||
ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG,
|
||||
ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_RF_TX_PWR,
|
||||
HostCmd_ACT_GEN_GET, 0, NULL);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
@ -450,6 +450,30 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the command response of get RF Tx power.
|
||||
*/
|
||||
static int mwifiex_ret_rf_tx_power(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp)
|
||||
{
|
||||
struct host_cmd_ds_rf_tx_pwr *txp = &resp->params.txp;
|
||||
u16 action = le16_to_cpu(txp->action);
|
||||
|
||||
priv->tx_power_level = le16_to_cpu(txp->cur_level);
|
||||
|
||||
if (action == HostCmd_ACT_GEN_GET) {
|
||||
priv->max_tx_power_level = txp->max_power;
|
||||
priv->min_tx_power_level = txp->min_power;
|
||||
}
|
||||
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"Current TxPower Level=%d, Max Power=%d, Min Power=%d\n",
|
||||
priv->tx_power_level, priv->max_tx_power_level,
|
||||
priv->min_tx_power_level);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the command response of set/get MAC address.
|
||||
*
|
||||
@ -841,6 +865,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
|
||||
case HostCmd_CMD_TXPWR_CFG:
|
||||
ret = mwifiex_ret_tx_power_cfg(priv, resp);
|
||||
break;
|
||||
case HostCmd_CMD_RF_TX_PWR:
|
||||
ret = mwifiex_ret_rf_tx_power(priv, resp);
|
||||
break;
|
||||
case HostCmd_CMD_802_11_PS_MODE_ENH:
|
||||
ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf);
|
||||
break;
|
||||
|
@ -66,9 +66,6 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
|
||||
dev_dbg(adapter->dev, "cmd pending\n");
|
||||
atomic_inc(&adapter->cmd_pending);
|
||||
|
||||
/* Status pending, wake up main process */
|
||||
queue_work(adapter->workqueue, &adapter->main_work);
|
||||
|
||||
/* Wait for completion */
|
||||
wait_event_interruptible(adapter->cmd_wait_q.wait,
|
||||
*(cmd_queued->condition));
|
||||
|
@ -26,6 +26,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
struct mwifiex_uap_bss_param *bss_config,
|
||||
struct cfg80211_ap_settings *params) {
|
||||
int i;
|
||||
struct mwifiex_wep_key wep_key;
|
||||
|
||||
if (!params->privacy) {
|
||||
bss_config->protocol = PROTOCOL_NO_SECURITY;
|
||||
@ -65,7 +66,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
}
|
||||
if (params->crypto.wpa_versions &
|
||||
NL80211_WPA_VERSION_2) {
|
||||
bss_config->protocol = PROTOCOL_WPA2;
|
||||
bss_config->protocol |= PROTOCOL_WPA2;
|
||||
bss_config->key_mgmt = KEY_MGMT_EAP;
|
||||
}
|
||||
break;
|
||||
@ -77,7 +78,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
}
|
||||
if (params->crypto.wpa_versions &
|
||||
NL80211_WPA_VERSION_2) {
|
||||
bss_config->protocol = PROTOCOL_WPA2;
|
||||
bss_config->protocol |= PROTOCOL_WPA2;
|
||||
bss_config->key_mgmt = KEY_MGMT_PSK;
|
||||
}
|
||||
break;
|
||||
@ -91,10 +92,19 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
bss_config->wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP;
|
||||
if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
|
||||
bss_config->wpa_cfg.pairwise_cipher_wpa |=
|
||||
CIPHER_TKIP;
|
||||
if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
|
||||
bss_config->wpa_cfg.pairwise_cipher_wpa2 |=
|
||||
CIPHER_TKIP;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
bss_config->wpa_cfg.pairwise_cipher_wpa2 =
|
||||
if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1)
|
||||
bss_config->wpa_cfg.pairwise_cipher_wpa |=
|
||||
CIPHER_AES_CCMP;
|
||||
if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2)
|
||||
bss_config->wpa_cfg.pairwise_cipher_wpa2 |=
|
||||
CIPHER_AES_CCMP;
|
||||
default:
|
||||
break;
|
||||
@ -104,6 +114,27 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
switch (params->crypto.cipher_group) {
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
if (priv->sec_info.wep_enabled) {
|
||||
bss_config->protocol = PROTOCOL_STATIC_WEP;
|
||||
bss_config->key_mgmt = KEY_MGMT_NONE;
|
||||
bss_config->wpa_cfg.length = 0;
|
||||
|
||||
for (i = 0; i < NUM_WEP_KEYS; i++) {
|
||||
wep_key = priv->wep_key[i];
|
||||
bss_config->wep_cfg[i].key_index = i;
|
||||
|
||||
if (priv->wep_key_curr_index == i)
|
||||
bss_config->wep_cfg[i].is_default = 1;
|
||||
else
|
||||
bss_config->wep_cfg[i].is_default = 0;
|
||||
|
||||
bss_config->wep_cfg[i].length =
|
||||
wep_key.key_length;
|
||||
memcpy(&bss_config->wep_cfg[i].key,
|
||||
&wep_key.key_material,
|
||||
wep_key.key_length);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
bss_config->wpa_cfg.group_cipher = CIPHER_TKIP;
|
||||
@ -118,6 +149,33 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function updates 11n related parameters from IE and sets them into
|
||||
* bss_config structure.
|
||||
*/
|
||||
void
|
||||
mwifiex_set_ht_params(struct mwifiex_private *priv,
|
||||
struct mwifiex_uap_bss_param *bss_cfg,
|
||||
struct cfg80211_ap_settings *params)
|
||||
{
|
||||
const u8 *ht_ie;
|
||||
|
||||
if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
|
||||
return;
|
||||
|
||||
ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, params->beacon.tail,
|
||||
params->beacon.tail_len);
|
||||
if (ht_ie) {
|
||||
memcpy(&bss_cfg->ht_cap, ht_ie + 2,
|
||||
sizeof(struct ieee80211_ht_cap));
|
||||
} else {
|
||||
memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap));
|
||||
bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP);
|
||||
bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function initializes some of mwifiex_uap_bss_param variables.
|
||||
* This helps FW in ignoring invalid values. These values may or may not
|
||||
* be get updated to valid ones at later stage.
|
||||
@ -134,6 +192,120 @@ void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config)
|
||||
config->retry_limit = 0x7F;
|
||||
}
|
||||
|
||||
/* This function parses BSS related parameters from structure
|
||||
* and prepares TLVs specific to WPA/WPA2 security.
|
||||
* These TLVs are appended to command buffer.
|
||||
*/
|
||||
static void
|
||||
mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
|
||||
{
|
||||
struct host_cmd_tlv_pwk_cipher *pwk_cipher;
|
||||
struct host_cmd_tlv_gwk_cipher *gwk_cipher;
|
||||
struct host_cmd_tlv_passphrase *passphrase;
|
||||
struct host_cmd_tlv_akmp *tlv_akmp;
|
||||
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
|
||||
u16 cmd_size = *param_size;
|
||||
u8 *tlv = *tlv_buf;
|
||||
|
||||
tlv_akmp = (struct host_cmd_tlv_akmp *)tlv;
|
||||
tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
|
||||
tlv_akmp->tlv.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
tlv_akmp->key_mgmt_operation = cpu_to_le16(bss_cfg->key_mgmt_operation);
|
||||
tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt);
|
||||
cmd_size += sizeof(struct host_cmd_tlv_akmp);
|
||||
tlv += sizeof(struct host_cmd_tlv_akmp);
|
||||
|
||||
if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) {
|
||||
pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
|
||||
pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
|
||||
pwk_cipher->tlv.len =
|
||||
cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA);
|
||||
pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa;
|
||||
cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
}
|
||||
|
||||
if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) {
|
||||
pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
|
||||
pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
|
||||
pwk_cipher->tlv.len =
|
||||
cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2);
|
||||
pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa2;
|
||||
cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
}
|
||||
|
||||
if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) {
|
||||
gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv;
|
||||
gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
|
||||
gwk_cipher->tlv.len =
|
||||
cpu_to_le16(sizeof(struct host_cmd_tlv_gwk_cipher) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher;
|
||||
cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher);
|
||||
tlv += sizeof(struct host_cmd_tlv_gwk_cipher);
|
||||
}
|
||||
|
||||
if (bss_cfg->wpa_cfg.length) {
|
||||
passphrase = (struct host_cmd_tlv_passphrase *)tlv;
|
||||
passphrase->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
|
||||
passphrase->tlv.len = cpu_to_le16(bss_cfg->wpa_cfg.length);
|
||||
memcpy(passphrase->passphrase, bss_cfg->wpa_cfg.passphrase,
|
||||
bss_cfg->wpa_cfg.length);
|
||||
cmd_size += sizeof(struct host_cmd_tlv) +
|
||||
bss_cfg->wpa_cfg.length;
|
||||
tlv += sizeof(struct host_cmd_tlv) + bss_cfg->wpa_cfg.length;
|
||||
}
|
||||
|
||||
*param_size = cmd_size;
|
||||
*tlv_buf = tlv;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function parses BSS related parameters from structure
|
||||
* and prepares TLVs specific to WEP encryption.
|
||||
* These TLVs are appended to command buffer.
|
||||
*/
|
||||
static void
|
||||
mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
|
||||
{
|
||||
struct host_cmd_tlv_wep_key *wep_key;
|
||||
u16 cmd_size = *param_size;
|
||||
int i;
|
||||
u8 *tlv = *tlv_buf;
|
||||
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
|
||||
|
||||
for (i = 0; i < NUM_WEP_KEYS; i++) {
|
||||
if (bss_cfg->wep_cfg[i].length &&
|
||||
(bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 ||
|
||||
bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) {
|
||||
wep_key = (struct host_cmd_tlv_wep_key *)tlv;
|
||||
wep_key->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WEP_KEY);
|
||||
wep_key->tlv.len =
|
||||
cpu_to_le16(bss_cfg->wep_cfg[i].length + 2);
|
||||
wep_key->key_index = bss_cfg->wep_cfg[i].key_index;
|
||||
wep_key->is_default = bss_cfg->wep_cfg[i].is_default;
|
||||
memcpy(wep_key->key, bss_cfg->wep_cfg[i].key,
|
||||
bss_cfg->wep_cfg[i].length);
|
||||
cmd_size += sizeof(struct host_cmd_tlv) + 2 +
|
||||
bss_cfg->wep_cfg[i].length;
|
||||
tlv += sizeof(struct host_cmd_tlv) + 2 +
|
||||
bss_cfg->wep_cfg[i].length;
|
||||
}
|
||||
}
|
||||
|
||||
*param_size = cmd_size;
|
||||
*tlv_buf = tlv;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function parses BSS related parameters from structure
|
||||
* and prepares TLVs. These TLVs are appended to command buffer.
|
||||
*/
|
||||
@ -148,12 +320,9 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
|
||||
struct host_cmd_tlv_frag_threshold *frag_threshold;
|
||||
struct host_cmd_tlv_rts_threshold *rts_threshold;
|
||||
struct host_cmd_tlv_retry_limit *retry_limit;
|
||||
struct host_cmd_tlv_pwk_cipher *pwk_cipher;
|
||||
struct host_cmd_tlv_gwk_cipher *gwk_cipher;
|
||||
struct host_cmd_tlv_encrypt_protocol *encrypt_protocol;
|
||||
struct host_cmd_tlv_auth_type *auth_type;
|
||||
struct host_cmd_tlv_passphrase *passphrase;
|
||||
struct host_cmd_tlv_akmp *tlv_akmp;
|
||||
struct mwifiex_ie_types_htcap *htcap;
|
||||
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
|
||||
u16 cmd_size = *param_size;
|
||||
|
||||
@ -243,70 +412,11 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
|
||||
}
|
||||
if ((bss_cfg->protocol & PROTOCOL_WPA) ||
|
||||
(bss_cfg->protocol & PROTOCOL_WPA2) ||
|
||||
(bss_cfg->protocol & PROTOCOL_EAP)) {
|
||||
tlv_akmp = (struct host_cmd_tlv_akmp *)tlv;
|
||||
tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP);
|
||||
tlv_akmp->tlv.len =
|
||||
cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
tlv_akmp->key_mgmt_operation =
|
||||
cpu_to_le16(bss_cfg->key_mgmt_operation);
|
||||
tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt);
|
||||
cmd_size += sizeof(struct host_cmd_tlv_akmp);
|
||||
tlv += sizeof(struct host_cmd_tlv_akmp);
|
||||
(bss_cfg->protocol & PROTOCOL_EAP))
|
||||
mwifiex_uap_bss_wpa(&tlv, cmd_buf, &cmd_size);
|
||||
else
|
||||
mwifiex_uap_bss_wep(&tlv, cmd_buf, &cmd_size);
|
||||
|
||||
if (bss_cfg->wpa_cfg.pairwise_cipher_wpa &
|
||||
VALID_CIPHER_BITMAP) {
|
||||
pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
|
||||
pwk_cipher->tlv.type =
|
||||
cpu_to_le16(TLV_TYPE_PWK_CIPHER);
|
||||
pwk_cipher->tlv.len = cpu_to_le16(
|
||||
sizeof(struct host_cmd_tlv_pwk_cipher) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA);
|
||||
pwk_cipher->cipher =
|
||||
bss_cfg->wpa_cfg.pairwise_cipher_wpa;
|
||||
cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
}
|
||||
if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 &
|
||||
VALID_CIPHER_BITMAP) {
|
||||
pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv;
|
||||
pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER);
|
||||
pwk_cipher->tlv.len = cpu_to_le16(
|
||||
sizeof(struct host_cmd_tlv_pwk_cipher) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2);
|
||||
pwk_cipher->cipher =
|
||||
bss_cfg->wpa_cfg.pairwise_cipher_wpa2;
|
||||
cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
tlv += sizeof(struct host_cmd_tlv_pwk_cipher);
|
||||
}
|
||||
if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) {
|
||||
gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv;
|
||||
gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER);
|
||||
gwk_cipher->tlv.len = cpu_to_le16(
|
||||
sizeof(struct host_cmd_tlv_gwk_cipher) -
|
||||
sizeof(struct host_cmd_tlv));
|
||||
gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher;
|
||||
cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher);
|
||||
tlv += sizeof(struct host_cmd_tlv_gwk_cipher);
|
||||
}
|
||||
if (bss_cfg->wpa_cfg.length) {
|
||||
passphrase = (struct host_cmd_tlv_passphrase *)tlv;
|
||||
passphrase->tlv.type =
|
||||
cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE);
|
||||
passphrase->tlv.len =
|
||||
cpu_to_le16(bss_cfg->wpa_cfg.length);
|
||||
memcpy(passphrase->passphrase,
|
||||
bss_cfg->wpa_cfg.passphrase,
|
||||
bss_cfg->wpa_cfg.length);
|
||||
cmd_size += sizeof(struct host_cmd_tlv) +
|
||||
bss_cfg->wpa_cfg.length;
|
||||
tlv += sizeof(struct host_cmd_tlv) +
|
||||
bss_cfg->wpa_cfg.length;
|
||||
}
|
||||
}
|
||||
if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) ||
|
||||
(bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) {
|
||||
auth_type = (struct host_cmd_tlv_auth_type *)tlv;
|
||||
@ -330,6 +440,25 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
|
||||
tlv += sizeof(struct host_cmd_tlv_encrypt_protocol);
|
||||
}
|
||||
|
||||
if (bss_cfg->ht_cap.cap_info) {
|
||||
htcap = (struct mwifiex_ie_types_htcap *)tlv;
|
||||
htcap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
|
||||
htcap->header.len =
|
||||
cpu_to_le16(sizeof(struct ieee80211_ht_cap));
|
||||
htcap->ht_cap.cap_info = bss_cfg->ht_cap.cap_info;
|
||||
htcap->ht_cap.ampdu_params_info =
|
||||
bss_cfg->ht_cap.ampdu_params_info;
|
||||
memcpy(&htcap->ht_cap.mcs, &bss_cfg->ht_cap.mcs,
|
||||
sizeof(struct ieee80211_mcs_info));
|
||||
htcap->ht_cap.extended_ht_cap_info =
|
||||
bss_cfg->ht_cap.extended_ht_cap_info;
|
||||
htcap->ht_cap.tx_BF_cap_info = bss_cfg->ht_cap.tx_BF_cap_info;
|
||||
htcap->ht_cap.antenna_selection_info =
|
||||
bss_cfg->ht_cap.antenna_selection_info;
|
||||
cmd_size += sizeof(struct mwifiex_ie_types_htcap);
|
||||
tlv += sizeof(struct mwifiex_ie_types_htcap);
|
||||
}
|
||||
|
||||
*param_size = cmd_size;
|
||||
|
||||
return 0;
|
||||
@ -421,33 +550,3 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function sets the RF channel for AP.
|
||||
*
|
||||
* This function populates channel information in AP config structure
|
||||
* and sends command to configure channel information in AP.
|
||||
*/
|
||||
int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel)
|
||||
{
|
||||
struct mwifiex_uap_bss_param *bss_cfg;
|
||||
struct wiphy *wiphy = priv->wdev->wiphy;
|
||||
|
||||
bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
|
||||
if (!bss_cfg)
|
||||
return -ENOMEM;
|
||||
|
||||
mwifiex_set_sys_config_invalid_data(bss_cfg);
|
||||
bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
|
||||
bss_cfg->channel = channel;
|
||||
|
||||
if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG,
|
||||
HostCmd_ACT_GEN_SET,
|
||||
UAP_BSS_PARAMS_I, bss_cfg)) {
|
||||
wiphy_err(wiphy, "Failed to set the uAP channel\n");
|
||||
kfree(bss_cfg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
kfree(bss_cfg);
|
||||
return 0;
|
||||
}
|
||||
|
@ -99,6 +99,14 @@ config RT2800PCI_RT53XX
|
||||
rt2800pci driver.
|
||||
Supported chips: RT5390
|
||||
|
||||
config RT2800PCI_RT3290
|
||||
bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
default y
|
||||
---help---
|
||||
This adds support for rt3290 wireless chipset family to the
|
||||
rt2800pci driver.
|
||||
Supported chips: RT3290
|
||||
endif
|
||||
|
||||
config RT2500USB
|
||||
|
@ -68,6 +68,7 @@
|
||||
#define RF3320 0x000b
|
||||
#define RF3322 0x000c
|
||||
#define RF3053 0x000d
|
||||
#define RF3290 0x3290
|
||||
#define RF5360 0x5360
|
||||
#define RF5370 0x5370
|
||||
#define RF5372 0x5372
|
||||
@ -117,6 +118,12 @@
|
||||
* Registers.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* MAC_CSR0_3290: MAC_CSR0 for RT3290 to identity MAC version number.
|
||||
*/
|
||||
#define MAC_CSR0_3290 0x0000
|
||||
|
||||
/*
|
||||
* E2PROM_CSR: PCI EEPROM control register.
|
||||
* RELOAD: Write 1 to reload eeprom content.
|
||||
@ -132,6 +139,150 @@
|
||||
#define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040)
|
||||
#define E2PROM_CSR_RELOAD FIELD32(0x00000080)
|
||||
|
||||
/*
|
||||
* CMB_CTRL_CFG
|
||||
*/
|
||||
#define CMB_CTRL 0x0020
|
||||
#define AUX_OPT_BIT0 FIELD32(0x00000001)
|
||||
#define AUX_OPT_BIT1 FIELD32(0x00000002)
|
||||
#define AUX_OPT_BIT2 FIELD32(0x00000004)
|
||||
#define AUX_OPT_BIT3 FIELD32(0x00000008)
|
||||
#define AUX_OPT_BIT4 FIELD32(0x00000010)
|
||||
#define AUX_OPT_BIT5 FIELD32(0x00000020)
|
||||
#define AUX_OPT_BIT6 FIELD32(0x00000040)
|
||||
#define AUX_OPT_BIT7 FIELD32(0x00000080)
|
||||
#define AUX_OPT_BIT8 FIELD32(0x00000100)
|
||||
#define AUX_OPT_BIT9 FIELD32(0x00000200)
|
||||
#define AUX_OPT_BIT10 FIELD32(0x00000400)
|
||||
#define AUX_OPT_BIT11 FIELD32(0x00000800)
|
||||
#define AUX_OPT_BIT12 FIELD32(0x00001000)
|
||||
#define AUX_OPT_BIT13 FIELD32(0x00002000)
|
||||
#define AUX_OPT_BIT14 FIELD32(0x00004000)
|
||||
#define AUX_OPT_BIT15 FIELD32(0x00008000)
|
||||
#define LDO25_LEVEL FIELD32(0x00030000)
|
||||
#define LDO25_LARGEA FIELD32(0x00040000)
|
||||
#define LDO25_FRC_ON FIELD32(0x00080000)
|
||||
#define CMB_RSV FIELD32(0x00300000)
|
||||
#define XTAL_RDY FIELD32(0x00400000)
|
||||
#define PLL_LD FIELD32(0x00800000)
|
||||
#define LDO_CORE_LEVEL FIELD32(0x0F000000)
|
||||
#define LDO_BGSEL FIELD32(0x30000000)
|
||||
#define LDO3_EN FIELD32(0x40000000)
|
||||
#define LDO0_EN FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* EFUSE_CSR_3290: RT3290 EEPROM
|
||||
*/
|
||||
#define EFUSE_CTRL_3290 0x0024
|
||||
|
||||
/*
|
||||
* EFUSE_DATA3 of 3290
|
||||
*/
|
||||
#define EFUSE_DATA3_3290 0x0028
|
||||
|
||||
/*
|
||||
* EFUSE_DATA2 of 3290
|
||||
*/
|
||||
#define EFUSE_DATA2_3290 0x002c
|
||||
|
||||
/*
|
||||
* EFUSE_DATA1 of 3290
|
||||
*/
|
||||
#define EFUSE_DATA1_3290 0x0030
|
||||
|
||||
/*
|
||||
* EFUSE_DATA0 of 3290
|
||||
*/
|
||||
#define EFUSE_DATA0_3290 0x0034
|
||||
|
||||
/*
|
||||
* OSC_CTRL_CFG
|
||||
* Ring oscillator configuration
|
||||
*/
|
||||
#define OSC_CTRL 0x0038
|
||||
#define OSC_REF_CYCLE FIELD32(0x00001fff)
|
||||
#define OSC_RSV FIELD32(0x0000e000)
|
||||
#define OSC_CAL_CNT FIELD32(0x0fff0000)
|
||||
#define OSC_CAL_ACK FIELD32(0x10000000)
|
||||
#define OSC_CLK_32K_VLD FIELD32(0x20000000)
|
||||
#define OSC_CAL_REQ FIELD32(0x40000000)
|
||||
#define OSC_ROSC_EN FIELD32(0x80000000)
|
||||
|
||||
/*
|
||||
* COEX_CFG_0
|
||||
*/
|
||||
#define COEX_CFG0 0x0040
|
||||
#define COEX_CFG_ANT FIELD32(0xff000000)
|
||||
/*
|
||||
* COEX_CFG_1
|
||||
*/
|
||||
#define COEX_CFG1 0x0044
|
||||
|
||||
/*
|
||||
* COEX_CFG_2
|
||||
*/
|
||||
#define COEX_CFG2 0x0048
|
||||
#define BT_COEX_CFG1 FIELD32(0xff000000)
|
||||
#define BT_COEX_CFG0 FIELD32(0x00ff0000)
|
||||
#define WL_COEX_CFG1 FIELD32(0x0000ff00)
|
||||
#define WL_COEX_CFG0 FIELD32(0x000000ff)
|
||||
/*
|
||||
* PLL_CTRL_CFG
|
||||
* PLL configuration register
|
||||
*/
|
||||
#define PLL_CTRL 0x0050
|
||||
#define PLL_RESERVED_INPUT1 FIELD32(0x000000ff)
|
||||
#define PLL_RESERVED_INPUT2 FIELD32(0x0000ff00)
|
||||
#define PLL_CONTROL FIELD32(0x00070000)
|
||||
#define PLL_LPF_R1 FIELD32(0x00080000)
|
||||
#define PLL_LPF_C1_CTRL FIELD32(0x00300000)
|
||||
#define PLL_LPF_C2_CTRL FIELD32(0x00c00000)
|
||||
#define PLL_CP_CURRENT_CTRL FIELD32(0x03000000)
|
||||
#define PLL_PFD_DELAY_CTRL FIELD32(0x0c000000)
|
||||
#define PLL_LOCK_CTRL FIELD32(0x70000000)
|
||||
#define PLL_VBGBK_EN FIELD32(0x80000000)
|
||||
|
||||
|
||||
/*
|
||||
* WLAN_CTRL_CFG
|
||||
* RT3290 wlan configuration
|
||||
*/
|
||||
#define WLAN_FUN_CTRL 0x0080
|
||||
#define WLAN_EN FIELD32(0x00000001)
|
||||
#define WLAN_CLK_EN FIELD32(0x00000002)
|
||||
#define WLAN_RSV1 FIELD32(0x00000004)
|
||||
#define WLAN_RESET FIELD32(0x00000008)
|
||||
#define PCIE_APP0_CLK_REQ FIELD32(0x00000010)
|
||||
#define FRC_WL_ANT_SET FIELD32(0x00000020)
|
||||
#define INV_TR_SW0 FIELD32(0x00000040)
|
||||
#define WLAN_GPIO_IN_BIT0 FIELD32(0x00000100)
|
||||
#define WLAN_GPIO_IN_BIT1 FIELD32(0x00000200)
|
||||
#define WLAN_GPIO_IN_BIT2 FIELD32(0x00000400)
|
||||
#define WLAN_GPIO_IN_BIT3 FIELD32(0x00000800)
|
||||
#define WLAN_GPIO_IN_BIT4 FIELD32(0x00001000)
|
||||
#define WLAN_GPIO_IN_BIT5 FIELD32(0x00002000)
|
||||
#define WLAN_GPIO_IN_BIT6 FIELD32(0x00004000)
|
||||
#define WLAN_GPIO_IN_BIT7 FIELD32(0x00008000)
|
||||
#define WLAN_GPIO_IN_BIT_ALL FIELD32(0x0000ff00)
|
||||
#define WLAN_GPIO_OUT_BIT0 FIELD32(0x00010000)
|
||||
#define WLAN_GPIO_OUT_BIT1 FIELD32(0x00020000)
|
||||
#define WLAN_GPIO_OUT_BIT2 FIELD32(0x00040000)
|
||||
#define WLAN_GPIO_OUT_BIT3 FIELD32(0x00050000)
|
||||
#define WLAN_GPIO_OUT_BIT4 FIELD32(0x00100000)
|
||||
#define WLAN_GPIO_OUT_BIT5 FIELD32(0x00200000)
|
||||
#define WLAN_GPIO_OUT_BIT6 FIELD32(0x00400000)
|
||||
#define WLAN_GPIO_OUT_BIT7 FIELD32(0x00800000)
|
||||
#define WLAN_GPIO_OUT_BIT_ALL FIELD32(0x00ff0000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT0 FIELD32(0x01000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT1 FIELD32(0x02000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT2 FIELD32(0x04000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT3 FIELD32(0x08000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT4 FIELD32(0x10000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT5 FIELD32(0x20000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT6 FIELD32(0x40000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT7 FIELD32(0x80000000)
|
||||
#define WLAN_GPIO_OUT_OE_BIT_ALL FIELD32(0xff000000)
|
||||
|
||||
/*
|
||||
* AUX_CTRL: Aux/PCI-E related configuration
|
||||
*/
|
||||
@ -1763,9 +1914,11 @@ struct mac_iveiv_entry {
|
||||
/*
|
||||
* BBP 3: RX Antenna
|
||||
*/
|
||||
#define BBP3_RX_ADC FIELD8(0x03)
|
||||
#define BBP3_RX_ADC FIELD8(0x03)
|
||||
#define BBP3_RX_ANTENNA FIELD8(0x18)
|
||||
#define BBP3_HT40_MINUS FIELD8(0x20)
|
||||
#define BBP3_ADC_MODE_SWITCH FIELD8(0x40)
|
||||
#define BBP3_ADC_INIT_MODE FIELD8(0x80)
|
||||
|
||||
/*
|
||||
* BBP 4: Bandwidth
|
||||
@ -1774,6 +1927,14 @@ struct mac_iveiv_entry {
|
||||
#define BBP4_BANDWIDTH FIELD8(0x18)
|
||||
#define BBP4_MAC_IF_CTRL FIELD8(0x40)
|
||||
|
||||
/*
|
||||
* BBP 47: Bandwidth
|
||||
*/
|
||||
#define BBP47_TSSI_REPORT_SEL FIELD8(0x03)
|
||||
#define BBP47_TSSI_UPDATE_REQ FIELD8(0x04)
|
||||
#define BBP47_TSSI_TSSI_MODE FIELD8(0x18)
|
||||
#define BBP47_TSSI_ADC6 FIELD8(0x80)
|
||||
|
||||
/*
|
||||
* BBP 109
|
||||
*/
|
||||
@ -1916,6 +2077,16 @@ struct mac_iveiv_entry {
|
||||
#define RFCSR27_R3 FIELD8(0x30)
|
||||
#define RFCSR27_R4 FIELD8(0x40)
|
||||
|
||||
/*
|
||||
* RFCSR 29:
|
||||
*/
|
||||
#define RFCSR29_ADC6_TEST FIELD8(0x01)
|
||||
#define RFCSR29_ADC6_INT_TEST FIELD8(0x02)
|
||||
#define RFCSR29_RSSI_RESET FIELD8(0x04)
|
||||
#define RFCSR29_RSSI_ON FIELD8(0x08)
|
||||
#define RFCSR29_RSSI_RIP_CTRL FIELD8(0x30)
|
||||
#define RFCSR29_RSSI_GAIN FIELD8(0xc0)
|
||||
|
||||
/*
|
||||
* RFCSR 30:
|
||||
*/
|
||||
|
@ -354,16 +354,15 @@ int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev,
|
||||
* of 4kb. Certain USB chipsets however require different firmware,
|
||||
* which Ralink only provides attached to the original firmware
|
||||
* file. Thus for USB devices, firmware files have a length
|
||||
* which is a multiple of 4kb.
|
||||
* which is a multiple of 4kb. The firmware for rt3290 chip also
|
||||
* have a length which is a multiple of 4kb.
|
||||
*/
|
||||
if (rt2x00_is_usb(rt2x00dev)) {
|
||||
if (rt2x00_is_usb(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3290))
|
||||
fw_len = 4096;
|
||||
multiple = true;
|
||||
} else {
|
||||
else
|
||||
fw_len = 8192;
|
||||
multiple = true;
|
||||
}
|
||||
|
||||
multiple = true;
|
||||
/*
|
||||
* Validate the firmware length
|
||||
*/
|
||||
@ -415,7 +414,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
|
||||
return -EBUSY;
|
||||
|
||||
if (rt2x00_is_pci(rt2x00dev)) {
|
||||
if (rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
rt2800_register_read(rt2x00dev, AUX_CTRL, ®);
|
||||
@ -851,8 +851,13 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
|
||||
return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
|
||||
if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
|
||||
return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0);
|
||||
} else {
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
|
||||
return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_rfkill_poll);
|
||||
|
||||
@ -1935,9 +1940,54 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
|
||||
}
|
||||
|
||||
#define RT3290_POWER_BOUND 0x27
|
||||
#define RT3290_FREQ_OFFSET_BOUND 0x5f
|
||||
#define RT5390_POWER_BOUND 0x27
|
||||
#define RT5390_FREQ_OFFSET_BOUND 0x5f
|
||||
|
||||
static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf,
|
||||
struct rf_channel *rf,
|
||||
struct channel_info *info)
|
||||
{
|
||||
u8 rfcsr;
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
|
||||
rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2);
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr);
|
||||
if (info->default_power1 > RT3290_POWER_BOUND)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT3290_POWER_BOUND);
|
||||
else
|
||||
rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
|
||||
if (rt2x00dev->freq_offset > RT3290_FREQ_OFFSET_BOUND)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR17_CODE,
|
||||
RT3290_FREQ_OFFSET_BOUND);
|
||||
else
|
||||
rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
|
||||
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
|
||||
|
||||
if (rf->channel <= 14) {
|
||||
if (rf->channel == 6)
|
||||
rt2800_bbp_write(rt2x00dev, 68, 0x0c);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 68, 0x0b);
|
||||
|
||||
if (rf->channel >= 1 && rf->channel <= 6)
|
||||
rt2800_bbp_write(rt2x00dev, 59, 0x0f);
|
||||
else if (rf->channel >= 7 && rf->channel <= 11)
|
||||
rt2800_bbp_write(rt2x00dev, 59, 0x0e);
|
||||
else if (rf->channel >= 12 && rf->channel <= 14)
|
||||
rt2800_bbp_write(rt2x00dev, 59, 0x0d);
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf,
|
||||
struct rf_channel *rf,
|
||||
@ -2036,15 +2086,6 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
|
||||
}
|
||||
|
||||
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
@ -2054,7 +2095,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
u32 reg;
|
||||
unsigned int tx_pin;
|
||||
u8 bbp;
|
||||
u8 bbp, rfcsr;
|
||||
|
||||
if (rf->channel <= 14) {
|
||||
info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1);
|
||||
@ -2075,6 +2116,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
case RF3052:
|
||||
rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info);
|
||||
break;
|
||||
case RF3290:
|
||||
rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
|
||||
break;
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
case RF5372:
|
||||
@ -2086,6 +2130,22 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
|
||||
}
|
||||
|
||||
if (rt2x00_rf(rt2x00dev, RF3290) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
rt2x00_rf(rt2x00dev, RF5372) ||
|
||||
rt2x00_rf(rt2x00dev, RF5390) ||
|
||||
rt2x00_rf(rt2x00dev, RF5392)) {
|
||||
rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change BBP settings
|
||||
*/
|
||||
@ -2566,6 +2626,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
|
||||
break;
|
||||
case RF3290:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
case RF5372:
|
||||
@ -2701,6 +2762,7 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev)
|
||||
if (rt2x00_rt(rt2x00dev, RT3070) ||
|
||||
rt2x00_rt(rt2x00dev, RT3071) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
@ -2797,10 +2859,54 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_set_field32(®, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
|
||||
rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
|
||||
if (rt2x00_get_field32(reg, WLAN_EN) == 1) {
|
||||
rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 1);
|
||||
rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
|
||||
}
|
||||
|
||||
rt2800_register_read(rt2x00dev, CMB_CTRL, ®);
|
||||
if (!(rt2x00_get_field32(reg, LDO0_EN) == 1)) {
|
||||
rt2x00_set_field32(®, LDO0_EN, 1);
|
||||
rt2x00_set_field32(®, LDO_BGSEL, 3);
|
||||
rt2800_register_write(rt2x00dev, CMB_CTRL, reg);
|
||||
}
|
||||
|
||||
rt2800_register_read(rt2x00dev, OSC_CTRL, ®);
|
||||
rt2x00_set_field32(®, OSC_ROSC_EN, 1);
|
||||
rt2x00_set_field32(®, OSC_CAL_REQ, 1);
|
||||
rt2x00_set_field32(®, OSC_REF_CYCLE, 0x27);
|
||||
rt2800_register_write(rt2x00dev, OSC_CTRL, reg);
|
||||
|
||||
rt2800_register_read(rt2x00dev, COEX_CFG0, ®);
|
||||
rt2x00_set_field32(®, COEX_CFG_ANT, 0x5e);
|
||||
rt2800_register_write(rt2x00dev, COEX_CFG0, reg);
|
||||
|
||||
rt2800_register_read(rt2x00dev, COEX_CFG2, ®);
|
||||
rt2x00_set_field32(®, BT_COEX_CFG1, 0x00);
|
||||
rt2x00_set_field32(®, BT_COEX_CFG0, 0x17);
|
||||
rt2x00_set_field32(®, WL_COEX_CFG1, 0x93);
|
||||
rt2x00_set_field32(®, WL_COEX_CFG0, 0x7f);
|
||||
rt2800_register_write(rt2x00dev, COEX_CFG2, reg);
|
||||
|
||||
rt2800_register_read(rt2x00dev, PLL_CTRL, ®);
|
||||
rt2x00_set_field32(®, PLL_CONTROL, 1);
|
||||
rt2800_register_write(rt2x00dev, PLL_CTRL, reg);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3071) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390)) {
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290))
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0,
|
||||
0x00000404);
|
||||
else
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0,
|
||||
0x00000400);
|
||||
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
|
||||
if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
|
||||
rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
|
||||
@ -3209,14 +3315,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_wait_bbp_ready(rt2x00dev)))
|
||||
return -EACCES;
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
rt2800_bbp_read(rt2x00dev, 4, &value);
|
||||
rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1);
|
||||
rt2800_bbp_write(rt2x00dev, 4, value);
|
||||
}
|
||||
|
||||
if (rt2800_is_305x_soc(rt2x00dev) ||
|
||||
rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
@ -3225,20 +3333,26 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 65, 0x2c);
|
||||
rt2800_bbp_write(rt2x00dev, 66, 0x38);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 68, 0x0b);
|
||||
|
||||
if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
|
||||
rt2800_bbp_write(rt2x00dev, 69, 0x16);
|
||||
rt2800_bbp_write(rt2x00dev, 73, 0x12);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
rt2800_bbp_write(rt2x00dev, 69, 0x12);
|
||||
rt2800_bbp_write(rt2x00dev, 73, 0x13);
|
||||
rt2800_bbp_write(rt2x00dev, 75, 0x46);
|
||||
rt2800_bbp_write(rt2x00dev, 76, 0x28);
|
||||
rt2800_bbp_write(rt2x00dev, 77, 0x59);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290))
|
||||
rt2800_bbp_write(rt2x00dev, 77, 0x58);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 77, 0x59);
|
||||
} else {
|
||||
rt2800_bbp_write(rt2x00dev, 69, 0x12);
|
||||
rt2800_bbp_write(rt2x00dev, 73, 0x10);
|
||||
@ -3263,23 +3377,33 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 81, 0x37);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
rt2800_bbp_write(rt2x00dev, 74, 0x0b);
|
||||
rt2800_bbp_write(rt2x00dev, 79, 0x18);
|
||||
rt2800_bbp_write(rt2x00dev, 80, 0x09);
|
||||
rt2800_bbp_write(rt2x00dev, 81, 0x33);
|
||||
}
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 82, 0x62);
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 83, 0x7a);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 83, 0x6a);
|
||||
|
||||
if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
|
||||
rt2800_bbp_write(rt2x00dev, 84, 0x19);
|
||||
else if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
else if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 84, 0x9a);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 84, 0x99);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 86, 0x38);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 86, 0x00);
|
||||
@ -3289,8 +3413,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 91, 0x04);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 92, 0x02);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 92, 0x00);
|
||||
@ -3304,6 +3429,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
|
||||
rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392) ||
|
||||
@ -3312,27 +3438,32 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 103, 0x00);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 104, 0x92);
|
||||
|
||||
if (rt2800_is_305x_soc(rt2x00dev))
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x01);
|
||||
else if (rt2x00_rt(rt2x00dev, RT3290))
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x1c);
|
||||
else if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x3c);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x05);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390))
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390))
|
||||
rt2800_bbp_write(rt2x00dev, 106, 0x03);
|
||||
else if (rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 106, 0x12);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 106, 0x35);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 128, 0x12);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
@ -3357,6 +3488,29 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 138, value);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
rt2800_bbp_write(rt2x00dev, 67, 0x24);
|
||||
rt2800_bbp_write(rt2x00dev, 143, 0x04);
|
||||
rt2800_bbp_write(rt2x00dev, 142, 0x99);
|
||||
rt2800_bbp_write(rt2x00dev, 150, 0x30);
|
||||
rt2800_bbp_write(rt2x00dev, 151, 0x2e);
|
||||
rt2800_bbp_write(rt2x00dev, 152, 0x20);
|
||||
rt2800_bbp_write(rt2x00dev, 153, 0x34);
|
||||
rt2800_bbp_write(rt2x00dev, 154, 0x40);
|
||||
rt2800_bbp_write(rt2x00dev, 155, 0x3b);
|
||||
rt2800_bbp_write(rt2x00dev, 253, 0x04);
|
||||
|
||||
rt2800_bbp_read(rt2x00dev, 47, &value);
|
||||
rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
|
||||
rt2800_bbp_write(rt2x00dev, 47, value);
|
||||
|
||||
/* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
|
||||
rt2800_bbp_read(rt2x00dev, 3, &value);
|
||||
rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
|
||||
rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
|
||||
rt2800_bbp_write(rt2x00dev, 3, value);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
int ant, div_mode;
|
||||
@ -3489,6 +3643,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
if (!rt2x00_rt(rt2x00dev, RT3070) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3071) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3090) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3290) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3390) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3572) &&
|
||||
!rt2x00_rt(rt2x00dev, RT5390) &&
|
||||
@ -3499,8 +3654,9 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
/*
|
||||
* Init RF calibration.
|
||||
*/
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 2, rfcsr);
|
||||
@ -3538,6 +3694,53 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 24, 0x16);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x01);
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x1f);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
|
||||
rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 6, 0xa0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 8, 0xf3);
|
||||
rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
|
||||
rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
|
||||
rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
|
||||
rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 18, 0x02);
|
||||
rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x83);
|
||||
rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
|
||||
rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
|
||||
rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
|
||||
rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 34, 0x05);
|
||||
rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
|
||||
rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
|
||||
rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
|
||||
rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
|
||||
rt2800_rfcsr_write(rt2x00dev, 43, 0x7b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
|
||||
rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
|
||||
rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
|
||||
rt2800_rfcsr_write(rt2x00dev, 47, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
|
||||
rt2800_rfcsr_write(rt2x00dev, 49, 0x98);
|
||||
rt2800_rfcsr_write(rt2x00dev, 52, 0x38);
|
||||
rt2800_rfcsr_write(rt2x00dev, 53, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
|
||||
rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
|
||||
rt2800_rfcsr_write(rt2x00dev, 56, 0x02);
|
||||
rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 59, 0x09);
|
||||
rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0xc1);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3390)) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 0, 0xa0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, 0xe1);
|
||||
@ -3946,6 +4149,12 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 27, rfcsr);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3);
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, rfcsr);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
|
||||
@ -4052,9 +4261,14 @@ EXPORT_SYMBOL_GPL(rt2800_disable_radio);
|
||||
int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
u32 reg;
|
||||
u16 efuse_ctrl_reg;
|
||||
|
||||
rt2800_register_read(rt2x00dev, EFUSE_CTRL, ®);
|
||||
if (rt2x00_rt(rt2x00dev, RT3290))
|
||||
efuse_ctrl_reg = EFUSE_CTRL_3290;
|
||||
else
|
||||
efuse_ctrl_reg = EFUSE_CTRL;
|
||||
|
||||
rt2800_register_read(rt2x00dev, efuse_ctrl_reg, ®);
|
||||
return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
|
||||
@ -4062,27 +4276,44 @@ EXPORT_SYMBOL_GPL(rt2800_efuse_detect);
|
||||
static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
|
||||
{
|
||||
u32 reg;
|
||||
u16 efuse_ctrl_reg;
|
||||
u16 efuse_data0_reg;
|
||||
u16 efuse_data1_reg;
|
||||
u16 efuse_data2_reg;
|
||||
u16 efuse_data3_reg;
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
efuse_ctrl_reg = EFUSE_CTRL_3290;
|
||||
efuse_data0_reg = EFUSE_DATA0_3290;
|
||||
efuse_data1_reg = EFUSE_DATA1_3290;
|
||||
efuse_data2_reg = EFUSE_DATA2_3290;
|
||||
efuse_data3_reg = EFUSE_DATA3_3290;
|
||||
} else {
|
||||
efuse_ctrl_reg = EFUSE_CTRL;
|
||||
efuse_data0_reg = EFUSE_DATA0;
|
||||
efuse_data1_reg = EFUSE_DATA1;
|
||||
efuse_data2_reg = EFUSE_DATA2;
|
||||
efuse_data3_reg = EFUSE_DATA3;
|
||||
}
|
||||
mutex_lock(&rt2x00dev->csr_mutex);
|
||||
|
||||
rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, ®);
|
||||
rt2800_register_read_lock(rt2x00dev, efuse_ctrl_reg, ®);
|
||||
rt2x00_set_field32(®, EFUSE_CTRL_ADDRESS_IN, i);
|
||||
rt2x00_set_field32(®, EFUSE_CTRL_MODE, 0);
|
||||
rt2x00_set_field32(®, EFUSE_CTRL_KICK, 1);
|
||||
rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg);
|
||||
rt2800_register_write_lock(rt2x00dev, efuse_ctrl_reg, reg);
|
||||
|
||||
/* Wait until the EEPROM has been loaded */
|
||||
rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®);
|
||||
|
||||
rt2800_regbusy_read(rt2x00dev, efuse_ctrl_reg, EFUSE_CTRL_KICK, ®);
|
||||
/* Apparently the data is read from end to start */
|
||||
rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®);
|
||||
rt2800_register_read_lock(rt2x00dev, efuse_data3_reg, ®);
|
||||
/* The returned value is in CPU order, but eeprom is le */
|
||||
*(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg);
|
||||
rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®);
|
||||
rt2800_register_read_lock(rt2x00dev, efuse_data2_reg, ®);
|
||||
*(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
|
||||
rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®);
|
||||
rt2800_register_read_lock(rt2x00dev, efuse_data1_reg, ®);
|
||||
*(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg);
|
||||
rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, ®);
|
||||
rt2800_register_read_lock(rt2x00dev, efuse_data0_reg, ®);
|
||||
*(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg);
|
||||
|
||||
mutex_unlock(&rt2x00dev->csr_mutex);
|
||||
@ -4244,9 +4475,14 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
* RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field
|
||||
* RT53xx: defined in "EEPROM_CHIP_ID" field
|
||||
*/
|
||||
rt2800_register_read(rt2x00dev, MAC_CSR0, ®);
|
||||
if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
|
||||
rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
|
||||
if (rt2x00_rt(rt2x00dev, RT3290))
|
||||
rt2800_register_read(rt2x00dev, MAC_CSR0_3290, ®);
|
||||
else
|
||||
rt2800_register_read(rt2x00dev, MAC_CSR0, ®);
|
||||
|
||||
if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT3290 ||
|
||||
rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 ||
|
||||
rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392)
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value);
|
||||
else
|
||||
value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
|
||||
@ -4261,6 +4497,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
case RT3070:
|
||||
case RT3071:
|
||||
case RT3090:
|
||||
case RT3290:
|
||||
case RT3390:
|
||||
case RT3572:
|
||||
case RT5390:
|
||||
@ -4281,6 +4518,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
case RF3021:
|
||||
case RF3022:
|
||||
case RF3052:
|
||||
case RF3290:
|
||||
case RF3320:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
@ -4597,6 +4835,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_rf(rt2x00dev, RF2020) ||
|
||||
rt2x00_rf(rt2x00dev, RF3021) ||
|
||||
rt2x00_rf(rt2x00dev, RF3022) ||
|
||||
rt2x00_rf(rt2x00dev, RF3290) ||
|
||||
rt2x00_rf(rt2x00dev, RF3320) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
@ -4685,6 +4924,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
case RF3022:
|
||||
case RF3320:
|
||||
case RF3052:
|
||||
case RF3290:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
case RF5372:
|
||||
|
@ -280,7 +280,13 @@ static void rt2800pci_stop_queue(struct data_queue *queue)
|
||||
*/
|
||||
static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
return FIRMWARE_RT2860;
|
||||
/*
|
||||
* Chip rt3290 use specific 4KB firmware named rt3290.bin.
|
||||
*/
|
||||
if (rt2x00_rt(rt2x00dev, RT3290))
|
||||
return FIRMWARE_RT3290;
|
||||
else
|
||||
return FIRMWARE_RT2860;
|
||||
}
|
||||
|
||||
static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
|
||||
@ -974,6 +980,66 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
return rt2800_validate_eeprom(rt2x00dev);
|
||||
}
|
||||
|
||||
static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
u32 reg;
|
||||
int i, count;
|
||||
|
||||
rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
|
||||
if ((rt2x00_get_field32(reg, WLAN_EN) == 1))
|
||||
return 0;
|
||||
|
||||
rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff);
|
||||
rt2x00_set_field32(®, FRC_WL_ANT_SET, 1);
|
||||
rt2x00_set_field32(®, WLAN_CLK_EN, 0);
|
||||
rt2x00_set_field32(®, WLAN_EN, 1);
|
||||
rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
|
||||
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
/*
|
||||
* Check PLL_LD & XTAL_RDY.
|
||||
*/
|
||||
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
||||
rt2800_register_read(rt2x00dev, CMB_CTRL, ®);
|
||||
if ((rt2x00_get_field32(reg, PLL_LD) == 1) &&
|
||||
(rt2x00_get_field32(reg, XTAL_RDY) == 1))
|
||||
break;
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
}
|
||||
|
||||
if (i >= REGISTER_BUSY_COUNT) {
|
||||
|
||||
if (count >= 10)
|
||||
return -EIO;
|
||||
|
||||
rt2800_register_write(rt2x00dev, 0x58, 0x018);
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
rt2800_register_write(rt2x00dev, 0x58, 0x418);
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
rt2800_register_write(rt2x00dev, 0x58, 0x618);
|
||||
udelay(REGISTER_BUSY_DELAY);
|
||||
count++;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
|
||||
rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0);
|
||||
rt2x00_set_field32(®, WLAN_CLK_EN, 1);
|
||||
rt2x00_set_field32(®, WLAN_RESET, 1);
|
||||
rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
|
||||
udelay(10);
|
||||
rt2x00_set_field32(®, WLAN_RESET, 0);
|
||||
rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg);
|
||||
udelay(10);
|
||||
rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff);
|
||||
} while (count != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
@ -996,6 +1062,17 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* In probe phase call rt2800_enable_wlan_rt3290 to enable wlan
|
||||
* clk for rt3290. That avoid the MCU fail in start phase.
|
||||
*/
|
||||
if (rt2x00_rt(rt2x00dev, RT3290)) {
|
||||
retval = rt2800_enable_wlan_rt3290(rt2x00dev);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* This device has multiple filters for control frames
|
||||
* and has a separate filter for PS Poll frames.
|
||||
@ -1175,6 +1252,9 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
|
||||
{ PCI_DEVICE(0x1432, 0x7768) },
|
||||
{ PCI_DEVICE(0x1462, 0x891a) },
|
||||
{ PCI_DEVICE(0x1a3b, 0x1059) },
|
||||
#ifdef CONFIG_RT2800PCI_RT3290
|
||||
{ PCI_DEVICE(0x1814, 0x3290) },
|
||||
#endif
|
||||
#ifdef CONFIG_RT2800PCI_RT33XX
|
||||
{ PCI_DEVICE(0x1814, 0x3390) },
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@
|
||||
* 8051 firmware image.
|
||||
*/
|
||||
#define FIRMWARE_RT2860 "rt2860.bin"
|
||||
#define FIRMWARE_RT3290 "rt3290.bin"
|
||||
#define FIRMWARE_IMAGE_BASE 0x2000
|
||||
|
||||
/*
|
||||
|
@ -971,6 +971,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
||||
{ USB_DEVICE(0x0411, 0x015d) },
|
||||
{ USB_DEVICE(0x0411, 0x016f) },
|
||||
{ USB_DEVICE(0x0411, 0x01a2) },
|
||||
{ USB_DEVICE(0x0411, 0x01ee) },
|
||||
/* Corega */
|
||||
{ USB_DEVICE(0x07aa, 0x002f) },
|
||||
{ USB_DEVICE(0x07aa, 0x003c) },
|
||||
|
@ -187,6 +187,7 @@ struct rt2x00_chip {
|
||||
#define RT3070 0x3070
|
||||
#define RT3071 0x3071
|
||||
#define RT3090 0x3090 /* 2.4GHz PCIe */
|
||||
#define RT3290 0x3290
|
||||
#define RT3390 0x3390
|
||||
#define RT3572 0x3572
|
||||
#define RT3593 0x3593
|
||||
|
@ -256,6 +256,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
|
||||
struct ieee80211_hw *hw;
|
||||
struct rt2x00_dev *rt2x00dev;
|
||||
int retval;
|
||||
u16 chip;
|
||||
|
||||
retval = pci_enable_device(pci_dev);
|
||||
if (retval) {
|
||||
@ -305,6 +306,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
|
||||
if (retval)
|
||||
goto exit_free_device;
|
||||
|
||||
/*
|
||||
* Because rt3290 chip use different efuse offset to read efuse data.
|
||||
* So before read efuse it need to indicate it is the
|
||||
* rt3290 or not.
|
||||
*/
|
||||
pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
|
||||
rt2x00dev->chip.rt = chip;
|
||||
|
||||
retval = rt2x00lib_probe_dev(rt2x00dev);
|
||||
if (retval)
|
||||
goto exit_free_reg;
|
||||
|
@ -47,6 +47,8 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = {
|
||||
{ PCI_DEVICE(0x1799, 0x6001) },
|
||||
{ PCI_DEVICE(0x1799, 0x6020) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) },
|
||||
{ PCI_DEVICE(0x1186, 0x3301) },
|
||||
{ PCI_DEVICE(0x1432, 0x7106) },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -128,7 +128,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
|
||||
u32 us_config;
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||
"EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n",
|
||||
ul_entry_idx, ul_key_id, ul_enc_alg,
|
||||
ul_default_key, mac_addr);
|
||||
@ -342,7 +342,8 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
|
||||
/* Remove from HW Security CAM */
|
||||
memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN);
|
||||
rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
|
||||
pr_info("&&&&&&&&&del entry %d\n", i);
|
||||
RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
|
||||
"del CAM entry %d\n", i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -1273,17 +1273,18 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
|
||||
*after reset, release previous pending packet,
|
||||
*and force the tx idx to the first one
|
||||
*/
|
||||
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
|
||||
for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) {
|
||||
if (rtlpci->tx_ring[i].desc) {
|
||||
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i];
|
||||
|
||||
while (skb_queue_len(&ring->queue)) {
|
||||
struct rtl_tx_desc *entry =
|
||||
&ring->desc[ring->idx];
|
||||
struct sk_buff *skb =
|
||||
__skb_dequeue(&ring->queue);
|
||||
struct rtl_tx_desc *entry;
|
||||
struct sk_buff *skb;
|
||||
|
||||
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock,
|
||||
flags);
|
||||
entry = &ring->desc[ring->idx];
|
||||
skb = __skb_dequeue(&ring->queue);
|
||||
pci_unmap_single(rtlpci->pdev,
|
||||
rtlpriv->cfg->ops->
|
||||
get_desc((u8 *)
|
||||
@ -1291,15 +1292,15 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
|
||||
true,
|
||||
HW_DESC_TXBUFF_ADDR),
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
kfree_skb(skb);
|
||||
ring->idx = (ring->idx + 1) % ring->entries;
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
|
||||
flags);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
ring->idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1247,6 +1247,9 @@ static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
|
||||
/* Read HT 40 OFDM TX power */
|
||||
ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
|
||||
ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
|
||||
} else {
|
||||
ofdmpowerLevel[0] = 0;
|
||||
ofdmpowerLevel[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "../wifi.h"
|
||||
#include "../core.h"
|
||||
#include "../pci.h"
|
||||
#include "../base.h"
|
||||
#include "../pci.h"
|
||||
#include "reg.h"
|
||||
|
@ -277,15 +277,6 @@ int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
|
||||
join->rx_config_options = wl->rx_config;
|
||||
join->rx_filter_options = wl->rx_filter;
|
||||
|
||||
/*
|
||||
* FIXME: disable temporarily all filters because after commit
|
||||
* 9cef8737 "mac80211: fix managed mode BSSID handling" broke
|
||||
* association. The filter logic needs to be implemented properly
|
||||
* and once that is done, this hack can be removed.
|
||||
*/
|
||||
join->rx_config_options = 0;
|
||||
join->rx_filter_options = WL1251_DEFAULT_RX_FILTER;
|
||||
|
||||
join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
|
||||
RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
|
||||
|
||||
|
@ -334,6 +334,12 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Join command applies filters, and if we are not associated,
|
||||
* BSSID filter must be disabled for association to work.
|
||||
*/
|
||||
if (is_zero_ether_addr(wl->bssid))
|
||||
wl->rx_config &= ~CFG_BSSID_FILTER_EN;
|
||||
|
||||
ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval,
|
||||
dtim_period);
|
||||
@ -348,33 +354,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl1251_filter_work(struct work_struct *work)
|
||||
{
|
||||
struct wl1251 *wl =
|
||||
container_of(work, struct wl1251, filter_work);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
if (wl->state == WL1251_STATE_OFF)
|
||||
goto out;
|
||||
|
||||
ret = wl1251_ps_elp_wakeup(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int,
|
||||
wl->dtim_period);
|
||||
if (ret < 0)
|
||||
goto out_sleep;
|
||||
|
||||
out_sleep:
|
||||
wl1251_ps_elp_sleep(wl);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
static void wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct wl1251 *wl = hw->priv;
|
||||
@ -478,7 +457,6 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
|
||||
|
||||
cancel_work_sync(&wl->irq_work);
|
||||
cancel_work_sync(&wl->tx_work);
|
||||
cancel_work_sync(&wl->filter_work);
|
||||
cancel_delayed_work_sync(&wl->elp_work);
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
@ -681,13 +659,15 @@ out:
|
||||
FIF_FCSFAIL | \
|
||||
FIF_BCN_PRBRESP_PROMISC | \
|
||||
FIF_CONTROL | \
|
||||
FIF_OTHER_BSS)
|
||||
FIF_OTHER_BSS | \
|
||||
FIF_PROBE_REQ)
|
||||
|
||||
static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
|
||||
unsigned int changed,
|
||||
unsigned int *total,u64 multicast)
|
||||
{
|
||||
struct wl1251 *wl = hw->priv;
|
||||
int ret;
|
||||
|
||||
wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter");
|
||||
|
||||
@ -698,7 +678,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
|
||||
/* no filters which we support changed */
|
||||
return;
|
||||
|
||||
/* FIXME: wl->rx_config and wl->rx_filter are not protected */
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
|
||||
wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
|
||||
@ -721,15 +701,25 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
|
||||
}
|
||||
if (*total & FIF_CONTROL)
|
||||
wl->rx_filter |= CFG_RX_CTL_EN;
|
||||
if (*total & FIF_OTHER_BSS)
|
||||
wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
|
||||
if (*total & FIF_OTHER_BSS || is_zero_ether_addr(wl->bssid))
|
||||
wl->rx_config &= ~CFG_BSSID_FILTER_EN;
|
||||
if (*total & FIF_PROBE_REQ)
|
||||
wl->rx_filter |= CFG_RX_PREQ_EN;
|
||||
|
||||
/*
|
||||
* FIXME: workqueues need to be properly cancelled on stop(), for
|
||||
* now let's just disable changing the filter settings. They will
|
||||
* be updated any on config().
|
||||
*/
|
||||
/* schedule_work(&wl->filter_work); */
|
||||
if (wl->state == WL1251_STATE_OFF)
|
||||
goto out;
|
||||
|
||||
ret = wl1251_ps_elp_wakeup(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* send filters to firmware */
|
||||
wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
|
||||
|
||||
wl1251_ps_elp_sleep(wl);
|
||||
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
/* HW encryption */
|
||||
@ -1390,7 +1380,6 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
|
||||
|
||||
skb_queue_head_init(&wl->tx_queue);
|
||||
|
||||
INIT_WORK(&wl->filter_work, wl1251_filter_work);
|
||||
INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
|
||||
wl->channel = WL1251_DEFAULT_CHANNEL;
|
||||
wl->scanning = false;
|
||||
|
@ -315,7 +315,6 @@ struct wl1251 {
|
||||
bool tx_queue_stopped;
|
||||
|
||||
struct work_struct tx_work;
|
||||
struct work_struct filter_work;
|
||||
|
||||
/* Pending TX frames */
|
||||
struct sk_buff *tx_frames[16];
|
||||
|
@ -174,7 +174,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
|
||||
struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
|
||||
struct wl1271_radio_parms_cmd *radio_parms;
|
||||
struct wl1271_ini_general_params *gp = &nvs->general_params;
|
||||
int ret;
|
||||
int ret, fem_idx;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
@ -185,11 +185,13 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
|
||||
|
||||
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
|
||||
|
||||
fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer);
|
||||
|
||||
/* 2.4GHz parameters */
|
||||
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
|
||||
sizeof(struct wl1271_ini_band_params_2));
|
||||
memcpy(&radio_parms->dyn_params_2,
|
||||
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
|
||||
&nvs->dyn_radio_params_2[fem_idx].params,
|
||||
sizeof(struct wl1271_ini_fem_params_2));
|
||||
|
||||
/* 5GHz parameters */
|
||||
@ -197,7 +199,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl)
|
||||
&nvs->stat_radio_params_5,
|
||||
sizeof(struct wl1271_ini_band_params_5));
|
||||
memcpy(&radio_parms->dyn_params_5,
|
||||
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
|
||||
&nvs->dyn_radio_params_5[fem_idx].params,
|
||||
sizeof(struct wl1271_ini_fem_params_5));
|
||||
|
||||
wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
|
||||
@ -216,7 +218,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl)
|
||||
struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
|
||||
struct wl128x_radio_parms_cmd *radio_parms;
|
||||
struct wl128x_ini_general_params *gp = &nvs->general_params;
|
||||
int ret;
|
||||
int ret, fem_idx;
|
||||
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
@ -227,11 +229,13 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl)
|
||||
|
||||
radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
|
||||
|
||||
fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer);
|
||||
|
||||
/* 2.4GHz parameters */
|
||||
memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
|
||||
sizeof(struct wl128x_ini_band_params_2));
|
||||
memcpy(&radio_parms->dyn_params_2,
|
||||
&nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
|
||||
&nvs->dyn_radio_params_2[fem_idx].params,
|
||||
sizeof(struct wl128x_ini_fem_params_2));
|
||||
|
||||
/* 5GHz parameters */
|
||||
@ -239,7 +243,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl)
|
||||
&nvs->stat_radio_params_5,
|
||||
sizeof(struct wl128x_ini_band_params_5));
|
||||
memcpy(&radio_parms->dyn_params_5,
|
||||
&nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
|
||||
&nvs->dyn_radio_params_5[fem_idx].params,
|
||||
sizeof(struct wl128x_ini_fem_params_5));
|
||||
|
||||
radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
|
||||
|
@ -246,6 +246,7 @@ static struct wlcore_conf wl12xx_conf = {
|
||||
.forced_ps = false,
|
||||
.keep_alive_interval = 55000,
|
||||
.max_listen_interval = 20,
|
||||
.sta_sleep_auth = WL1271_PSM_ILLEGAL,
|
||||
},
|
||||
.itrim = {
|
||||
.enable = false,
|
||||
@ -597,8 +598,10 @@ static const int wl12xx_rtable[REG_TABLE_LEN] = {
|
||||
#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
|
||||
#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
|
||||
|
||||
static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
|
||||
static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (wl->chip.id != CHIP_ID_1283_PG20) {
|
||||
struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
|
||||
struct wl127x_rx_mem_pool_addr rx_mem_addr;
|
||||
@ -615,9 +618,13 @@ static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
|
||||
|
||||
rx_mem_addr.addr_extra = rx_mem_addr.addr + 4;
|
||||
|
||||
wl1271_write(wl, WL1271_SLV_REG_DATA,
|
||||
&rx_mem_addr, sizeof(rx_mem_addr), false);
|
||||
ret = wlcore_write(wl, WL1271_SLV_REG_DATA, &rx_mem_addr,
|
||||
sizeof(rx_mem_addr), false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wl12xx_identify_chip(struct wl1271 *wl)
|
||||
@ -681,64 +688,95 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
|
||||
static int __must_check wl12xx_top_reg_write(struct wl1271 *wl, int addr,
|
||||
u16 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* write address >> 1 + 0x30000 to OCP_POR_CTR */
|
||||
addr = (addr >> 1) + 0x30000;
|
||||
wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
|
||||
ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* write value to OCP_POR_WDATA */
|
||||
wl1271_write32(wl, WL12XX_OCP_DATA_WRITE, val);
|
||||
ret = wlcore_write32(wl, WL12XX_OCP_DATA_WRITE, val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* write 1 to OCP_CMD */
|
||||
wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
|
||||
ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr)
|
||||
static int __must_check wl12xx_top_reg_read(struct wl1271 *wl, int addr,
|
||||
u16 *out)
|
||||
{
|
||||
u32 val;
|
||||
int timeout = OCP_CMD_LOOP;
|
||||
int ret;
|
||||
|
||||
/* write address >> 1 + 0x30000 to OCP_POR_CTR */
|
||||
addr = (addr >> 1) + 0x30000;
|
||||
wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
|
||||
ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* write 2 to OCP_CMD */
|
||||
wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
|
||||
ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* poll for data ready */
|
||||
do {
|
||||
val = wl1271_read32(wl, WL12XX_OCP_DATA_READ);
|
||||
ret = wlcore_read32(wl, WL12XX_OCP_DATA_READ, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} while (!(val & OCP_READY_MASK) && --timeout);
|
||||
|
||||
if (!timeout) {
|
||||
wl1271_warning("Top register access timed out.");
|
||||
return 0xffff;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* check data status and return if OK */
|
||||
if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
|
||||
return val & 0xffff;
|
||||
else {
|
||||
if ((val & OCP_STATUS_MASK) != OCP_STATUS_OK) {
|
||||
wl1271_warning("Top register access returned error.");
|
||||
return 0xffff;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (out)
|
||||
*out = val & 0xffff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
|
||||
{
|
||||
u16 spare_reg;
|
||||
int ret;
|
||||
|
||||
/* Mask bits [2] & [8:4] in the sys_clk_cfg register */
|
||||
spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
|
||||
ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (spare_reg == 0xFFFF)
|
||||
return -EFAULT;
|
||||
spare_reg |= (BIT(3) | BIT(5) | BIT(6));
|
||||
wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
|
||||
ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
|
||||
wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
|
||||
WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
|
||||
ret = wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
|
||||
WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Delay execution for 15msec, to let the HW settle */
|
||||
mdelay(15);
|
||||
@ -749,8 +787,12 @@ static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
|
||||
static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
|
||||
{
|
||||
u16 tcxo_detection;
|
||||
int ret;
|
||||
|
||||
ret = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG, &tcxo_detection);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
tcxo_detection = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG);
|
||||
if (tcxo_detection & TCXO_DET_FAILED)
|
||||
return false;
|
||||
|
||||
@ -760,8 +802,12 @@ static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
|
||||
static bool wl128x_is_fref_valid(struct wl1271 *wl)
|
||||
{
|
||||
u16 fref_detection;
|
||||
int ret;
|
||||
|
||||
ret = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG, &fref_detection);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
fref_detection = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG);
|
||||
if (fref_detection & FREF_CLK_DETECT_FAIL)
|
||||
return false;
|
||||
|
||||
@ -770,11 +816,21 @@ static bool wl128x_is_fref_valid(struct wl1271 *wl)
|
||||
|
||||
static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
|
||||
{
|
||||
wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
|
||||
wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
|
||||
wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
|
||||
int ret;
|
||||
|
||||
return 0;
|
||||
ret = wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG,
|
||||
MCS_PLL_CONFIG_REG_VAL);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
|
||||
@ -783,13 +839,19 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
|
||||
u16 pll_config;
|
||||
u8 input_freq;
|
||||
struct wl12xx_priv *priv = wl->priv;
|
||||
int ret;
|
||||
|
||||
/* Mask bits [3:1] in the sys_clk_cfg register */
|
||||
spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
|
||||
ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (spare_reg == 0xFFFF)
|
||||
return -EFAULT;
|
||||
spare_reg |= BIT(2);
|
||||
wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
|
||||
ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Handle special cases of the TCXO clock */
|
||||
if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
|
||||
@ -799,14 +861,17 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
|
||||
/* Set the input frequency according to the selected clock source */
|
||||
input_freq = (clk & 1) + 1;
|
||||
|
||||
pll_config = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG);
|
||||
ret = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG, &pll_config);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (pll_config == 0xFFFF)
|
||||
return -EFAULT;
|
||||
pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
|
||||
pll_config |= MCS_PLL_ENABLE_HP;
|
||||
wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
|
||||
ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -820,6 +885,7 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
|
||||
{
|
||||
struct wl12xx_priv *priv = wl->priv;
|
||||
u16 sys_clk_cfg;
|
||||
int ret;
|
||||
|
||||
/* For XTAL-only modes, FREF will be used after switching from TCXO */
|
||||
if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
|
||||
@ -830,7 +896,10 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
|
||||
}
|
||||
|
||||
/* Query the HW, to determine which clock source we should use */
|
||||
sys_clk_cfg = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG);
|
||||
ret = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG, &sys_clk_cfg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (sys_clk_cfg == 0xFFFF)
|
||||
return -EINVAL;
|
||||
if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
|
||||
@ -865,6 +934,7 @@ static int wl127x_boot_clk(struct wl1271 *wl)
|
||||
struct wl12xx_priv *priv = wl->priv;
|
||||
u32 pause;
|
||||
u32 clk;
|
||||
int ret;
|
||||
|
||||
if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
|
||||
wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
|
||||
@ -885,48 +955,74 @@ static int wl127x_boot_clk(struct wl1271 *wl)
|
||||
if (priv->ref_clock != CONF_REF_CLK_19_2_E) {
|
||||
u16 val;
|
||||
/* Set clock type (open drain) */
|
||||
val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE);
|
||||
ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE, &val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
val &= FREF_CLK_TYPE_BITS;
|
||||
wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
|
||||
ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Set clock pull mode (no pull) */
|
||||
val = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL);
|
||||
ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
val |= NO_PULL;
|
||||
wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
|
||||
ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
} else {
|
||||
u16 val;
|
||||
/* Set clock polarity */
|
||||
val = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY);
|
||||
ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY, &val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
val &= FREF_CLK_POLARITY_BITS;
|
||||
val |= CLK_REQ_OUTN_SEL;
|
||||
wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
|
||||
ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk);
|
||||
ret = wlcore_write32(wl, WL12XX_PLL_PARAMETERS, clk);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
pause = wl1271_read32(wl, WL12XX_PLL_PARAMETERS);
|
||||
ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
|
||||
|
||||
pause &= ~(WU_COUNTER_PAUSE_VAL);
|
||||
pause |= WU_COUNTER_PAUSE_VAL;
|
||||
wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
|
||||
ret = wlcore_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl1271_boot_soft_reset(struct wl1271 *wl)
|
||||
{
|
||||
unsigned long timeout;
|
||||
u32 boot_data;
|
||||
int ret = 0;
|
||||
|
||||
/* perform soft reset */
|
||||
wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
|
||||
ret = wlcore_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* SOFT_RESET is self clearing */
|
||||
timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
|
||||
while (1) {
|
||||
boot_data = wl1271_read32(wl, WL12XX_SLV_SOFT_RESET);
|
||||
ret = wlcore_read32(wl, WL12XX_SLV_SOFT_RESET, &boot_data);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
|
||||
if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
|
||||
break;
|
||||
@ -942,12 +1038,15 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl)
|
||||
}
|
||||
|
||||
/* disable Rx/Tx */
|
||||
wl1271_write32(wl, WL12XX_ENABLE, 0x0);
|
||||
ret = wlcore_write32(wl, WL12XX_ENABLE, 0x0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* disable auto calibration on start*/
|
||||
wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff);
|
||||
ret = wlcore_write32(wl, WL12XX_SPARE_A2, 0xffff);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl12xx_pre_boot(struct wl1271 *wl)
|
||||
@ -968,16 +1067,23 @@ static int wl12xx_pre_boot(struct wl1271 *wl)
|
||||
}
|
||||
|
||||
/* Continue the ELP wake up sequence */
|
||||
wl1271_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
|
||||
ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
udelay(500);
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Read-modify-write DRPW_SCRATCH_START register (see next state)
|
||||
to be used by DRPw FW. The RTRIM value will be added by the FW
|
||||
before taking DRPw out of reset */
|
||||
|
||||
clk = wl1271_read32(wl, WL12XX_DRPW_SCRATCH_START);
|
||||
ret = wlcore_read32(wl, WL12XX_DRPW_SCRATCH_START, &clk);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
|
||||
|
||||
@ -986,12 +1092,18 @@ static int wl12xx_pre_boot(struct wl1271 *wl)
|
||||
else
|
||||
clk |= (priv->ref_clock << 1) << 4;
|
||||
|
||||
wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
|
||||
ret = wlcore_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Disable interrupts */
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
|
||||
ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wl1271_boot_soft_reset(wl);
|
||||
if (ret < 0)
|
||||
@ -1001,47 +1113,72 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl12xx_pre_upload(struct wl1271 *wl)
|
||||
static int wl12xx_pre_upload(struct wl1271 *wl)
|
||||
{
|
||||
u32 tmp, polarity;
|
||||
u32 tmp;
|
||||
u16 polarity;
|
||||
int ret;
|
||||
|
||||
/* write firmware's last address (ie. it's length) to
|
||||
* ACX_EEPROMLESS_IND_REG */
|
||||
wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
|
||||
|
||||
wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
|
||||
ret = wlcore_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
tmp = wlcore_read_reg(wl, REG_CHIP_ID_B);
|
||||
ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
|
||||
|
||||
/* 6. read the EEPROM parameters */
|
||||
tmp = wl1271_read32(wl, WL12XX_SCR_PAD2);
|
||||
ret = wlcore_read32(wl, WL12XX_SCR_PAD2, &tmp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* WL1271: The reference driver skips steps 7 to 10 (jumps directly
|
||||
* to upload_fw) */
|
||||
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20)
|
||||
wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20) {
|
||||
ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* polarity must be set before the firmware is loaded */
|
||||
polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY);
|
||||
ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* We use HIGH polarity, so unset the LOW bit */
|
||||
polarity &= ~POLARITY_LOW;
|
||||
wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
|
||||
ret = wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl12xx_enable_interrupts(struct wl1271 *wl)
|
||||
static int wl12xx_enable_interrupts(struct wl1271 *wl)
|
||||
{
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL12XX_ACX_ALL_EVENTS_VECTOR);
|
||||
int ret;
|
||||
|
||||
ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
|
||||
WL12XX_ACX_ALL_EVENTS_VECTOR);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wlcore_enable_interrupts(wl);
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_MASK,
|
||||
WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
|
||||
ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
|
||||
WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
|
||||
ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl12xx_boot(struct wl1271 *wl)
|
||||
@ -1056,7 +1193,9 @@ static int wl12xx_boot(struct wl1271 *wl)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl12xx_pre_upload(wl);
|
||||
ret = wl12xx_pre_upload(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wlcore_boot_upload_firmware(wl);
|
||||
if (ret < 0)
|
||||
@ -1066,22 +1205,30 @@ static int wl12xx_boot(struct wl1271 *wl)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl12xx_enable_interrupts(wl);
|
||||
ret = wl12xx_enable_interrupts(wl);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
|
||||
static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
wl1271_write(wl, cmd_box_addr, buf, len, false);
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
|
||||
int ret;
|
||||
|
||||
ret = wlcore_write(wl, cmd_box_addr, buf, len, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl12xx_ack_event(struct wl1271 *wl)
|
||||
static int wl12xx_ack_event(struct wl1271 *wl)
|
||||
{
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK);
|
||||
return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
|
||||
WL12XX_INTR_TRIG_EVENT_ACK);
|
||||
}
|
||||
|
||||
static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
|
||||
@ -1161,13 +1308,13 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
|
||||
return data_len - sizeof(*desc) - desc->pad_len;
|
||||
}
|
||||
|
||||
static void wl12xx_tx_delayed_compl(struct wl1271 *wl)
|
||||
static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
|
||||
{
|
||||
if (wl->fw_status_1->tx_results_counter ==
|
||||
(wl->tx_results_count & 0xff))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
wl1271_tx_complete(wl);
|
||||
return wlcore_tx_complete(wl);
|
||||
}
|
||||
|
||||
static int wl12xx_hw_init(struct wl1271 *wl)
|
||||
@ -1268,39 +1415,58 @@ static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
|
||||
return supported;
|
||||
}
|
||||
|
||||
static void wl12xx_get_fuse_mac(struct wl1271 *wl)
|
||||
static int wl12xx_get_fuse_mac(struct wl1271 *wl)
|
||||
{
|
||||
u32 mac1, mac2;
|
||||
int ret;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
|
||||
mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
|
||||
ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2, &mac2);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* these are the two parts of the BD_ADDR */
|
||||
wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
|
||||
((mac1 & 0xff000000) >> 24);
|
||||
wl->fuse_nic_addr = mac1 & 0xffffff;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static s8 wl12xx_get_pg_ver(struct wl1271 *wl)
|
||||
static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
|
||||
{
|
||||
u32 die_info;
|
||||
u16 die_info;
|
||||
int ret;
|
||||
|
||||
if (wl->chip.id == CHIP_ID_1283_PG20)
|
||||
die_info = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
|
||||
ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1,
|
||||
&die_info);
|
||||
else
|
||||
die_info = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
|
||||
ret = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1,
|
||||
&die_info);
|
||||
|
||||
return (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;
|
||||
if (ret >= 0 && ver)
|
||||
*ver = (s8)((die_info & PG_VER_MASK) >> PG_VER_OFFSET);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl12xx_get_mac(struct wl1271 *wl)
|
||||
static int wl12xx_get_mac(struct wl1271 *wl)
|
||||
{
|
||||
if (wl12xx_mac_in_fuse(wl))
|
||||
wl12xx_get_fuse_mac(wl);
|
||||
return wl12xx_get_fuse_mac(wl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wl12xx_set_tx_desc_csum(struct wl1271 *wl,
|
||||
@ -1448,10 +1614,8 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
|
||||
wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
|
||||
wl->fw_status_priv_len = 0;
|
||||
wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics);
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl12xx_ht_cap,
|
||||
sizeof(wl12xx_ht_cap));
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], &wl12xx_ht_cap,
|
||||
sizeof(wl12xx_ht_cap));
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap);
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
|
||||
wl12xx_conf_init(wl);
|
||||
|
||||
if (!fref_param) {
|
||||
|
@ -32,25 +32,21 @@ enum {
|
||||
/* numbers of bits the length field takes (add 1 for the actual number) */
|
||||
#define WL18XX_HOST_IF_LEN_SIZE_FIELD 15
|
||||
|
||||
#define WL18XX_ACX_EVENTS_VECTOR_PG1 (WL1271_ACX_INTR_WATCHDOG | \
|
||||
WL1271_ACX_INTR_INIT_COMPLETE | \
|
||||
WL1271_ACX_INTR_EVENT_A | \
|
||||
WL1271_ACX_INTR_EVENT_B | \
|
||||
WL1271_ACX_INTR_CMD_COMPLETE | \
|
||||
WL1271_ACX_INTR_HW_AVAILABLE | \
|
||||
WL1271_ACX_INTR_DATA)
|
||||
#define WL18XX_ACX_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \
|
||||
WL1271_ACX_INTR_INIT_COMPLETE | \
|
||||
WL1271_ACX_INTR_EVENT_A | \
|
||||
WL1271_ACX_INTR_EVENT_B | \
|
||||
WL1271_ACX_INTR_CMD_COMPLETE | \
|
||||
WL1271_ACX_INTR_HW_AVAILABLE | \
|
||||
WL1271_ACX_INTR_DATA | \
|
||||
WL1271_ACX_SW_INTR_WATCHDOG)
|
||||
|
||||
#define WL18XX_ACX_EVENTS_VECTOR_PG2 (WL18XX_ACX_EVENTS_VECTOR_PG1 | \
|
||||
WL1271_ACX_SW_INTR_WATCHDOG)
|
||||
|
||||
#define WL18XX_INTR_MASK_PG1 (WL1271_ACX_INTR_WATCHDOG | \
|
||||
WL1271_ACX_INTR_EVENT_A | \
|
||||
WL1271_ACX_INTR_EVENT_B | \
|
||||
WL1271_ACX_INTR_HW_AVAILABLE | \
|
||||
WL1271_ACX_INTR_DATA)
|
||||
|
||||
#define WL18XX_INTR_MASK_PG2 (WL18XX_INTR_MASK_PG1 | \
|
||||
WL1271_ACX_SW_INTR_WATCHDOG)
|
||||
#define WL18XX_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \
|
||||
WL1271_ACX_INTR_EVENT_A | \
|
||||
WL1271_ACX_INTR_EVENT_B | \
|
||||
WL1271_ACX_INTR_HW_AVAILABLE | \
|
||||
WL1271_ACX_INTR_DATA | \
|
||||
WL1271_ACX_SW_INTR_WATCHDOG)
|
||||
|
||||
struct wl18xx_acx_host_config_bitmap {
|
||||
struct acx_header header;
|
||||
|
@ -24,37 +24,52 @@
|
||||
|
||||
#include "io.h"
|
||||
|
||||
void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
|
||||
int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
|
||||
{
|
||||
u32 tmp;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(addr % 2))
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
if ((addr % 4) == 0) {
|
||||
tmp = wl1271_read32(wl, addr);
|
||||
ret = wlcore_read32(wl, addr, &tmp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
tmp = (tmp & 0xffff0000) | val;
|
||||
wl1271_write32(wl, addr, tmp);
|
||||
ret = wlcore_write32(wl, addr, tmp);
|
||||
} else {
|
||||
tmp = wl1271_read32(wl, addr - 2);
|
||||
ret = wlcore_read32(wl, addr - 2, &tmp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
tmp = (tmp & 0xffff) | (val << 16);
|
||||
wl1271_write32(wl, addr - 2, tmp);
|
||||
ret = wlcore_write32(wl, addr - 2, tmp);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr)
|
||||
int wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (WARN_ON(addr % 2))
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
|
||||
if ((addr % 4) == 0) {
|
||||
/* address is 4-bytes aligned */
|
||||
val = wl1271_read32(wl, addr);
|
||||
return val & 0xffff;
|
||||
ret = wlcore_read32(wl, addr, &val);
|
||||
if (ret >= 0 && out)
|
||||
*out = val & 0xffff;
|
||||
} else {
|
||||
val = wl1271_read32(wl, addr - 2);
|
||||
return (val & 0xffff0000) >> 16;
|
||||
ret = wlcore_read32(wl, addr - 2, &val);
|
||||
if (ret >= 0 && out)
|
||||
*out = (val & 0xffff0000) >> 16;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef __WL18XX_IO_H__
|
||||
#define __WL18XX_IO_H__
|
||||
|
||||
void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val);
|
||||
u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr);
|
||||
int __must_check wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val);
|
||||
int __must_check wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out);
|
||||
|
||||
#endif /* __WL18XX_IO_H__ */
|
||||
|
@ -43,10 +43,11 @@
|
||||
|
||||
#define WL18XX_RX_CHECKSUM_MASK 0x40
|
||||
|
||||
static char *ht_mode_param = "wide";
|
||||
static char *ht_mode_param = "default";
|
||||
static char *board_type_param = "hdk";
|
||||
static bool checksum_param = false;
|
||||
static bool enable_11a_param = true;
|
||||
static int num_rx_desc_param = -1;
|
||||
|
||||
/* phy paramters */
|
||||
static int dc2dc_param = -1;
|
||||
@ -372,6 +373,7 @@ static struct wlcore_conf wl18xx_conf = {
|
||||
.forced_ps = false,
|
||||
.keep_alive_interval = 55000,
|
||||
.max_listen_interval = 20,
|
||||
.sta_sleep_auth = WL1271_PSM_ILLEGAL,
|
||||
},
|
||||
.itrim = {
|
||||
.enable = false,
|
||||
@ -606,24 +608,15 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
|
||||
wl->plt_fw_name = WL18XX_FW_NAME;
|
||||
wl->quirks |= WLCORE_QUIRK_NO_ELP |
|
||||
WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
|
||||
WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN |
|
||||
WLCORE_QUIRK_TX_PAD_LAST_FRAME;
|
||||
|
||||
break;
|
||||
case CHIP_ID_185x_PG10:
|
||||
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)",
|
||||
wl->chip.id);
|
||||
wl->sr_fw_name = WL18XX_FW_NAME;
|
||||
/* wl18xx uses the same firmware for PLT */
|
||||
wl->plt_fw_name = WL18XX_FW_NAME;
|
||||
wl->quirks |= WLCORE_QUIRK_NO_ELP |
|
||||
WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED |
|
||||
WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
|
||||
WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
|
||||
wl1271_warning("chip id 0x%x (185x PG10) is deprecated",
|
||||
wl->chip.id);
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
|
||||
/* PG 1.0 has some problems with MCS_13, so disable it */
|
||||
wl->ht_cap[IEEE80211_BAND_2GHZ].mcs.rx_mask[1] &= ~BIT(5);
|
||||
|
||||
break;
|
||||
default:
|
||||
wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
|
||||
ret = -ENODEV;
|
||||
@ -634,123 +627,178 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl18xx_set_clk(struct wl1271 *wl)
|
||||
static int wl18xx_set_clk(struct wl1271 *wl)
|
||||
{
|
||||
u32 clk_freq;
|
||||
u16 clk_freq;
|
||||
int ret;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* TODO: PG2: apparently we need to read the clk type */
|
||||
|
||||
clk_freq = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT);
|
||||
ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq,
|
||||
wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m,
|
||||
wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q,
|
||||
wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit");
|
||||
|
||||
wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, wl18xx_clk_table[clk_freq].n);
|
||||
wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, wl18xx_clk_table[clk_freq].m);
|
||||
ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N,
|
||||
wl18xx_clk_table[clk_freq].n);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M,
|
||||
wl18xx_clk_table[clk_freq].m);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
if (wl18xx_clk_table[clk_freq].swallow) {
|
||||
/* first the 16 lower bits */
|
||||
wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1,
|
||||
wl18xx_clk_table[clk_freq].q &
|
||||
PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK);
|
||||
ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1,
|
||||
wl18xx_clk_table[clk_freq].q &
|
||||
PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* then the 16 higher bits, masked out */
|
||||
wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2,
|
||||
(wl18xx_clk_table[clk_freq].q >> 16) &
|
||||
PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK);
|
||||
ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2,
|
||||
(wl18xx_clk_table[clk_freq].q >> 16) &
|
||||
PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* first the 16 lower bits */
|
||||
wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1,
|
||||
wl18xx_clk_table[clk_freq].p &
|
||||
PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK);
|
||||
ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1,
|
||||
wl18xx_clk_table[clk_freq].p &
|
||||
PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* then the 16 higher bits, masked out */
|
||||
wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2,
|
||||
(wl18xx_clk_table[clk_freq].p >> 16) &
|
||||
PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK);
|
||||
ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2,
|
||||
(wl18xx_clk_table[clk_freq].p >> 16) &
|
||||
PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK);
|
||||
} else {
|
||||
wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN,
|
||||
PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
|
||||
ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN,
|
||||
PLLSH_WCS_PLL_SWALLOW_EN_VAL2);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl18xx_boot_soft_reset(struct wl1271 *wl)
|
||||
static int wl18xx_boot_soft_reset(struct wl1271 *wl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* disable Rx/Tx */
|
||||
wl1271_write32(wl, WL18XX_ENABLE, 0x0);
|
||||
ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* disable auto calibration on start*/
|
||||
wl1271_write32(wl, WL18XX_SPARE_A2, 0xffff);
|
||||
ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl18xx_pre_boot(struct wl1271 *wl)
|
||||
{
|
||||
wl18xx_set_clk(wl);
|
||||
int ret;
|
||||
|
||||
ret = wl18xx_set_clk(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Continue the ELP wake up sequence */
|
||||
wl1271_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
|
||||
ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
udelay(500);
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* Disable interrupts */
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
|
||||
ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl18xx_boot_soft_reset(wl);
|
||||
ret = wl18xx_boot_soft_reset(wl);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl18xx_pre_upload(struct wl1271 *wl)
|
||||
static int wl18xx_pre_upload(struct wl1271 *wl)
|
||||
{
|
||||
u32 tmp;
|
||||
int ret;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* TODO: check if this is all needed */
|
||||
wl1271_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
|
||||
ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
tmp = wlcore_read_reg(wl, REG_CHIP_ID_B);
|
||||
ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
|
||||
|
||||
tmp = wl1271_read32(wl, WL18XX_SCR_PAD2);
|
||||
ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl18xx_set_mac_and_phy(struct wl1271 *wl)
|
||||
static int wl18xx_set_mac_and_phy(struct wl1271 *wl)
|
||||
{
|
||||
struct wl18xx_priv *priv = wl->priv;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
/* the parameters struct is smaller for PG1 */
|
||||
if (wl->chip.id == CHIP_ID_185x_PG10)
|
||||
len = offsetof(struct wl18xx_mac_and_phy_params, psat) + 1;
|
||||
else
|
||||
len = sizeof(struct wl18xx_mac_and_phy_params);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
|
||||
wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, len,
|
||||
false);
|
||||
ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy,
|
||||
sizeof(struct wl18xx_mac_and_phy_params), false);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl18xx_enable_interrupts(struct wl1271 *wl)
|
||||
static int wl18xx_enable_interrupts(struct wl1271 *wl)
|
||||
{
|
||||
u32 event_mask, intr_mask;
|
||||
int ret;
|
||||
|
||||
if (wl->chip.id == CHIP_ID_185x_PG10) {
|
||||
event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1;
|
||||
intr_mask = WL18XX_INTR_MASK_PG1;
|
||||
} else {
|
||||
event_mask = WL18XX_ACX_EVENTS_VECTOR_PG2;
|
||||
intr_mask = WL18XX_INTR_MASK_PG2;
|
||||
}
|
||||
event_mask = WL18XX_ACX_EVENTS_VECTOR;
|
||||
intr_mask = WL18XX_INTR_MASK;
|
||||
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
|
||||
ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wlcore_enable_interrupts(wl);
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_MASK,
|
||||
WL1271_ACX_INTR_ALL & ~intr_mask);
|
||||
|
||||
ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
|
||||
WL1271_ACX_INTR_ALL & ~intr_mask);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl18xx_boot(struct wl1271 *wl)
|
||||
@ -761,25 +809,29 @@ static int wl18xx_boot(struct wl1271 *wl)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl18xx_pre_upload(wl);
|
||||
ret = wl18xx_pre_upload(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wlcore_boot_upload_firmware(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl18xx_set_mac_and_phy(wl);
|
||||
ret = wl18xx_set_mac_and_phy(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wlcore_boot_run_firmware(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl18xx_enable_interrupts(wl);
|
||||
ret = wl18xx_enable_interrupts(wl);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
|
||||
static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
struct wl18xx_priv *priv = wl->priv;
|
||||
@ -787,13 +839,14 @@ static void wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
|
||||
memcpy(priv->cmd_buf, buf, len);
|
||||
memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len);
|
||||
|
||||
wl1271_write(wl, cmd_box_addr, priv->cmd_buf, WL18XX_CMD_MAX_SIZE,
|
||||
false);
|
||||
return wlcore_write(wl, cmd_box_addr, priv->cmd_buf,
|
||||
WL18XX_CMD_MAX_SIZE, false);
|
||||
}
|
||||
|
||||
static void wl18xx_ack_event(struct wl1271 *wl)
|
||||
static int wl18xx_ack_event(struct wl1271 *wl)
|
||||
{
|
||||
wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL18XX_INTR_TRIG_EVENT_ACK);
|
||||
return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
|
||||
WL18XX_INTR_TRIG_EVENT_ACK);
|
||||
}
|
||||
|
||||
static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
|
||||
@ -975,34 +1028,32 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl,
|
||||
} else if (!strcmp(ht_mode_param, "mimo")) {
|
||||
wl1271_debug(DEBUG_ACX, "using MIMO rate mask");
|
||||
|
||||
/*
|
||||
* PG 1.0 has some problems with MCS_13, so disable it
|
||||
*
|
||||
* TODO: instead of hacking this in here, we should
|
||||
* make it more general and change a bit in the
|
||||
* wlvif->rate_set instead.
|
||||
*/
|
||||
if (wl->chip.id == CHIP_ID_185x_PG10)
|
||||
return CONF_TX_MIMO_RATES & ~CONF_HW_BIT_RATE_MCS_13;
|
||||
|
||||
return CONF_TX_MIMO_RATES;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static s8 wl18xx_get_pg_ver(struct wl1271 *wl)
|
||||
static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
|
||||
{
|
||||
u32 fuse;
|
||||
int ret;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
fuse = wl1271_read32(wl, WL18XX_REG_FUSE_DATA_1_3);
|
||||
fuse = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
|
||||
ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
|
||||
if (ver)
|
||||
*ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
|
||||
|
||||
return (s8)fuse;
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin"
|
||||
@ -1021,8 +1072,7 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
|
||||
}
|
||||
|
||||
if (fw->size != WL18XX_CONF_SIZE) {
|
||||
wl1271_error("configuration binary file size is wrong, "
|
||||
"expected %ld got %zd",
|
||||
wl1271_error("configuration binary file size is wrong, expected %zu got %zu",
|
||||
WL18XX_CONF_SIZE, fw->size);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
@ -1069,26 +1119,41 @@ out:
|
||||
|
||||
static int wl18xx_plt_init(struct wl1271 *wl)
|
||||
{
|
||||
wl1271_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
|
||||
int ret;
|
||||
|
||||
ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return wl->ops->boot(wl);
|
||||
}
|
||||
|
||||
static void wl18xx_get_mac(struct wl1271 *wl)
|
||||
static int wl18xx_get_mac(struct wl1271 *wl)
|
||||
{
|
||||
u32 mac1, mac2;
|
||||
int ret;
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
mac1 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1);
|
||||
mac2 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2);
|
||||
ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* these are the two parts of the BD_ADDR */
|
||||
wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
|
||||
((mac1 & 0xff000000) >> 24);
|
||||
wl->fuse_nic_addr = (mac1 & 0xffffff);
|
||||
|
||||
wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
|
||||
ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wl18xx_handle_static_data(struct wl1271 *wl,
|
||||
@ -1214,8 +1279,8 @@ static struct wlcore_ops wl18xx_ops = {
|
||||
.pre_pkt_send = wl18xx_pre_pkt_send,
|
||||
};
|
||||
|
||||
/* HT cap appropriate for wide channels */
|
||||
static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = {
|
||||
/* HT cap appropriate for wide channels in 2Ghz */
|
||||
static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = {
|
||||
.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
|
||||
IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40,
|
||||
.ht_supported = true,
|
||||
@ -1228,6 +1293,20 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = {
|
||||
},
|
||||
};
|
||||
|
||||
/* HT cap appropriate for wide channels in 5Ghz */
|
||||
static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = {
|
||||
.cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
|
||||
IEEE80211_HT_CAP_SUP_WIDTH_20_40,
|
||||
.ht_supported = true,
|
||||
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
|
||||
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
|
||||
.mcs = {
|
||||
.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
.rx_highest = cpu_to_le16(150),
|
||||
.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
|
||||
},
|
||||
};
|
||||
|
||||
/* HT cap appropriate for SISO 20 */
|
||||
static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = {
|
||||
.cap = IEEE80211_HT_CAP_SGI_20,
|
||||
@ -1254,18 +1333,6 @@ static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_5ghz = {
|
||||
.cap = IEEE80211_HT_CAP_SGI_20,
|
||||
.ht_supported = true,
|
||||
.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
|
||||
.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
|
||||
.mcs = {
|
||||
.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
|
||||
.rx_highest = cpu_to_le16(72),
|
||||
.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
|
||||
},
|
||||
};
|
||||
|
||||
static int __devinit wl18xx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wl1271 *wl;
|
||||
@ -1286,7 +1353,7 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
|
||||
wl->ptable = wl18xx_ptable;
|
||||
wl->rtable = wl18xx_rtable;
|
||||
wl->num_tx_desc = 32;
|
||||
wl->num_rx_desc = 16;
|
||||
wl->num_rx_desc = 32;
|
||||
wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
|
||||
wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX;
|
||||
wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0;
|
||||
@ -1294,32 +1361,8 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
|
||||
wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics);
|
||||
wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv);
|
||||
|
||||
if (!strcmp(ht_mode_param, "wide")) {
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ],
|
||||
&wl18xx_siso40_ht_cap,
|
||||
sizeof(wl18xx_siso40_ht_cap));
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ],
|
||||
&wl18xx_siso40_ht_cap,
|
||||
sizeof(wl18xx_siso40_ht_cap));
|
||||
} else if (!strcmp(ht_mode_param, "mimo")) {
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ],
|
||||
&wl18xx_mimo_ht_cap_2ghz,
|
||||
sizeof(wl18xx_mimo_ht_cap_2ghz));
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ],
|
||||
&wl18xx_mimo_ht_cap_5ghz,
|
||||
sizeof(wl18xx_mimo_ht_cap_5ghz));
|
||||
} else if (!strcmp(ht_mode_param, "siso20")) {
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ],
|
||||
&wl18xx_siso20_ht_cap,
|
||||
sizeof(wl18xx_siso20_ht_cap));
|
||||
memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ],
|
||||
&wl18xx_siso20_ht_cap,
|
||||
sizeof(wl18xx_siso20_ht_cap));
|
||||
} else {
|
||||
wl1271_error("invalid ht_mode '%s'", ht_mode_param);
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
if (num_rx_desc_param != -1)
|
||||
wl->num_rx_desc = num_rx_desc_param;
|
||||
|
||||
ret = wl18xx_conf_init(wl, &pdev->dev);
|
||||
if (ret < 0)
|
||||
@ -1366,6 +1409,37 @@ static int __devinit wl18xx_probe(struct platform_device *pdev)
|
||||
if (dc2dc_param != -1)
|
||||
priv->conf.phy.external_pa_dc2dc = dc2dc_param;
|
||||
|
||||
if (!strcmp(ht_mode_param, "default")) {
|
||||
/*
|
||||
* Only support mimo with multiple antennas. Fall back to
|
||||
* siso20.
|
||||
*/
|
||||
if (priv->conf.phy.number_of_assembled_ant2_4 >= 2)
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
|
||||
&wl18xx_mimo_ht_cap_2ghz);
|
||||
else
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
|
||||
&wl18xx_siso20_ht_cap);
|
||||
|
||||
/* 5Ghz is always wide */
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
|
||||
&wl18xx_siso40_ht_cap_5ghz);
|
||||
} else if (!strcmp(ht_mode_param, "wide")) {
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
|
||||
&wl18xx_siso40_ht_cap_2ghz);
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
|
||||
&wl18xx_siso40_ht_cap_5ghz);
|
||||
} else if (!strcmp(ht_mode_param, "siso20")) {
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ,
|
||||
&wl18xx_siso20_ht_cap);
|
||||
wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ,
|
||||
&wl18xx_siso20_ht_cap);
|
||||
} else {
|
||||
wl1271_error("invalid ht_mode '%s'", ht_mode_param);
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (!checksum_param) {
|
||||
wl18xx_ops.set_rx_csum = NULL;
|
||||
wl18xx_ops.init_vif = NULL;
|
||||
@ -1410,7 +1484,7 @@ static void __exit wl18xx_exit(void)
|
||||
module_exit(wl18xx_exit);
|
||||
|
||||
module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR);
|
||||
MODULE_PARM_DESC(ht_mode, "Force HT mode: wide (default), mimo or siso20");
|
||||
MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20");
|
||||
|
||||
module_param_named(board_type, board_type_param, charp, S_IRUSR);
|
||||
MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or "
|
||||
@ -1458,6 +1532,11 @@ module_param_named(pwr_limit_reference_11_abg,
|
||||
MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 "
|
||||
"(default is 0xc8)");
|
||||
|
||||
module_param_named(num_rx_desc,
|
||||
num_rx_desc_param, int, S_IRUSR);
|
||||
MODULE_PARM_DESC(num_rx_desc_param,
|
||||
"Number of Rx descriptors: u8 (default is 32)");
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
|
||||
MODULE_FIRMWARE(WL18XX_FW_NAME);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user