Esempio n. 1
0
/** 
 *  @brief Set wapi enable
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param enable               MTRUE or MFALSE
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_set_wapi_enable(moal_private * priv, t_u8 wait_option, t_u32 enable)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_WAPI_ENABLED;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_SET;
    sec->param.wapi_enabled = enable;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}
Esempio n. 2
0
/** 
 *  @brief Get uap statistics 
 *   
 *  @param priv 		        A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param ustats               A pointer to mlan_ds_uap_stats structure
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail 
 */
mlan_status
woal_uap_get_stats(moal_private * priv, t_u8 wait_option,
                   mlan_ds_uap_stats * ustats)
{
    mlan_ds_get_info *info = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (req == NULL) {
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    info = (mlan_ds_get_info *) req->pbuf;
    info->sub_command = MLAN_OID_GET_STATS;
    req->req_id = MLAN_IOCTL_GET_INFO;
    req->action = MLAN_ACT_GET;

    status = woal_request_ioctl(priv, req, wait_option);
    if (status == MLAN_STATUS_SUCCESS) {
        if (ustats)
            memcpy(ustats, &info->param.ustats, sizeof(mlan_ds_uap_stats));
    }

    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);

    LEAVE();
    return status;
}
Esempio n. 3
0
/**
 *  @brief Cancel Host Sleep configuration
 *
 *  @param priv             A pointer to moal_private structure
 *  @param wait_option      wait option
 *
 *  @return      MLAN_STATUS_SUCCESS, MLAN_STATUS_PENDING,
 *                      or MLAN_STATUS_FAILURE          
 */
mlan_status
woal_hs_cfg_cancel(moal_private * priv, t_u8 wait_option)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_ioctl_req *req = NULL;
    mlan_ds_pm_cfg *pmcfg = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
    pmcfg->sub_command = MLAN_OID_PM_CFG_HS_CFG;
    req->req_id = MLAN_IOCTL_PM_CFG;
    req->action = MLAN_ACT_SET;

    /* Get current Host Sleep configuration */
    woal_get_hs_params(priv, wait_option, &pmcfg->param.hs_cfg);

    pmcfg->param.hs_cfg.conditions = HOST_SLEEP_CFG_CANCEL;
    pmcfg->param.hs_cfg.is_invoke_hostcmd = MTRUE;

    ret = woal_request_ioctl(priv, req, wait_option);

    if (ret != MLAN_STATUS_PENDING)
        kfree(req);

  done:
    LEAVE();
    return ret;
}
Esempio n. 4
0
/**
 *  @brief uap BSS control ioctl handler
 *   
 *  @param priv             A pointer to moal_private structure
 *  @param wait_option      Wait option
 *  @param data             BSS control type
 *  @return                 0 --success, otherwise fail
 */
int
woal_uap_bss_ctrl(moal_private * priv, t_u8 wait_option, int data)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    int ret = 0;

    ENTER();

    PRINTM(MIOCTL, "ioctl bss ctrl=%d\n", data);
    if ((data != UAP_BSS_START) && (data != UAP_BSS_STOP) &&
        (data != UAP_BSS_RESET)) {
        PRINTM(MERROR, "Invalid parameter: %d\n", data);
        ret = -EINVAL;
        goto done;
    }

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    bss = (mlan_ds_bss *) req->pbuf;
    switch (data) {
    case UAP_BSS_START:
        if (priv->bss_started == MTRUE) {
            PRINTM(MWARN, "Warning: BSS already started!\n");
            // goto done;
        }
        bss->sub_command = MLAN_OID_BSS_START;
        break;
    case UAP_BSS_STOP:
        if (priv->bss_started == MFALSE) {
            PRINTM(MWARN, "Warning: BSS already stopped!\n");
            // goto done;
        }
        bss->sub_command = MLAN_OID_BSS_STOP;
        break;
    case UAP_BSS_RESET:
        bss->sub_command = MLAN_OID_UAP_BSS_RESET;
        break;
    }
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_SET;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (data == UAP_BSS_STOP || data == UAP_BSS_RESET)
        priv->bss_started = MFALSE;

  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}
Esempio n. 5
0
/** 
 *  @brief uAP set WAPI flag ioctl
 *   
 *  @param priv      A pointer to moal_private structure
 *  @param msg       A pointer to wapi_msg structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_uap_set_wapi_flag_ioctl(moal_private * priv, wapi_msg * msg)
{
    t_u8 wapi_psk_ie[] =
        { 0x44, 0x14, 0x01, 0x00, 0x01, 0x00, 0x00, 0x14, 0x72, 0x02,
        0x01, 0x00, 0x00, 0x14, 0x72, 0x01, 0x00, 0x14, 0x72, 0x01,
        0x00, 0x00
    };
    t_u8 wapi_cert_ie[] =
        { 0x44, 0x14, 0x01, 0x00, 0x01, 0x00, 0x00, 0x14, 0x72, 0x01,
        0x01, 0x00, 0x00, 0x14, 0x72, 0x01, 0x00, 0x14, 0x72, 0x01,
        0x00, 0x00
    };
    mlan_ds_misc_cfg *misc = NULL;
    mlan_ioctl_req *req = NULL;
    int ret = 0;

    ENTER();

    woal_uap_bss_ctrl(priv, MOAL_IOCTL_WAIT, UAP_BSS_STOP);

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    misc = (mlan_ds_misc_cfg *) req->pbuf;
    misc->sub_command = MLAN_OID_MISC_GEN_IE;
    req->req_id = MLAN_IOCTL_MISC_CFG;
    req->action = MLAN_ACT_SET;

    misc->param.gen_ie.type = MLAN_IE_TYPE_GEN_IE;
    misc->param.gen_ie.len = sizeof(wapi_psk_ie);
    if (msg->msg[0] & WAPI_MODE_PSK) {
        memcpy(misc->param.gen_ie.ie_data, wapi_psk_ie, misc->param.gen_ie.len);
    } else if (msg->msg[0] & WAPI_MODE_CERT) {
        memcpy(misc->param.gen_ie.ie_data, wapi_cert_ie,
               misc->param.gen_ie.len);
    } else if (msg->msg[0] == 0) {
        /* disable WAPI in driver */
        if (MLAN_STATUS_SUCCESS !=
            woal_set_wapi_enable(priv, MOAL_IOCTL_WAIT, 0))
            ret = -EFAULT;
        woal_enable_wapi(priv, MFALSE);
        goto done;
    } else {
        ret = -EINVAL;
        goto done;
    }
    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    woal_enable_wapi(priv, MTRUE);
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}
Esempio n. 6
0
/** 
 *  @brief Get version 
 *   
 *  @param priv 		A pointer to moal_private structure
 *  @param version		A pointer to version buffer
 *  @param max_len		max length of version buffer
 *
 *  @return 	   		N/A
 */
