diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/wmi.c')
-rwxr-xr-x | drivers/net/wireless/ath/ath6kl/wmi.c | 139 |
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; |