diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 307 |
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 | ||
2033 | int 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 | |||
2031 | int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) | 2053 | int 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 | ||
3039 | int 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 */ |
3018 | int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) | 3056 | int 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 | */ |
3186 | int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | 3224 | static 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 | ||
3223 | int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, | 3262 | static 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 | ||
3301 | int 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 | |||
3262 | int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, | 3327 | int 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 */ |
3374 | int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) | 3439 | static 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 | |||
3519 | static 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 */ | ||
3668 | int 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 | |||
3619 | void ath6kl_wmi_reset(struct wmi *wmi) | 3682 | void ath6kl_wmi_reset(struct wmi *wmi) |
3620 | { | 3683 | { |
3621 | spin_lock_bh(&wmi->lock); | 3684 | spin_lock_bh(&wmi->lock); |