void
woal_uap_get_version(moal_private * priv, char *version, int max_len)
{
    mlan_ds_get_info *info = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (req == NULL) {
        LEAVE();
        return;
    }

    info = (mlan_ds_get_info *) req->pbuf;
    info->sub_command = MLAN_OID_GET_VER_EXT;
    req->req_id = MLAN_IOCTL_GET_INFO;
    req->action = MLAN_ACT_GET;

    status = woal_request_ioctl(priv, req, MOAL_PROC_WAIT);
    if (status == MLAN_STATUS_SUCCESS) {
        PRINTM(MINFO, "MOAL UAP VERSION: %s\n",
               info->param.ver_ext.version_str);
        snprintf(version, max_len, driver_version,
                 info->param.ver_ext.version_str);
    }

    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);

    LEAVE();
    return;
}
/**
 *  @brief Notify mlan BSS will be removed.
 *
 *  @param priv          A pointer to moal_private structure
 *
 *  @return              MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, otherwise fail
 */
mlan_status
woal_bss_remove(moal_private *priv)
{
	mlan_ioctl_req *req = NULL;
	mlan_ds_bss *bss = NULL;
	mlan_status status;

	ENTER();

	/* Allocate an IOCTL request buffer */
	req = (mlan_ioctl_req *)woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (req == NULL) {
		status = MLAN_STATUS_FAILURE;
		goto done;
	}

	/* Fill request buffer */
	bss = (mlan_ds_bss *)req->pbuf;
	bss->sub_command = MLAN_OID_BSS_REMOVE;
	req->req_id = MLAN_IOCTL_BSS;
	req->action = MLAN_ACT_SET;
	/* Send IOCTL request to MLAN */
	status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(req);
	LEAVE();
	return status;
}
Esempio n. 8
0
/**
 * @brief Set/Get radio
 * 
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 * 
 * @return           0 --success, otherwise fail
 */
static int
woal_uap_radio_ctl(struct net_device *dev, struct ifreq *req)
{
    moal_private *priv = (moal_private *) netdev_priv(dev);
    int ret = 0;
    mlan_ds_radio_cfg *radio = NULL;
    mlan_ioctl_req *mreq = NULL;
    int data[2] = { 0, 0 };
    mlan_bss_info bss_info;

    ENTER();

    /* Sanity check */
    if (req->ifr_data == NULL) {
        PRINTM(MERROR, "uap_radio_ctl() corrupt data\n");
        ret = -EFAULT;
        goto done;
    }

    /* Get user data */
    if (copy_from_user(&data, req->ifr_data, sizeof(data))) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    if (data[0]) {
        mreq = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
        if (mreq == NULL) {
            ret = -ENOMEM;
            goto done;
        }
        radio = (mlan_ds_radio_cfg *) mreq->pbuf;
        radio->sub_command = MLAN_OID_RADIO_CTRL;
        mreq->req_id = MLAN_IOCTL_RADIO_CFG;
        mreq->action = MLAN_ACT_SET;
        radio->param.radio_on_off = (t_u32) data[1];
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, mreq, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
        }
        if (mreq)
            kfree(mreq);
    } else {
        /* Get radio status */
        memset(&bss_info, 0, sizeof(bss_info));
        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);

        data[1] = bss_info.radio_on;
        if (copy_to_user(req->ifr_data, data, sizeof(data))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
        }
    }
  done:
    LEAVE();
    return ret;
}
Esempio n. 9
0
/** 
 *  @brief uap station deauth ioctl handler
 *   
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 *  @return         0 --success, otherwise fail
 */
