Beispiel #1
0
/**
 *  @brief Perform a radar measurement and report the result if required on
 *         given channel
 *
 *  Check to see if the provided channel requires a channel availability
 *    check (60 second radar detection measurement).  If required, perform
 *    measurement, stalling calling thread until the measurement completes
 *    and then report result.
 *
 *  Used when starting an adhoc network.
 *
 *  @param priv    Private driver information structure
 *  @param channel Channel on which to perform radar measurement
 *
 *  @return
 *    - MTRUE if radar has been detected
 *    - MFALSE if radar detection is not required or radar has not been detected
 *
 *  @sa wlan_11h_radar_detect_required
 */
int
wlan_11h_radar_detected(mlan_private * priv, t_u8 channel)
{
    int ret;
    HostCmd_DS_MEASUREMENT_REQUEST meas_req;
    HostCmd_DS_MEASUREMENT_REPORT meas_rpt;

    ENTER();

    /* 
     * If the channel requires radar, default the return value to it being
     *   detected.
     */
    ret = wlan_11h_radar_detect_required(priv, channel);

    memset(&meas_req, 0x00, sizeof(meas_req));
    memset(&meas_rpt, 0x00, sizeof(meas_rpt));

    /* 
     * Send a basic measurement request on the indicated channel for the
     *   required channel availability check time.
     */
    meas_req.meas_type = WLAN_MEAS_BASIC;
    meas_req.req.basic.channel = channel;
    meas_req.req.basic.duration = WLAN_11H_CHANNEL_AVAIL_CHECK_DURATION;

    /* 
     * Set the STA that we are requesting the measurement from to our own
     *   mac address, causing our firmware to perform the measurement itself
     */
    memcpy(meas_req.mac_addr, priv->curr_addr, sizeof(meas_req.mac_addr));

    /* 
     * Send the measurement request and timeout duration to wait for
     *   the command to spend until the measurement report is received
     *   from the firmware.  If the command fails, the default ret value set
     *   above will be returned.
     */
    if (!wlan_meas_util_send_req(priv, &meas_req,
                                 meas_req.req.basic.duration, &meas_rpt)) {
        /* 
         * If the report indicates no measurement was done, leave the default
         *   return value alone.
         */
        if (!meas_rpt.rpt.basic.map.unmeasured)
            /* 
             * Set the return value based on the radar indication bit
             */
            ret = meas_rpt.rpt.basic.map.radar ? MTRUE : MFALSE;

    }

    LEAVE();
    return ret;
}
/**
 *  @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;
}
Beispiel #3
0
/**
 *  @brief This function Checks if channel txpwr is learned from AP/IBSS
 *
 *  @param pmadapter            A pointer to mlan_adapter structure
 *  @param band                 Band number
 *  @param chan                 Channel number
 *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t
 *
 *  @return                     MTRUE or MFALSE
 */
