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')
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c307
1 files changed, 185 insertions, 122 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 97abf4699b41..2b442332cd0f 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc. 2 * Copyright (c) 2004-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -126,7 +127,7 @@ int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb)
126 127
127 if (!is_ethertype(be16_to_cpu(type))) { 128 if (!is_ethertype(be16_to_cpu(type))) {
128 ath6kl_dbg(ATH6KL_DBG_WMI, 129 ath6kl_dbg(ATH6KL_DBG_WMI,
129 "%s: pkt is already in 802.3 format\n", __func__); 130 "%s: pkt is already in 802.3 format\n", __func__);
130 return 0; 131 return 0;
131 } 132 }
132 133
@@ -827,8 +828,8 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
827 if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 && 828 if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 &&
828 pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) { 829 pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) {
829 /* WMM OUT (00:50:F2) */ 830 /* WMM OUT (00:50:F2) */
830 if (pie[1] > 5 831 if (pie[1] > 5 &&
831 && pie[6] == WMM_PARAM_OUI_SUBTYPE) 832 pie[6] == WMM_PARAM_OUI_SUBTYPE)
832 wmi->is_wmm_enabled = true; 833 wmi->is_wmm_enabled = true;
833 } 834 }
834 break; 835 break;
@@ -912,17 +913,17 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
912 regpair = ath6kl_get_regpair((u16) reg_code); 913 regpair = ath6kl_get_regpair((u16) reg_code);
913 country = ath6kl_regd_find_country_by_rd((u16) reg_code); 914 country = ath6kl_regd_find_country_by_rd((u16) reg_code);
914 ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", 915 ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
915 regpair->regDmnEnum); 916 regpair->regDmnEnum);
916 } 917 }
917 918
918 if (country) { 919 if (country && wmi->parent_dev->wiphy_registered) {
919 alpha2[0] = country->isoName[0]; 920 alpha2[0] = country->isoName[0];
920 alpha2[1] = country->isoName[1]; 921 alpha2[1] = country->isoName[1];
921 922
922 regulatory_hint(wmi->parent_dev->wiphy, alpha2); 923 regulatory_hint(wmi->parent_dev->wiphy, alpha2);
923 924
924 ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n", 925 ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n",
925 alpha2[0], alpha2[1]); 926 alpha2[0], alpha2[1]);
926 } 927 }
927} 928}
928 929
@@ -1033,8 +1034,9 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
1033 if (len < 8 + 2 + 2) 1034 if (len < 8 + 2 + 2)
1034 return -EINVAL; 1035 return -EINVAL;
1035 1036
1036 if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags) 1037 if (bih->frame_type == BEACON_FTYPE &&
1037 && memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { 1038 test_bit(CONNECTED, &vif->flags) &&
1039 memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) {
1038 const u8 *tim; 1040 const u8 *tim;
1039 tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2, 1041 tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
1040 len - 8 - 2 - 2); 1042 len - 8 - 2 - 2);
@@ -1366,8 +1368,8 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
1366 /* Upper threshold breached */ 1368 /* Upper threshold breached */
1367 if (rssi < sq_thresh->upper_threshold[0]) { 1369 if (rssi < sq_thresh->upper_threshold[0]) {
1368 ath6kl_dbg(ATH6KL_DBG_WMI, 1370 ath6kl_dbg(ATH6KL_DBG_WMI,
1369 "spurious upper rssi threshold event: %d\n", 1371 "spurious upper rssi threshold event: %d\n",
1370 rssi); 1372 rssi);
1371 } else if ((rssi < sq_thresh->upper_threshold[1]) && 1373 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1372 (rssi >= sq_thresh->upper_threshold[0])) { 1374 (rssi >= sq_thresh->upper_threshold[0])) {
1373 new_threshold = WMI_RSSI_THRESHOLD1_ABOVE; 1375 new_threshold = WMI_RSSI_THRESHOLD1_ABOVE;
@@ -1390,7 +1392,7 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
1390 /* Lower threshold breached */ 1392 /* Lower threshold breached */
1391 if (rssi > sq_thresh->lower_threshold[0]) { 1393 if (rssi > sq_thresh->lower_threshold[0]) {
1392 ath6kl_dbg(ATH6KL_DBG_WMI, 1394 ath6kl_dbg(ATH6KL_DBG_WMI,
1393 "spurious lower rssi threshold event: %d %d\n", 1395 "spurious lower rssi threshold event: %d %d\n",
1394 rssi, sq_thresh->lower_threshold[0]); 1396 rssi, sq_thresh->lower_threshold[0]);
1395 } else if ((rssi > sq_thresh->lower_threshold[1]) && 1397 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1396 (rssi <= sq_thresh->lower_threshold[0])) { 1398 (rssi <= sq_thresh->lower_threshold[0])) {
@@ -1551,8 +1553,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
1551 /* Upper threshold breached */ 1553 /* Upper threshold breached */
1552 if (snr < sq_thresh->upper_threshold[0]) { 1554 if (snr < sq_thresh->upper_threshold[0]) {
1553 ath6kl_dbg(ATH6KL_DBG_WMI, 1555 ath6kl_dbg(ATH6KL_DBG_WMI,
1554 "spurious upper snr threshold event: %d\n", 1556 "spurious upper snr threshold event: %d\n",
1555 snr); 1557 snr);
1556 } else if ((snr < sq_thresh->upper_threshold[1]) && 1558 } else if ((snr < sq_thresh->upper_threshold[1]) &&
1557 (snr >= sq_thresh->upper_threshold[0])) { 1559 (snr >= sq_thresh->upper_threshold[0])) {
1558 new_threshold = WMI_SNR_THRESHOLD1_ABOVE; 1560 new_threshold = WMI_SNR_THRESHOLD1_ABOVE;
@@ -1569,8 +1571,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
1569 /* Lower threshold breached */ 1571 /* Lower threshold breached */
1570 if (snr > sq_thresh->lower_threshold[0]) { 1572 if (snr > sq_thresh->lower_threshold[0]) {
1571 ath6kl_dbg(ATH6KL_DBG_WMI, 1573 ath6kl_dbg(ATH6KL_DBG_WMI,
1572 "spurious lower snr threshold event: %d\n", 1574 "spurious lower snr threshold event: %d\n",
1573 sq_thresh->lower_threshold[0]); 1575 sq_thresh->lower_threshold[0]);
1574 } else if ((snr > sq_thresh->lower_threshold[1]) && 1576 } else if ((snr > sq_thresh->lower_threshold[1]) &&
1575 (snr <= sq_thresh->lower_threshold[0])) { 1577 (snr <= sq_thresh->lower_threshold[0])) {
1576 new_threshold = WMI_SNR_THRESHOLD4_BELOW; 1578 new_threshold = WMI_SNR_THRESHOLD4_BELOW;
@@ -2028,6 +2030,26 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
2028 return ret; 2030 return ret;
2029} 2031}
2030 2032
2033int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx,
2034 u16 bmiss_time, u16 num_beacons)
2035{
2036 struct sk_buff *skb;
2037 struct wmi_bmiss_time_cmd *cmd;
2038 int ret;
2039
2040 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
2041 if (!skb)
2042 return -ENOMEM;
2043
2044 cmd = (struct wmi_bmiss_time_cmd *) skb->data;
2045 cmd->bmiss_time = cpu_to_le16(bmiss_time);
2046 cmd->num_beacons = cpu_to_le16(num_beacons);
2047
2048 ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BMISS_TIME_CMDID,
2049 NO_SYNC_WMIFLAG);
2050 return ret;
2051}
2052
2031int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) 2053int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode)
2032{ 2054{
2033 struct sk_buff *skb; 2055 struct sk_buff *skb;
@@ -2613,7 +2635,7 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
2613 int ret; 2635 int ret;
2614 2636
2615 if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) && 2637 if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) &&
2616 wow_mode != ATH6KL_WOW_MODE_DISABLE) { 2638 wow_mode != ATH6KL_WOW_MODE_DISABLE) {
2617 ath6kl_err("invalid wow mode: %d\n", wow_mode); 2639 ath6kl_err("invalid wow mode: %d\n", wow_mode);
2618 return -EINVAL; 2640 return -EINVAL;
2619 } 2641 }
@@ -3014,6 +3036,22 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
3014 NO_SYNC_WMIFLAG); 3036 NO_SYNC_WMIFLAG);
3015} 3037}
3016 3038
3039int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable)
3040{
3041 struct sk_buff *skb;
3042 struct wmi_ap_hidden_ssid_cmd *cmd;
3043
3044 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3045 if (!skb)
3046 return -ENOMEM;
3047
3048 cmd = (struct wmi_ap_hidden_ssid_cmd *) skb->data;
3049 cmd->hidden_ssid = enable ? 1 : 0;
3050
3051 return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_HIDDEN_SSID_CMDID,
3052 NO_SYNC_WMIFLAG);
3053}
3054
3017/* This command will be used to enable/disable AP uAPSD feature */ 3055/* This command will be used to enable/disable AP uAPSD feature */
3018int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) 3056int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable)
3019{ 3057{
@@ -3183,8 +3221,9 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur)
3183 * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P 3221 * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P
3184 * mgmt operations using station interface. 3222 * mgmt operations using station interface.
3185 */ 3223 */
3186int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, 3224static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
3187 u32 wait, const u8 *data, u16 data_len) 3225 u32 freq, u32 wait, const u8 *data,
3226 u16 data_len)
3188{ 3227{
3189 struct sk_buff *skb; 3228 struct sk_buff *skb;
3190 struct wmi_send_action_cmd *p; 3229 struct wmi_send_action_cmd *p;
@@ -3220,9 +3259,9 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
3220 NO_SYNC_WMIFLAG); 3259 NO_SYNC_WMIFLAG);
3221} 3260}
3222 3261
3223int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, 3262static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
3224 u32 wait, const u8 *data, u16 data_len, 3263 u32 freq, u32 wait, const u8 *data,
3225 u32 no_cck) 3264 u16 data_len, u32 no_cck)
3226{ 3265{
3227 struct sk_buff *skb; 3266 struct sk_buff *skb;
3228 struct wmi_send_mgmt_cmd *p; 3267 struct wmi_send_mgmt_cmd *p;
@@ -3259,6 +3298,32 @@ int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
3259 NO_SYNC_WMIFLAG); 3298 NO_SYNC_WMIFLAG);
3260} 3299}
3261 3300
3301int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
3302 u32 wait, const u8 *data, u16 data_len,
3303 u32 no_cck)
3304{
3305 int status;
3306 struct ath6kl *ar = wmi->parent_dev;
3307
3308 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
3309 ar->fw_capabilities)) {
3310 /*
3311 * If capable of doing P2P mgmt operations using
3312 * station interface, send additional information like
3313 * supported rates to advertise and xmit rates for
3314 * probe requests
3315 */
3316 status = __ath6kl_wmi_send_mgmt_cmd(ar->wmi, if_idx, id, freq,
3317 wait, data, data_len,
3318 no_cck);
3319 } else {
3320 status = ath6kl_wmi_send_action_cmd(ar->wmi, if_idx, id, freq,
3321 wait, data, data_len);
3322 }
3323
3324 return status;
3325}
3326
3262int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, 3327int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
3263 const u8 *dst, const u8 *data, 3328 const u8 *dst, const u8 *data,
3264 u16 data_len) 3329 u16 data_len)
@@ -3370,32 +3435,101 @@ static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len)
3370 return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len); 3435 return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len);
3371} 3436}
3372 3437
3373/* Control Path */ 3438/* Process interface specific wmi events, caller would free the datap */
3374int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) 3439static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id,
3440 u8 *datap, u32 len)
3375{ 3441{
3376 struct wmi_cmd_hdr *cmd;
3377 struct ath6kl_vif *vif; 3442 struct ath6kl_vif *vif;
3378 u32 len;
3379 u16 id;
3380 u8 if_idx;
3381 u8 *datap;
3382 int ret = 0;
3383 3443
3384 if (WARN_ON(skb == NULL)) 3444 vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx);
3445 if (!vif) {
3446 ath6kl_dbg(ATH6KL_DBG_WMI,
3447 "Wmi event for unavailable vif, vif_index:%d\n",
3448 if_idx);
3385 return -EINVAL; 3449 return -EINVAL;
3450 }
3386 3451
3387 if (skb->len < sizeof(struct wmi_cmd_hdr)) { 3452 switch (cmd_id) {
3388 ath6kl_err("bad packet 1\n"); 3453 case WMI_CONNECT_EVENTID:
3389 dev_kfree_skb(skb); 3454 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
3455 return ath6kl_wmi_connect_event_rx(wmi, datap, len, vif);
3456 case WMI_DISCONNECT_EVENTID:
3457 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
3458 return ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif);
3459 case WMI_TKIP_MICERR_EVENTID:
3460 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
3461 return ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif);
3462 case WMI_BSSINFO_EVENTID:
3463 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
3464 return ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif);
3465 case WMI_NEIGHBOR_REPORT_EVENTID:
3466 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
3467 return ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len,
3468 vif);
3469 case WMI_SCAN_COMPLETE_EVENTID:
3470 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
3471 return ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif);
3472 case WMI_REPORT_STATISTICS_EVENTID:
3473 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
3474 return ath6kl_wmi_stats_event_rx(wmi, datap, len, vif);
3475 case WMI_CAC_EVENTID:
3476 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
3477 return ath6kl_wmi_cac_event_rx(wmi, datap, len, vif);
3478 case WMI_PSPOLL_EVENTID:
3479 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
3480 return ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif);
3481 case WMI_DTIMEXPIRY_EVENTID:
3482 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
3483 return ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif);
3484 case WMI_ADDBA_REQ_EVENTID:
3485 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
3486 return ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif);
3487 case WMI_DELBA_REQ_EVENTID:
3488 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
3489 return ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif);
3490 case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
3491 ath6kl_dbg(ATH6KL_DBG_WMI,
3492 "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
3493 return ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
3494 case WMI_REMAIN_ON_CHNL_EVENTID:
3495 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
3496 return ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
3497 case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID:
3498 ath6kl_dbg(ATH6KL_DBG_WMI,
3499 "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n");
3500 return ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap,
3501 len, vif);
3502 case WMI_TX_STATUS_EVENTID:
3503 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n");
3504 return ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif);
3505 case WMI_RX_PROBE_REQ_EVENTID:
3506 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n");
3507 return ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif);
3508 case WMI_RX_ACTION_EVENTID:
3509 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
3510 return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
3511 default:
3512 ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id);
3390 return -EINVAL; 3513 return -EINVAL;
3391 } 3514 }
3392 3515
3516 return 0;
3517}
3518
3519static int ath6kl_wmi_proc_events(struct wmi *wmi, struct sk_buff *skb)
3520{
3521 struct wmi_cmd_hdr *cmd;
3522 int ret = 0;
3523 u32 len;
3524 u16 id;
3525 u8 if_idx;
3526 u8 *datap;
3527
3393 cmd = (struct wmi_cmd_hdr *) skb->data; 3528 cmd = (struct wmi_cmd_hdr *) skb->data;
3394 id = le16_to_cpu(cmd->cmd_id); 3529 id = le16_to_cpu(cmd->cmd_id);
3395 if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK; 3530 if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK;
3396 3531
3397 skb_pull(skb, sizeof(struct wmi_cmd_hdr)); 3532 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
3398
3399 datap = skb->data; 3533 datap = skb->data;
3400 len = skb->len; 3534 len = skb->len;
3401 3535
@@ -3403,15 +3537,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3403 ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ", 3537 ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ",
3404 datap, len); 3538 datap, len);
3405 3539
3406 vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx);
3407 if (!vif) {
3408 ath6kl_dbg(ATH6KL_DBG_WMI,
3409 "Wmi event for unavailable vif, vif_index:%d\n",
3410 if_idx);
3411 dev_kfree_skb(skb);
3412 return -EINVAL;
3413 }
3414
3415 switch (id) { 3540 switch (id) {
3416 case WMI_GET_BITRATE_CMDID: 3541 case WMI_GET_BITRATE_CMDID:
3417 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n"); 3542 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n");
@@ -3429,26 +3554,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3429 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n"); 3554 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n");
3430 ret = ath6kl_wmi_ready_event_rx(wmi, datap, len); 3555 ret = ath6kl_wmi_ready_event_rx(wmi, datap, len);
3431 break; 3556 break;
3432 case WMI_CONNECT_EVENTID:
3433 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
3434 ret = ath6kl_wmi_connect_event_rx(wmi, datap, len, vif);
3435 break;
3436 case WMI_DISCONNECT_EVENTID:
3437 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
3438 ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif);
3439 break;
3440 case WMI_PEER_NODE_EVENTID: 3557 case WMI_PEER_NODE_EVENTID:
3441 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n"); 3558 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n");
3442 ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len); 3559 ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len);
3443 break; 3560 break;
3444 case WMI_TKIP_MICERR_EVENTID:
3445 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
3446 ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif);
3447 break;
3448 case WMI_BSSINFO_EVENTID:
3449 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
3450 ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif);
3451 break;
3452 case WMI_REGDOMAIN_EVENTID: 3561 case WMI_REGDOMAIN_EVENTID:
3453 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n"); 3562 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
3454 ath6kl_wmi_regdomain_event(wmi, datap, len); 3563 ath6kl_wmi_regdomain_event(wmi, datap, len);
@@ -3457,23 +3566,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3457 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n"); 3566 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
3458 ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len); 3567 ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len);
3459 break; 3568 break;
3460 case WMI_NEIGHBOR_REPORT_EVENTID:
3461 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
3462 ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len,
3463 vif);
3464 break;
3465 case WMI_SCAN_COMPLETE_EVENTID:
3466 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
3467 ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif);
3468 break;
3469 case WMI_CMDERROR_EVENTID: 3569 case WMI_CMDERROR_EVENTID:
3470 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n"); 3570 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n");
3471 ret = ath6kl_wmi_error_event_rx(wmi, datap, len); 3571 ret = ath6kl_wmi_error_event_rx(wmi, datap, len);
3472 break; 3572 break;
3473 case WMI_REPORT_STATISTICS_EVENTID:
3474 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
3475 ret = ath6kl_wmi_stats_event_rx(wmi, datap, len, vif);
3476 break;
3477 case WMI_RSSI_THRESHOLD_EVENTID: 3573 case WMI_RSSI_THRESHOLD_EVENTID:
3478 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n"); 3574 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n");
3479 ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len); 3575 ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len);
@@ -3493,10 +3589,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3493 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n"); 3589 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n");
3494 ret = ath6kl_wmi_control_rx_xtnd(wmi, skb); 3590 ret = ath6kl_wmi_control_rx_xtnd(wmi, skb);
3495 break; 3591 break;
3496 case WMI_CAC_EVENTID:
3497 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
3498 ret = ath6kl_wmi_cac_event_rx(wmi, datap, len, vif);
3499 break;
3500 case WMI_CHANNEL_CHANGE_EVENTID: 3592 case WMI_CHANNEL_CHANGE_EVENTID:
3501 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n"); 3593 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n");
3502 break; 3594 break;
@@ -3536,28 +3628,12 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3536 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n"); 3628 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n");
3537 ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len); 3629 ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len);
3538 break; 3630 break;
3539 case WMI_PSPOLL_EVENTID:
3540 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
3541 ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif);
3542 break;
3543 case WMI_DTIMEXPIRY_EVENTID:
3544 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
3545 ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif);
3546 break;
3547 case WMI_SET_PARAMS_REPLY_EVENTID: 3631 case WMI_SET_PARAMS_REPLY_EVENTID:
3548 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n"); 3632 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n");
3549 break; 3633 break;
3550 case WMI_ADDBA_REQ_EVENTID:
3551 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
3552 ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif);
3553 break;
3554 case WMI_ADDBA_RESP_EVENTID: 3634 case WMI_ADDBA_RESP_EVENTID:
3555 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n"); 3635 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n");
3556 break; 3636 break;
3557 case WMI_DELBA_REQ_EVENTID:
3558 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
3559 ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif);
3560 break;
3561 case WMI_REPORT_BTCOEX_CONFIG_EVENTID: 3637 case WMI_REPORT_BTCOEX_CONFIG_EVENTID:
3562 ath6kl_dbg(ATH6KL_DBG_WMI, 3638 ath6kl_dbg(ATH6KL_DBG_WMI,
3563 "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n"); 3639 "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n");
@@ -3570,52 +3646,39 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3570 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); 3646 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
3571 ret = ath6kl_wmi_tx_complete_event_rx(datap, len); 3647 ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
3572 break; 3648 break;
3573 case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
3574 ath6kl_dbg(ATH6KL_DBG_WMI,
3575 "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
3576 ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
3577 break;
3578 case WMI_REMAIN_ON_CHNL_EVENTID:
3579 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
3580 ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
3581 break;
3582 case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID:
3583 ath6kl_dbg(ATH6KL_DBG_WMI,
3584 "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n");
3585 ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap,
3586 len, vif);
3587 break;
3588 case WMI_TX_STATUS_EVENTID:
3589 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n");
3590 ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif);
3591 break;
3592 case WMI_RX_PROBE_REQ_EVENTID:
3593 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n");
3594 ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif);
3595 break;
3596 case WMI_P2P_CAPABILITIES_EVENTID: 3649 case WMI_P2P_CAPABILITIES_EVENTID:
3597 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n"); 3650 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n");
3598 ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len); 3651 ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len);
3599 break; 3652 break;
3600 case WMI_RX_ACTION_EVENTID:
3601 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
3602 ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
3603 break;
3604 case WMI_P2P_INFO_EVENTID: 3653 case WMI_P2P_INFO_EVENTID:
3605 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n"); 3654 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n");
3606 ret = ath6kl_wmi_p2p_info_event_rx(datap, len); 3655 ret = ath6kl_wmi_p2p_info_event_rx(datap, len);
3607 break; 3656 break;
3608 default: 3657 default:
3609 ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id); 3658 /* may be the event is interface specific */
3610 ret = -EINVAL; 3659 ret = ath6kl_wmi_proc_events_vif(wmi, if_idx, id, datap, len);
3611 break; 3660 break;
3612 } 3661 }
3613 3662
3614 dev_kfree_skb(skb); 3663 dev_kfree_skb(skb);
3615
3616 return ret; 3664 return ret;
3617} 3665}
3618 3666
3667/* Control Path */
3668int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3669{
3670 if (WARN_ON(skb == NULL))
3671 return -EINVAL;
3672
3673 if (skb->len < sizeof(struct wmi_cmd_hdr)) {
3674 ath6kl_err("bad packet 1\n");
3675 dev_kfree_skb(skb);
3676 return -EINVAL;
3677 }
3678
3679 return ath6kl_wmi_proc_events(wmi, skb);
3680}
3681
3619void ath6kl_wmi_reset(struct wmi *wmi) 3682void ath6kl_wmi_reset(struct wmi *wmi)
3620{ 3683{
3621 spin_lock_bh(&wmi->lock); 3684 spin_lock_bh(&wmi->lock);