aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl/wmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/wmi.c')
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/wmi.c139
1 files changed, 133 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 6fbf4a9..f7afb1d 100755
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -291,6 +291,13 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
layer2_priority);
} else
usr_pri = layer2_priority & 0x7;
+
+ /*
+ * Queue the EAPOL frames in the same WMM_AC_VO queue
+ * as that of management frames.
+ */
+ if (skb->protocol == cpu_to_be16(ETH_P_PAE))
+ usr_pri = WMI_VOICE_USER_PRIORITY;
}
/*
@@ -526,6 +533,8 @@ static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len,
id = le32_to_cpu(ev->id);
ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n",
id, ev->ack_status);
+
+ mutex_lock(&wmi->lock_mgmt);
if (wmi->last_mgmt_tx_frame) {
cfg80211_mgmt_tx_status(vif->ndev, id,
wmi->last_mgmt_tx_frame,
@@ -535,6 +544,7 @@ static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len,
wmi->last_mgmt_tx_frame = NULL;
wmi->last_mgmt_tx_frame_len = 0;
}
+ mutex_unlock(&wmi->lock_mgmt);
return 0;
}
@@ -712,13 +722,57 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
cmd = (struct roam_ctrl_cmd *) skb->data;
+#ifdef CONFIG_MACH_PX
+ if (wmi->parent_dev->psminfo == 0)
+ cmd->info.params.lrssi_scan_period = 0xFFFF;
+ else
+ cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
+#else
cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
+#endif
+
cmd->info.params.lrssi_scan_threshold = a_cpu_to_sle16(lrssi +
DEF_SCAN_FOR_ROAM_INTVL);
cmd->info.params.lrssi_roam_threshold = a_cpu_to_sle16(lrssi);
cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR;
cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
+ ath6kl_dbg(ATH6KL_DBG_WMI, "lrssi_scan_period %d, lrssi_scan_threshold = %d, "
+ "lrssi_roam_threshold = %d, roam_rssi_floor = %d\n",
+ cmd->info.params.lrssi_scan_period, cmd->info.params.lrssi_scan_threshold,
+ cmd->info.params.lrssi_roam_threshold, cmd->info.params.roam_rssi_floor);
+
+ ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return 0;
+}
+
+int ath6kl_wmi_set_roam_lrssi_config_cmd(struct wmi *wmi,
+ struct low_rssi_scan_params *params)
+{
+ struct sk_buff *skb;
+ struct roam_ctrl_cmd *cmd;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct roam_ctrl_cmd *) skb->data;
+ ath6kl_dbg(ATH6KL_DBG_WMI, "lrssi_scan_period %d, lrssi_scan_threshold = %d, "
+ "lrssi_roam_threshold = %d, roam_rssi_floor = %d\n",
+ params->lrssi_scan_period, params->lrssi_scan_threshold,
+ params->lrssi_roam_threshold, params->roam_rssi_floor);
+
+ if (params->lrssi_scan_period == 0)
+ cmd->info.params.lrssi_scan_period = 0xFFFF;
+ else
+ cmd->info.params.lrssi_scan_period = params->lrssi_scan_period;
+ cmd->info.params.lrssi_scan_threshold = params->lrssi_scan_threshold;
+ cmd->info.params.lrssi_roam_threshold = params->lrssi_roam_threshold;
+ cmd->info.params.roam_rssi_floor = params->roam_rssi_floor;
+ cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
+
ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
NO_SYNC_WMIFLAG);
@@ -1823,7 +1877,11 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
{
struct sk_buff *skb;
struct wmi_begin_scan_cmd *sc;
+#ifdef CONFIG_MACH_PX
+ unsigned int size;
+#else
s8 size;
+#endif
int i, band, ret;
struct ath6kl *ar = wmi->parent_dev;
int num_rates;
@@ -1989,7 +2047,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))
@@ -2047,7 +2105,7 @@ int ath6kl_wmi_mcastrate_cmd(struct wmi *wmi, u8 if_idx,
struct wmi_set_mcastrate_cmd *cmd;
int ret;
- printk(KERN_ERR "\tmcastrate = %d\n", bitrate);
+ printk(KERN_INFO "\tmcastrate = %d\n", bitrate);
skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
if (!skb)
@@ -2988,6 +3046,61 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
return ret;
}
+int ath6kl_wmi_set_ht_cap_cmd(struct wmi *wmi, u8 if_idx,
+ struct wmi_set_ht_cap_cmd *params)
+{
+ struct sk_buff *skb;
+ struct wmi_set_ht_cap_cmd *cmd;
+ struct ath6kl *ar = wmi->parent_dev;
+ struct ieee80211_supported_band *sband;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_ht_cap_cmd *) skb->data;
+ ath6kl_dbg(ATH6KL_DBG_WMI, "bands %d, ht_supported = %d, "
+ "chan_width_40m_supported %d, short_gi_20mhz = %d, "
+ "short_gi_40mhz = %d, intolerance_40mhz = %d\n",
+ params->band, params->enable,
+ params->chan_width_40m_supported, params->short_gi_20mhz,
+ params->short_gi_40mhz, params->intolerance_40mhz);
+ memcpy(cmd, params, sizeof(*cmd));
+
+ sband = ar->wiphy->bands[params->band];
+ sband->ht_cap.ht_supported = params->enable;
+ if (params->chan_width_40m_supported)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+ if (params->short_gi_20mhz)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
+
+ if (params->short_gi_40mhz)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
+
+ if (params->intolerance_40mhz)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT;
+
+ if (params->max_ampdu_len_exp)
+ sband->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
+ else
+ sband->ht_cap.cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_HT_CAP_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+
s32 ath6kl_wmi_get_rate(s8 rate_index)
{
u32 sgi;
@@ -3311,6 +3424,7 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
struct sk_buff *skb;
struct wmi_send_action_cmd *p;
u8 *buf;
+ int ret;
if (wait)
return -EINVAL; /* Offload for wait not supported */
@@ -3325,7 +3439,10 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
return -ENOMEM;
}
- kfree(wmi->last_mgmt_tx_frame);
+ mutex_lock(&wmi->lock_mgmt);
+ if (wmi->last_mgmt_tx_frame)
+ kfree(wmi->last_mgmt_tx_frame);
+
memcpy(buf, data, data_len);
wmi->last_mgmt_tx_frame = buf;
wmi->last_mgmt_tx_frame_len = data_len;
@@ -3338,8 +3455,10 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
p->wait = cpu_to_le32(wait);
p->len = cpu_to_le16(data_len);
memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_ACTION_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_ACTION_CMDID,
NO_SYNC_WMIFLAG);
+ mutex_unlock(&wmi->lock_mgmt);
+ return ret;
}
static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
@@ -3349,6 +3468,7 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
struct sk_buff *skb;
struct wmi_send_mgmt_cmd *p;
u8 *buf;
+ int ret;
if (wait)
return -EINVAL; /* Offload for wait not supported */
@@ -3363,7 +3483,10 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
return -ENOMEM;
}
- kfree(wmi->last_mgmt_tx_frame);
+ mutex_lock(&wmi->lock_mgmt);
+ if (wmi->last_mgmt_tx_frame)
+ kfree(wmi->last_mgmt_tx_frame);
+
memcpy(buf, data, data_len);
wmi->last_mgmt_tx_frame = buf;
wmi->last_mgmt_tx_frame_len = data_len;
@@ -3377,8 +3500,11 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
p->no_cck = cpu_to_le32(no_cck);
p->len = cpu_to_le16(data_len);
memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_MGMT_CMDID,
+ ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_MGMT_CMDID,
NO_SYNC_WMIFLAG);
+ mutex_unlock(&wmi->lock_mgmt);
+
+ return ret;
}
int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
@@ -3800,6 +3926,7 @@ void *ath6kl_wmi_init(struct ath6kl *dev)
return NULL;
spin_lock_init(&wmi->lock);
+ mutex_init(&wmi->lock_mgmt);
wmi->parent_dev = dev;