/** * @brief configure tx_pause settings * * @param dev A pointer to net_device structure * @param req A pointer to ifreq structure * @return 0 --success, otherwise fail */ static int woal_uap_txdatapause(struct net_device *dev, struct ifreq *req) { moal_private *priv = (moal_private *) netdev_priv(dev); mlan_ioctl_req *ioctl_req = NULL; mlan_ds_misc_cfg *misc = NULL; tx_data_pause_para param; int ret = 0; ENTER(); memset(¶m, 0, sizeof(param)); /* Sanity check */ if (req->ifr_data == NULL) { PRINTM(MERROR, "woal_uap_txdatapause corrupt data\n"); ret = -EFAULT; goto done; } if (copy_from_user(¶m, req->ifr_data, sizeof(param))) { PRINTM(MERROR, "Copy from user failed\n"); ret = -EFAULT; goto done; } DBG_HEXDUMP(MCMD_D, "tx_data_pause_para", (t_u8 *) & param, sizeof(param)); ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg)); if (ioctl_req == NULL) { LEAVE(); return -ENOMEM; } misc = (mlan_ds_misc_cfg *) ioctl_req->pbuf; misc->sub_command = MLAN_OID_MISC_TX_DATAPAUSE; ioctl_req->req_id = MLAN_IOCTL_MISC_CFG; if (!param.action) { /* Get Tx data pause status from MLAN */ ioctl_req->action = MLAN_ACT_GET; } else { /* Set Tx data pause in MLAN */ ioctl_req->action = MLAN_ACT_SET; misc->param.tx_datapause.tx_pause = param.txpause; misc->param.tx_datapause.tx_buf_cnt = param.txbufcnt; } if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) { ret = -EFAULT; goto done; } param.txpause = misc->param.tx_datapause.tx_pause; param.txbufcnt = misc->param.tx_datapause.tx_buf_cnt; /* Copy to user */ if (copy_to_user(req->ifr_data, ¶m, sizeof(param))) { PRINTM(MERROR, "Copy to user failed!\n"); ret = -EFAULT; goto done; } done: if (ioctl_req) kfree(ioctl_req); LEAVE(); return ret; }
/** * @brief uap addba parameter 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_addba_param(struct net_device *dev, struct ifreq *req) { moal_private *priv = (moal_private *) netdev_priv(dev); mlan_ioctl_req *ioctl_req = NULL; mlan_ds_11n_cfg *cfg_11n = NULL; addba_param param; int ret = 0; ENTER(); memset(¶m, 0, sizeof(param)); /* Sanity check */ if (req->ifr_data == NULL) { PRINTM(MERROR, "uap_addba_param() corrupt data\n"); ret = -EFAULT; goto done; } if (copy_from_user(¶m, req->ifr_data, sizeof(param))) { PRINTM(MERROR, "Copy from user failed\n"); ret = -EFAULT; goto done; } PRINTM(MIOCTL, "addba param: action=%d, timeout=%d, txwinsize=%d, rxwinsize=%d\n", (int) param.action, (int) param.timeout, (int) param.txwinsize, (int) param.rxwinsize); ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg)); if (ioctl_req == NULL) { LEAVE(); return -ENOMEM; } cfg_11n = (mlan_ds_11n_cfg *) ioctl_req->pbuf; cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_PARAM; ioctl_req->req_id = MLAN_IOCTL_11N_CFG; if (!param.action) { /* Get addba param from MLAN */ ioctl_req->action = MLAN_ACT_GET; } else { /* Set addba param in MLAN */ ioctl_req->action = MLAN_ACT_SET; cfg_11n->param.addba_param.timeout = param.timeout; cfg_11n->param.addba_param.txwinsize = param.txwinsize; cfg_11n->param.addba_param.rxwinsize = param.rxwinsize; } if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) { ret = -EFAULT; goto done; } param.timeout = cfg_11n->param.addba_param.timeout; param.txwinsize = cfg_11n->param.addba_param.txwinsize; param.rxwinsize = cfg_11n->param.addba_param.rxwinsize; /* Copy to user */ if (copy_to_user(req->ifr_data, ¶m, sizeof(param))) { PRINTM(MERROR, "Copy to user failed!\n"); ret = -EFAULT; goto done; } done: if (ioctl_req) kfree(ioctl_req); LEAVE(); return ret; }
/** * @brief uap addba reject tbl * * @param dev A pointer to net_device structure * @param req A pointer to ifreq structure * @return 0 --success, otherwise fail */ static int woal_uap_addba_reject(struct net_device *dev, struct ifreq *req) { moal_private *priv = (moal_private *) netdev_priv(dev); mlan_ioctl_req *ioctl_req = NULL; mlan_ds_11n_cfg *cfg_11n = NULL; addba_reject_para param; int ret = 0; int i = 0; ENTER(); memset(¶m, 0, sizeof(param)); /* Sanity check */ if (req->ifr_data == NULL) { PRINTM(MERROR, "woal_uap_addba_reject() corrupt data\n"); ret = -EFAULT; goto done; } if (copy_from_user(¶m, req->ifr_data, sizeof(param))) { PRINTM(MERROR, "Copy from user failed\n"); ret = -EFAULT; goto done; } DBG_HEXDUMP(MCMD_D, "addba_reject tbl", (t_u8 *) & param, sizeof(param)); ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg)); if (ioctl_req == NULL) { LEAVE(); return -ENOMEM; } cfg_11n = (mlan_ds_11n_cfg *) ioctl_req->pbuf; cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_REJECT; ioctl_req->req_id = MLAN_IOCTL_11N_CFG; if (!param.action) { /* Get addba_reject tbl from MLAN */ ioctl_req->action = MLAN_ACT_GET; } else { /* Set addba_reject tbl in MLAN */ ioctl_req->action = MLAN_ACT_SET; for (i = 0; i < MAX_NUM_TID; i++) { cfg_11n->param.addba_reject[i] = param.addba_reject[i]; } } if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) { ret = -EFAULT; goto done; } for (i = 0; i < MAX_NUM_TID; i++) { param.addba_reject[i] = cfg_11n->param.addba_reject[i]; } /* Copy to user */ if (copy_to_user(req->ifr_data, ¶m, sizeof(param))) { PRINTM(MERROR, "Copy to user failed!\n"); ret = -EFAULT; goto done; } done: if (ioctl_req) kfree(ioctl_req); LEAVE(); return ret; }
/** * @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; woal_cancel_cac_block(priv); 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; }
/** * @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_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; }
/** * @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; }
/** * @brief configure deep sleep * * @param dev A pointer to net_device structure * @param req A pointer to ifreq structure * @return 0 --success, otherwise fail */ static int woal_uap_deep_sleep(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 = NULL; deep_sleep_para param; int ret = 0; ENTER(); memset(¶m, 0, sizeof(param)); /* Sanity check */ if (req->ifr_data == NULL) { PRINTM(MERROR, "woal_uap_deep_sleep() corrupt data\n"); ret = -EFAULT; goto done; } if (copy_from_user(¶m, req->ifr_data, sizeof(param))) { PRINTM(MERROR, "Copy from user failed\n"); ret = -EFAULT; goto done; } DBG_HEXDUMP(MCMD_D, "deep_sleep_para", (t_u8 *) & param, sizeof(param)); ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg)); if (ioctl_req == NULL) { LEAVE(); return -ENOMEM; } pm = (mlan_ds_pm_cfg *) ioctl_req->pbuf; pm->sub_command = MLAN_OID_PM_CFG_DEEP_SLEEP; ioctl_req->req_id = MLAN_IOCTL_PM_CFG; if (!param.action) { /* Get deep_sleep status from MLAN */ ioctl_req->action = MLAN_ACT_GET; } else { /* Set deep_sleep in MLAN */ ioctl_req->action = MLAN_ACT_SET; if (param.deep_sleep == MTRUE) { pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_ON; pm->param.auto_deep_sleep.idletime = param.idle_time; } else { pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_OFF; } } if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, ioctl_req, MOAL_IOCTL_WAIT)) { ret = -EFAULT; goto done; } if (pm->param.auto_deep_sleep.auto_ds == DEEP_SLEEP_ON) param.deep_sleep = MTRUE; else param.deep_sleep = MFALSE; param.idle_time = pm->param.auto_deep_sleep.idletime; /* Copy to user */ if (copy_to_user(req->ifr_data, ¶m, sizeof(param))) { PRINTM(MERROR, "Copy to user failed!\n"); ret = -EFAULT; goto done; } done: if (ioctl_req) kfree(ioctl_req); LEAVE(); return ret; }