/**
 *  @brief Callback to finish 11H channel check handling.
 *  Not to be called directly to initiate channel check.
 *
 *  @param priv A pointer to mlan_private structure (cast from t_void*)
 *
 *  @return     MLAN_STATUS_SUCCESS/PENDING --success, otherwise fail
 *  @sa         wlan_uap_11h_channel_check_req
 */
static mlan_status
wlan_uap_callback_11h_channel_check_req(IN t_void * priv)
{
	mlan_status ret = MLAN_STATUS_FAILURE;
	mlan_private *pmpriv = (mlan_private *) priv;
	mlan_callbacks *pcb = (mlan_callbacks *) & pmpriv->adapter->callbacks;
	wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb;
	/* keep copy as local variable */
	pmlan_ioctl_req pioctl = puap_state_chan_cb->pioctl_req_curr;

	ENTER();
	/* clear callback now that we're here */
	puap_state_chan_cb->get_chan_callback = MNULL;
	/* clear early to avoid race condition */
	puap_state_chan_cb->pioctl_req_curr = MNULL;

	/*
	 * Check if the region and channel requires a channel availability
	 * check.
	 */
	if ((puap_state_chan_cb->band_config & BAND_CONFIG_5GHZ) &&
	    wlan_11h_radar_detect_required(pmpriv, puap_state_chan_cb->channel)
	    && !wlan_11h_is_channel_under_nop(pmpriv->adapter,
					      puap_state_chan_cb->channel)) {

		/*
		 * Radar detection is required for this channel, make sure
		 * 11h is activated in the firmware
		 */
		ret = wlan_11h_activate(pmpriv, MNULL, MTRUE);
		ret = wlan_11h_config_master_radar_det(pmpriv, MTRUE);
		ret = wlan_11h_check_update_radar_det_state(pmpriv);

		/* Check for radar on the channel */
		ret = wlan_11h_issue_radar_detect(pmpriv,
						  pioctl,
						  puap_state_chan_cb->channel);
		if (ret == MLAN_STATUS_SUCCESS)
			ret = MLAN_STATUS_PENDING;
	} else {
		/* No command sent with the ioctl, need manually signal
		   completion */
		pcb->moal_ioctl_complete(pmpriv->adapter->pmoal_handle,
					 pioctl, MLAN_STATUS_FAILURE);
	}

	LEAVE();
	return ret;
}
/**
 *  @brief Callback to finish 11H handling
 *  Not to be called directly to initiate 11H setting.
 *
 *  @param pmpriv   A pointer to mlan_private structure (cast from t_void*)
 *
 *  @return     MLAN_STATUS_PENDING --success, otherwise fail
 *  @sa         wlan_uap_snmp_mib_11h
 */
static mlan_status
wlan_uap_callback_snmp_mib_11h(IN t_void * priv)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_private *pmpriv = (mlan_private *) priv;
    wlan_uap_get_info_cb_t *puap_state_chan_cb = &pmpriv->uap_state_chan_cb;
    mlan_ds_snmp_mib *snmp;
    t_bool enable_11h;

    ENTER();
    /* clear callback now that we're here */
    puap_state_chan_cb->get_chan_callback = MNULL;

    snmp = (mlan_ds_snmp_mib *) puap_state_chan_cb->pioctl_req_curr->pbuf;
    enable_11h = (snmp->param.oid_value) ? MTRUE : MFALSE;

    if (enable_11h) {
        if ((puap_state_chan_cb->band_config & BAND_CONFIG_5GHZ) &&
            wlan_11h_radar_detect_required(pmpriv,
                                           puap_state_chan_cb->channel)) {
            if (!wlan_11h_is_master_radar_det_active(pmpriv))
                wlan_11h_config_master_radar_det(pmpriv, MTRUE);
        }
    }

    ret =
        wlan_11h_activate(pmpriv,
                          (t_void *) puap_state_chan_cb->pioctl_req_curr,
                          enable_11h);
    wlan_11h_check_update_radar_det_state(pmpriv);
    if (ret == MLAN_STATUS_SUCCESS)
        ret = MLAN_STATUS_PENDING;

    puap_state_chan_cb->pioctl_req_curr = MNULL;        // prevent re-use
    LEAVE();
    return ret;
}
/**
 *  @brief This function handles disconnect event, reports disconnect
 *          to upper layer, cleans tx/rx packets,
 *          resets link state etc.
 *
 *  @param priv             A pointer to mlan_private structure
 *  @param drv_disconnect   Flag indicating the driver should disconnect
 *                          and flush pending packets.
 *
 *  @return                 N/A
 */
