[PATCH] staging: rtl8188eu: Fix private WEXT IOCTL calls
From: Ishraq Ibne Ashraf Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT IOCTL calls of this driver as these are not invoked through ndo_do_ioctl interface anymore. As a result hostapd stops working with this driver. In this patch this problem is solved by implementing equivalent private IOCTL functions of the existing ones which are accessed via iw_handler_def interface. Signed-off-by: Ishraq Ibne Ashraf --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1042 1 file changed, 1042 insertions(+) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index c0664dc..7503751 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -3061,6 +3061,1046 @@ static iw_handler rtw_handlers[] = { NULL, /*---hole---*/ }; +static int get_private_handler_ieee_param(struct adapter *padapter, + union iwreq_data *wrqu, + void *param) +{ + /* +* This function is expected to be called in master mode, which allows no +* power saving. So we just check hw_init_completed. +*/ + + if (!padapter->hw_init_completed) + return -EPERM; + + if (!wrqu->data.pointer) + return -EINVAL; + + /* +* Since we don't allocate memory for param in this function, we assume +* the caller of this function will properly allocate and deallocate memory +* for param. +*/ + if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + return 0; +} + +static int rtw_hostapd_sta_flush_pvt(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + + DBG_88E("%s\n", __func__); + + flush_all_cam_entry(padapter); // Clear CAM. + + return rtw_sta_flush(padapter); +} + +static int rtw_add_sta_pvt(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret = 0; + struct sta_info *psta = NULL; + struct ieee_param *param = NULL; + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + param = (struct ieee_param *)rtw_malloc(wrqu->data.length); + + if (!param) { + DBG_88E(" rtw_add_sta: ieee_param allocate fail !!!\n"); + + return -ENOMEM; + } + + ret = get_private_handler_ieee_param(padapter, wrqu, param); + + if (ret != 0) { + kfree(param); + DBG_88E(" rtw_add_sta: ieee_param get fail !!!\n"); + + return ret; + } + + DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr)); + + if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) + return -EINVAL; + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) + return -EINVAL; + + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if (psta) { + int flags = param->u.add_sta.flags; + psta->aid = param->u.add_sta.aid; // aid = 1~2007. + + memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); + + // Check WMM cap. + if (WLAN_STA_WME&flags) + psta->qos_option = 1; + else + psta->qos_option = 0; + + if (pmlmepriv->qospriv.qos_option == 0) + psta->qos_option = 0; + + // Check 802.11n HT cap. + if (WLAN_STA_HT&flags) { + psta->htpriv.ht_option = true; + psta->qos_option = 1; + memcpy(&psta->htpriv.ht_cap, + ¶m->u.add_sta.ht_cap, + sizeof(struct ieee80211_ht_cap)); + } else { + psta->htpriv.ht_option = false; + } + + if (pmlmepriv->htpriv.ht_option == false) + psta->htpriv.ht_option = false; + + update_sta_info_apmode(padapter, psta); + } else { + ret = -ENOMEM; + } + + if (ret == 0 && (copy_to_user(wrqu->data.pointer, param, wrqu->data.length))) + ret = -EFAULT; + + return ret; +} + +static int rtw_del_sta_pvt(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret = 0; +
[PATCH 2/2] staging: rtl8188eu: Fix private WEXT IOCTL calls
From: Ishraq Ibne Ashraf Apply changes suggested by Dan Carpenter --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1052 1 file changed, 536 insertions(+), 516 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 7503751..e871344 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -3062,25 +3062,16 @@ static iw_handler rtw_handlers[] = { }; static int get_private_handler_ieee_param(struct adapter *padapter, - union iwreq_data *wrqu, - void *param) + union iwreq_data *wrqu, + void *param) { /* * This function is expected to be called in master mode, which allows no * power saving. So we just check hw_init_completed. */ - if (!padapter->hw_init_completed) return -EPERM; - if (!wrqu->data.pointer) - return -EINVAL; - - /* -* Since we don't allocate memory for param in this function, we assume -* the caller of this function will properly allocate and deallocate memory -* for param. -*/ if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length)) return -EFAULT; @@ -3088,305 +3079,310 @@ static int get_private_handler_ieee_param(struct adapter *padapter, } static int rtw_hostapd_sta_flush_pvt(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) +struct iw_request_info *info, +union iwreq_data *wrqu, +char *extra) { struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - DBG_88E("%s\n", __func__); - - flush_all_cam_entry(padapter); // Clear CAM. - + flush_all_cam_entry(padapter); /* Clear CAM. */ return rtw_sta_flush(padapter); } static int rtw_add_sta_pvt(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) { - int ret = 0; - struct sta_info *psta = NULL; - struct ieee_param *param = NULL; + int ret; + int flags; + struct sta_info *psta; + struct ieee_param *param; struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - param = (struct ieee_param *)rtw_malloc(wrqu->data.length); - - if (!param) { - DBG_88E(" rtw_add_sta: ieee_param allocate fail !!!\n"); - + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL); + if (!param) return -ENOMEM; - } ret = get_private_handler_ieee_param(padapter, wrqu, param); + if (ret) + goto err_free_param; - if (ret != 0) { - kfree(param); - DBG_88E(" rtw_add_sta: ieee_param get fail !!!\n"); + DBG_88E("rtw_add_sta(aid =%d) =%pM\n", + param->u.add_sta.aid, + (param->sta_addr)); - return ret; + if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) { + ret = -EINVAL; + goto err_free_param; } - DBG_88E("rtw_add_sta(aid =%d) =%pM\n", param->u.add_sta.aid, (param->sta_addr)); - - if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) - return -EINVAL; - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) - return -EINVAL; + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + ret = -EINVAL; + goto err_free_param; + } psta = rtw_get_stainfo(pstapriv, param->sta_addr); - if (psta) { - int flags = param->u.add_sta.flags; - psta->aid = param->u.add_sta.aid; // aid = 1~2007. - - memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); + if (!psta) { + ret = -ENOMEM; + goto err_free_param; + } - // Check WMM cap. - if (WLAN_STA_WME&flags) - psta->qos_option = 1; - else - psta->qos_option = 0; + flags = param->u.add_sta.flags; + psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */ - if (pmlmepriv->qospri
[PATCH v2] staging: rtl8188eu: Fix private WEXT IOCTL calls
From: Ishraq Ibne Ashraf Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT IOCTL calls of this driver as these are not invoked through ndo_do_ioctl interface anymore. As a result hostapd stops working with this driver. In this patch this problem is solved by implementing equivalent private IOCTL functions of the existing ones which are accessed via iw_handler_def interface. Signed-off-by: Ishraq Ibne Ashraf --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1062 1 file changed, 1062 insertions(+) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index c0664dc..e871344 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -3061,6 +3061,1066 @@ static iw_handler rtw_handlers[] = { NULL, /*---hole---*/ }; +static int get_private_handler_ieee_param(struct adapter *padapter, + union iwreq_data *wrqu, + void *param) +{ + /* +* This function is expected to be called in master mode, which allows no +* power saving. So we just check hw_init_completed. +*/ + if (!padapter->hw_init_completed) + return -EPERM; + + if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + return 0; +} + +static int rtw_hostapd_sta_flush_pvt(struct net_device *dev, +struct iw_request_info *info, +union iwreq_data *wrqu, +char *extra) +{ + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + flush_all_cam_entry(padapter); /* Clear CAM. */ + return rtw_sta_flush(padapter); +} + +static int rtw_add_sta_pvt(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + int flags; + struct sta_info *psta; + struct ieee_param *param; + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL); + if (!param) + return -ENOMEM; + + ret = get_private_handler_ieee_param(padapter, wrqu, param); + if (ret) + goto err_free_param; + + DBG_88E("rtw_add_sta(aid =%d) =%pM\n", + param->u.add_sta.aid, + (param->sta_addr)); + + if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) { + ret = -EINVAL; + goto err_free_param; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + ret = -EINVAL; + goto err_free_param; + } + + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if (!psta) { + ret = -ENOMEM; + goto err_free_param; + } + + flags = param->u.add_sta.flags; + psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */ + + memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); + + /* Check WMM cap. */ + if (WLAN_STA_WME&flags) + psta->qos_option = 1; + else + psta->qos_option = 0; + + if (pmlmepriv->qospriv.qos_option == 0) + psta->qos_option = 0; + + /* Check 802.11n HT cap. */ + if (WLAN_STA_HT&flags) { + psta->htpriv.ht_option = true; + psta->qos_option = 1; + memcpy(&psta->htpriv.ht_cap, + ¶m->u.add_sta.ht_cap, + sizeof(struct ieee80211_ht_cap)); + } else { + psta->htpriv.ht_option = false; + } + + if (pmlmepriv->htpriv.ht_option == false) + psta->htpriv.ht_option = false; + + update_sta_info_apmode(padapter, psta); + + ret = 0; + + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) + ret = -EFAULT; + + err_free_param: + kfree(param); + return ret; +} + +static int rtw_del_sta_pvt(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + int updated; + struct sta_info *psta; + struct ieee_param *param; + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct sta_priv *pstapriv = &padapt
[PATCH v3] staging: rtl8188eu: Fix private WEXT IOCTL calls
From: Ishraq Ibne Ashraf Commit 8bfb36766064 ("wireless: wext: remove ndo_do_ioctl fallback") breaks private WEXT IOCTL calls of this driver as these are not invoked through ndo_do_ioctl interface anymore. As a result hostapd stops working with this driver. In this patch this problem is solved by implementing equivalent private IOCTL functions of the existing ones which are accessed via iw_handler_def interface. Signed-off-by: Ishraq Ibne Ashraf --- drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 1077 1 file changed, 1077 insertions(+) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index c0664dc..8d99f99 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -3061,6 +3061,1081 @@ static iw_handler rtw_handlers[] = { NULL, /*---hole---*/ }; +static int get_private_handler_ieee_param(struct adapter *padapter, + union iwreq_data *wrqu, + void *param) +{ + /* +* This function is expected to be called in master mode, which allows no +* power saving. So we just check hw_init_completed. +*/ + if (!padapter->hw_init_completed) + return -EPERM; + + if (copy_from_user(param, wrqu->data.pointer, wrqu->data.length)) + return -EFAULT; + + return 0; +} + +static int rtw_hostapd_sta_flush_pvt(struct net_device *dev, +struct iw_request_info *info, +union iwreq_data *wrqu, +char *extra) +{ + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + flush_all_cam_entry(padapter); /* Clear CAM. */ + return rtw_sta_flush(padapter); +} + +static int rtw_add_sta_pvt(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + int flags; + struct sta_info *psta; + struct ieee_param *param; + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); + struct sta_priv *pstapriv = &padapter->stapriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + + param = (struct ieee_param *)kmalloc(wrqu->data.length, GFP_KERNEL); + if (!param) + return -ENOMEM; + + ret = get_private_handler_ieee_param(padapter, wrqu, param); + if (ret) + goto err_free_param; + + DBG_88E("rtw_add_sta(aid =%d) =%pM\n", + param->u.add_sta.aid, + (param->sta_addr)); + + if (!check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))) { + ret = -EINVAL; + goto err_free_param; + } + + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + ret = -EINVAL; + goto err_free_param; + } + + psta = rtw_get_stainfo(pstapriv, param->sta_addr); + if (!psta) { + ret = -ENOMEM; + goto err_free_param; + } + + flags = param->u.add_sta.flags; + psta->aid = param->u.add_sta.aid; /* aid = 1~2007. */ + + memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16); + + /* Check WMM cap. */ + if (WLAN_STA_WME&flags) + psta->qos_option = 1; + else + psta->qos_option = 0; + + if (pmlmepriv->qospriv.qos_option == 0) + psta->qos_option = 0; + + /* Check 802.11n HT cap. */ + if (WLAN_STA_HT&flags) { + psta->htpriv.ht_option = true; + psta->qos_option = 1; + memcpy(&psta->htpriv.ht_cap, + ¶m->u.add_sta.ht_cap, + sizeof(struct ieee80211_ht_cap)); + } else { + psta->htpriv.ht_option = false; + } + + if (pmlmepriv->htpriv.ht_option == false) + psta->htpriv.ht_option = false; + + update_sta_info_apmode(padapter, psta); + + if (copy_to_user(wrqu->data.pointer, param, wrqu->data.length)) { + ret = -EFAULT; + goto err_free_param; + } + + kfree(param); + return 0; + +err_free_param: + kfree(param); + return ret; +} + +static int rtw_del_sta_pvt(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int ret; + int updated; + struct sta_info *psta; + struct ieee_param *param; + struct adapter *padapter = (struct adapter *)rtw_netdev_priv(