OSDN Git Service

Remove semaphore wrappers
[android-x86/external-modules-rtl8723au.git] / os_dep / xmit_linux.c
index 208c786..af7cc73 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <if_ether.h>
 #include <ip.h>
-#include <rtw_byteorder.h>
 #include <wifi.h>
 #include <mlme_osdep.h>
 #include <xmit_osdep.h>
@@ -37,7 +36,7 @@ uint rtw_remainder_len(struct pkt_file *pfile)
        return (pfile->buf_len - ((SIZE_PTR)(pfile->cur_addr) - (SIZE_PTR)(pfile->buf_start)));
 }
 
-void _rtw_open_pktfile (struct sk_buff *pktptr, struct pkt_file *pfile)
+void _rtw_open_pktfile (_pkt *pktptr, struct pkt_file *pfile)
 {
 _func_enter_;
 
@@ -59,7 +58,7 @@ _func_enter_;
        len =  rtw_remainder_len(pfile);
        len = (rlen > len)? len: rlen;
 
-       if (rmem)
+       if(rmem)
          skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len, rmem, len);
 
        pfile->cur_addr += len;
@@ -76,15 +75,15 @@ _func_enter_;
 
        if (pfile->pkt_len == 0) {
 _func_exit_;
-               return true;
+               return _TRUE;
        }
 
 _func_exit_;
 
-       return false;
+       return _FALSE;
 }
 
-void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib)
+void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib)
 {
 
 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
@@ -97,11 +96,11 @@ void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib)
                         const struct iphdr *ip = ip_hdr(skb);
                         if (ip->protocol == IPPROTO_TCP) {
                                 // TCP checksum offload by HW
-                                DBG_871X("CHECKSUM_PARTIAL TCP\n");
+                                DBG_8723A("CHECKSUM_PARTIAL TCP\n");
                                 pattrib->hw_tcp_csum = 1;
                                 //skb_checksum_help(skb);
                         } else if (ip->protocol == IPPROTO_UDP) {
-                                //DBG_871X("CHECKSUM_PARTIAL UDP\n");
+                                //DBG_8723A("CHECKSUM_PARTIAL UDP\n");
 #if 1
                                 skb_checksum_help(skb);
 #else
@@ -110,12 +109,12 @@ void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib)
                                 udp->check = 0;
 #endif
                         } else {
-                               DBG_871X("%s-%d TCP CSUM offload Error!!\n", __func__, __LINE__);
+                               DBG_8723A("%s-%d TCP CSUM offload Error!!\n", __FUNCTION__, __LINE__);
                                 WARN_ON(1);     /* we need a WARN() */
                            }
                }
                else { // IP fragmentation case
-                       DBG_871X("%s-%d nr_frags != 0, using skb_checksum_help(skb);!!\n", __func__, __LINE__);
+                       DBG_8723A("%s-%d nr_frags != 0, using skb_checksum_help(skb);!!\n", __FUNCTION__, __LINE__);
                        skb_checksum_help(skb);
                }
        }
@@ -125,6 +124,7 @@ void rtw_set_tx_chksum_offload(struct sk_buff *pkt, struct pkt_attrib *pattrib)
 
 int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 alloc_sz)
 {
+#ifdef CONFIG_USB_HCI
        int i;
        struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
        struct usb_device       *pusbd = pdvobjpriv->pusbdev;
@@ -132,13 +132,12 @@ int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32
 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
        pxmitbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)alloc_sz, &pxmitbuf->dma_transfer_addr);
        pxmitbuf->pbuf = pxmitbuf->pallocated_buf;
-       if (pxmitbuf->pallocated_buf == NULL)
+       if(pxmitbuf->pallocated_buf == NULL)
                return _FAIL;
 #else // CONFIG_USE_USB_BUFFER_ALLOC_TX
 
-       pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz);
-       if (pxmitbuf->pallocated_buf == NULL)
-       {
+       pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL);
+       if (pxmitbuf->pallocated_buf == NULL) {
                return _FAIL;
        }
 
@@ -147,29 +146,40 @@ int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32
 
 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
 
-       for (i=0; i<8; i++)
+       for(i=0; i<8; i++)
        {
                pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
-               if (pxmitbuf->pxmit_urb[i] == NULL)
+               if(pxmitbuf->pxmit_urb[i] == NULL)
                {
-                       DBG_871X("pxmitbuf->pxmit_urb[i]==NULL");
+                       DBG_8723A("pxmitbuf->pxmit_urb[i]==NULL");
                        return _FAIL;
                }
 
        }
