hif/usb_api: remove dup code - usb_reg_in_patch
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / rompatch / usb_api_patch.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 #include "usb_defs.h"
36 #include "usb_type.h"
37 #include "usb_pre.h"
38 #include "usb_extr.h"
39 #include "usb_std.h"
40 #include "reg_defs.h"
41 #include "athos_api.h"
42 #include "usbfifo_api.h"
43
44 #include "sys_cfg.h"
45
46 #define measure_time 0
47 #define measure_time_pll 10000000
48
49 typedef void (* USBFIFO_recv_command)(VBUF *cmd);
50
51 extern Action eUsbCxFinishAction;
52 extern CommandType eUsbCxCommand;
53 extern BOOLEAN UsbChirpFinish;
54 extern USB_FIFO_CONFIG usbFifoConf;
55 extern uint16_t *pu8DescriptorEX;
56 extern uint16_t u16TxRxCounter;
57
58 USBFIFO_recv_command m_origUsbfifoRecvCmd = NULL;
59
60 void zfTurnOffPower_patch(void);
61
62 static void _fw_reset_dma_fifo();
63 static void _fw_restore_dma_fifo();
64 static void _fw_power_on();
65 static void _fw_power_off();
66
67 BOOLEAN bEepromExist = TRUE;
68 BOOLEAN bJumptoFlash = FALSE;
69
70 void _fw_usbfifo_recv_command(VBUF *buf)
71 {
72         A_UINT8 *cmd_data;
73         A_UINT32 tmp;
74
75         cmd_data = (A_UINT8 *)(buf->desc_list->buf_addr + buf->desc_list->data_offset);
76         tmp = *((A_UINT32 *)cmd_data);
77         if ( tmp == 0xFFFFFFFF ) {      
78                 // reset usb/wlan dma
79                 _fw_reset_dma_fifo();
80
81                 // restore gpio setting and usb/wlan dma state
82                 _fw_restore_dma_fifo();
83
84                 // set clock to bypass mode - 40Mhz from XTAL 
85                 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4));
86
87                 A_DELAY_USECS(100); // wait for stable
88
89                 HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));
90
91                 A_DELAY_USECS(100); // wait for stable
92                 A_UART_HWINIT((40*1000*1000), 19200);
93
94                 A_CLOCK_INIT(40);
95
96                 if (!bEepromExist) { //jump to flash boot (eeprom data in flash)
97                         bJumptoFlash = TRUE;
98                         A_PRINTF("Jump to Flash BOOT\n");
99                         app_start();
100                 }else{
101                         A_PRINTF("receive the suspend command...\n");
102                         // reboot.....
103                         A_USB_JUMP_BOOT();              
104                 }
105
106         } else {
107                 m_origUsbfifoRecvCmd(buf);
108         }
109 }
110
111 void _fw_usbfifo_init(USB_FIFO_CONFIG *pConfig)
112 {
113         m_origUsbfifoRecvCmd = pConfig->recv_command;
114
115         usbFifoConf.get_command_buf = pConfig->get_command_buf;
116         usbFifoConf.recv_command    = _fw_usbfifo_recv_command;
117         usbFifoConf.get_event_buf   = pConfig->get_event_buf;
118         usbFifoConf.send_event_done = pConfig->send_event_done;
119 }
120
121 /* 
122  *  -- usb1.1 ep6 fix --
123  */
124 extern uint16_t       u8UsbConfigValue;
125 extern uint16_t       u8UsbInterfaceValue;
126 extern uint16_t       u8UsbInterfaceAlternateSetting;
127 extern SetupPacket    ControlCmd;
128 extern void vUsbClrEPx(void);
129
130 #undef FS_C1_I0_A0_EP_NUMBER
131 #define FS_C1_I0_A0_EP_NUMBER 6
132
133 #define FS_C1_I0_A0_EP6_BLKSIZE    BLK512BYTE
134 #define FS_C1_I0_A0_EP6_BLKNO      DOUBLE_BLK
135 #define FS_C1_I0_A0_EP6_DIRECTION  DIRECTION_OUT
136 #define FS_C1_I0_A0_EP6_TYPE       TF_TYPE_BULK
137 #define FS_C1_I0_A0_EP6_MAX_PACKET 0x0040
138 #define FS_C1_I0_A0_EP6_bInterval  00
139
140 // EP6
141 #define FS_C1_I0_A0_EP6_FIFO_START  (FS_C1_I0_A0_EP5_FIFO_START + FS_C1_I0_A0_EP5_FIFO_NO)
142 #define FS_C1_I0_A0_EP6_FIFO_NO     (FS_C1_I0_A0_EP6_BLKNO * FS_C1_I0_A0_EP6_BLKSIZE)
143 #define FS_C1_I0_A0_EP6_FIFO_CONFIG (0x80 | ((FS_C1_I0_A0_EP6_BLKSIZE - 1) << 4) | ((FS_C1_I0_A0_EP6_BLKNO - 1) << 2) | FS_C1_I0_A0_EP6_TYPE)
144 #define FS_C1_I0_A0_EP6_FIFO_MAP    (((1 - FS_C1_I0_A0_EP6_DIRECTION) << 4) | EP6)
145 #define FS_C1_I0_A0_EP6_MAP         (FS_C1_I0_A0_EP6_FIFO_START |   (FS_C1_I0_A0_EP6_FIFO_START << 4)   | (MASK_F0 >> (4*FS_C1_I0_A0_EP6_DIRECTION)))
146
147
148 #define CMD_PCI_RC_RESET_ON() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \
149                          (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \
150                           (PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT)))
151
152 void vUSBFIFO_EP6Cfg_FS_patch(void)
153 {
154 #if (FS_C1_I0_A0_EP_NUMBER >= 6)
155         int i;
156
157         //EP0X06
158         mUsbEPMap(EP6, FS_C1_I0_A0_EP6_MAP);
159         mUsbFIFOMap(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_MAP);
160         mUsbFIFOConfig(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_CONFIG);
161
162         for(i = FS_C1_I0_A0_EP6_FIFO_START + 1 ;
163             i < FS_C1_I0_A0_EP6_FIFO_START + FS_C1_I0_A0_EP6_FIFO_NO ; i ++)
164         {
165                 mUsbFIFOConfig(i, (FS_C1_I0_A0_EP6_FIFO_CONFIG & (~BIT7)) );
166         }
167
168         mUsbEPMxPtSzHigh(EP6, FS_C1_I0_A0_EP6_DIRECTION, (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
169         mUsbEPMxPtSzLow(EP6, FS_C1_I0_A0_EP6_DIRECTION, (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
170         mUsbEPinHighBandSet(EP6 , FS_C1_I0_A0_EP6_DIRECTION, FS_C1_I0_A0_EP6_MAX_PACKET);
171 #endif
172 }
173
174 void vUsbFIFO_EPxCfg_FS_patch(void)
175 {
176         switch (u8UsbConfigValue)
177         {
178 #if (FS_CONFIGURATION_NUMBER >= 1)
179                 // Configuration 0X01
180         case 0X01:
181                 switch (u8UsbInterfaceValue)
182                 {
183 #if (FS_C1_INTERFACE_NUMBER >= 1)
184                         // Interface 0
185                 case 0:
186                         switch (u8UsbInterfaceAlternateSetting)
187                         {
188
189 #if (FS_C1_I0_ALT_NUMBER >= 1)
190                                 // AlternateSetting 0
191                         case 0:
192
193                                 // snapped....
194
195                                 // patch up this ep6_fs config
196                                 vUSBFIFO_EP6Cfg_FS_patch();
197
198                                 break;
199
200 #endif
201                         default:
202                                 break;
203                         }
204                         break;
205 #endif
206                 default:
207                         break;
208                 }
209                 break;
210 #endif
211         default:
212                 break;
213         }
214         //mCHECK_STACK();
215 }
216
217
218 BOOLEAN bSet_configuration_patch(void)
219 {
220         bSet_configuration();
221
222         if (mLOW_BYTE(mDEV_REQ_VALUE()) == 0)
223         {
224                 // snapped....
225                 ;
226         }
227         else
228         {
229                 if (mUsbHighSpeedST())                  // First judge HS or FS??
230                 {
231                         // snapped....
232                         ;
233                 }
234                 else
235                 {
236                         // snapped....
237                         vUsbFIFO_EPxCfg_FS_patch();
238                 }
239
240                 // snapped....
241         }
242
243         eUsbCxFinishAction = ACT_DONE;
244         return TRUE;
245 }
246
247
248
249 #define PCI_RC_RESET_BIT                            BIT6
250 #define PCI_RC_PHY_RESET_BIT                        BIT7
251 #define PCI_RC_PLL_RESET_BIT                        BIT8
252 #define PCI_RC_PHY_SHIFT_RESET_BIT                  BIT10
253
254
255 /*
256  * -- urn_off_merlin --
257  * . values suggested from Lalit
258  *
259  */
260 static void turn_off_merlin()
261 {
262         volatile uint32_t default_data[9];
263         uint32_t i=0;
264
265         if(1)
266         {
267                 A_PRINTF("turn_off_merlin_ep_start ......\n");
268                 A_DELAY_USECS(measure_time);
269                 default_data[0] = 0x9248fd00;
270                 default_data[1] = 0x24924924;
271                 default_data[2] = 0xa8000019;
272                 default_data[3] = 0x17160820;
273                 default_data[4] = 0x25980560;
274                 default_data[5] = 0xc1c00000;
275                 default_data[6] = 0x1aaabe40;
276                 default_data[7] = 0xbe105554;
277                 default_data[8] = 0x00043007;
278         
279                 for(i=0; i<9; i++)
280                 {
281                         A_DELAY_USECS(10);
282         
283                         HAL_WORD_REG_WRITE( 0x10ff4040, default_data[i]); 
284                 }
285                 A_DELAY_USECS(10);
286                 HAL_WORD_REG_WRITE(0x10ff4044, BIT0);
287                 A_PRINTF("turn_off_merlin_ep_end ......\n");
288         }
289 }
290
291 /*
292  * -- turn_off_phy --
293  *
294  * . write shift register to both pcie ep and rc
295  * . 
296  */
297
298 static void turn_off_phy()
299 {
300
301         volatile uint32_t default_data[9];
302         volatile uint32_t read_data = 0;
303         uint32_t i=0;
304
305         default_data[0] = 0x9248fd00;
306         default_data[1] = 0x24924924;
307         default_data[2] = 0xa8000019;
308         default_data[3] = 0x17160820;
309         default_data[4] = 0x25980560;
310         default_data[5] = 0xc1c00000;
311         default_data[6] = 0x1aaabe40;
312         default_data[7] = 0xbe105554;
313         default_data[8] = 0x00043007;
314
315         for(i=0; i<9; i++)
316         {
317                 // check for the done bit to be set 
318
319                 while (1)
320                 {
321                         read_data=HAL_WORD_REG_READ(0x40028);
322                         if( read_data & BIT31 )
323                                 break;
324                 }
325         
326                 A_DELAY_USECS(1);
327     
328                 HAL_WORD_REG_WRITE( 0x40024, default_data[i]); 
329         }
330         HAL_WORD_REG_WRITE(0x40028, BIT0);
331 }
332
333 static void turn_off_phy_rc()
334 {
335     
336         volatile uint32_t default_data[9];
337         volatile uint32_t read_data = 0;
338         uint32_t i=0;
339     
340         A_PRINTF("turn_off_phy_rc\n");
341     
342         default_data[0] = 0x9248fd00;
343         default_data[1] = 0x24924924;
344         default_data[2] = 0xa8000019;
345         default_data[3] = 0x13160820;//PwdClk1MHz=0
346         default_data[4] = 0x25980560;
347         default_data[5] = 0xc1c00000;
348         default_data[6] = 0x1aaabe40;
349         default_data[7] = 0xbe105554;
350         default_data[8] = 0x00043007;
351         
352         for(i=0; i<9; i++)
353         {
354                 // check for the done bit to be set 
355      
356                 while (1)
357                 {
358                         read_data=HAL_WORD_REG_READ(0x40028);
359                         if( read_data & BIT31 )
360                                 break;
361                 }
362
363                 A_DELAY_USECS(1);
364
365                 HAL_WORD_REG_WRITE( 0x40024, default_data[i]); 
366         }
367         HAL_WORD_REG_WRITE(0x40028, BIT0);
368 }
369
370 volatile uint32_t gpio_func = 0x0;
371 volatile uint32_t gpio = 0x0;
372
373 /*
374  * -- patch zfTurnOffPower --
375  *
376  * . set suspend counter to non-zero value
377  * . 
378  */
379 void zfTurnOffPower_patch(void)
380 {
381         A_PRINTF("+++ goto suspend ......\n");
382
383         // setting the go suspend here, power down right away...
384         HAL_WORD_REG_WRITE(0x10000, HAL_WORD_REG_READ(0x10000)|(0x8));
385
386         A_DELAY_USECS(100);
387
388         // TURN OFF ETH PLL
389         _fw_power_off();
390
391         //32clk wait for External ETH PLL stable
392         A_DELAY_USECS(100);
393     
394         HAL_WORD_REG_WRITE(0x52000, 0x70303);//read back 0x703f7
395         HAL_WORD_REG_WRITE(0x52008, 0x0e91c);//read back 0x1e948    
396     
397         HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
398                            (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(BIT0))); //0x56030
399         // wake up, and turn on cpu, eth, pcie and usb pll 
400         _fw_power_on();
401         // restore gpio and other settings
402         _fw_restore_dma_fifo();
403
404         // clear suspend..................
405         HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
406                            (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)&(~BIT0)));
407         HAL_WORD_REG_WRITE(0x52028, HAL_WORD_REG_READ(0x52028)&(~(BIT8|BIT12|BIT16)));
408 }
409
410 /*
411  * -- patch zfResetUSBFIFO_patch --
412  *
413  * . clear ep3/ep4 fifo
414  * . set suspend magic pattern
415  * . reset pcie ep phy
416  * . reset pcie rc phy
417  * . turn off pcie pll
418  * . reset all pcie/gmac related registers
419  * . reset usb dma
420  */
421 void zfResetUSBFIFO_patch(void)
422 {
423         A_PRINTF("0x9808  0x%x ......\n", HAL_WORD_REG_READ(0x10ff9808));
424         A_PRINTF("0x7890  0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
425         A_PRINTF("0x7890  0x%x ......\n", HAL_WORD_REG_READ(0x10ff7890));
426         A_PRINTF("0x4088  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
427         _fw_reset_dma_fifo();
428 }
429
430 static void _fw_reset_dma_fifo()
431 {
432         HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100ae)|0x10));
433         HAL_BYTE_REG_WRITE(0x100ae, (HAL_BYTE_REG_READ(0x100af)|0x10));
434         A_PRINTF("_fw_reset_dma_fifo\n");
435
436         // disable ep3 int enable, so that resume back won't send wdt magic pattern out!!!
437         mUSB_STATUS_IN_INT_DISABLE();
438
439         // update magic pattern to indicate this is a suspend
440         HAL_WORD_REG_WRITE(WATCH_DOG_MAGIC_PATTERN_ADDR, SUS_MAGIC_PATTERN);
441
442         A_PRINTF("org 0x4048  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
443         A_PRINTF("org 0x404C  0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
444         A_PRINTF("org 0x4088  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
445
446         HAL_WORD_REG_WRITE(0x10ff4088,0xaaa6a);//1010.1010.1010.0110.1010 for UB94
447         HAL_WORD_REG_WRITE(0x10ff404C,0x0);
448
449         A_DELAY_USECS(1000);
450         A_PRINTF("0x4048  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4048));
451         A_PRINTF("0x404C  0x%x ......\n", HAL_WORD_REG_READ(0x10ff404C));
452         A_PRINTF("0x4088  0x%x ......\n", HAL_WORD_REG_READ(0x10ff4088));
453          
454         // turn off merlin
455         turn_off_merlin();
456         // pcie ep
457         A_PRINTF("turn_off_magpie_ep_start ......\n");
458         A_DELAY_USECS(measure_time);
459         HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)|BIT0|(1<<1)));
460         turn_off_phy();
461         HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&~(BIT0|(1<<1))));
462         A_PRINTF("turn_off_magpie_ep_end ......\n");
463
464         // pcie rc 
465         A_PRINTF("turn_off_magpie_rc_start ......\n");
466         A_DELAY_USECS(measure_time);
467         HAL_WORD_REG_WRITE( 0x40040, (HAL_WORD_REG_READ(0x40040)&(~BIT0)));
468         turn_off_phy_rc();
469         A_PRINTF("turn_off_magpie_rc_end ......down\n");
470         A_DELAY_USECS(measure_time);
471
472         A_PRINTF("0x4001C  %p ......\n", HAL_WORD_REG_READ(0x4001c)); 
473         A_PRINTF("0x40040  %p ......\n", HAL_WORD_REG_READ(0x40040));
474     
475         // turn off pcie_pll - power down (bit16)
476         A_PRINTF(" before pwd PCIE PLL CFG:0x5601C  %p ......\n", HAL_WORD_REG_READ(0x5601C));
477         HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)|(BIT18)));   
478         A_PRINTF(" after pwd PCIE PLL CFG:0x5601C  %p ......\n", HAL_WORD_REG_READ(0x5601C));
479
480         /* set everything to reset state?, requested by Oligo */
481         HAL_WORD_REG_WRITE(0x50010, HAL_WORD_REG_READ(0x50010)|(BIT13|BIT12|BIT11|BIT9|BIT7|BIT6));
482
483         HAL_WORD_REG_WRITE(0x5C000, 0);
484
485         A_DELAY_USECS(10);
486
487         // reset usb DMA controller
488         HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x0);
489
490         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT4)));
491         A_DELAY_USECS(5);
492         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~BIT4)));
493
494
495         HAL_WORD_REG_WRITE((USB_CTRL_BASE_ADDRESS+0x118), 0x1);
496 }
497
498 static void _fw_power_off()
499 {
500         /*
501          *  1. set CPU bypass
502          *  2. turn off CPU PLL
503          *  3. turn off ETH PLL
504          *  4. disable ETH PLL bypass and update
505          *  4.1 set suspend timeout 
506          *  5. set SUSPEND_ENABLE
507          */
508
509         HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_BYPASS_ADDR, (BIT0|BIT4)); //0x56004
510
511         A_DELAY_USECS(100); // wait for stable
512
513         HAL_WORD_REG_WRITE(MAGPIE_REG_CPU_PLL_ADDR, (BIT16));//0x56000
514
515         A_DELAY_USECS(100); // wait for stable
516
517         A_UART_HWINIT((40*1000*1000), 19200);
518         A_CLOCK_INIT(40);
519
520         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
521                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)|(BIT16)));   //0x5600c
522
523         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
524                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)|(BIT4|BIT0))); //0x56010
525
526         HAL_WORD_REG_WRITE(MAGPIE_REG_SUSPEND_ENABLE_ADDR,
527                            (HAL_WORD_REG_READ(MAGPIE_REG_SUSPEND_ENABLE_ADDR)|(0x10<<8))); //0x56030
528 }
529
530 static void _fw_power_on()
531
532     /*
533      *  1. turn on CPU PLL
534      *  2. disable CPU bypass
535      *  3. turn on ETH PLL
536      *  4. disable ETH PLL bypass and update
537      *  5. turn on pcie pll
538      */    
539
540         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_ADDR,
541                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_ADDR)&(~BIT16)));
542
543         // deassert eth_pll bypass mode and trigger update bit
544         HAL_WORD_REG_WRITE(MAGPIE_REG_ETH_PLL_BYPASS_ADDR,
545                            (HAL_WORD_REG_READ(MAGPIE_REG_ETH_PLL_BYPASS_ADDR)&(~(BIT4|BIT0))));
546 }
547
548 static void _fw_restore_dma_fifo(void)
549 {
550         HAL_WORD_REG_WRITE(0x5601C, (HAL_WORD_REG_READ(0x5601C)&(~(BIT18))));
551     
552         // reset pcie_rc shift 
553         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)&(~(BIT10|BIT8|BIT7))));
554         A_DELAY_USECS(1);
555         HAL_WORD_REG_WRITE(0x50010, (HAL_WORD_REG_READ(0x50010)|(BIT10|BIT8|BIT7)));
556
557         // reset pci_rc phy
558         CMD_PCI_RC_RESET_ON();
559         A_DELAY_USECS(20);
560
561         // enable dma swap function
562         MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
563         MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
564         MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
565         MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
566 }
567
568 extern uint16_t *u8ConfigDescriptorEX;
569 extern uint16_t *pu8DescriptorEX;
570 extern uint16_t u16TxRxCounter;
571
572 extern uint16_t *u8UsbDeviceDescriptor;
573
574 extern BOOLEAN bGet_descriptor(void);
575
576 uint16_t ConfigDescriptorPatch[30];
577
578 uint16_t UsbDeviceDescriptorPatch[9];
579 #define BCD_DEVICE_OFFSET               6
580 #define BCD_DEVICE_FW_SIGNATURE         0xffff
581 #define VENDOR_ID_OFFSET                4
582 #define PRODUCT_ID_OFFSET               5
583
584 #define EP3_TRANSFER_TYPE_OFFSET    17
585 #define EP3_INT_INTERVAL            19
586 #define EP4_TRANSFER_TYPE_OFFSET    21
587 #define EP4_INT_INTERVAL            22
588
589
590
591  #define A_SFLASH_READ_4B(u32Data, start_addr) u32Data = *(uint32_t *)(0xf000000+start_addr);
592  #define FLASH_SIZE 0x800000 //8M
593  #define FLASH_USB_VENDOR_ID_OFFSET     0x86
594  #define FLASH_USB_PRODUCT_ID_OFFSET    0x87
595
596  // flash reserved size for saving eeprom data is 4K.
597  #define EE_DATA_RESERVED_LEN 0x1000 //4K
598
599 #define mLOW_MASK(u16)          ((uint8_t) ((u16) & mMASK(8)))
600 #define mHIGH_MASK(u16)         ((uint8_t) ((u16) & ~mMASK(8)))
601
602 /* (1234) -> 0034 */
603 //#define mLOW_BYTE(u16)          ((U_8)(u16))
604 #define mLOW_BYTE(u16)          mLOW_MASK(u16)
605 /* (1234) -> 0012 */
606 #define mHIGH_BYTE(u16)         ((uint8_t) (((uint16_t) (u16)) >> 8))
607
608 #define mLOW_WORD0(u32)         ((uint16_t) ((u32) & 0xFFFF))
609 #define mHIGH_WORD0(u32)        ((uint16_t) ((u32) >> 16))
610
611 /* (1234) -> 3412 */
612 #define mSWAP_BYTE(u16)         ((mLOW_MASK(u16) << 8) | mHIGH_BYTE(u16))
613  
614 BOOLEAN bGet_descriptor_patch(void)
615 {
616         if (mDEV_REQ_VALUE_HIGH() == 1)
617         {
618                 uint8_t *p = (uint8_t *)u8UsbDeviceDescriptor;
619                 uint32_t u32Tmp=0;
620                 /* Copy Usb Device Descriptor */
621                 ath_hal_memcpy(UsbDeviceDescriptorPatch, p, sizeof(UsbDeviceDescriptorPatch));
622
623                 UsbDeviceDescriptorPatch[BCD_DEVICE_OFFSET] =
624                         BCD_DEVICE_FW_SIGNATURE;
625
626                 /* Patch for custom id from flash */
627                 if (bEepromExist == FALSE) {
628                         A_SFLASH_READ_4B(u32Tmp, FLASH_SIZE -
629                                 EE_DATA_RESERVED_LEN + FLASH_USB_VENDOR_ID_OFFSET*2);
630                         UsbDeviceDescriptorPatch[VENDOR_ID_OFFSET] =
631                                 mSWAP_BYTE(mLOW_WORD0(u32Tmp));
632                         UsbDeviceDescriptorPatch[PRODUCT_ID_OFFSET] =
633                                 mSWAP_BYTE(mHIGH_WORD0(u32Tmp));
634                 }
635       
636                 pu8DescriptorEX = UsbDeviceDescriptorPatch;
637                 u16TxRxCounter = mTABLE_LEN(u8UsbDeviceDescriptor[0]);
638   
639                 if (u16TxRxCounter > mDEV_REQ_LENGTH())  
640                         u16TxRxCounter = mDEV_REQ_LENGTH();
641              
642                 A_USB_EP0_TX_DATA();
643            
644                 //u16TxRxCounter = 18;
645                 return TRUE;
646         }  
647         if (mDEV_REQ_VALUE_HIGH() == 2) {
648                 uint8_t *p = (uint8_t *)u8ConfigDescriptorEX;
649
650                 /* Copy ConfigDescriptor */
651                 ath_hal_memcpy(ConfigDescriptorPatch, p, sizeof(ConfigDescriptorPatch));
652
653                  /* place holder for EPx patches */
654
655                 switch (mDEV_REQ_VALUE_LOW())
656                 {
657                 case 0x00:      // configuration no: 0
658                         pu8DescriptorEX = ConfigDescriptorPatch;
659                         u16TxRxCounter = ConfigDescriptorPatch[1];
660                         //u16TxRxCounter = 46;
661                         break;
662                 default:
663                         return FALSE;
664                 }
665
666                 if (u16TxRxCounter > mDEV_REQ_LENGTH())
667                         u16TxRxCounter = mDEV_REQ_LENGTH();
668
669                 A_USB_EP0_TX_DATA();
670                 return TRUE;
671         }
672         else {
673                 return bGet_descriptor();
674         }
675 }
676
677 extern BOOLEAN bStandardCommand(void);
678
679 BOOLEAN bStandardCommand_patch(void)
680 {
681         if (mDEV_REQ_REQ() == USB_SET_CONFIGURATION) {
682                 A_USB_SET_CONFIG();
683
684 #if ENABLE_SWAP_DATA_MODE
685                 // SWAP FUNCTION should be enabled while DMA engine is not working,
686                 // the best place to enable it is before we trigger the DMA
687                 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
688                 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
689
690 #if SYSTEM_MODULE_HP_EP5
691                 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
692 #endif
693
694 #if SYSTEM_MODULE_HP_EP6
695                 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
696 #endif
697
698 #endif //ENABLE_SWAP_DATA_MODE
699                 return TRUE;
700         }
701         else {
702                 return bStandardCommand();
703         }
704 }