fix compile warnings for gcc 6.2.0
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / hif / usb_api_main_patch.c
1 /* shared patches for k2 and magpie */
2
3 #include <ah_osdep.h>
4 #include <rom.h>
5
6 #include "usb_defs.h"
7 #include "usb_type.h"
8 #include "usb_pre.h"
9 #include "usb_extr.h"
10 #include "usb_std.h"
11 #include "reg_defs.h"
12 #include "athos_api.h"
13 #include "usbfifo_api.h"
14
15 #include "adf_os_io.h"
16
17 #include "sys_cfg.h"
18
19 #define USB_EP4_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
20 #define USB_EP3_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
21
22 extern USB_FIFO_CONFIG usbFifoConf;
23 extern Action eUsbCxFinishAction;
24 extern void _fw_usb_suspend_reboot();
25
26 typedef void (* USBFIFO_recv_command)(VBUF *cmd);
27 USBFIFO_recv_command m_origUsbfifoRecvCmd = NULL;
28
29 void _fw_usbfifo_recv_command(VBUF *buf)
30 {
31         uint8_t *cmd_data;
32         uint32_t tmp;
33
34         cmd_data = (uint8_t *)(buf->desc_list->buf_addr +
35                                 buf->desc_list->data_offset);
36         tmp = *((uint32_t *)cmd_data);
37         if (tmp == 0xFFFFFFFF)
38                 _fw_usb_suspend_reboot();
39         else
40                 m_origUsbfifoRecvCmd(buf);
41 }
42
43 void _fw_usbfifo_init(USB_FIFO_CONFIG *pConfig)
44 {
45         m_origUsbfifoRecvCmd = pConfig->recv_command;
46
47         usbFifoConf.get_command_buf = pConfig->get_command_buf;
48         usbFifoConf.recv_command    = _fw_usbfifo_recv_command;
49         usbFifoConf.get_event_buf   = pConfig->get_event_buf;
50         usbFifoConf.send_event_done = pConfig->send_event_done;
51 }
52
53 void cold_reboot(void)
54 {
55         A_PRINTF("Cold reboot initiated.");
56 #if defined(PROJECT_MAGPIE)
57         iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, 0);
58 #elif defined(PROJECT_K2)
59         iowrite32(MAGPIE_REG_RST_STATUS_ADDR, 0);
60 #endif /* #if defined(PROJECT_MAGPIE) */
61         A_USB_JUMP_BOOT();
62 }
63
64 /*
65  * support more than 64 bytes command on ep3
66  */
67 void usb_status_in_patch(void)
68 {
69         uint16_t count;
70         uint16_t remainder;
71         uint16_t reg_buf_len;
72         static uint16_t buf_len;
73         static VBUF *evntbuf = NULL;
74         static volatile uint32_t *regaddr;
75         static BOOLEAN cmd_is_new = TRUE;
76         BOOLEAN cmd_end = FALSE;
77
78         if (cmd_is_new) {
79                 evntbuf = usbFifoConf.get_event_buf();
80                 if (evntbuf != NULL) {
81                         regaddr = (uint32_t *)VBUF_GET_DATA_ADDR(evntbuf);
82                         buf_len = evntbuf->buf_length;
83                 } else {
84                         mUSB_STATUS_IN_INT_DISABLE();
85                         return;
86                 }
87
88                 cmd_is_new = FALSE;
89         }
90
91         if (buf_len > USB_EP3_MAX_PKT_SIZE) {
92                 reg_buf_len = USB_EP3_MAX_PKT_SIZE;
93                 buf_len -= USB_EP3_MAX_PKT_SIZE;
94         }
95         /* TODO: 64 bytes...
96          * controller supposed will take care of zero-length? */
97         else {
98                 reg_buf_len = buf_len;
99                 cmd_end = TRUE;
100         }
101
102         /* INT use EP3 */
103         for (count = 0; count < (reg_buf_len / 4); count++)
104         {
105                 iowrite32_usb(ZM_EP3_DATA_OFFSET, *regaddr);
106                 regaddr++;
107         }
108
109         remainder = reg_buf_len % 4;
110
111         if (remainder) {
112                 switch(remainder) {
113                 case 3:
114                         iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7);
115                         break;
116                 case 2:
117                         iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3);
118                         break;
119                 case 1:
120                         iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1);
121                         break;
122                 }
123
124                 iowrite32_usb(ZM_EP3_DATA_OFFSET, *regaddr);
125
126                 /* Restore CBus FIFO size to word size */
127                 iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF);
128         }
129
130         mUSB_EP3_XFER_DONE();
131
132         if (evntbuf != NULL && cmd_end) {
133                 usbFifoConf.send_event_done(evntbuf);
134                 cmd_is_new = TRUE;
135         }
136 }
137
138 /*
139  * support more than 64 bytes command on ep4 
140  */
141 void usb_reg_out_patch(void)
142 {
143         uint16_t usbfifolen;
144         uint16_t ii;
145         uint32_t ep4_data;
146         static volatile uint32_t *regaddr;
147         static uint16_t cmd_len;
148         static VBUF *buf;
149         BOOLEAN cmd_is_last = FALSE;
150         static BOOLEAN cmd_is_new = TRUE;
151
152         /* get the size of this transcation */
153         usbfifolen = ioread8_usb(ZM_EP4_BYTE_COUNT_LOW_OFFSET);
154
155         if (usbfifolen > USB_EP4_MAX_PKT_SIZE) {
156                 A_PRINTF("EP4 FIFO Bug? Buffer is too big: %x\n", usbfifolen);
157                 cold_reboot();
158         }
159
160         /* check is command is new */
161         if(cmd_is_new) {
162
163                 buf = usbFifoConf.get_command_buf();
164                 cmd_len = 0;
165
166                 if(!buf) {
167                         A_PRINTF("%s: Filed to get new buffer.\n", __func__);
168                         goto err;
169                 }
170
171                 /* copy free, assignment buffer of the address */
172                 regaddr = (uint32_t *)buf->desc_list->buf_addr;
173
174                 cmd_is_new = FALSE;
175         }
176
177         /* just in case, suppose should not happen */
178         if(!buf)
179                 goto err;
180
181         /* if size is smaller, this is the last command!
182          * zero-length supposed should be set through 0x27/bit7->0x19/bit4, not here
183          */
184         if(usbfifolen < USB_EP4_MAX_PKT_SIZE)
185                 cmd_is_last = TRUE;
186
187         /* accumulate the size */
188         cmd_len += usbfifolen;
189
190         if (cmd_len > buf->desc_list->buf_size) {
191                 A_PRINTF("%s: Data length on EP4 FIFO is bigger as "
192                          "allocated buffer data! Drop it!\n", __func__);
193                 goto err;
194         }
195
196         /* round it to alignment */
197         if(usbfifolen % 4)
198                 usbfifolen = (usbfifolen >> 2) + 1;
199         else
200                 usbfifolen = usbfifolen >> 2;
201
202         /* retrieve the data from fifo */
203         for(ii = 0; ii < usbfifolen; ii++) {
204                 /* read fifo data out */
205                 ep4_data = ioread32_usb(ZM_EP4_DATA_OFFSET);
206                 *regaddr = ep4_data;
207                 regaddr++;
208         }
209
210         /* if this is the last command, callback to HTC */
211         if (cmd_is_last) {
212                 buf->desc_list->next_desc = NULL;
213                 buf->desc_list->data_offset = 0;
214                 buf->desc_list->data_size = cmd_len;
215                 buf->desc_list->control = 0;
216                 buf->next_buf = NULL;
217                 buf->buf_length = cmd_len;
218
219                 usbFifoConf.recv_command(buf);
220
221                 cmd_is_new = TRUE;
222         }
223
224         goto done;
225 err:
226         /* we might get no command buffer here?
227          * but if we return here, the ep4 fifo will be lock out,
228          * so that we still read them out but just drop it? */
229         for(ii = 0; ii < usbfifolen; ii++)
230                 ep4_data = ioread32_usb(ZM_EP4_DATA_OFFSET);
231
232 done:
233         /* mUSB_STATUS_IN_INT_ENABLE(); */
234         ;
235 }
236
237 /*
238  * usb1.1 ep6 fix
239  * TODO:
240  * - theoretically ep6 configured same way as ep1
241  * so, if there are some problems we should have it
242  * there too.
243  * - do we really need support usb1.1?
244  */
245 extern uint16_t         u8UsbConfigValue;
246 extern uint16_t         u8UsbInterfaceValue;
247 extern uint16_t         u8UsbInterfaceAlternateSetting;
248 extern SetupPacket      ControlCmd;
249 extern void             vUsbClrEPx(void);
250
251 #undef FS_C1_I0_A0_EP_NUMBER
252 #define FS_C1_I0_A0_EP_NUMBER 6
253
254 #define FS_C1_I0_A0_EP6_BLKSIZE    BLK512BYTE
255 #define FS_C1_I0_A0_EP6_BLKNO      DOUBLE_BLK
256 #define FS_C1_I0_A0_EP6_DIRECTION  DIRECTION_OUT
257 #define FS_C1_I0_A0_EP6_TYPE       TF_TYPE_BULK
258 #define FS_C1_I0_A0_EP6_MAX_PACKET 0x0040
259 #define FS_C1_I0_A0_EP6_bInterval  0
260
261 /* EP6 */
262 #define FS_C1_I0_A0_EP6_FIFO_START      \
263          (FS_C1_I0_A0_EP5_FIFO_START + FS_C1_I0_A0_EP5_FIFO_NO)
264 #define FS_C1_I0_A0_EP6_FIFO_NO         \
265          (FS_C1_I0_A0_EP6_BLKNO * FS_C1_I0_A0_EP6_BLKSIZE)
266 #define FS_C1_I0_A0_EP6_FIFO_CONFIG     \
267          (0x80 | ((FS_C1_I0_A0_EP6_BLKSIZE - 1) << 4) | \
268           ((FS_C1_I0_A0_EP6_BLKNO - 1) << 2) | FS_C1_I0_A0_EP6_TYPE)
269 #define FS_C1_I0_A0_EP6_FIFO_MAP        \
270          (((1 - FS_C1_I0_A0_EP6_DIRECTION) << 4) | EP6)
271 #define FS_C1_I0_A0_EP6_MAP             \
272          (FS_C1_I0_A0_EP6_FIFO_START | (FS_C1_I0_A0_EP6_FIFO_START << 4) | \
273           (MASK_F0 >> (4*FS_C1_I0_A0_EP6_DIRECTION)))
274
275 void vUSBFIFO_EP6Cfg_FS_patch(void)
276 {
277 #if (FS_C1_I0_A0_EP_NUMBER >= 6)
278         int i;
279
280         /* EP0X06 */
281         mUsbEPMap(EP6, FS_C1_I0_A0_EP6_MAP);
282         mUsbFIFOMap(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_MAP);
283         mUsbFIFOConfig(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_CONFIG);
284
285         for(i = FS_C1_I0_A0_EP6_FIFO_START + 1 ;
286             i < FS_C1_I0_A0_EP6_FIFO_START + FS_C1_I0_A0_EP6_FIFO_NO ; i ++)
287         {
288                 mUsbFIFOConfig(i, (FS_C1_I0_A0_EP6_FIFO_CONFIG & (~BIT7)) );
289         }
290
291         mUsbEPMxPtSzHigh(EP6, FS_C1_I0_A0_EP6_DIRECTION,
292                          (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
293         mUsbEPMxPtSzLow(EP6, FS_C1_I0_A0_EP6_DIRECTION,
294                         (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
295         mUsbEPinHighBandSet(EP6, FS_C1_I0_A0_EP6_DIRECTION,
296                             FS_C1_I0_A0_EP6_MAX_PACKET);
297 #endif
298 }
299
300 void vUsbFIFO_EPxCfg_FS_patch(void)
301 {
302         switch (u8UsbConfigValue)
303         {
304 #if (FS_CONFIGURATION_NUMBER >= 1)
305                 /* Configuration 0X01 */
306         case 0X01:
307                 switch (u8UsbInterfaceValue)
308                 {
309 #if (FS_C1_INTERFACE_NUMBER >= 1)
310                         /* Interface 0 */
311                 case 0:
312                         switch (u8UsbInterfaceAlternateSetting)
313                         {
314
315 #if (FS_C1_I0_ALT_NUMBER >= 1)
316                                 /* AlternateSetting 0 */
317                         case 0:
318
319                                 /* snapped.... */
320
321                                 /* patch up this ep6_fs config */
322                                 vUSBFIFO_EP6Cfg_FS_patch();
323
324                                 break;
325
326 #endif
327                         default:
328                                 break;
329                         }
330                         break;
331 #endif
332                 default:
333                         break;
334                 }
335                 break;
336 #endif
337         default:
338                 break;
339         }
340         /* mCHECK_STACK(); */
341 }
342
343 BOOLEAN bSet_configuration_patch(void)
344 {
345         /* do some defaul configuration */
346         bSet_configuration();
347
348         /* overwrite defaul FIFO configuration for FullSpeed USB */
349         if ((mLOW_BYTE(mDEV_REQ_VALUE()) != 0) && !mUsbHighSpeedST())
350                         vUsbFIFO_EPxCfg_FS_patch();
351
352         eUsbCxFinishAction = ACT_DONE;
353         return TRUE;
354 }
355
356 extern BOOLEAN bStandardCommand(void);
357
358 BOOLEAN bStandardCommand_patch(void)
359 {
360         if (mDEV_REQ_REQ() == USB_SET_CONFIGURATION) {
361                 A_USB_SET_CONFIG();
362
363 #if ENABLE_SWAP_DATA_MODE
364                 /* SWAP FUNCTION should be enabled while DMA engine
365                  * is not working, the best place to enable it
366                  * is before we trigger the DMA */
367                 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
368                 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
369
370 #if SYSTEM_MODULE_HP_EP5
371                 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
372 #endif
373
374 #if SYSTEM_MODULE_HP_EP6
375                 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
376 #endif
377
378 #endif /* ENABLE_SWAP_DATA_MODE */
379                 return TRUE;
380         } else
381                 return bStandardCommand();
382 }
383
384 /*
385  * usb descriptor patch
386  */
387
388 extern uint16_t         *u8ConfigDescriptorEX;
389 extern uint16_t         *pu8DescriptorEX;
390 extern uint16_t         u16TxRxCounter;
391 extern SetupPacket      ControlCmd;
392 extern uint16_t         *u8UsbDeviceDescriptor;
393 extern BOOLEAN          bGet_descriptor(void);
394
395 uint16_t ConfigDescriptorPatch[30];
396 uint16_t UsbDeviceDescriptorPatch[9];
397
398 #define BCD_DEVICE_OFFSET               6
399 #define BCD_DEVICE_FW_SIGNATURE         0xffff
400 #define VENDOR_ID_OFFSET                4
401 #define PRODUCT_ID_OFFSET               5
402
403 #define EP3_TRANSFER_TYPE_OFFSET        17
404 #define EP3_INT_INTERVAL                19
405 #define EP4_TRANSFER_TYPE_OFFSET        21
406 #define EP4_INT_INTERVAL                22
407
408 BOOLEAN bGet_descriptor_patch(void)
409 {
410         if (mDEV_REQ_VALUE_HIGH() == 1)
411         {
412                 uint8_t *p = (uint8_t *)u8UsbDeviceDescriptor;
413
414                 /* Copy Usb Device Descriptor */
415                 ath_hal_memcpy(UsbDeviceDescriptorPatch, p,
416                                 sizeof(UsbDeviceDescriptorPatch));
417
418                 /* Change bcdDevice. we need it to detect if FW
419                  * was uploaded. */
420                 UsbDeviceDescriptorPatch[BCD_DEVICE_OFFSET] =
421                         BCD_DEVICE_FW_SIGNATURE;
422
423                 pu8DescriptorEX = UsbDeviceDescriptorPatch;
424                 u16TxRxCounter = mTABLE_LEN(u8UsbDeviceDescriptor[0]);
425
426                 if (u16TxRxCounter > mDEV_REQ_LENGTH())
427                         u16TxRxCounter = mDEV_REQ_LENGTH();
428
429                 A_USB_EP0_TX_DATA();
430
431                 return TRUE;
432         } else if (mDEV_REQ_VALUE_HIGH() == 2) {
433                 uint8_t *p = (uint8_t *)u8ConfigDescriptorEX;
434
435                 /* Copy ConfigDescriptor */
436                 ath_hal_memcpy(ConfigDescriptorPatch, p,
437                                 sizeof(ConfigDescriptorPatch));
438
439                  /* place holder for EPx patches */
440
441                 if (mDEV_REQ_VALUE_LOW() == 0) {
442                         /* configuration no: 0 */
443                         pu8DescriptorEX = ConfigDescriptorPatch;
444                         u16TxRxCounter = ConfigDescriptorPatch[1];
445                 } else
446                         return FALSE;
447
448                 if (u16TxRxCounter > mDEV_REQ_LENGTH())
449                         u16TxRxCounter = mDEV_REQ_LENGTH();
450
451                 A_USB_EP0_TX_DATA();
452                 return TRUE;
453         } else
454                 return bGet_descriptor();
455 }
456