+#endif
+#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+       pxmitbuf->pallocated_buf = kzalloc(alloc_sz);
+       if (pxmitbuf->pallocated_buf == NULL) {
+               return _FAIL;
+       }
+
+       pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
+#endif
+
        return _SUCCESS;
 }
 
 void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 free_sz)
 {
+#ifdef CONFIG_USB_HCI
        int i;
        struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
        struct usb_device       *pusbd = pdvobjpriv->pusbdev;
 
 
-       for (i=0; i<8; i++)
+       for(i=0; i<8; i++)
        {
-               if (pxmitbuf->pxmit_urb[i])
+               if(pxmitbuf->pxmit_urb[i])
                {
                        //usb_kill_urb(pxmitbuf->pxmit_urb[i]);
                        usb_free_urb(pxmitbuf->pxmit_urb[i]);
@@ -181,14 +191,20 @@ void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32
        pxmitbuf->pallocated_buf =  NULL;
        pxmitbuf->dma_transfer_addr = 0;
 #else  // CONFIG_USE_USB_BUFFER_ALLOC_TX
-       if (pxmitbuf->pallocated_buf)
-               rtw_mfree(pxmitbuf->pallocated_buf, free_sz);
+       if(pxmitbuf->pallocated_buf)
+               kfree(pxmitbuf->pallocated_buf);
 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
+
+#endif
+#if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+       if(pxmitbuf->pallocated_buf)
+               kfree(pxmitbuf->pallocated_buf);
+#endif
 }
 
 #define WMM_XMIT_THRESHOLD     (NR_XMITFRAME*2/5)
 
-void rtw_os_pkt_complete(_adapter *padapter, struct sk_buff *pkt)
+void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt)
 {
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
        u16     queue;
@@ -196,13 +212,13 @@ void rtw_os_pkt_complete(_adapter *padapter, struct sk_buff *pkt)
 
        queue = skb_get_queue_mapping(pkt);
        if (padapter->registrypriv.wifi_spec) {
-               if (__netif_subqueue_stopped(padapter->pnetdev, queue) &&
+               if(__netif_subqueue_stopped(padapter->pnetdev, queue) &&
                        (pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD))
                {
                        netif_wake_subqueue(padapter->pnetdev, queue);
                }
        } else {
-               if (__netif_subqueue_stopped(padapter->pnetdev, queue))
+               if(__netif_subqueue_stopped(padapter->pnetdev, queue))
                        netif_wake_subqueue(padapter->pnetdev, queue);
        }
 #else
@@ -215,9 +231,15 @@ void rtw_os_pkt_complete(_adapter *padapter, struct sk_buff *pkt)
 
 void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe)
 {
-       if (pxframe->pkt)
+       if(pxframe->pkt)
+       {
+               //RT_TRACE(_module_xmit_osdep_c_,_drv_err_,("linux : rtw_os_xmit_complete, dev_kfree_skb()\n"));
+
+               //dev_kfree_skb_any(pxframe->pkt);
                rtw_os_pkt_complete(padapter, pxframe->pkt);
 
+       }
+
        pxframe->pkt = NULL;
 }
 
@@ -225,23 +247,40 @@ void rtw_os_xmit_schedule(_adapter *padapter)
 {
        _adapter *pri_adapter = padapter;
 
-       unsigned long  irqL;
+#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+       if(!padapter)
+               return;
+
+#ifdef CONFIG_CONCURRENT_MODE
+       if(padapter->adapter_type > PRIMARY_ADAPTER)
+               pri_adapter = padapter->pbuddy_adapter;
+#endif
+
+       if (_rtw_queue_empty(&pri_adapter->xmitpriv.pending_xmitbuf_queue) == _FALSE)
+               up(&pri_adapter->xmitpriv.xmit_sema);
+
+
+#else
+       _irqL  irqL;
        struct xmit_priv *pxmitpriv;
 
-       if (!padapter)
+       if(!padapter)
                return;
 
        pxmitpriv = &padapter->xmitpriv;
 
-       _enter_critical_bh(&pxmitpriv->lock, &irqL);
+       spin_lock_bh(&pxmitpriv->lock);
 
-       if (rtw_txframes_pending(padapter))
+       if(rtw_txframes_pending(padapter))
+       {
                tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+       }
 
-       _exit_critical_bh(&pxmitpriv->lock, &irqL);
+       spin_unlock_bh(&pxmitpriv->lock);
+#endif
 }
 
-static void rtw_check_xmit_resource(_adapter *padapter, struct sk_buff *pkt)
+static void rtw_check_xmit_resource(_adapter *padapter, _pkt *pkt)
 {
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
@@ -251,17 +290,17 @@ static void rtw_check_xmit_resource(_adapter *padapter, struct sk_buff *pkt)
        if (padapter->registrypriv.wifi_spec) {
                /* No free space for Tx, tx_worker is too slow */
                if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD) {
-                       //DBG_871X("%s(): stop netif_subqueue[%d]\n", __func__, queue);
+                       //DBG_8723A("%s(): stop netif_subqueue[%d]\n", __FUNCTION__, queue);
                        netif_stop_subqueue(padapter->pnetdev, queue);
                }
        } else {
-               if (pxmitpriv->free_xmitframe_cnt<=4) {
+               if(pxmitpriv->free_xmitframe_cnt<=4) {
                        if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue)))
                                netif_stop_subqueue(padapter->pnetdev, queue);
                }
        }
 #else
