mirror of
https://github.com/lwfinger/rtl8188eu.git
synced 2025-05-09 06:43:06 +00:00
rtl8188eu: Flatten os_dep
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
This commit is contained in:
parent
b0c8a54865
commit
52f8d17ffc
18 changed files with 14750 additions and 26420 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,620 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#define _MLME_OSDEP_C_
|
||||
|
||||
#include <drv_conf.h>
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
#include <mlme_osdep.h>
|
||||
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
void Linkup_workitem_callback(struct work_struct *work)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkup_workitem);
|
||||
_adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
|
||||
|
||||
_func_enter_;
|
||||
|
||||
RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkup_workitem_callback\n"));
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
|
||||
kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKUP);
|
||||
#else
|
||||
kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKUP);
|
||||
#endif
|
||||
|
||||
_func_exit_;
|
||||
}
|
||||
|
||||
void Linkdown_workitem_callback(struct work_struct *work)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkdown_workitem);
|
||||
_adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
|
||||
|
||||
_func_enter_;
|
||||
|
||||
RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+ Linkdown_workitem_callback\n"));
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12))
|
||||
kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKDOWN);
|
||||
#else
|
||||
kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKDOWN);
|
||||
#endif
|
||||
|
||||
_func_exit_;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
void sitesurvey_ctrl_handler(void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
|
||||
_sitesurvey_ctrl_handler(adapter);
|
||||
|
||||
_set_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, 3000);
|
||||
}
|
||||
*/
|
||||
|
||||
void rtw_join_timeout_handler (void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
_rtw_join_timeout_handler(adapter);
|
||||
}
|
||||
|
||||
|
||||
void _rtw_scan_timeout_handler (void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
rtw_scan_timeout_handler(adapter);
|
||||
}
|
||||
|
||||
|
||||
void _dynamic_check_timer_handlder (void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
/* remove for MP power tracking DM.
|
||||
#if (MP_DRIVER == 1)
|
||||
if (adapter->registrypriv.mp_mode == 1)
|
||||
return;
|
||||
#endif
|
||||
*/
|
||||
rtw_dynamic_check_timer_handlder(adapter);
|
||||
|
||||
_set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SET_SCAN_DENY_TIMER
|
||||
void _rtw_set_scan_deny_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
rtw_set_scan_deny_timer_hdl(adapter);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DETECT_C2H_BY_POLLING
|
||||
void _rtw_event_polling_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
|
||||
rtw_event_polling_timer_hdl(adapter);
|
||||
|
||||
_set_timer(&adapter->mlmepriv.event_polling_timer, 200);
|
||||
}
|
||||
#endif
|
||||
|
||||
void rtw_init_mlme_timer(_adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
_init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, rtw_join_timeout_handler, padapter);
|
||||
//_init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer), padapter->pnetdev, sitesurvey_ctrl_handler, padapter);
|
||||
_init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, _rtw_scan_timeout_handler, padapter);
|
||||
|
||||
_init_timer(&(pmlmepriv->dynamic_chk_timer), padapter->pnetdev, _dynamic_check_timer_handlder, padapter);
|
||||
|
||||
#ifdef CONFIG_SET_SCAN_DENY_TIMER
|
||||
_init_timer(&(pmlmepriv->set_scan_deny_timer), padapter->pnetdev, _rtw_set_scan_deny_timer_hdl, padapter);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DETECT_C2H_BY_POLLING
|
||||
_init_timer(&(pmlmepriv->event_polling_timer), padapter->pnetdev, _rtw_event_polling_timer_hdl, padapter);
|
||||
#endif
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
_init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter);
|
||||
_init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter);
|
||||
#endif
|
||||
#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
|
||||
if (padapter->HalFunc.hal_init_checkbthang_workqueue)
|
||||
padapter->HalFunc.hal_init_checkbthang_workqueue(padapter);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void rtw_indicate_wx_assoc_event(_adapter *padapter);
|
||||
extern void rtw_indicate_wx_disassoc_event(_adapter *padapter);
|
||||
|
||||
void rtw_os_indicate_connect(_adapter *adapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
|
||||
_func_enter_;
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) ||
|
||||
(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) )
|
||||
{
|
||||
rtw_cfg80211_ibss_indicate_connect(adapter);
|
||||
}
|
||||
else
|
||||
rtw_cfg80211_indicate_connect(adapter);
|
||||
#endif //CONFIG_IOCTL_CFG80211
|
||||
|
||||
rtw_indicate_wx_assoc_event(adapter);
|
||||
netif_carrier_on(adapter->pnetdev);
|
||||
|
||||
if(adapter->pid[2] !=0)
|
||||
rtw_signal_process(adapter->pid[2], SIGALRM);
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
_set_workitem(&adapter->mlmepriv.Linkup_workitem);
|
||||
#endif
|
||||
|
||||
_func_exit_;
|
||||
|
||||
}
|
||||
|
||||
extern void indicate_wx_scan_complete_event(_adapter *padapter);
|
||||
void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted)
|
||||
{
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), aborted);
|
||||
#endif
|
||||
indicate_wx_scan_complete_event(padapter);
|
||||
}
|
||||
|
||||
static RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ];
|
||||
void rtw_reset_securitypriv( _adapter *adapter )
|
||||
{
|
||||
u8 backupPMKIDIndex = 0;
|
||||
u8 backupTKIPCountermeasure = 0x00;
|
||||
u32 backupTKIPcountermeasure_time = 0;
|
||||
// add for CONFIG_IEEE80211W, none 11w also can use
|
||||
_irqL irqL;
|
||||
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
|
||||
|
||||
_enter_critical_bh(&adapter->security_key_mutex, &irqL);
|
||||
|
||||
if(adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)//802.1x
|
||||
{
|
||||
// Added by Albert 2009/02/18
|
||||
// We have to backup the PMK information for WiFi PMK Caching test item.
|
||||
//
|
||||
// Backup the btkip_countermeasure information.
|
||||
// When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds.
|
||||
|
||||
_rtw_memset( &backupPMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
|
||||
|
||||
_rtw_memcpy( &backupPMKIDList[ 0 ], &adapter->securitypriv.PMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
|
||||
backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
|
||||
backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure;
|
||||
backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
//reset RX BIP packet number
|
||||
pmlmeext->mgnt_80211w_IPN_rx = 0;
|
||||
#endif //CONFIG_IEEE80211W
|
||||
_rtw_memset((unsigned char *)&adapter->securitypriv, 0, sizeof (struct security_priv));
|
||||
//_init_timer(&(adapter->securitypriv.tkip_timer),adapter->pnetdev, rtw_use_tkipkey_handler, adapter);
|
||||
|
||||
// Added by Albert 2009/02/18
|
||||
// Restore the PMK information to securitypriv structure for the following connection.
|
||||
_rtw_memcpy( &adapter->securitypriv.PMKIDList[ 0 ], &backupPMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
|
||||
adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
|
||||
adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure;
|
||||
adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time;
|
||||
|
||||
adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
|
||||
adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
|
||||
|
||||
}
|
||||
else //reset values in securitypriv
|
||||
{
|
||||
//if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE)
|
||||
//{
|
||||
struct security_priv *psec_priv=&adapter->securitypriv;
|
||||
|
||||
psec_priv->dot11AuthAlgrthm =dot11AuthAlgrthm_Open; //open system
|
||||
psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
|
||||
psec_priv->dot11PrivacyKeyIndex = 0;
|
||||
|
||||
psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_;
|
||||
psec_priv->dot118021XGrpKeyid = 1;
|
||||
|
||||
psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
|
||||
psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
|
||||
//}
|
||||
}
|
||||
// add for CONFIG_IEEE80211W, none 11w also can use
|
||||
_exit_critical_bh(&adapter->security_key_mutex, &irqL);
|
||||
}
|
||||
|
||||
void rtw_os_indicate_disconnect( _adapter *adapter )
|
||||
{
|
||||
//RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ];
|
||||
|
||||
_func_enter_;
|
||||
|
||||
netif_carrier_off(adapter->pnetdev); // Do it first for tx broadcast pkt after disconnection issue!
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
rtw_cfg80211_indicate_disconnect(adapter);
|
||||
#endif //CONFIG_IOCTL_CFG80211
|
||||
|
||||
rtw_indicate_wx_disassoc_event(adapter);
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
_set_workitem(&adapter->mlmepriv.Linkdown_workitem);
|
||||
#endif
|
||||
//modify for CONFIG_IEEE80211W, none 11w also can use the same command
|
||||
rtw_reset_securitypriv_cmd(adapter);
|
||||
|
||||
_func_exit_;
|
||||
|
||||
}
|
||||
|
||||
void rtw_report_sec_ie(_adapter *adapter,u8 authmode,u8 *sec_ie)
|
||||
{
|
||||
uint len;
|
||||
u8 *buff,*p,i;
|
||||
union iwreq_data wrqu;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+rtw_report_sec_ie, authmode=%d\n", authmode));
|
||||
|
||||
buff = NULL;
|
||||
if(authmode==_WPA_IE_ID_)
|
||||
{
|
||||
RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("rtw_report_sec_ie, authmode=%d\n", authmode));
|
||||
|
||||
buff = rtw_malloc(IW_CUSTOM_MAX);
|
||||
|
||||
_rtw_memset(buff,0,IW_CUSTOM_MAX);
|
||||
|
||||
p=buff;
|
||||
|
||||
p+=sprintf(p,"ASSOCINFO(ReqIEs=");
|
||||
|
||||
len = sec_ie[1]+2;
|
||||
len = (len < IW_CUSTOM_MAX) ? len:IW_CUSTOM_MAX;
|
||||
|
||||
for(i=0;i<len;i++){
|
||||
p+=sprintf(p,"%02x",sec_ie[i]);
|
||||
}
|
||||
|
||||
p+=sprintf(p,")");
|
||||
|
||||
_rtw_memset(&wrqu,0,sizeof(wrqu));
|
||||
|
||||
wrqu.data.length=p-buff;
|
||||
|
||||
wrqu.data.length = (wrqu.data.length<IW_CUSTOM_MAX) ? wrqu.data.length:IW_CUSTOM_MAX;
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event(adapter->pnetdev,IWEVCUSTOM,&wrqu,buff);
|
||||
#endif
|
||||
|
||||
if(buff)
|
||||
rtw_mfree(buff, IW_CUSTOM_MAX);
|
||||
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
|
||||
}
|
||||
|
||||
void _survey_timer_hdl (void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
|
||||
survey_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
void _link_timer_hdl (void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
link_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
void _addba_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
struct sta_info *psta = (struct sta_info *)FunctionContext;
|
||||
addba_timer_hdl(psta);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
void _sa_query_timer_hdl (void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
sa_query_timer_hdl(padapter);
|
||||
}
|
||||
#endif //CONFIG_IEEE80211W
|
||||
|
||||
void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
|
||||
_init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta);
|
||||
}
|
||||
|
||||
/*
|
||||
void _reauth_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
reauth_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
void _reassoc_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
reassoc_timer_hdl(padapter);
|
||||
}
|
||||
*/
|
||||
|
||||
void init_mlme_ext_timer(_adapter *padapter)
|
||||
{
|
||||
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
|
||||
|
||||
_init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter);
|
||||
_init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter);
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
_init_timer(&pmlmeext->sa_query_timer, padapter->pnetdev, _sa_query_timer_hdl, padapter);
|
||||
#endif //CONFIG_IEEE80211W
|
||||
//_init_timer(&pmlmeext->ADDBA_timer, padapter->pnetdev, _addba_timer_hdl, padapter);
|
||||
|
||||
//_init_timer(&pmlmeext->reauth_timer, padapter->pnetdev, _reauth_timer_hdl, padapter);
|
||||
//_init_timer(&pmlmeext->reassoc_timer, padapter->pnetdev, _reassoc_timer_hdl, padapter);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AP_MODE
|
||||
|
||||
void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
union iwreq_data wrqu;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
|
||||
if(psta==NULL)
|
||||
return;
|
||||
|
||||
if(psta->aid > NUM_STA)
|
||||
return;
|
||||
|
||||
if(pstapriv->sta_aid[psta->aid - 1] != psta)
|
||||
return;
|
||||
|
||||
|
||||
wrqu.addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
_rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
|
||||
|
||||
DBG_871X("+rtw_indicate_sta_assoc_event\n");
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
union iwreq_data wrqu;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
|
||||
if(psta==NULL)
|
||||
return;
|
||||
|
||||
if(psta->aid > NUM_STA)
|
||||
return;
|
||||
|
||||
if(pstapriv->sta_aid[psta->aid - 1] != psta)
|
||||
return;
|
||||
|
||||
|
||||
wrqu.addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
_rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
|
||||
|
||||
DBG_871X("+rtw_indicate_sta_disassoc_event\n");
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_HOSTAPD_MLME
|
||||
|
||||
static int mgnt_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
_adapter *padapter = (_adapter *)phostapdpriv->padapter;
|
||||
|
||||
//DBG_871X("%s\n", __FUNCTION__);
|
||||
|
||||
return rtw_hal_hostap_mgnt_xmit_entry(padapter, skb);
|
||||
}
|
||||
|
||||
static int mgnt_netdev_open(struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
|
||||
DBG_871X("mgnt_netdev_open: MAC Address:" MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr));
|
||||
|
||||
|
||||
init_usb_anchor(&phostapdpriv->anchored);
|
||||
|
||||
if(!rtw_netif_queue_stopped(pnetdev))
|
||||
rtw_netif_start_queue(pnetdev);
|
||||
else
|
||||
rtw_netif_wake_queue(pnetdev);
|
||||
|
||||
|
||||
netif_carrier_on(pnetdev);
|
||||
|
||||
//rtw_write16(phostapdpriv->padapter, 0x0116, 0x0100);//only excluding beacon
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int mgnt_netdev_close(struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
|
||||
DBG_871X("%s\n", __FUNCTION__);
|
||||
|
||||
usb_kill_anchored_urbs(&phostapdpriv->anchored);
|
||||
|
||||
netif_carrier_off(pnetdev);
|
||||
|
||||
if (!rtw_netif_queue_stopped(pnetdev))
|
||||
rtw_netif_stop_queue(pnetdev);
|
||||
|
||||
//rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
|
||||
static const struct net_device_ops rtl871x_mgnt_netdev_ops = {
|
||||
.ndo_open = mgnt_netdev_open,
|
||||
.ndo_stop = mgnt_netdev_close,
|
||||
.ndo_start_xmit = mgnt_xmit_entry,
|
||||
//.ndo_set_mac_address = r871x_net_set_mac_address,
|
||||
//.ndo_get_stats = r871x_net_get_stats,
|
||||
//.ndo_do_ioctl = r871x_mp_ioctl,
|
||||
};
|
||||
#endif
|
||||
|
||||
int hostapd_mode_init(_adapter *padapter)
|
||||
{
|
||||
unsigned char mac[ETH_ALEN];
|
||||
struct hostapd_priv *phostapdpriv;
|
||||
struct net_device *pnetdev;
|
||||
|
||||
pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv));
|
||||
if (!pnetdev)
|
||||
return -ENOMEM;
|
||||
|
||||
//SET_MODULE_OWNER(pnetdev);
|
||||
ether_setup(pnetdev);
|
||||
|
||||
//pnetdev->type = ARPHRD_IEEE80211;
|
||||
|
||||
phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
phostapdpriv->pmgnt_netdev = pnetdev;
|
||||
phostapdpriv->padapter= padapter;
|
||||
padapter->phostapdpriv = phostapdpriv;
|
||||
|
||||
//pnetdev->init = NULL;
|
||||
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
|
||||
|
||||
DBG_871X("register rtl871x_mgnt_netdev_ops to netdev_ops\n");
|
||||
|
||||
pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops;
|
||||
|
||||
#else
|
||||
|
||||
pnetdev->open = mgnt_netdev_open;
|
||||
|
||||
pnetdev->stop = mgnt_netdev_close;
|
||||
|
||||
pnetdev->hard_start_xmit = mgnt_xmit_entry;
|
||||
|
||||
//pnetdev->set_mac_address = r871x_net_set_mac_address;
|
||||
|
||||
//pnetdev->get_stats = r871x_net_get_stats;
|
||||
|
||||
//pnetdev->do_ioctl = r871x_mp_ioctl;
|
||||
|
||||
#endif
|
||||
|
||||
pnetdev->watchdog_timeo = HZ; /* 1 second timeout */
|
||||
|
||||
//pnetdev->wireless_handlers = NULL;
|
||||
|
||||
#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
|
||||
pnetdev->features |= NETIF_F_IP_CSUM;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if(dev_alloc_name(pnetdev,"mgnt.wlan%d") < 0)
|
||||
{
|
||||
DBG_871X("hostapd_mode_init(): dev_alloc_name, fail! \n");
|
||||
}
|
||||
|
||||
|
||||
//SET_NETDEV_DEV(pnetdev, pintfpriv->udev);
|
||||
|
||||
|
||||
mac[0]=0x00;
|
||||
mac[1]=0xe0;
|
||||
mac[2]=0x4c;
|
||||
mac[3]=0x87;
|
||||
mac[4]=0x11;
|
||||
mac[5]=0x12;
|
||||
|
||||
_rtw_memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
|
||||
|
||||
|
||||
netif_carrier_off(pnetdev);
|
||||
|
||||
|
||||
/* Tell the network stack we exist */
|
||||
if (register_netdev(pnetdev) != 0)
|
||||
{
|
||||
DBG_871X("hostapd_mode_init(): register_netdev fail!\n");
|
||||
|
||||
if(pnetdev)
|
||||
{
|
||||
rtw_free_netdev(pnetdev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void hostapd_mode_unload(_adapter *padapter)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
|
||||
struct net_device *pnetdev = phostapdpriv->pmgnt_netdev;
|
||||
|
||||
unregister_netdev(pnetdev);
|
||||
rtw_free_netdev(pnetdev);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,512 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _RECV_OSDEP_C_
|
||||
|
||||
#include <drv_conf.h>
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
|
||||
#include <wifi.h>
|
||||
#include <recv_osdep.h>
|
||||
|
||||
#include <osdep_intf.h>
|
||||
#include <ethernet.h>
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
#include <usb_ops.h>
|
||||
#endif
|
||||
|
||||
//init os related resource in struct recv_priv
|
||||
int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter)
|
||||
{
|
||||
int res=_SUCCESS;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//alloc os related resource in union recv_frame
|
||||
int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe)
|
||||
{
|
||||
int res=_SUCCESS;
|
||||
|
||||
precvframe->u.hdr.pkt_newalloc = precvframe->u.hdr.pkt = NULL;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
//free os related resource in union recv_frame
|
||||
void rtw_os_recv_resource_free(struct recv_priv *precvpriv)
|
||||
{
|
||||
sint i;
|
||||
union recv_frame *precvframe;
|
||||
precvframe = (union recv_frame*) precvpriv->precv_frame_buf;
|
||||
|
||||
for(i=0; i < NR_RECVFRAME; i++)
|
||||
{
|
||||
if(precvframe->u.hdr.pkt)
|
||||
{
|
||||
rtw_skb_free(precvframe->u.hdr.pkt);//free skb by driver
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
}
|
||||
precvframe++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//alloc os related resource in struct recv_buf
|
||||
int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
int res=_SUCCESS;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
precvbuf->irp_pending = _FALSE;
|
||||
precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if(precvbuf->purb == NULL){
|
||||
res = _FAIL;
|
||||
}
|
||||
|
||||
precvbuf->pskb = NULL;
|
||||
|
||||
precvbuf->reuse = _FALSE;
|
||||
|
||||
precvbuf->pallocated_buf = precvbuf->pbuf = NULL;
|
||||
|
||||
precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL;
|
||||
|
||||
precvbuf->transfer_len = 0;
|
||||
|
||||
precvbuf->len = 0;
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
|
||||
precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, &precvbuf->dma_transfer_addr);
|
||||
precvbuf->pbuf = precvbuf->pallocated_buf;
|
||||
if(precvbuf->pallocated_buf == NULL)
|
||||
return _FAIL;
|
||||
#endif //CONFIG_USE_USB_BUFFER_ALLOC_RX
|
||||
|
||||
#endif //CONFIG_USB_HCI
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//free os related resource in struct recv_buf
|
||||
int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
int ret = _SUCCESS;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
|
||||
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
rtw_usb_buffer_free(pusbd, (size_t)precvbuf->alloc_sz, precvbuf->pallocated_buf, precvbuf->dma_transfer_addr);
|
||||
precvbuf->pallocated_buf = NULL;
|
||||
precvbuf->dma_transfer_addr = 0;
|
||||
|
||||
#endif //CONFIG_USE_USB_BUFFER_ALLOC_RX
|
||||
|
||||
if(precvbuf->purb)
|
||||
{
|
||||
//usb_kill_urb(precvbuf->purb);
|
||||
usb_free_urb(precvbuf->purb);
|
||||
}
|
||||
|
||||
#endif //CONFIG_USB_HCI
|
||||
|
||||
|
||||
if(precvbuf->pskb)
|
||||
rtw_skb_free(precvbuf->pskb);
|
||||
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup)
|
||||
{
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
enum nl80211_key_type key_type;
|
||||
#endif
|
||||
union iwreq_data wrqu;
|
||||
struct iw_michaelmicfailure ev;
|
||||
struct mlme_priv* pmlmepriv = &padapter->mlmepriv;
|
||||
struct security_priv *psecuritypriv = &padapter->securitypriv;
|
||||
u32 cur_time = 0;
|
||||
|
||||
if( psecuritypriv->last_mic_err_time == 0 )
|
||||
{
|
||||
psecuritypriv->last_mic_err_time = rtw_get_current_time();
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_time = rtw_get_current_time();
|
||||
|
||||
if( cur_time - psecuritypriv->last_mic_err_time < 60*HZ )
|
||||
{
|
||||
psecuritypriv->btkip_countermeasure = _TRUE;
|
||||
psecuritypriv->last_mic_err_time = 0;
|
||||
psecuritypriv->btkip_countermeasure_time = cur_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
psecuritypriv->last_mic_err_time = rtw_get_current_time();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
if ( bgroup )
|
||||
{
|
||||
key_type |= NL80211_KEYTYPE_GROUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_type |= NL80211_KEYTYPE_PAIRWISE;
|
||||
}
|
||||
|
||||
cfg80211_michael_mic_failure(padapter->pnetdev, (u8 *)&pmlmepriv->assoc_bssid[ 0 ], key_type, -1,
|
||||
NULL, GFP_ATOMIC);
|
||||
#endif
|
||||
|
||||
_rtw_memset( &ev, 0x00, sizeof( ev ) );
|
||||
if ( bgroup )
|
||||
{
|
||||
ev.flags |= IW_MICFAILURE_GROUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.flags |= IW_MICFAILURE_PAIRWISE;
|
||||
}
|
||||
|
||||
ev.src_addr.sa_family = ARPHRD_ETHER;
|
||||
_rtw_memcpy( ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
|
||||
|
||||
_rtw_memset( &wrqu, 0x00, sizeof( wrqu ) );
|
||||
wrqu.data.length = sizeof( ev );
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event( padapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu, (char*) &ev );
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
#ifdef CONFIG_HOSTAPD_MLME
|
||||
_pkt *skb;
|
||||
struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
|
||||
struct net_device *pmgnt_netdev = phostapdpriv->pmgnt_netdev;
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("+rtw_hostapd_mlme_rx\n"));
|
||||
|
||||
skb = precv_frame->u.hdr.pkt;
|
||||
|
||||
if (skb == NULL)
|
||||
return;
|
||||
|
||||
skb->data = precv_frame->u.hdr.rx_data;
|
||||
skb->tail = precv_frame->u.hdr.rx_tail;
|
||||
skb->len = precv_frame->u.hdr.len;
|
||||
|
||||
//pskb_copy = rtw_skb_copy(skb);
|
||||
// if(skb == NULL) goto _exit;
|
||||
|
||||
skb->dev = pmgnt_netdev;
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
//skb->protocol = __constant_htons(0x0019); /*ETH_P_80211_RAW*/
|
||||
skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/
|
||||
|
||||
//DBG_871X("(1)data=0x%x, head=0x%x, tail=0x%x, mac_header=0x%x, len=%d\n", skb->data, skb->head, skb->tail, skb->mac_header, skb->len);
|
||||
|
||||
//skb->mac.raw = skb->data;
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
//skb_pull(skb, 24);
|
||||
_rtw_memset(skb->cb, 0, sizeof(skb->cb));
|
||||
|
||||
rtw_netif_rx(pmgnt_netdev, skb);
|
||||
|
||||
precv_frame->u.hdr.pkt = NULL; // set pointer to NULL before rtw_free_recvframe() if call rtw_netif_rx()
|
||||
#endif
|
||||
}
|
||||
|
||||
int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
struct recv_priv *precvpriv;
|
||||
_queue *pfree_recv_queue;
|
||||
_pkt *skb;
|
||||
struct mlme_priv*pmlmepriv = &padapter->mlmepriv;
|
||||
#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
|
||||
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BR_EXT
|
||||
void *br_port = NULL;
|
||||
#endif
|
||||
|
||||
_func_enter_;
|
||||
|
||||
precvpriv = &(padapter->recvpriv);
|
||||
pfree_recv_queue = &(precvpriv->free_recv_queue);
|
||||
|
||||
#ifdef CONFIG_DRVEXT_MODULE
|
||||
if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS)
|
||||
{
|
||||
goto _recv_indicatepkt_drop;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WAPI_SUPPORT
|
||||
if (rtw_wapi_check_for_drop(padapter,precv_frame))
|
||||
{
|
||||
WAPI_TRACE(WAPI_ERR, "%s(): Rx Reorder Drop case!!\n", __FUNCTION__);
|
||||
goto _recv_indicatepkt_drop;
|
||||
}
|
||||
#endif
|
||||
|
||||
skb = precv_frame->u.hdr.pkt;
|
||||
if(skb == NULL)
|
||||
{
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n"));
|
||||
goto _recv_indicatepkt_drop;
|
||||
}
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n"));
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data));
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len));
|
||||
|
||||
skb->data = precv_frame->u.hdr.rx_data;
|
||||
|
||||
skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
|
||||
|
||||
skb->len = precv_frame->u.hdr.len;
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb->tail, skb->end, skb->len));
|
||||
|
||||
if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
|
||||
{
|
||||
_pkt *pskb2=NULL;
|
||||
struct sta_info *psta = NULL;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
|
||||
int bmcast = IS_MCAST(pattrib->dst);
|
||||
|
||||
//DBG_871X("bmcast=%d\n", bmcast);
|
||||
|
||||
if(_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)==_FALSE)
|
||||
{
|
||||
//DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst);
|
||||
|
||||
if(bmcast)
|
||||
{
|
||||
psta = rtw_get_bcmc_stainfo(padapter);
|
||||
pskb2 = rtw_skb_clone(skb);
|
||||
} else {
|
||||
psta = rtw_get_stainfo(pstapriv, pattrib->dst);
|
||||
}
|
||||
|
||||
if(psta)
|
||||
{
|
||||
struct net_device *pnetdev= (struct net_device*)padapter->pnetdev;
|
||||
|
||||
//DBG_871X("directly forwarding to the rtw_xmit_entry\n");
|
||||
|
||||
//skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->dev = pnetdev;
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
|
||||
skb_set_queue_mapping(skb, rtw_recv_select_queue(skb));
|
||||
#endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)
|
||||
|
||||
_rtw_xmit_entry(skb, pnetdev);
|
||||
|
||||
if(bmcast)
|
||||
skb = pskb2;
|
||||
else
|
||||
goto _recv_indicatepkt_end;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else// to APself
|
||||
{
|
||||
//DBG_871X("to APSelf\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_BR_EXT
|
||||
|
||||
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
|
||||
br_port = padapter->pnetdev->br_port;
|
||||
#else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
|
||||
rcu_read_lock();
|
||||
br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
|
||||
rcu_read_unlock();
|
||||
#endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
|
||||
|
||||
if( br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) )
|
||||
{
|
||||
int nat25_handle_frame(_adapter *priv, struct sk_buff *skb);
|
||||
if (nat25_handle_frame(padapter, skb) == -1) {
|
||||
//priv->ext_stats.rx_data_drops++;
|
||||
//DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n");
|
||||
//return FAIL;
|
||||
#if 1
|
||||
// bypass this frame to upper layer!!
|
||||
#else
|
||||
goto _recv_indicatepkt_drop;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONFIG_BR_EXT
|
||||
|
||||
|
||||
#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
|
||||
if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) {
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
//DBG_871X("CHECKSUM_UNNECESSARY \n");
|
||||
} else {
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
//DBG_871X("CHECKSUM_NONE(%d, %d) \n", pattrib->tcpchk_valid, pattrib->tcp_chkrpt);
|
||||
}
|
||||
#else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
|
||||
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
#endif
|
||||
|
||||
skb->dev = padapter->pnetdev;
|
||||
skb->protocol = eth_type_trans(skb, padapter->pnetdev);
|
||||
|
||||
#ifdef DBG_TRX_STA_PKTS
|
||||
{
|
||||
|
||||
struct sta_info *psta = NULL;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
|
||||
int bmcast = IS_MCAST(pattrib->dst);
|
||||
|
||||
if(bmcast)
|
||||
{
|
||||
psta = rtw_get_bcmc_stainfo(padapter);
|
||||
|
||||
} else {
|
||||
psta = rtw_get_stainfo(pstapriv, pattrib->src);
|
||||
}
|
||||
if(psta)
|
||||
{
|
||||
switch(pattrib->priority)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
psta->rx_bk_cnt++;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
psta->rx_vi_cnt++;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
psta->rx_vo_cnt++;
|
||||
break;
|
||||
case 0:
|
||||
case 3:
|
||||
default:
|
||||
psta->rx_be_cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rtw_netif_rx(padapter->pnetdev, skb);
|
||||
|
||||
_recv_indicatepkt_end:
|
||||
|
||||
precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe()
|
||||
|
||||
rtw_free_recvframe(precv_frame, pfree_recv_queue);
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_netif_rx!!!!\n"));
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return _SUCCESS;
|
||||
|
||||
_recv_indicatepkt_drop:
|
||||
|
||||
//enqueue back to free_recv_queue
|
||||
if(precv_frame)
|
||||
rtw_free_recvframe(precv_frame, pfree_recv_queue);
|
||||
|
||||
return _FAIL;
|
||||
|
||||
_func_exit_;
|
||||
|
||||
}
|
||||
|
||||
void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
struct recv_priv *precvpriv = &padapter->recvpriv;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
|
||||
precvbuf->ref_cnt--;
|
||||
|
||||
//free skb in recv_buf
|
||||
rtw_skb_free(precvbuf->pskb);
|
||||
|
||||
precvbuf->pskb = NULL;
|
||||
precvbuf->reuse = _FALSE;
|
||||
|
||||
if(precvbuf->irp_pending == _FALSE)
|
||||
{
|
||||
rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
|
||||
precvbuf->pskb = NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext);
|
||||
void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext)
|
||||
{
|
||||
struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)FunctionContext;
|
||||
rtw_reordering_ctrl_timeout_handler(preorder_ctrl);
|
||||
}
|
||||
|
||||
void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
|
||||
{
|
||||
_adapter *padapter = preorder_ctrl->padapter;
|
||||
|
||||
_init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev, _rtw_reordering_ctrl_timeout_handler, preorder_ctrl);
|
||||
|
||||
}
|
||||
|
|
@ -1,828 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include <rtw_android.h>
|
||||
#include <osdep_service.h>
|
||||
#include <rtw_debug.h>
|
||||
#include <ioctl_cfg80211.h>
|
||||
#include <rtw_ioctl_set.h>
|
||||
|
||||
#ifdef CONFIG_GPIO_WAKEUP
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)
|
||||
#include <linux/platform_device.h>
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
#include <linux/wlan_plat.h>
|
||||
#else
|
||||
#include <linux/wifi_tiwlan.h>
|
||||
#endif
|
||||
#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */
|
||||
|
||||
#ifdef CONFIG_GPIO_WAKEUP
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#endif
|
||||
|
||||
static const char *android_wifi_cmd_str[ANDROID_WIFI_CMD_MAX] = {
|
||||
"START",
|
||||
"STOP",
|
||||
"SCAN-ACTIVE",
|
||||
"SCAN-PASSIVE",
|
||||
"RSSI",
|
||||
"LINKSPEED",
|
||||
"RXFILTER-START",
|
||||
"RXFILTER-STOP",
|
||||
"RXFILTER-ADD",
|
||||
"RXFILTER-REMOVE",
|
||||
"BTCOEXSCAN-START",
|
||||
"BTCOEXSCAN-STOP",
|
||||
"BTCOEXMODE",
|
||||
"SETSUSPENDOPT",
|
||||
"P2P_DEV_ADDR",
|
||||
"SETFWPATH",
|
||||
"SETBAND",
|
||||
"GETBAND",
|
||||
"COUNTRY",
|
||||
"P2P_SET_NOA",
|
||||
"P2P_GET_NOA",
|
||||
"P2P_SET_PS",
|
||||
"SET_AP_WPS_P2P_IE",
|
||||
#ifdef PNO_SUPPORT
|
||||
"PNOSSIDCLR",
|
||||
"PNOSETUP ",
|
||||
"PNOFORCE",
|
||||
"PNODEBUG",
|
||||
#endif
|
||||
|
||||
"MACADDR",
|
||||
|
||||
"BLOCK",
|
||||
"WFD-ENABLE",
|
||||
"WFD-DISABLE",
|
||||
"WFD-SET-TCPPORT",
|
||||
"WFD-SET-MAXTPUT",
|
||||
"WFD-SET-DEVTYPE",
|
||||
};
|
||||
|
||||
#ifdef PNO_SUPPORT
|
||||
#define PNO_TLV_PREFIX 'S'
|
||||
#define PNO_TLV_VERSION '1'
|
||||
#define PNO_TLV_SUBVERSION '2'
|
||||
#define PNO_TLV_RESERVED '0'
|
||||
#define PNO_TLV_TYPE_SSID_IE 'S'
|
||||
#define PNO_TLV_TYPE_TIME 'T'
|
||||
#define PNO_TLV_FREQ_REPEAT 'R'
|
||||
#define PNO_TLV_FREQ_EXPO_MAX 'M'
|
||||
|
||||
typedef struct cmd_tlv {
|
||||
char prefix;
|
||||
char version;
|
||||
char subver;
|
||||
char reserved;
|
||||
} cmd_tlv_t;
|
||||
#endif /* PNO_SUPPORT */
|
||||
|
||||
typedef struct android_wifi_priv_cmd {
|
||||
char *buf;
|
||||
int used_len;
|
||||
int total_len;
|
||||
} android_wifi_priv_cmd;
|
||||
|
||||
/**
|
||||
* Local (static) functions and variables
|
||||
*/
|
||||
|
||||
/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
|
||||
* time (only) in dhd_open, subsequential wifi on will be handled by
|
||||
* wl_android_wifi_on
|
||||
*/
|
||||
static int g_wifi_on = _TRUE;
|
||||
|
||||
static unsigned int oob_irq;
|
||||
|
||||
#ifdef PNO_SUPPORT
|
||||
static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len)
|
||||
{
|
||||
wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
|
||||
int res = -1;
|
||||
int nssid = 0;
|
||||
cmd_tlv_t *cmd_tlv_temp;
|
||||
char *str_ptr;
|
||||
int tlv_size_left;
|
||||
int pno_time = 0;
|
||||
int pno_repeat = 0;
|
||||
int pno_freq_expo_max = 0;
|
||||
|
||||
#ifdef PNO_SET_DEBUG
|
||||
int i;
|
||||
char pno_in_example[] = {
|
||||
'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
|
||||
'S', '1', '2', '0',
|
||||
'S',
|
||||
0x05,
|
||||
'd', 'l', 'i', 'n', 'k',
|
||||
'S',
|
||||
0x04,
|
||||
'G', 'O', 'O', 'G',
|
||||
'T',
|
||||
'0', 'B',
|
||||
'R',
|
||||
'2',
|
||||
'M',
|
||||
'2',
|
||||
0x00
|
||||
};
|
||||
#endif /* PNO_SET_DEBUG */
|
||||
|
||||
DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
|
||||
|
||||
if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
|
||||
DBG_871X("%s argument=%d less min size\n", __FUNCTION__, total_len);
|
||||
goto exit_proc;
|
||||
}
|
||||
|
||||
#ifdef PNO_SET_DEBUG
|
||||
memcpy(command, pno_in_example, sizeof(pno_in_example));
|
||||
for (i = 0; i < sizeof(pno_in_example); i++)
|
||||
printf("%02X ", command[i]);
|
||||
printf("\n");
|
||||
total_len = sizeof(pno_in_example);
|
||||
#endif
|
||||
|
||||
str_ptr = command + strlen(CMD_PNOSETUP_SET);
|
||||
tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET);
|
||||
|
||||
cmd_tlv_temp = (cmd_tlv_t *)str_ptr;
|
||||
memset(ssids_local, 0, sizeof(ssids_local));
|
||||
|
||||
if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) &&
|
||||
(cmd_tlv_temp->version == PNO_TLV_VERSION) &&
|
||||
(cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) {
|
||||
|
||||
str_ptr += sizeof(cmd_tlv_t);
|
||||
tlv_size_left -= sizeof(cmd_tlv_t);
|
||||
|
||||
if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local,
|
||||
MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) {
|
||||
DBG_871X("SSID is not presented or corrupted ret=%d\n", nssid);
|
||||
goto exit_proc;
|
||||
} else {
|
||||
if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {
|
||||
DBG_871X("%s scan duration corrupted field size %d\n",
|
||||
__FUNCTION__, tlv_size_left);
|
||||
goto exit_proc;
|
||||
}
|
||||
str_ptr++;
|
||||
pno_time = simple_strtoul(str_ptr, &str_ptr, 16);
|
||||
DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time));
|
||||
|
||||
if (str_ptr[0] != 0) {
|
||||
if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {
|
||||
DBG_871X("%s pno repeat : corrupted field\n",
|
||||
__FUNCTION__);
|
||||
goto exit_proc;
|
||||
}
|
||||
str_ptr++;
|
||||
pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);
|
||||
DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat));
|
||||
if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {
|
||||
DBG_871X("%s FREQ_EXPO_MAX corrupted field size\n",
|
||||
__FUNCTION__);
|
||||
goto exit_proc;
|
||||
}
|
||||
str_ptr++;
|
||||
pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);
|
||||
DHD_INFO(("%s: pno_freq_expo_max=%d\n",
|
||||
__FUNCTION__, pno_freq_expo_max));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DBG_871X("%s get wrong TLV command\n", __FUNCTION__);
|
||||
goto exit_proc;
|
||||
}
|
||||
|
||||
res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max);
|
||||
|
||||
exit_proc:
|
||||
return res;
|
||||
}
|
||||
#endif /* PNO_SUPPORT */
|
||||
|
||||
int rtw_android_cmdstr_to_num(char *cmdstr)
|
||||
{
|
||||
int cmd_num;
|
||||
for(cmd_num=0 ; cmd_num<ANDROID_WIFI_CMD_MAX; cmd_num++)
|
||||
if(0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num], strlen(android_wifi_cmd_str[cmd_num])) )
|
||||
break;
|
||||
|
||||
return cmd_num;
|
||||
}
|
||||
|
||||
static int rtw_android_get_rssi(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
|
||||
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
|
||||
struct wlan_network *pcur_network = &pmlmepriv->cur_network;
|
||||
int bytes_written = 0;
|
||||
|
||||
if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
|
||||
bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d",
|
||||
pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
|
||||
}
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
|
||||
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
|
||||
struct wlan_network *pcur_network = &pmlmepriv->cur_network;
|
||||
int bytes_written = 0;
|
||||
u16 link_speed = 0;
|
||||
|
||||
link_speed = rtw_get_cur_max_rate(padapter)/10;
|
||||
bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed);
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)rtw_netdev_priv(net);
|
||||
int bytes_written = 0;
|
||||
|
||||
bytes_written = snprintf(command, total_len, "Macaddr = "MAC_FMT, MAC_ARG(net->dev_addr));
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_set_country(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)rtw_netdev_priv(net);
|
||||
char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1;
|
||||
int ret = _FAIL;
|
||||
|
||||
ret = rtw_set_country(adapter, country_code);
|
||||
|
||||
return (ret==_SUCCESS)?0:-1;
|
||||
}
|
||||
|
||||
static int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
int bytes_written = 0;
|
||||
|
||||
//We use the same address as our HW MAC address
|
||||
_rtw_memcpy(command, net->dev_addr, ETH_ALEN);
|
||||
|
||||
bytes_written = ETH_ALEN;
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_set_block(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)rtw_netdev_priv(net);
|
||||
char *block_value = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_BLOCK]) + 1;
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
wdev_to_priv(adapter->rtw_wdev)->block = (*block_value=='0')?_FALSE:_TRUE;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_int_from_command(char *pcmd)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for( i = 0; i < strlen( pcmd ); i++ )
|
||||
{
|
||||
if ( pcmd[ i ] == '=' )
|
||||
{
|
||||
// Skip the '=' and space characters.
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ( rtw_atoi( pcmd + i ) );
|
||||
}
|
||||
|
||||
int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
int ret = 0;
|
||||
char *command = NULL;
|
||||
int cmd_num;
|
||||
int bytes_written = 0;
|
||||
android_wifi_priv_cmd priv_cmd;
|
||||
_adapter* padapter = ( _adapter * ) rtw_netdev_priv(net);
|
||||
#ifdef CONFIG_WFD
|
||||
struct wifi_display_info *pwfd_info;
|
||||
#endif
|
||||
|
||||
rtw_lock_suspend();
|
||||
|
||||
if (!ifr->ifr_data) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) {
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
//DBG_871X("%s priv_cmd.buf=%p priv_cmd.total_len=%d priv_cmd.used_len=%d\n",__func__,priv_cmd.buf,priv_cmd.total_len,priv_cmd.used_len);
|
||||
command = rtw_zmalloc(priv_cmd.total_len);
|
||||
if (!command)
|
||||
{
|
||||
DBG_871X("%s: failed to allocate memory\n", __FUNCTION__);
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){
|
||||
DBG_871X("%s: failed to access memory\n", __FUNCTION__);
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
if (copy_from_user(command, (void *)priv_cmd.buf, priv_cmd.total_len)) {
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
DBG_871X("%s: Android private cmd \"%s\" on %s\n"
|
||||
, __FUNCTION__, command, ifr->ifr_name);
|
||||
|
||||
cmd_num = rtw_android_cmdstr_to_num(command);
|
||||
|
||||
switch(cmd_num) {
|
||||
case ANDROID_WIFI_CMD_START:
|
||||
//bytes_written = wl_android_wifi_on(net);
|
||||
goto response;
|
||||
case ANDROID_WIFI_CMD_SETFWPATH:
|
||||
goto response;
|
||||
}
|
||||
|
||||
if (!g_wifi_on) {
|
||||
DBG_871X("%s: Ignore private cmd \"%s\" - iface %s is down\n"
|
||||
,__FUNCTION__, command, ifr->ifr_name);
|
||||
ret = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch(cmd_num) {
|
||||
|
||||
case ANDROID_WIFI_CMD_STOP:
|
||||
//bytes_written = wl_android_wifi_off(net);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_SCAN_ACTIVE:
|
||||
//rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_ACTIVE);
|
||||
#ifdef CONFIG_PLATFORM_MSTAR
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
(wdev_to_priv(net->ieee80211_ptr))->bandroid_scan = _TRUE;
|
||||
#endif //CONFIG_IOCTL_CFG80211
|
||||
#endif //CONFIG_PLATFORM_MSTAR
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_SCAN_PASSIVE:
|
||||
//rtw_set_scan_mode((_adapter *)rtw_netdev_priv(net), SCAN_PASSIVE);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_RSSI:
|
||||
bytes_written = rtw_android_get_rssi(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_LINKSPEED:
|
||||
bytes_written = rtw_android_get_link_speed(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_MACADDR:
|
||||
bytes_written = rtw_android_get_macaddr(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_BLOCK:
|
||||
bytes_written = rtw_android_set_block(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_RXFILTER_START:
|
||||
//bytes_written = net_os_set_packet_filter(net, 1);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RXFILTER_STOP:
|
||||
//bytes_written = net_os_set_packet_filter(net, 0);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RXFILTER_ADD:
|
||||
//int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0';
|
||||
//bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RXFILTER_REMOVE:
|
||||
//int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0';
|
||||
//bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_BTCOEXSCAN_START:
|
||||
/* TBD: BTCOEXSCAN-START */
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP:
|
||||
/* TBD: BTCOEXSCAN-STOP */
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_BTCOEXMODE:
|
||||
#if 0
|
||||
uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';
|
||||
if (mode == 1)
|
||||
net_os_set_packet_filter(net, 0); /* DHCP starts */
|
||||
else
|
||||
net_os_set_packet_filter(net, 1); /* DHCP ends */
|
||||
#ifdef WL_CFG80211
|
||||
bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_SETSUSPENDOPT:
|
||||
//bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_SETBAND:
|
||||
{
|
||||
uint band = *(command + strlen("SETBAND") + 1) - '0';
|
||||
_adapter* padapter = ( _adapter * ) rtw_netdev_priv(net);
|
||||
|
||||
if (padapter->chip_type == RTL8192D)
|
||||
padapter->setband = band;
|
||||
|
||||
break;
|
||||
}
|
||||
case ANDROID_WIFI_CMD_GETBAND:
|
||||
//bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
|
||||
case ANDROID_WIFI_CMD_COUNTRY:
|
||||
bytes_written = rtw_android_set_country(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
|
||||
#ifdef PNO_SUPPORT
|
||||
case ANDROID_WIFI_CMD_PNOSSIDCLR_SET:
|
||||
//bytes_written = dhd_dev_pno_reset(net);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_PNOSETUP_SET:
|
||||
//bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_PNOENABLE_SET:
|
||||
//uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0';
|
||||
//bytes_written = dhd_dev_pno_enable(net, pfn_enabled);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ANDROID_WIFI_CMD_P2P_DEV_ADDR:
|
||||
bytes_written = rtw_android_get_p2p_dev_addr(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_P2P_SET_NOA:
|
||||
//int skip = strlen(CMD_P2P_SET_NOA) + 1;
|
||||
//bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip, priv_cmd.total_len - skip);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_P2P_GET_NOA:
|
||||
//bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_P2P_SET_PS:
|
||||
//int skip = strlen(CMD_P2P_SET_PS) + 1;
|
||||
//bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip, priv_cmd.total_len - skip);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE:
|
||||
{
|
||||
int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3;
|
||||
bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0');
|
||||
break;
|
||||
}
|
||||
#endif //CONFIG_IOCTL_CFG80211
|
||||
|
||||
#ifdef CONFIG_WFD
|
||||
case ANDROID_WIFI_CMD_WFD_ENABLE:
|
||||
// Commented by Albert 2012/07/24
|
||||
// We can enable the WFD function by using the following command:
|
||||
// wpa_cli driver wfd-enable
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
|
||||
pwfd_info->wfd_enable = _TRUE;
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_DISABLE:
|
||||
// Commented by Albert 2012/07/24
|
||||
// We can disable the WFD function by using the following command:
|
||||
// wpa_cli driver wfd-disable
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
|
||||
pwfd_info->wfd_enable = _FALSE;
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_SET_TCPPORT:
|
||||
// Commented by Albert 2012/07/24
|
||||
// We can set the tcp port number by using the following command:
|
||||
// wpa_cli driver wfd-set-tcpport = 554
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
|
||||
pwfd_info->rtsp_ctrlport = (u16)get_int_from_command(priv_cmd.buf);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE:
|
||||
{
|
||||
// Commented by Albert 2012/08/28
|
||||
// Specify the WFD device type ( WFD source/primary sink )
|
||||
|
||||
struct wifi_display_info *pwfd_info;
|
||||
_adapter* padapter = ( _adapter * ) rtw_netdev_priv(net);
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
|
||||
pwfd_info->wfd_device_type = (u8)get_int_from_command(priv_cmd.buf);
|
||||
|
||||
pwfd_info->wfd_device_type &= WFD_DEVINFO_DUAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
DBG_871X("Unknown PRIVATE command %s - ignored\n", command);
|
||||
snprintf(command, 3, "OK");
|
||||
bytes_written = strlen("OK");
|
||||
}
|
||||
|
||||
response:
|
||||
if (bytes_written >= 0) {
|
||||
if ((bytes_written == 0) && (priv_cmd.total_len > 0))
|
||||
command[0] = '\0';
|
||||
if (bytes_written >= priv_cmd.total_len) {
|
||||
DBG_871X("%s: bytes_written = %d\n", __FUNCTION__, bytes_written);
|
||||
bytes_written = priv_cmd.total_len;
|
||||
} else {
|
||||
bytes_written++;
|
||||
}
|
||||
priv_cmd.used_len = bytes_written;
|
||||
if (copy_to_user((void *)priv_cmd.buf, command, bytes_written)) {
|
||||
DBG_871X("%s: failed to copy data to user buffer\n", __FUNCTION__);
|
||||
ret = -EFAULT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = bytes_written;
|
||||
}
|
||||
|
||||
exit:
|
||||
rtw_unlock_suspend();
|
||||
if (command) {
|
||||
rtw_mfree(command, priv_cmd.total_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Functions for Android WiFi card detection
|
||||
*/
|
||||
#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)
|
||||
|
||||
static int g_wifidev_registered = 0;
|
||||
static struct semaphore wifi_control_sem;
|
||||
static struct wifi_platform_data *wifi_control_data = NULL;
|
||||
static struct resource *wifi_irqres = NULL;
|
||||
|
||||
static int wifi_add_dev(void);
|
||||
static void wifi_del_dev(void);
|
||||
|
||||
int rtw_android_wifictrl_func_add(void)
|
||||
{
|
||||
int ret = 0;
|
||||
sema_init(&wifi_control_sem, 0);
|
||||
|
||||
ret = wifi_add_dev();
|
||||
if (ret) {
|
||||
DBG_871X("%s: platform_driver_register failed\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
g_wifidev_registered = 1;
|
||||
|
||||
/* Waiting callback after platform_driver_register is done or exit with error */
|
||||
if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
|
||||
ret = -EINVAL;
|
||||
DBG_871X("%s: platform_driver_register timeout\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rtw_android_wifictrl_func_del(void)
|
||||
{
|
||||
if (g_wifidev_registered)
|
||||
{
|
||||
wifi_del_dev();
|
||||
g_wifidev_registered = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *wl_android_prealloc(int section, unsigned long size)
|
||||
{
|
||||
void *alloc_ptr = NULL;
|
||||
if (wifi_control_data && wifi_control_data->mem_prealloc) {
|
||||
alloc_ptr = wifi_control_data->mem_prealloc(section, size);
|
||||
if (alloc_ptr) {
|
||||
DBG_871X("success alloc section %d\n", section);
|
||||
if (size != 0L)
|
||||
memset(alloc_ptr, 0, size);
|
||||
return alloc_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
DBG_871X("can't alloc section %d\n", section);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int wifi_get_irq_number(unsigned long *irq_flags_ptr)
|
||||
{
|
||||
if (wifi_irqres) {
|
||||
*irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK;
|
||||
return (int)wifi_irqres->start;
|
||||
}
|
||||
#ifdef CUSTOM_OOB_GPIO_NUM
|
||||
return CUSTOM_OOB_GPIO_NUM;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int wifi_set_power(int on, unsigned long msec)
|
||||
{
|
||||
DBG_871X("%s = %d\n", __FUNCTION__, on);
|
||||
if (wifi_control_data && wifi_control_data->set_power) {
|
||||
wifi_control_data->set_power(on);
|
||||
}
|
||||
if (msec)
|
||||
msleep(msec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
int wifi_get_mac_addr(unsigned char *buf)
|
||||
{
|
||||
DBG_871X("%s\n", __FUNCTION__);
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
if (wifi_control_data && wifi_control_data->get_mac_addr) {
|
||||
return wifi_control_data->get_mac_addr(buf);
|
||||
}
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) || defined(COMPAT_KERNEL_RELEASE)
|
||||
void *wifi_get_country_code(char *ccode)
|
||||
{
|
||||
DBG_871X("%s\n", __FUNCTION__);
|
||||
if (!ccode)
|
||||
return NULL;
|
||||
if (wifi_control_data && wifi_control_data->get_country_code) {
|
||||
return wifi_control_data->get_country_code(ccode);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */
|
||||
|
||||
static int wifi_set_carddetect(int on)
|
||||
{
|
||||
DBG_871X("%s = %d\n", __FUNCTION__, on);
|
||||
if (wifi_control_data && wifi_control_data->set_carddetect) {
|
||||
wifi_control_data->set_carddetect(on);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wifi_platform_data *wifi_ctrl =
|
||||
(struct wifi_platform_data *)(pdev->dev.platform_data);
|
||||
int wifi_wake_gpio = 0;
|
||||
|
||||
DBG_871X("## %s\n", __FUNCTION__);
|
||||
wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
|
||||
|
||||
if (wifi_irqres == NULL)
|
||||
wifi_irqres = platform_get_resource_byname(pdev,
|
||||
IORESOURCE_IRQ, "bcm4329_wlan_irq");
|
||||
else
|
||||
wifi_wake_gpio = wifi_irqres->start;
|
||||
|
||||
#ifdef CONFIG_GPIO_WAKEUP
|
||||
printk("%s: gpio:%d wifi_wake_gpio:%d\n", __func__,
|
||||
wifi_irqres->start, wifi_wake_gpio);
|
||||
|
||||
if (wifi_wake_gpio > 0) {
|
||||
gpio_request(wifi_wake_gpio, "oob_irq");
|
||||
gpio_direction_input(wifi_wake_gpio);
|
||||
oob_irq = gpio_to_irq(wifi_wake_gpio);
|
||||
printk("%s oob_irq:%d\n", __func__, oob_irq);
|
||||
}
|
||||
#endif
|
||||
wifi_control_data = wifi_ctrl;
|
||||
|
||||
wifi_set_power(1, 0); /* Power On */
|
||||
wifi_set_carddetect(1); /* CardDetect (0->1) */
|
||||
|
||||
up(&wifi_control_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct wifi_platform_data *wifi_ctrl =
|
||||
(struct wifi_platform_data *)(pdev->dev.platform_data);
|
||||
|
||||
DBG_871X("## %s\n", __FUNCTION__);
|
||||
wifi_control_data = wifi_ctrl;
|
||||
|
||||
wifi_set_power(0, 0); /* Power Off */
|
||||
wifi_set_carddetect(0); /* CardDetect (1->0) */
|
||||
|
||||
up(&wifi_control_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
DBG_871X("##> %s\n", __FUNCTION__);
|
||||
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
|
||||
bcmsdh_oob_intr_set(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_resume(struct platform_device *pdev)
|
||||
{
|
||||
DBG_871X("##> %s\n", __FUNCTION__);
|
||||
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
|
||||
if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
|
||||
bcmsdh_oob_intr_set(1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* temporarily use these two */
|
||||
static struct platform_driver wifi_device = {
|
||||
.probe = wifi_probe,
|
||||
.remove = wifi_remove,
|
||||
.suspend = wifi_suspend,
|
||||
.resume = wifi_resume,
|
||||
.driver = {
|
||||
.name = "bcmdhd_wlan",
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_driver wifi_device_legacy = {
|
||||
.probe = wifi_probe,
|
||||
.remove = wifi_remove,
|
||||
.suspend = wifi_suspend,
|
||||
.resume = wifi_resume,
|
||||
.driver = {
|
||||
.name = "bcm4329_wlan",
|
||||
}
|
||||
};
|
||||
|
||||
static int wifi_add_dev(void)
|
||||
{
|
||||
DBG_871X("## Calling platform_driver_register\n");
|
||||
platform_driver_register(&wifi_device);
|
||||
platform_driver_register(&wifi_device_legacy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wifi_del_dev(void)
|
||||
{
|
||||
DBG_871X("## Unregister platform_driver_register\n");
|
||||
platform_driver_unregister(&wifi_device);
|
||||
platform_driver_unregister(&wifi_device_legacy);
|
||||
}
|
||||
#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,698 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define _USB_OPS_LINUX_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
#include <usb_ops_linux.h>
|
||||
#include <rtw_sreset.h>
|
||||
|
||||
#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
|
||||
static void _usbctrl_vendorreq_async_callback(struct urb *urb, struct pt_regs *regs)
|
||||
{
|
||||
if (urb) {
|
||||
if (urb->context) {
|
||||
rtw_mfree(urb->context);
|
||||
}
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
}
|
||||
|
||||
static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
|
||||
u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
|
||||
{
|
||||
int rc;
|
||||
unsigned int pipe;
|
||||
u8 reqtype;
|
||||
struct usb_ctrlrequest *dr;
|
||||
struct urb *urb;
|
||||
struct rtl819x_async_write_data {
|
||||
u8 data[VENDOR_CMD_MAX_DATA_LEN];
|
||||
struct usb_ctrlrequest dr;
|
||||
} *buf;
|
||||
|
||||
|
||||
if (requesttype == VENDOR_READ) {
|
||||
pipe = usb_rcvctrlpipe(udev, 0);//read_in
|
||||
reqtype = REALTEK_USB_VENQT_READ;
|
||||
}
|
||||
else {
|
||||
pipe = usb_sndctrlpipe(udev, 0);//write_out
|
||||
reqtype = REALTEK_USB_VENQT_WRITE;
|
||||
}
|
||||
|
||||
buf = (struct rtl819x_async_write_data *)rtw_zmalloc(sizeof(*buf));
|
||||
if (!buf) {
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!urb) {
|
||||
rtw_mfree((u8*)buf, sizeof(*buf));
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dr = &buf->dr;
|
||||
|
||||
dr->bRequestType = reqtype;
|
||||
dr->bRequest = request;
|
||||
dr->wValue = cpu_to_le16(value);
|
||||
dr->wIndex = cpu_to_le16(index);
|
||||
dr->wLength = cpu_to_le16(len);
|
||||
|
||||
_rtw_memcpy(buf, pdata, len);
|
||||
|
||||
usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr, buf, len,
|
||||
_usbctrl_vendorreq_async_callback, buf);
|
||||
|
||||
rc = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (rc < 0) {
|
||||
rtw_mfree((u8*)buf, sizeof(*buf));
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int usb_write_async(struct usb_device *udev, u32 addr, void *pdata, u16 len)
|
||||
{
|
||||
u8 request;
|
||||
u8 requesttype;
|
||||
u16 wvalue;
|
||||
u16 index;
|
||||
|
||||
int ret;
|
||||
|
||||
requesttype = VENDOR_WRITE;//write_out
|
||||
request = REALTEK_USB_VENQT_CMD_REQ;
|
||||
index = REALTEK_USB_VENQT_CMD_IDX;//n/a
|
||||
|
||||
wvalue = (u16)(addr&0x0000ffff);
|
||||
|
||||
ret = _usbctrl_vendorreq_async_write(udev, request, wvalue, index, pdata, len, requesttype);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
|
||||
{
|
||||
u8 data;
|
||||
int ret;
|
||||
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
|
||||
struct usb_device *udev=pdvobjpriv->pusbdev;
|
||||
|
||||
_func_enter_;
|
||||
data = val;
|
||||
ret = usb_write_async(udev, addr, &data, 1);
|
||||
_func_exit_;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
|
||||
{
|
||||
u16 data;
|
||||
int ret;
|
||||
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
|
||||
struct usb_device *udev=pdvobjpriv->pusbdev;
|
||||
|
||||
_func_enter_;
|
||||
data = val;
|
||||
ret = usb_write_async(udev, addr, &data, 2);
|
||||
_func_exit_;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
|
||||
{
|
||||
u32 data;
|
||||
int ret;
|
||||
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
|
||||
struct usb_device *udev=pdvobjpriv->pusbdev;
|
||||
|
||||
_func_enter_;
|
||||
data = val;
|
||||
ret = usb_write_async(udev, addr, &data, 4);
|
||||
_func_exit_;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */
|
||||
|
||||
unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
|
||||
{
|
||||
unsigned int pipe=0, ep_num=0;
|
||||
struct usb_device *pusbd = pdvobj->pusbdev;
|
||||
|
||||
if (addr == RECV_BULK_IN_ADDR) {
|
||||
pipe=usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]);
|
||||
|
||||
} else if (addr == RECV_INT_IN_ADDR) {
|
||||
pipe=usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[1]);
|
||||
|
||||
} else if (addr < HW_QUEUE_ENTRY) {
|
||||
ep_num = pdvobj->Queue2Pipe[addr];
|
||||
pipe = usb_sndbulkpipe(pusbd, ep_num);
|
||||
}
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
struct zero_bulkout_context{
|
||||
void *pbuf;
|
||||
void *purb;
|
||||
void *pirp;
|
||||
void *padapter;
|
||||
};
|
||||
|
||||
static void usb_bulkout_zero_complete(struct urb *purb, struct pt_regs *regs)
|
||||
{
|
||||
struct zero_bulkout_context *pcontext = (struct zero_bulkout_context *)purb->context;
|
||||
|
||||
//DBG_8192C("+usb_bulkout_zero_complete\n");
|
||||
|
||||
if(pcontext)
|
||||
{
|
||||
if(pcontext->pbuf)
|
||||
{
|
||||
rtw_mfree(pcontext->pbuf, sizeof(int));
|
||||
}
|
||||
|
||||
if(pcontext->purb && (pcontext->purb==purb))
|
||||
{
|
||||
usb_free_urb(pcontext->purb);
|
||||
}
|
||||
|
||||
|
||||
rtw_mfree((u8*)pcontext, sizeof(struct zero_bulkout_context));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr)
|
||||
{
|
||||
int pipe, status, len;
|
||||
u32 ret;
|
||||
unsigned char *pbuf;
|
||||
struct zero_bulkout_context *pcontext;
|
||||
PURB purb = NULL;
|
||||
_adapter *padapter = (_adapter *)pintfhdl->padapter;
|
||||
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobj->pusbdev;
|
||||
|
||||
//DBG_871X("%s\n", __func__);
|
||||
|
||||
|
||||
if((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx))
|
||||
{
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
|
||||
pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context));
|
||||
|
||||
pbuf = (unsigned char *)rtw_zmalloc(sizeof(int));
|
||||
purb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
|
||||
len = 0;
|
||||
pcontext->pbuf = pbuf;
|
||||
pcontext->purb = purb;
|
||||
pcontext->pirp = NULL;
|
||||
pcontext->padapter = padapter;
|
||||
|
||||
|
||||
//translate DMA FIFO addr to pipehandle
|
||||
//pipe = ffaddr2pipehdl(pdvobj, addr);
|
||||
|
||||
usb_fill_bulk_urb(purb, pusbd, pipe,
|
||||
pbuf,
|
||||
len,
|
||||
usb_bulkout_zero_complete,
|
||||
pcontext);//context is pcontext
|
||||
|
||||
status = usb_submit_urb(purb, GFP_ATOMIC);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
ret= _SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret= _FAIL;
|
||||
}
|
||||
|
||||
|
||||
return _SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void usb_read_port_cancel(struct intf_hdl *pintfhdl)
|
||||
{
|
||||
int i;
|
||||
struct recv_buf *precvbuf;
|
||||
_adapter *padapter = pintfhdl->padapter;
|
||||
precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
|
||||
|
||||
DBG_871X("%s\n", __func__);
|
||||
|
||||
padapter->bReadPortCancel = _TRUE;
|
||||
|
||||
for (i=0; i < NR_RECVBUFF ; i++) {
|
||||
|
||||
precvbuf->reuse = _TRUE;
|
||||
if (precvbuf->purb) {
|
||||
//DBG_8192C("usb_read_port_cancel : usb_kill_urb \n");
|
||||
usb_kill_urb(precvbuf->purb);
|
||||
}
|
||||
precvbuf++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
|
||||
usb_kill_urb(padapter->recvpriv.int_in_urb);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
|
||||
{
|
||||
_irqL irqL;
|
||||
int i;
|
||||
struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
|
||||
//struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
|
||||
//_adapter *padapter = pxmitframe->padapter;
|
||||
_adapter *padapter = pxmitbuf->padapter;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
//struct pkt_attrib *pattrib = &pxmitframe->attrib;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
switch(pxmitbuf->flags)
|
||||
{
|
||||
case VO_QUEUE_INX:
|
||||
pxmitpriv->voq_cnt--;
|
||||
break;
|
||||
case VI_QUEUE_INX:
|
||||
pxmitpriv->viq_cnt--;
|
||||
break;
|
||||
case BE_QUEUE_INX:
|
||||
pxmitpriv->beq_cnt--;
|
||||
break;
|
||||
case BK_QUEUE_INX:
|
||||
pxmitpriv->bkq_cnt--;
|
||||
break;
|
||||
case HIGH_QUEUE_INX:
|
||||
#ifdef CONFIG_AP_MODE
|
||||
rtw_chk_hi_queue_cmd(padapter);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
_enter_critical(&pxmitpriv->lock, &irqL);
|
||||
|
||||
pxmitpriv->txirp_cnt--;
|
||||
|
||||
switch(pattrib->priority)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
pxmitpriv->bkq_cnt--;
|
||||
//DBG_8192C("pxmitpriv->bkq_cnt=%d\n", pxmitpriv->bkq_cnt);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
pxmitpriv->viq_cnt--;
|
||||
//DBG_8192C("pxmitpriv->viq_cnt=%d\n", pxmitpriv->viq_cnt);
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
pxmitpriv->voq_cnt--;
|
||||
//DBG_8192C("pxmitpriv->voq_cnt=%d\n", pxmitpriv->voq_cnt);
|
||||
break;
|
||||
case 0:
|
||||
case 3:
|
||||
default:
|
||||
pxmitpriv->beq_cnt--;
|
||||
//DBG_8192C("pxmitpriv->beq_cnt=%d\n", pxmitpriv->beq_cnt);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
_exit_critical(&pxmitpriv->lock, &irqL);
|
||||
|
||||
|
||||
if(pxmitpriv->txirp_cnt==0)
|
||||
{
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: txirp_cnt== 0, set allrxreturnevt!\n"));
|
||||
_rtw_up_sema(&(pxmitpriv->tx_retevt));
|
||||
}
|
||||
*/
|
||||
//rtw_free_xmitframe(pxmitpriv, pxmitframe);
|
||||
|
||||
if(padapter->bSurpriseRemoved || padapter->bDriverStopped ||padapter->bWritePortCancel)
|
||||
{
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
|
||||
DBG_8192C("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x) \n",
|
||||
__FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved,padapter->bReadPortCancel,pxmitbuf->ext_tag);
|
||||
|
||||
goto check_completion;
|
||||
}
|
||||
|
||||
|
||||
if (purb->status==0) {
|
||||
|
||||
} else {
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete : purb->status(%d) != 0 \n", purb->status));
|
||||
DBG_871X("###=> urb_write_port_complete status(%d)\n",purb->status);
|
||||
if((purb->status==-EPIPE)||(purb->status==-EPROTO))
|
||||
{
|
||||
//usb_clear_halt(pusbdev, purb->pipe);
|
||||
//msleep(10);
|
||||
sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL);
|
||||
} else if (purb->status == -EINPROGRESS) {
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: EINPROGESS\n"));
|
||||
goto check_completion;
|
||||
|
||||
} else if (purb->status == -ENOENT) {
|
||||
DBG_871X("%s: -ENOENT\n", __func__);
|
||||
goto check_completion;
|
||||
|
||||
} else if (purb->status == -ECONNRESET) {
|
||||
DBG_871X("%s: -ECONNRESET\n", __func__);
|
||||
goto check_completion;
|
||||
|
||||
} else if (purb->status == -ESHUTDOWN) {
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: ESHUTDOWN\n"));
|
||||
padapter->bDriverStopped=_TRUE;
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped=TRUE\n"));
|
||||
|
||||
goto check_completion;
|
||||
}
|
||||
else
|
||||
{
|
||||
padapter->bSurpriseRemoved=_TRUE;
|
||||
DBG_8192C("bSurpriseRemoved=TRUE\n");
|
||||
//rtl8192cu_trigger_gpio_0(padapter);
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bSurpriseRemoved=TRUE\n"));
|
||||
|
||||
goto check_completion;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DBG_CONFIG_ERROR_DETECT
|
||||
{
|
||||
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
|
||||
pHalData->srestpriv.last_tx_complete_time = rtw_get_current_time();
|
||||
}
|
||||
#endif
|
||||
|
||||
check_completion:
|
||||
_enter_critical(&pxmitpriv->lock_sctx, &irqL);
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx,
|
||||
purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
|
||||
_exit_critical(&pxmitpriv->lock_sctx, &irqL);
|
||||
|
||||
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
|
||||
|
||||
//if(rtw_txframes_pending(padapter))
|
||||
{
|
||||
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
|
||||
}
|
||||
|
||||
u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
|
||||
{
|
||||
_irqL irqL;
|
||||
unsigned int pipe;
|
||||
int status;
|
||||
u32 ret = _FAIL, bwritezero = _FALSE;
|
||||
PURB purb = NULL;
|
||||
_adapter *padapter = (_adapter *)pintfhdl->padapter;
|
||||
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem;
|
||||
struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
|
||||
struct usb_device *pusbd = pdvobj->pusbdev;
|
||||
struct pkt_attrib *pattrib = &pxmitframe->attrib;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port\n"));
|
||||
|
||||
if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx)) {
|
||||
#ifdef DBG_TX
|
||||
DBG_871X(" DBG_TX %s:%d bDriverStopped%d, bSurpriseRemoved:%d, pnp_bstop_trx:%d\n",__FUNCTION__, __LINE__
|
||||
,padapter->bDriverStopped, padapter->bSurpriseRemoved, dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx );
|
||||
#endif
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||pwrctl->pnp_bstop_trx)!!!\n"));
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
_enter_critical(&pxmitpriv->lock, &irqL);
|
||||
|
||||
switch(addr)
|
||||
{
|
||||
case VO_QUEUE_INX:
|
||||
pxmitpriv->voq_cnt++;
|
||||
pxmitbuf->flags = VO_QUEUE_INX;
|
||||
break;
|
||||
case VI_QUEUE_INX:
|
||||
pxmitpriv->viq_cnt++;
|
||||
pxmitbuf->flags = VI_QUEUE_INX;
|
||||
break;
|
||||
case BE_QUEUE_INX:
|
||||
pxmitpriv->beq_cnt++;
|
||||
pxmitbuf->flags = BE_QUEUE_INX;
|
||||
break;
|
||||
case BK_QUEUE_INX:
|
||||
pxmitpriv->bkq_cnt++;
|
||||
pxmitbuf->flags = BK_QUEUE_INX;
|
||||
break;
|
||||
case HIGH_QUEUE_INX:
|
||||
pxmitbuf->flags = HIGH_QUEUE_INX;
|
||||
break;
|
||||
default:
|
||||
pxmitbuf->flags = MGT_QUEUE_INX;
|
||||
break;
|
||||
}
|
||||
|
||||
_exit_critical(&pxmitpriv->lock, &irqL);
|
||||
|
||||
#ifdef DBG_TRX_STA_PKTS
|
||||
{
|
||||
struct sta_info *psta = NULL;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
int bmcast = IS_MCAST(pattrib->dst);
|
||||
u8 agg_num = 1;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
#ifdef CONFIG_USB_TX_AGGREGATION
|
||||
if(pxmitframe->agg_num>1)
|
||||
agg_num = pxmitframe->agg_num;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
|
||||
if(pxmitframe->agg_num>1)
|
||||
agg_num = pxmitframe->agg_num;
|
||||
#endif
|
||||
|
||||
if(bmcast)
|
||||
{
|
||||
psta = rtw_get_bcmc_stainfo(padapter);
|
||||
|
||||
} else {
|
||||
psta = rtw_get_stainfo(pstapriv, pattrib->dst);
|
||||
}
|
||||
if(psta)
|
||||
{
|
||||
switch(pattrib->priority)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
psta->tx_bk_cnt += agg_num;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
psta->tx_vi_cnt += agg_num;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
psta->tx_vo_cnt += agg_num;
|
||||
break;
|
||||
case 0:
|
||||
case 3:
|
||||
default:
|
||||
psta->tx_be_cnt += agg_num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
purb = pxmitbuf->pxmit_urb[0];
|
||||
|
||||
#if 0
|
||||
if(pdvobj->ishighspeed)
|
||||
{
|
||||
if(cnt> 0 && cnt%512 == 0)
|
||||
{
|
||||
//DBG_8192C("ishighspeed, cnt=%d\n", cnt);
|
||||
bwritezero = _TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cnt > 0 && cnt%64 == 0)
|
||||
{
|
||||
//DBG_8192C("cnt=%d\n", cnt);
|
||||
bwritezero = _TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//translate DMA FIFO addr to pipehandle
|
||||
pipe = ffaddr2pipehdl(pdvobj, addr);
|
||||
|
||||
#ifdef CONFIG_REDUCE_USB_TX_INT
|
||||
if ( (pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0)
|
||||
|| (pxmitbuf->ext_tag == _TRUE) )
|
||||
{
|
||||
purb->transfer_flags &= (~URB_NO_INTERRUPT);
|
||||
} else {
|
||||
purb->transfer_flags |= URB_NO_INTERRUPT;
|
||||
//DBG_8192C("URB_NO_INTERRUPT ");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
usb_fill_bulk_urb(purb, pusbd, pipe,
|
||||
pxmitframe->buf_addr, //= pxmitbuf->pbuf
|
||||
cnt,
|
||||
usb_write_port_complete,
|
||||
pxmitbuf);//context is pxmitbuf
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
purb->transfer_dma = pxmitbuf->dma_transfer_addr;
|
||||
purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
|
||||
purb->transfer_flags |= URB_ZERO_PACKET;
|
||||
#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
|
||||
#if 0
|
||||
if (bwritezero)
|
||||
{
|
||||
purb->transfer_flags |= URB_ZERO_PACKET;
|
||||
}
|
||||
#endif
|
||||
|
||||
status = usb_submit_urb(purb, GFP_ATOMIC);
|
||||
if (!status) {
|
||||
#ifdef DBG_CONFIG_ERROR_DETECT
|
||||
{
|
||||
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
|
||||
pHalData->srestpriv.last_tx_time = rtw_get_current_time();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
|
||||
DBG_871X("usb_write_port, status=%d\n", status);
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port(): usb_submit_urb, status=%x\n", status));
|
||||
|
||||
switch (status) {
|
||||
case -ENODEV:
|
||||
padapter->bDriverStopped=_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret= _SUCCESS;
|
||||
|
||||
// Commented by Albert 2009/10/13
|
||||
// We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically.
|
||||
/*
|
||||
if(bwritezero == _TRUE)
|
||||
{
|
||||
usb_bulkout_zero(pintfhdl, addr);
|
||||
}
|
||||
*/
|
||||
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("-usb_write_port\n"));
|
||||
|
||||
exit:
|
||||
if (ret != _SUCCESS)
|
||||
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
|
||||
_func_exit_;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void usb_write_port_cancel(struct intf_hdl *pintfhdl)
|
||||
{
|
||||
int i, j;
|
||||
_adapter *padapter = pintfhdl->padapter;
|
||||
struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf;
|
||||
|
||||
DBG_871X("%s \n", __func__);
|
||||
|
||||
padapter->bWritePortCancel = _TRUE;
|
||||
|
||||
for (i=0; i<NR_XMITBUFF; i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
if (pxmitbuf->pxmit_urb[j]) {
|
||||
usb_kill_urb(pxmitbuf->pxmit_urb[j]);
|
||||
}
|
||||
}
|
||||
pxmitbuf++;
|
||||
}
|
||||
|
||||
pxmitbuf = (struct xmit_buf*)padapter->xmitpriv.pxmit_extbuf;
|
||||
for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
if(pxmitbuf->pxmit_urb[j]) {
|
||||
usb_kill_urb(pxmitbuf->pxmit_urb[j]);
|
||||
}
|
||||
}
|
||||
pxmitbuf++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,456 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _XMIT_OSDEP_C_
|
||||
|
||||
#include <drv_conf.h>
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
|
||||
#include <if_ether.h>
|
||||
#include <ip.h>
|
||||
#include <rtw_byteorder.h>
|
||||
#include <wifi.h>
|
||||
#include <mlme_osdep.h>
|
||||
#include <xmit_osdep.h>
|
||||
#include <osdep_intf.h>
|
||||
#include <circ_buf.h>
|
||||
|
||||
uint rtw_remainder_len(struct pkt_file *pfile)
|
||||
{
|
||||
return (pfile->buf_len - ((SIZE_PTR)(pfile->cur_addr) - (SIZE_PTR)(pfile->buf_start)));
|
||||
}
|
||||
|
||||
void _rtw_open_pktfile (_pkt *pktptr, struct pkt_file *pfile)
|
||||
{
|
||||
_func_enter_;
|
||||
|
||||
pfile->pkt = pktptr;
|
||||
pfile->cur_addr = pfile->buf_start = pktptr->data;
|
||||
pfile->pkt_len = pfile->buf_len = pktptr->len;
|
||||
|
||||
pfile->cur_buffer = pfile->buf_start ;
|
||||
|
||||
_func_exit_;
|
||||
}
|
||||
|
||||
uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen)
|
||||
{
|
||||
uint len = 0;
|
||||
|
||||
_func_enter_;
|
||||
|
||||
len = rtw_remainder_len(pfile);
|
||||
len = (rlen > len)? len: rlen;
|
||||
|
||||
if(rmem)
|
||||
skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len, rmem, len);
|
||||
|
||||
pfile->cur_addr += len;
|
||||
pfile->pkt_len -= len;
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
sint rtw_endofpktfile(struct pkt_file *pfile)
|
||||
{
|
||||
_func_enter_;
|
||||
|
||||
if (pfile->pkt_len == 0) {
|
||||
_func_exit_;
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return _FALSE;
|
||||
}
|
||||
|
||||
void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
|
||||
struct sk_buff *skb = (struct sk_buff *)pkt;
|
||||
pattrib->hw_tcp_csum = 0;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
if (skb_shinfo(skb)->nr_frags == 0)
|
||||
{
|
||||
const struct iphdr *ip = ip_hdr(skb);
|
||||
if (ip->protocol == IPPROTO_TCP) {
|
||||
// TCP checksum offload by HW
|
||||
DBG_871X("CHECKSUM_PARTIAL TCP\n");
|
||||
pattrib->hw_tcp_csum = 1;
|
||||
//skb_checksum_help(skb);
|
||||
} else if (ip->protocol == IPPROTO_UDP) {
|
||||
//DBG_871X("CHECKSUM_PARTIAL UDP\n");
|
||||
#if 1
|
||||
skb_checksum_help(skb);
|
||||
#else
|
||||
// Set UDP checksum = 0 to skip checksum check
|
||||
struct udphdr *udp = skb_transport_header(skb);
|
||||
udp->check = 0;
|
||||
#endif
|
||||
} else {
|
||||
DBG_871X("%s-%d TCP CSUM offload Error!!\n", __FUNCTION__, __LINE__);
|
||||
WARN_ON(1); /* we need a WARN() */
|
||||
}
|
||||
}
|
||||
else { // IP fragmentation case
|
||||
DBG_871X("%s-%d nr_frags != 0, using skb_checksum_help(skb);!!\n", __FUNCTION__, __LINE__);
|
||||
skb_checksum_help(skb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 alloc_sz)
|
||||
{
|
||||
#ifdef CONFIG_USB_HCI
|
||||
int i;
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
pxmitbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)alloc_sz, &pxmitbuf->dma_transfer_addr);
|
||||
pxmitbuf->pbuf = pxmitbuf->pallocated_buf;
|
||||
if(pxmitbuf->pallocated_buf == NULL)
|
||||
return _FAIL;
|
||||
#else // CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
|
||||
pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz);
|
||||
if (pxmitbuf->pallocated_buf == NULL)
|
||||
{
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
|
||||
pxmitbuf->dma_transfer_addr = 0;
|
||||
|
||||
#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if(pxmitbuf->pxmit_urb[i] == NULL)
|
||||
{
|
||||
DBG_871X("pxmitbuf->pxmit_urb[i]==NULL");
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
|
||||
pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz);
|
||||
if (pxmitbuf->pallocated_buf == NULL)
|
||||
{
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
|
||||
#endif
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 free_sz)
|
||||
{
|
||||
#ifdef CONFIG_USB_HCI
|
||||
int i;
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
if(pxmitbuf->pxmit_urb[i])
|
||||
{
|
||||
//usb_kill_urb(pxmitbuf->pxmit_urb[i]);
|
||||
usb_free_urb(pxmitbuf->pxmit_urb[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
rtw_usb_buffer_free(pusbd, (size_t)free_sz, pxmitbuf->pallocated_buf, pxmitbuf->dma_transfer_addr);
|
||||
pxmitbuf->pallocated_buf = NULL;
|
||||
pxmitbuf->dma_transfer_addr = 0;
|
||||
#else // CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
if(pxmitbuf->pallocated_buf)
|
||||
rtw_mfree(pxmitbuf->pallocated_buf, free_sz);
|
||||
#endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
|
||||
#endif
|
||||
#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
|
||||
if(pxmitbuf->pallocated_buf)
|
||||
rtw_mfree(pxmitbuf->pallocated_buf, free_sz);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define WMM_XMIT_THRESHOLD (NR_XMITFRAME*2/5)
|
||||
|
||||
void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
|
||||
u16 queue;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
queue = skb_get_queue_mapping(pkt);
|
||||
if (padapter->registrypriv.wifi_spec) {
|
||||
if(__netif_subqueue_stopped(padapter->pnetdev, queue) &&
|
||||
(pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD))
|
||||
{
|
||||
netif_wake_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
} else {
|
||||
if(__netif_subqueue_stopped(padapter->pnetdev, queue))
|
||||
netif_wake_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
#else
|
||||
if (netif_queue_stopped(padapter->pnetdev))
|
||||
netif_wake_queue(padapter->pnetdev);
|
||||
#endif
|
||||
|
||||
rtw_skb_free(pkt);
|
||||
}
|
||||
|
||||
void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe)
|
||||
{
|
||||
if(pxframe->pkt)
|
||||
rtw_os_pkt_complete(padapter, pxframe->pkt);
|
||||
|
||||
pxframe->pkt = NULL;
|
||||
}
|
||||
|
||||
void rtw_os_xmit_schedule(_adapter *padapter)
|
||||
{
|
||||
_adapter *pri_adapter = padapter;
|
||||
|
||||
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
|
||||
if(!padapter)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_CONCURRENT_MODE
|
||||
if(padapter->adapter_type > PRIMARY_ADAPTER)
|
||||
pri_adapter = padapter->pbuddy_adapter;
|
||||
#endif
|
||||
|
||||
if (_rtw_queue_empty(&pri_adapter->xmitpriv.pending_xmitbuf_queue) == _FALSE)
|
||||
_rtw_up_sema(&pri_adapter->xmitpriv.xmit_sema);
|
||||
|
||||
|
||||
#else
|
||||
_irqL irqL;
|
||||
struct xmit_priv *pxmitpriv;
|
||||
|
||||
if(!padapter)
|
||||
return;
|
||||
|
||||
pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
_enter_critical_bh(&pxmitpriv->lock, &irqL);
|
||||
|
||||
if(rtw_txframes_pending(padapter))
|
||||
{
|
||||
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
|
||||
}
|
||||
|
||||
_exit_critical_bh(&pxmitpriv->lock, &irqL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rtw_check_xmit_resource(_adapter *padapter, _pkt *pkt)
|
||||
{
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
|
||||
u16 queue;
|
||||
|
||||
queue = skb_get_queue_mapping(pkt);
|
||||
if (padapter->registrypriv.wifi_spec) {
|
||||
/* No free space for Tx, tx_worker is too slow */
|
||||
if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD) {
|
||||
//DBG_871X("%s(): stop netif_subqueue[%d]\n", __FUNCTION__, queue);
|
||||
netif_stop_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
} else {
|
||||
if(pxmitpriv->free_xmitframe_cnt<=4) {
|
||||
if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue)))
|
||||
netif_stop_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(pxmitpriv->free_xmitframe_cnt<=4)
|
||||
{
|
||||
if (!rtw_netif_queue_stopped(padapter->pnetdev))
|
||||
rtw_netif_stop_queue(padapter->pnetdev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TX_MCAST2UNI
|
||||
static int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb)
|
||||
{
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
_irqL irqL;
|
||||
_list *phead, *plist;
|
||||
struct sk_buff *newskb;
|
||||
struct sta_info *psta = NULL;
|
||||
u8 chk_alive_num = 0;
|
||||
char chk_alive_list[NUM_STA];
|
||||
u8 bc_addr[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
u8 null_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
int i;
|
||||
s32 res;
|
||||
|
||||
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
|
||||
phead = &pstapriv->asoc_list;
|
||||
plist = get_next(phead);
|
||||
|
||||
//free sta asoc_queue
|
||||
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
|
||||
int stainfo_offset;
|
||||
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
|
||||
plist = get_next(plist);
|
||||
|
||||
stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
|
||||
if (stainfo_offset_valid(stainfo_offset)) {
|
||||
chk_alive_list[chk_alive_num++] = stainfo_offset;
|
||||
}
|
||||
}
|
||||
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
|
||||
|
||||
for (i = 0; i < chk_alive_num; i++) {
|
||||
psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
|
||||
if(!(psta->state &_FW_LINKED))
|
||||
continue;
|
||||
|
||||
/* avoid come from STA1 and send back STA1 */
|
||||
if (_rtw_memcmp(psta->hwaddr, &skb->data[6], 6) == _TRUE
|
||||
|| _rtw_memcmp(psta->hwaddr, null_addr, 6) == _TRUE
|
||||
|| _rtw_memcmp(psta->hwaddr, bc_addr, 6) == _TRUE
|
||||
)
|
||||
continue;
|
||||
|
||||
newskb = rtw_skb_copy(skb);
|
||||
|
||||
if (newskb) {
|
||||
_rtw_memcpy(newskb->data, psta->hwaddr, 6);
|
||||
res = rtw_xmit(padapter, &newskb);
|
||||
if (res < 0) {
|
||||
DBG_871X("%s()-%d: rtw_xmit() return error!\n", __FUNCTION__, __LINE__);
|
||||
pxmitpriv->tx_drop++;
|
||||
rtw_skb_free(newskb);
|
||||
} else
|
||||
pxmitpriv->tx_pkts++;
|
||||
} else {
|
||||
DBG_871X("%s-%d: rtw_skb_copy() failed!\n", __FUNCTION__, __LINE__);
|
||||
pxmitpriv->tx_drop++;
|
||||
//rtw_skb_free(skb);
|
||||
return _FALSE; // Caller shall tx this multicast frame via normal way.
|
||||
}
|
||||
}
|
||||
|
||||
rtw_skb_free(skb);
|
||||
return _TRUE;
|
||||
}
|
||||
#endif // CONFIG_TX_MCAST2UNI
|
||||
|
||||
|
||||
int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
#ifdef CONFIG_TX_MCAST2UNI
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
extern int rtw_mc2u_disable;
|
||||
#endif // CONFIG_TX_MCAST2UNI
|
||||
s32 res = 0;
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
|
||||
u16 queue;
|
||||
#endif
|
||||
|
||||
_func_enter_;
|
||||
|
||||
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("+xmit_enry\n"));
|
||||
|
||||
if (rtw_if_up(padapter) == _FALSE) {
|
||||
RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit_entry: rtw_if_up fail\n"));
|
||||
#ifdef DBG_TX_DROP_FRAME
|
||||
DBG_871X("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__);
|
||||
#endif
|
||||
goto drop_packet;
|
||||
}
|
||||
|
||||
rtw_check_xmit_resource(padapter, pkt);
|
||||
|
||||
#ifdef CONFIG_TX_MCAST2UNI
|
||||
if ( !rtw_mc2u_disable
|
||||
&& check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE
|
||||
&& ( IP_MCAST_MAC(pkt->data)
|
||||
|| ICMPV6_MCAST_MAC(pkt->data) )
|
||||
&& (padapter->registrypriv.wifi_spec == 0)
|
||||
)
|
||||
{
|
||||
if ( pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME/4) ) {
|
||||
res = rtw_mlcst2unicst(padapter, pkt);
|
||||
if (res == _TRUE) {
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
//DBG_871X("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt);
|
||||
//DBG_871X("!m2u );
|
||||
}
|
||||
}
|
||||
#endif // CONFIG_TX_MCAST2UNI
|
||||
|
||||
res = rtw_xmit(padapter, &pkt);
|
||||
if (res < 0) {
|
||||
#ifdef DBG_TX_DROP_FRAME
|
||||
DBG_871X("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__);
|
||||
#endif
|
||||
goto drop_packet;
|
||||
}
|
||||
|
||||
pxmitpriv->tx_pkts++;
|
||||
RT_TRACE(_module_xmit_osdep_c_, _drv_info_, ("rtw_xmit_entry: tx_pkts=%d\n", (u32)pxmitpriv->tx_pkts));
|
||||
goto exit;
|
||||
|
||||
drop_packet:
|
||||
pxmitpriv->tx_drop++;
|
||||
rtw_skb_free(pkt);
|
||||
RT_TRACE(_module_xmit_osdep_c_, _drv_notice_, ("rtw_xmit_entry: drop, tx_drop=%d\n", (u32)pxmitpriv->tx_drop));
|
||||
|
||||
exit:
|
||||
|
||||
_func_exit_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev)
|
||||
{
|
||||
if (pkt)
|
||||
rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, pkt->truesize);
|
||||
return _rtw_xmit_entry(pkt, pnetdev);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue