int rtw_os_alloc_recvframe(_adapter *padapter, union recv_frame *precvframe, u8 *pdata, _pkt *pskb) { int res = _SUCCESS; u8 shift_sz = 0; u32 skb_len, alloc_sz; _pkt *pkt_copy = NULL; struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; if(pdata == NULL) { precvframe->u.hdr.pkt = NULL; res = _FAIL; return res; } // Modified by Albert 20101213 // For 8 bytes IP header alignment. shift_sz = pattrib->qos ? 6:0;// Qos data, wireless lan header length is 26 skb_len = pattrib->pkt_len; // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. // modify alloc_sz for recvive crc error packet by thomas 2011-06-02 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) { //alloc_sz = 1664; //1664 is 128 alignment. alloc_sz = (skb_len <= 1650) ? 1664:(skb_len + 14); } else { alloc_sz = skb_len; // 6 is for IP header 8 bytes alignment in QoS packet case. // 8 is for skb->data 4 bytes alignment. alloc_sz += 14; } pkt_copy = rtw_skb_alloc(alloc_sz); if(pkt_copy) { pkt_copy->dev = padapter->pnetdev; precvframe->u.hdr.pkt = pkt_copy; precvframe->u.hdr.rx_head = pkt_copy->data; precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz; skb_reserve(pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data) & 7 ));//force pkt_copy->data at 8-byte alignment address skb_reserve(pkt_copy, shift_sz);//force ip_hdr at 8-byte alignment address according to shift_sz. _rtw_memcpy(pkt_copy->data, pdata, skb_len); precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data; } else { #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX DBG_871X("%s:can not allocate memory for skb copy\n", __FUNCTION__); precvframe->u.hdr.pkt = NULL; //rtw_free_recvframe(precvframe, pfree_recv_queue); //goto _exit_recvbuf2recvframe; res = _FAIL; #else if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) { DBG_871X("%s: alloc_skb fail , drop frag frame \n", __FUNCTION__); //rtw_free_recvframe(precvframe, pfree_recv_queue); res = _FAIL; goto exit_rtw_os_recv_resource_alloc; } if(pskb == NULL) { res = _FAIL; goto exit_rtw_os_recv_resource_alloc; } precvframe->u.hdr.pkt = rtw_skb_clone(pskb); if(precvframe->u.hdr.pkt) { precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pdata; precvframe->u.hdr.rx_end = pdata + alloc_sz; } else { DBG_871X("%s: rtw_skb_clone fail\n", __FUNCTION__); //rtw_free_recvframe(precvframe, pfree_recv_queue); //goto _exit_recvbuf2recvframe; res = _FAIL; } #endif } exit_rtw_os_recv_resource_alloc: return res; }
void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup) { #ifdef CONFIG_IOCTL_CFG80211 enum nl80211_key_type key_type = 0; #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 }
//struct sta_info *rtw_alloc_stainfo(_queue *pfree_sta_queue, unsigned char *hwaddr) struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) { _irqL irqL, irqL2; uint tmp_aid; s32 index; _list *phash_list; struct sta_info *psta; _queue *pfree_sta_queue; struct recv_reorder_ctrl *preorder_ctrl; int i = 0; u16 wRxSeqInitialValue = 0xffff; _func_enter_; pfree_sta_queue = &pstapriv->free_sta_queue; //_enter_critical_bh(&(pfree_sta_queue->lock), &irqL); _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); if (_rtw_queue_empty(pfree_sta_queue) == _TRUE) { //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL); _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); psta = NULL; } else { psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list); rtw_list_delete(&(psta->list)); //_exit_critical_bh(&(pfree_sta_queue->lock), &irqL); tmp_aid = psta->aid; _rtw_init_stainfo(psta); psta->padapter = pstapriv->padapter; _rtw_memcpy(psta->hwaddr, hwaddr, ETH_ALEN); index = wifi_mac_hash(hwaddr); RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("rtw_alloc_stainfo: index = %x", index)); if(index >= NUM_STA){ RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("ERROR=> rtw_alloc_stainfo: index >= NUM_STA")); psta= NULL; goto exit; } phash_list = &(pstapriv->sta_hash[index]); //_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); rtw_list_insert_tail(&psta->hash_list, phash_list); pstapriv->asoc_sta_count ++ ; //_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); // Commented by Albert 2009/08/13 // For the SMC router, the sequence number of first packet of WPS handshake will be 0. // In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. // So, we initialize the tid_rxseq variable as the 0xffff. for( i = 0; i < 16; i++ ) { _rtw_memcpy( &psta->sta_recvpriv.rxcache.tid_rxseq[ i ], &wRxSeqInitialValue, 2 ); } RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("alloc number_%d stainfo with hwaddr = %x %x %x %x %x %x \n", pstapriv->asoc_sta_count , hwaddr[0], hwaddr[1], hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5])); init_addba_retry_timer(pstapriv->padapter, psta); #ifdef CONFIG_IEEE80211W init_dot11w_expire_timer(pstapriv->padapter, psta); #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_TDLS rtw_init_tdls_timer(pstapriv->padapter, psta); #endif //CONFIG_TDLS //for A-MPDU Rx reordering buffer control for(i=0; i < 16 ; i++) { preorder_ctrl = &psta->recvreorder_ctrl[i]; preorder_ctrl->padapter = pstapriv->padapter; preorder_ctrl->enable = _FALSE; preorder_ctrl->indicate_seq = 0xffff; #ifdef DBG_RX_SEQ DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d\n", __FUNCTION__, __LINE__, preorder_ctrl->indicate_seq); #endif preorder_ctrl->wend_b= 0xffff; //preorder_ctrl->wsize_b = (NR_RECVBUFF-2); preorder_ctrl->wsize_b = 64;//64; preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID; _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue); rtw_init_recv_timer(preorder_ctrl); } //init for DM psta->rssi_stat.UndecoratedSmoothedPWDB = (-1); psta->rssi_stat.UndecoratedSmoothedCCK = (-1); #ifdef CONFIG_ATMEL_RC_PATCH psta->flag_atmel_rc = 0; #endif /* init for the sequence number of received management frame */ psta->RxMgmtFrameSeqNum = 0xffff; psta->ra_rpt_linked = _FALSE; //alloc mac id for non-bc/mc station, rtw_alloc_macid(pstapriv->padapter, psta); } exit: _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); _func_exit_; return psta; }
// // Description: // Download 8192C firmware code. // // int FirmwareDownload92C( IN PADAPTER Adapter ) { int rtStatus = _SUCCESS; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); char R92CFwImageFileName_TSMC[] ={RTL8192C_FW_TSMC_IMG}; char R92CFwImageFileName_UMC[] ={RTL8192C_FW_UMC_IMG}; char R8723FwImageFileName_UMC[] ={RTL8723_FW_UMC_IMG}; char * FwImage; u32 FwImageLen; char* pFwImageFileName; //vivi, merge 92c and 92s into one driver, 20090817 //vivi modify this temply, consider it later!!!!!!!! //PRT_FIRMWARE pFirmware = GET_FIRMWARE_819X(Adapter); //PRT_FIRMWARE_92C pFirmware = GET_FIRMWARE_8192C(Adapter); PRT_FIRMWARE_92C pFirmware = NULL; PRT_8192C_FIRMWARE_HDR pFwHdr = NULL; u8 *pFirmwareBuf; u32 FirmwareLen; pFirmware = (PRT_FIRMWARE_92C)_rtw_malloc(sizeof(RT_FIRMWARE_92C)); if(!pFirmware) { rtStatus = _FAIL; goto Exit; } //RT_TRACE(COMP_INIT, DBG_LOUD, (" ===> FirmwareDownload91C() fw:%s\n", pFwImageFileName)); #ifdef CONFIG_EMBEDDED_FWIMG pFirmware->eFWSource = FW_SOURCE_HEADER_FILE; #else pFirmware->eFWSource = FW_SOURCE_IMG_FILE; #endif if(IS_NORMAL_CHIP(pHalData->VersionID)) { if(IS_VENDOR_UMC_A_CUT(pHalData->VersionID) && !IS_92C_SERIAL(pHalData->VersionID))// UMC , 8188 { pFwImageFileName = R92CFwImageFileName_UMC; FwImage = Rtl819XFwUMCImageArray; FwImageLen = UMCImgArrayLength; DBG_871X(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_UMC\n"); } else { pFwImageFileName = R92CFwImageFileName_TSMC; FwImage = Rtl819XFwTSMCImageArray; FwImageLen = TSMCImgArrayLength; DBG_871X(" ===> FirmwareDownload91C() fw:Rtl819XFwImageArray_TSMC\n"); } } else { #if 0 pFwImageFileName = TestChipFwFile; FwImage = Rtl8192CTestFwImg; FwImageLen = Rtl8192CTestFwImgLen; RT_TRACE(COMP_INIT, DBG_LOUD, (" ===> FirmwareDownload91C() fw:Rtl8192CTestFwImg\n")); #endif } switch(pFirmware->eFWSource) { case FW_SOURCE_IMG_FILE: //TODO:load fw bin file break; case FW_SOURCE_HEADER_FILE: if(TSMCImgArrayLength > FW_8192C_SIZE){ rtStatus = _FAIL; //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE) ); DBG_871X("Firmware size exceed 0x%X. Check it.\n", FW_8192C_SIZE); goto Exit; } _rtw_memcpy(pFirmware->szFwBuffer, FwImage, FwImageLen); pFirmware->ulFwLength = FwImageLen; break; } pFirmwareBuf = pFirmware->szFwBuffer; FirmwareLen = pFirmware->ulFwLength; // To Check Fw header. pFwHdr = (PRT_8192C_FIRMWARE_HDR)pFirmware->szFwBuffer; pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion); //RT_TRACE(COMP_INIT, DBG_LOUD, (" FirmwareVersion(%#x), Signature(%#x)\n", // Adapter->MgntInfo.FirmwareVersion, pFwHdr->Signature)); DBG_8192C("fw_ver=v%d, fw_subver=%d, sig=0x%x\n", pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, le16_to_cpu(pFwHdr->Signature)&0xFFF0); if(IS_FW_HEADER_EXIST(pFwHdr)) { //RT_TRACE(COMP_INIT, DBG_LOUD,("Shift 32 bytes for FW header!!\n")); pFirmwareBuf = pFirmwareBuf + 32; FirmwareLen = FirmwareLen -32; } // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, // or it will cause download Fw fail. 2010.02.01. by tynli. if(rtw_read8(Adapter, REG_MCUFWDL)&BIT7) //8051 RAM code { DBG_8192C("8051 in Ram......prepare to reset by itself\n"); _FirmwareSelfReset(Adapter); rtw_write8(Adapter, REG_MCUFWDL, 0x00); } _FWDownloadEnable(Adapter, _TRUE); _WriteFW(Adapter, pFirmwareBuf, FirmwareLen); _FWDownloadEnable(Adapter, _FALSE); rtStatus = _FWFreeToGo(Adapter); if(_SUCCESS != rtStatus){ //RT_TRACE(COMP_INIT, DBG_SERIOUS, ("DL Firmware failed!\n") ); goto Exit; } //RT_TRACE(COMP_INIT, DBG_LOUD, (" Firmware is ready to run!\n")); Exit: if(pFirmware) _rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_92C)); //RT_TRACE(COMP_INIT, DBG_LOUD, (" <=== FirmwareDownload91C()\n")); return rtStatus; }
//This function initializes the DUT to the MP test mode s32 mp_start_test(PADAPTER padapter) { WLAN_BSSID_EX bssid; struct sta_info *psta; u32 length; u8 val8; _irqL irqL; s32 res = _SUCCESS; struct mp_priv *pmppriv = &padapter->mppriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *tgt_network = &pmlmepriv->cur_network; padapter->registrypriv.mp_mode = 1; pmppriv->bSetTxPower=0; //for manually set tx power //3 disable dynamic mechanism disable_dm(padapter); //3 0. update mp_priv if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) { // switch (phal->rf_type) { switch (GET_RF_TYPE(padapter)) { case RF_1T1R: pmppriv->antenna_tx = ANTENNA_A; pmppriv->antenna_rx = ANTENNA_A; break; case RF_1T2R: default: pmppriv->antenna_tx = ANTENNA_A; pmppriv->antenna_rx = ANTENNA_AB; break; case RF_2T2R: case RF_2T2R_GREEN: pmppriv->antenna_tx = ANTENNA_AB; pmppriv->antenna_rx = ANTENNA_AB; break; case RF_2T4R: pmppriv->antenna_tx = ANTENNA_AB; pmppriv->antenna_rx = ANTENNA_ABCD; break; } } mpt_ProStartTest(padapter); //3 1. initialize a new WLAN_BSSID_EX // _rtw_memset(&bssid, 0, sizeof(WLAN_BSSID_EX)); _rtw_memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN); bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc"); _rtw_memcpy(bssid.Ssid.Ssid, (u8*)"mp_pseudo_adhoc", bssid.Ssid.SsidLength); bssid.InfrastructureMode = Ndis802_11IBSS; bssid.NetworkTypeInUse = Ndis802_11DS; bssid.IELength = 0; length = get_WLAN_BSSID_EX_sz(&bssid); if (length % 4) bssid.Length = ((length >> 2) + 1) << 2; //round up to multiple of 4 bytes. else
static void _ReadIDs( IN PADAPTER Adapter, IN u8* PROMContent, IN BOOLEAN AutoloadFail ) { //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); if(_FALSE == AutoloadFail){ // VID, PID #if 1 //for Funai BD's alignment error u16 tmp = 0; _rtw_memcpy( &tmp , (void*) &PROMContent[EEPROM_VID], 2 ); tmp = le16_to_cpu( tmp ); pEEPROM->EEPROMVID = tmp; tmp = 0; _rtw_memcpy( &tmp , (void*) &PROMContent[EEPROM_PID], 2 ); tmp = le16_to_cpu( tmp ); pEEPROM->EEPROMPID = tmp; #else pEEPROM->EEPROMVID = le16_to_cpu( *(u16 *)&PROMContent[EEPROM_VID]); pEEPROM->EEPROMPID = le16_to_cpu( *(u16 *)&PROMContent[EEPROM_PID]); #endif // Customer ID, 0x00 and 0xff are reserved for Realtek. pEEPROM->EEPROMCustomerID = *(u8 *)&PROMContent[EEPROM_CUSTOMER_ID]; pEEPROM->EEPROMSubCustomerID = *(u8 *)&PROMContent[EEPROM_SUBCUSTOMER_ID]; } else{ pEEPROM->EEPROMVID = EEPROM_Default_VID; pEEPROM->EEPROMPID = EEPROM_Default_PID; // Customer ID, 0x00 and 0xff are reserved for Realtek. pEEPROM->EEPROMCustomerID = EEPROM_Default_CustomerID; pEEPROM->EEPROMSubCustomerID = EEPROM_Default_SubCustomerID; } switch(pEEPROM->EEPROMCustomerID) { case EEPROM_CID_ALPHA: pHalData->CustomerID = RT_CID_819x_ALPHA; break; case EEPROM_CID_CAMEO: pHalData->CustomerID = RT_CID_819x_CAMEO; break; case EEPROM_CID_SITECOM: pHalData->CustomerID = RT_CID_819x_Sitecom; break; case EEPROM_CID_COREGA: pHalData->CustomerID = RT_CID_COREGA; break; case EEPROM_CID_Senao: pHalData->CustomerID = RT_CID_819x_Senao; break; case EEPROM_CID_EDIMAX_BELKIN: pHalData->CustomerID = RT_CID_819x_Edimax_Belkin; break; case EEPROM_CID_SERCOMM_BELKIN: pHalData->CustomerID = RT_CID_819x_Sercomm_Belkin; break; case EEPROM_CID_WNC_COREGA: pHalData->CustomerID = RT_CID_819x_WNC_COREGA; break; case EEPROM_CID_WHQL: /* Adapter->bInHctTest = TRUE; pMgntInfo->bSupportTurboMode = FALSE; pMgntInfo->bAutoTurboBy8186 = FALSE; pMgntInfo->PowerSaveControl.bInactivePs = FALSE; pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE; pMgntInfo->PowerSaveControl.bLeisurePs = FALSE; pMgntInfo->keepAliveLevel = 0; Adapter->bUnloadDriverwhenS3S4 = FALSE; */ break; case EEPROM_CID_NetCore: pHalData->CustomerID = RT_CID_819x_Netcore; break; case EEPROM_CID_CAMEO1: pHalData->CustomerID = RT_CID_819x_CAMEO1; break; case EEPROM_CID_CLEVO: pHalData->CustomerID = RT_CID_819x_CLEVO; break; default: pHalData->CustomerID = RT_CID_DEFAULT; break; } // For customized behavior. if((pEEPROM->EEPROMVID == 0x103C) && (pEEPROM->EEPROMPID == 0x1629))// HP Lite-On for RTL8188CUS Slim Combo. pHalData->CustomerID = RT_CID_819x_HP; MSG_8192C("EEPROMVID = 0x%04x\n", pEEPROM->EEPROMVID); MSG_8192C("EEPROMPID = 0x%04x\n", pEEPROM->EEPROMPID); MSG_8192C("EEPROMCustomerID : 0x%02x\n", pEEPROM->EEPROMCustomerID); MSG_8192C("EEPROMSubCustomerID: 0x%02x\n", pEEPROM->EEPROMSubCustomerID); MSG_8192C("RT_CustomerID: 0x%02x\n", pHalData->CustomerID); }
/* * drv_init() - a device potentially for us * * notes: drv_init() is called when the bus driver has located a card for us to support. * We accept the new device by returning 0. */ static int rtw_drv_init( struct sdio_func *func, const struct sdio_device_id *id) { struct net_device *pnetdev; PADAPTER padapter; struct dvobj_priv *pdvobjpriv; PSDIO_DATA psdio; RT_TRACE(_module_hci_intfs_c_, _drv_info_, ("+rtw_drv_init: vendor=0x%04x device=0x%04x class=0x%02x\n", func->vendor, func->device, func->class)); //3 1. init network device data pnetdev = rtw_init_netdev(NULL); if (!pnetdev) goto error; SET_NETDEV_DEV(pnetdev, &func->dev); padapter = rtw_netdev_priv(pnetdev); pdvobjpriv = &padapter->dvobjpriv; pdvobjpriv->padapter = padapter; psdio = &pdvobjpriv->intf_data; psdio->func = func; #ifdef CONFIG_IOCTL_CFG80211 rtw_wdev_alloc(padapter, &func->dev); #endif //3 2. set interface private data sdio_set_drvdata(func, pdvobjpriv); //3 3. init driver special setting, interface, OS and hardware relative // set interface_type to sdio padapter->interface_type = RTW_SDIO; decide_chip_type_by_device_id(padapter, (u32)func->device); //4 3.1 set hardware operation functions padapter->HalData = rtw_zmalloc(sizeof(HAL_DATA_TYPE)); if (padapter->HalData == NULL) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("rtw_drv_init: can't alloc memory for HAL DATA\n")); goto error; } padapter->hal_data_sz = sizeof(HAL_DATA_TYPE); set_hal_ops(padapter); //3 4. interface init if (sdio_init(padapter) != _SUCCESS) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("rtw_drv_init: initialize device object priv Failed!\n")); goto error; } padapter->intf_start = &sd_intf_start; padapter->intf_stop = &sd_intf_stop; //3 5. register I/O operations if (rtw_init_io_priv(padapter) == _FAIL) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("rtw_drv_init: Can't init io_priv\n")); goto deinit; } //3 6. intf_read_chip_version(padapter); //3 7. intf_chip_configure(padapter); //3 8. read efuse/eeprom data intf_read_chip_info(padapter); //3 9. init driver common data if (rtw_init_drv_sw(padapter) == _FAIL) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("rtw_drv_init: Initialize driver software resource Failed!\n")); goto deinit; } //3 10. get WLan MAC address // alloc dev name after read efuse. rtw_init_netdev_name(pnetdev, ifname); rtw_macaddr_cfg(padapter->eeprompriv.mac_addr); _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); #ifdef CONFIG_PROC_DEBUG #ifdef RTK_DMP_PLATFORM rtw_proc_init_one(pnetdev); #endif #endif #ifdef CONFIG_HOSTAPD_MLME hostapd_mode_init(padapter); #endif #ifdef CONFIG_CONCURRENT_MODE //set global variable to primary adapter padapter->ph2c_fwcmd_mutex = &drvpriv.h2c_fwcmd_mutex; padapter->psetch_mutex = &drvpriv.setch_mutex; padapter->psetbw_mutex = &drvpriv.setbw_mutex; padapter->hw_init_mutex = &drvpriv.hw_init_mutex; #endif #ifdef CONFIG_PLATFORM_RTD2880B DBG_871X("wlan link up\n"); rtd2885_wlan_netlink_sendMsg("linkup", "8712"); #endif #ifdef CONFIG_GLOBAL_UI_PID if(ui_pid[1]!=0) { DBG_871X("ui_pid[1]:%d\n",ui_pid[1]); rtw_signal_process(ui_pid[1], SIGUSR2); } #endif DBG_871X("bDriverStopped:%d, bSurpriseRemoved:%d, bup:%d, hw_init_completed:%d\n" ,padapter->bDriverStopped ,padapter->bSurpriseRemoved ,padapter->bup ,padapter->hw_init_completed ); //3 8. Tell the network stack we exist if (register_netdev(pnetdev) != 0) { RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("rtw_drv_init: register_netdev() failed\n")); goto deinit; } #ifdef CONFIG_CONCURRENT_MODE if(rtw_drv_if2_init(padapter, NULL)==NULL) { goto deinit; } #endif RT_TRACE(_module_hci_intfs_c_, _drv_info_, ("-rtw_drv_init: Success. bDriverStopped=%d bSurpriseRemoved=%d\n", padapter->bDriverStopped, padapter->bSurpriseRemoved)); return 0; deinit: sdio_deinit(padapter); error: if (padapter) { if (padapter->HalData && padapter->hal_data_sz>0) { rtw_mfree(padapter->HalData, padapter->hal_data_sz); padapter->HalData = NULL; } } if (pnetdev) rtw_free_netdev(pnetdev); RT_TRACE(_module_hci_intfs_c_, _drv_crit_, ("-rtw_drv_init: FAIL!\n")); return -1; }
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); DBG_871X(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(adapter)); }
u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr) { PADAPTER padapter; u8 bMacPwrCtrlOn; u8 deviceId; u16 offset; u32 ftaddr; u8 shift; u32 val; s32 err; _func_enter_; padapter = pintfhdl->padapter; ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || (_FALSE == bMacPwrCtrlOn) #ifdef CONFIG_LPS_LCLK || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) #endif ) { err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8*)&val); #ifdef SDIO_DEBUG_IO if (!err) { #endif val = le32_to_cpu(val); return val; #ifdef SDIO_DEBUG_IO } DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n", __func__, err, addr); return SDIO_ERR_VAL32; #endif } // 4 bytes alignment shift = ftaddr & 0x3; if (shift == 0) { val = sd_read32(pintfhdl, ftaddr, NULL); } else { u8 *ptmpbuf; ptmpbuf = (u8*)rtw_malloc(8); if (NULL == ptmpbuf) { DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size=8) addr=0x%x\n", __func__, addr); return SDIO_ERR_VAL32; } ftaddr &= ~(u16)0x3; sd_read(pintfhdl, ftaddr, 8, ptmpbuf); _rtw_memcpy(&val, ptmpbuf+shift, 4); val = le32_to_cpu(val); rtw_mfree(ptmpbuf, 8); } _func_exit_; return val; }
s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) { PADAPTER padapter; u8 bMacPwrCtrlOn; u8 deviceId; u16 offset; u32 ftaddr; u8 shift; s32 err; _func_enter_; padapter = pintfhdl->padapter; err = 0; ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || (_FALSE == bMacPwrCtrlOn) #ifdef CONFIG_LPS_LCLK || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) #endif ) { val = cpu_to_le32(val); err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val); return err; } // 4 bytes alignment shift = ftaddr & 0x3; #if 1 if (shift == 0) { sd_write32(pintfhdl, ftaddr, val, &err); } else { val = cpu_to_le32(val); err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8*)&val); } #else if (shift == 0) { sd_write32(pintfhdl, ftaddr, val, &err); } else { u8 *ptmpbuf; ptmpbuf = (u8*)rtw_malloc(8); if (NULL == ptmpbuf) return (-1); ftaddr &= ~(u16)0x3; err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf); if (err) { rtw_mfree(ptmpbuf, 8); return err; } val = cpu_to_le32(val); _rtw_memcpy(ptmpbuf+shift, &val, 4); err = sd_write(pintfhdl, ftaddr, 8, ptmpbuf); rtw_mfree(ptmpbuf, 8); } #endif _func_exit_; return err; }
static void rtl8723as_recv_tasklet(void *priv) { PADAPTER padapter; PHAL_DATA_TYPE pHalData; struct recv_priv *precvpriv; struct recv_buf *precvbuf; union recv_frame *precvframe; struct recv_frame_hdr *phdr; struct rx_pkt_attrib *pattrib; _irqL irql; u8 *ptr; u32 pkt_len, pkt_offset, skb_len, alloc_sz; _pkt *pkt_copy = NULL; u8 shift_sz = 0, rx_report_sz = 0; padapter = (PADAPTER)priv; pHalData = GET_HAL_DATA(padapter); precvpriv = &padapter->recvpriv; do { precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue); if (NULL == precvbuf) break; ptr = precvbuf->pdata; while (ptr < precvbuf->ptail) { precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue); if (precvframe == NULL) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("%s: no enough recv frame!\n",__FUNCTION__)); rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue); // The case of can't allocte recvframe should be temporary, // schedule again and hope recvframe is available next time. #ifdef PLATFORM_LINUX tasklet_schedule(&precvpriv->recv_tasklet); #endif return; } //rx desc parsing update_recvframe_attrib(precvframe, (struct recv_stat*)ptr); pattrib = &precvframe->u.hdr.attrib; // fix Hardware RX data error, drop whole recv_buffer if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err) { if (padapter->registrypriv.mp_mode == 1) padapter->mppriv.rx_crcerrpktcount++; else DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); break; } if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) rx_report_sz = RXDESC_SIZE + 4 + pattrib->drvinfo_sz; else rx_report_sz = RXDESC_SIZE + pattrib->drvinfo_sz; pkt_offset = rx_report_sz + pattrib->pkt_len; if ((ptr + pkt_offset) > precvbuf->ptail) { DBG_8192C("%s()-%d: : next pkt len(%p,%d) exceed ptail(%p)!\n", __FUNCTION__, __LINE__, ptr, pkt_offset, precvbuf->ptail); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); break; } if ((pattrib->crc_err) || (pattrib->icv_err)) { if (padapter->registrypriv.mp_mode == 0) DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); } else { // Modified by Albert 20101213 // For 8 bytes IP header alignment. if (pattrib->qos) // Qos data, wireless lan header length is 26 { shift_sz = 6; } else { shift_sz = 0; } skb_len = pattrib->pkt_len; // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. // modify alloc_sz for recvive crc error packet by thomas 2011-06-02 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){ //alloc_sz = 1664; //1664 is 128 alignment. if(skb_len <= 1650) alloc_sz = 1664; else alloc_sz = skb_len + 14; } else { alloc_sz = skb_len; // 6 is for IP header 8 bytes alignment in QoS packet case. // 8 is for skb->data 4 bytes alignment. alloc_sz += 14; } pkt_copy = rtw_skb_alloc(alloc_sz); if(pkt_copy) { pkt_copy->dev = padapter->pnetdev; precvframe->u.hdr.pkt = pkt_copy; skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz. _rtw_memcpy(pkt_copy->data, (ptr + rx_report_sz), skb_len); precvframe->u.hdr.rx_head = pkt_copy->head; precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data; precvframe->u.hdr.rx_end = skb_end_pointer(pkt_copy); } else { if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) { DBG_8192C("rtl8723as_recv_tasklet: alloc_skb fail , drop frag frame \n"); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); break; } precvframe->u.hdr.pkt = rtw_skb_clone(precvbuf->pskb); if(precvframe->u.hdr.pkt) { _pkt *pkt_clone = precvframe->u.hdr.pkt; pkt_clone->data = ptr + rx_report_sz; skb_reset_tail_pointer(pkt_clone); precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_clone->data; precvframe->u.hdr.rx_end = pkt_clone->data + skb_len; } else { DBG_8192C("rtl8723as_recv_tasklet: rtw_skb_clone fail\n"); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); break; } } recvframe_put(precvframe, skb_len); //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE); if (pHalData->ReceiveConfig & RCR_APPFCS) recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN); // move to drv info position ptr += RXDESC_SIZE; // update drv info if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) { //rtl8723s_update_bassn(padapter, pdrvinfo); ptr += 4; } #ifdef CONFIG_CONCURRENT_MODE if(rtw_buddy_adapter_up(padapter)) { if(pre_recv_entry(precvframe, precvbuf, (struct phy_stat*)ptr) != _SUCCESS) { RT_TRACE(_module_rtl871x_recv_c_,_drv_err_, ("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n")); } } else #endif { if (pattrib->physt) update_recvframe_phyinfo(precvframe, (struct phy_stat*)ptr); if (rtw_recv_entry(precvframe) != _SUCCESS) { RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",__FUNCTION__)); } } } // Page size of receive package is 128 bytes alignment =>DMA AGG // refer to _InitTransferPageSize() pkt_offset = _RND128(pkt_offset); precvbuf->pdata += pkt_offset; ptr = precvbuf->pdata; precvframe = NULL; pkt_copy = NULL; } rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue); } while (1); }
static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_buf *precvbuf, struct phy_stat *pphy_status) { s32 ret=_SUCCESS; #ifdef CONFIG_CONCURRENT_MODE u8 *primary_myid, *secondary_myid, *paddr1; union recv_frame *precvframe_if2 = NULL; _adapter *primary_padapter = precvframe->u.hdr.adapter; _adapter *secondary_padapter = primary_padapter->pbuddy_adapter; struct recv_priv *precvpriv = &primary_padapter->recvpriv; _queue *pfree_recv_queue = &precvpriv->free_recv_queue; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(primary_padapter); if(!secondary_padapter) return ret; paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data); if(IS_MCAST(paddr1) == _FALSE)//unicast packets { //primary_myid = myid(&primary_padapter->eeprompriv); secondary_myid = myid(&secondary_padapter->eeprompriv); if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN)) { //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; } //ret = recv_entry(precvframe); } else // Handle BC/MC Packets { //clone/copy to if2 _pkt *pkt_copy = NULL; struct rx_pkt_attrib *pattrib = NULL; precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue); if(!precvframe_if2) return _FAIL; precvframe_if2->u.hdr.adapter = secondary_padapter; _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)); pattrib = &precvframe_if2->u.hdr.attrib; //driver need to set skb len for rtw_skb_copy(). //If skb->len is zero, rtw_skb_copy() will not copy data from original skb. skb_put(precvframe->u.hdr.pkt, pattrib->pkt_len); pkt_copy = rtw_skb_copy(precvframe->u.hdr.pkt); if (pkt_copy == NULL) { if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)) { DBG_8192C("pre_recv_entry(): rtw_skb_copy fail , drop frag frame \n"); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); return ret; } pkt_copy = rtw_skb_clone(precvframe->u.hdr.pkt); if(pkt_copy == NULL) { DBG_8192C("pre_recv_entry(): rtw_skb_clone fail , drop frame\n"); rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); return ret; } } pkt_copy->dev = secondary_padapter->pnetdev; precvframe_if2->u.hdr.pkt = pkt_copy; precvframe_if2->u.hdr.rx_head = pkt_copy->head; precvframe_if2->u.hdr.rx_data = pkt_copy->data; precvframe_if2->u.hdr.rx_tail = skb_tail_pointer(pkt_copy); precvframe_if2->u.hdr.rx_end = skb_end_pointer(pkt_copy); precvframe_if2->u.hdr.len = pkt_copy->len; //recvframe_put(precvframe_if2, pattrib->pkt_len); if ( pHalData->ReceiveConfig & RCR_APPFCS) recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN); if (pattrib->physt) update_recvframe_phyinfo(precvframe_if2, pphy_status); if(rtw_recv_entry(precvframe_if2) != _SUCCESS) { RT_TRACE(_module_rtl871x_recv_c_,_drv_err_, ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n")); } } if (precvframe->u.hdr.attrib.physt) update_recvframe_phyinfo(precvframe, pphy_status); ret = rtw_recv_entry(precvframe); #endif return ret; }
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; DBG_COUNTER(padapter->tx_logs.os_tx_m2u); SPIN_LOCK_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; } } SPIN_UNLOCK_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)) { DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_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 ) { DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_self); continue; } DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry); newskb = rtw_skb_copy(skb); if (newskb) { _rtw_memcpy(newskb->data, psta->hwaddr, 6); res = rtw_xmit(padapter, &newskb); if (res < 0) { DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_xmit); DBG_871X("%s()-%d: rtw_xmit() return error!\n", __FUNCTION__, __LINE__); pxmitpriv->tx_drop++; rtw_skb_free(newskb); } } else { DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_skb); 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; }
u8 query_802_11_association_information( _adapter *padapter,PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo) { struct wlan_network *tgt_network; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct security_priv *psecuritypriv=&(padapter->securitypriv); WLAN_BSSID_EX *psecnetwork=(WLAN_BSSID_EX*)&(psecuritypriv->sec_bss); u8 * pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); unsigned char i,*auth_ie,*supp_ie; //NdisZeroMemory(pAssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); _rtw_memset(pAssocInfo, 0, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); //pAssocInfo->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); //------------------------------------------------------ // Association Request related information //------------------------------------------------------ // Req_1. AvailableRequestFixedIEs if(psecnetwork!=NULL){ pAssocInfo->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CAPABILITIES|NDIS_802_11_AI_REQFI_CURRENTAPADDRESS; pAssocInfo->RequestFixedIEs.Capabilities = (unsigned short)* & psecnetwork->IEs[10]; _rtw_memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress, & psecnetwork->MacAddress, 6); pAssocInfo->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); if(check_fwstate( pmlmepriv, _FW_UNDER_LINKING|_FW_LINKED)==_TRUE) { if(psecuritypriv->ndisauthtype>=Ndis802_11AuthModeWPA2) pDest[0] =48; //RSN Information Element else pDest[0] =221; //WPA(SSN) Information Element RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n Adapter->ndisauthtype==Ndis802_11AuthModeWPA)?0xdd:0x30 [%d]",pDest[0])); supp_ie=&psecuritypriv->supplicant_ie[0]; for(i=0;i<supp_ie[0];i++) { RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("IEs [%d] = 0x%x \n\n", i,supp_ie[i])); } i=13; //0~11 is fixed information element RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("i= %d tgt_network->network.IELength=%d\n\n", i,(int)psecnetwork->IELength)); while((i<supp_ie[0]) && (i<256)){ if((unsigned char)supp_ie[i]==pDest[0]){ _rtw_memcpy((u8 *)(pDest), &supp_ie[i], supp_ie[1+i]+2); break; } i=i+supp_ie[i+1]+2; if(supp_ie[1+i]==0) i=i+1; RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("iteration i=%d IEs [%d] = 0x%x \n\n", i,i,supp_ie[i+1])); } pAssocInfo->RequestIELength += (2 + supp_ie[1+i]);// (2 + psecnetwork->IEs[1+i]+4); } RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n psecnetwork != NULL,fwstate==_FW_UNDER_LINKING \n")); } //------------------------------------------------------ // Association Response related information //------------------------------------------------------ if(check_fwstate( pmlmepriv, _FW_LINKED)==_TRUE) { tgt_network =&(pmlmepriv->cur_network); if(tgt_network!=NULL){ pAssocInfo->AvailableResponseFixedIEs = NDIS_802_11_AI_RESFI_CAPABILITIES |NDIS_802_11_AI_RESFI_ASSOCIATIONID ; pAssocInfo->ResponseFixedIEs.Capabilities =(unsigned short)* & tgt_network->network.IEs[10]; pAssocInfo->ResponseFixedIEs.StatusCode = 0; pAssocInfo->ResponseFixedIEs.AssociationId =(unsigned short) tgt_network->aid; pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+pAssocInfo->RequestIELength; auth_ie=&psecuritypriv->authenticator_ie[0]; for(i=0;i<auth_ie[0];i++) RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("IEs [%d] = 0x%x \n\n", i,auth_ie[i])); i=auth_ie[0]-12; if(i>0){ _rtw_memcpy((u8 *)&pDest[0],&auth_ie[1],i); pAssocInfo->ResponseIELength =i; } pAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength; RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n tgt_network != NULL,fwstate==_FW_LINKED \n")); } } RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n exit query_802_11_association_information \n")); _func_exit_; return _TRUE; }
/* * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */ int rtw_change_ifname(_adapter *padapter, const char *ifname) { struct net_device *pnetdev; struct net_device *cur_pnetdev = padapter->pnetdev; struct rereg_nd_name_data *rereg_priv; int ret; if(!padapter) goto error; rereg_priv = &padapter->rereg_nd_name_priv; //free the old_pnetdev if(rereg_priv->old_pnetdev) { free_netdev(rereg_priv->old_pnetdev); rereg_priv->old_pnetdev = NULL; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) if(!rtnl_is_locked()) unregister_netdev(cur_pnetdev); else #endif unregister_netdevice(cur_pnetdev); rtw_proc_remove_one(cur_pnetdev); rereg_priv->old_pnetdev=cur_pnetdev; pnetdev = rtw_init_netdev(padapter); if (!pnetdev) { ret = -1; goto error; } SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter))); rtw_init_netdev_name(pnetdev, ifname); _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) if(!rtnl_is_locked()) ret = register_netdev(pnetdev); else #endif ret = register_netdevice(pnetdev); if ( ret != 0) { RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n")); goto error; } rtw_proc_init_one(pnetdev); return 0; error: return -1; }
/***************************************** * H2C Msg format : * 0x1DF - 0x1D0 *| 31 - 8 | 7-5 4 - 0 | *| h2c_msg |Class_ID CMD_ID | * * Extend 0x1FF - 0x1F0 *|31 - 0 | *|ext_msg| ******************************************/ static s32 FillH2CCmd_8812(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer) { u8 bcmd_down = _FALSE; s32 retry_cnts = 100; u8 h2c_box_num; u32 msgbox_addr; u32 msgbox_ex_addr; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); u8 cmd_idx,ext_cmd_len; u32 h2c_cmd = 0; u32 h2c_cmd_ex = 0; s32 ret = _FAIL; _func_enter_; padapter = GET_PRIMARY_ADAPTER(padapter); pHalData = GET_HAL_DATA(padapter); if(padapter->bFWReady == _FALSE) { //DBG_8192C("FillH2CCmd_8812(): return H2C cmd because fw is not ready\n"); return ret; } _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); if (!pCmdBuffer) { goto exit; } if (CmdLen > RTL8812_MAX_CMD_LEN) { goto exit; } if (padapter->bSurpriseRemoved == _TRUE) goto exit; //pay attention to if race condition happened in H2C cmd setting. do{ h2c_box_num = pHalData->LastHMEBoxNum; if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){ DBG_8192C(" fw read cmd failed...\n"); goto exit; } *(u8*)(&h2c_cmd) = ElementID; if(CmdLen<=3) { _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen ); } else{ _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer,3); ext_cmd_len = CmdLen-3; _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3,ext_cmd_len ); //Write Ext command msgbox_ex_addr = REG_HMEBOX_EXT0_8812 + (h2c_box_num *RTL8812_EX_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for(cmd_idx=0;cmd_idx<ext_cmd_len;cmd_idx++ ){ rtw_write8(padapter,msgbox_ex_addr+cmd_idx,*((u8*)(&h2c_cmd_ex)+cmd_idx)); } #else h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex ); rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex); #endif } // Write command msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *RTL8812_MESSAGE_BOX_SIZE); #ifdef CONFIG_H2C_EF for(cmd_idx=0;cmd_idx<RTL8812_MESSAGE_BOX_SIZE;cmd_idx++ ){ rtw_write8(padapter,msgbox_addr+cmd_idx,*((u8*)(&h2c_cmd)+cmd_idx)); } #else h2c_cmd = le32_to_cpu( h2c_cmd ); rtw_write32(padapter,msgbox_addr, h2c_cmd); #endif bcmd_down = _TRUE; // DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" // ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL8812_MAX_H2C_BOX_NUMS; }while((!bcmd_down) && (retry_cnts--)); ret = _SUCCESS; exit: _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL); _func_exit_; return ret; }
s32 rtl8192eu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt) { #if 0 //#ifdef PLATFORM_LINUX u16 fc; int rc, len, pipe; unsigned int bmcst, tid, qsel; struct sk_buff *skb, *pxmit_skb; struct urb *urb; unsigned char *pxmitbuf; struct tx_desc *ptxdesc; struct rtw_ieee80211_hdr *tx_hdr; struct hostapd_priv *phostapdpriv = padapter->phostapdpriv; struct net_device *pnetdev = padapter->pnetdev; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); //DBG_8192C("%s\n", __FUNCTION__); skb = pkt; len = skb->len; tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data); fc = le16_to_cpu(tx_hdr->frame_ctl); bmcst = IS_MCAST(tx_hdr->addr1); if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT) goto _exit; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/[email protected]/msg17214.html pxmit_skb = dev_alloc_skb(len + TXDESC_SIZE); #else pxmit_skb = netdev_alloc_skb(pnetdev, len + TXDESC_SIZE); #endif if(!pxmit_skb) goto _exit; pxmitbuf = pxmit_skb->data; urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { goto _exit; } // ----- fill tx desc ----- ptxdesc = (struct tx_desc *)pxmitbuf; _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc)); //offset 0 ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff); ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); if(bmcst) { ptxdesc->txdw0 |= cpu_to_le32(BIT(24)); } //offset 4 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00); ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode //offset 8 //offset 12 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000); //offset 16 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate //offset 20 //HW append seq ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29. rtl8192e_cal_txdesc_chksum(ptxdesc); // ----- end of fill tx desc ----- // skb_put(pxmit_skb, len + TXDESC_SIZE); pxmitbuf = pxmitbuf + TXDESC_SIZE; _rtw_memcpy(pxmitbuf, skb->data, len); //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len); // ----- prepare urb for submit ----- //translate DMA FIFO addr to pipehandle //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX); pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f); usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe, pxmit_skb->data, pxmit_skb->len, rtl8192eu_hostap_mgnt_xmit_cb, pxmit_skb); urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(urb, &phostapdpriv->anchored); rc = usb_submit_urb(urb, GFP_ATOMIC); if (rc < 0) { usb_unanchor_urb(urb); kfree_skb(skb); } usb_free_urb(urb); _exit: dev_kfree_skb_any(skb); #endif return 0; }
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_8192C("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_8192C("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_8192C("hostapd_mode_init(): register_netdev fail!\n"); if(pnetdev) { rtw_free_netdev(pnetdev); } } return 0; }
/* * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */ int rtw_change_ifname(_adapter *padapter, const char *ifname) { struct net_device *pnetdev; struct net_device *old_pnetdev = padapter->pnetdev; int ret; if(!padapter) goto error; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) if(!rtnl_is_locked()) unregister_netdev(old_pnetdev); else #endif unregister_netdevice(old_pnetdev); rtw_proc_remove_one(old_pnetdev); pnetdev = rtw_init_netdev(padapter); if (!pnetdev) { ret = -1; goto error; } #ifdef CONFIG_USB_HCI SET_NETDEV_DEV(pnetdev, &padapter->dvobjpriv.pusbintf->dev); usb_set_intfdata(padapter->dvobjpriv.pusbintf, pnetdev); #elif defined(CONFIG_PCI_HCI) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) SET_NETDEV_DEV(pnetdev, &padapter->dvobjpriv.ppcidev->dev); #endif pci_set_drvdata(padapter->dvobjpriv.ppcidev, pnetdev); #endif rtw_init_netdev_name(pnetdev, ifname); _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) if(!rtnl_is_locked()) ret = register_netdev(pnetdev); else #endif ret = register_netdevice(pnetdev); if ( ret != 0) { RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n")); goto error; } rtw_proc_init_one(pnetdev); //do free_netdev outside return 0; error: return -1; }