-       if (pxmitpriv->free_xmitframe_cnt<=4)
+       if(pxmitpriv->free_xmitframe_cnt<=4)
        {
                if (!rtw_netif_queue_stopped(padapter->pnetdev))
                        rtw_netif_stop_queue(padapter->pnetdev);
@@ -274,25 +313,44 @@ int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb)
 {
        struct  sta_priv *pstapriv = &padapter->stapriv;
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-       unsigned long   irqL;
+       _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);
+       spin_lock_bh(&pstapriv->asoc_list_lock);
        phead = &pstapriv->asoc_list;
        plist = get_next(phead);
 
        //free sta asoc_queue
-       while ((rtw_end_of_queue_search(phead, plist)) == false)
-       {
+       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);
 
-               /* avoid   come from STA1 and send back STA1 */
-               if (!memcmp(psta->hwaddr, &skb->data[6], 6))
+               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);
+
+       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 (!memcmp(psta->hwaddr, &skb->data[6], 6) ||
+                   !memcmp(psta->hwaddr, null_addr, 6) ||
+                   !memcmp(psta->hwaddr, bc_addr, 6))
                        continue;
 
                newskb = skb_copy(skb, GFP_ATOMIC);
@@ -301,29 +359,26 @@ int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb)
                        memcpy(newskb->data, psta->hwaddr, 6);
                        res = rtw_xmit(padapter, &newskb);
                        if (res < 0) {
-                               DBG_871X("%s()-%d: rtw_xmit() return error!\n", __func__, __LINE__);
+                               DBG_8723A("%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", __func__, __LINE__);
+                       DBG_8723A("%s-%d: skb_copy() failed!\n", __FUNCTION__, __LINE__);
                        pxmitpriv->tx_drop++;
-
-                       _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
                        //dev_kfree_skb_any(skb);
-                       return false;   // Caller shall tx this multicast frame via normal way.
+                       return _FALSE;  // Caller shall tx this multicast frame via normal way.
                }
        }
 
-       _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
        dev_kfree_skb_any(skb);
-       return true;
+       return _TRUE;
 }
 #endif // CONFIG_TX_MCAST2UNI
 
 
-int rtw_xmit_entry(struct sk_buff *pkt, struct net_device *pnetdev)
+int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev)
 {
        _adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
@@ -340,10 +395,10 @@ _func_enter_;
 
        RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("+xmit_enry\n"));
 
-       if (rtw_if_up(padapter) == false) {
+       if (rtw_if_up(padapter) == _FALSE) {
                RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit_entry: rtw_if_up fail\n"));
                #ifdef DBG_TX_DROP_FRAME
-               DBG_871X("DBG_TX_DROP_FRAME %s if_up fail\n", __func__);
+               DBG_8723A("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__);
                #endif
                goto drop_packet;
        }
@@ -351,14 +406,21 @@ _func_enter_;
        rtw_check_xmit_resource(padapter, pkt);
 
 #ifdef CONFIG_TX_MCAST2UNI
-       if (!rtw_mc2u_disable &&
-           check_fwstate(pmlmepriv, WIFI_AP_STATE) == true &&
-           (IP_MCAST_MAC(pkt->data) ||
-           ICMPV6_MCAST_MAC(pkt->data))) {
-               if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME / 4)) {
+       if ( !rtw_mc2u_disable
+               && check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE
+               && ( IP_MCAST_MAC(pkt->data)
+                       || ICMPV6_MCAST_MAC(pkt->data) )
+               && (padapter->registrypriv.wifi_spec == 0)
+                )
+       {
+               if ( pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME/4) ) {
                        res = rtw_mlcst2unicst(padapter, pkt);
-                       if (res == true)
+                       if (res == _TRUE) {
                                goto exit;
+                       }
+               } else {
+                       //DBG_8723A("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt);
+                       //DBG_8723A("!m2u );
                }
        }
 #endif // CONFIG_TX_MCAST2UNI
@@ -366,7 +428,7 @@ _func_enter_;
        res = rtw_xmit(padapter, &pkt);
        if (res < 0) {
                #ifdef DBG_TX_DROP_FRAME
-               DBG_871X("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __func__);
+               DBG_8723A("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__);
                #endif
                goto drop_packet;
        }