diff options
| author | Xiaochang Duan <xduan@qca.qualcomm.com> | 2014-04-16 20:08:41 -0700 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-04-17 16:46:04 -0700 |
| commit | 50749c996bb33c3a6a22eecd34d033d05fd18aed (patch) | |
| tree | 88acd5e517d7c173eaac725af89e26e41d0e6e3a | |
| parent | 54e1ceade6eaa082b5ee429baeeb8b34aeac8b48 (diff) | |
qcacld-new:ibss:add support to scan and secure to open switch
Current IBSS implementation deletes ibss vdev during leave_ibss
handling. This leads to that the scan for IBSS networks does
not work after the leave_ibss handling.
Add scan support by recreating new ibss vdev and its bss peer
as the final part of the leave_ibss handling.
Also force the remote ibss peer's keys to be cleared whenever
the peer is created. This is to support the switch from a secure
IBSS network to a open IBSS network. Without this change the
keys for the secure IBSS network remain and cause that data
connections like ping fail after the switch.
Change-Id: I48a4306d126a2376b76c369bf121dd167e79d9a0
CRs-Fixed: 645419
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 211 |
1 files changed, 151 insertions, 60 deletions
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 3ca0d5e4ad24..0e7b69d363eb 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -197,6 +197,14 @@ wma_process_ftm_command(tp_wma_handle wma_handle, struct ar6k_testmode_cmd_data *msg_buffer); #endif +static VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev, u8 peer_addr[6], + u_int32_t peer_type, u_int8_t vdev_id); +static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle, + tpAddStaSelfParams self_sta_req, + u_int8_t generateRsp); +static void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info); + /*DFS Attach*/ struct ieee80211com* wma_dfs_attach(struct ieee80211com *ic); static void wma_set_bss_rate_flags(struct wma_txrx_node *iface, @@ -1004,7 +1012,7 @@ static void wma_delete_all_ibss_peers(tp_wma_handle wma, A_UINT32 vdev_id) } } - /* remote IBSS bss peer last */ + /* remove IBSS bss peer last */ peer = TAILQ_FIRST(&vdev->peer_list); wma_remove_peer(wma, wma->interfaces[vdev_id].bssid, vdev_id, peer); } @@ -1032,6 +1040,60 @@ static void wma_delete_all_ap_remote_peers(tp_wma_handle wma, A_UINT32 vdev_id) } } } +#ifdef QCA_IBSS_SUPPORT +static void wma_recreate_ibss_vdev_and_bss_peer(tp_wma_handle wma, u_int8_t vdev_id) +{ + ol_txrx_vdev_handle vdev; + tDelStaSelfParams del_sta_param; + tAddStaSelfParams add_sta_self_param; + VOS_STATUS status; + + if (!wma) { + WMA_LOGE("%s: Null wma handle", __func__); + return; + } + + vdev = wma_find_vdev_by_id(wma, vdev_id); + if (!vdev) { + WMA_LOGE("%s: Can't find vdev with id %d", __func__, vdev_id); + return; + } + + vos_copy_macaddr((v_MACADDR_t *)&(add_sta_self_param.selfMacAddr), + (v_MACADDR_t *)&(vdev->mac_addr)); + add_sta_self_param.sessionId = vdev_id; + add_sta_self_param.type = WMI_VDEV_TYPE_IBSS; + add_sta_self_param.subType = 0; + add_sta_self_param.status = 0; + + /* delete old ibss vdev */ + del_sta_param.sessionId = vdev_id; + vos_mem_copy((void *)del_sta_param.selfMacAddr, + (void *)&(vdev->mac_addr), + VOS_MAC_ADDR_SIZE); + wma_vdev_detach(wma, &del_sta_param, 0); + + /* create new vdev for ibss */ + vdev = wma_vdev_attach(wma, &add_sta_self_param, 0); + if (!vdev) { + WMA_LOGE("%s: Failed to create vdev", __func__); + return; + } + + WLANTL_RegisterVdev(wma->vos_context, vdev); + /* Register with TxRx Module for Data Ack Complete Cb */ + wdi_in_data_tx_cb_set(vdev, wma_data_tx_ack_comp_hdlr, wma); + WMA_LOGA("new IBSS vdev created with mac %pM", add_sta_self_param.selfMacAddr); + + /* create ibss bss peer */ + status = wma_create_peer(wma, vdev->pdev, vdev, vdev->mac_addr.raw, + WMI_PEER_TYPE_DEFAULT, vdev_id); + if (status != VOS_STATUS_SUCCESS) + WMA_LOGE("%s: Failed to create IBSS bss peer", __func__); + else + WMA_LOGA("IBSS BSS peer created with mac %pM", vdev->mac_addr.raw); +} +#endif //#ifdef QCA_IBSS_SUPPORT static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, u32 len) @@ -1043,10 +1105,6 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, ol_txrx_peer_handle peer; ol_txrx_pdev_handle pdev; u_int8_t peer_id; -#ifdef QCA_IBSS_SUPPORT - tDelStaSelfParams del_sta_param; - ol_txrx_vdev_handle vdev; -#endif struct wma_txrx_node *iface; WMA_LOGI("%s: Enter", __func__); @@ -1133,14 +1191,9 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, #endif #ifdef QCA_IBSS_SUPPORT - vdev = wma->interfaces[resp_event->vdev_id].handle; - if (wma_is_vdev_in_ibss_mode(wma, params->sessionId)) { - del_sta_param.sessionId = params->sessionId; - vos_mem_copy((void *)del_sta_param.selfMacAddr, - (void *)&(vdev->mac_addr), - VOS_MAC_ADDR_SIZE); - wma_vdev_detach(wma, &del_sta_param, 0); - } + /* recreate ibss vdev and bss peer for scan purpose */ + if (wma_is_vdev_in_ibss_mode(wma, resp_event->vdev_id)) + wma_recreate_ibss_vdev_and_bss_peer(wma, resp_event->vdev_id); #endif params->status = VOS_STATUS_SUCCESS; @@ -3404,6 +3457,22 @@ static VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, ol_txrx_peer_detach(peer); goto err; } + +#ifdef QCA_IBSS_SUPPORT + /* for each remote ibss peer, clear its keys */ + if (wma_is_vdev_in_ibss_mode(wma, vdev_id) + && !vos_mem_compare(peer_addr, vdev->mac_addr.raw, ETH_ALEN)) { + + tSetStaKeyParams key_info; + WMA_LOGD("%s: remote ibss peer %pM key clearing\n", __func__, + peer_addr); + vos_mem_set(&key_info, sizeof(key_info), 0); + key_info.smesessionId= vdev_id; + vos_mem_copy(key_info.peerMacAddr, peer_addr, ETH_ALEN); + wma_set_stakey(wma, &key_info, FALSE); + } +#endif + return VOS_STATUS_SUCCESS; err: wma->peer_count--; @@ -6212,9 +6281,6 @@ void wma_vdev_resp_timer(void *data) ol_txrx_pdev_handle pdev; u_int8_t peer_id; struct wma_target_req *msg; -#ifdef QCA_IBSS_SUPPORT - tDelStaSelfParams del_sta_param; -#endif wma = (tp_wma_handle) vos_get_context(VOS_MODULE_ID_WDA, vos_context); @@ -6300,12 +6366,9 @@ void wma_vdev_resp_timer(void *data) #endif #ifdef QCA_IBSS_SUPPORT - if (wma_is_vdev_in_ibss_mode(wma, params->sessionId)) { - del_sta_param.sessionId = params->sessionId; - vos_mem_copy((void *)del_sta_param.selfMacAddr, - (void *)params->bssid, VOS_MAC_ADDR_SIZE); - wma_vdev_detach(wma, &del_sta_param, 0); - } + /* recreate ibss vdev and bss peer for scan purpose */ + if (wma_is_vdev_in_ibss_mode(wma, tgt_req->vdev_id)) + wma_recreate_ibss_vdev_and_bss_peer(wma, tgt_req->vdev_id); #endif params->status = VOS_STATUS_E_TIMEOUT; WMA_LOGA("%s: WDA_DELETE_BSS_REQ timedout", __func__); @@ -8394,6 +8457,7 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss) VOS_STATUS status; tDelStaSelfParams del_sta_param; tAddStaSelfParams add_sta_self_param; + tSetBssKeyParams key_info; WMA_LOGD("%s: add_bss->sessionId = %d", __func__, add_bss->sessionId); vdev_id = add_bss->sessionId; @@ -8404,11 +8468,22 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss) goto send_fail_resp; } wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss); + vdev = wma_find_vdev_by_id(wma, vdev_id); - if (vdev) { + if (!vdev) { + WMA_LOGE("%s: vdev not found for vdev id %d.", + __func__, vdev_id); + goto send_fail_resp; + } + + /* only change vdev type to ibss during 1st time join_ibss handling */ + + if (FALSE == wma_is_vdev_in_ibss_mode(wma, vdev_id)) { + WMA_LOGD("%s: vdev found for vdev id %d. deleting the vdev", - __func__, vdev_id); + __func__, vdev_id); + /* remove peers on the existing non-ibss vdev */ TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) { WMA_LOGE("%s: peer found for vdev id %d. deleting the peer", __func__, vdev_id); @@ -8416,6 +8491,7 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss) vdev_id, peer); } + /* remove the non-ibss vdev */ vos_copy_macaddr((v_MACADDR_t *)&(del_sta_param.selfMacAddr), (v_MACADDR_t *)&(vdev->mac_addr)); del_sta_param.sessionId = vdev_id; @@ -8423,46 +8499,52 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss) wma_vdev_detach(wma, &del_sta_param, 0); - } - else { - WMA_LOGD("%s: vdev with session id %d not found ", __func__, vdev_id); - } + /* create new vdev for ibss */ + vos_copy_macaddr((v_MACADDR_t *)&(add_sta_self_param.selfMacAddr), + (v_MACADDR_t *)&(add_bss->selfMacAddr)); + add_sta_self_param.sessionId = vdev_id; + add_sta_self_param.type = WMI_VDEV_TYPE_IBSS; + add_sta_self_param.subType = 0; + add_sta_self_param.status = 0; - /* create new vdev for ibss */ - vos_copy_macaddr((v_MACADDR_t *)&(add_sta_self_param.selfMacAddr), - (v_MACADDR_t *)&(add_bss->selfMacAddr)); - add_sta_self_param.sessionId = vdev_id; - add_sta_self_param.type = WMI_VDEV_TYPE_IBSS; - add_sta_self_param.subType = 0; - add_sta_self_param.status = 0; + vdev = wma_vdev_attach(wma, &add_sta_self_param, 0); + if (!vdev) { + WMA_LOGE("%s: Failed to create vdev", __func__); + goto send_fail_resp; + } - vdev = wma_vdev_attach(wma, &add_sta_self_param, 0); - if (!vdev) { - WMA_LOGE("%s: Failed to create vdev", __func__); - goto send_fail_resp; - } - WLANTL_RegisterVdev(wma->vos_context, vdev); - /* Register with TxRx Module for Data Ack Complete Cb */ - wdi_in_data_tx_cb_set(vdev, wma_data_tx_ack_comp_hdlr, wma); - WMA_LOGA("new IBSS vdev created with mac %pM", add_bss->selfMacAddr); + WLANTL_RegisterVdev(wma->vos_context, vdev); + /* Register with TxRx Module for Data Ack Complete Cb */ + wdi_in_data_tx_cb_set(vdev, wma_data_tx_ack_comp_hdlr, wma); + WMA_LOGA("new IBSS vdev created with mac %pM", add_bss->selfMacAddr); - /* create self peer */ - status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr, + /* create ibss bss peer */ + status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr, WMI_PEER_TYPE_DEFAULT, vdev_id); - if (status != VOS_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to create peer", __func__); - goto send_fail_resp; - } - WMA_LOGA("IBSS BSS peer created with mac %pM", add_bss->selfMacAddr); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE("%s: Failed to create peer", __func__); + goto send_fail_resp; + } + WMA_LOGA("IBSS BSS peer created with mac %pM", add_bss->selfMacAddr); - peer = ol_txrx_find_peer_by_addr(pdev, add_bss->selfMacAddr, &peer_id); - if (!peer) { - WMA_LOGE("%s Failed to find peer %pM", __func__, - add_bss->selfMacAddr); - goto send_fail_resp; - } + peer = ol_txrx_find_peer_by_addr(pdev, add_bss->selfMacAddr, &peer_id); + if (!peer) { + WMA_LOGE("%s Failed to find peer %pM", __func__, + add_bss->selfMacAddr); + goto send_fail_resp; + } + } + + /* clear leftover ibss keys on bss peer */ + + WMA_LOGD("%s: ibss bss key clearing", __func__); + vos_mem_set(&key_info, sizeof(key_info), 0); + key_info.smesessionId = vdev_id; + key_info.numKeys = SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS; + vos_mem_copy(&wma->ibsskey_info, &key_info, sizeof(tSetBssKeyParams)); + + /* start ibss vdev */ - /* set operation mode to be IBSS */ add_bss->operMode = BSS_OPERATIONAL_MODE_IBSS; msg = wma_fill_vdev_req(wma, vdev_id, WDA_ADD_BSS_REQ, @@ -8478,8 +8560,8 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss) vos_mem_zero(&req, sizeof(req)); req.vdev_id = vdev_id; - req.chan = add_bss->currentOperChannel; /* FIXME: verify param value */ - req.chan_offset = add_bss->currentExtChannel; /* FIXME: verify param value */ + req.chan = add_bss->currentOperChannel; + req.chan_offset = add_bss->currentExtChannel; req.vht_capable = add_bss->vhtCapable; #if defined WLAN_FEATURE_VOWIF req.max_txpow = add_bss->maxTxPower; @@ -9754,6 +9836,9 @@ static void wma_set_bsskey(tp_wma_handle wma_handle, tpSetBssKeyParams key_info) (const v_VOID_t *) key_info->key[i].key, key_info->key[i].keyLength); + WMA_LOGD("%s: bss key[%d] length %d", __func__, i, + key_info->key[i].keyLength); + buf = wma_setup_install_key_cmd(wma_handle, &key_params, &len); if (!buf) { WMA_LOGE("%s:Failed to setup install key buf", __func__); @@ -9831,6 +9916,9 @@ static void wma_set_ibsskey_helper(tp_wma_handle wma_handle, tpSetBssKeyParams k (const v_VOID_t *) key_info->key[i].key, key_info->key[i].keyLength); + WMA_LOGD("%s: peer bcast key[%d] length %d", __func__, i, + key_info->key[i].keyLength); + buf = wma_setup_install_key_cmd(wma_handle, &key_params, &len); if (!buf) { WMA_LOGE("%s:Failed to setup install key buf", __func__); @@ -9934,6 +10022,9 @@ static void wma_set_stakey(tp_wma_handle wma_handle, tpSetStaKeyParams key_info, goto out; } + WMA_LOGD("%s: peer unicast key[%d] %d ", __func__, i, + key_info->key[i].keyLength); + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, WMI_VDEV_INSTALL_KEY_CMDID); if (status) { |
