diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/wmi.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 72 |
1 files changed, 31 insertions, 41 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 9d7ac1ab2d02..08a154bce139 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -776,10 +776,8 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi) cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR; cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS; - ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID, + return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID, NO_SYNC_WMIFLAG); - - return 0; } int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) @@ -1080,7 +1078,7 @@ static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len, void ath6kl_wmi_sscan_timer(struct timer_list *t) { - struct ath6kl_vif *vif = from_timer(vif, t, sched_scan_timer); + struct ath6kl_vif *vif = timer_container_of(vif, t, sched_scan_timer); cfg80211_sched_scan_results(vif->ar->wiphy, 0); } @@ -1178,6 +1176,10 @@ static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap, return -EINVAL; ev = (struct wmi_pstream_timeout_event *) datap; + if (ev->traffic_class >= WMM_NUM_AC) { + ath6kl_err("invalid traffic class: %d\n", ev->traffic_class); + return -EINVAL; + } /* * When the pstream (fat pipe == AC) timesout, it means there were @@ -1199,8 +1201,7 @@ static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap, static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) { struct wmi_bit_rate_reply *reply; - s32 rate; - u32 sgi, index; + u32 index; if (len < sizeof(struct wmi_bit_rate_reply)) return -EINVAL; @@ -1209,15 +1210,10 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) ath6kl_dbg(ATH6KL_DBG_WMI, "rateindex %d\n", reply->rate_index); - if (reply->rate_index == (s8) RATE_AUTO) { - rate = RATE_AUTO; - } else { + if (reply->rate_index != (s8) RATE_AUTO) { index = reply->rate_index & 0x7f; if (WARN_ON_ONCE(index > (RATE_MCS_7_40 + 1))) return -EINVAL; - - sgi = (reply->rate_index & 0x80) ? 1 : 0; - rate = wmi_rate_tbl[index][sgi]; } ath6kl_wakeup_event(wmi->parent_dev); @@ -1297,8 +1293,7 @@ static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap, if (len < sizeof(*ev)) return -EINVAL; ev = (struct wmi_neighbor_report_event *) datap; - if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info) - > len) { + if (struct_size(ev, neighbor, ev->num_neighbors) > len) { ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event (num=%d len=%d)\n", ev->num_neighbors, len); @@ -1519,6 +1514,10 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len, return -EINVAL; reply = (struct wmi_cac_event *) datap; + if (reply->ac >= WMM_NUM_AC) { + ath6kl_err("invalid AC: %d\n", reply->ac); + return -EINVAL; + } if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) && (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) { @@ -1751,7 +1750,6 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap, static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len) { - u16 ap_info_entry_size; struct wmi_aplist_event *ev = (struct wmi_aplist_event *) datap; struct wmi_ap_info_v1 *ap_info_v1; u8 index; @@ -1760,14 +1758,12 @@ static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len) ev->ap_list_ver != APLIST_VER1) return -EINVAL; - ap_info_entry_size = sizeof(struct wmi_ap_info_v1); ap_info_v1 = (struct wmi_ap_info_v1 *) ev->ap_list; ath6kl_dbg(ATH6KL_DBG_WMI, "number of APs in aplist event: %d\n", ev->num_ap); - if (len < (int) (sizeof(struct wmi_aplist_event) + - (ev->num_ap - 1) * ap_info_entry_size)) + if (len < struct_size(ev, ap_list, ev->num_ap)) return -EINVAL; /* AP list version 1 contents */ @@ -1822,8 +1818,8 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, /* Only for OPT_TX_CMD, use BE endpoint. */ if (cmd_id == WMI_OPT_TX_FRAME_CMDID) { - ret = ath6kl_wmi_data_hdr_add(wmi, skb, OPT_MSGTYPE, - false, false, 0, NULL, if_idx); + ret = ath6kl_wmi_data_hdr_add(wmi, skb, OPT_MSGTYPE, false, + WMI_DATA_HDR_DATA_TYPE_802_3, 0, NULL, if_idx); if (ret) { dev_kfree_skb(skb); return ret; @@ -1960,21 +1956,15 @@ static int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, { struct sk_buff *skb; struct wmi_start_scan_cmd *sc; - s8 size; int i, ret; - size = sizeof(struct wmi_start_scan_cmd); - if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) return -EINVAL; if (num_chan > WMI_MAX_CHANNELS) return -EINVAL; - if (num_chan) - size += sizeof(u16) * (num_chan - 1); - - skb = ath6kl_wmi_get_new_buf(size); + skb = ath6kl_wmi_get_new_buf(struct_size(sc, ch_list, num_chan)); if (!skb) return -ENOMEM; @@ -2009,7 +1999,7 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, struct ieee80211_supported_band *sband; struct sk_buff *skb; struct wmi_begin_scan_cmd *sc; - s8 size, *supp_rates; + s8 *supp_rates; int i, band, ret; struct ath6kl *ar = wmi->parent_dev; int num_rates; @@ -2024,18 +2014,13 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, num_chan, ch_list); } - size = sizeof(struct wmi_begin_scan_cmd); - if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) return -EINVAL; if (num_chan > WMI_MAX_CHANNELS) return -EINVAL; - if (num_chan) - size += sizeof(u16) * (num_chan - 1); - - skb = ath6kl_wmi_get_new_buf(size); + skb = ath6kl_wmi_get_new_buf(struct_size(sc, ch_list, num_chan)); if (!skb) return -ENOMEM; @@ -2505,8 +2490,10 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) goto free_data_skb; for (index = 0; index < num_pri_streams; index++) { - if (WARN_ON(!data_sync_bufs[index].skb)) + if (WARN_ON(!data_sync_bufs[index].skb)) { + ret = -ENOMEM; goto free_data_skb; + } ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, data_sync_bufs[index]. @@ -2614,7 +2601,7 @@ int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx, } /* - * Indicate activty change to driver layer only if this is the + * Indicate activity change to driver layer only if this is the * first TSID to get created in this AC explicitly or an implicit * fat pipe is getting created. */ @@ -2635,11 +2622,16 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class, u16 active_tsids = 0; int ret; - if (traffic_class > 3) { + if (traffic_class >= WMM_NUM_AC) { ath6kl_err("invalid traffic class: %d\n", traffic_class); return -EINVAL; } + if (tsid >= 16) { + ath6kl_err("invalid tsid: %d\n", tsid); + return -EINVAL; + } + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); if (!skb) return -ENOMEM; @@ -3645,7 +3637,7 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, if (wait) return -EINVAL; /* Offload for wait not supported */ - buf = kmalloc(data_len, GFP_KERNEL); + buf = kmemdup(data, data_len, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -3656,7 +3648,6 @@ static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, } 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; @@ -3684,7 +3675,7 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, if (wait) return -EINVAL; /* Offload for wait not supported */ - buf = kmalloc(data_len, GFP_KERNEL); + buf = kmemdup(data, data_len, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -3695,7 +3686,6 @@ static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, } 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; |
