]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/staging/rt3070/common/netif_block.c
Merge branch 'omap-pool'
[linux-2.6-omap-h63xx.git] / drivers / staging / rt3070 / common / netif_block.c
diff --git a/drivers/staging/rt3070/common/netif_block.c b/drivers/staging/rt3070/common/netif_block.c
new file mode 100644 (file)
index 0000000..4773c11
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify  *
+ * it under the terms of the GNU General Public License as published by  *
+ * the Free Software Foundation; either version 2 of the License, or     *
+ * (at your option) any later version.                                   *
+ *                                                                       *
+ * This program is distributed in the hope that it will be useful,       *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ * GNU General Public License for more details.                          *
+ *                                                                       *
+ * You should have received a copy of the GNU General Public License     *
+ * along with this program; if not, write to the                         *
+ * Free Software Foundation, Inc.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#include "../rt_config.h"
+#include "netif_block.h"
+
+static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
+static LIST_HEADER freeNetIfEntryList;
+
+void initblockQueueTab(
+       IN PRTMP_ADAPTER pAd)
+{
+       int i;
+
+       initList(&freeNetIfEntryList);
+       for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
+               insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
+
+       for (i=0; i < NUM_OF_TX_RING; i++)
+               initList(&pAd->blockQueueTab[i].NetIfList);
+
+       return;
+}
+
+BOOLEAN blockNetIf(
+       IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+       IN PNET_DEV pNetDev)
+{
+       PNETIF_ENTRY pNetIfEntry = NULL;
+
+       if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
+       {
+               netif_stop_queue(pNetDev);
+               pNetIfEntry->pNetDev = pNetDev;
+               insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
+
+               pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
+               DBGPRINT(RT_DEBUG_TRACE, ("netif_stop_queue(%s)\n", pNetDev->name));
+       }
+       else
+               return FALSE;
+
+       return TRUE;
+}
+
+VOID releaseNetIf(
+       IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
+{
+       PNETIF_ENTRY pNetIfEntry = NULL;
+       PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
+
+       while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) !=  NULL)
+       {
+               PNET_DEV pNetDev = pNetIfEntry->pNetDev;
+               netif_wake_queue(pNetDev);
+               insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
+
+               DBGPRINT(RT_DEBUG_TRACE, ("netif_wake_queue(%s)\n", pNetDev->name));
+       }
+       pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
+       return;
+}
+
+
+VOID StopNetIfQueue(
+       IN PRTMP_ADAPTER pAd,
+       IN UCHAR QueIdx,
+       IN PNDIS_PACKET pPacket)
+{
+       PNET_DEV NetDev = NULL;
+       UCHAR IfIdx = 0;
+       BOOLEAN valid = FALSE;
+
+#ifdef WDS_SUPPORT
+       if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
+       {
+               IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
+               NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
+       }
+       else
+#endif // WDS_SUPPORT //
+       {
+#ifdef MBSS_SUPPORT
+               if (pAd->OpMode == OPMODE_AP)
+               {
+                       IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
+                       NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
+               }
+               else
+               {
+                       IfIdx = MAIN_MBSSID;
+                       NetDev = pAd->net_dev;
+               }
+#else
+               IfIdx = MAIN_MBSSID;
+               NetDev = pAd->net_dev;
+#endif
+       }
+
+       // WMM support 4 software queues.
+       // One software queue full doesn't mean device have no capbility to transmit packet.
+       // So disable block Net-If queue function while WMM enable.
+#ifdef CONFIG_STA_SUPPORT
+       IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+               valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
+#endif // CONFIG_STA_SUPPORT //
+
+       if (valid)
+               blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
+       return;
+}
+