1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3
4 #define _RECV_OSDEP_C_
5
6 #include "../include/osdep_service.h"
7 #include "../include/drv_types.h"
8
9 #include "../include/wifi.h"
10 #include "../include/recv_osdep.h"
11
12 #include "../include/osdep_intf.h"
13 #include "../include/usb_ops.h"
14
15 /* init os related resource in struct recv_priv */
rtw_os_recv_resource_init(struct recv_priv * precvpriv,struct adapter * padapter)16 int rtw_os_recv_resource_init(struct recv_priv *precvpriv,
17 struct adapter *padapter)
18 {
19 return _SUCCESS;
20 }
21
22 /* alloc os related resource in struct recv_frame */
rtw_os_recv_resource_alloc(struct adapter * padapter,struct recv_frame * precvframe)23 int rtw_os_recv_resource_alloc(struct adapter *padapter,
24 struct recv_frame *precvframe)
25 {
26 precvframe->pkt_newalloc = NULL;
27 precvframe->pkt = NULL;
28 return _SUCCESS;
29 }
30
31 /* free os related resource in struct recv_frame */
rtw_os_recv_resource_free(struct recv_priv * precvpriv)32 void rtw_os_recv_resource_free(struct recv_priv *precvpriv)
33 {
34 }
35
36 /* alloc os related resource in struct recv_buf */
rtw_os_recvbuf_resource_alloc(struct adapter * padapter,struct recv_buf * precvbuf)37 int rtw_os_recvbuf_resource_alloc(struct adapter *padapter,
38 struct recv_buf *precvbuf)
39 {
40 int res = _SUCCESS;
41
42 precvbuf->irp_pending = false;
43 precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
44 if (!precvbuf->purb)
45 res = _FAIL;
46 precvbuf->pskb = NULL;
47 precvbuf->reuse = false;
48 precvbuf->pallocated_buf = NULL;
49 precvbuf->pbuf = NULL;
50 precvbuf->pdata = NULL;
51 precvbuf->phead = NULL;
52 precvbuf->ptail = NULL;
53 precvbuf->pend = NULL;
54 precvbuf->transfer_len = 0;
55 precvbuf->len = 0;
56 return res;
57 }
58
59 /* free os related resource in struct recv_buf */
rtw_os_recvbuf_resource_free(struct adapter * padapter,struct recv_buf * precvbuf)60 int rtw_os_recvbuf_resource_free(struct adapter *padapter,
61 struct recv_buf *precvbuf)
62 {
63 usb_free_urb(precvbuf->purb);
64 return _SUCCESS;
65 }
66
rtw_handle_tkip_mic_err(struct adapter * padapter,u8 bgroup)67 void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup)
68 {
69 union iwreq_data wrqu;
70 struct iw_michaelmicfailure ev;
71 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
72 struct security_priv *psecuritypriv = &padapter->securitypriv;
73 u32 cur_time = 0;
74
75 if (psecuritypriv->last_mic_err_time == 0) {
76 psecuritypriv->last_mic_err_time = jiffies;
77 } else {
78 cur_time = jiffies;
79
80 if (cur_time - psecuritypriv->last_mic_err_time < 60 * HZ) {
81 psecuritypriv->btkip_countermeasure = true;
82 psecuritypriv->last_mic_err_time = 0;
83 psecuritypriv->btkip_countermeasure_time = cur_time;
84 } else {
85 psecuritypriv->last_mic_err_time = jiffies;
86 }
87 }
88
89 memset(&ev, 0x00, sizeof(ev));
90 if (bgroup)
91 ev.flags |= IW_MICFAILURE_GROUP;
92 else
93 ev.flags |= IW_MICFAILURE_PAIRWISE;
94
95 ev.src_addr.sa_family = ARPHRD_ETHER;
96 memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN);
97 memset(&wrqu, 0x00, sizeof(wrqu));
98 wrqu.data.length = sizeof(ev);
99 wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE,
100 &wrqu, (char *)&ev);
101 }
102
rtw_hostapd_mlme_rx(struct adapter * padapter,struct recv_frame * precv_frame)103 void rtw_hostapd_mlme_rx(struct adapter *padapter,
104 struct recv_frame *precv_frame)
105 {
106 }
107
rtw_recv_indicatepkt(struct adapter * padapter,struct recv_frame * precv_frame)108 int rtw_recv_indicatepkt(struct adapter *padapter,
109 struct recv_frame *precv_frame)
110 {
111 struct recv_priv *precvpriv;
112 struct __queue *pfree_recv_queue;
113 struct sk_buff *skb;
114 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
115
116 precvpriv = &padapter->recvpriv;
117 pfree_recv_queue = &precvpriv->free_recv_queue;
118
119 skb = precv_frame->pkt;
120 if (!skb)
121 goto _recv_indicatepkt_drop;
122
123 skb->data = precv_frame->rx_data;
124
125 skb_set_tail_pointer(skb, precv_frame->len);
126
127 skb->len = precv_frame->len;
128
129 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
130 struct sk_buff *pskb2 = NULL;
131 struct sta_info *psta = NULL;
132 struct sta_priv *pstapriv = &padapter->stapriv;
133 struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
134 bool bmcast = is_multicast_ether_addr(pattrib->dst);
135
136 if (memcmp(pattrib->dst, myid(&padapter->eeprompriv),
137 ETH_ALEN)) {
138 if (bmcast) {
139 psta = rtw_get_bcmc_stainfo(padapter);
140 pskb2 = skb_clone(skb, GFP_ATOMIC);
141 } else {
142 psta = rtw_get_stainfo(pstapriv, pattrib->dst);
143 }
144
145 if (psta) {
146 struct net_device *pnetdev;
147
148 pnetdev = (struct net_device *)padapter->pnetdev;
149 skb->dev = pnetdev;
150 skb_set_queue_mapping(skb, rtw_recv_select_queue(skb));
151
152 rtw_xmit_entry(skb, pnetdev);
153
154 if (bmcast)
155 skb = pskb2;
156 else
157 goto _recv_indicatepkt_end;
158 }
159 }
160 }
161
162 rcu_read_lock();
163 rcu_dereference(padapter->pnetdev->rx_handler_data);
164 rcu_read_unlock();
165
166 skb->ip_summed = CHECKSUM_NONE;
167 skb->dev = padapter->pnetdev;
168 skb->protocol = eth_type_trans(skb, padapter->pnetdev);
169
170 netif_rx(skb);
171
172 _recv_indicatepkt_end:
173
174 /* pointers to NULL before rtw_free_recvframe() */
175 precv_frame->pkt = NULL;
176
177 rtw_free_recvframe(precv_frame, pfree_recv_queue);
178
179 return _SUCCESS;
180
181 _recv_indicatepkt_drop:
182
183 /* enqueue back to free_recv_queue */
184 rtw_free_recvframe(precv_frame, pfree_recv_queue);
185
186 return _FAIL;
187 }
188
rtw_os_read_port(struct adapter * padapter,struct recv_buf * precvbuf)189 void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf)
190 {
191 struct recv_priv *precvpriv = &padapter->recvpriv;
192
193 precvbuf->ref_cnt--;
194 /* free skb in recv_buf */
195 dev_kfree_skb_any(precvbuf->pskb);
196 precvbuf->pskb = NULL;
197 precvbuf->reuse = false;
198 if (!precvbuf->irp_pending)
199 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0,
200 (unsigned char *)precvbuf);
201 }
202
_rtw_reordering_ctrl_timeout_handler(struct timer_list * t)203 static void _rtw_reordering_ctrl_timeout_handler(struct timer_list *t)
204 {
205 struct recv_reorder_ctrl *preorder_ctrl;
206
207 preorder_ctrl = from_timer(preorder_ctrl, t, reordering_ctrl_timer);
208 rtw_reordering_ctrl_timeout_handler(preorder_ctrl);
209 }
210
rtw_init_recv_timer(struct recv_reorder_ctrl * preorder_ctrl)211 void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
212 {
213 timer_setup(&preorder_ctrl->reordering_ctrl_timer, _rtw_reordering_ctrl_timeout_handler, 0);
214 }
215