static int
woal_uap_sta_deauth_ioctl(struct net_device *dev, struct ifreq *req)
{
    moal_private *priv = (moal_private *) netdev_priv(dev);
    mlan_ioctl_req *ioctl_req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_deauth_param deauth_param;
    int ret = 0;

    ENTER();

    memset(&deauth_param, 0, sizeof(mlan_deauth_param));
    /* Sanity check */
    if (req->ifr_data == NULL) {
        PRINTM(MERROR, "uap_sta_deauth_ioctl() corrupt data\n");
        ret = -EFAULT;
        goto done;
    }
    if (copy_from_user(&deauth_param, req->ifr_data, sizeof(mlan_deauth_param))) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    PRINTM(MIOCTL,
           "ioctl deauth station: %02x:%02x:%02x:%02x:%02x:%02x, reason=%d\n",
           deauth_param.mac_addr[0], deauth_param.mac_addr[1],
           deauth_param.mac_addr[2], deauth_param.mac_addr[3],
           deauth_param.mac_addr[4], deauth_param.mac_addr[5],
           deauth_param.reason_code);

    ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (ioctl_req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    bss = (mlan_ds_bss *) ioctl_req->pbuf;

    bss->sub_command = MLAN_OID_UAP_DEAUTH_STA;
    ioctl_req->req_id = MLAN_IOCTL_BSS;
    ioctl_req->action = MLAN_ACT_SET;

    memcpy(&bss->param.deauth_param, &deauth_param, sizeof(mlan_deauth_param));
    if (MLAN_STATUS_SUCCESS !=
        woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        if (copy_to_user(req->ifr_data, &ioctl_req->status_code, sizeof(t_u32)))
            PRINTM(MERROR, "Copy to user failed!\n");
        goto done;
    }

  done:
    if (ioctl_req)
        kfree(ioctl_req);
    LEAVE();
    return ret;
}
/**
 * @brief Get station info
 *
 * @param wiphy           A pointer to wiphy structure
 * @param dev             A pointer to net_device structure
 * @param mac			  A pointer to station mac address
 * @param stainfo		  A pointer to station_info structure
 *
 * @return                0 -- success, otherwise fail
 */
int
woal_uap_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                              u8 * mac, struct station_info *stainfo)
{
    moal_private *priv = (moal_private *) woal_get_netdev_priv(dev);
    int ret = -EFAULT;
    int i = 0;
    mlan_ds_get_info *info = NULL;
    mlan_ioctl_req *ioctl_req = NULL;

    ENTER();
    if (priv->media_connected == MFALSE) {
        PRINTM(MINFO, "cfg80211: Media not connected!\n");
        LEAVE();
        return -ENOENT;
    }

    /* Allocate an IOCTL request buffer */
    ioctl_req =
        (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (ioctl_req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    info = (mlan_ds_get_info *) ioctl_req->pbuf;
    info->sub_command = MLAN_OID_UAP_STA_LIST;
    ioctl_req->req_id = MLAN_IOCTL_GET_INFO;
    ioctl_req->action = MLAN_ACT_GET;

    if (MLAN_STATUS_SUCCESS !=
        woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
        goto done;
    }
    for (i = 0; i < info->param.sta_list.sta_count; i++) {
        if (!memcmp(info->param.sta_list.info[i].mac_address, mac, ETH_ALEN)) {
            PRINTM(MIOCTL,
                   "Get station: %02x:%02x:%02x:%02x:%02x:%02x RSSI=%d\n",
                   mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
                   (int) info->param.sta_list.info[i].rssi);
            stainfo->filled = STATION_INFO_INACTIVE_TIME | STATION_INFO_SIGNAL;
            stainfo->inactive_time = 0;
            stainfo->signal = info->param.sta_list.info[i].rssi;
            ret = 0;
            break;
        }
    }
  done:
    if (ioctl_req)
        kfree(ioctl_req);
    LEAVE();
    return ret;
}
Esempio n. 11
0
/** 
 *  @brief Enable/Disable wapi in firmware
 *   
 *  @param priv          A pointer to moal_private structure
 *  @param enable        MTRUE/MFALSE
 *
 *  @return              MLAN_STATUS_SUCCESS/MLAN_STATUS_PENDING -- success, otherwise fail
 */
static mlan_status
woal_enable_wapi(moal_private * priv, t_u8 enable)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_status status;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        status = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_UAP_BSS_CONFIG;
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
    if (status != MLAN_STATUS_SUCCESS) {
        PRINTM(MERROR, "Get AP setting  failed! status=%d, error_code=0x%lx\n",
               status, req->status_code);
    }

    /* Change AP default setting */
    req->action = MLAN_ACT_SET;
    if (enable == MFALSE) {
        bss->param.bss_config.auth_mode = MLAN_AUTH_MODE_OPEN;
        bss->param.bss_config.protocol = PROTOCOL_NO_SECURITY;
    } else {
        bss->param.bss_config.auth_mode = MLAN_AUTH_MODE_OPEN;
        bss->param.bss_config.protocol = PROTOCOL_WAPI;
    }

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
    if (status != MLAN_STATUS_SUCCESS) {
        PRINTM(MERROR, "Set AP setting failed! status=%d, error_code=0x%lx\n",
               status, req->status_code);
    }
    if (enable)
        woal_uap_bss_ctrl(priv, MOAL_IOCTL_WAIT, UAP_BSS_START);
  done:
    if (req)
        kfree(req);
    LEAVE();
    return status;
}
Esempio n. 12
0
/** 
 *  @brief uap get station list handler
 *   
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 *  @return         0 --success, otherwise fail
 */
static int
woal_uap_get_sta_list_ioctl(struct net_device *dev, struct ifreq *req)
{
    moal_private *priv = (moal_private *) netdev_priv(dev);
    int ret = 0;
    mlan_ds_get_info *info = NULL;
    mlan_ioctl_req *ioctl_req = NULL;

    ENTER();

    /* Sanity check */
    if (req->ifr_data == NULL) {
        PRINTM(MERROR, "uap_get_sta_list_ioctl() corrupt data\n");
        ret = -EFAULT;
        goto done;
    }

    /* Allocate an IOCTL request buffer */
    ioctl_req =
        (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (ioctl_req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    info = (mlan_ds_get_info *) ioctl_req->pbuf;
    info->sub_command = MLAN_OID_UAP_STA_LIST;
    ioctl_req->req_id = MLAN_IOCTL_GET_INFO;
    ioctl_req->action = MLAN_ACT_GET;

    if (MLAN_STATUS_SUCCESS !=
        woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (ioctl_req->action == MLAN_ACT_GET) {
        /* Copy to user : sta_list */
        if (copy_to_user
            (req->ifr_data, &info->param.sta_list, sizeof(mlan_ds_sta_list))) {
            PRINTM(MERROR, "Copy to user failed!\n");
            ret = -EFAULT;
            goto done;
        }
    }
  done:
    if (ioctl_req)
        kfree(ioctl_req);
    LEAVE();
    return ret;
}
Esempio n. 13
0
/**
 * @brief send deauth to all station
 *
 * @param                 A pointer to moal_private
 * @param mac			  A pointer to station mac address
 *
 * @return                0 -- success, otherwise fail
 */
static int
woal_deauth_all_station(moal_private *priv)
{
	int ret = -EFAULT;
	int i = 0;
	mlan_ds_get_info *info = NULL;
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();
	if (priv->media_connected == MFALSE) {
		PRINTM(MINFO, "cfg80211: Media not connected!\n");
		LEAVE();
		return 0;
	}
	PRINTM(MIOCTL, "del all station\n");
	/* Allocate an IOCTL request buffer */
	ioctl_req =
		(mlan_ioctl_req *)
		woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}

	info = (mlan_ds_get_info *)ioctl_req->pbuf;
	info->sub_command = MLAN_OID_UAP_STA_LIST;
	ioctl_req->req_id = MLAN_IOCTL_GET_INFO;
	ioctl_req->action = MLAN_ACT_GET;

	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS)
		goto done;
	if (!info->param.sta_list.sta_count)
		goto done;
	for (i = 0; i < info->param.sta_list.sta_count; i++) {
		PRINTM(MIOCTL, "deauth station " MACSTR "\n",
		       MAC2STR(info->param.sta_list.info[i].mac_address));
		ret = woal_deauth_station(priv,
					  info->param.sta_list.info[i].
					  mac_address);
	}
	woal_sched_timeout(200);
done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);
	return ret;
}
Esempio n. 14
0
/** 
 *  @brief uAP set WAPI key ioctl
 *   
 *  @param priv      A pointer to moal_private structure
 *  @param msg       A pointer to wapi_msg structure
 *
 *  @return          0 --success, otherwise fail
 */
static int
woal_uap_set_wapi_key_ioctl(moal_private * priv, wapi_msg * msg)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    int ret = 0;
    wapi_key_msg *key_msg = NULL;
    t_u8 bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

    ENTER();
    if (msg->msg_len != sizeof(wapi_key_msg)) {
        ret = -EINVAL;
        goto done;
    }
    key_msg = (wapi_key_msg *) msg->msg;

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    sec = (mlan_ds_sec_cfg *) req->pbuf;
    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
    req->req_id = MLAN_IOCTL_SEC_CFG;
    req->action = MLAN_ACT_SET;

    sec->param.encrypt_key.is_wapi_key = MTRUE;
    sec->param.encrypt_key.key_len = MLAN_MAX_KEY_LENGTH;
    memcpy(sec->param.encrypt_key.mac_addr, key_msg->mac_addr, ETH_ALEN);
    sec->param.encrypt_key.key_index = key_msg->key_id;
    if (0 == memcmp(key_msg->mac_addr, bcast_addr, ETH_ALEN))
        sec->param.encrypt_key.key_flags = KEY_FLAG_GROUP_KEY;
    else
        sec->param.encrypt_key.key_flags = KEY_FLAG_SET_TX_KEY;
    memcpy(sec->param.encrypt_key.key_material, key_msg->key,
           sec->param.encrypt_key.key_len);

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
        ret = -EFAULT;
  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}
Esempio n. 15
0
/**
 *  @brief Set/Get system configuration parameters
 *
 *  @param priv 		    A pointer to moal_private structure
 *  @param action           MLAN_ACT_SET or MLAN_ACT_GET
 *  @param sys_cfg          A pointer to mlan_uap_bss_param structure
 *
 *  @return                 MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
woal_set_get_sys_config(moal_private * priv, t_u16 action,
                        mlan_uap_bss_param * sys_cfg)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_ds_bss *bss = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_UAP_BSS_CONFIG;
    req->req_id = MLAN_IOCTL_BSS;
    req->action = action;

    if (action == MLAN_ACT_SET) {
        memcpy(&bss->param.bss_config, sys_cfg, sizeof(mlan_uap_bss_param));
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = MLAN_STATUS_FAILURE;
        goto done;
    }

    if (action == MLAN_ACT_GET) {
        memcpy(sys_cfg, &bss->param.bss_config, sizeof(mlan_uap_bss_param));
    }

  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}
Esempio n. 16
0
/** 
 *  @brief Send multicast list request to MLAN
 *   
 *  @param priv   A pointer to moal_private structure
 *  @param dev    A pointer to net_device structure                 
 *
 *  @return       None
 */
