usb_api_main_patch.c use new io funcs
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / hif / usb_api_main_patch.c
index 10a1123a97c7405b04c086f2f95c8ca8da9858cc..d1cc35e4e7132d7f49092456dab46ac3f7a1c7f5 100644 (file)
@@ -1,3 +1,4 @@
+/* shared patches for k2 and magpie */
 
 #include "usb_defs.h"
 #include "usb_type.h"
@@ -8,20 +9,51 @@
 #include "athos_api.h"
 #include "usbfifo_api.h"
 
+#include "adf_os_io.h"
+
 #include "sys_cfg.h"
 
 #define USB_EP4_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
 #define USB_EP3_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
 
 extern USB_FIFO_CONFIG usbFifoConf;
+extern Action eUsbCxFinishAction;
+extern void _fw_usb_suspend_reboot();
+
+typedef void (* USBFIFO_recv_command)(VBUF *cmd);
+USBFIFO_recv_command m_origUsbfifoRecvCmd = NULL;
+
+void _fw_usbfifo_recv_command(VBUF *buf)
+{
+       uint8_t *cmd_data;
+       uint32_t tmp;
+
+       cmd_data = (uint8_t *)(buf->desc_list->buf_addr +
+                               buf->desc_list->data_offset);
+       tmp = *((uint32_t *)cmd_data);
+       if (tmp == 0xFFFFFFFF)
+               _fw_usb_suspend_reboot();
+       else
+               m_origUsbfifoRecvCmd(buf);
+}
+
+void _fw_usbfifo_init(USB_FIFO_CONFIG *pConfig)
+{
+       m_origUsbfifoRecvCmd = pConfig->recv_command;
+
+       usbFifoConf.get_command_buf = pConfig->get_command_buf;
+       usbFifoConf.recv_command    = _fw_usbfifo_recv_command;
+       usbFifoConf.get_event_buf   = pConfig->get_event_buf;
+       usbFifoConf.send_event_done = pConfig->send_event_done;
+}
 
 void cold_reboot(void)
 {
        A_PRINTF("Cold reboot initiated.");
 #if defined(PROJECT_MAGPIE)
-       HAL_WORD_REG_WRITE(WATCH_DOG_MAGIC_PATTERN_ADDR, 0);
+       iowrite32(WATCH_DOG_MAGIC_PATTERN_ADDR, 0);
 #elif defined(PROJECT_K2)
-       HAL_WORD_REG_WRITE(MAGPIE_REG_RST_STATUS_ADDR, 0);
+       iowrite32(MAGPIE_REG_RST_STATUS_ADDR, 0);
 #endif /* #if defined(PROJECT_MAGPIE) */
        A_USB_JUMP_BOOT();
 }
@@ -67,7 +99,7 @@ void usb_status_in_patch(void)
        /* INT use EP3 */
        for (count = 0; count < (reg_buf_len / 4); count++)
        {
-               USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
+               iowrite32_usb(ZM_EP3_DATA_OFFSET, *regaddr);
                regaddr++;
        }
 
@@ -76,20 +108,20 @@ void usb_status_in_patch(void)
        if (remainder) {
                switch(remainder) {
                case 3:
-                       USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7);
+                       iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7);
                        break;
                case 2:
-                       USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3);
+                       iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3);
                        break;
                case 1:
-                       USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1);
+                       iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1);
                        break;
                }
 
-               USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
+               iowrite32_usb(ZM_EP3_DATA_OFFSET, *regaddr);
 
                /* Restore CBus FIFO size to word size */
-               USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF);
+               iowrite32_usb(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF);
        }
 
        mUSB_EP3_XFER_DONE();
@@ -115,7 +147,7 @@ void usb_reg_out_patch(void)
        static BOOLEAN cmd_is_new = TRUE;
 
        /* get the size of this transcation */
-       usbfifolen = USB_BYTE_REG_READ(ZM_EP4_BYTE_COUNT_LOW_OFFSET);
+       usbfifolen = ioread8_usb(ZM_EP4_BYTE_COUNT_LOW_OFFSET);
 
        if (usbfifolen > USB_EP4_MAX_PKT_SIZE) {
                A_PRINTF("EP4 FIFO Bug? Buffer is too big: %x\n", usbfifolen);
@@ -167,7 +199,7 @@ void usb_reg_out_patch(void)
        /* retrieve the data from fifo */
        for(ii = 0; ii < usbfifolen; ii++) {
                /* read fifo data out */
-               ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET);
+               ep4_data = ioread32_usb(ZM_EP4_DATA_OFFSET);
                *regaddr = ep4_data;
                regaddr++;
        }
