software/drivers/sd8887/src/wlan/mlinux/moal_uap_cfg80211.c
/**
 * @brief channel switch

 * @param wiphy           A pointer to wiphy structure
 * @param dev             A pointer to net_device structure
 * @param params		  A pointer to cfg80211_csa_settings structure
 *
 * @return                0 -- success, otherwise fail
 */
@brief channel switch
@param wiphy           A pointer to wiphy structure
@param dev             A pointer to net_device structure
@param params                  A pointer to cfg80211_csa_settings structure

@return                0 -- success, otherwise fail
@brief channel switch @param wiphy A pointer to wiphy structure @param dev A pointer to net_device structure @param params A pointer to cfg80211_csa_settings structure @return 0 -- success otherwise fail
int
woal_cfg80211_channel_switch(struct wiphy *wiphy,
			     struct net_device *dev,
			     struct cfg80211_csa_settings *params)
{
	int ret = 0;
	moal_private *priv = (moal_private *)woal_get_netdev_priv(dev);
	t_u32 chsw_msec;
	mlan_uap_bss_param *bss_cfg = NULL;
	ENTER();
	if (!params) {
		ret = -EINVAL;
		goto done;
	}
	if (params->radar_required) {
		PRINTM(MMSG,
		       " hostapd handle this case by disable and re-enable interface\n");
		ret = -ENOTSUPP;
		goto done;
	}
	if (cfg80211_chandef_identical(&params->chandef, &priv->chan)) {
		PRINTM(MMSG,
		       "csa channel is same with current channel, invaild\n");
		ret = -EINVAL;
		goto done;
	}
	bss_cfg = kzalloc(sizeof(mlan_uap_bss_param), GFP_ATOMIC);
	if (!bss_cfg) {
		PRINTM(MERROR, "Fail to alloc memory for mlan_uap_bss_param\n");
		ret = -EFAULT;
		goto done;
	}
	if (params->block_tx) {
		if (netif_carrier_ok(dev))
			netif_carrier_off(dev);
		woal_stop_queue(dev);
		priv->uap_tx_blocked = MTRUE;
	}
	woal_clear_all_mgmt_ies(priv, MOAL_IOCTL_WAIT);
	if (woal_cfg80211_set_beacon(wiphy, dev, &params->beacon_csa)) {
		PRINTM(MERROR, "%s: setting csa mgmt ies failed\n", __func__);
		goto done;
	}
	memcpy(&priv->csa_chan, &params->chandef,
	       sizeof(struct cfg80211_chan_def));
	memcpy(&priv->beacon_after, &params->beacon_after,
	       sizeof(struct cfg80211_beacon_data));
	if (!priv->phandle->fw_ecsa_enable) {
		if (MLAN_STATUS_SUCCESS !=
		    woal_set_get_sys_config(priv, MLAN_ACT_GET, MOAL_IOCTL_WAIT,
					    bss_cfg)) {
			PRINTM(MERROR, "%s: get uap config failed\n", __func__);
			ret = -EFAULT;
			goto done;
		}
		chsw_msec = params->count * bss_cfg->beacon_period;
		queue_delayed_work(priv->csa_workqueue, &priv->csa_work,
				   msecs_to_jiffies(chsw_msec));
	}
done:
	kfree(bss_cfg);
	LEAVE();
	return ret;
}
int woal_cfg80211_channel_switch ( struct wiphy * wiphy , struct net_device * dev , struct cfg80211_csa_settings * params ) { int ret = 0 ; moal_private * priv = ( moal_private * ) woal_get_netdev_priv ( dev ) ; t_u32 chsw_msec ; mlan_uap_bss_param * bss_cfg = NULL ; ENTER ( ) ; if ( ! params ) { ret = - EINVAL ; goto done ; } if ( params -> radar_required ) { PRINTM ( MMSG , " \n " ) ; ret = - ENOTSUPP ; goto done ; } if ( cfg80211_chandef_identical ( & params -> chandef , & priv -> chan ) ) { PRINTM ( MMSG , " \n " ) ; ret = - EINVAL ; goto done ; } bss_cfg = kzalloc ( sizeof ( mlan_uap_bss_param ) , GFP_ATOMIC ) ; if ( ! bss_cfg ) { PRINTM ( MERROR , " \n " ) ; ret = - EFAULT ; goto done ; } if ( params -> block_tx ) { if ( netif_carrier_ok ( dev ) ) netif_carrier_off ( dev ) ; woal_stop_queue ( dev ) ; priv -> uap_tx_blocked = MTRUE ; } woal_clear_all_mgmt_ies ( priv , MOAL_IOCTL_WAIT ) ; if ( woal_cfg80211_set_beacon ( wiphy , dev , & params -> beacon_csa ) ) { PRINTM ( MERROR , " \n " , __func__ ) ; goto done ; } memcpy ( & priv -> csa_chan , & params -> chandef , sizeof ( struct cfg80211_chan_def ) ) ; memcpy ( & priv -> beacon_after , & params -> beacon_after , sizeof ( struct cfg80211_beacon_data ) ) ; if ( ! priv -> phandle -> fw_ecsa_enable ) { if ( MLAN_STATUS_SUCCESS != woal_set_get_sys_config ( priv , MLAN_ACT_GET , MOAL_IOCTL_WAIT , bss_cfg ) ) { PRINTM ( MERROR , " \n " , __func__ ) ; ret = - EFAULT ; goto done ; } chsw_msec = params -> count * bss_cfg -> beacon_period ; queue_delayed_work ( priv -> csa_workqueue , & priv -> csa_work , msecs_to_jiffies ( chsw_msec ) ) ; } done : kfree ( bss_cfg ) ; LEAVE ( ) ; return ret ; }
@brief channel switch
 @param wiphy           A pointer to wiphy structure
 @param dev             A pointer to net_device structure
 @param params                  A pointer to cfg80211_csa_settings structure
@brief channel switch @param wiphy A pointer to wiphy structure @param dev A pointer to net_device structure @param params A pointer to cfg80211_csa_settings structure
/* TODO: support this case in next version */ /* actually hostapd would always choose one diff channel */