void
woal_request_set_multicast_list(moal_private * priv, struct net_device *dev)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_status status;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        PRINTM(MERROR, "%s:Fail to alloc ioctl req buffer\n", __FUNCTION__);
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_BSS_MULTICAST_LIST;
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_SET;
    if (dev->flags & IFF_PROMISC) {
        bss->param.multicast_list.mode = MLAN_PROMISC_MODE;
    } else if (dev->flags & IFF_ALLMULTI ||
               dev->mc_count > MLAN_MAX_MULTICAST_LIST_SIZE) {
        bss->param.multicast_list.mode = MLAN_ALL_MULTI_MODE;
    } else {
        bss->param.multicast_list.mode = MLAN_MULTICAST_MODE;
        if (dev->mc_count)
            bss->param.multicast_list.num_multicast_addr =
                woal_copy_mcast_addr(&bss->param.multicast_list, dev);
    }

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_NO_WAIT);
    if (status != MLAN_STATUS_PENDING)
        kfree(req);
  done:
    LEAVE();
    return;
}
Esempio n. 17
0
/** 
 *  @brief Set debug info
 *
 *  @param priv                 A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param debug_info           A pointer to mlan_debug_info structure
 *
 *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_set_debug_info(moal_private * priv, t_u8 wait_option,
                    mlan_debug_info * debug_info)
{
    int ret = 0;
    mlan_ioctl_req *req = NULL;
    mlan_ds_get_info *info = NULL;
    mlan_status status = MLAN_STATUS_SUCCESS;

    ENTER();

    if (!debug_info) {
        ret = -EINVAL;
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    info = (mlan_ds_get_info *) req->pbuf;
    info->sub_command = MLAN_OID_GET_DEBUG_INFO;
    memcpy(&info->param.debug_info, debug_info, sizeof(mlan_debug_info));
    req->req_id = MLAN_IOCTL_GET_INFO;
    req->action = MLAN_ACT_SET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
  done:
    if (req && (status != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return status;
}
Esempio n. 18
0
/** 
 *  @brief Send set MAC address request to MLAN
 *   
 *  @param priv   A pointer to moal_private structure
 *
 *  @return       MLAN_STATUS_SUCCESS -- success, otherwise fail
 */
mlan_status
woal_request_set_mac_address(moal_private * priv)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_status status;
    ENTER();

    /* Allocate an IOCTL request buffer */
    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        status = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_BSS_MAC_ADDR;
    memcpy(&bss->param.mac_addr, priv->current_addr,
           sizeof(mlan_802_11_mac_addr));
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_SET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);
    if (status == MLAN_STATUS_SUCCESS) {
        memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
        HEXDUMP("priv->MacAddr:", priv->current_addr, ETH_ALEN);
    } else {
        PRINTM(MERROR, "set mac address failed! status=%d, error_code=0x%lx\n",
               status, req->status_code);
    }
  done:
    if (req)
        kfree(req);
    LEAVE();
    return status;
}
Esempio n. 19
0
/** 
 *  @brief Send deauth command to MLAN
 *   
 *  @param priv          A pointer to moal_private structure
 *  @param wait_option          Wait option
 *  @param mac           MAC address to deauthenticate
 *
 *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail
 */
mlan_status
woal_disconnect(moal_private * priv, t_u8 wait_option, t_u8 * mac)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_status status;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        status = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_BSS_STOP;
    if (mac)
        memcpy((t_u8 *) & bss->param.bssid, mac, sizeof(mlan_802_11_mac_addr));
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_SET;

    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);

  done:
    if (req)
        kfree(req);
#ifdef REASSOCIATION
    priv->reassoc_required = MFALSE;
#endif /* REASSOCIATION */
    LEAVE();
    return status;
}
Esempio n. 20
0
/** 
 *  @brief Send bss_start command to MLAN
 *   
 *  @param priv          A pointer to moal_private structure
 *  @param wait_option          Wait option  
 *  @param ssid_bssid    A point to mlan_ssid_bssid structure
 *
 *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail
 */
mlan_status
woal_bss_start(moal_private * priv, t_u8 wait_option,
               mlan_ssid_bssid * ssid_bssid)
{
    mlan_ioctl_req *req = NULL;
    mlan_ds_bss *bss = NULL;
    mlan_status status;

    ENTER();

    /* Stop the O.S. TX queue if needed */
    if (!netif_queue_stopped(priv->netdev))
        netif_stop_queue(priv->netdev);

    /* Allocate an IOCTL request buffer */
    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (req == NULL) {
        status = MLAN_STATUS_FAILURE;
        goto done;
    }

    /* Fill request buffer */
    bss = (mlan_ds_bss *) req->pbuf;
    bss->sub_command = MLAN_OID_BSS_START;
    if (ssid_bssid)
        memcpy(&bss->param.ssid_bssid, ssid_bssid, sizeof(mlan_ssid_bssid));
    req->req_id = MLAN_IOCTL_BSS;
    req->action = MLAN_ACT_SET;
    /* Send IOCTL request to MLAN */
    status = woal_request_ioctl(priv, req, wait_option);
  done:
    if (req)
        kfree(req);
    LEAVE();
    return status;
}
Esempio n. 21
0
/** 
 *  @brief Get Host Sleep parameters
 *
 *  @param priv         A pointer to moal_private structure
 *  @param wait_option  Wait option (MOAL_WAIT or MOAL_NO_WAIT)   
 *  @param hscfg        A pointer to mlan_ds_hs_cfg structure
 *
 *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
 */
mlan_status
woal_get_hs_params(moal_private * priv, t_u8 wait_option,
                   mlan_ds_hs_cfg * hscfg)
{
    mlan_status ret = MLAN_STATUS_SUCCESS;
    mlan_ds_pm_cfg *pmcfg = NULL;
    mlan_ioctl_req *req = NULL;

    ENTER();

    /* Allocate an IOCTL request buffer */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    /* Fill request buffer */
    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
    pmcfg->sub_command = MLAN_OID_PM_CFG_HS_CFG;
    req->req_id = MLAN_IOCTL_PM_CFG;
    req->action = MLAN_ACT_GET;

    /* Send IOCTL request to MLAN */
    ret = woal_request_ioctl(priv, req, wait_option);
    if (ret == MLAN_STATUS_SUCCESS) {
        if (hscfg) {
            memcpy(hscfg, &pmcfg->param.hs_cfg, sizeof(mlan_ds_hs_cfg));
        }
    }
  done:
    if (req && (ret != MLAN_STATUS_PENDING))
        kfree(req);
    LEAVE();
    return ret;
}
Esempio n. 22
0
/**
 * @brief send deauth to station
 *
 * @param                 A pointer to moal_private
 * @param mac			  A pointer to station mac address
 *
 * @return                0 -- success, otherwise fail
 */
static int
woal_deauth_station(moal_private *priv, u8 *mac_addr)
{
	mlan_ioctl_req *ioctl_req = NULL;
	mlan_ds_bss *bss = NULL;
	int ret = 0;
	mlan_status status = MLAN_STATUS_SUCCESS;

	ENTER();

	ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
	if (ioctl_req == NULL) {
		ret = -ENOMEM;
		goto done;
	}
	bss = (mlan_ds_bss *)ioctl_req->pbuf;
	bss->sub_command = MLAN_OID_UAP_DEAUTH_STA;
	ioctl_req->req_id = MLAN_IOCTL_BSS;
	ioctl_req->action = MLAN_ACT_SET;

	memcpy(bss->param.deauth_param.mac_addr, mac_addr,
	       MLAN_MAC_ADDR_LENGTH);
#define  REASON_CODE_DEAUTH_LEAVING 3
	bss->param.deauth_param.reason_code = REASON_CODE_DEAUTH_LEAVING;
	status = woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT);
	if (status != MLAN_STATUS_SUCCESS) {
		ret = -EFAULT;
		goto done;
	}

