1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26 
27     Module Name:
28 		mac_usb.h
29 
30     Abstract:
31 
32     Revision History:
33     Who          	When            What
34     Justin P. Mattock	11/07/2010	Fix a typo
35     ---------    ----------    ----------------------------------------------
36  */
37 
38 #ifndef __MAC_USB_H__
39 #define __MAC_USB_H__
40 
41 #include "../rtmp_type.h"
42 #include "rtmp_mac.h"
43 #include "rtmp_phy.h"
44 #include "../rtmp_iface.h"
45 #include "../rtmp_dot11.h"
46 
47 #define USB_CYC_CFG				0x02a4
48 
49 #define BEACON_RING_SIZE		2
50 #define MGMTPIPEIDX			0	/* EP6 is highest priority */
51 
52 #define RTMP_PKT_TAIL_PADDING	11	/* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */
53 
54 #define fRTMP_ADAPTER_NEED_STOP_TX		\
55 		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
56 		 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
57 		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
58 
59 /* */
60 /* RXINFO appends at the end of each rx packet. */
61 /* */
62 #define RXINFO_SIZE				4
63 #define RT2870_RXDMALEN_FIELD_SIZE	4
64 
65 typedef struct PACKED rt_rxinfo {
66 	u32 BA:1;
67 	u32 DATA:1;
68 	u32 NULLDATA:1;
69 	u32 FRAG:1;
70 	u32 U2M:1;		/* 1: this RX frame is unicast to me */
71 	u32 Mcast:1;		/* 1: this is a multicast frame */
72 	u32 Bcast:1;		/* 1: this is a broadcast frame */
73 	u32 MyBss:1;		/* 1: this frame belongs to the same BSSID */
74 	u32 Crc:1;		/* 1: CRC error */
75 	u32 CipherErr:2;	/* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */
76 	u32 AMSDU:1;		/* rx with 802.3 header, not 802.11 header. */
77 	u32 HTC:1;
78 	u32 RSSI:1;
79 	u32 L2PAD:1;
80 	u32 AMPDU:1;		/* To be moved */
81 	u32 Decrypted:1;
82 	u32 PlcpRssil:1;
83 	u32 CipherAlg:1;
84 	u32 LastAMSDU:1;
85 	u32 PlcpSignal:12;
86 } RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
87 
88 /* */
89 /* TXINFO */
90 /* */
91 #define TXINFO_SIZE				4
92 
93 struct rt_txinfo {
94 	/* Word 0 */
95 	u32 USBDMATxPktLen:16;	/*used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame. */
96 	u32 rsv:8;
97 	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correct position */
98 	u32 QSEL:2;		/* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
99 	u32 SwUseLastRound:1;	/* Software use. */
100 	u32 rsv2:2;		/* Software use. */
101 	u32 USBDMANextVLD:1;	/*used ONLY in USB bulk Aggregation, NextValid */
102 	u32 USBDMATxburst:1;	/*used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint */
103 };
104 
105 /* */
106 /* Management ring buffer format */
107 /* */
108 struct rt_mgmt {
109 	BOOLEAN Valid;
110 	u8 *pBuffer;
111 	unsigned long Length;
112 };
113 
114 /*////////////////////////////////////////////////////////////////////////// */
115 /* The struct rt_tx_buffer structure forms the transmitted USB packet to the device */
116 /*////////////////////////////////////////////////////////////////////////// */
117 struct rt_tx_buffer {
118 	union {
119 		u8 WirelessPacket[TX_BUFFER_NORMSIZE];
120 		struct rt_header_802_11 NullFrame;
121 		struct rt_pspoll_frame PsPollPacket;
122 		struct rt_rts_frame RTSFrame;
123 	} field;
124 	u8 Aggregation[4];	/*Buffer for save Aggregation size. */
125 };
126 
127 struct rt_httx_buffer {
128 	union {
129 		u8 WirelessPacket[MAX_TXBULK_SIZE];
130 		struct rt_header_802_11 NullFrame;
131 		struct rt_pspoll_frame PsPollPacket;
132 		struct rt_rts_frame RTSFrame;
133 	} field;
134 	u8 Aggregation[4];	/*Buffer for save Aggregation size. */
135 };
136 
137 /* used to track driver-generated write irps */
138 struct rt_tx_context {
139 	void *pAd;		/*Initialized in MiniportInitialize */
140 	PURB pUrb;		/*Initialized in MiniportInitialize */
141 	PIRP pIrp;		/*used to cancel pending bulk out. */
142 	/*Initialized in MiniportInitialize */
143 	struct rt_tx_buffer *TransferBuffer;	/*Initialized in MiniportInitialize */
144 	unsigned long BulkOutSize;
145 	u8 BulkOutPipeId;
146 	u8 SelfIdx;
147 	BOOLEAN InUse;
148 	BOOLEAN bWaitingBulkOut;	/* at least one packet is in this TxContext, ready for making IRP anytime. */
149 	BOOLEAN bFullForBulkOut;	/* all tx buffer are full , so waiting for tx bulkout. */
150 	BOOLEAN IRPPending;
151 	BOOLEAN LastOne;
152 	BOOLEAN bAggregatible;
153 	u8 Header_802_3[LENGTH_802_3];
154 	u8 Rsv[2];
155 	unsigned long DataOffset;
156 	u32 TxRate;
157 	dma_addr_t data_dma;	/* urb dma on linux */
158 
159 };
160 
161 /* used to track driver-generated write irps */
162 struct rt_ht_tx_context {
163 	void *pAd;		/*Initialized in MiniportInitialize */
164 	PURB pUrb;		/*Initialized in MiniportInitialize */
165 	PIRP pIrp;		/*used to cancel pending bulk out. */
166 	/*Initialized in MiniportInitialize */
167 	struct rt_httx_buffer *TransferBuffer;	/*Initialized in MiniportInitialize */
168 	unsigned long BulkOutSize;	/* Indicate the total bulk-out size in bytes in one bulk-transmission */
169 	u8 BulkOutPipeId;
170 	BOOLEAN IRPPending;
171 	BOOLEAN LastOne;
172 	BOOLEAN bCurWriting;
173 	BOOLEAN bRingEmpty;
174 	BOOLEAN bCopySavePad;
175 	u8 SavedPad[8];
176 	u8 Header_802_3[LENGTH_802_3];
177 	unsigned long CurWritePosition;	/* Indicate the buffer offset which packet will be inserted start from. */
178 	unsigned long CurWriteRealPos;	/* Indicate the buffer offset which packet now are writing to. */
179 	unsigned long NextBulkOutPosition;	/* Indicate the buffer start offset of a bulk-transmission */
180 	unsigned long ENextBulkOutPosition;	/* Indicate the buffer end offset of a bulk-transmission */
181 	u32 TxRate;
182 	dma_addr_t data_dma;	/* urb dma on linux */
183 };
184 
185 /* */
186 /* Structure to keep track of receive packets and buffers to indicate */
187 /* receive data to the protocol. */
188 /* */
189 struct rt_rx_context {
190 	u8 *TransferBuffer;
191 	void *pAd;
192 	PIRP pIrp;		/*used to cancel pending bulk in. */
193 	PURB pUrb;
194 	/*These 2 Boolean shouldn't both be 1 at the same time. */
195 	unsigned long BulkInOffset;	/* number of packets waiting for reordering . */
196 /*      BOOLEAN                         ReorderInUse;   // At least one packet in this buffer are in reordering buffer and wait for receive indication */
197 	BOOLEAN bRxHandling;	/* Notify this packet is being process now. */
198 	BOOLEAN InUse;		/* USB Hardware Occupied. Wait for USB HW to put packet. */
199 	BOOLEAN Readable;	/* Receive Complete back. OK for driver to indicate receiving packet. */
200 	BOOLEAN IRPPending;	/* TODO: To be removed */
201 	atomic_t IrpLock;
202 	spinlock_t RxContextLock;
203 	dma_addr_t data_dma;	/* urb dma on linux */
204 };
205 
206 /******************************************************************************
207 
208 	USB Frimware Related MACRO
209 
210 ******************************************************************************/
211 /* 8051 firmware image for usb - use last-half base address = 0x3000 */
212 #define FIRMWARE_IMAGE_BASE			0x3000
213 #define MAX_FIRMWARE_IMAGE_SIZE		0x1000	/* 4kbyte */
214 
215 #define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)		\
216 	RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
217 
218 /******************************************************************************
219 
220 	USB TX Related MACRO
221 
222 ******************************************************************************/
223 #define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)				\
224 			do {													\
225 				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
226 				if (pAd->DeQueueRunning[QueIdx]) {						\
227 					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
228 					DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx));		\
229 					continue;											\
230 				} else {												\
231 					pAd->DeQueueRunning[QueIdx] = TRUE;					\
232 					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
233 				}														\
234 			} while (0)
235 
236 #define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)						\
237 			do {													\
238 				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
239 				pAd->DeQueueRunning[QueIdx] = FALSE;					\
240 				RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);	\
241 			} while (0)
242 
243 #define	RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
244 		(RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
245 
246 #define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)			\
247 		do {} while (0)
248 
249 #define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType)		\
250 		((_TxFrameType == TX_RALINK_FRAME) && \
251 		(RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
252 
253 #define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
254 		RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
255 
256 #define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
257 		RtmpUSB_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
258 
259 #define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
260 		RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
261 
262 #define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)	\
263 		RtmpUSB_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
264 
265 #define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)	\
266 		RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
267 
268 #define HAL_LastTxIdx(pAd, QueIdx, TxIdx) \
269 				/*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx) */
270 
271 #define HAL_KickOutTx(pAd, pTxBlk, QueIdx)	\
272 			RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
273 
274 #define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)	\
275 			RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
276 
277 #define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
278 			RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
279 
280 #define GET_TXRING_FREENO(_pAd, _QueIdx)	(_QueIdx)	/*(_pAd->TxRing[_QueIdx].TxSwFreeIdx) */
281 #define GET_MGMTRING_FREENO(_pAd)			(_pAd->MgmtRing.TxSwFreeIdx)
282 
283 /* ----------------- RX Related MACRO ----------------- */
284 
285 /*
286   *	Device Hardware Interface Related MACRO
287   */
288 #define RTMP_IRQ_INIT(pAd)				do {} while (0)
289 #define RTMP_IRQ_ENABLE(pAd)			do {} while (0)
290 
291 /*
292   *	MLME Related MACRO
293   */
294 #define RTMP_MLME_HANDLER(pAd)			RTUSBMlmeUp(pAd)
295 
296 #define RTMP_MLME_PRE_SANITY_CHECK(pAd)								\
297 	{	if ((pAd->CommonCfg.bHardwareRadio == TRUE) &&					\
298 			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&		\
299 			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {	\
300 			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
301 
302 #define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
303 	{	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0);	\
304 		RTUSBMlmeUp(pAd); }
305 
306 #define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
307 	{	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL);	\
308 		RTUSBMlmeUp(pAd); }
309 
310 #define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
311 	{	RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(struct rt_mac_table_entry));	\
312 		RTUSBMlmeUp(_pAd);									\
313 	}
314 
315 /*
316   *	Power Save Related MACRO
317   */
318 #define RTMP_PS_POLL_ENQUEUE(pAd)						\
319 	{	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);	\
320 		RTUSBKickBulkOut(pAd); }
321 
322 #define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \
323 	RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx);
324 
325 #define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
326     RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
327 
328 #define RTMP_SET_PSM_BIT(_pAd, _val) \
329 	{\
330 		if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \
331 			MlmeSetPsmBit(_pAd, _val);\
332 		else { \
333 			u16 _psm_val; \
334 			_psm_val = _val; \
335 			RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(u16)); \
336 		} \
337 	}
338 
339 #define RTMP_MLME_RADIO_ON(pAd) \
340     RT28xxUsbMlmeRadioOn(pAd);
341 
342 #define RTMP_MLME_RADIO_OFF(pAd) \
343     RT28xxUsbMlmeRadioOFF(pAd);
344 
345 #endif /*__MAC_USB_H__ // */
346