x86, mce: Clean up thermal init by introducing intel_thermal_supported()
[sfrench/cifs-2.6.git] / drivers / staging / rt2860 / common / 2860_rtmp_init.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         2860_rtmp_init.c
29
30         Abstract:
31         Miniport generic portion header file
32
33         Revision History:
34         Who         When          What
35         --------    ----------    ----------------------------------------------
36         Paul Lin    2002-08-01    created
37     John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
38     Jan Lee  2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
39 */
40 #include "../rt_config.h"
41
42
43
44
45 /*
46         ========================================================================
47
48         Routine Description:
49                 Allocate DMA memory blocks for send, receive
50
51         Arguments:
52                 Adapter         Pointer to our adapter
53
54         Return Value:
55                 NDIS_STATUS_SUCCESS
56                 NDIS_STATUS_FAILURE
57                 NDIS_STATUS_RESOURCES
58
59         IRQL = PASSIVE_LEVEL
60
61         Note:
62
63         ========================================================================
64 */
65 NDIS_STATUS     RTMPAllocTxRxRingMemory(
66         IN      PRTMP_ADAPTER   pAd)
67 {
68         NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;
69         ULONG                   RingBasePaHigh;
70         ULONG                   RingBasePaLow;
71         PVOID                   RingBaseVa;
72         INT                             index, num;
73         PTXD_STRUC              pTxD;
74         PRXD_STRUC              pRxD;
75         ULONG                   ErrorValue = 0;
76         PRTMP_TX_RING   pTxRing;
77         PRTMP_DMABUF    pDmaBuf;
78         PNDIS_PACKET    pPacket;
79
80         DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
81         do
82         {
83                 //
84                 // Allocate all ring descriptors, include TxD, RxD, MgmtD.
85                 // Although each size is different, to prevent cacheline and alignment
86                 // issue, I intentional set them all to 64 bytes.
87                 //
88                 for (num=0; num<NUM_OF_TX_RING; num++)
89                 {
90                         ULONG  BufBasePaHigh;
91                         ULONG  BufBasePaLow;
92                         PVOID  BufBaseVa;
93
94                         //
95                         // Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
96                         //
97                         pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
98                         RTMP_AllocateTxDescMemory(
99                                 pAd,
100                                 num,
101                                 pAd->TxDescRing[num].AllocSize,
102                                 FALSE,
103                                 &pAd->TxDescRing[num].AllocVa,
104                                 &pAd->TxDescRing[num].AllocPa);
105
106                         if (pAd->TxDescRing[num].AllocVa == NULL)
107                         {
108                                 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
109                                 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
110                                 Status = NDIS_STATUS_RESOURCES;
111                                 break;
112                         }
113
114                         // Zero init this memory block
115                         NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
116
117                         // Save PA & VA for further operation
118                         RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
119                         RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
120                         RingBaseVa     = pAd->TxDescRing[num].AllocVa;
121
122                         //
123                         // Allocate all 1st TXBuf's memory for this TxRing
124                         //
125                         pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
126                         RTMP_AllocateFirstTxBuffer(
127                                 pAd,
128                                 num,
129                                 pAd->TxBufSpace[num].AllocSize,
130                                 FALSE,
131                                 &pAd->TxBufSpace[num].AllocVa,
132                                 &pAd->TxBufSpace[num].AllocPa);
133
134                         if (pAd->TxBufSpace[num].AllocVa == NULL)
135                         {
136                                 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
137                                 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
138                                 Status = NDIS_STATUS_RESOURCES;
139                                 break;
140                         }
141
142                         // Zero init this memory block
143                         NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
144
145                         // Save PA & VA for further operation
146                         BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
147                         BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
148                         BufBaseVa     = pAd->TxBufSpace[num].AllocVa;
149
150                         //
151                         // Initialize Tx Ring Descriptor and associated buffer memory
152                         //
153                         pTxRing = &pAd->TxRing[num];
154                         for (index = 0; index < TX_RING_SIZE; index++)
155                         {
156                                 pTxRing->Cell[index].pNdisPacket = NULL;
157                                 pTxRing->Cell[index].pNextNdisPacket = NULL;
158                                 // Init Tx Ring Size, Va, Pa variables
159                                 pTxRing->Cell[index].AllocSize = TXD_SIZE;
160                                 pTxRing->Cell[index].AllocVa = RingBaseVa;
161                                 RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
162                                 RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
163
164                                 // Setup Tx Buffer size & address. only 802.11 header will store in this space
165                                 pDmaBuf = &pTxRing->Cell[index].DmaBuf;
166                                 pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
167                                 pDmaBuf->AllocVa = BufBaseVa;
168                                 RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
169                                 RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
170
171                                 // link the pre-allocated TxBuf to TXD
172                                 pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
173                                 pTxD->SDPtr0 = BufBasePaLow;
174                                 // advance to next ring descriptor address
175                                 pTxD->DMADONE = 1;
176                                 RingBasePaLow += TXD_SIZE;
177                                 RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
178
179                                 // advance to next TxBuf address
180                                 BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
181                                 BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
182                         }
183                         DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
184                 }
185                 if (Status == NDIS_STATUS_RESOURCES)
186                         break;
187
188                 //
189                 // Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
190                 //
191                 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
192                 RTMP_AllocateMgmtDescMemory(
193                         pAd,
194                         pAd->MgmtDescRing.AllocSize,
195                         FALSE,
196                         &pAd->MgmtDescRing.AllocVa,
197                         &pAd->MgmtDescRing.AllocPa);
198
199                 if (pAd->MgmtDescRing.AllocVa == NULL)
200                 {
201                         ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
202                         DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
203                         Status = NDIS_STATUS_RESOURCES;
204                         break;
205                 }
206
207                 // Zero init this memory block
208                 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
209
210                 // Save PA & VA for further operation
211                 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
212                 RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
213                 RingBaseVa     = pAd->MgmtDescRing.AllocVa;
214
215                 //
216                 // Initialize MGMT Ring and associated buffer memory
217                 //
218                 for (index = 0; index < MGMT_RING_SIZE; index++)
219                 {
220                         pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
221                         pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
222                         // Init MGMT Ring Size, Va, Pa variables
223                         pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
224                         pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
225                         RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
226                         RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
227
228                         // Offset to next ring descriptor address
229                         RingBasePaLow += TXD_SIZE;
230                         RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
231
232                         // link the pre-allocated TxBuf to TXD
233                         pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
234                         pTxD->DMADONE = 1;
235
236                         // no pre-allocated buffer required in MgmtRing for scatter-gather case
237                 }
238                 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
239
240                 //
241                 // Allocate RX ring descriptor's memory except Tx ring which allocated eariler
242                 //
243                 pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
244                 RTMP_AllocateRxDescMemory(
245                         pAd,
246                         pAd->RxDescRing.AllocSize,
247                         FALSE,
248                         &pAd->RxDescRing.AllocVa,
249                         &pAd->RxDescRing.AllocPa);
250
251                 if (pAd->RxDescRing.AllocVa == NULL)
252                 {
253                         ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
254                         DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
255                         Status = NDIS_STATUS_RESOURCES;
256                         break;
257                 }
258
259                 // Zero init this memory block
260                 NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
261
262
263                 printk("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa,
264                                         pAd->RxDescRing.AllocSize);
265
266                 // Save PA & VA for further operation
267                 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
268                 RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
269                 RingBaseVa     = pAd->RxDescRing.AllocVa;
270
271                 //
272                 // Initialize Rx Ring and associated buffer memory
273                 //
274                 for (index = 0; index < RX_RING_SIZE; index++)
275                 {
276                         // Init RX Ring Size, Va, Pa variables
277                         pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
278                         pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
279                         RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
280                         RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
281
282                         // Offset to next ring descriptor address
283                         RingBasePaLow += RXD_SIZE;
284                         RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
285
286                         // Setup Rx associated Buffer size & allocate share memory
287                         pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
288                         pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
289                         pPacket = RTMP_AllocateRxPacketBuffer(
290                                 pAd,
291                                 pDmaBuf->AllocSize,
292                                 FALSE,
293                                 &pDmaBuf->AllocVa,
294                                 &pDmaBuf->AllocPa);
295
296                         /* keep allocated rx packet */
297                         pAd->RxRing.Cell[index].pNdisPacket = pPacket;
298
299                         // Error handling
300                         if (pDmaBuf->AllocVa == NULL)
301                         {
302                                 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
303                                 DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
304                                 Status = NDIS_STATUS_RESOURCES;
305                                 break;
306                         }
307
308                         // Zero init this memory block
309                         NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
310
311                         // Write RxD buffer address & allocated buffer length
312                         pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
313                         pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
314                         pRxD->DDONE = 0;
315                 }
316
317                 DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
318
319         }       while (FALSE);
320
321
322         NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
323         pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
324
325         if (pAd->FragFrame.pFragPacket == NULL)
326         {
327                 Status = NDIS_STATUS_RESOURCES;
328         }
329
330         if (Status != NDIS_STATUS_SUCCESS)
331         {
332                 // Log error inforamtion
333                 NdisWriteErrorLogEntry(
334                         pAd->AdapterHandle,
335                         NDIS_ERROR_CODE_OUT_OF_RESOURCES,
336                         1,
337                         ErrorValue);
338         }
339
340         DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
341         return Status;
342 }
343
344
345 /*
346         ========================================================================
347
348         Routine Description:
349                 Initialize transmit data structures
350
351         Arguments:
352                 Adapter                                         Pointer to our adapter
353
354         Return Value:
355                 None
356
357         IRQL = PASSIVE_LEVEL
358
359         Note:
360                 Initialize all transmit releated private buffer, include those define
361                 in RTMP_ADAPTER structure and all private data structures.
362
363         ========================================================================
364 */
365 VOID    NICInitTxRxRingAndBacklogQueue(
366         IN      PRTMP_ADAPTER   pAd)
367 {
368         //WPDMA_GLO_CFG_STRUC   GloCfg;
369         int i;
370
371         DBGPRINT(RT_DEBUG_TRACE, ("<--> NICInitTxRxRingAndBacklogQueue\n"));
372
373         // Initialize all transmit related software queues
374         InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BE]);
375         InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BK]);
376         InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VI]);
377         InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VO]);
378         InitializeQueueHeader(&pAd->TxSwQueue[QID_HCCA]);
379
380         // Init RX Ring index pointer
381         pAd->RxRing.RxSwReadIdx = 0;
382         pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
383
384         // Init TX rings index pointer
385                 for (i=0; i<NUM_OF_TX_RING; i++)
386                 {
387                         pAd->TxRing[i].TxSwFreeIdx = 0;
388                         pAd->TxRing[i].TxCpuIdx = 0;
389                 }
390
391         // init MGMT ring index pointer
392         pAd->MgmtRing.TxSwFreeIdx = 0;
393         pAd->MgmtRing.TxCpuIdx = 0;
394
395         pAd->PrivateInfo.TxRingFullCnt       = 0;
396 }
397
398
399 /*
400         ========================================================================
401
402         Routine Description:
403                 Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
404
405         Arguments:
406                 Adapter                                         Pointer to our adapter
407
408         Return Value:
409                 None
410
411         IRQL = PASSIVE_LEVEL
412         IRQL = DISPATCH_LEVEL
413
414         Note:
415                 Reset NIC to initial state AS IS system boot up time.
416
417         ========================================================================
418 */
419 VOID    RTMPRingCleanUp(
420         IN      PRTMP_ADAPTER   pAd,
421         IN      UCHAR                   RingType)
422 {
423         PTXD_STRUC              pTxD;
424         PRXD_STRUC              pRxD;
425         PQUEUE_ENTRY    pEntry;
426         PNDIS_PACKET    pPacket;
427         int                             i;
428         PRTMP_TX_RING   pTxRing;
429         unsigned long   IrqFlags;
430
431         DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
432         switch (RingType)
433         {
434                 case QID_AC_BK:
435                 case QID_AC_BE:
436                 case QID_AC_VI:
437                 case QID_AC_VO:
438                 case QID_HCCA:
439                         RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
440                         pTxRing = &pAd->TxRing[RingType];
441
442                         // We have to clean all descriptors in case some error happened with reset
443                         for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
444                         {
445                                 pTxD  = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
446
447                                 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
448                                 // release scatter-and-gather NDIS_PACKET
449                                 if (pPacket)
450                                 {
451                                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
452                                         pTxRing->Cell[i].pNdisPacket = NULL;
453                                 }
454
455                                 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
456                                 // release scatter-and-gather NDIS_PACKET
457                                 if (pPacket)
458                                 {
459                                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
460                                         pTxRing->Cell[i].pNextNdisPacket = NULL;
461                                 }
462                         }
463
464                         RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
465                         pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
466                         pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
467                         RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
468
469                         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
470                         RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
471                         while (pAd->TxSwQueue[RingType].Head != NULL)
472                         {
473                                 pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
474                                 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
475                                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
476                                 DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
477                         }
478                         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
479                         break;
480
481                 case QID_MGMT:
482                         // We have to clean all descriptors in case some error happened with reset
483                         NdisAcquireSpinLock(&pAd->MgmtRingLock);
484
485                         for (i=0; i<MGMT_RING_SIZE; i++)
486                         {
487                                 pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
488
489                                 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
490                                 // rlease scatter-and-gather NDIS_PACKET
491                                 if (pPacket)
492                                 {
493                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
494                                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
495                                 }
496                                 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
497
498                                 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
499                                 // release scatter-and-gather NDIS_PACKET
500                                 if (pPacket)
501                                 {
502                                         PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
503                                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
504                                 }
505                                 pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
506
507                         }
508
509                         RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
510                         pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
511                         pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
512                         RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
513
514                         NdisReleaseSpinLock(&pAd->MgmtRingLock);
515                         pAd->RalinkCounters.MgmtRingFullCount = 0;
516                         break;
517
518                 case QID_RX:
519                         // We have to clean all descriptors in case some error happened with reset
520                         NdisAcquireSpinLock(&pAd->RxRingLock);
521
522                         for (i=0; i<RX_RING_SIZE; i++)
523                         {
524                                 pRxD  = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
525                                 pRxD->DDONE = 0 ;
526                         }
527
528                         RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
529                         pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
530                         pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
531                         RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
532
533                         NdisReleaseSpinLock(&pAd->RxRingLock);
534                         break;
535
536                 default:
537                         break;
538         }
539 }
540
541
542 NDIS_STATUS AdapterBlockAllocateMemory(
543         IN PVOID        handle,
544         OUT     PVOID   *ppAd)
545 {
546         PPCI_DEV pci_dev;
547         dma_addr_t      *phy_addr;
548         POS_COOKIE pObj = (POS_COOKIE) handle;
549
550         pci_dev = pObj->pci_dev;
551         phy_addr = &pObj->pAd_pa;
552
553         *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
554
555         if (*ppAd)
556         {
557                 NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
558                 ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
559                 return (NDIS_STATUS_SUCCESS);
560         } else {
561                 return (NDIS_STATUS_FAILURE);
562         }
563 }
564
565
566 void RTMP_AllocateTxDescMemory(
567         IN      PRTMP_ADAPTER pAd,
568         IN      UINT    Index,
569         IN      ULONG   Length,
570         IN      BOOLEAN Cached,
571         OUT     PVOID   *VirtualAddress,
572         OUT     PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
573 {
574         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
575
576         *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
577
578 }
579
580 void RTMP_AllocateMgmtDescMemory(
581         IN      PRTMP_ADAPTER pAd,
582         IN      ULONG   Length,
583         IN      BOOLEAN Cached,
584         OUT     PVOID   *VirtualAddress,
585         OUT     PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
586 {
587         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
588
589         *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
590
591 }
592
593 void RTMP_AllocateRxDescMemory(
594         IN      PRTMP_ADAPTER pAd,
595         IN      ULONG   Length,
596         IN      BOOLEAN Cached,
597         OUT     PVOID   *VirtualAddress,
598         OUT     PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
599 {
600         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
601
602         *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
603
604 }
605
606 void RTMP_FreeRxDescMemory(
607         IN      PRTMP_ADAPTER pAd,
608         IN      ULONG   Length,
609         IN      PVOID   VirtualAddress,
610         IN      NDIS_PHYSICAL_ADDRESS PhysicalAddress)
611 {
612         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
613
614         PCI_FREE_CONSISTENT(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
615 }
616
617
618 void RTMP_AllocateFirstTxBuffer(
619         IN      PRTMP_ADAPTER pAd,
620         IN      UINT    Index,
621         IN      ULONG   Length,
622         IN      BOOLEAN Cached,
623         OUT     PVOID   *VirtualAddress,
624         OUT     PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
625 {
626         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
627
628         *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
629 }
630
631 /*
632  * FUNCTION: Allocate a common buffer for DMA
633  * ARGUMENTS:
634  *     AdapterHandle:  AdapterHandle
635  *     Length:  Number of bytes to allocate
636  *     Cached:  Whether or not the memory can be cached
637  *     VirtualAddress:  Pointer to memory is returned here
638  *     PhysicalAddress:  Physical address corresponding to virtual address
639  */
640
641 void RTMP_AllocateSharedMemory(
642         IN      PRTMP_ADAPTER pAd,
643         IN      ULONG   Length,
644         IN      BOOLEAN Cached,
645         OUT     PVOID   *VirtualAddress,
646         OUT     PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
647 {
648         POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
649
650         *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
651 }
652
653 VOID RTMPFreeTxRxRingMemory(
654     IN  PRTMP_ADAPTER   pAd)
655 {
656         int index, num , j;
657         PRTMP_TX_RING pTxRing;
658         PTXD_STRUC        pTxD;
659         PNDIS_PACKET  pPacket;
660         unsigned int  IrqFlags;
661
662         POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
663
664         DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
665
666         // Free TxSwQueue Packet
667         for (index=0; index <NUM_OF_TX_RING; index++)
668         {
669                 PQUEUE_ENTRY pEntry;
670                 PNDIS_PACKET pPacket;
671                 PQUEUE_HEADER   pQueue;
672
673                 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
674                 pQueue = &pAd->TxSwQueue[index];
675                 while (pQueue->Head)
676                 {
677                         pEntry = RemoveHeadQueue(pQueue);
678                         pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
679                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
680                 }
681                 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
682         }
683
684         // Free Tx Ring Packet
685         for (index=0;index< NUM_OF_TX_RING;index++)
686         {
687                 pTxRing = &pAd->TxRing[index];
688
689                 for (j=0; j< TX_RING_SIZE; j++)
690                 {
691                         pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
692                         pPacket = pTxRing->Cell[j].pNdisPacket;
693
694                         if (pPacket)
695                         {
696                 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
697                                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
698                         }
699                         //Always assign pNdisPacket as NULL after clear
700                         pTxRing->Cell[j].pNdisPacket = NULL;
701
702                         pPacket = pTxRing->Cell[j].pNextNdisPacket;
703
704                         if (pPacket)
705                         {
706                 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
707                                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
708                         }
709                         //Always assign pNextNdisPacket as NULL after clear
710                         pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
711
712                 }
713         }
714
715         for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
716         {
717                 if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
718                 {
719                         PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
720                         RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
721                 }
722         }
723         NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
724
725         if (pAd->RxDescRing.AllocVa)
726     {
727         PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
728     }
729     NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
730
731         if (pAd->MgmtDescRing.AllocVa)
732         {
733                 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
734         }
735         NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
736
737         for (num = 0; num < NUM_OF_TX_RING; num++)
738         {
739         if (pAd->TxBufSpace[num].AllocVa)
740             {
741                 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxBufSpace[num].AllocSize, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
742             }
743             NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
744
745         if (pAd->TxDescRing[num].AllocVa)
746             {
747                 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
748             }
749             NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
750         }
751
752         if (pAd->FragFrame.pFragPacket)
753                 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
754
755         DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
756 }
757
758
759 /*
760  * FUNCTION: Allocate a packet buffer for DMA
761  * ARGUMENTS:
762  *     AdapterHandle:  AdapterHandle
763  *     Length:  Number of bytes to allocate
764  *     Cached:  Whether or not the memory can be cached
765  *     VirtualAddress:  Pointer to memory is returned here
766  *     PhysicalAddress:  Physical address corresponding to virtual address
767  * Notes:
768  *     Cached is ignored: always cached memory
769  */
770 PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
771         IN      PRTMP_ADAPTER pAd,
772         IN      ULONG   Length,
773         IN      BOOLEAN Cached,
774         OUT     PVOID   *VirtualAddress,
775         OUT     PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
776 {
777         PNDIS_PACKET pkt;
778
779         pkt = RTPKT_TO_OSPKT(DEV_ALLOC_SKB(Length));
780
781         if (pkt == NULL) {
782                 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
783         }
784
785         if (pkt) {
786                 RTMP_SET_PACKET_SOURCE(pkt, PKTSRC_NDIS);
787                 *VirtualAddress = (PVOID) RTPKT_TO_OSPKT(pkt)->data;
788                 *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE);
789         } else {
790                 *VirtualAddress = (PVOID) NULL;
791                 *PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
792         }
793
794         return (PNDIS_PACKET) pkt;
795 }
796
797
798 VOID Invalid_Remaining_Packet(
799         IN      PRTMP_ADAPTER pAd,
800         IN       ULONG VirtualAddress)
801 {
802         NDIS_PHYSICAL_ADDRESS PhysicalAddress;
803
804         PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
805 }
806
807 PNDIS_PACKET GetPacketFromRxRing(
808         IN              PRTMP_ADAPTER   pAd,
809         OUT             PRT28XX_RXD_STRUC       pSaveRxD,
810         OUT             BOOLEAN                 *pbReschedule,
811         IN OUT  UINT32                  *pRxPending)
812 {
813         PRXD_STRUC                              pRxD;
814         PNDIS_PACKET                    pRxPacket = NULL;
815         PNDIS_PACKET                    pNewPacket;
816         PVOID                                   AllocVa;
817         NDIS_PHYSICAL_ADDRESS   AllocPa;
818         BOOLEAN                                 bReschedule = FALSE;
819
820         RTMP_SEM_LOCK(&pAd->RxRingLock);
821
822         if (*pRxPending == 0)
823         {
824                 // Get how may packets had been received
825                 RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
826
827                 if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
828                 {
829                         // no more rx packets
830                         bReschedule = FALSE;
831                         goto done;
832                 }
833
834                 // get rx pending count
835                 if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
836                         *pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
837                 else
838                         *pRxPending     = pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
839
840         }
841
842         // Point to Rx indexed rx ring descriptor
843         pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
844
845         if (pRxD->DDONE == 0)
846         {
847                 *pRxPending = 0;
848                 // DMAIndx had done but DDONE bit not ready
849                 bReschedule = TRUE;
850                 goto done;
851         }
852
853
854         // return rx descriptor
855         NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
856
857         pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
858
859         if (pNewPacket)
860         {
861                 // unmap the rx buffer
862                 PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
863                                          pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
864                 pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
865
866                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize      = RX_BUFFER_AGGRESIZE;
867                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket           = (PNDIS_PACKET) pNewPacket;
868                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa        = AllocVa;
869                 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa        = AllocPa;
870                 /* update SDP0 to new buffer of rx packet */
871                 pRxD->SDP0 = AllocPa;
872         }
873         else
874         {
875                 //printk("No Rx Buffer\n");
876                 pRxPacket = NULL;
877                 bReschedule = TRUE;
878         }
879
880         pRxD->DDONE = 0;
881
882         // had handled one rx packet
883         *pRxPending = *pRxPending - 1;
884
885         // update rx descriptor and kick rx
886         INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
887
888         pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
889         RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
890
891 done:
892         RTMP_SEM_UNLOCK(&pAd->RxRingLock);
893         *pbReschedule = bReschedule;
894         return pRxPacket;
895 }
896 /* End of 2860_rtmp_init.c */
897