1 /******************************************************************************
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 *****************************************************************************/
18 #define RTW_RX_MSDU_ACT_NONE 0
19 #define RTW_RX_MSDU_ACT_INDICATE BIT0
20 #define RTW_RX_MSDU_ACT_FORWARD BIT1
23 #ifdef CONFIG_SDIO_HCI
24 #define NR_RECVBUFF 1024/* 512 */ /* 128 */
26 #define NR_RECVBUFF (16)
28 #elif defined(PLATFORM_OS_CE)
29 #ifdef CONFIG_SDIO_HCI
30 #define NR_RECVBUFF (128)
32 #define NR_RECVBUFF (4)
34 #else /* PLATFORM_LINUX /PLATFORM_BSD */
36 #ifdef CONFIG_SINGLE_RECV_BUF
37 #define NR_RECVBUFF (1)
39 #if defined(CONFIG_GSPI_HCI)
40 #define NR_RECVBUFF (32)
41 #elif defined(CONFIG_SDIO_HCI)
42 #define NR_RECVBUFF (8)
44 #define NR_RECVBUFF (8)
46 #endif /* CONFIG_SINGLE_RECV_BUF */
47 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
48 #define NR_PREALLOC_RECV_SKB (rtw_rtkm_get_nr_recv_skb()>>1)
49 #else /*!CONFIG_PREALLOC_RX_SKB_BUFFER */
50 #define NR_PREALLOC_RECV_SKB 8
51 #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
53 #ifdef CONFIG_RTW_NAPI
54 #define RTL_NAPI_WEIGHT (32)
58 #if defined(CONFIG_RTL8821C) && defined(CONFIG_SDIO_HCI) && defined(CONFIG_RECV_THREAD_MODE)
61 #define NR_RECVBUFF (32)
65 #define NR_RECVFRAME 256
67 #define RXFRAME_ALIGN 8
68 #define RXFRAME_ALIGN_SZ (1<<RXFRAME_ALIGN)
70 #define DRVINFO_SZ 4 /* unit is 8bytes */
72 #define MAX_RXFRAME_CNT 512
73 #define MAX_RX_NUMBLKS (32)
74 #define RECVFRAME_HDR_ALIGN 128
75 #define MAX_CONTINUAL_NORXPACKET_COUNT 4 /* In MAX_CONTINUAL_NORXPACKET_COUNT*2 sec , no rx traffict would issue DELBA*/
77 #define PHY_RSSI_SLID_WIN_MAX 100
78 #define PHY_LINKQUALITY_SLID_WIN_MAX 20
81 #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
83 #define RX_MPDU_QUEUE 0
84 #define RX_CMD_QUEUE 1
85 #define RX_MAX_QUEUE 2
87 #define MAX_SUBFRAME_COUNT 64
88 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
89 extern u8 rtw_bridge_tunnel_header[];
90 extern u8 rtw_rfc1042_header[];
92 /* for Rx reordering buffer control */
93 struct recv_reorder_ctrl {
97 u16 indicate_seq;/* =wstart_b, init_value=0xffff */
101 _queue pending_recvframe_queue;
102 _timer reordering_ctrl_timer;
106 struct stainfo_rxcache {
111 unsigned short tid0_rxseq;
112 unsigned short tid1_rxseq;
113 unsigned short tid2_rxseq;
114 unsigned short tid3_rxseq;
115 unsigned short tid4_rxseq;
116 unsigned short tid5_rxseq;
117 unsigned short tid6_rxseq;
118 unsigned short tid7_rxseq;
119 unsigned short tid8_rxseq;
120 unsigned short tid9_rxseq;
121 unsigned short tid10_rxseq;
122 unsigned short tid11_rxseq;
123 unsigned short tid12_rxseq;
124 unsigned short tid13_rxseq;
125 unsigned short tid14_rxseq;
126 unsigned short tid15_rxseq;
131 struct smooth_rssi_data {
132 u32 elements[100]; /* array to store values */
133 u32 index; /* index to current array to store */
134 u32 total_num; /* num of valid elements */
135 u32 total_val; /* sum of valid elements */
139 u8 update_req; /* used to indicate */
140 u8 avg_val; /* avg of valid elements */
141 u32 total_num; /* num of valid elements */
142 u32 total_val; /* sum of valid elements */
150 u8 mimo_signal_strength[4];/* in 0~100 index */
151 u8 mimo_signal_quality[4];
158 #include "cmn_info/rtw_sta_info.h"
160 struct rx_pkt_attrib {
165 u8 hdrlen; /* the WLAN Header Len */
176 u8 privacy; /* in frame_ctrl field */
178 u8 encrypt; /* when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith */
191 #ifdef CONFIG_RTW_MESH
192 u8 msa[ETH_ALEN]; /* mesh sa */
193 u8 mda[ETH_ALEN]; /* mesh da */
194 u8 mesh_ctrl_present;
195 u8 mesh_ctrl_len; /* length of mesh control field */
203 u8 ch; /* RX channel */
210 u32 MacIDValidEntry[2]; /* 64 bits present 64 entry. */
212 u32 free_cnt; /* free run counter */
213 struct phydm_phyinfo_struct phy_info;
216 #ifdef CONFIG_RTW_MESH
217 #define RATTRIB_GET_MCTRL_LEN(rattrib) ((rattrib)->mesh_ctrl_len)
219 #define RATTRIB_GET_MCTRL_LEN(rattrib) 0
222 /* These definition is used for Rx packet reordering. */
223 #define SN_LESS(a, b) (((a-b) & 0x800) != 0)
224 #define SN_EQUAL(a, b) (a == b)
225 /* #define REORDER_WIN_SIZE 128 */
226 /* #define REORDER_ENTRY_NUM 128 */
227 #define REORDER_WAIT_TIME (50) /* (ms) */
229 #if defined(CONFIG_PLATFORM_RTK390X) && defined(CONFIG_USB_HCI)
230 #define RECVBUFF_ALIGN_SZ 32
232 #define RECVBUFF_ALIGN_SZ 8
235 #ifdef CONFIG_TRX_BD_ARCH
236 #define RX_WIFI_INFO_SIZE 24
237 #elif (defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B)) && defined(CONFIG_PCI_HCI)
238 #define RXBD_SIZE sizeof(struct recv_stat)
241 #define RXDESC_SIZE 24
242 #define RXDESC_OFFSET RXDESC_SIZE
244 #ifdef CONFIG_TRX_BD_ARCH
246 /* RX has exactly one segment */
247 #ifdef CONFIG_64BIT_DMA
248 unsigned int dword[4];
250 unsigned int dword[2];
255 unsigned int rxdw[8];
263 #if !((defined(CONFIG_RTL8192E) || defined(CONFIG_RTL8814A) || defined(CONFIG_RTL8822B) || defined(CONFIG_RTL8821C)) && defined(CONFIG_PCI_HCI)) /* exclude 8192ee, 8814ae, 8822be, 8821ce */
269 #ifndef BUF_DESC_ARCH
274 #ifdef CONFIG_PCI_HCI
279 #endif /* if BUF_DESC_ARCH is defined, rx_buf_desc occupy 4 double words */
285 #ifdef CONFIG_PCI_HCI
286 #define PCI_MAX_RX_QUEUE 1/* MSDU packet queue, Rx Command Queue */
287 #define PCI_MAX_RX_COUNT 128
288 #ifdef CONFIG_TRX_BD_ARCH
289 #define RX_BD_NUM PCI_MAX_RX_COUNT /* alias */
293 #ifdef CONFIG_TRX_BD_ARCH
294 struct rx_buf_desc *buf_desc;
296 struct recv_stat *desc;
300 struct sk_buff *rx_buf[PCI_MAX_RX_COUNT];
307 accesser of recv_priv: rtw_recv_entry(dispatch / passive level); recv_thread(passive) ; returnpkt(dispatch)
310 using enter_critical section to protect
313 #ifndef DBG_RX_BH_TRACKING
314 #define DBG_RX_BH_TRACKING 0
320 #ifdef CONFIG_RECV_THREAD_MODE
325 /* _queue blk_strms[MAX_RX_NUMBLKS]; */ /* keeping the block ack frame until return ack */
326 _queue free_recv_queue;
327 _queue recv_pending_queue;
328 _queue uc_swdec_pending_queue;
331 u8 *pallocated_frame_buf;
334 uint free_recvframe_cnt;
336 #if DBG_RX_BH_TRACKING
338 u32 rx_bh_buf_dq_cnt;
341 void *rx_bh_cbuf_data;
349 #ifdef PLATFORM_WINDOWS
350 _nic_hdl RxPktPoolHdl;
351 _nic_hdl RxBufPoolHdl;
353 #ifdef PLATFORM_OS_XP
356 uint counter; /* record the number that up-layer will return to drv; only when counter==0 can we release recv_priv */
357 NDIS_EVENT recv_resource_evt ;
361 u32 is_any_non_be_pkts;
367 u64 dbg_rx_drop_count;
368 u64 dbg_rx_ampdu_drop_count;
369 u64 dbg_rx_ampdu_forced_indicate_count;
370 u64 dbg_rx_ampdu_loss_count;
371 u64 dbg_rx_dup_mgt_frame_drop_count;
372 u64 dbg_rx_ampdu_window_shift_cnt;
373 u64 dbg_rx_conflic_mac_addr_cnt;
376 uint rx_largepacket_crcerr;
377 uint rx_smallpacket_crcerr;
378 uint rx_middlepacket_crcerr;
380 #ifdef CONFIG_USB_HCI
381 /* u8 *pallocated_urb_buf; */
382 _sema allrxreturnevt;
384 ATOMIC_T rx_pending_cnt;
386 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
387 #ifdef PLATFORM_LINUX
392 #endif /* CONFIG_USB_INTERRUPT_IN_PIPE */
395 #if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
396 #ifdef PLATFORM_FREEBSD
397 struct task irq_prepare_beacon_tasklet;
398 struct task recv_tasklet;
399 #else /* PLATFORM_FREEBSD */
400 struct tasklet_struct irq_prepare_beacon_tasklet;
401 struct tasklet_struct recv_tasklet;
402 #endif /* PLATFORM_FREEBSD */
403 struct sk_buff_head free_recv_skb_queue;
404 struct sk_buff_head rx_skb_queue;
405 #ifdef CONFIG_RTW_NAPI
406 struct sk_buff_head rx_napi_skb_queue;
408 #ifdef CONFIG_RX_INDICATE_QUEUE
409 struct task rx_indicate_tasklet;
410 struct ifqueue rx_indicate_queue;
411 #endif /* CONFIG_RX_INDICATE_QUEUE */
413 #endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) */
415 u8 *pallocated_recv_buf;
416 u8 *precv_buf; /* 4 alignment */
417 _queue free_recv_buf_queue;
418 u32 free_recv_buf_queue_cnt;
420 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) || defined(CONFIG_USB_HCI)
421 _queue recv_buf_pending_queue;
424 #ifdef CONFIG_PCI_HCI
426 struct rtw_rx_ring rx_ring[PCI_MAX_RX_QUEUE];
427 int rxringcount; /* size should be PCI_MAX_RX_QUEUE */
431 /* For display the phy informatiom */
432 u8 is_signal_dbg; /* for debug */
433 u8 signal_strength_dbg; /* for debug */
437 s8 rssi; /* translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength); */
438 struct rx_raw_rssi raw_rssi_info;
440 /* int RxSNRdB[2]; */
442 /* int FalseAlmCnt_all; */
445 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
446 _timer signal_stat_timer;
447 u32 signal_stat_sampling_interval;
448 /* u32 signal_stat_converging_constant; */
449 struct signal_stat signal_qual_data;
450 struct signal_stat signal_strength_data;
451 #else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
452 struct smooth_rssi_data signal_qual_data;
453 struct smooth_rssi_data signal_strength_data;
454 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
455 u16 sink_udpport, pre_rtp_rxseq, cur_rtp_rxseq;
457 BOOLEAN store_law_data_flag;
460 #define RX_BH_STG_UNKNOWN 0
461 #define RX_BH_STG_HDL_ENTER 1
462 #define RX_BH_STG_HDL_EXIT 2
463 #define RX_BH_STG_NEW_BUF 3
464 #define RX_BH_STG_NEW_FRAME 4
465 #define RX_BH_STG_NORMAL_RX 5
466 #define RX_BH_STG_NORMAL_RX_END 6
467 #define RX_BH_STG_C2H 7
468 #define RX_BH_STG_C2H_END 8
470 #if DBG_RX_BH_TRACKING
471 void rx_bh_tk_set_stage(struct recv_priv *recv, u32 s);
472 void rx_bh_tk_set_buf(struct recv_priv *recv, void *buf, void *data, u32 dlen);
473 void rx_bh_tk_set_buf_pos(struct recv_priv *recv, void *pos);
474 void rx_bh_tk_set_frame(struct recv_priv *recv, void *frame);
475 void dump_rx_bh_tk(void *sel, struct recv_priv *recv);
477 #define rx_bh_tk_set_stage(recv, s) do {} while (0)
478 #define rx_bh_tk_set_buf(recv, buf, data, dlen) do {} while (0)
479 #define rx_bh_tk_set_buf_pos(recv, pos) do {} while (0)
480 #define rx_bh_tk_set_frame(recv, frame) do {} while (0)
481 #define dump_rx_bh_tk(sel, recv) do {} while (0)
484 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
485 #define rtw_set_signal_stat_timer(recvpriv) _set_timer(&(recvpriv)->signal_stat_timer, (recvpriv)->signal_stat_sampling_interval)
486 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
488 struct sta_recv_priv {
493 /* _queue blk_strms[MAX_RX_NUMBLKS]; */
494 _queue defrag_q; /* keeping the fragment frame until defrag */
496 struct stainfo_rxcache rxcache;
497 u16 bmc_tid_rxseq[16];
499 u16 nonqos_bmc_rxseq;
501 /* uint sta_rx_bytes; */
502 /* uint sta_rx_pkts; */
503 /* uint sta_rx_fail; */
526 #ifdef CONFIG_USB_HCI
528 #if defined(PLATFORM_OS_XP) || defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
530 dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */
534 #ifdef PLATFORM_OS_XP
538 #ifdef PLATFORM_OS_CE
539 USB_TRANSFER usb_transfer_read_port;
547 #if defined(PLATFORM_LINUX)
549 #elif defined(PLATFORM_FREEBSD) /* skb solution */
550 struct sk_buff *pskb;
567 len = (unsigned int )(tail - data);
570 struct recv_frame_hdr {
580 struct rx_pkt_attrib attrib;
592 struct sta_info *psta;
594 /* for A-MPDU Rx reordering buffer control */
595 struct recv_reorder_ctrl *preorder_ctrl;
597 #ifdef CONFIG_WAPI_SUPPORT
601 u8 bWapiCheckPNInDecrypt;
612 struct recv_frame_hdr hdr;
613 uint mem[RECVFRAME_HDR_ALIGN >> 2];
616 /* uint mem[MAX_RXSZ>>2]; */
620 bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset);
622 typedef enum _RX_PACKET_TYPE {
623 NORMAL_RX,/* Normal rx packet */
625 TX_REPORT2,/* TX RPT */
626 HIS_REPORT,/* USB HISR RPT */
628 } RX_PACKET_TYPE, *PRX_PACKET_TYPE;
630 extern union recv_frame *_rtw_alloc_recvframe(_queue *pfree_recv_queue); /* get a free recv_frame from pfree_recv_queue */
631 extern union recv_frame *rtw_alloc_recvframe(_queue *pfree_recv_queue); /* get a free recv_frame from pfree_recv_queue */
632 extern void rtw_init_recvframe(union recv_frame *precvframe , struct recv_priv *precvpriv);
633 extern int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue);
635 #define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue)
636 extern int _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue);
637 extern int rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue);
639 extern void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue);
640 u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter);
642 sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue);
643 sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue);
644 struct recv_buf *rtw_dequeue_recvbuf(_queue *queue);
646 #if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
647 void rtw_reordering_ctrl_timeout_handler(void *pcontext);
650 void rx_query_phy_status(union recv_frame *rframe, u8 *phy_stat);
651 int rtw_inc_and_chk_continual_no_rx_packet(struct sta_info *sta, int tid_index);
652 void rtw_reset_continual_no_rx_packet(struct sta_info *sta, int tid_index);
654 #ifdef CONFIG_RECV_THREAD_MODE
655 thread_return rtw_recv_thread(thread_context context);
658 __inline static u8 *get_rxmem(union recv_frame *precvframe)
660 /* always return rx_head... */
661 if (precvframe == NULL)
664 return precvframe->u.hdr.rx_head;
667 __inline static u8 *get_rx_status(union recv_frame *precvframe)
670 return get_rxmem(precvframe);
674 __inline static u8 *get_recvframe_data(union recv_frame *precvframe)
677 /* alwasy return rx_data */
678 if (precvframe == NULL)
681 return precvframe->u.hdr.rx_data;
685 __inline static u8 *recvframe_push(union recv_frame *precvframe, sint sz)
687 /* append data before rx_data */
689 /* add data to the start of recv_frame
691 * This function extends the used data area of the recv_frame at the buffer
692 * start. rx_data must be still larger than rx_head, after pushing.
695 if (precvframe == NULL)
699 precvframe->u.hdr.rx_data -= sz ;
700 if (precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head) {
701 precvframe->u.hdr.rx_data += sz ;
705 precvframe->u.hdr.len += sz;
707 return precvframe->u.hdr.rx_data;
712 __inline static u8 *recvframe_pull(union recv_frame *precvframe, sint sz)
714 /* rx_data += sz; move rx_data sz bytes hereafter */
716 /* used for extract sz bytes from rx_data, update rx_data and return the updated rx_data to the caller */
719 if (precvframe == NULL)
723 precvframe->u.hdr.rx_data += sz;
725 if (precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) {
726 precvframe->u.hdr.rx_data -= sz;
730 precvframe->u.hdr.len -= sz;
732 return precvframe->u.hdr.rx_data;
736 __inline static u8 *recvframe_put(union recv_frame *precvframe, sint sz)
738 /* rx_tai += sz; move rx_tail sz bytes hereafter */
740 /* used for append sz bytes from ptr to rx_tail, update rx_tail and return the updated rx_tail to the caller */
741 /* after putting, rx_tail must be still larger than rx_end. */
742 unsigned char *prev_rx_tail;
744 /* RTW_INFO("recvframe_put: len=%d\n", sz); */
746 if (precvframe == NULL)
749 prev_rx_tail = precvframe->u.hdr.rx_tail;
751 precvframe->u.hdr.rx_tail += sz;
753 if (precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) {
754 precvframe->u.hdr.rx_tail -= sz;
758 precvframe->u.hdr.len += sz;
760 return precvframe->u.hdr.rx_tail;
766 __inline static u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz)
768 /* rmv data from rx_tail (by yitsen) */
770 /* used for extract sz bytes from rx_end, update rx_end and return the updated rx_end to the caller */
771 /* after pulling, rx_end must be still larger than rx_data. */
773 if (precvframe == NULL)
776 precvframe->u.hdr.rx_tail -= sz;
778 if (precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) {
779 precvframe->u.hdr.rx_tail += sz;
783 precvframe->u.hdr.len -= sz;
785 return precvframe->u.hdr.rx_tail;
791 __inline static _buffer *get_rxbuf_desc(union recv_frame *precvframe)
795 if (precvframe == NULL)
797 #ifdef PLATFORM_WINDOWS
798 NdisQueryPacket(precvframe->u.hdr.pkt, NULL, NULL, &buf_desc, NULL);
805 __inline static union recv_frame *rxmem_to_recvframe(u8 *rxmem)
807 /* due to the design of 2048 bytes alignment of recv_frame, we can reference the union recv_frame */
808 /* from any given member of recv_frame. */
809 /* rxmem indicates the any member/address in recv_frame */
811 return (union recv_frame *)(((SIZE_PTR)rxmem >> RXFRAME_ALIGN) << RXFRAME_ALIGN);
815 __inline static union recv_frame *pkt_to_recvframe(_pkt *pkt)
819 union recv_frame *precv_frame;
820 #ifdef PLATFORM_WINDOWS
824 NdisQueryPacket(pkt, NULL, NULL, &buf_desc, &len);
825 NdisQueryBufferSafe(buf_desc, &buf_star, &len, HighPagePriority);
827 precv_frame = rxmem_to_recvframe((unsigned char *)buf_star);
832 __inline static u8 *pkt_to_recvmem(_pkt *pkt)
834 /* return the rx_head */
836 union recv_frame *precv_frame = pkt_to_recvframe(pkt);
838 return precv_frame->u.hdr.rx_head;
842 __inline static u8 *pkt_to_recvdata(_pkt *pkt)
844 /* return the rx_data */
846 union recv_frame *precv_frame = pkt_to_recvframe(pkt);
848 return precv_frame->u.hdr.rx_data;
853 __inline static sint get_recvframe_len(union recv_frame *precvframe)
855 return precvframe->u.hdr.len;
859 __inline static s32 translate_percentage_to_dbm(u32 SignalStrengthIndex)
861 s32 SignalPower; /* in dBm. */
863 /* Translate to dBm (x=y-100) */
864 SignalPower = SignalStrengthIndex - 100;
870 extern void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv);
872 extern void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame);
874 u8 adapter_allow_bmc_data_rx(_adapter *adapter);
875 s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status);
876 void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info *sta);