done:
	if (status != MLAN_STATUS_PENDING)
		kfree(ioctl_req);
	LEAVE();
	return ret;
}
Esempio n. 23
0
/**
 *  @brief  Extended version of encoding configuration
 *
 *  @param dev          A pointer to net_device structure
 *  @param info         A pointer to iw_request_info structure
 *  @param dwrq         A pointer to iw_point structure
 *  @param extra        A pointer to extra data buf
 *
 *  @return              0 --success, otherwise fail
 */
static int
woal_set_encode_ext(struct net_device *dev,
		    struct iw_request_info *info,
		    struct iw_point *dwrq, char *extra)
{
	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
	moal_private *priv = (moal_private *) netdev_priv(dev);
	int key_index;
	t_u8 *pkey_material = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_ds_sec_cfg *sec = NULL;
	mlan_uap_bss_param sys_cfg;
	wep_key *pwep_key = NULL;
	int ret = 0;

	ENTER();

	key_index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
	if (key_index < 0 || key_index > 5) {
		ret = -EINVAL;
		goto done;
	}
	if (ext->key_len > (dwrq->length - sizeof(struct iw_encode_ext))) {
		ret = -EINVAL;
		goto done;
	}

	/* Initialize the invalid values so that the correct values below are
	   downloaded to firmware */
	woal_set_sys_config_invalid_data(&sys_cfg);

	pkey_material = (t_u8 *) (ext + 1);
	/* Disable Key */
	if ((dwrq->flags & IW_ENCODE_DISABLED) && !ext->key_len) {
		sys_cfg.protocol = PROTOCOL_NO_SECURITY;
	} else if (ext->alg == IW_ENCODE_ALG_WEP) {
		sys_cfg.protocol = PROTOCOL_STATIC_WEP;
		/* Set WEP key */
		switch (key_index) {
		case 0:
			pwep_key = &sys_cfg.wep_cfg.key0;
			break;
		case 1:
			pwep_key = &sys_cfg.wep_cfg.key1;
			break;
		case 2:
			pwep_key = &sys_cfg.wep_cfg.key2;
			break;
		case 3:
			pwep_key = &sys_cfg.wep_cfg.key3;
			break;
		}
		if (pwep_key) {
			pwep_key->key_index = key_index;
			pwep_key->is_default = MTRUE;
			pwep_key->length = ext->key_len;
			memcpy(pwep_key->key, pkey_material, ext->key_len);
		}
	} else {
		/* Set GTK/PTK key */
		req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
		if (req == NULL) {
			ret = -ENOMEM;
			goto done;
		}
		sec = (mlan_ds_sec_cfg *) req->pbuf;
		sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
		req->req_id = MLAN_IOCTL_SEC_CFG;
		req->action = MLAN_ACT_SET;
		sec->param.encrypt_key.key_len = ext->key_len;
		sec->param.encrypt_key.key_index = key_index;
		memcpy(sec->param.encrypt_key.key_material, pkey_material,
		       ext->key_len);
		memcpy(sec->param.encrypt_key.mac_addr, ext->addr.sa_data,
		       ETH_ALEN);
		sec->param.encrypt_key.key_flags = ext->ext_flags;
		if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
			memcpy(sec->param.encrypt_key.pn, (t_u8 *) ext->rx_seq,
			       SEQ_MAX_SIZE);
			DBG_HEXDUMP(MCMD_D, "Uap Rx PN",
				    sec->param.encrypt_key.pn, SEQ_MAX_SIZE);
		}
		if (ext->ext_flags & IW_ENCODE_EXT_TX_SEQ_VALID) {
			memcpy(sec->param.encrypt_key.pn, (t_u8 *) ext->tx_seq,
			       SEQ_MAX_SIZE);
			DBG_HEXDUMP(MCMD_D, "Uap Tx PN",
				    sec->param.encrypt_key.pn, SEQ_MAX_SIZE);
		}
		PRINTM(MIOCTL,
		       "set uap wpa key key_index=%d, key_len=%d key_flags=0x%x "
		       MACSTR "\n", key_index, ext->key_len,
		       sec->param.encrypt_key.key_flags,
		       MAC2STR(sec->param.encrypt_key.mac_addr));
		DBG_HEXDUMP(MCMD_D, "uap wpa key", pkey_material, ext->key_len);
#define IW_ENCODE_ALG_AES_CMAC	5

		if (ext->alg == IW_ENCODE_ALG_AES_CMAC)
			sec->param.encrypt_key.key_flags |=
				KEY_FLAG_AES_MCAST_IGTK;
		if (MLAN_STATUS_SUCCESS !=
		    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
			ret = -EFAULT;
		}
		/* Cipher set will be done in set generic IE */
		priv->pairwise_cipher = ext->alg;
		priv->group_cipher = ext->alg;
		goto done;	/* No AP configuration */
	}
	if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv,
							   MLAN_ACT_SET,
							   MOAL_IOCTL_WAIT,
							   &sys_cfg)) {
		PRINTM(MERROR, "Error setting AP confiruration\n");
		ret = -EFAULT;
		goto done;
	}

done:
	if (req)
		kfree(req);
	LEAVE();
	return ret;
}
Esempio n. 24
0
/**
 *  @brief  Request MLME operation
 *
 *  @param dev          A pointer to net_device structure
 *  @param info         A pointer to iw_request_info structure
 *  @param dwrq         A pointer to iw_point structure
 *  @param extra        A pointer to extra data buf
 *
 *  @return             0--success, otherwise fail
 */
static int
woal_set_mlme(struct net_device *dev,
	      struct iw_request_info *info, struct iw_point *dwrq, char *extra)
{
	struct iw_mlme *mlme = (struct iw_mlme *)extra;
	moal_private *priv = (moal_private *) netdev_priv(dev);
	mlan_ds_bss *bss = NULL;
	mlan_ds_get_info *pinfo = NULL;
	mlan_ioctl_req *req = NULL;
	mlan_ds_sta_list *sta_list = NULL;
	const t_u8 bc_addr[] = { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF };
	t_u8 sta_addr[ETH_ALEN];
	int ret = 0, i;

	ENTER();

