Merge git://git.infradead.org/iommu-2.6
[sfrench/cifs-2.6.git] / drivers / staging / otus / hal / hpusb.c
1 /*
2  * Copyright (c) 2000-2005 ZyDAS Technology Corporation
3  * Copyright (c) 2007-2008 Atheros Communications Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 /*                                                                      */
18 /*  Module Name : ud.c                                                  */
19 /*                                                                      */
20 /*  Abstract                                                            */
21 /*      This module contains USB descriptor functions.                  */
22 /*                                                                      */
23 /*  NOTES                                                               */
24 /*      None                                                            */
25 /*                                                                      */
26 /************************************************************************/
27 #include "../80211core/cprecomp.h"
28 #include "hpani.h"
29 #include "hpusb.h"
30
31 extern void zfwUsbCmd(zdev_t* dev, u8_t endpt, u32_t* cmd, u16_t cmdLen);
32
33 extern void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen);
34 extern u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val);
35 extern u16_t zfFlushDelayWrite(zdev_t* dev);
36
37
38 #define USB_ENDPOINT_TX_INDEX   1
39 #define USB_ENDPOINT_RX_INDEX   2
40 #define USB_ENDPOINT_INT_INDEX  3
41 #define USB_ENDPOINT_CMD_INDEX  4
42
43 void zfIdlCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen)
44 {
45 #if ZM_SW_LOOP_BACK != 1
46     zfwUsbCmd(dev, USB_ENDPOINT_CMD_INDEX, cmd, cmdLen);
47 #endif
48
49     return;
50 }
51
52
53 /* zfAdjustCtrlSetting: fit OUTS format */
54 /*     convert MIMO2 to OUTS             */
55 void zfAdjustCtrlSetting(zdev_t* dev, u16_t* header, zbuf_t* buf)
56 {
57     /* MIMO2 => OUTS FB-50 */
58     /* length not change, only modify format */
59
60     u32_t oldMT;
61         u32_t oldMCS;
62
63     u32_t phyCtrl;
64     u32_t oldPhyCtrl;
65
66     u16_t tpc = 0;
67     struct zsHpPriv* hpPriv;
68
69     zmw_get_wlan_dev(dev);
70     hpPriv=wd->hpPrivate;
71
72    /* mm */
73     if (header == NULL)
74     {
75         oldPhyCtrl = zmw_buf_readh(dev, buf, 4) | ((u32_t)zmw_buf_readh(dev, buf, 6) << 16);
76     }
77     else
78     {
79         oldPhyCtrl = header[2] | ((u32_t)header[3] <<16);
80     }
81
82         phyCtrl = 0;
83
84
85         /* MT : Bit[1~0] */
86         oldMT = oldPhyCtrl&0x3;
87         phyCtrl |= oldMT;
88     if ( oldMT == 0x3 )   /* DL-OFDM (Duplicate Legacy OFDM) */
89                 phyCtrl |= 0x1;
90
91
92         /* PT : Bit[2]    HT PT: 0 Mixed mode    1 Green field */
93         phyCtrl |= (oldPhyCtrl&0x4);
94
95         /* Bandwidth control : Bit[4~3] */
96         if ( oldPhyCtrl&0x800000 )    /* Bit23 : 40M */
97         {
98                 #if 0
99                 if (oldMT == 0x3)             /* DL-OFDM */
100             phyCtrl |= (0x3<<3);   /* 40M duplicate */
101                 else
102                         phyCtrl |= (0x2<<3);   /* 40M shared */
103                 #else
104                 if (oldMT == 0x2 && ((struct zsHpPriv*)wd->hpPrivate)->hwBw40)
105                 {
106                         phyCtrl |= (0x2<<3);   /* 40M shared */
107                 }
108                 #endif
109         }
110         else {
111         oldPhyCtrl &= ~0x80000000;
112     }
113
114         /* MCS : Bit[24~18] */
115         oldMCS = (oldPhyCtrl&0x7f0000)>>16;  /* Bit[22~16] */
116         phyCtrl |= (oldMCS<<18);
117
118         /* Short GI : Bit[31]*/
119     phyCtrl |= (oldPhyCtrl&0x80000000);
120
121         /* AM : Antenna mask */
122         //if ((oldMT == 2) && (oldMCS > 7))
123         if (hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM)
124         {
125             phyCtrl |= (0x1<<15);
126         }
127         else
128         {
129             /* HT                     Tx 2 chain */
130             /* OFDM 6M/9M/12M/18M/24M Tx 2 chain */
131             /* OFDM 36M/48M/54M/      Tx 1 chain */
132             /* CCK                    Tx 2 chain */
133             if ((oldMT == 2) || (oldMT == 3))
134             {
135                 phyCtrl |= (0x5<<15);
136             }
137             else if (oldMT == 1)
138             {
139                 if ((oldMCS == 0xb) || (oldMCS == 0xf) ||
140                     (oldMCS == 0xa) || (oldMCS == 0xe) ||
141                     (oldMCS == 0x9))                       //6M/9M/12M/18M/24M
142                 {
143                     phyCtrl |= (0x5<<15);
144                 }
145                 else
146                 {
147                     phyCtrl |= (0x1<<15);
148                 }
149             }
150             else //(oldMT==0)
151             {
152                 phyCtrl |= (0x5<<15);
153             }
154         }
155         //else
156         //    phyCtrl |= (0x1<<15);
157
158         /* TPC */
159         /* TODO : accelerating these code */
160         if (hpPriv->hwFrequency < 3000)
161         {
162         if (oldMT == 0)
163         {
164             /* CCK */
165             tpc = (hpPriv->tPow2xCck[oldMCS]&0x3f);
166         }
167         else if (oldMT == 1)
168         {
169             /* OFDM */
170             if (oldMCS == 0xc)
171             {
172                 tpc = (hpPriv->tPow2x2g[3]&0x3f);
173             }
174             else if (oldMCS == 0x8)
175             {
176                 tpc = (hpPriv->tPow2x2g[2]&0x3f);
177             }
178             else if (oldMCS == 0xd)
179             {
180                 tpc = (hpPriv->tPow2x2g[1]&0x3f);
181             }
182             else if (oldMCS == 0x9)
183             {
184                 tpc = ((hpPriv->tPow2x2g[0]-hpPriv->tPow2x2g24HeavyClipOffset)&0x3f);
185             }
186             else
187             {
188                 tpc = (hpPriv->tPow2x2g[0]&0x3f);
189             }
190         }
191         else if (oldMT == 2)
192         {
193             if ( oldPhyCtrl&0x800000 )    /* Bit23 : 40M */
194             {
195                 /* HT 40 */
196                 tpc = (hpPriv->tPow2x2gHt40[oldMCS&0x7]&0x3f);
197             }
198             else
199             {
200                 /* HT 20 */
201                 tpc = (hpPriv->tPow2x2gHt20[oldMCS&0x7]&0x3f);
202             }
203         }
204     }
205     else  //5GHz
206     {
207         if (oldMT == 1)
208         {
209             /* OFDM */
210             if (oldMCS == 0xc)
211             {
212                 tpc = (hpPriv->tPow2x5g[3]&0x3f);
213             }
214             else if (oldMCS == 0x8)
215             {
216                 tpc = (hpPriv->tPow2x5g[2]&0x3f);
217             }
218             else if (oldMCS == 0xd)
219             {
220                 tpc = (hpPriv->tPow2x5g[1]&0x3f);
221             }
222             else
223             {
224                 tpc = (hpPriv->tPow2x5g[0]&0x3f);
225             }
226         }
227         else if (oldMT == 2)
228         {
229             if ( oldPhyCtrl&0x800000 )    /* Bit23 : 40M */
230             {
231                 /* HT 40 */
232                 tpc = (hpPriv->tPow2x5gHt40[oldMCS&0x7]&0x3f);
233             }
234             else
235             {
236                 /* HT 20 */
237                 tpc = (hpPriv->tPow2x5gHt20[oldMCS&0x7]&0x3f);
238             }
239         }
240     }
241
242     /* Tx power adjust for HT40 */
243         /* HT40   +1dBm */
244         if ((oldMT==2) && (oldPhyCtrl&0x800000) )
245         {
246             tpc += 2;
247         }
248         tpc &= 0x3f;
249
250     /* Evl force tx TPC */
251     if(wd->forceTxTPC)
252     {
253         tpc = (u16_t)(wd->forceTxTPC & 0x3f);
254     }
255
256     if (hpPriv->hwFrequency < 3000) {
257         wd->maxTxPower2 &= 0x3f;
258         tpc = (tpc > wd->maxTxPower2)? wd->maxTxPower2 : tpc;
259     } else {
260         wd->maxTxPower5 &= 0x3f;
261         tpc = (tpc > wd->maxTxPower5)? wd->maxTxPower5 : tpc;
262     }
263
264
265 #define ZM_MIN_TPC     5
266 #define ZM_TPC_OFFSET  5
267 #define ZM_SIGNAL_THRESHOLD  56
268     if ((wd->sta.bScheduleScan == FALSE) && (wd->sta.bChannelScan == FALSE))
269     {
270         if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
271                 && (zfStaIsConnected(dev))
272                 && (wd->SignalStrength > ZM_SIGNAL_THRESHOLD))
273         {
274             if (tpc > ((ZM_MIN_TPC+ZM_TPC_OFFSET)*2))
275             {
276                 tpc -= (ZM_TPC_OFFSET*2);
277             }
278             else if (tpc > (ZM_MIN_TPC*2))
279             {
280                 tpc = (ZM_MIN_TPC*2);
281             }
282         }
283     }
284 #undef ZM_MIN_TPC
285 #undef ZM_TPC_OFFSET
286 #undef ZM_SIGNAL_THRESHOLD
287
288     #ifndef ZM_OTUS_LINUX_PHASE_2
289     phyCtrl |= (tpc & 0x3f) << 9;
290     #endif
291
292     /* Set bits[8:6]BF-MCS for heavy clip */
293     if ((phyCtrl&0x3) == 2)
294         {
295             phyCtrl |= ((phyCtrl >> 12) & 0x1c0);
296     }
297
298         /* PHY control */
299     if (header == NULL)
300     {
301         zmw_buf_writeh(dev, buf, 4, (u16_t) (phyCtrl&0xffff));
302         zmw_buf_writeh(dev, buf, 6, (u16_t) (phyCtrl>>16));
303     }
304     else
305     {
306         //PHY control L
307         header[2] = (u16_t) (phyCtrl&0xffff);
308         //PHY control H
309         header[3] = (u16_t) (phyCtrl>>16);
310     }
311
312         zm_msg2_tx(ZM_LV_2, "old phy ctrl = ", oldPhyCtrl);
313     zm_msg2_tx(ZM_LV_2, "new phy ctrl = ", phyCtrl);
314         //DbgPrint("old phy ctrl =%08x \n", oldPhyCtrl);
315     //DbgPrint("new phy ctrl =%08x \n", phyCtrl);
316 }
317
318
319 #define EXTRA_INFO_LEN      24    //RSSI(7) + EVM(12) + PHY(1) + MACStatus(4)
320 u16_t zfHpSend(zdev_t* dev, u16_t* header, u16_t headerLen,
321                 u16_t* snap, u16_t snapLen,
322                 u16_t* tail, u16_t tailLen, zbuf_t* buf, u16_t offset,
323                 u16_t bufType, u8_t ac, u8_t keyIdx)
324 {
325 #if ZM_SW_LOOP_BACK == 1
326     zbuf_t *rxbuf;
327     u8_t *puRxBuf;
328     u8_t *pHdr;
329            u8_t *psnap;
330            u16_t plcplen = 12;
331     u16_t i;
332         u16_t swlpOffset;
333 #endif /* #if ZM_SW_LOOP_BACK == 1 */
334     struct zsHpPriv* hpPriv;
335
336     zmw_get_wlan_dev(dev);
337     hpPriv=wd->hpPrivate;
338
339     zm_msg1_tx(ZM_LV_1, "zfHpSend(), len = ", 12 + headerLen-8 + snapLen + zfwBufGetSize(dev, buf) + 4 + 8);
340
341         /* Adjust ctrl setting : 6N14 yjsung */
342     zfAdjustCtrlSetting(dev, header, buf);
343
344 #if ZM_SW_LOOP_BACK != 1
345     hpPriv->usbSendBytes += zfwBufGetSize(dev, buf);
346     hpPriv->usbAcSendBytes[ac&0x3] += zfwBufGetSize(dev, buf);
347
348     /* Submit USB Out Urb */
349     zfwUsbSend(dev, USB_ENDPOINT_TX_INDEX, (u8_t *)header, headerLen,
350                   (u8_t *)snap, snapLen, (u8_t *)tail, tailLen, buf, offset);
351 #endif
352
353 #if ZM_SW_LOOP_BACK == 1
354
355     rxbuf = zfwBufAllocate(dev, plcplen + headerLen-8 + snapLen + (zfwBufGetSize(dev, buf)-offset) + 4 + EXTRA_INFO_LEN);
356     pHdr = (u8_t *) header+8;
357         psnap = (u8_t *) snap;
358
359     zmw_enter_critical_section(dev);
360     /* software loop back */
361     /* Copy WLAN header and packet buffer */
362         swlpOffset = plcplen;
363
364     for(i = 0; i < headerLen-8; i++)
365     {
366         zmw_rx_buf_writeb(dev, rxbuf, swlpOffset+i, pHdr[i]);
367     }
368
369         swlpOffset += headerLen-8;
370
371     /* Copy SNAP header */
372     for(i = 0; i < snapLen; i++)
373     {
374                       zmw_rx_buf_writeb(dev, rxbuf, swlpOffset+i, psnap[i]);
375     }
376
377            swlpOffset += snapLen;
378
379     /* Copy body from tx buf to rxbuf */
380     for(i = 0; i < (zfwBufGetSize(dev, buf)-offset); i++)
381     {
382         u8_t value = zmw_rx_buf_readb(dev, buf, i+offset);
383         zmw_rx_buf_writeb(dev, rxbuf, swlpOffset+i, value);
384     }
385
386            /* total length = PLCP +         MacHeader       + Payload   + FCS + RXstatus */
387            /*                 12  +  headerLen-8  + snapLen + buf length + 4  + 8        */
388         zfwSetBufSetSize(dev, rxbuf, swlpOffset + (zfwBufGetSize(dev, buf)-offset) + 4 + EXTRA_INFO_LEN );
389
390     zmw_leave_critical_section(dev);
391
392     zfwBufFree(dev, buf, 0);
393
394            //zfwDumpBuf(dev, rxbuf);
395            //-------------------------------------------------
396
397     //zfCoreRecv(dev, rxbuf);
398
399 #endif /* #if ZM_SW_LOOP_BACK */
400
401     return ZM_SUCCESS;
402 }
403
404 /* Report moniter Hal rx information about rssi, evm, bandwidth, SG etc */
405 void zfHpQueryMonHalRxInfo(zdev_t* dev, u8_t *monHalRxInfo)
406 {
407     zmw_get_wlan_dev(dev);
408     zfMemoryCopy(monHalRxInfo,
409                 (u8_t*)&(((struct zsHpPriv*)wd->hpPrivate)->halRxInfo),
410                 sizeof(struct zsHalRxInfo));
411 }
412
413
414 u8_t zfIsDataFrame(zdev_t* dev, zbuf_t* buf)
415 {
416     u8_t frameType;
417     u8_t mpduInd;
418
419     mpduInd = zmw_rx_buf_readb(dev, buf, zfwBufGetSize(dev, buf)-1);
420
421     /* sinlge or First */
422     if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x20)
423     {
424         frameType = zmw_rx_buf_readb(dev, buf, 12);
425     }
426     else
427     {
428         frameType = zmw_rx_buf_readb(dev, buf, 0);
429     }
430
431     if((frameType & 0xf) == ZM_WLAN_DATA_FRAME)
432         return 1;
433     else
434         return 0;
435 }
436
437 u32_t zfcConvertRateOFDM(zdev_t* dev, zbuf_t* buf)
438 {
439     // What's the default value??
440     u32_t MCS = 0;
441
442     switch(zmw_rx_buf_readb(dev, buf, 0)& 0xf)
443     {
444         case 0xb:
445             MCS = 0x4;
446             break;
447         case 0xf:
448             MCS = 0x5;
449             break;
450         case 0xa:
451             MCS = 0x6;
452             break;
453         case 0xe:
454             MCS = 0x7;
455             break;
456         case 0x9:
457             MCS = 0x8;
458             break;
459         case 0xd:
460             MCS = 0x9;
461             break;
462         case 0x8:
463             MCS = 0xa;
464             break;
465         case 0xc:
466             MCS = 0xb;
467             break;
468     }
469     return MCS;
470 }
471
472 u16_t zfHpGetPayloadLen(zdev_t* dev,
473                         zbuf_t* buf,
474                         u16_t len,
475                         u16_t plcpHdrLen,
476                         u32_t *rxMT,
477                         u32_t *rxMCS,
478                         u32_t *rxBW,
479                         u32_t *rxSG
480                         )
481 {
482     u8_t modulation,mpduInd;
483     u16_t low, high, msb;
484     s16_t payloadLen = 0;
485
486     zmw_get_wlan_dev(dev);
487
488     mpduInd = zmw_rx_buf_readb(dev, buf, len-1);
489     modulation = zmw_rx_buf_readb(dev, buf, (len-1)) & 0x3;
490     *rxMT = modulation;
491
492     //zm_debug_msg1(" modulation= ", modulation);
493     switch (modulation) {
494     case 0: /* CCK Mode */
495         low = zmw_rx_buf_readb(dev, buf, 2);
496         high = zmw_rx_buf_readb(dev, buf, 3);
497         payloadLen = (low | high << 8) - 4;
498         if (wd->enableHALDbgInfo)
499         {
500             *rxMCS = zmw_rx_buf_readb(dev, buf, 0);
501             *rxBW  = 0;
502             *rxSG  = 0;
503         }
504         break;
505     case 1: /* Legacy-OFDM mode */
506         low = zmw_rx_buf_readb(dev, buf, 0) >> 5;
507         high = zmw_rx_buf_readb(dev, buf, 1);
508         msb = zmw_rx_buf_readb(dev, buf, 2) & 0x1;
509         payloadLen = (low | (high << 3) | (msb << 11)) - 4;
510         if (wd->enableHALDbgInfo)
511         {
512             *rxMCS = zfcConvertRateOFDM(dev, buf);
513             *rxBW  = 0;
514             *rxSG  = 0;
515         }
516         break;
517     case 2: /* HT OFDM mode */
518         //zm_debug_msg1("aggregation= ", (zmw_rx_buf_readb(dev, buf, 6) >> 3) &0x1 );
519         if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x10)    //single or last mpdu
520             payloadLen = len - 24 - 4 - plcpHdrLen;  // - rxStatus - fcs
521         else {
522             payloadLen = len - 4 - 4 - plcpHdrLen;  // - rxStatus - fcs
523             //zm_debug_msg1("first or middle mpdu, plcpHdrLen= ", plcpHdrLen);
524         }
525         if (wd->enableHALDbgInfo)
526         {
527             *rxMCS = zmw_rx_buf_readb(dev, buf, 3) & 0x7f;
528             *rxBW  = (zmw_rx_buf_readb(dev, buf, 3) >> 7) & 0x1;
529             *rxSG  = (zmw_rx_buf_readb(dev, buf, 6) >> 7) & 0x1;
530         }
531         break;
532     default:
533         break;
534
535     }
536     /* return the payload length - FCS */
537     if (payloadLen < 0) payloadLen = 0;
538     return payloadLen;
539 }
540
541 /************************************************************************/
542 /*                                                                      */
543 /*    FUNCTION DESCRIPTION                  zfiUsbRecv                  */
544 /*      Callback function for USB IN Transfer.                          */
545 /*                                                                      */
546 /*    INPUTS                                                            */
547 /*      dev: device pointer                                             */
548 /*                                                                      */
549 /*    OUTPUTS                                                           */
550 /*      None                                                            */
551 /*                                                                      */
552 /*    AUTHOR                                                            */
553 /*      Yuan-Gu Wei        ZyDAS Technology Corporation    2005.10      */
554 /*                                                                      */
555 /************************************************************************/
556 #define ZM_INT_USE_EP2                1
557 #define ZM_INT_USE_EP2_HEADER_SIZE   12
558
559 #if ZM_INT_USE_EP2 == 1
560 void zfiUsbRegIn(zdev_t* dev, u32_t* rsp, u16_t rspLen);
561 #endif
562
563 #ifdef ZM_OTUS_RX_STREAM_MODE
564 void zfiUsbRecvPerPkt(zdev_t *dev, zbuf_t *buf)
565 #else
566 void zfiUsbRecv(zdev_t *dev, zbuf_t *buf)
567 #endif
568 {
569
570
571 #if ZM_FW_LOOP_BACK != 1
572     u8_t mpduInd;
573     u16_t plcpHdrLen;
574     u16_t crcPlusRxStatusLen;
575     u16_t len, payloadLen=0;
576     u16_t i; //CWYang(+)
577     struct zsAdditionInfo addInfo;
578     u32_t               rxMT;
579     u32_t               rxMCS;
580     u32_t               rxBW;
581     u32_t               rxSG;
582     struct zsHpPriv* hpPriv;
583
584     zmw_get_wlan_dev(dev);
585     hpPriv=wd->hpPrivate;
586
587     //zm_msg0_rx(ZM_LV_0, "zfiUsbRecv()");
588
589 #if ZM_INT_USE_EP2 == 1
590
591     for (i=0; i<(ZM_INT_USE_EP2_HEADER_SIZE>>1); i++)
592     {
593         if (zmw_rx_buf_readh(dev, buf, i*2) != 0xffff)
594                 break;
595     }
596
597     if (i==(ZM_INT_USE_EP2_HEADER_SIZE>>1))
598     {
599         u32_t               rsp[ZM_USB_MAX_EPINT_BUFFER/4];
600         u16_t               rspLen;
601         u32_t               rspi;
602         u8_t*               pdst = (u8_t*)rsp;
603
604         /* Interrupt Rsp */
605         rspLen = (u16_t) zfwBufGetSize(dev, buf)-ZM_INT_USE_EP2_HEADER_SIZE;
606
607         if (rspLen > 60)
608         {
609             zm_debug_msg1("Get error len by EP2 = \n", rspLen);
610             /* free USB buf */
611                   zfwBufFree(dev, buf, 0);
612                   return;
613         }
614
615         for (rspi=0; rspi<rspLen; rspi++)
616         {
617                 *pdst = zmw_rx_buf_readb(dev, buf, rspi+ZM_INT_USE_EP2_HEADER_SIZE);
618                 pdst++;
619         }
620
621         //if (adapter->zfcbUsbRegIn)
622         //    adapter->zfcbUsbRegIn(adapter, rsp, rspLen);
623         zfiUsbRegIn(dev, rsp, rspLen);
624
625               /* free USB buf */
626               zfwBufFree(dev, buf, 0);
627               return;
628     }
629 #endif /* end of #if ZM_INT_USE_EP2 == 1 */
630
631     ZM_PERFORMANCE_RX_MPDU(dev, buf);
632
633     if (wd->swSniffer)
634     {
635         /* airopeek: Report everything up */
636         if (wd->zfcbRecv80211 != NULL)
637         {
638             wd->zfcbRecv80211(dev, buf, NULL);
639         }
640     }
641
642     /* Read the last byte */
643     len = zfwBufGetSize(dev, buf);
644     mpduInd = zmw_rx_buf_readb(dev, buf, len-1);
645
646     /* First MPDU */
647     if((mpduInd & 0x30) == 0x20)
648     {
649         u16_t duration;
650         if (zmw_rx_buf_readb(dev, buf, 36) == 0) //AC = BE
651         {
652             duration = zmw_rx_buf_readh(dev, buf, 14);
653             if (duration > hpPriv->aggMaxDurationBE)
654             {
655                 hpPriv->aggMaxDurationBE = duration;
656             }
657             else
658             {
659                 if (hpPriv->aggMaxDurationBE > 10)
660                 {
661                     hpPriv->aggMaxDurationBE--;
662                 }
663             }
664             //DbgPrint("aggMaxDurationBE=%d", hpPriv->aggMaxDurationBE);
665         }
666     }
667
668 #if 1
669     /* First MPDU or Single MPDU */
670     if(((mpduInd & 0x30) == 0x00) || ((mpduInd & 0x30) == 0x20))
671     //if ((mpduInd & 0x10) == 0x00)
672     {
673         plcpHdrLen = 12;        // PLCP header length
674     }
675     else
676     {
677         if (zmw_rx_buf_readh(dev, buf, 4) == wd->macAddr[0] &&
678             zmw_rx_buf_readh(dev, buf, 6) == wd->macAddr[1] &&
679             zmw_rx_buf_readh(dev, buf, 8) == wd->macAddr[2]) {
680             plcpHdrLen = 0;
681         }
682         else if (zmw_rx_buf_readh(dev, buf, 16) == wd->macAddr[0] &&
683                  zmw_rx_buf_readh(dev, buf, 18) == wd->macAddr[1] &&
684                  zmw_rx_buf_readh(dev, buf, 20) == wd->macAddr[2]){
685             plcpHdrLen = 12;
686         }
687         else {
688             plcpHdrLen = 0;
689         }
690     }
691
692     /* Last MPDU or Single MPDU */
693     if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x10)
694     {
695         crcPlusRxStatusLen = EXTRA_INFO_LEN + 4;     // Extra bytes + FCS
696     }
697     else
698     {
699         crcPlusRxStatusLen = 4 + 4;     // Extra 4 bytes + FCS
700     }
701 #else
702     plcpHdrLen = 12;
703     crcPlusRxStatusLen = EXTRA_INFO_LEN + 4;     // Extra bytes + FCS
704 #endif
705
706     if (len < (plcpHdrLen+10+crcPlusRxStatusLen))
707     {
708         zm_msg1_rx(ZM_LV_0, "Invalid Rx length=", len);
709         //zfwDumpBuf(dev, buf);
710
711         zfwBufFree(dev, buf, 0);
712         return;
713     }
714
715     /* display RSSI combined */
716     /*
717      * Â¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
718      * Â¢x PLCP Header Â¢x  MPDU  Â¢x RSSI Â¢x  EVM Â¢x PHY Err Â¢x  MAC Status Â¢x
719      * Â¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
720      * Â¢x     12      Â¢x    n   Â¢x  7   Â¢x  12  Â¢x    1    Â¢x      4      Â¢x
721      * Â¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
722      *  RSSI filed (From BB and MAC just pass them to host)
723      *   Byte1: RSSI for antenna 0.
724      *   Byte2: RSSI for antenna 1.
725      *   Byte3: RSSI for antenna 2.
726      *   Byte4: RSSI for antenna 0 extension.
727      *   Byte5: RSSI for antenna 1 extension.
728      *   Byte6: RSSI for antenna 2 extension.
729      *   Byte7: RSSI for antenna combined.
730      */
731
732     //zm_debug_msg1(" recv RSSI = ", zmw_rx_buf_readb(dev, buf, (len-1)-17));
733
734     payloadLen = zfHpGetPayloadLen(dev, buf, len, plcpHdrLen, &rxMT, &rxMCS, &rxBW, &rxSG);
735
736     /* Hal Rx info */
737     /* First MPDU or Single MPDU */
738     if(((mpduInd & 0x30) == 0x00) || ((mpduInd & 0x30) == 0x20))
739     {
740         if (wd->enableHALDbgInfo && zfIsDataFrame(dev, buf))
741         {
742             ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataMT   = rxMT;
743             ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataMCS  = rxMCS;
744             ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataBW   = rxBW;
745             ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataSG   = rxSG;
746         }
747     }
748
749     if ((plcpHdrLen + payloadLen) > len) {
750         zm_msg1_rx(ZM_LV_0, "Invalid payload length=", payloadLen);
751         zfwBufFree(dev, buf, 0);
752         return;
753     }
754
755     //Store Rx Tail Infomation before Remove--CWYang(+)
756
757 #if 0
758     for (i = 0; i < crcPlusRxStatusLen-4; i++)
759     {
760        addInfo.Tail.Byte[i] =
761                zmw_rx_buf_readb(dev, buf, len - crcPlusRxStatusLen + 4 + i);
762     }
763 #else
764 /*
765 * Brief format of OUTS chip
766 * Â¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
767 * Â¢x PLCP Header Â¢x  MPDU  Â¢x RSSI Â¢x  EVM Â¢x PHY Err Â¢x  MAC Status Â¢x
768 * Â¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
769 * Â¢x     12      Â¢x    n   Â¢x  7   Â¢x  12  Â¢x    1    Â¢x      4      Â¢x
770 * Â¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
771 * RSSI:
772 *       Byte 1  antenna 0
773 *       Byte 2  antenna 1
774 *       Byte 3  antenna 2
775 *       Byte 4  antenna 0 extension
776 *       Byte 5  antenna 1 extension
777 *       Byte 6  antenna 2 extension
778 *       Byte 7  antenna combined
779 * EVM:
780 *       Byte 1  Stream 0 pilot 0
781 *       Byte 2  Stream 0 pilot 1
782 *       Byte 3  Stream 0 pilot 2
783 *       Byte 4  Stream 0 pilot 3
784 *       Byte 5  Stream 0 pilot 4
785 *       Byte 6  Stream 0 pilot 5
786 *       Byte 7  Stream 1 pilot 0
787 *       Byte 8  Stream 1 pilot 1
788 *       Byte 9  Stream 1 pilot 2
789 *       Byte 10 Stream 1 pilot 3
790 *       Byte 11 Stream 1 pilot 4
791 *       Byte 12 Stream 1 pilot 5
792 */
793
794     /* Fill the Tail information */
795     /* Last MPDU or Single MPDU */
796     if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x10)
797     {
798 #define ZM_RX_RSSI_COMPENSATION     27
799         u8_t zm_rx_rssi_compensation = ZM_RX_RSSI_COMPENSATION;
800
801         /* RSSI information */
802         addInfo.Tail.Data.SignalStrength1 = zmw_rx_buf_readb(dev, buf,
803                 (len-1) - 17) + ((hpPriv->rxStrongRSSI == 1)?zm_rx_rssi_compensation:0);
804 #undef ZM_RX_RSSI_COMPENSATION
805
806       /* EVM */
807
808       /* TODO: for RD/BB debug message */
809       /* save current rx hw infomration, report to DrvCore/Application */
810       if (wd->enableHALDbgInfo && zfIsDataFrame(dev, buf))
811       {
812             u8_t trssi;
813             for (i=0; i<7; i++)
814             {
815                 trssi = zmw_rx_buf_readb(dev, buf, (len-1) - 23 + i);
816                     if (trssi&0x80)
817                     {
818                     trssi = ((~((u8_t)trssi) & 0x7f) + 1) & 0x7f;
819                 }
820                 ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[i] = trssi;
821
822             }
823           if (rxMT==2)
824           {
825             //if (rxBW)
826             //{
827                   for (i=0; i<12; i++)
828                     ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[i] =
829                                        zmw_rx_buf_readb(dev, buf, (len-1) - 16 + i);
830             //}
831             //else
832             //{
833             //    for (i=0; i<4; i++)
834             //        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[i] =
835             //                           zmw_rx_buf_readb(dev, buf, (len-1) - 16 + i);
836             //}
837           }
838
839           #if 0
840           /* print */
841             zm_dbg(("MT(%d) MCS(%d) BW(%d) SG(%d) RSSI:%d,%d,%d,%d,%d,%d,%d EVM:(%d,%d,%d,%d,%d,%d)(%d,%d,%d,%d,%d,%d)\n",
842                        rxMT,
843                        rxMCS,
844                        rxBW,
845                        rxSG,
846                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[0],
847                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[1],
848                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[2],
849                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[3],
850                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[4],
851                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[5],
852                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[6],
853                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[0],
854                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[1],
855                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[2],
856                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[3],
857                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[4],
858                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[5],
859                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[6],
860                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[7],
861                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[8],
862                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[9],
863                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[10],
864                        ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[11]
865                        ));
866           #endif
867       } /* if (wd->enableHALDbgInfo && zfIsDataFrame(dev, buf)) */
868
869     }
870     else
871     {
872         /* Mid or First aggregate frame without phy rx information */
873         addInfo.Tail.Data.SignalStrength1 = 0;
874     }
875
876     addInfo.Tail.Data.SignalStrength2 = 0;
877     addInfo.Tail.Data.SignalStrength3 = 0;
878     addInfo.Tail.Data.SignalQuality   = 0;
879
880     addInfo.Tail.Data.SAIndex           = zmw_rx_buf_readb(dev, buf, len - 4);
881     addInfo.Tail.Data.DAIndex           = zmw_rx_buf_readb(dev, buf, len - 3);
882     addInfo.Tail.Data.ErrorIndication   = zmw_rx_buf_readb(dev, buf, len - 2);
883     addInfo.Tail.Data.RxMacStatus       = zmw_rx_buf_readb(dev, buf, len - 1);
884
885 #endif
886     /* Remove CRC and Rx Status */
887     zfwBufSetSize(dev, buf, (len-crcPlusRxStatusLen));
888     //zfwBufSetSize(dev, buf, payloadLen + plcpHdrLen);    /* payloadLen + PLCP 12 - FCS 4*/
889
890     //Store PLCP Header Infomation before Remove--CWYang(+)
891     if (plcpHdrLen != 0)
892     {
893         for (i = 0; i < plcpHdrLen; i++)
894         {
895             addInfo.PlcpHeader[i] = zmw_rx_buf_readb(dev, buf, i);
896         }
897     }
898     else
899     {
900         addInfo.PlcpHeader[0] = 0;
901     }
902     /* Remove PLCP header */
903     zfwBufRemoveHead(dev, buf, plcpHdrLen);
904
905     /* handle 802.11 frame */
906     zfCoreRecv(dev, buf, &addInfo);
907
908 #else
909     /* Firmware loopback: Rx frame = Tx frame       */
910     /* convert Rx frame to fit receive frame format */
911     zbuf_t *new_buf;
912     u8_t    ctrl_offset = 8;
913     u8_t    PLCP_Len = 12;
914     u8_t    data;
915     u8_t    i;
916
917
918     /* Tx:  | ctrl_setting | Mac hdr | data | */
919     /*            8            24       x     */
920
921     /* Rx:          | PLCP | Mac hdr | data | FCS | Rxstatus | */
922     /*                 12      24        x     4       8       */
923
924     /* new allocate a rx format size buf */
925     new_buf = zfwBufAllocate(dev, zfwBufGetSize(dev, buf)-8+12+4+EXTRA_INFO_LEN);
926
927     for (i=0; i<zfwBufGetSize(dev, buf)-ctrl_offset; i++)
928     {
929         data = zmw_rx_buf_readb(dev, buf, ctrl_offset+i);
930         zmw_rx_buf_writeb(dev, new_buf, PLCP_Len+i, data);
931     }
932
933     zfwBufSetSize(dev, new_buf, zfwBufGetSize(dev, buf)-8+12+4+EXTRA_INFO_LEN);
934
935     zfwBufFree(dev, buf, 0);
936
937     /* receive the new_buf */
938     //zfCoreRecv(dev, new_buf);
939
940 #endif
941
942 }
943
944 #ifdef ZM_OTUS_RX_STREAM_MODE
945 void zfiUsbRecv(zdev_t *dev, zbuf_t *buf)
946 {
947     u16_t index = 0;
948     u16_t chkIdx;
949     u32_t status = 0;
950     u16_t ii;
951     zbuf_t *newBuf;
952     zbuf_t *rxBufPool[8];
953     u16_t rxBufPoolIndex = 0;
954     struct zsHpPriv *halPriv;
955     u8_t *srcBufPtr;
956     u32_t bufferLength;
957     u16_t usbRxRemainLen;
958     u16_t usbRxPktLen;
959
960     zmw_get_wlan_dev(dev);
961
962     halPriv = (struct zsHpPriv*)wd->hpPrivate;
963     srcBufPtr = zmw_buf_get_buffer(dev, buf);
964
965     bufferLength = zfwBufGetSize(dev, buf);
966
967     /* Zero Length Transfer */
968     if (!bufferLength)
969     {
970         zfwBufFree(dev, buf, 0);
971         return;
972     }
973
974     usbRxRemainLen = halPriv->usbRxRemainLen;
975     usbRxPktLen = halPriv->usbRxTransferLen;
976
977     /* Check whether there is any data in the last transfer */
978     if (usbRxRemainLen != 0 )
979     {
980         zbuf_t *remainBufPtr = halPriv->remainBuf;
981         u8_t* BufPtr = NULL;
982
983         if ( remainBufPtr != NULL )
984         {
985             BufPtr = zmw_buf_get_buffer(dev, remainBufPtr);
986         }
987
988         index = usbRxRemainLen;
989         usbRxRemainLen -= halPriv->usbRxPadLen;
990
991         /*  Copy data */
992         if ( BufPtr != NULL )
993         {
994             zfwMemoryCopy(&(BufPtr[usbRxPktLen]), srcBufPtr, usbRxRemainLen);
995         }
996
997         usbRxPktLen += usbRxRemainLen;
998         halPriv->usbRxRemainLen = 0;
999
1000         if ( remainBufPtr != NULL )
1001         {
1002             zfwBufSetSize(dev, remainBufPtr, usbRxPktLen);
1003             rxBufPool[rxBufPoolIndex++] = remainBufPtr;
1004         }
1005         halPriv->remainBuf = NULL;
1006     }
1007
1008     //zm_debug_msg1("length: %d\n", (int)pUsbRxTransfer->pRxUrb->UrbBulkOrInterruptTransfer.TransferBufferLength);
1009
1010     bufferLength = zfwBufGetSize(dev, buf);
1011 //printk("bufferLength %d\n", bufferLength);
1012     while(index < bufferLength)
1013     {
1014         u16_t pktLen;
1015         u16_t pktTag;
1016         //u8_t *ptr = (u8_t*)((struct zsBuffer*)pUsbRxTransfer->buf)->data;
1017         u8_t *ptr = srcBufPtr;
1018
1019         /* Retrieve packet length and tag */
1020         pktLen = ptr[index] + (ptr[index+1] << 8);
1021         pktTag = ptr[index+2] + (ptr[index+3] << 8);
1022
1023         if (pktTag == ZM_USB_STREAM_MODE_TAG)
1024         {
1025             u16_t padLen;
1026
1027             zm_assert(pktLen < ZM_WLAN_MAX_RX_SIZE);
1028
1029             //printk("Get a packet, pktLen: 0x%04x\n", pktLen);
1030             #if 0
1031             /* Dump data */
1032             for (ii = index; ii < pkt_len+4;)
1033             {
1034                 DbgPrint("0x%02x ",
1035                         (zmw_rx_buf_readb(adapter, pUsbRxTransfer->buf, ii) & 0xff));
1036
1037                 if ((++ii % 16) == 0)
1038                     DbgPrint("\n");
1039             }
1040
1041             DbgPrint("\n");
1042             #endif
1043
1044             /* Calcuate the padding length, in the current design,
1045                the length should be padded to 4 byte boundray. */
1046             padLen = ZM_USB_STREAM_MODE_TAG_LEN - (pktLen & 0x3);
1047
1048             if(padLen == ZM_USB_STREAM_MODE_TAG_LEN)
1049                 padLen = 0;
1050
1051             chkIdx = index;
1052             index = index + ZM_USB_STREAM_MODE_TAG_LEN + pktLen + padLen;
1053
1054             if (chkIdx > ZM_MAX_USB_IN_TRANSFER_SIZE)
1055             {
1056                 zm_debug_msg1("chkIdx is too large, chkIdx: %d\n", chkIdx);
1057                 zm_assert(0);
1058                 status = 1;
1059                 break;
1060             }
1061
1062             if (index > ZM_MAX_USB_IN_TRANSFER_SIZE)
1063             {
1064                 //struct zsBuffer* BufPtr;
1065                 //struct zsBuffer* UsbBufPtr;
1066                 u8_t *BufPtr;
1067                 u8_t *UsbBufPtr;
1068
1069                 halPriv->usbRxRemainLen = index - ZM_MAX_USB_IN_TRANSFER_SIZE; // - padLen;
1070                 halPriv->usbRxTransferLen = ZM_MAX_USB_IN_TRANSFER_SIZE -
1071                         chkIdx - ZM_USB_STREAM_MODE_TAG_LEN;
1072                 halPriv->usbRxPadLen = padLen;
1073                 //check_index = index;
1074
1075                 if (halPriv->usbRxTransferLen > ZM_WLAN_MAX_RX_SIZE)
1076                 {
1077                     zm_debug_msg1("check_len is too large, chk_len: %d\n",
1078                             halPriv->usbRxTransferLen);
1079                     status = 1;
1080                     break;
1081                 }
1082
1083                 /* Allocate a skb buffer */
1084                 newBuf = zfwBufAllocate(dev, ZM_WLAN_MAX_RX_SIZE);
1085
1086                 if ( newBuf != NULL )
1087                 {
1088                     BufPtr = zmw_buf_get_buffer(dev, newBuf);
1089                     UsbBufPtr = srcBufPtr;
1090
1091                     /* Copy the buffer */
1092                     zfwMemoryCopy(BufPtr, &(UsbBufPtr[chkIdx+ZM_USB_STREAM_MODE_TAG_LEN]), halPriv->usbRxTransferLen);
1093
1094                     /* Record the buffer pointer */
1095                     halPriv->remainBuf = newBuf;
1096                 }
1097             }
1098             else
1099             {
1100                 u8_t* BufPtr;
1101                 u8_t* UsbBufPtr;
1102
1103                 /* Allocate a skb buffer */
1104                 newBuf = zfwBufAllocate(dev, ZM_WLAN_MAX_RX_SIZE);
1105                 if ( newBuf != NULL )
1106                 {
1107                     BufPtr = zmw_buf_get_buffer(dev, newBuf);
1108                     UsbBufPtr = srcBufPtr;
1109
1110                     /* Copy the buffer */
1111                     zfwMemoryCopy(BufPtr, &(UsbBufPtr[chkIdx+ZM_USB_STREAM_MODE_TAG_LEN]), pktLen);
1112
1113                     zfwBufSetSize(dev, newBuf, pktLen);
1114                     rxBufPool[rxBufPoolIndex++] = newBuf;
1115                 }
1116             }
1117         }
1118         else
1119         {
1120                 u16_t i;
1121
1122                 DbgPrint("Can't find tag, pkt_len: 0x%04x, tag: 0x%04x\n",
1123                         pktLen, pktTag);
1124
1125                 #if 0
1126                 for(i = 0; i < 32; i++)
1127                 {
1128                     DbgPrint("%02x ", buf->data[index-16+i]);
1129
1130                     if ((i & 0xf) == 0xf)
1131                         DbgPrint("\n");
1132                 }
1133                 #endif
1134
1135                 break;
1136         }
1137     }
1138
1139     /* Free buffer */
1140     //zfwBufFree(adapter, pUsbRxTransfer->buf, 0);
1141     zfwBufFree(dev, buf, 0);
1142
1143     for(ii = 0; ii < rxBufPoolIndex; ii++)
1144     {
1145         zfiUsbRecvPerPkt(dev, rxBufPool[ii]);
1146     }
1147 }
1148 #endif
1149
1150 /************************************************************************/
1151 /*                                                                      */
1152 /*    FUNCTION DESCRIPTION                  zfUsbInit                   */
1153 /*      Initialize USB resource.                                        */
1154 /*                                                                      */
1155 /*    INPUTS                                                            */
1156 /*      dev : device pointer                                            */
1157 /*                                                                      */
1158 /*    OUTPUTS                                                           */
1159 /*      None                                                            */
1160 /*                                                                      */
1161 /*    AUTHOR                                                            */
1162 /*      Stephen Chen        ZyDAS Technology Corporation    2005.12     */
1163 /*                                                                      */
1164 /************************************************************************/
1165 void zfUsbInit(zdev_t* dev)
1166 {
1167     /* Initialize Rx & INT endpoint for receiving data & interrupt */
1168     zfwUsbEnableRxEpt(dev, USB_ENDPOINT_RX_INDEX);
1169     zfwUsbEnableIntEpt(dev, USB_ENDPOINT_INT_INDEX);
1170
1171     return;
1172 }
1173
1174
1175 /************************************************************************/
1176 /*                                                                      */
1177 /*    FUNCTION DESCRIPTION                  zfUsbFree                   */
1178 /*      Free PCI resource.                                              */
1179 /*                                                                      */
1180 /*    INPUTS                                                            */
1181 /*      dev : device pointer                                            */
1182 /*                                                                      */
1183 /*    OUTPUTS                                                           */
1184 /*      None                                                            */
1185 /*                                                                      */
1186 /*    AUTHOR                                                            */
1187 /*      Stephen Chen        ZyDAS Technology Corporation    2005.12     */
1188 /*                                                                      */
1189 /************************************************************************/
1190 void zfUsbFree(zdev_t* dev)
1191 {
1192     struct zsHpPriv *halPriv;
1193
1194     zmw_get_wlan_dev(dev);
1195
1196     halPriv = (struct zsHpPriv*)wd->hpPrivate;
1197
1198 #ifdef ZM_OTUS_RX_STREAM_MODE
1199     if ( halPriv->remainBuf != NULL )
1200     {
1201         zfwBufFree(dev, halPriv->remainBuf, 0);
1202     }
1203 #endif
1204
1205     return;
1206 }
1207
1208 void zfHpSendBeacon(zdev_t* dev, zbuf_t* buf, u16_t len)
1209 {
1210     u32_t hw, lw;
1211     u16_t i;
1212     zmw_get_wlan_dev(dev);
1213
1214     /* Write to beacon buffer (ZM_BEACON_BUFFER_ADDRESS) */
1215     for (i = 0; i<len; i+=4)
1216     {
1217         lw = zmw_tx_buf_readh(dev, buf, i);
1218         hw = zmw_tx_buf_readh(dev, buf, i+2);
1219
1220         zfDelayWriteInternalReg(dev, ZM_BEACON_BUFFER_ADDRESS+i, (hw<<16)+lw);
1221     }
1222
1223     /* Beacon PCLP header */
1224     if (((struct zsHpPriv*)wd->hpPrivate)->hwFrequency < 3000)
1225     {
1226     zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PLCP, ((len+4)<<(3+16))+0x0400);
1227     }
1228     else
1229     {
1230         zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PLCP, ((len+4)<<(16))+0x001b);
1231     }
1232
1233     /* Beacon length (include CRC32) */
1234     zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_LENGTH, len+4);
1235
1236     /* Beacon Ready */
1237     zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_CTRL, 1);
1238     zfFlushDelayWrite(dev);
1239
1240     /* Free beacon buf */
1241     zfwBufFree(dev, buf, 0);
1242
1243     return;
1244 }
1245
1246
1247 #define ZM_STATUS_TX_COMP       0x00
1248 #define ZM_STATUS_RETRY_COMP    0x01
1249 #define ZM_STATUS_TX_FAILED     0x02
1250 void zfiUsbRegIn(zdev_t* dev, u32_t* rsp, u16_t rspLen)
1251 {
1252     //u8_t len, type, i;
1253     u8_t type;
1254     u8_t *u8rsp;
1255     u16_t status;
1256     u32_t bitmap;
1257     zmw_get_wlan_dev(dev);
1258
1259     zm_msg0_mm(ZM_LV_3, "zfiUsbRegIn()");
1260
1261     u8rsp = (u8_t *)rsp;
1262
1263     //len = *u8rsp;
1264     type = *(u8rsp+1);
1265     u8rsp = u8rsp+4;
1266
1267
1268     /* Interrupt event */
1269     if ((type & 0xC0) == 0xC0)
1270     {
1271         if (type == 0xC0)
1272         {
1273             zfCoreEvent(dev, 0, u8rsp);
1274
1275         }
1276         else if (type == 0xC1)
1277         {
1278 #if 0
1279             {
1280                 u16_t i;
1281                 DbgPrint("rspLen=%d\n", rspLen);
1282                 for (i=0; i<(rspLen/4); i++)
1283                 {
1284                     DbgPrint("rsp[%d]=0x%lx\n", i, rsp[i]);
1285                 }
1286             }
1287 #endif
1288             status = (u16_t)(rsp[3] >> 16);
1289
1290             ////6789
1291             rsp[8] = rsp[8] >> 2 | (rsp[9] & 0x1) << 6;
1292             switch (status)
1293             {
1294             case ZM_STATUS_RETRY_COMP :
1295                 zfCoreEvent(dev, 1, u8rsp);
1296                 break;
1297             case ZM_STATUS_TX_FAILED :
1298                 zfCoreEvent(dev, 2, u8rsp);
1299                 break;
1300             case ZM_STATUS_TX_COMP :
1301                 zfCoreEvent(dev, 3, u8rsp);
1302                 break;
1303             }
1304         }
1305         else if (type == 0xC2)
1306         {
1307             zfBeaconCfgInterrupt(dev, u8rsp);
1308         }
1309         else if (type == 0xC3)
1310         {
1311             zfEndOfAtimWindowInterrupt(dev);
1312         }
1313         else if (type == 0xC4)
1314         {
1315 #if 0
1316             {
1317                 u16_t i;
1318                 DbgPrint("0xC2:rspLen=%d\n", rspLen);
1319                 for (i=0; i<(rspLen/4); i++)
1320                 {
1321                     DbgPrint("0xC2:rsp[%d]=0x%lx\n", i, rsp[i]);
1322                 }
1323             }
1324 #endif
1325             bitmap = (rsp[1] >> 16) + ((rsp[2] & 0xFFFF) << 16 );
1326             //zfBawCore(dev, (u16_t)rsp[1] & 0xFFFF, bitmap, (u16_t)(rsp[2] >> 16) & 0xFF);
1327         }
1328         else if (type == 0xC5)
1329         {
1330             u16_t i;
1331 #if 0
1332
1333             for (i=0; i<(rspLen/4); i++) {
1334                 DbgPrint("0xC5:rsp[%d]=0x%lx\n", i, rsp[i]);
1335             }
1336 #endif
1337             for (i=1; i<(rspLen/4); i++) {
1338                 u8rsp = (u8_t *)(rsp+i);
1339                 //DbgPrint("0xC5:rsp[%d]=0x%lx\n", i, ((u32_t*)u8rsp)[0]);
1340                 zfCoreEvent(dev, 4, u8rsp);
1341             }
1342         }
1343         else if (type == 0xC6)
1344         {
1345             zm_debug_msg0("\n\n WatchDog interrupt!!! : 0xC6 \n\n");
1346             if (wd->zfcbHwWatchDogNotify != NULL)
1347             {
1348                 wd->zfcbHwWatchDogNotify(dev);
1349             }
1350         }
1351         else if (type == 0xC8)
1352         {
1353             //PZSW_ADAPTER adapter;
1354
1355             // for SPI flash program chk Flag
1356             zfwDbgProgrameFlashChkDone(dev);
1357         }
1358         else if (type == 0xC9)
1359         {
1360             struct zsHpPriv* hpPriv=wd->hpPrivate;
1361
1362             zm_debug_msg0("##### Tx retransmission 5 times event #####");
1363
1364             /* correct tx retransmission issue */
1365             hpPriv->retransmissionEvent = 1;
1366         }
1367     }
1368     else
1369     {
1370         zfIdlRsp(dev, rsp, rspLen);
1371     }
1372 }
1373
1374
1375 #define ZM_PROGRAM_RAM_ADDR     0x200000 //0x1000 //0x700000
1376 #define FIRMWARE_DOWNLOAD       0x30
1377 #define FIRMWARE_DOWNLOAD_COMP  0x31
1378 #define FIRMWARE_CONFIRM        0x32
1379
1380 u16_t zfFirmwareDownload(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset)
1381 {
1382     u16_t ret = ZM_SUCCESS;
1383     u32_t uCodeOfst = offset;
1384     u8_t *image, *ptr;
1385     u32_t result;
1386
1387     image = (u8_t*) fw;
1388     ptr = image;
1389
1390     while (len > 0)
1391     {
1392         u32_t translen = (len > 4096) ? 4096 : len;
1393
1394         result = zfwUsbSubmitControl(dev, FIRMWARE_DOWNLOAD,
1395                                      (u16_t) (uCodeOfst >> 8),
1396                                      0, image, translen);
1397
1398         if (result != ZM_SUCCESS)
1399         {
1400             zm_msg0_init(ZM_LV_0, "FIRMWARE_DOWNLOAD failed");
1401             ret = 1;
1402             goto exit;
1403         }
1404
1405         len -= translen;
1406         image += translen;
1407         uCodeOfst += translen; // in Word (16 bit)
1408
1409         result = 0;
1410     }
1411
1412     /* If download firmware success, issue a command to firmware */
1413     if (ret == 0)
1414     {
1415         result = zfwUsbSubmitControl(dev, FIRMWARE_DOWNLOAD_COMP,
1416                                      0, 0, NULL, 0);
1417
1418         if (result != ZM_SUCCESS)
1419         {
1420             zm_msg0_init(ZM_LV_0, "FIRMWARE_DOWNLOAD_COMP failed");
1421             ret = 1;
1422             goto exit;
1423         }
1424     }
1425
1426 #if 0
1427     /* PCI code */
1428     /* Wait for firmware ready */
1429     result = zfwUsbSubmitControl(dev, FIRMWARE_CONFIRM, USB_DIR_IN | 0x40,
1430                      0, 0, &ret_value, sizeof(ret_value), HZ);
1431
1432     if (result != 0)
1433     {
1434         zm_msg0_init(ZM_LV_0, "Can't receive firmware ready: ", result);
1435         ret = 1;
1436     }
1437 #endif
1438
1439 exit:
1440
1441     return ret;
1442
1443 }
1444
1445 u16_t zfFirmwareDownloadNotJump(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset)
1446 {
1447     u16_t ret = ZM_SUCCESS;
1448     u32_t uCodeOfst = offset;
1449     u8_t *image, *ptr;
1450     u32_t result;
1451
1452     image = (u8_t*) fw;
1453     ptr = image;
1454
1455     while (len > 0)
1456     {
1457         u32_t translen = (len > 4096) ? 4096 : len;
1458
1459         result = zfwUsbSubmitControl(dev, FIRMWARE_DOWNLOAD,
1460                                      (u16_t) (uCodeOfst >> 8),
1461                                      0, image, translen);
1462
1463         if (result != ZM_SUCCESS)
1464         {
1465             zm_msg0_init(ZM_LV_0, "FIRMWARE_DOWNLOAD failed");
1466             ret = 1;
1467             goto exit;
1468         }
1469
1470         len -= translen;
1471         image += translen;
1472         uCodeOfst += translen; // in Word (16 bit)
1473
1474         result = 0;
1475     }
1476
1477 exit:
1478
1479     return ret;
1480
1481 }
1482
1483 /************************************************************************/
1484 /*                                                                      */
1485 /*    FUNCTION DESCRIPTION                  zfIdlGetFreeTxdCount        */
1486 /*      Get free PCI PCI TxD count.                                     */
1487 /*                                                                      */
1488 /*    INPUTS                                                            */
1489 /*      dev : device pointer                                            */
1490 /*                                                                      */
1491 /*    OUTPUTS                                                           */
1492 /*      None                                                            */
1493 /*                                                                      */
1494 /*    AUTHOR                                                            */
1495 /*      Stephen             ZyDAS Technology Corporation    2006.6      */
1496 /*                                                                      */
1497 /************************************************************************/
1498 u32_t zfHpGetFreeTxdCount(zdev_t* dev)
1499 {
1500     return zfwUsbGetFreeTxQSize(dev);
1501 }
1502
1503 u32_t zfHpGetMaxTxdCount(zdev_t* dev)
1504 {
1505     //return 8;
1506     return zfwUsbGetMaxTxQSize(dev);
1507 }
1508
1509 void zfiUsbRegOutComplete(zdev_t* dev)
1510 {
1511     return;
1512 }
1513
1514 extern void zfPushVtxq(zdev_t* dev);
1515
1516 void zfiUsbOutComplete(zdev_t* dev, zbuf_t *buf, u8_t status, u8_t *hdr) {
1517 #ifndef ZM_ENABLE_AGGREGATION
1518     if (buf) {
1519         zfwBufFree(dev, buf, 0);
1520     }
1521 #else
1522     #ifdef ZM_BYPASS_AGGR_SCHEDULING
1523     //Simply free the buf since BA retransmission is done in the firmware
1524     if (buf)
1525     {
1526         zfwBufFree(dev, buf, 0);
1527     }
1528     zfPushVtxq(dev);
1529     #else
1530     zmw_get_wlan_dev(dev);
1531
1532     #ifdef ZM_ENABLE_FW_BA_RETRANSMISSION
1533     //Simply free the buf since BA retransmission is done in the firmware
1534     if (buf)
1535     {
1536         zfwBufFree(dev, buf, 0);
1537     }
1538     #else
1539     u8_t agg;
1540     u16_t frameType;
1541
1542     if(!hdr && buf) {
1543         zfwBufFree(dev, buf, 0);
1544         //zm_debug_msg0("buf Free due to hdr == NULL");
1545         return;
1546     }
1547
1548     if(hdr && buf) {
1549         frameType = hdr[8] & 0xf;
1550         agg = (u8_t)(hdr[2] >> 5 ) & 0x1;
1551         //zm_debug_msg1("AGG=", agg);
1552
1553         if (!status) {
1554             if (agg) {
1555                 //delete buf in ba fail queue??
1556                 //not ganna happen?
1557             }
1558             else {
1559                 zfwBufFree(dev, buf, 0);
1560             }
1561         }
1562         else {
1563             if (agg) {
1564                 //don't do anything
1565                 //zfwBufFree(dev, buf, 0);
1566             }
1567             else {
1568                 zfwBufFree(dev, buf, 0);
1569             }
1570         }
1571     }
1572     #endif
1573
1574     if (wd->state != ZM_WLAN_STATE_ENABLED) {
1575         return;
1576     }
1577
1578     if( (wd->wlanMode == ZM_MODE_AP) ||
1579         (wd->wlanMode == ZM_MODE_INFRASTRUCTURE && wd->sta.EnableHT) ||
1580         (wd->wlanMode == ZM_MODE_PSEUDO) ) {
1581         zfAggTxScheduler(dev, 0);
1582     }
1583     #endif
1584 #endif
1585
1586     return;
1587
1588 }
1589