static t_u8
wlan_11d_channel_known(pmlan_adapter pmadapter,
		       t_u8 band,
		       t_u8 chan, parsed_region_chan_11d_t * parsed_region_chan)
{
	chan_power_11d_t *pchan_pwr = parsed_region_chan->chan_pwr;
	t_u8 no_of_chan = parsed_region_chan->no_of_chan;
	t_u8 i = 0;
	t_u8 ret = MFALSE;
	mlan_private *pmpriv;

	ENTER();

	HEXDUMP("11D: parsed_region_chan", (t_u8 *) pchan_pwr,
		sizeof(chan_power_11d_t) * no_of_chan);

	/* Search channel */
	for (i = 0; i < no_of_chan; i++) {
		if (chan == pchan_pwr[i].chan && band == pchan_pwr[i].band) {
			PRINTM(MINFO, "11D: Found channel:%d (band:%d)\n", chan,
			       band);
			ret = MTRUE;

			if (band & BAND_A) {
				/* If chan is a DFS channel, we need to see an
				   AP on it */
				pmpriv = wlan_get_priv(pmadapter,
						       MLAN_BSS_ROLE_STA);
				if (pmpriv &&
				    wlan_11h_radar_detect_required(pmpriv,
								   chan)) {
					PRINTM(MINFO,
					       "11H: DFS channel %d, and ap_seen=%d\n",
					       chan, pchan_pwr[i].ap_seen);
					ret = pchan_pwr[i].ap_seen;
				}
			}

			LEAVE();
			return ret;
		}
	}

	PRINTM(MINFO, "11D: Could not find channel:%d (band:%d)\n", chan, band);
	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 Callback to finish BSS IOCTL START
 *  Not to be called directly to initiate bss_start
 *
 *  @param priv A pointer to mlan_private structure (cast from t_void*)
 *
 *  @return     MLAN_STATUS_PENDING --success, otherwise fail
 *  @sa         wlan_uap_bss_ioctl_start
 */
static mlan_status
wlan_uap_callback_bss_ioctl_start(IN t_void * priv)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    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;
    t_u8 old_channel;

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

    /*
     * Check if the region and channel requires we check for radar.
     */
    if ((puap_state_chan_cb->band_config & BAND_CONFIG_5GHZ) &&
        wlan_11h_radar_detect_required(pmpriv, puap_state_chan_cb->channel)) {
        /* first check if channel is under NOP */
        if (wlan_11h_is_channel_under_nop(pmpriv->adapter,
                                          puap_state_chan_cb->channel)) {
            /* recently we've seen radar on this channel */
            ret = MLAN_STATUS_FAILURE;
        }

        /* Check cached radar check on the channel */
        if (ret == MLAN_STATUS_SUCCESS)
            ret =
                wlan_11h_check_chan_report(pmpriv, puap_state_chan_cb->channel);

        /* Found radar: try to switch to a non-dfs channel */
        if (ret != MLAN_STATUS_SUCCESS) {
            old_channel = puap_state_chan_cb->channel;
            ret =
                wlan_11h_switch_non_dfs_chan(pmpriv,
                                             &puap_state_chan_cb->channel);

            if (ret == MLAN_STATUS_SUCCESS) {
                ret = wlan_uap_set_channel(pmpriv,
                                           pmpriv->uap_state_chan_cb.
                                           band_config,
                                           puap_state_chan_cb->channel);
                if (ret == MLAN_STATUS_SUCCESS) {
                    PRINTM(MMSG, "Radar found on channel %d,"
                           "switch to new channel %d.\n",
                           old_channel, puap_state_chan_cb->channel);
                } else {
                    PRINTM(MMSG, "Radar found on channel %d,"
                           " switch to new channel %d failed.\n",
                           old_channel, puap_state_chan_cb->channel);
                    pcb->moal_ioctl_complete(pmpriv->adapter->pmoal_handle,
                                             puap_state_chan_cb->
                                             pioctl_req_curr,
                                             MLAN_STATUS_FAILURE);
                    goto done;
                }
            } else {
                PRINTM(MMSG,
                       "Radar found on channel %d, no switch channel available.\n",
                       old_channel);
                /* No command sent with the ioctl, need manually signal
                   completion */
                pcb->moal_ioctl_complete(pmpriv->adapter->pmoal_handle,
                                         puap_state_chan_cb->pioctl_req_curr,
                                         MLAN_STATUS_FAILURE);
                goto done;
            }
        } else {
            PRINTM(MINFO, "No Radar found on channel %d\n",
                   puap_state_chan_cb->channel);
        }
    }

    /* else okay to send command: not DFS channel or no radar */
    ret = wlan_prepare_cmd(pmpriv,
                           HOST_CMD_APCMD_BSS_START,
                           HostCmd_ACT_GEN_SET,
                           0,
                           (t_void *) puap_state_chan_cb->pioctl_req_curr,
                           MNULL);
    if (ret == MLAN_STATUS_SUCCESS)
        ret = MLAN_STATUS_PENDING;

  done:
    puap_state_chan_cb->pioctl_req_curr = MNULL;        // prevent re-use
    LEAVE();
    return ret;
}