@@ -192,10 +224,230 @@ err:
         * but if we return here, the ep4 fifo will be lock out,
         * so that we still read them out but just drop it? */
        for(ii = 0; ii < usbfifolen; ii++)
-               ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET);
+               ep4_data = ioread32_usb(ZM_EP4_DATA_OFFSET);
 
 done:
        /* mUSB_STATUS_IN_INT_ENABLE(); */
        ;
 }
 
+/*
+ * usb1.1 ep6 fix
+ * TODO:
+ * - theoretically ep6 configured same way as ep1
+ * so, if there are some problems we should have it
+ * there too.
+ * - do we really need support usb1.1?
+ */
+extern uint16_t                u8UsbConfigValue;
+extern uint16_t                u8UsbInterfaceValue;
+extern uint16_t                u8UsbInterfaceAlternateSetting;
+extern SetupPacket     ControlCmd;
+extern void            vUsbClrEPx(void);
+
+#undef FS_C1_I0_A0_EP_NUMBER
+#define FS_C1_I0_A0_EP_NUMBER 6
+
+#define FS_C1_I0_A0_EP6_BLKSIZE    BLK512BYTE
+#define FS_C1_I0_A0_EP6_BLKNO      DOUBLE_BLK
+#define FS_C1_I0_A0_EP6_DIRECTION  DIRECTION_OUT
+#define FS_C1_I0_A0_EP6_TYPE       TF_TYPE_BULK
+#define FS_C1_I0_A0_EP6_MAX_PACKET 0x0040
+#define FS_C1_I0_A0_EP6_bInterval  0
+
+/* EP6 */
+#define FS_C1_I0_A0_EP6_FIFO_START     \
+        (FS_C1_I0_A0_EP5_FIFO_START + FS_C1_I0_A0_EP5_FIFO_NO)
+#define FS_C1_I0_A0_EP6_FIFO_NO                \
+        (FS_C1_I0_A0_EP6_BLKNO * FS_C1_I0_A0_EP6_BLKSIZE)
+#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)
+#define FS_C1_I0_A0_EP6_FIFO_MAP       \
+        (((1 - FS_C1_I0_A0_EP6_DIRECTION) << 4) | EP6)
+#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)))
+
+void vUSBFIFO_EP6Cfg_FS_patch(void)
+{
+#if (FS_C1_I0_A0_EP_NUMBER >= 6)
+       int i;
+
+       /* EP0X06 */
+       mUsbEPMap(EP6, FS_C1_I0_A0_EP6_MAP);
+       mUsbFIFOMap(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_MAP);
+       mUsbFIFOConfig(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_CONFIG);
+
+       for(i = FS_C1_I0_A0_EP6_FIFO_START + 1 ;
+            i < FS_C1_I0_A0_EP6_FIFO_START + FS_C1_I0_A0_EP6_FIFO_NO ; i ++)
+       {
+               mUsbFIFOConfig(i, (FS_C1_I0_A0_EP6_FIFO_CONFIG & (~BIT7)) );
+       }
+
+       mUsbEPMxPtSzHigh(EP6, FS_C1_I0_A0_EP6_DIRECTION,
+                        (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
+       mUsbEPMxPtSzLow(EP6, FS_C1_I0_A0_EP6_DIRECTION,
+                       (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
+       mUsbEPinHighBandSet(EP6, FS_C1_I0_A0_EP6_DIRECTION,
+                           FS_C1_I0_A0_EP6_MAX_PACKET);
+#endif
+}
+
+void vUsbFIFO_EPxCfg_FS_patch(void)
+{
+       switch (u8UsbConfigValue)
+       {
+#if (FS_CONFIGURATION_NUMBER >= 1)
+               /* Configuration 0X01 */
+        case 0X01:
+               switch (u8UsbInterfaceValue)
+               {
+#if (FS_C1_INTERFACE_NUMBER >= 1)
+                       /* Interface 0 */
+                case 0:
+                       switch (u8UsbInterfaceAlternateSetting)
+                       {
+
+#if (FS_C1_I0_ALT_NUMBER >= 1)
+                               /* AlternateSetting 0 */
+                        case 0:
+
+                               /* snapped.... */
+
+                               /* patch up this ep6_fs config */
+                               vUSBFIFO_EP6Cfg_FS_patch();
+
+                               break;
+
+#endif
+                        default:
+                               break;
+                       }
+                       break;
+#endif
+                default:
+                       break;
+               }
+               break;
+#endif
+        default:
+               break;
+       }
+       /* mCHECK_STACK(); */
+}
+
+BOOLEAN bSet_configuration_patch(void)
+{
+       /* do some defaul configuration */
+       bSet_configuration();
+
+       /* overwrite defaul FIFO configuration for FullSpeed USB */
+       if ((mLOW_BYTE(mDEV_REQ_VALUE()) != 0) && !mUsbHighSpeedST())
+                       vUsbFIFO_EPxCfg_FS_patch();
+
+       eUsbCxFinishAction = ACT_DONE;
+       return TRUE;
+}
+
+extern BOOLEAN bStandardCommand(void);
+
+BOOLEAN bStandardCommand_patch(void)
+{
+       if (mDEV_REQ_REQ() == USB_SET_CONFIGURATION) {
+               A_USB_SET_CONFIG();
+
+#if ENABLE_SWAP_DATA_MODE
+               /* SWAP FUNCTION should be enabled while DMA engine
+                * is not working, the best place to enable it
+                * is before we trigger the DMA */
+               MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
+               MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
+
+#if SYSTEM_MODULE_HP_EP5
+               MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
+#endif
+
+#if SYSTEM_MODULE_HP_EP6
+               MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
+#endif
+
+#endif /* ENABLE_SWAP_DATA_MODE */
+               return TRUE;
+       } else
+               return bStandardCommand();
+}
+
+/*
+ * usb descriptor patch
+ */
+
+extern uint16_t                *u8ConfigDescriptorEX;
+extern uint16_t                *pu8DescriptorEX;
+extern uint16_t                u16TxRxCounter;
+extern SetupPacket     ControlCmd;
+extern uint16_t                *u8UsbDeviceDescriptor;
+extern BOOLEAN         bGet_descriptor(void);
+
+uint16_t ConfigDescriptorPatch[30];
+uint16_t UsbDeviceDescriptorPatch[9];
+
+#define BCD_DEVICE_OFFSET              6
+#define BCD_DEVICE_FW_SIGNATURE                0xffff
+#define VENDOR_ID_OFFSET               4
+#define PRODUCT_ID_OFFSET              5
+
+#define EP3_TRANSFER_TYPE_OFFSET       17
+#define EP3_INT_INTERVAL               19
+#define EP4_TRANSFER_TYPE_OFFSET       21
+#define EP4_INT_INTERVAL               22
+
+BOOLEAN bGet_descriptor_patch(void)
+{
+       if (mDEV_REQ_VALUE_HIGH() == 1)
+       {
+               uint8_t *p = (uint8_t *)u8UsbDeviceDescriptor;
+
+               /* Copy Usb Device Descriptor */
+               ath_hal_memcpy(UsbDeviceDescriptorPatch, p,
+                               sizeof(UsbDeviceDescriptorPatch));
+
+               /* Change bcdDevice. we need it to detect if FW
+                * was uploaded. */
+               UsbDeviceDescriptorPatch[BCD_DEVICE_OFFSET] =
+                       BCD_DEVICE_FW_SIGNATURE;
+
+               pu8DescriptorEX = UsbDeviceDescriptorPatch;
+               u16TxRxCounter = mTABLE_LEN(u8UsbDeviceDescriptor[0]);
+
+               if (u16TxRxCounter > mDEV_REQ_LENGTH())
+                       u16TxRxCounter = mDEV_REQ_LENGTH();
+
+               A_USB_EP0_TX_DATA();
+
+               return TRUE;
+       } else if (mDEV_REQ_VALUE_HIGH() == 2) {
+               uint8_t *p = (uint8_t *)u8ConfigDescriptorEX;
+
+               /* Copy ConfigDescriptor */
+               ath_hal_memcpy(ConfigDescriptorPatch, p,
+                               sizeof(ConfigDescriptorPatch));
+
+                /* place holder for EPx patches */
+
+               if (mDEV_REQ_VALUE_LOW() == 0) {
+                       /* configuration no: 0 */
+                       pu8DescriptorEX = ConfigDescriptorPatch;
+                       u16TxRxCounter = ConfigDescriptorPatch[1];
+               } else
+                       return FALSE;
+
+               if (u16TxRxCounter > mDEV_REQ_LENGTH())
+                       u16TxRxCounter = mDEV_REQ_LENGTH();
+
+               A_USB_EP0_TX_DATA();
+               return TRUE;
+       } else
+               return bGet_descriptor();
+}
+