	memset(sta_addr, 0, ETH_ALEN);
	if ((mlme->cmd == IW_MLME_DEAUTH) || (mlme->cmd == IW_MLME_DISASSOC)) {
		memcpy(sta_addr, (t_u8 *) mlme->addr.sa_data, ETH_ALEN);
		PRINTM(MIOCTL, "Deauth station: " MACSTR ", "
		       "reason=%d\n", MAC2STR(sta_addr), mlme->reason_code);

		/* FIXME: For flushing all stations we need to use zero MAC,
		   but right now the FW does not support this. So, manually
		   delete each one individually. */
		/* If deauth all station, get the connected STA list first */
		if (!memcmp(bc_addr, sta_addr, ETH_ALEN)) {
			PRINTM(MIOCTL, "Deauth all stations\n");
			req = woal_alloc_mlan_ioctl_req(sizeof
							(mlan_ds_get_info));
			if (req == NULL) {
				LEAVE();
				return -ENOMEM;
			}
			pinfo = (mlan_ds_get_info *) req->pbuf;
			pinfo->sub_command = MLAN_OID_UAP_STA_LIST;
			req->req_id = MLAN_IOCTL_GET_INFO;
			req->action = MLAN_ACT_GET;
			if (MLAN_STATUS_SUCCESS !=
			    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
				ret = -EFAULT;
				goto done;
			}
			sta_list =
				(mlan_ds_sta_list *)
				kmalloc(sizeof(mlan_ds_sta_list), GFP_KERNEL);
			if (sta_list == NULL) {
				PRINTM(MERROR, "Memory allocation failed!\n");
				ret = -ENOMEM;
				goto done;
			}
			memcpy(sta_list, &pinfo->param.sta_list,
			       sizeof(mlan_ds_sta_list));
			if (req) {
				kfree(req);
				req = NULL;
			}
		}
		req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
		if (req == NULL) {
			ret = -ENOMEM;
			goto done;
		}
		bss = (mlan_ds_bss *) req->pbuf;
		bss->sub_command = MLAN_OID_UAP_DEAUTH_STA;
		req->req_id = MLAN_IOCTL_BSS;
		req->action = MLAN_ACT_SET;

		if (!memcmp(bc_addr, sta_addr, ETH_ALEN)) {
			for (i = 0; i < sta_list->sta_count; i++) {
				memcpy(bss->param.deauth_param.mac_addr,
				       sta_list->info[i].mac_address, ETH_ALEN);
				bss->param.deauth_param.reason_code =
					mlme->reason_code;

				if (MLAN_STATUS_SUCCESS !=
				    woal_request_ioctl(priv, req,
						       MOAL_IOCTL_WAIT)) {
					ret = -EFAULT;
					goto done;
				}
			}
		} else {
			memcpy(bss->param.deauth_param.mac_addr, sta_addr,
			       ETH_ALEN);
			bss->param.deauth_param.reason_code = mlme->reason_code;

			if (MLAN_STATUS_SUCCESS !=
			    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
				ret = -EFAULT;
				goto done;
			}
		}
	}

done:
	if (req)
		kfree(req);
	if (sta_list)
		kfree(sta_list);

	LEAVE();
	return ret;
}
Esempio n. 25
0
/** 
 *  @brief  Extended version of encoding configuration 
 *
 *  @param dev          A pointer to net_device structure
 *  @param info         A pointer to iw_request_info structure
 *  @param dwrq         A pointer to iw_point structure
 *  @param extra        A pointer to extra data buf
 *
 *  @return              0 --success, otherwise fail
 */
static int
woal_set_encode_ext(struct net_device *dev,
                    struct iw_request_info *info,
                    struct iw_point *dwrq, char *extra)
{
    struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
    moal_private *priv = (moal_private *) netdev_priv(dev);
    int key_index;
    t_u8 *pkey_material = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_ds_sec_cfg *sec = NULL;
    mlan_uap_bss_param sys_cfg;
    wep_key *pwep_key = NULL;
    int ret = 0;

    ENTER();

    key_index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
    if (key_index < 0 || key_index > 3) {
        ret = -EINVAL;
        goto done;
    }
    if (ext->key_len > (dwrq->length - sizeof(struct iw_encode_ext))) {
        ret = -EINVAL;
        goto done;
    }

    /* Initialize the invalid values so that the correct values below are
       downloaded to firmware */
    woal_set_sys_config_invalid_data(&sys_cfg);

    pkey_material = (t_u8 *) (ext + 1);
    /* Disable Key */
    if ((dwrq->flags & IW_ENCODE_DISABLED) && !ext->key_len) {
        sys_cfg.protocol = PROTOCOL_NO_SECURITY;
    } else if (ext->alg == IW_ENCODE_ALG_WEP) {
        sys_cfg.protocol = PROTOCOL_STATIC_WEP;
        /* Set WEP key */
        switch (key_index) {
        case 0:
            pwep_key = &sys_cfg.wep_cfg.key0;
            break;
        case 1:
            pwep_key = &sys_cfg.wep_cfg.key1;
            break;
        case 2:
            pwep_key = &sys_cfg.wep_cfg.key2;
            break;
        case 3:
            pwep_key = &sys_cfg.wep_cfg.key3;
            break;
        }
        pwep_key->key_index = key_index;
        pwep_key->is_default = MTRUE;
        pwep_key->length = ext->key_len;
        memcpy(pwep_key->key, pkey_material, ext->key_len);
    } else {
        sys_cfg.protocol = PROTOCOL_WPA2_MIXED;
        if (ext->alg == IW_ENCODE_ALG_TKIP) {
            sys_cfg.wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP;
            sys_cfg.wpa_cfg.pairwise_cipher_wpa2 = CIPHER_TKIP;
            sys_cfg.wpa_cfg.group_cipher = CIPHER_TKIP;
        }
        if (ext->alg == IW_ENCODE_ALG_CCMP) {
            sys_cfg.wpa_cfg.pairwise_cipher_wpa = CIPHER_AES_CCMP;
            sys_cfg.wpa_cfg.pairwise_cipher_wpa2 = CIPHER_AES_CCMP;
            sys_cfg.wpa_cfg.group_cipher = CIPHER_AES_CCMP;
        }
        /* Set WPA key */
        req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
        if (req == NULL) {
            ret = -ENOMEM;
            goto done;
        }
        sec = (mlan_ds_sec_cfg *) req->pbuf;
        sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
        req->req_id = MLAN_IOCTL_SEC_CFG;
        req->action = MLAN_ACT_SET;
        sec->param.encrypt_key.key_len = ext->key_len;
        sec->param.encrypt_key.key_index = key_index;
        memcpy(sec->param.encrypt_key.key_material, pkey_material,
               ext->key_len);
        memcpy(sec->param.encrypt_key.mac_addr, ext->addr.sa_data, ETH_ALEN);
        if ((ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && !key_index) {
            key_index = 1;
            sec->param.encrypt_key.key_index = key_index;
            PRINTM(MWARN, "Key index changed for GTK: %ld\n",
                   sec->param.encrypt_key.key_index);
        }
        if (MLAN_STATUS_SUCCESS !=
            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
            ret = -EFAULT;
        }
    }
    if (MLAN_STATUS_SUCCESS !=
        woal_set_get_sys_config(priv, MLAN_ACT_SET, &sys_cfg)) {
        PRINTM(MERROR, "Error setting AP confiruration\n");
        ret = -EFAULT;
        goto done;
    }

  done:
    if (req)
        kfree(req);
    LEAVE();
    return ret;
}
Esempio n. 26
0
/**
 *  @brief Set IE
 *
 *  Pass an opaque block of data, expected to be IEEE IEs, to the driver 
 *    for eventual passthrough to the firmware in an associate/join 
 *    (and potentially start) command.
 *
 *  @param dev                  A pointer to net_device structure
 *  @param info                 A pointer to iw_request_info structure
 *  @param dwrq                 A pointer to iw_point structure
 *  @param extra                A pointer to extra data buf
 *
 *  @return                     0 --success, otherwise fail
 */
static int
woal_set_gen_ie(struct net_device *dev, struct iw_request_info *info,
                struct iw_point *dwrq, char *extra)
{
    int ret = 0;
    moal_private *priv = (moal_private *) netdev_priv(dev);
    mlan_ds_misc_cfg *misc = NULL;
    mlan_ioctl_req *req = NULL;
    mlan_uap_bss_param sys_cfg;
    IEEEtypes_Header_t *ie_hdr = NULL;
    IEEEtypes_Header_t *ie_hdr1 = NULL;

