net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / os_dep / linux / recv_linux.c
old mode 100755 (executable)
new mode 100644 (file)
index d4ce0fc..e37f014
@@ -183,8 +183,6 @@ int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf)
 
        precvbuf->pskb = NULL;
 
-       precvbuf->reuse = _FALSE;
-
        precvbuf->pallocated_buf  = precvbuf->pbuf = NULL;
 
        precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL;
@@ -233,9 +231,12 @@ int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf)
 
 
        if(precvbuf->pskb)
+       {
+#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
+               if(rtw_free_skb_premem(precvbuf->pskb)!=0)
+#endif
                rtw_skb_free(precvbuf->pskb);
-
-
+       }
        return ret;
 
 }
@@ -296,12 +297,18 @@ _pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8
        return sub_skb;
 }
 
+#ifdef DBG_UDP_PKT_LOSE_11AC
+#define PAYLOAD_LEN_LOC_OF_IP_HDR 0x10 /*ethernet payload length location of ip header (DA+SA+eth_type+(version&hdr_len)) */   
+#endif
+
 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) {
@@ -314,7 +321,7 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attri
 
                        //DBG_871X("bmcast=%d\n", bmcast);
 
-                       if(_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)==_FALSE)
+                       if (_rtw_memcmp(pattrib->dst, adapter_mac_addr(padapter), ETH_ALEN) == _FALSE)
                        {
                                //DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst);
 
@@ -342,7 +349,9 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attri
 
                                        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;
                                        }
                                }
@@ -350,6 +359,7 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attri
                        else// to APself
                        {
                                //DBG_871X("to APSelf\n");
+                               DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self);
                        }
                }
                
@@ -381,7 +391,25 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attri
                        }                                                       
                }
 #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;
 
@@ -395,11 +423,15 @@ void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attri
                pkt->ip_summed = CHECKSUM_NONE;
 #endif //CONFIG_TCP_CSUM_OFFLOAD_RX
 
-               rtw_netif_rx(padapter->pnetdev, pkt);
+               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_handle_tkip_mic_err(_adapter *padapter,u8 bgroup)
+void rtw_handle_tkip_mic_err(_adapter *padapter, struct sta_info *sta, u8 bgroup)
 {
 #ifdef CONFIG_IOCTL_CFG80211
        enum nl80211_key_type key_type = 0;
@@ -440,8 +472,7 @@ void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup)
                key_type |= NL80211_KEYTYPE_PAIRWISE;
        }
 
-       cfg80211_michael_mic_failure(padapter->pnetdev, (u8 *)&pmlmepriv->assoc_bssid[ 0 ], key_type, -1,
-               NULL, GFP_ATOMIC);
+       cfg80211_michael_mic_failure(padapter->pnetdev, sta->hwaddr, key_type, -1, NULL, GFP_ATOMIC);
 #endif
 
        _rtw_memset( &ev, 0x00, sizeof( ev ) );
@@ -455,7 +486,7 @@ void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup)
        }
 
        ev.src_addr.sa_family = ARPHRD_ETHER;
-       _rtw_memcpy( ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
+       _rtw_memcpy(ev.src_addr.sa_data, sta->hwaddr, ETH_ALEN);
 
        _rtw_memset( &wrqu, 0x00, sizeof( wrqu ) );
        wrqu.data.length = sizeof( ev );
@@ -604,10 +635,13 @@ int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
        _queue  *pfree_recv_queue;
        _pkt *skb;
        struct mlme_priv*pmlmepriv = &padapter->mlmepriv;
-       struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
-
-_func_enter_;
+       struct rx_pkt_attrib *pattrib;
+       
+       if(NULL == precv_frame)
+               goto _recv_indicatepkt_drop;
 
+       DBG_COUNTER(padapter->rx_logs.os_indicate);
+       pattrib = &precv_frame->u.hdr.attrib;
        precvpriv = &(padapter->recvpriv);
        pfree_recv_queue = &(precvpriv->free_recv_queue);
 
@@ -668,6 +702,52 @@ _func_enter_;
 #endif
 #endif //CONFIG_AUTO_AP_MODE
 
+       /* TODO: move to core */
+       {
+               _pkt *pkt = skb;
+               struct ethhdr *etherhdr = (struct ethhdr *)pkt->data;
+               struct sta_info *sta = precv_frame->u.hdr.psta;
+
+               if (!sta)
+                       goto bypass_session_tracker;
+
+               if (ntohs(etherhdr->h_proto) == ETH_P_IP) {
+                       u8 *ip = pkt->data + 14;
+
+                       if (GET_IPV4_PROTOCOL(ip) == 0x06  /* TCP */
+                               && rtw_st_ctl_chk_reg_s_proto(&sta->st_ctl, 0x06) == _TRUE
+                       ) {
+                               u8 *tcp = ip + GET_IPV4_IHL(ip) * 4;
+
+                               if (rtw_st_ctl_chk_reg_rule(&sta->st_ctl, padapter, IPV4_DST(ip), TCP_DST(tcp), IPV4_SRC(ip), TCP_SRC(tcp)) == _TRUE) {
+                                       if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) {
+                                               session_tracker_add_cmd(padapter, sta
+                                                       , IPV4_DST(ip), TCP_DST(tcp)
+                                                       , IPV4_SRC(ip), TCP_SRC(tcp));
+                                               if (DBG_SESSION_TRACKER)
+                                                       DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n"
+                                                               , FUNC_ADPT_ARG(padapter)
+                                                               , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp))
+                                                               , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp)));
+                                       }
+                                       if (GET_TCP_FIN(tcp)) {
+                                               session_tracker_del_cmd(padapter, sta
+                                                       , IPV4_DST(ip), TCP_DST(tcp)
+                                                       , IPV4_SRC(ip), TCP_SRC(tcp));
+                                               if (DBG_SESSION_TRACKER)
+                                                       DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n"
+                                                               , FUNC_ADPT_ARG(padapter)
+                                                               , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp))
+                                                               , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp)));
+                                       }
+                               }
+
+                       }
+               }
+bypass_session_tracker:
+               ;
+       }
+
        rtw_os_recv_indicate_pkt(padapter, skb, pattrib);
 
 _recv_indicatepkt_end:
@@ -678,7 +758,6 @@ _recv_indicatepkt_end:
 
        RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_os_recv_indicate_pkt!!!!\n"));
 
-_func_exit_;
 
         return _SUCCESS;
 
@@ -688,9 +767,9 @@ _recv_indicatepkt_drop:
         if(precv_frame)
                 rtw_free_recvframe(precv_frame, pfree_recv_queue);
 
-        return _FAIL;
+        DBG_COUNTER(padapter->rx_logs.os_indicate_err);
 
-_func_exit_;
+        return _FAIL;
 
 }
 
@@ -706,7 +785,6 @@ void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf)
        rtw_skb_free(precvbuf->pskb);
 
        precvbuf->pskb = NULL;
-       precvbuf->reuse = _FALSE;
 
        if(precvbuf->irp_pending == _FALSE)
        {