blob: a0cf6826e60332319d1c3b9e7d0e4c58f9593c0d [file] [edit]
/******************************************************************************
*
* This file is provided under a dual license. When you use or
* distribute this software, you may choose to be licensed under
* version 2 of the GNU General Public License ("GPLv2 License")
* or BSD License.
*
* GPLv2 License
*
* Copyright(C) 2016 MediaTek Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See http://www.gnu.org/licenses/gpl-2.0.html for more details.
*
* BSD LICENSE
*
* Copyright(C) 2016 MediaTek Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
/*! \file "hif.h"
* \brief Functions for the driver to register bus and setup the IRQ
*
* Functions for the driver to register bus and setup the IRQ
*/
#ifndef _HIF_H
#define _HIF_H
#include "nic_cmd_event.h"
#include "wlan_typedef.h"
#include "nic_tx.h"
/*******************************************************************************
* C O M P I L E R F L A G S
********************************************************************************
*/
/*******************************************************************************
* E X T E R N A L R E F E R E N C E S
********************************************************************************
*/
/*******************************************************************************
* C O N S T A N T S
********************************************************************************
*/
#if defined(_HIF_USB)
#define HIF_NAME "USB"
#else
#error "No HIF defined!"
#endif
#define HIF_CR4_FWDL_SECTION_NUM 2
#define HIF_IMG_DL_STATUS_PORT_IDX 0
#define HIF_IST_LOOP_COUNT (4)
#define HIF_IST_TX_THRESHOLD (1) /* Min msdu count to trigger Tx during INT polling state */
#define HIF_NUM_OF_QM_RX_PKT_NUM (512)
#define HIF_TX_BUFF_COUNT_TC0 256
#define HIF_TX_BUFF_COUNT_TC1 256
#define HIF_TX_BUFF_COUNT_TC2 256
#define HIF_TX_BUFF_COUNT_TC3 256
#define HIF_TX_BUFF_COUNT_TC4 256
#define HIF_TX_BUFF_COUNT_TC5 256
#define HIF_TX_RESOURCE_CTRL 0 /* enable/disable TX resource control */
#define HIF_TX_RESOURCE_CTRL_PLE 0 /* enable/disable TX resource control PLE */
#if CFG_USB_TX_AGG
#define HIF_TX_PAGE_SIZE_IN_POWER_OF_2 0
#define HIF_TX_PAGE_SIZE 1 /* in unit of bytes */
#else
#define HIF_TX_PAGE_SIZE_IN_POWER_OF_2 11
#define HIF_TX_PAGE_SIZE 2048 /* in unit of bytes */
#endif
#define USB_EVENT_TYPE (EVENT_EP_TYPE_UNKONW)
#define USB_CMD_EP_OUT (USB_DATA_BULK_OUT_EP8)
#define USB_EVENT_EP_IN (0x85)
#define USB_DATA_EP_IN (0x84)
#define HIF_TX_INIT_CMD_PORT USB_CMD_EP_OUT
#ifdef CFG_USB_REQ_TX_DATA_FFA_CNT
#define USB_REQ_TX_DATA_FFA_CNT (CFG_USB_REQ_TX_DATA_FFA_CNT) /* platform specific USB_REQ_TX_DATA_FFA_CNT */
#else
#define USB_REQ_TX_DATA_FFA_CNT (10)
#endif
#ifdef CFG_USB_REQ_TX_DATA_CNT
#define USB_REQ_TX_DATA_CNT (CFG_USB_REQ_TX_DATA_CNT) /* platform specific USB_REQ_TX_DATA_CNT */
#else
#if CFG_USB_TX_AGG
#define USB_REQ_TX_DATA_CNT (2) /* must be >= 2 */
#else
#define USB_REQ_TX_DATA_CNT (CFG_TX_MAX_PKT_NUM)
#endif
#endif
#define USB_REQ_TX_CMD_CNT (CFG_TX_MAX_CMD_PKT_NUM)
#define USB_REQ_RX_EVENT_CNT (1)
#ifdef CFG_USB_REQ_RX_DATA_CNT
#define USB_REQ_RX_DATA_CNT (CFG_USB_REQ_RX_DATA_CNT) /* platform specific USB_REQ_RX_DATA_CNT */
#else
#define USB_REQ_RX_DATA_CNT (2)
#endif
#define USB_RX_AGGREGTAION_LIMIT (32) /* Unit: K-bytes */
#define USB_RX_AGGREGTAION_TIMEOUT (100) /* Unit: us */
#define USB_RX_AGGREGTAION_PKT_LIMIT (30)
#ifdef MT7668
/* Due to CR4, MT7668 can't enlarge this setting */
#define USB_TX_CMD_BUF_SIZE (1608)
#else
/* enlarge to 2048 from 1608: Radio Measurment frame may be > 1608 bytes */
#define USB_TX_CMD_BUF_SIZE (2048)
#endif
#if CFG_USB_TX_AGG
#define USB_TX_DATA_BUFF_SIZE (32*1024)
#else
#define USB_TX_DATA_BUF_SIZE (NIC_TX_DESC_AND_PADDING_LENGTH + NIC_TX_DESC_HEADER_PADDING_LENGTH + \
NIC_TX_MAX_SIZE_PER_FRAME + LEN_USB_UDMA_TX_TERMINATOR)
#endif
#define USB_RX_EVENT_BUF_SIZE (CFG_RX_MAX_PKT_SIZE + 3 + LEN_USB_RX_PADDING_CSO + 4)
#define USB_RX_DATA_BUF_SIZE (CFG_RX_MAX_PKT_SIZE + \
min(USB_RX_AGGREGTAION_LIMIT * 1024, \
(USB_RX_AGGREGTAION_PKT_LIMIT * \
(CFG_RX_MAX_PKT_SIZE + 3 + LEN_USB_RX_PADDING_CSO) + 4)))
#define LEN_USB_UDMA_TX_TERMINATOR (4) /*HW design spec */
#define LEN_USB_RX_PADDING_CSO (4) /*HW design spec */
#define USB_RX_EVENT_RFB_RSV_CNT (0)
#define USB_RX_DATA_RFB_RSV_CNT (4)
#if CFG_USB_RX_DISPATCH_CPU
#define INVALID_CPUID (-1)
#endif
#define DEVICE_VENDOR_REQUEST_IN (0xc0)
#define DEVICE_VENDOR_REQUEST_OUT (0x40)
#define VENDOR_TIMEOUT_MS (1000)
#define BULK_TIMEOUT_MS (1500)
#define INTERRUPT_TIMEOUT_MS (1000)
#define SW_RFB_RECHECK_MS (10)
#define SW_RFB_LOG_LIMIT_MS (5000)
/* Vendor Request */
#define VND_REQ_POWER_ON_WIFI (0x4)
#if CFG_SUPPORT_SER
#define VND_REQ_WIFI_SER_CONTROL (0x5)
#endif /* CFG_SUPPORT_SER */
#define VND_REQ_REG_READ (0x63)
#define VND_REQ_REG_WRITE (0x66)
#define VND_REQ_EP5_IN_INFO (0x67)
#define VND_REQ_FEATURE_SET (0x91)
#define FEATURE_SET_WVALUE_RESUME (0x5)
#define FEATURE_SET_WVALUE_SUSPEND (0x6)
#if CFG_SUPPORT_SER
#define WVALUE_WIFI_GET_SER_STATE (0x0)
#define WVALUE_WIFI_SET_SER_STATE (0x1)
#endif /* CFG_SUPPORT_SER */
#define USB_TX_CMD_QUEUE_MASK (BITS(2, 4)) /* For H2CDMA Tx CMD mapping */
#define USB_DBDC1_TC (TC_NUM)/* for DBDC1 */
#define USB_TC_NUM (TC_NUM + 1)/* for DBDC1 */
#define HIF_EXTRA_IO_BUFFER_SIZE (0)
#define HIF_TX_COALESCING_BUFFER_SIZE (USB_TX_CMD_BUF_SIZE)
#define HIF_RX_COALESCING_BUFFER_SIZE (USB_RX_EVENT_BUF_SIZE)
#define MTK_USB_BULK_IN_MIN_EP 4
#define MTK_USB_BULK_IN_MAX_EP 5
#define MTK_USB_BULK_OUT_MIN_EP 4
#define MTK_USB_BULK_OUT_MAX_EP 9
/*******************************************************************************
* D A T A T Y P E S
********************************************************************************
*/
/* host interface's private data structure, which is attached to os glue
** layer info structure.
*/
enum ENUM_USB_END_POINT {
USB_DATA_BULK_OUT_EP4 = 4,
USB_DATA_BULK_OUT_EP5,
USB_DATA_BULK_OUT_EP6,
USB_DATA_BULK_OUT_EP7,
USB_DATA_BULK_OUT_EP8,
USB_DATA_BULK_OUT_EP9,
};
enum usb_state {
USB_STATE_WIFI_OFF, /* Hif power off wifi */
USB_STATE_LINK_DOWN,
USB_STATE_PRE_SUSPEND_START,
USB_STATE_PRE_SUSPEND_DONE,
USB_STATE_PRE_SUSPEND_FAIL,
USB_STATE_SUSPEND,
USB_STATE_PRE_RESUME,
USB_STATE_LINK_UP,
USB_STATE_READY
};
enum usb_submit_type {
SUBMIT_TYPE_TX_CMD,
SUBMIT_TYPE_TX_DATA,
SUBMIT_TYPE_RX_EVENT,
SUBMIT_TYPE_RX_DATA
};
enum usb_rx_type {
USB_RX_TYPE_DATA,
USB_RX_TYPE_EVENT,
};
enum EVENT_EP_TYPE {
EVENT_EP_TYPE_UNKONW,
EVENT_EP_TYPE_BULK,
EVENT_EP_TYPE_INTR,
EVENT_EP_TYPE_DATA_EP
};
struct BUF_CTRL {
uint8_t *pucBuf;
uint32_t u4BufSize;
uint32_t u4WrIdx;
uint32_t u4ReadSize;
};
struct GL_HIF_INFO {
struct usb_interface *intf;
struct usb_device *udev;
struct GLUE_INFO *prGlueInfo;
enum usb_state state;
spinlock_t rTxDataQLock;
spinlock_t rTxCmdQLock;
spinlock_t rRxEventQLock;
spinlock_t rRxDataQLock;
spinlock_t rStateLock;
void *prTxCmdReqHead;
void *arTxDataFfaReqHead;
void *arTxDataReqHead[USB_TC_NUM];
void *prRxEventReqHead;
void *prRxDataReqHead;
struct list_head rTxCmdFreeQ;
spinlock_t rTxCmdFreeQLock;
struct list_head rTxCmdSendingQ;
spinlock_t rTxCmdSendingQLock;
struct list_head rTxDataFfaQ;
#if CFG_USB_TX_AGG
uint32_t u4AggRsvSize[USB_TC_NUM];
struct list_head rTxDataFreeQ[USB_TC_NUM];
struct usb_anchor rTxDataAnchor[USB_TC_NUM];
#else
struct list_head rTxDataFreeQ;
struct usb_anchor rTxDataAnchor;
#endif
/*spinlock_t rTxDataFreeQLock;*/
struct list_head rRxEventFreeQ;
/*spinlock_t rRxEventFreeQLock;*/
struct usb_anchor rRxEventAnchor;
struct list_head rRxDataFreeQ;
/*spinlock_t rRxDataFreeQLock;*/
struct usb_anchor rRxDataAnchor;
struct list_head rRxEventCompleteQ;
/*spinlock_t rRxEventCompleteQLock;*/
struct list_head rRxDataCompleteQ;
/*spinlock_t rRxDataCompleteQLock;*/
struct list_head rTxCmdCompleteQ;
struct list_head rTxDataCompleteQ;
struct BUF_CTRL rTxCmdBufCtrl[USB_REQ_TX_CMD_CNT];
struct BUF_CTRL rTxDataFfaBufCtrl[USB_REQ_TX_DATA_FFA_CNT];
#if CFG_USB_TX_AGG
struct BUF_CTRL rTxDataBufCtrl[USB_TC_NUM][USB_REQ_TX_DATA_CNT];
#else
struct BUF_CTRL rTxDataBufCtrl[USB_REQ_TX_DATA_CNT];
#endif
struct BUF_CTRL rRxEventBufCtrl[USB_REQ_RX_EVENT_CNT];
struct BUF_CTRL rRxDataBufCtrl[USB_REQ_RX_DATA_CNT];
struct mutex vendor_req_sem;
u_int8_t fgIntReadClear;
u_int8_t fgMbxReadClear;
u_int8_t fgEventEpDetected;
enum EVENT_EP_TYPE eEventEpType;
#if CFG_USB_RX_DISPATCH_CPU
int rx_cpuid;
#endif
};
struct USB_REQ {
struct list_head list;
struct urb *prUrb;
struct BUF_CTRL *prBufCtrl;
struct GL_HIF_INFO *prHifInfo;
void *prPriv;
struct QUE rSendingDataMsduInfoList;
};
struct BUS_INFO {
const uint32_t u4UdmaWlCfg_0_Addr;
const uint32_t u4UdmaWlCfg_1_Addr;
uint32_t u4UdmaWlCfg_0;
uint32_t u4UdmaTxTimeout; /* UDMA Tx time out limit, unit: us */
u_int8_t (*asicUsbSuspend)(IN struct ADAPTER *prAdapter, IN struct GLUE_INFO *prGlueInfo);
uint8_t (*asicUsbEventEpDetected)(IN struct ADAPTER *prAdapter);
};
/* USB_REQ_T prPriv field for TxData */
#define FFA_MASK BIT(7) /* Indicate if this UsbReq is from FFA queue. */
#define TC_MASK BITS(0, 6) /* Indicate which TC this UsbReq belongs to */
/*******************************************************************************
* P U B L I C D A T A
********************************************************************************
*/
/*******************************************************************************
* P R I V A T E D A T A
********************************************************************************
*/
/*******************************************************************************
* M A C R O S
********************************************************************************
*/
#define USB_TRANS_MSDU_TC(_prMsduInfo) \
((_prMsduInfo)->ucWmmQueSet ? USB_DBDC1_TC : (_prMsduInfo)->ucTC)
/*******************************************************************************
* F U N C T I O N D E C L A R A T I O N S
********************************************************************************
*/
uint32_t glRegisterBus(probe_card pfProbe, remove_card pfRemove);
void glUnregisterBus(remove_card pfRemove);
void glSetHifInfo(struct GLUE_INFO *prGlueInfo, unsigned long ulCookie);
void glClearHifInfo(struct GLUE_INFO *prGlueInfo);
u_int8_t glBusInit(void *pvData);
void glBusRelease(void *pData);
int32_t glBusSetIrq(void *pvData, void *pfnIsr, void *pvCookie);
void glBusFreeIrq(void *pvData, void *pvCookie);
void glSetPowerState(IN struct GLUE_INFO *prGlueInfo, IN uint32_t ePowerMode);
void glUdmaTxRxEnable(struct GLUE_INFO *prGlueInfo, u_int8_t enable);
void glUdmaRxAggEnable(struct GLUE_INFO *prGlueInfo, u_int8_t enable);
u_int8_t mtk_usb_vendor_request(IN struct GLUE_INFO *prGlueInfo, IN uint8_t uEndpointAddress, IN uint8_t RequestType,
IN uint8_t Request, IN uint16_t Value, IN uint16_t Index, IN void *TransferBuffer,
IN uint32_t TransferBufferLength);
void glUsbEnqueueReq(struct GL_HIF_INFO *prHifInfo, struct list_head *prHead, struct USB_REQ *prUsbReq,
spinlock_t *prLock, u_int8_t fgHead);
struct USB_REQ *glUsbDequeueReq(struct GL_HIF_INFO *prHifInfo, struct list_head *prHead, spinlock_t *prLock);
u_int8_t glUsbBorrowFfaReq(struct GL_HIF_INFO *prHifInfo, uint8_t ucTc);
void glUsbSetState(IN struct GL_HIF_INFO *prHifInfo, enum usb_state state);
int glUsbSubmitUrb(IN struct GL_HIF_INFO *prHifInfo, struct urb *urb,
enum usb_submit_type type);
uint32_t halTxUSBSendCmd(IN struct GLUE_INFO *prGlueInfo, IN uint8_t ucTc, IN struct CMD_INFO *prCmdInfo);
void halTxUSBSendCmdComplete(struct urb *urb);
void halTxUSBProcessCmdComplete(IN struct ADAPTER *prAdapter, struct USB_REQ *prUsbReq);
uint32_t halTxUSBSendData(IN struct GLUE_INFO *prGlueInfo, IN struct MSDU_INFO *prMsduInfo);
uint32_t halTxUSBKickData(IN struct GLUE_INFO *prGlueInfo);
void halTxUSBSendDataComplete(struct urb *urb);
void halTxUSBProcessMsduDone(IN struct GLUE_INFO *prGlueInfo, struct USB_REQ *prUsbReq);
void halTxUSBProcessDataComplete(IN struct ADAPTER *prAdapter, struct USB_REQ *prUsbReq);
uint32_t halRxUSBEnqueueRFB(IN struct ADAPTER *prAdapter, IN uint8_t *pucBuf, IN uint32_t u4Length,
IN uint32_t u4MinRfbCnt);
uint32_t halRxUSBReceiveEvent(IN struct ADAPTER *prAdapter, IN u_int8_t fgFillUrb);
void halRxUSBReceiveEventComplete(struct urb *urb);
uint32_t halRxUSBReceiveData(IN struct ADAPTER *prAdapter);
void halRxUSBReceiveDataComplete(struct urb *urb);
void halRxUSBProcessEventDataComplete(IN struct ADAPTER *prAdapter,
enum usb_rx_type);
void halPreSuspendCmd(IN struct ADAPTER *prAdapter);
void halPreResumeCmd(IN struct ADAPTER *prAdapter);
void halUSBPreSuspendDone(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo, IN uint8_t *pucEventBuf);
void halUSBPreSuspendTimeout(IN struct ADAPTER *prAdapter, IN struct CMD_INFO *prCmdInfo);
void glGetDev(void *ctx, struct device **dev);
void glGetHifDev(struct GL_HIF_INFO *prHif, struct device **dev);
void halGetCompleteStatus(IN struct ADAPTER *prAdapter, OUT uint32_t *pu4IntStatus);
uint16_t glGetUsbDeviceVendorId(struct usb_device *dev);
uint16_t glGetUsbDeviceProductId(struct usb_device *dev);
int32_t glGetUsbDeviceManufacturerName(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen);
int32_t glGetUsbDeviceProductName(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen);
int32_t glGetUsbDeviceSerialNumber(struct usb_device *dev, uint8_t *buffer, uint32_t bufLen);
/*******************************************************************************
* F U N C T I O N S
********************************************************************************
*/
#endif /* _HIF_H */