    ENTER();

    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
    if (req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    req->req_id = MLAN_IOCTL_MISC_CFG;
    misc = (mlan_ds_misc_cfg *) req->pbuf;
    misc->sub_command = MLAN_OID_MISC_CUSTOM_IE;
    misc->param.cust_ie.type = 0x0169;  /* TLV_TYPE_MGMT_IE */
    req->action = MLAN_ACT_SET;

    if (dwrq->length > MAX_IE_SIZE) {
        ret = -EFAULT;
        goto done;
    }
    misc->param.cust_ie.len = dwrq->length + sizeof(custom_ie) - MAX_IE_SIZE;
    misc->param.cust_ie.ie_data_list[0].ie_index = 0;
    misc->param.cust_ie.ie_data_list[0].mgmt_subtype_mask = 0xffff;
    misc->param.cust_ie.ie_data_list[0].ie_length = dwrq->length;
    memcpy(misc->param.cust_ie.ie_data_list[0].ie_buffer, extra, dwrq->length);

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    /* Initialize the invalid values so that the correct values below are
       downloaded to firmware */
    woal_set_sys_config_invalid_data(&sys_cfg);
    ie_hdr = (IEEEtypes_Header_t *) extra;

    if (ie_hdr->element_id == WPA_IE)
        sys_cfg.protocol = PROTOCOL_WPA;
    else if (ie_hdr->element_id == RSN_IE)
        sys_cfg.protocol = PROTOCOL_WPA2;
    if (dwrq->length > (ie_hdr->len + sizeof(IEEEtypes_Header_t))) {
        ie_hdr1 = (IEEEtypes_Header_t *) ((t_u8 *) extra +
                                          ie_hdr->len +
                                          sizeof(IEEEtypes_Header_t));
        if ((ie_hdr->element_id == WPA_IE && ie_hdr1->element_id == RSN_IE) ||
            (ie_hdr->element_id == RSN_IE && ie_hdr1->element_id == WPA_IE)) {
            sys_cfg.protocol = PROTOCOL_WPA2_MIXED;
        }
    }

    if (sys_cfg.protocol) {
        if (MLAN_STATUS_SUCCESS !=
            woal_set_get_sys_config(priv, MLAN_ACT_SET, &sys_cfg)) {
            PRINTM(MERROR, "Error setting AP confiruration\n");
            ret = -EFAULT;
            goto done;
        }
    }

  done:
    if (req)
        kfree(req);

    LEAVE();
    return ret;
}
/**
 * @brief Initialize the uAP wiphy
 *
 * @param priv            A pointer to moal_private structure
 * @param wait_option     Wait option
 *
 * @return                MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
 */
mlan_status
woal_cfg80211_uap_init_wiphy(moal_private * priv, t_u8 wait_option)
{
    struct wiphy *wiphy;
    mlan_uap_bss_param ap_cfg;
    mlan_ioctl_req *req = NULL;
    mlan_ds_11n_cfg *cfg_11n = NULL;
    t_u32 hw_dev_cap;

    ENTER();

    if (priv->wdev)
        wiphy = priv->wdev->wiphy;
    else {
        PRINTM(MERROR, "Invalid parameter when init wiphy.\n");
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }
    if (MLAN_STATUS_SUCCESS != woal_set_get_sys_config(priv,
                                                       MLAN_ACT_GET,
                                                       wait_option, &ap_cfg)) {
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    /* Get 11n tx parameters from MLAN */
    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
    if (req == NULL) {
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }
    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
    cfg_11n->sub_command = MLAN_OID_11N_HTCAP_CFG;
    req->req_id = MLAN_IOCTL_11N_CFG;
    req->action = MLAN_ACT_GET;
    cfg_11n->param.htcap_cfg.hw_cap_req = MTRUE;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
        kfree(req);
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }
    hw_dev_cap = cfg_11n->param.htcap_cfg.htcap;

    /* Get supported MCS sets */
    memset(req->pbuf, 0, sizeof(mlan_ds_11n_cfg));
    cfg_11n->sub_command = MLAN_OID_11N_CFG_SUPPORTED_MCS_SET;
    req->req_id = MLAN_IOCTL_11N_CFG;
    req->action = MLAN_ACT_GET;

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
        kfree(req);
        LEAVE();
        return MLAN_STATUS_FAILURE;
    }

    /* Initialize parameters for 2GHz and 5GHz bands */
    woal_cfg80211_setup_ht_cap(&wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap,
                               hw_dev_cap, cfg_11n->param.supported_mcs_set);
    /* For 2.4G band only card, this shouldn't be set */
    if (wiphy->bands[IEEE80211_BAND_5GHZ])
        woal_cfg80211_setup_ht_cap(&wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap,
                                   hw_dev_cap,
                                   cfg_11n->param.supported_mcs_set);
    if (req)
        kfree(req);

    /* Set retry limit count to wiphy */
    wiphy->retry_long = (t_u8) ap_cfg.retry_limit;
    wiphy->retry_short = (t_u8) ap_cfg.retry_limit;
    wiphy->max_scan_ie_len = MAX_IE_SIZE;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) || defined(COMPAT_WIRELESS)
    wiphy->mgmt_stypes = ieee80211_uap_mgmt_stypes;
#endif
    /* Set RTS threshold to wiphy */
    wiphy->rts_threshold = (t_u32) ap_cfg.rts_threshold;

    /* Set fragment threshold to wiphy */
    wiphy->frag_threshold = (t_u32) ap_cfg.frag_threshold;

    LEAVE();
    return MLAN_STATUS_SUCCESS;
}
Esempio n. 28
0
/** 
 *  @brief uap BSS config ioctl handler
 *   
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 *  @return         0 --success, otherwise fail
 */
