mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-03 07:46:45 +07:00
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John Linville says: ==================== Here is another batch of updates intended for 3.6. This includes a number of pulls, including ones from the mac80211, iwlwifi, ath6kl, and wl12xx trees. I also pulled from the wireless tree to avoid potential build conflicts. There are a number of other patches applied directly, including a number for the Broadcom drivers and the mwifiex driver. The updates cover the usual variety of new hardware support and feature enhancements. It's all good work, but there aren't any big headliners. This does resolve a net-next/wireless-next merge conflict reported by Stephen. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
dd7f36ba3c
@ -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 @@ void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
|
||||
|
||||
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 @@ void ath_ani_calibrate(unsigned long data)
|
||||
* 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 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
|
||||
* 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 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
|
||||
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 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
|
||||
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 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
|
||||
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 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
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 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
|
||||
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 @@ static int wl12xx_pre_boot(struct wl1271 *wl)
|
||||
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 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
|
||||
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 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
|
||||
|
||||
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