t_void
wlan_reset_connect_state(pmlan_private priv, t_u8 drv_disconnect)
{
	mlan_adapter *pmadapter = priv->adapter;
	mlan_status ret = MLAN_STATUS_SUCCESS;
	state_11d_t enable;

	ENTER();

	PRINTM(MINFO, "Handles disconnect event.\n");

	if (drv_disconnect) {
		priv->media_connected = MFALSE;
		wlan_11h_check_update_radar_det_state(priv);
	}

	if (priv->port_ctrl_mode == MTRUE) {
		/* Close the port on Disconnect */
		PRINTM(MINFO, "DISC: port_status = CLOSED\n");
		priv->port_open = MFALSE;
	}
	pmadapter->scan_block = MFALSE;

	/* Reset SNR/NF/RSSI values */
	priv->data_rssi_last = 0;
	priv->data_nf_last = 0;
	priv->data_rssi_avg = 0;
	priv->data_nf_avg = 0;
	priv->bcn_rssi_last = 0;
	priv->bcn_nf_last = 0;
	priv->bcn_rssi_avg = 0;
	priv->bcn_nf_avg = 0;
	priv->rxpd_rate = 0;
	priv->rxpd_rate_info = 0;
	priv->max_amsdu = 0;
	wlan_coex_ampdu_rxwinsize(pmadapter);

	priv->sec_info.ewpa_enabled = MFALSE;
	priv->sec_info.wpa_enabled = MFALSE;
	priv->sec_info.wpa2_enabled = MFALSE;
	priv->wpa_ie_len = 0;

	priv->sec_info.wapi_enabled = MFALSE;
	priv->wapi_ie_len = 0;
	priv->sec_info.wapi_key_on = MFALSE;

	priv->wps.session_enable = MFALSE;
	memset(priv->adapter, (t_u8 *)&priv->wps.wps_ie, 0x00,
	       sizeof(priv->wps.wps_ie));
	priv->sec_info.osen_enabled = MFALSE;
	priv->osen_ie_len = 0;

	priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE;

	/* Enable auto data rate */
	priv->is_data_rate_auto = MTRUE;
	priv->data_rate = 0;

	if (priv->bss_mode == MLAN_BSS_MODE_IBSS) {
		priv->adhoc_state = ADHOC_IDLE;
		priv->adhoc_is_link_sensed = MFALSE;
		priv->intf_state_11h.adhoc_auto_sel_chan = MTRUE;
	}

	if (drv_disconnect) {
		/* Free Tx and Rx packets, report disconnect to upper layer */
		wlan_clean_txrx(priv);

		/* Need to erase the current SSID and BSSID info */
		memset(pmadapter,
		       &priv->curr_bss_params, 0x00,
		       sizeof(priv->curr_bss_params));
	}
	wlan_send_tdls_tear_down_request(priv);
	wlan_delete_station_list(priv);
	pmadapter->tdls_status = TDLS_NOT_SETUP;
	priv->wmm_qosinfo = priv->saved_wmm_qosinfo;
	pmadapter->sleep_period.period = pmadapter->saved_sleep_period.period;
	pmadapter->tx_lock_flag = MFALSE;
	pmadapter->pps_uapsd_mode = MFALSE;
	pmadapter->delay_null_pkt = MFALSE;

	if ((wlan_11d_is_enabled(priv)) &&
	    (priv->state_11d.user_enable_11d == DISABLE_11D)) {

		priv->state_11d.enable_11d = DISABLE_11D;
		enable = DISABLE_11D;

		/* Send cmd to FW to enable/disable 11D function */
		ret = wlan_prepare_cmd(priv,
				       HostCmd_CMD_802_11_SNMP_MIB,
				       HostCmd_ACT_GEN_SET,
				       Dot11D_i, MNULL, &enable);
		if (ret)
			PRINTM(MERROR, "11D: Failed to enable 11D\n");
	}
	if (pmadapter->num_cmd_timeout && pmadapter->curr_cmd &&
	    (pmadapter->cmd_timer_is_set == MFALSE)) {
		LEAVE();
		return;
	}

	wlan_recv_event(priv, MLAN_EVENT_ID_FW_DISCONNECTED, MNULL);

	LEAVE();
}