static int
woal_uap_bss_cfg_ioctl(struct net_device *dev, struct ifreq *req)
{
    moal_private *priv = (moal_private *) netdev_priv(dev);
    int ret = 0;
    mlan_ds_bss *bss = NULL;
    mlan_ioctl_req *ioctl_req = NULL;
    int offset = 0;
    t_u32 action = 0;

    ENTER();

    /* Sanity check */
    if (req->ifr_data == NULL) {
        PRINTM(MERROR, "uap_bss_cfg_ioctl() corrupt data\n");
        ret = -EFAULT;
        goto done;
    }

    /* Get action */
    if (copy_from_user(&action, req->ifr_data + offset, sizeof(action))) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }
    offset += sizeof(action);

    /* Allocate an IOCTL request buffer */
    ioctl_req =
        (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
    if (ioctl_req == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    bss = (mlan_ds_bss *) ioctl_req->pbuf;
    bss->sub_command = MLAN_OID_UAP_BSS_CONFIG;
    ioctl_req->req_id = MLAN_IOCTL_BSS;
    if (action == 1) {
        ioctl_req->action = MLAN_ACT_SET;
    } else {
        ioctl_req->action = MLAN_ACT_GET;
    }

    if (ioctl_req->action == MLAN_ACT_SET) {
        /* Get the BSS config from user */
        if (copy_from_user
            (&bss->param.bss_config, req->ifr_data + offset,
             sizeof(mlan_uap_bss_param))) {
            PRINTM(MERROR, "Copy from user failed\n");
            ret = -EFAULT;
            goto done;
        }
    }

    if (MLAN_STATUS_SUCCESS !=
        woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }

    if (ioctl_req->action == MLAN_ACT_GET) {
        offset = sizeof(action);

        /* Copy to user : BSS config */
        if (copy_to_user
            (req->ifr_data + offset, &bss->param.bss_config,
             sizeof(mlan_uap_bss_param))) {
            PRINTM(MERROR, "Copy to user failed!\n");
            ret = -EFAULT;
            goto done;
        }
    }
  done:
    if (ioctl_req)
        kfree(ioctl_req);
    LEAVE();
    return ret;
}
Esempio n. 29
0
/** 
 *  @brief uap power mode ioctl handler
 *   
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 *  @return         0 --success, otherwise fail
 */
static int
woal_uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req)
{
    moal_private *priv = (moal_private *) netdev_priv(dev);
    mlan_ioctl_req *ioctl_req = NULL;
    mlan_ds_pm_cfg *pm_cfg = NULL;
    mlan_ds_ps_mgmt ps_mgmt;
    int ret = 0;

    ENTER();

    memset(&ps_mgmt, 0, sizeof(mlan_ds_ps_mgmt));

    /* Sanity check */
    if (req->ifr_data == NULL) {
        PRINTM(MERROR, "uap_power_mode_ioctl() corrupt data\n");
        ret = -EFAULT;
        goto done;
    }
    if (copy_from_user(&ps_mgmt, req->ifr_data, sizeof(mlan_ds_ps_mgmt))) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    PRINTM(MIOCTL,
           "ioctl power: flag=0x%x ps_mode=%d ctrl_bitmap=%d min_sleep=%d max_sleep=%d "
           "inact_to=%d min_awake=%d max_awake=%d\n", ps_mgmt.flags,
           (int) ps_mgmt.ps_mode, (int) ps_mgmt.sleep_param.ctrl_bitmap,
           (int) ps_mgmt.sleep_param.min_sleep,
           (int) ps_mgmt.sleep_param.max_sleep,
           (int) ps_mgmt.inact_param.inactivity_to,
           (int) ps_mgmt.inact_param.min_awake,
           (int) ps_mgmt.inact_param.max_awake);

    if (ps_mgmt.
        flags & ~(PS_FLAG_PS_MODE | PS_FLAG_SLEEP_PARAM |
                  PS_FLAG_INACT_SLEEP_PARAM)) {
        PRINTM(MERROR, "Invalid parameter: flags = 0x%x\n", ps_mgmt.flags);
        ret = -EINVAL;
        goto done;
    }

    if (ps_mgmt.ps_mode > PS_MODE_INACTIVITY) {
        PRINTM(MERROR, "Invalid parameter: ps_mode = %d\n",
               (int) ps_mgmt.flags);
        ret = -EINVAL;
        goto done;
    }

    ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
    if (ioctl_req == NULL) {
        ret = -ENOMEM;
        goto done;
    }
    pm_cfg = (mlan_ds_pm_cfg *) ioctl_req->pbuf;
    pm_cfg->sub_command = MLAN_OID_PM_CFG_PS_MODE;
    ioctl_req->req_id = MLAN_IOCTL_PM_CFG;
    if (ps_mgmt.flags) {
        ioctl_req->action = MLAN_ACT_SET;
        memcpy(&pm_cfg->param.ps_mgmt, &ps_mgmt, sizeof(mlan_ds_ps_mgmt));
    } else {
        ioctl_req->action = MLAN_ACT_GET;
    }

    if (MLAN_STATUS_SUCCESS !=
        woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        if (copy_to_user(req->ifr_data, &ioctl_req->status_code, sizeof(t_u32)))
            PRINTM(MERROR, "Copy to user failed!\n");
        goto done;
    }
    if (!ps_mgmt.flags) {
        /* Copy to user */
        if (copy_to_user
            (req->ifr_data, &pm_cfg->param.ps_mgmt, sizeof(mlan_ds_ps_mgmt))) {
            PRINTM(MERROR, "Copy to user failed!\n");
            ret = -EFAULT;
            goto done;
        }
    }
  done:
    if (ioctl_req)
        kfree(ioctl_req);
    LEAVE();
    return ret;
}
Esempio n. 30
0
/**
 * @brief Set/Get tx rate
 * 
 *  @param dev      A pointer to net_device structure
 *  @param req      A pointer to ifreq structure
 * 
 * @return           0 --success, otherwise fail
 */
static int
woal_uap_tx_rate_cfg(struct net_device *dev, struct ifreq *req)
{
    moal_private *priv = (moal_private *) netdev_priv(dev);
    int data[2] = { 0, 0 };
    int ret = 0;
    mlan_ds_rate *rate = NULL;
    mlan_ioctl_req *mreq = NULL;

    ENTER();

    /* Sanity check */
    if (req->ifr_data == NULL) {
        PRINTM(MERROR, "uap_radio_ctl() corrupt data\n");
        ret = -EFAULT;
        goto done;
    }

    /* Get user data */
    if (copy_from_user(&data, req->ifr_data, sizeof(data))) {
        PRINTM(MERROR, "Copy from user failed\n");
        ret = -EFAULT;
        goto done;
    }

    mreq = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
    if (mreq == NULL) {
        ret = -ENOMEM;
        goto done;
    }

    rate = (mlan_ds_rate *) mreq->pbuf;
    rate->param.rate_cfg.rate_type = MLAN_RATE_INDEX;
    rate->sub_command = MLAN_OID_RATE_CFG;
    mreq->req_id = MLAN_IOCTL_RATE;
    if (!data[0])
        mreq->action = MLAN_ACT_GET;
    else {
        mreq->action = MLAN_ACT_SET;
        if (data[1] == AUTO_RATE)
            rate->param.rate_cfg.is_rate_auto = 1;
        else {
            if ((data[1] != MLAN_RATE_INDEX_MCS32) &&
                ((data[1] < 0) || (data[1] > MLAN_RATE_INDEX_MCS7))) {
                ret = -EINVAL;
                goto done;
            }
        }
        rate->param.rate_cfg.rate = data[1];
    }

    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, mreq, MOAL_IOCTL_WAIT)) {
        ret = -EFAULT;
        goto done;
    }
    if (data[0]) {
        priv->rate_index = data[1];
    } else {
        if (rate->param.rate_cfg.is_rate_auto)
            data[1] = AUTO_RATE;
        else
            data[1] = rate->param.rate_cfg.rate;

        if (copy_to_user(req->ifr_data, data, sizeof(data))) {
            PRINTM(MERROR, "Copy to user failed\n");
            ret = -EFAULT;
        }
    }
  done:
    if (mreq)
        kfree(mreq);
    LEAVE();
    return ret;
}