/** * @brief Process an TLV buffer for a pending BSS Join command for * both adhoc and infra networks * * The TLV command processing for a BSS join for either adhoc or * infrastructure network is performed with this function. The * capability bits are inspected for the IBSS flag and the appropriate * local routines are called to setup the necessary TLVs. * * Activate 11h functionality in the firmware if the spectrum management * capability bit is found in the network information for the BSS we are * joining. * * @param priv Private driver information structure * @param ppbuffer Output parameter: Pointer to the TLV output buffer, * modified on return to point after the appended 11h TLVs * @param pcap_info Pointer to the capability info for the BSS to join * @param channel Channel on which we are joining the BSS * @param p11h_bss_info Pointer to the 11h BSS information for this * network that was parsed out of the scan response. * * @return Integer number of bytes appended to the TLV output * buffer (ppbuffer), MLAN_STATUS_FAILURE (-1), * or MLAN_STATUS_SUCCESS (0) */ int wlan_11h_process_join(mlan_private * priv, t_u8 ** ppbuffer, IEEEtypes_CapInfo_t * pcap_info, t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info) { int ret = 0; ENTER(); if (priv->media_connected == MTRUE) { if (wlan_11h_is_active(priv) == p11h_bss_info->sensed_11h) { /* Assume DFS parameters are the same for roaming as long as the current & next APs have the same spectrum mgmt capability bit setting */ ret = MLAN_STATUS_SUCCESS; } else { /* No support for roaming between DFS/non-DFS yet */ ret = MLAN_STATUS_FAILURE; } LEAVE(); return ret; } if (p11h_bss_info->sensed_11h) { /* No use having 11h enabled without 11d enabled */ wlan_11d_enable(priv, MNULL, ENABLE_11D); wlan_11d_parse_dnld_countryinfo(priv, priv->pattempted_bss_desc); /* Activate 11h functions in firmware, turns on capability bit */ wlan_11h_activate(priv, MTRUE); pcap_info->spectrum_mgmt = 1; if (pcap_info->ibss) { PRINTM(MINFO, "11h: Adhoc join: Sensed\n"); ret = wlan_11h_process_adhoc(priv, ppbuffer, channel, p11h_bss_info); } else { PRINTM(MINFO, "11h: Infra join: Sensed\n"); ret = wlan_11h_process_infra_join(priv, ppbuffer, channel, p11h_bss_info); } } else { /* Deactivate 11h functions in the firmware */ wlan_11h_activate(priv, MFALSE); pcap_info->spectrum_mgmt = 0; } LEAVE(); return ret; }
/** * @brief Set SNMP MIB for 11H * * @param pmadapter A pointer to mlan_adapter structure * @param pioctl_req A pointer to ioctl request buffer * * @return MLAN_STATUS_PENDING --success, otherwise fail * @sa wlan_uap_callback_snmp_mib_11h */ static mlan_status wlan_uap_snmp_mib_11h(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; mlan_ds_snmp_mib *snmp = MNULL; t_bool enable; ENTER(); if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) { PRINTM(MWARN, "MLAN snmp_mib IOCTL length is too short.\n"); pioctl_req->data_read_written = 0; pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib); LEAVE(); return MLAN_STATUS_RESOURCE; } snmp = (mlan_ds_snmp_mib *) pioctl_req->pbuf; enable = (snmp->param.oid_value) ? MTRUE : MFALSE; if (enable) { /* first enable 11D if it is not enabled */ if (!wlan_11d_is_enabled(pmpriv)) { ret = wlan_11d_enable(pmpriv, MNULL, ENABLE_11D); if (ret != MLAN_STATUS_SUCCESS) { PRINTM(MERROR, "Failed to first enable 11D before enabling 11H.\n"); LEAVE(); return ret; } } } /* store params, issue command to get UAP channel, whose CMD_RESP will callback remainder of 11H handling (and radar detect if DFS chan) */ pmpriv->uap_state_chan_cb.pioctl_req_curr = pioctl_req; pmpriv->uap_state_chan_cb.get_chan_callback = wlan_uap_callback_snmp_mib_11h; ret = wlan_uap_get_channel(pmpriv); if (ret == MLAN_STATUS_SUCCESS) ret = MLAN_STATUS_PENDING; LEAVE(); return ret; }
/** * @brief Process an TLV buffer for a pending BSS Adhoc start command. * * Activate 11h functionality in the firmware if driver has is enabled * for 11h (configured by the application via IOCTL). * * @param priv Private driver information structure * @param ppbuffer Output parameter: Pointer to the TLV output buffer, * modified on return to point after the appended 11h TLVs * @param pcap_info Pointer to the capability info for the BSS to join * @param channel Channel on which we are starting the IBSS * @param p11h_bss_info Input/Output parameter: Pointer to the 11h BSS * information for this network that we are establishing. * 11h sensed flag set on output if warranted. * * @return Integer number of bytes appended to the TLV output * buffer (ppbuffer) * */ int wlan_11h_process_start(mlan_private * priv, t_u8 ** ppbuffer, IEEEtypes_CapInfo_t * pcap_info, t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info) { mlan_adapter *adapter = priv->adapter; int ret = 0; ENTER(); if (wlan_11h_is_enabled(priv) && ((adapter->adhoc_start_band & BAND_A) || (adapter->adhoc_start_band & BAND_AN) ) ) { if (wlan_11d_get_state(priv) == DISABLE_11D) { /* No use having 11h enabled without 11d enabled */ wlan_11d_enable(priv, MNULL, ENABLE_11D); wlan_11d_create_dnld_countryinfo(priv, adapter->adhoc_start_band); } /* Activate 11h functions in firmware, turns on capability bit */ wlan_11h_activate(priv, MTRUE); pcap_info->spectrum_mgmt = 1; /* Set flag indicating this BSS we are starting is using 11h */ p11h_bss_info->sensed_11h = MTRUE; ret = wlan_11h_process_adhoc(priv, ppbuffer, channel, MNULL); } else { /* Deactivate 11h functions in the firmware */ wlan_11h_activate(priv, MFALSE); pcap_info->spectrum_mgmt = 0; } LEAVE(); return ret; }
/** * @brief Set SNMP MIB for 11D * * @param pmadapter A pointer to mlan_adapter structure * @param pioctl_req A pointer to ioctl request buffer * * @return MLAN_STATUS_PENDING --success, otherwise fail */ static mlan_status wlan_uap_snmp_mib_11d(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req) { mlan_status ret = MLAN_STATUS_SUCCESS; mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_index]; mlan_ds_snmp_mib *snmp = MNULL; state_11d_t flag; ENTER(); if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) { PRINTM(MWARN, "MLAN snmp_mib IOCTL length is too short.\n"); pioctl_req->data_read_written = 0; pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib); LEAVE(); return MLAN_STATUS_RESOURCE; } if ((pioctl_req->action == MLAN_ACT_SET) && pmpriv->uap_bss_started) { PRINTM(MIOCTL, "11D setting cannot be changed while UAP bss is started.\n"); pioctl_req->data_read_written = 0; LEAVE(); return MLAN_STATUS_FAILURE; } snmp = (mlan_ds_snmp_mib *) pioctl_req->pbuf; flag = (snmp->param.oid_value) ? ENABLE_11D : DISABLE_11D; ret = wlan_11d_enable(pmpriv, (t_void *) pioctl_req, flag); if (ret == MLAN_STATUS_SUCCESS) ret = MLAN_STATUS_PENDING; LEAVE(); return ret; }