u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid) { _irqL irqL; u8 status=_TRUE; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; _queue *queue = &pmlmepriv->scanned_queue; _func_enter_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, ("+rtw_set_802_11_bssid: bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5])); if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) || (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF)) { status = _FALSE; return status; } _enter_critical_bh(&pmlmepriv->lock, &irqL); RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("\n rtw_set_802_11_bssid: bssid= 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5])); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set BSSID is not allowed under surveying || adhoc master || under linking, fw_state=0x%08x\n", get_fwstate(pmlmepriv))); status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); goto _Abort_Set_BSSID; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE) goto _Abort_Set_BSSID;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same ssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", bssid[0],bssid[1],bssid[2],bssid[3],bssid[4],bssid[5])); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", pmlmepriv->cur_network.network.MacAddress[0],pmlmepriv->cur_network.network.MacAddress[1],pmlmepriv->cur_network.network.MacAddress[2], pmlmepriv->cur_network.network.MacAddress[3],pmlmepriv->cur_network.network.MacAddress[4],pmlmepriv->cur_network.network.MacAddress[5])); rtw_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); pmlmepriv->assoc_by_bssid=_TRUE; status = do_join(padapter); goto done; _Abort_Set_BSSID: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_bssid: _Abort_Set_BSSID\n")); done: _exit_critical_bh(&pmlmepriv->lock, &irqL); _func_exit_; return status; }
u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid) { _irqL irqL; u8 status=_SUCCESS; u32 cur_time = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; _func_enter_; DBG_88E_LEVEL(_drv_info_, "set bssid:%pM\n", bssid); if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) || (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF)) { status = _FAIL; goto exit; } _enter_critical_bh(&pmlmepriv->lock, &irqL); DBG_88E("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { goto handle_tkip_countermeasure; } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) { goto release_mlme_lock; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == true) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false) goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same bssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid=%pM\n", (bssid) )); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid=%pM\n", (pmlmepriv->cur_network.network.MacAddress) )); rtw_disassoc_cmd(padapter, 0, true); if (check_fwstate(pmlmepriv, _FW_LINKED) == true) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } handle_tkip_countermeasure: /* should we add something here...? */ if (padapter->securitypriv.btkip_countermeasure == true) { cur_time = rtw_get_current_time(); if ( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ ) { padapter->securitypriv.btkip_countermeasure = false; padapter->securitypriv.btkip_countermeasure_time = 0; } else { status = _FAIL; goto release_mlme_lock; } } _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); pmlmepriv->assoc_by_bssid=true; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { pmlmepriv->to_join = true; } else { status = rtw_do_join(padapter); } release_mlme_lock: _exit_critical_bh(&pmlmepriv->lock, &irqL); exit: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_bssid: status=%d\n", status)); _func_exit_; return status; }
void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attrib *pattrib) { struct mlme_priv*pmlmepriv = &padapter->mlmepriv; struct recv_priv *precvpriv = &(padapter->recvpriv); #ifdef CONFIG_BR_EXT void *br_port = NULL; #endif int ret; /* Indicat the packets to upper layer */ if (pkt) { if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { _pkt *pskb2=NULL; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; int bmcast = IS_MCAST(pattrib->dst); //DBG_871X("bmcast=%d\n", bmcast); if (_rtw_memcmp(pattrib->dst, adapter_mac_addr(padapter), 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(pkt); } 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; pkt->dev = pnetdev; #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt)); #endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) _rtw_xmit_entry(pkt, pnetdev); if(bmcast && (pskb2 != NULL) ) { pkt = pskb2; DBG_COUNTER(padapter->rx_logs.os_indicate_ap_mcast); } else { DBG_COUNTER(padapter->rx_logs.os_indicate_ap_forward); return; } } } else// to APself { //DBG_871X("to APSelf\n"); DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self); } } #ifdef CONFIG_BR_EXT // Insert NAT2.5 RX here! #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, pkt) == -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 rtw_skb_free(sub_skb); continue; #endif } } #endif // CONFIG_BR_EXT if( precvpriv->sink_udpport > 0) rtw_sink_rtp_seq_dbg(padapter,pkt); #ifdef DBG_UDP_PKT_LOSE_11AC /* After eth_type_trans process , pkt->data pointer will move from ethrnet header to ip header , * we have to check ethernet type , so this debug must be print before eth_type_trans */ if (*((unsigned short *)(pkt->data+ETH_ALEN*2)) == htons(ETH_P_ARP)) { /* ARP Payload length will be 42bytes or 42+18(tailer)=60bytes*/ if (pkt->len != 42 && pkt->len != 60) DBG_871X("Error !!%s,ARP Payload length %u not correct\n" , __func__ , pkt->len); } else if (*((unsigned short *)(pkt->data+ETH_ALEN*2)) == htons(ETH_P_IP)) { if (be16_to_cpu(*((u16 *)(pkt->data+PAYLOAD_LEN_LOC_OF_IP_HDR))) != (pkt->len)-ETH_HLEN) { DBG_871X("Error !!%s,Payload length not correct\n" , __func__); DBG_871X("%s, IP header describe Total length=%u\n" , __func__ , be16_to_cpu(*((u16 *)(pkt->data+PAYLOAD_LEN_LOC_OF_IP_HDR)))); DBG_871X("%s, Pkt real length=%u\n" , __func__ , (pkt->len)-ETH_HLEN); } } #endif /* After eth_type_trans process , pkt->data pointer will move from ethrnet header to ip header */ pkt->protocol = eth_type_trans(pkt, padapter->pnetdev); pkt->dev = padapter->pnetdev; #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { pkt->ip_summed = CHECKSUM_UNNECESSARY; } else { pkt->ip_summed = CHECKSUM_NONE; } #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */ pkt->ip_summed = CHECKSUM_NONE; #endif //CONFIG_TCP_CSUM_OFFLOAD_RX ret = rtw_netif_rx(padapter->pnetdev, pkt); if (ret == NET_RX_SUCCESS) DBG_COUNTER(padapter->rx_logs.os_netif_ok); else DBG_COUNTER(padapter->rx_logs.os_netif_err); } }
void 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_RTL8712_TCP_CSUM_OFFLOAD_RX struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; #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) { rtw_free_recvframe(precv_frame, pfree_recv_queue); return; } #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; #ifdef NET_SKBUFF_DATA_USES_OFFSET skb_set_tail_pointer(skb, precv_frame->u.hdr.len); #else skb->tail = precv_frame->u.hdr.rx_tail; #endif 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) { psta = rtw_get_stainfo(pstapriv, pattrib->dst); //DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst); if(bmcast) { pskb2 = skb_clone(skb, GFP_ATOMIC); } if(psta) { //DBG_871X("directly forwarding to the xmit_entry\n"); //skb->ip_summed = CHECKSUM_NONE; //skb->protocol = eth_type_trans(skb, pnetdev); skb->dev = padapter->pnetdev; rtw_xmit_entry(skb, padapter->pnetdev); if(bmcast == _FALSE) goto _recv_indicatepkt_end; } if(bmcast) skb = pskb2; } else// to APself { //DBG_871X("to APSelf\n"); } } #ifdef CONFIG_RTL8712_TCP_CSUM_OFFLOAD_RX if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { skb->ip_summed = CHECKSUM_UNNECESSARY; //printk("CHECKSUM_UNNECESSARY \n"); } else { skb->ip_summed = CHECKSUM_NONE; //printk("CHECKSUM_NONE(%d, %d) \n", pattrib->tcpchk_valid, pattrib->tcp_chkrpt); } #else /* !CONFIG_RTL8712_TCP_CSUM_OFFLOAD_RX */ skb->ip_summed = CHECKSUM_NONE; #endif skb->dev = padapter->pnetdev; skb->protocol = eth_type_trans(skb, padapter->pnetdev); netif_rx(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 netif_rx!!!!\n")); _func_exit_; return; _recv_indicatepkt_drop: //enqueue back to free_recv_queue if(precv_frame) rtw_free_recvframe(precv_frame, pfree_recv_queue); precvpriv->rx_drop++; _func_exit_; }
int rtw_get_sec_ie(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len) { u8 authmode, sec_idx, i; u8 wpa_oui[4]={0x0,0x50,0xf2,0x01}; uint cnt; _func_enter_; //Search required WPA or WPA2 IE and copy to sec_ie[ ] cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_); sec_idx=0; while(cnt<in_len) { authmode=in_ie[cnt]; if((authmode==_WPA_IE_ID_)&&(_rtw_memcmp(&in_ie[cnt+2], &wpa_oui[0],4)==_TRUE)) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw_get_wpa_ie: sec_idx=%d in_ie[cnt+1]+2=%d\n",sec_idx,in_ie[cnt+1]+2)); if (wpa_ie) { _rtw_memcpy(wpa_ie, &in_ie[cnt],in_ie[cnt+1]+2); for(i=0;i<(in_ie[cnt+1]+2);i=i+8){ RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n %2x,%2x,%2x,%2x,%2x,%2x,%2x,%2x\n", wpa_ie[i],wpa_ie[i+1],wpa_ie[i+2],wpa_ie[i+3],wpa_ie[i+4], wpa_ie[i+5],wpa_ie[i+6],wpa_ie[i+7])); } } *wpa_len=in_ie[cnt+1]+2; cnt+=in_ie[cnt+1]+2; //get next } else { if(authmode==_WPA2_IE_ID_) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n get_rsn_ie: sec_idx=%d in_ie[cnt+1]+2=%d\n",sec_idx,in_ie[cnt+1]+2)); if (rsn_ie) { _rtw_memcpy(rsn_ie, &in_ie[cnt],in_ie[cnt+1]+2); for(i=0;i<(in_ie[cnt+1]+2);i=i+8){ RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n %2x,%2x,%2x,%2x,%2x,%2x,%2x,%2x\n", rsn_ie[i],rsn_ie[i+1],rsn_ie[i+2],rsn_ie[i+3],rsn_ie[i+4], rsn_ie[i+5],rsn_ie[i+6],rsn_ie[i+7])); } } *rsn_len=in_ie[cnt+1]+2; cnt+=in_ie[cnt+1]+2; //get next } else { cnt+=in_ie[cnt+1]+2; //get next } } } _func_exit_; return (*rsn_len+*wpa_len); }
u8 rtw_do_join(_adapter * padapter) { _irqL irqL; _list *plist, *phead; u8* pibss = NULL; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); _queue *queue = &(pmlmepriv->scanned_queue); u8 ret=_SUCCESS; _func_enter_; _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); phead = get_list_head(queue); plist = get_next(phead); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("\n rtw_do_join: phead = %p; plist = %p \n\n\n", phead, plist)); pmlmepriv->cur_network.join_res = -2; set_fwstate(pmlmepriv, _FW_UNDER_LINKING); pmlmepriv->pscanned = plist; pmlmepriv->to_join = _TRUE; if(_rtw_queue_empty(queue)== _TRUE) { _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); //when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty //we try to issue sitesurvey firstly if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==_FALSE || rtw_to_roaming(padapter) > 0 ) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_do_join(): site survey if scanned_queue is empty\n.")); // submit site_survey_cmd if(_SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ) { pmlmepriv->to_join = _FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_do_join(): site survey return error\n.")); } } else { pmlmepriv->to_join = _FALSE; ret = _FAIL; } goto exit; } else { int select_ret; _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); if((select_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS) { pmlmepriv->to_join = _FALSE; _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); } else { if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) { // submit createbss_cmd to change to a ADHOC_MASTER //pmlmepriv->lock has been acquired by caller... WLAN_BSSID_EX *pdev_network = &(padapter->registrypriv.dev_network); pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; pibss = padapter->registrypriv.dev_network.MacAddress; _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); rtw_update_registrypriv_dev_network(padapter); rtw_generate_random_ibss(pibss); if(rtw_createbss_cmd(padapter)!=_SUCCESS) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>do_goin: rtw_createbss_cmd status FAIL*** \n ")); ret = _FALSE; goto exit; } pmlmepriv->to_join = _FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("***Error=> rtw_select_and_join_from_scanned_queue FAIL under STA_Mode*** \n ")); } else { // can't associate ; reset under-linking _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); #if 0 if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) { if(_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) { // for funk to do roaming // funk will reconnect, but funk will not sitesurvey before reconnect RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("for funk to do roaming")); if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE) rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0); } } #endif //when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue //we try to issue sitesurvey firstly if(pmlmepriv->LinkDetectInfo.bBusyTraffic==_FALSE || rtw_to_roaming(padapter) > 0 ) { //DBG_871X("rtw_do_join() when no desired bss in scanning queue \n"); if( _SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ){ pmlmepriv->to_join = _FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("do_join(): site survey return error\n.")); } } else { ret = _FAIL; pmlmepriv->to_join = _FALSE; } } } } exit: _func_exit_; return ret; }
uint8_t rtw_set_802_11_ssid(struct rtl_priv* rtlpriv, NDIS_802_11_SSID *ssid) { uint8_t status = _SUCCESS; uint32_t cur_time = 0; struct mlme_priv *pmlmepriv = &rtlpriv->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state=0x%08x\n", ssid->Ssid, get_fwstate(pmlmepriv)); if(rtlpriv->hw_init_completed==_FALSE){ status = _FAIL; goto exit; } spin_lock_bh(&pmlmepriv->lock); DBG_871X("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { goto handle_tkip_countermeasure; } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { goto release_mlme_lock; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) { if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) { if(rtw_is_same_ibss(rtlpriv, pnetwork) == _FALSE) { //if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again rtw_disassoc_cmd(rtlpriv, 0, _TRUE); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(rtlpriv); rtw_free_assoc_resources(rtlpriv, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else { goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } } else { rtw_lps_ctrl_wk_cmd(rtlpriv, LPS_CTRL_JOINBSS, 1); } } else { rtw_disassoc_cmd(rtlpriv, 0, _TRUE); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(rtlpriv); rtw_free_assoc_resources(rtlpriv, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } handle_tkip_countermeasure: if((status=rtw_handle_tkip_countermeasure(rtlpriv)) == _FAIL) goto release_mlme_lock; #ifdef CONFIG_VALIDATE_SSID if (rtw_validate_ssid(ssid) == _FALSE) { status = _FAIL; goto release_mlme_lock; } #endif memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); pmlmepriv->assoc_by_bssid=_FALSE; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { pmlmepriv->to_join = _TRUE; } else { status = rtw_do_join(rtlpriv); } release_mlme_lock: spin_unlock_bh(&pmlmepriv->lock); exit: return status; }
u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid) { _irqL irqL; u8 status=_SUCCESS; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; _func_enter_; DBG_871X_LEVEL(_drv_always_, "set bssid:%pM\n", bssid); if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) || (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF)) { status = _FAIL; goto exit; } _enter_critical_bh(&pmlmepriv->lock, &irqL); DBG_871X("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { goto handle_tkip_countermeasure; } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { goto release_mlme_lock; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE) goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same bssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid="MAC_FMT"\n", MAC_ARG(bssid) )); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress) )); rtw_disassoc_cmd(padapter, 0, _TRUE); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } handle_tkip_countermeasure: if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) { status = _FAIL; goto release_mlme_lock; } _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID)); _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); pmlmepriv->assoc_by_bssid=_TRUE; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { pmlmepriv->to_join = _TRUE; } else { status = rtw_do_join(padapter); } release_mlme_lock: _exit_critical_bh(&pmlmepriv->lock, &irqL); exit: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("rtw_set_802_11_bssid: status=%d\n", status)); _func_exit_; return status; }
static s32 pre_recv_entry(union recv_frame *precvframe, u8 *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; u8 *pbuf = precvframe->u.hdr.rx_data; if(!secondary_padapter) return ret; paddr1 = GetAddr1Ptr(pbuf); 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 { u8 clone = _TRUE; #if 0 u8 type, subtype, *paddr2, *paddr3; type = GetFrameType(pbuf); subtype = GetFrameSubType(pbuf); //bit(7)~bit(2) switch (type) { case WIFI_MGT_TYPE: //Handle BC/MC mgnt Packets if(subtype == WIFI_BEACON) { paddr3 = GetAddr3Ptr(precvframe->u.hdr.rx_data); if (check_fwstate(&secondary_padapter->mlmepriv, _FW_LINKED) && _rtw_memcmp(paddr3, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN)) { //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; clone = _FALSE; } if(check_fwstate(&primary_padapter->mlmepriv, _FW_LINKED) && _rtw_memcmp(paddr3, get_bssid(&primary_padapter->mlmepriv), ETH_ALEN)) { if(clone==_FALSE) { clone = _TRUE; } else { clone = _FALSE; } precvframe->u.hdr.adapter = primary_padapter; } if(check_fwstate(&primary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) || check_fwstate(&secondary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) { clone = _TRUE; precvframe->u.hdr.adapter = primary_padapter; } } else if(subtype == WIFI_PROBEREQ) { //probe req frame is only for interface2 //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; clone = _FALSE; } break; case WIFI_CTRL_TYPE: // Handle BC/MC ctrl Packets break; case WIFI_DATA_TYPE: //Handle BC/MC data Packets //Notes: AP MODE never rx BC/MC data packets paddr2 = GetAddr2Ptr(precvframe->u.hdr.rx_data); if(_rtw_memcmp(paddr2, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN)) { //change to secondary interface precvframe->u.hdr.adapter = secondary_padapter; clone = _FALSE; } break; default: break; } #endif if(_TRUE == clone) { //clone/copy to if2 struct rx_pkt_attrib *pattrib = NULL; precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue); if(precvframe_if2) { precvframe_if2->u.hdr.adapter = secondary_padapter; _rtw_init_listhead(&precvframe_if2->u.hdr.list); precvframe_if2->u.hdr.precvbuf = NULL; //can't access the precvbuf for new arch. precvframe_if2->u.hdr.len=0; _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)); pattrib = &precvframe_if2->u.hdr.attrib; if(rtw_os_alloc_recvframe(secondary_padapter, precvframe_if2, pbuf, NULL) == _SUCCESS) { recvframe_put(precvframe_if2, pattrib->pkt_len); //recvframe_pull(precvframe_if2, drvinfo_sz + RXDESC_SIZE); if (pattrib->physt && pphy_status) rtl8192e_query_rx_phy_status(precvframe_if2, pphy_status); ret = rtw_recv_entry(precvframe_if2); } else { rtw_free_recvframe(precvframe_if2, pfree_recv_queue); DBG_8192C("%s()-%d: alloc_skb() failed!\n", __FUNCTION__, __LINE__); } } } } //if (precvframe->u.hdr.attrib.physt) // rtl8192e_query_rx_phy_status(precvframe, pphy_status); //ret = rtw_recv_entry(precvframe); #endif return ret; }
void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attrib *pattrib) { struct mlme_priv*pmlmepriv = &padapter->mlmepriv; #ifdef CONFIG_BR_EXT void *br_port = NULL; #endif /* Indicat the packets to upper layer */ if (pkt) { if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) { _pkt *pskb2=NULL; struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; 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 = skb_clone(pkt, GFP_ATOMIC); } 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; pkt->dev = pnetdev; #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)) skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt)); #endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) rtw_xmit_entry(pkt, pnetdev); if(bmcast && (pskb2 != NULL) ) { pkt = pskb2; } else { return; } } } else// to APself { //DBG_871X("to APSelf\n"); } } #ifdef CONFIG_BR_EXT // Insert NAT2.5 RX here! #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, pkt) == -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 dev_kfree_skb_any(sub_skb); continue; #endif } } #endif // CONFIG_BR_EXT pkt->protocol = eth_type_trans(pkt, padapter->pnetdev); pkt->dev = padapter->pnetdev; #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) { pkt->ip_summed = CHECKSUM_UNNECESSARY; } else { pkt->ip_summed = CHECKSUM_NONE; } #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */ pkt->ip_summed = CHECKSUM_NONE; #endif //CONFIG_TCP_CSUM_OFFLOAD_RX netif_rx(pkt); } }
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 = skb_copy(skb, GFP_ATOMIC); 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++; dev_kfree_skb_any(newskb); } else pxmitpriv->tx_pkts++; } else { DBG_871X("%s-%d: skb_copy() failed!\n", __FUNCTION__, __LINE__); pxmitpriv->tx_drop++; //dev_kfree_skb_any(skb); return _FALSE; // Caller shall tx this multicast frame via normal way. } } dev_kfree_skb_any(skb); return _TRUE; }
u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) { u8 *frame_body; u8 status, dialogToken; struct sta_info *psta = NULL; _adapter *padapter = pwdinfo->padapter; struct sta_priv *pstapriv = &padapter->stapriv; u8 p2p_ie[ MAX_P2P_IE_LEN ] = { 0xFF }; u32 p2p_ielen = 0; frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); dialogToken = frame_body[7]; status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP; if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) ) { u8 groupid[ 38 ] = { 0x00 }; u8 dev_addr[ETH_ALEN] = { 0x00 }; u32 attr_contentlen = 0; if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) { if(_rtw_memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) && _rtw_memcmp(pwdinfo->p2p_group_ssid, groupid+ETH_ALEN, pwdinfo->p2p_group_ssid_len)) { attr_contentlen=0; if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) { _list *phead, *plist; phead = &pstapriv->asoc_list; plist = get_next(phead); //look up sta asoc_queue while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) { psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); plist = get_next(plist); if(psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) && _rtw_memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) { //issue GO Discoverability Request issue_group_disc_req(pwdinfo, psta->hwaddr); status = P2P_STATUS_SUCCESS; break; } else { status = P2P_STATUS_FAIL_INFO_UNAVAILABLE; } } } else {
u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len) { u8 *p; u32 ret=_FALSE; u8 p2pie[ MAX_P2P_IE_LEN ] = { 0xFF }; u32 p2pielen = 0; int ssid_len=0, rate_cnt = 0; p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); if ( rate_cnt <= 4 ) { int i, g_rate =0; for( i = 0; i < rate_cnt; i++ ) { if ( ( ( *( p + 2 + i ) & 0xff ) != 0x02 ) && ( ( *( p + 2 + i ) & 0xff ) != 0x04 ) && ( ( *( p + 2 + i ) & 0xff ) != 0x0B ) && ( ( *( p + 2 + i ) & 0xff ) != 0x16 ) ) { g_rate = 1; } } if ( g_rate == 0 ) { // There is no OFDM rate included in SupportedRates IE of this probe request frame // The driver should response this probe request. return ret; } } else { // rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. // We should proceed the following check for this probe request. } // Added comments by Albert 20100906 // There are several items we should check here. // 1. This probe request frame must contain the P2P IE. (Done) // 2. This probe request frame must contain the wildcard SSID. (Done) // 3. Wildcard BSSID. (Todo) // 4. Destination Address. ( Done in mgt_dispatcher function ) // 5. Requested Device Type in WSC IE. (Todo) // 6. Device ID attribute in P2P IE. (Todo) p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); if((pwdinfo->role == P2P_ROLE_DEVICE) || (pwdinfo->role == P2P_ROLE_GO)) { if(rtw_get_p2p_ie( pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ , p2pie, &p2pielen)) { if ( (p != NULL) && _rtw_memcmp( ( void * ) ( p+2 ), ( void * ) pwdinfo->p2p_wildcard_ssid , 7 )) { //todo: //Check Requested Device Type attributes in WSC IE. //Check Device ID attribute in P2P IE ret = _TRUE; } } else { //non -p2p device } } return ret; }
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); _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)) { 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); RTW_INFO("%s()-%d: rtw_xmit() return error! res=%d\n", __FUNCTION__, __LINE__, res); pxmitpriv->tx_drop++; rtw_skb_free(newskb); } } else { DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_skb); RTW_INFO("%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 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid) { _irqL irqL; u8 status = _TRUE; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; _queue *queue = &pmlmepriv->scanned_queue; #ifdef PLATFORM_WINDOWS LARGE_INTEGER sys_time; u32 diff_time,cur_time ; #endif _func_enter_; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, ("+rtw_set_802_11_ssid: ssid=[%s] fw_state=0x%08x\n", ssid->Ssid, get_fwstate(pmlmepriv))); if(padapter->hw_init_completed==_FALSE){ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); return _FALSE; } _enter_critical_bh(&pmlmepriv->lock, &irqL); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is not allowed under surveying || adhoc master || under linking\n")); status = check_fwstate(pmlmepriv, _FW_UNDER_LINKING); goto _Abort_Set_SSID; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) { if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state=0x%08x\n", get_fwstate(pmlmepriv))); if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE) { //if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again rtw_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else { goto _Abort_Set_SSID;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } } #ifdef CONFIG_LPS else { lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); } #endif } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); rtw_disassoc_cmd(padapter); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } #ifdef PLATFORM_WINDOWS if (padapter->securitypriv.btkip_countermeasure==_TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:padapter->securitypriv.btkip_countermeasure==_TRUE\n")); NdisGetCurrentSystemTime(&sys_time); cur_time=(u32)(sys_time.QuadPart/10); // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:cur_time=0x%x\n",cur_time)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:psecuritypriv->last_mic_err_time=0x%x\n",padapter->securitypriv.btkip_countermeasure_time)); diff_time = cur_time -padapter->securitypriv.btkip_countermeasure_time; // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:diff_time=0x%x\n",diff_time)); if (diff_time > 60000000) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time >60s.\n")); padapter->securitypriv.btkip_countermeasure=_FALSE; // Update MIC error time. padapter->securitypriv.btkip_countermeasure_time=0; } else { // can't join in 60 seconds. status = _FALSE; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time <60s.\n")); goto _Abort_Set_SSID; } } #endif #ifdef PLATFORM_LINUX if (padapter->securitypriv.btkip_countermeasure == _TRUE) { status = _FALSE; goto _Abort_Set_SSID; } #endif if (rtw_validate_ssid(ssid) == _FALSE) { status = _FALSE; goto _Abort_Set_SSID; } _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); pmlmepriv->assoc_by_bssid=_FALSE; status = do_join(padapter); goto done; _Abort_Set_SSID: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("-rtw_set_802_11_ssid: _Abort_Set_SSID: status=%d\n", status)); done: _exit_critical_bh(&pmlmepriv->lock, &irqL); _func_exit_; return status; }
// // Description: // Construct the ARP response packet to support ARP offload. // static void ConstructARPResponse( PADAPTER padapter, u8 *pframe, u32 *pLength, u8 *pIPAddress ) { struct rtw_ieee80211_hdr *pwlanhdr; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &pmlmepriv->cur_network; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct security_priv *psecuritypriv = &padapter->securitypriv; static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06}; u16 *fctrl; u32 pktlen; u8 *pARPRspPkt = pframe; //for TKIP Cal MIC u8 *payload = pframe; u8 EncryptionHeadOverhead = 0; pwlanhdr = (struct rtw_ieee80211_hdr*)pframe; fctrl = &pwlanhdr->frame_ctl; *(fctrl) = 0; //------------------------------------------------------------------------- // MAC Header. //------------------------------------------------------------------------- SetFrameType(fctrl, WIFI_DATA); //SetFrameSubType(fctrl, 0); SetToDs(fctrl); _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); SetSeqNum(pwlanhdr, 0); SetDuration(pwlanhdr, 0); //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); //SET_80211_HDR_TO_DS(pARPRspPkt, 1); //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); //SET_80211_HDR_DURATION(pARPRspPkt, 0); //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); #ifdef CONFIG_WAPI_SUPPORT *pLength = sMacHdrLng; #else *pLength = 24; #endif //YJ,del,120503 #if 0 //------------------------------------------------------------------------- // Qos Header: leave space for it if necessary. //------------------------------------------------------------------------- if(pStaQos->CurrentQosMode > QOS_DISABLE) { SET_80211_HDR_QOS_EN(pARPRspPkt, 1); PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng); *pLength += sQoSCtlLng; } #endif //------------------------------------------------------------------------- // Security Header: leave space for it if necessary. //------------------------------------------------------------------------- switch (psecuritypriv->dot11PrivacyAlgrthm) { case _WEP40_: case _WEP104_: EncryptionHeadOverhead = 4; break; case _TKIP_: EncryptionHeadOverhead = 8; break; case _AES_: EncryptionHeadOverhead = 8; break; #ifdef CONFIG_WAPI_SUPPORT case _SMS4_: EncryptionHeadOverhead = 18; break; #endif default: EncryptionHeadOverhead = 0; } if(EncryptionHeadOverhead > 0) { _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead); *pLength += EncryptionHeadOverhead; //SET_80211_HDR_WEP(pARPRspPkt, 1); //Suggested by CCW. SetPrivacy(fctrl); } //------------------------------------------------------------------------- // Frame Body. //------------------------------------------------------------------------- pARPRspPkt = (u8*)(pframe+ *pLength); // LLC header _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8); *pLength += 8; // ARP element pARPRspPkt += 8; SET_ARP_PKT_HW(pARPRspPkt, 0x0100); SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); // IP protocol SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6); SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4); SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv))); SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress); #ifdef CONFIG_ARP_KEEP_ALIVE if (rtw_gw_addr_query(padapter)==0) { SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr); SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip); } else #endif { SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network))); SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress); DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network)))); DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress)); } *pLength += 28; if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { u8 mic[8]; struct mic_data micdata; struct sta_info *psta = NULL; u8 priority[4]={0x0,0x0,0x0,0x0}; u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; DBG_871X("%s(): Add MIC\n",__FUNCTION__); psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network))); if (psta != NULL) { if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){ DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__); } //start to calculate the mic code rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]); } rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); //DA rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA priority[0]=0; rtw_secmicappend(&micdata, &priority[0], 4); rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28 rtw_secgetmic(&micdata,&(mic[0])); pARPRspPkt += 28; _rtw_memcpy(pARPRspPkt, &(mic[0]),8); *pLength += 8; } }
u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid) { _irqL irqL; u8 status = _SUCCESS; u32 cur_time = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; _func_enter_; DBG_871X_LEVEL(_drv_always_, "set ssid [%s] fw_state=0x%08x\n", ssid->Ssid, get_fwstate(pmlmepriv)); if(padapter->hw_init_completed==_FALSE){ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n")); status = _FAIL; goto exit; } _enter_critical_bh(&pmlmepriv->lock, &irqL); DBG_871X("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { goto handle_tkip_countermeasure; } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { goto release_mlme_lock; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE)) { if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state=0x%08x\n", get_fwstate(pmlmepriv))); if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE) { //if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again rtw_disassoc_cmd(padapter, 0, _TRUE); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else { goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } } #ifdef CONFIG_LPS else { rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); } #endif } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); rtw_disassoc_cmd(padapter, 0, _TRUE); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } handle_tkip_countermeasure: #ifdef PLATFORM_WINDOWS if (padapter->securitypriv.btkip_countermeasure==_TRUE) { LARGE_INTEGER sys_time; u32 diff_time,cur_time ; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:padapter->securitypriv.btkip_countermeasure==_TRUE\n")); NdisGetCurrentSystemTime(&sys_time); cur_time=(u32)(sys_time.QuadPart/10); // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:cur_time=0x%x\n",cur_time)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:psecuritypriv->last_mic_err_time=0x%x\n",padapter->securitypriv.btkip_countermeasure_time)); diff_time = cur_time -padapter->securitypriv.btkip_countermeasure_time; // In micro-second. RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:diff_time=0x%x\n",diff_time)); if (diff_time > 60000000) { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time >60s.\n")); padapter->securitypriv.btkip_countermeasure=_FALSE; // Update MIC error time. padapter->securitypriv.btkip_countermeasure_time=0; } else { // can't join in 60 seconds. status = _FAIL; RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time <60s.\n")); goto release_mlme_lock; } } #endif #ifdef PLATFORM_LINUX if (padapter->securitypriv.btkip_countermeasure == _TRUE) { cur_time = rtw_get_current_time(); if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ ) { padapter->securitypriv.btkip_countermeasure = _FALSE; padapter->securitypriv.btkip_countermeasure_time = 0; } else { status = _FAIL; goto release_mlme_lock; } } #endif #ifdef CONFIG_VALIDATE_SSID if (rtw_validate_ssid(ssid) == _FALSE) { status = _FAIL; goto release_mlme_lock; } #endif _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); pmlmepriv->assoc_by_bssid=_FALSE; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { pmlmepriv->to_join = _TRUE; } else { status = rtw_do_join(padapter); } release_mlme_lock: _exit_critical_bh(&pmlmepriv->lock, &irqL); exit: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("-rtw_set_802_11_ssid: status=%d\n", status)); _func_exit_; return status; }
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 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) { int tx_ret; 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) tx_ret = _rtw_xmit_entry(skb, pnetdev); if (tx_ret != NETDEV_TX_OK) { padapter->xmitpriv.tx_drop++; rtw_skb_free(skb); } 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); 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_; }
uint8_t rtw_set_802_11_bssid(struct rtl_priv* rtlpriv, uint8_t *bssid) { uint8_t status=_SUCCESS; struct mlme_priv *pmlmepriv = &rtlpriv->mlmepriv; DBG_871X_LEVEL(_drv_always_, "set bssid:%pM\n", bssid); if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) || (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF)) { status = _FAIL; goto exit; } spin_lock_bh(&pmlmepriv->lock); DBG_871X("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { goto handle_tkip_countermeasure; } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) { goto release_mlme_lock; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE) { if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE) { if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE) goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. } else { rtw_disassoc_cmd(rtlpriv, 0, _TRUE); if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) rtw_indicate_disconnect(rtlpriv); rtw_free_assoc_resources(rtlpriv, 1); if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } handle_tkip_countermeasure: //should we add something here...? if((status=rtw_handle_tkip_countermeasure(rtlpriv)) == _FAIL) goto release_mlme_lock; memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN); pmlmepriv->assoc_by_bssid=_TRUE; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) { pmlmepriv->to_join = _TRUE; } else { status = rtw_do_join(rtlpriv); } release_mlme_lock: spin_unlock_bh(&pmlmepriv->lock); exit: return status; }
int rtw_parse_wpa_ie(uint8_t * wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) { int i, ret=_SUCCESS; int left, count; uint8_t *pos; uint8_t SUITE_1X[4] = {0x00, 0x50, 0xf2, 1}; if (wpa_ie_len <= 0) { /* No WPA IE - fail silently */ return _FAIL; } if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (uint8_t)(wpa_ie_len - 2)) || (_rtw_memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != true) ) { return _FAIL; } pos = wpa_ie; pos += 8; left = wpa_ie_len - 8; //group_cipher if (left >= WPA_SELECTOR_LEN) { *group_cipher = rtw_get_wpa_cipher_suite(pos); pos += WPA_SELECTOR_LEN; left -= WPA_SELECTOR_LEN; } else if (left > 0) { return _FAIL; } //pairwise_cipher if (left >= 2) { //count = le16_to_cpu(*(u16 *)pos); count = RTW_GET_LE16(pos); pos += 2; left -= 2; if (count == 0 || left < count * WPA_SELECTOR_LEN) { return _FAIL; } for (i = 0; i < count; i++) { *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos); pos += WPA_SELECTOR_LEN; left -= WPA_SELECTOR_LEN; } } else if (left == 1) { return _FAIL; } if (is_8021x) { if (left >= 6) { pos += 2; if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) { *is_8021x = 1; } } } return ret; }
uint8_t rtw_do_join(struct rtl_priv * rtlpriv) { struct list_head *plist, *phead; uint8_t * pibss = NULL; struct mlme_priv *pmlmepriv = &(rtlpriv->mlmepriv); struct __queue *queue = &(pmlmepriv->scanned_queue); uint8_t ret=_SUCCESS; spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); phead = get_list_head(queue); plist = get_next(phead); pmlmepriv->cur_network.join_res = -2; set_fwstate(pmlmepriv, _FW_UNDER_LINKING); pmlmepriv->pscanned = plist; pmlmepriv->to_join = _TRUE; if(list_empty(&queue->list)) { spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); //when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty //we try to issue sitesurvey firstly if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==_FALSE) { // submit site_survey_cmd if(_SUCCESS!=(ret=rtw_sitesurvey_cmd(rtlpriv, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ) { pmlmepriv->to_join = _FALSE; } } else { pmlmepriv->to_join = _FALSE; ret = _FAIL; } goto exit; } else { int select_ret; spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); if((select_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS) { pmlmepriv->to_join = _FALSE; _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); } else { if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) { // submit createbss_cmd to change to a ADHOC_MASTER //pmlmepriv->lock has been acquired by caller... WLAN_BSSID_EX *pdev_network = &(rtlpriv->registrypriv.dev_network); pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; pibss = rtlpriv->registrypriv.dev_network.MacAddress; memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID)); memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID)); rtw_update_registrypriv_dev_network(rtlpriv); rtw_generate_random_ibss(pibss); if(rtw_createbss_cmd(rtlpriv)!=_SUCCESS) { ret = _FALSE; goto exit; } pmlmepriv->to_join = _FALSE; } else { // can't associate ; reset under-linking _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); #if 0 if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) { if(_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) { // for funk to do roaming // funk will reconnect, but funk will not sitesurvey before reconnect if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE) rtw_sitesurvey_cmd(rtlpriv, &pmlmepriv->assoc_ssid, 1, NULL, 0); } } #endif //when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue //we try to issue sitesurvey firstly if(pmlmepriv->LinkDetectInfo.bBusyTraffic==_FALSE) { //DBG_871X("rtw_do_join() when no desired bss in scanning queue \n"); if( _SUCCESS!=(ret=rtw_sitesurvey_cmd(rtlpriv, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ){ pmlmepriv->to_join = _FALSE; } } else { ret = _FAIL; pmlmepriv->to_join = _FALSE; } } } } exit: return ret; }
int rtw_parse_wpa2_ie(uint8_t * rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) { int i, ret=_SUCCESS; int left, count; uint8_t *pos; uint8_t SUITE_1X[4] = {0x00,0x0f, 0xac, 0x01}; if (rsn_ie_len <= 0) { /* No RSN IE - fail silently */ return _FAIL; } if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (uint8_t)(rsn_ie_len - 2))) { return _FAIL; } pos = rsn_ie; pos += 4; left = rsn_ie_len - 4; //group_cipher if (left >= RSN_SELECTOR_LEN) { *group_cipher = rtw_get_wpa2_cipher_suite(pos); pos += RSN_SELECTOR_LEN; left -= RSN_SELECTOR_LEN; } else if (left > 0) { return _FAIL; } //pairwise_cipher if (left >= 2) { //count = le16_to_cpu(*(u16 *)pos); count = RTW_GET_LE16(pos); pos += 2; left -= 2; if (count == 0 || left < count * RSN_SELECTOR_LEN) { return _FAIL; } for (i = 0; i < count; i++) { *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos); pos += RSN_SELECTOR_LEN; left -= RSN_SELECTOR_LEN; } } else if (left == 1) { return _FAIL; } if (is_8021x) { if (left >= 6) { pos += 2; if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) { *is_8021x = 1; } } } return ret; }
int rtw_parse_wpa2_ie(u8* rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x) { int i, ret=_SUCCESS; int left, count; u8 *pos; u8 SUITE_1X[4] = {0x00,0x0f, 0xac, 0x01}; if (rsn_ie_len <= 0) { /* No RSN IE - fail silently */ return _FAIL; } if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2))) { return _FAIL; } pos = rsn_ie; pos += 4; left = rsn_ie_len - 4; //group_cipher if (left >= RSN_SELECTOR_LEN) { *group_cipher = rtw_get_wpa2_cipher_suite(pos); pos += RSN_SELECTOR_LEN; left -= RSN_SELECTOR_LEN; } else if (left > 0) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left)); return _FAIL; } //pairwise_cipher if (left >= 2) { //count = le16_to_cpu(*(u16*)pos); count = RTW_GET_LE16(pos); pos += 2; left -= 2; if (count == 0 || left < count * RSN_SELECTOR_LEN) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), " "count %u left %u", __FUNCTION__, count, left)); return _FAIL; } for (i = 0; i < count; i++) { *pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos); pos += RSN_SELECTOR_LEN; left -= RSN_SELECTOR_LEN; } } else if (left == 1) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)", __FUNCTION__)); return _FAIL; } if (is_8021x) { if (left >= 6) { pos += 2; if (_rtw_memcmp(pos, SUITE_1X, 4) == 1) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("%s (): there has 802.1x auth\n", __FUNCTION__)); *is_8021x = 1; } } } return ret; }
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 skb_copy(). //If skb->len is zero, 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; }
int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher) { int i, ret=_SUCCESS; int left, count; u8 *pos; if (wpa_ie_len <= 0) { /* No WPA IE - fail silently */ return _FAIL; } if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) || (_rtw_memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != _TRUE) ) { return _FAIL; } pos = wpa_ie; pos += 8; left = wpa_ie_len - 8; //group_cipher if (left >= WPA_SELECTOR_LEN) { *group_cipher = rtw_get_wpa_cipher_suite(pos); pos += WPA_SELECTOR_LEN; left -= WPA_SELECTOR_LEN; } else if (left > 0) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left)); return _FAIL; } //pairwise_cipher if (left >= 2) { //count = le16_to_cpu(*(u16*)pos); count = RTW_GET_LE16(pos); pos += 2; left -= 2; if (count == 0 || left < count * WPA_SELECTOR_LEN) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), " "count %u left %u", __FUNCTION__, count, left)); return _FAIL; } for (i = 0; i < count; i++) { *pairwise_cipher |= rtw_get_wpa_cipher_suite(pos); pos += WPA_SELECTOR_LEN; left -= WPA_SELECTOR_LEN; } } else if (left == 1) { RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)", __FUNCTION__)); return _FAIL; } return ret; }
/* * Notice: * Before calling this function, * precvframe->u.hdr.rx_data should be ready! */ void update_recvframe_phyinfo( union recv_frame *precvframe, struct phy_stat *pphy_status) { PADAPTER padapter= precvframe->u.hdr.adapter; struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); PODM_PHY_INFO_T pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info); u8 *wlanhdr; ODM_PACKET_INFO_T pkt_info; u8 *sa=NULL; //_irqL irqL; struct sta_priv *pstapriv; struct sta_info *psta; pkt_info.bPacketMatchBSSID =_FALSE; pkt_info.bPacketToSelf = _FALSE; pkt_info.bPacketBeacon = _FALSE; wlanhdr = get_recvframe_data(precvframe); pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && !pattrib->icv_err && !pattrib->crc_err && _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN)); pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_da(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN)); pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON); if(pkt_info.bPacketBeacon){ if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){ sa = padapter->mlmepriv.cur_network.network.MacAddress; #if 0 { DBG_8192C("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n", sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]); } #endif } //to do Ad-hoc } else{ sa = get_sa(wlanhdr); } pkt_info.StationID = 0xFF; pstapriv = &padapter->stapriv; psta = rtw_get_stainfo(pstapriv, sa); if (psta) { pkt_info.StationID = psta->mac_id; //DBG_8192C("%s ==> StationID(%d)\n",__FUNCTION__,pkt_info.StationID); } pkt_info.DataRate = pattrib->data_rate; //rtl8723b_query_rx_phy_status(precvframe, pphy_status); //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); ODM_PhyStatusQuery(&pHalData->odmpriv,pPHYInfo,(u8 *)pphy_status,&(pkt_info)); //_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); precvframe->u.hdr.psta = NULL; if (pkt_info.bPacketMatchBSSID && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)) { if (psta) { precvframe->u.hdr.psta = psta; rtl8723b_process_phy_info(padapter, precvframe); } } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE) { if (psta) { precvframe->u.hdr.psta = psta; } } rtl8723b_process_phy_info(padapter, precvframe); } }
u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid) { _irqL irqL; u8 status = _SUCCESS; u32 cur_time = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *pnetwork = &pmlmepriv->cur_network; _func_enter_; DBG_88E_LEVEL(_drv_info_, "set ssid [%s] fw_state=0x%08x\n", ssid->Ssid, get_fwstate(pmlmepriv)); if (padapter->hw_init_completed==false){ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("set_ssid: hw_init_completed==false=>exit!!!\n")); status = _FAIL; goto exit; } _enter_critical_bh(&pmlmepriv->lock, &irqL); DBG_88E("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv)); if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { goto handle_tkip_countermeasure; } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) { goto release_mlme_lock; } if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == true) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == true)) { if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state=0x%08x\n", get_fwstate(pmlmepriv))); if (rtw_is_same_ibss(padapter, pnetwork) == false) { /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */ rtw_disassoc_cmd(padapter, 0, true); if (check_fwstate(pmlmepriv, _FW_LINKED) == true) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } else { goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ } } else { rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1); } } else { RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n")); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength)); RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength)); rtw_disassoc_cmd(padapter, 0, true); if (check_fwstate(pmlmepriv, _FW_LINKED) == true) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter, 1); if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } } } handle_tkip_countermeasure: if (padapter->securitypriv.btkip_countermeasure == true) { cur_time = rtw_get_current_time(); if ( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ ) { padapter->securitypriv.btkip_countermeasure = false; padapter->securitypriv.btkip_countermeasure_time = 0; } else { status = _FAIL; goto release_mlme_lock; } } _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID)); pmlmepriv->assoc_by_bssid=false; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) { pmlmepriv->to_join = true; } else { status = rtw_do_join(padapter); } release_mlme_lock: _exit_critical_bh(&pmlmepriv->lock, &irqL); exit: RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("-rtw_set_802_11_ssid: status=%d\n", status)); _func_exit_; return status; }
int rtw_recv_indicatepkt(struct adapter *padapter, union recv_frame *precv_frame) { struct recv_priv *precvpriv; struct __queue *pfree_recv_queue; struct sk_buff *skb; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; void *br_port = NULL; _func_enter_; precvpriv = &(padapter->recvpriv); pfree_recv_queue = &(precvpriv->free_recv_queue); 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_, ("skb->head =%p skb->data =%p skb->tail =%p skb->end =%p skb->len =%d\n", skb->head, skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len)); if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { struct sk_buff *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); if (!_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)) { if (bmcast) { psta = rtw_get_bcmc_stainfo(padapter); pskb2 = skb_clone(skb, GFP_ATOMIC); } else { psta = rtw_get_stainfo(pstapriv, pattrib->dst); } if (psta) { struct net_device *pnetdev; pnetdev = (struct net_device *)padapter->pnetdev; 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; } } } #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)) */ skb->ip_summed = CHECKSUM_NONE; skb->dev = padapter->pnetdev; skb->protocol = eth_type_trans(skb, padapter->pnetdev); netif_rx(skb); _recv_indicatepkt_end: /* pointers to NULL before rtw_free_recvframe() */ precv_frame->u.hdr.pkt = NULL; rtw_free_recvframe(precv_frame, pfree_recv_queue); RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("\n rtw_recv_indicatepkt :after 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); _func_exit_; return _FAIL; }