Commit | Line | Data |
---|---|---|
c5c77ba1 JK |
1 | /*! |
2 | * @file linux_mon.c | |
3 | * @brief File Operations OS wrapper functionality | |
4 | * @author mdaftedar | |
5 | * @sa wilc_wfi_netdevice.h | |
6 | * @date 01 MAR 2012 | |
7 | * @version 1.0 | |
8 | */ | |
c5c77ba1 JK |
9 | #include "wilc_wfi_cfgoperations.h" |
10 | #include "linux_wlan_common.h" | |
11 | #include "wilc_wlan_if.h" | |
12 | #include "wilc_wlan.h" | |
9690df3f | 13 | |
c5c77ba1 JK |
14 | #ifdef WILC_FULLY_HOSTING_AP |
15 | #include "wilc_host_ap.h" | |
16 | #endif | |
17 | #ifdef WILC_AP_EXTERNAL_MLME | |
c5c77ba1 JK |
18 | |
19 | struct wilc_wfi_radiotap_hdr { | |
20 | struct ieee80211_radiotap_header hdr; | |
21 | u8 rate; | |
22 | /* u32 channel; */ | |
23 | } __attribute__((packed)); | |
24 | ||
25 | struct wilc_wfi_radiotap_cb_hdr { | |
26 | struct ieee80211_radiotap_header hdr; | |
27 | u8 rate; | |
28 | u8 dump; | |
29 | u16 tx_flags; | |
30 | /* u32 channel; */ | |
31 | } __attribute__((packed)); | |
32 | ||
33 | extern linux_wlan_t *g_linux_wlan; | |
34 | ||
35 | static struct net_device *wilc_wfi_mon; /* global monitor netdev */ | |
36 | ||
9690df3f | 37 | #if USE_WIRELESS |
c5c77ba1 JK |
38 | extern int mac_xmit(struct sk_buff *skb, struct net_device *dev); |
39 | #endif | |
40 | ||
41 | ||
63d03e47 GKH |
42 | u8 srcAdd[6]; |
43 | u8 bssid[6]; | |
44 | u8 broadcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | |
c5c77ba1 JK |
45 | /** |
46 | * @brief WILC_WFI_monitor_rx | |
47 | * @details | |
48 | * @param[in] | |
49 | * @return int : Return 0 on Success | |
50 | * @author mdaftedar | |
51 | * @date 12 JUL 2012 | |
52 | * @version 1.0 | |
53 | */ | |
54 | ||
55 | #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ | |
56 | #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive*/ | |
57 | #define IS_MANAGMEMENT 0x100 | |
58 | #define IS_MANAGMEMENT_CALLBACK 0x080 | |
59 | #define IS_MGMT_STATUS_SUCCES 0x040 | |
60 | #define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff) | |
61 | ||
62 | void WILC_WFI_monitor_rx(uint8_t *buff, uint32_t size) | |
63 | { | |
64 | uint32_t header, pkt_offset; | |
65 | struct sk_buff *skb = NULL; | |
66 | struct wilc_wfi_radiotap_hdr *hdr; | |
67 | struct wilc_wfi_radiotap_cb_hdr *cb_hdr; | |
68 | ||
69 | PRINT_INFO(HOSTAPD_DBG, "In monitor interface receive function\n"); | |
70 | ||
71 | /* struct WILC_WFI_priv *priv = netdev_priv(dev); */ | |
72 | ||
73 | /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ | |
74 | ||
75 | /* Bug 4601 */ | |
76 | if (wilc_wfi_mon == NULL) | |
77 | return; | |
78 | ||
79 | if (!netif_running(wilc_wfi_mon)) { | |
80 | PRINT_INFO(HOSTAPD_DBG, "Monitor interface already RUNNING\n"); | |
81 | return; | |
82 | } | |
83 | ||
84 | /* Get WILC header */ | |
85 | memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); | |
86 | ||
87 | /* The packet offset field conain info about what type of managment frame */ | |
88 | /* we are dealing with and ack status */ | |
89 | pkt_offset = GET_PKT_OFFSET(header); | |
90 | ||
91 | if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { | |
92 | ||
93 | /* hostapd callback mgmt frame */ | |
94 | ||
95 | skb = dev_alloc_skb(size + sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
96 | if (skb == NULL) { | |
97 | PRINT_INFO(HOSTAPD_DBG, "Monitor if : No memory to allocate skb"); | |
98 | return; | |
99 | } | |
100 | ||
101 | memcpy(skb_put(skb, size), buff, size); | |
102 | ||
103 | cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr)); | |
104 | memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
105 | ||
106 | cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ | |
107 | ||
108 | cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
109 | ||
110 | cb_hdr->hdr.it_present = cpu_to_le32( | |
111 | (1 << IEEE80211_RADIOTAP_RATE) | | |
112 | (1 << IEEE80211_RADIOTAP_TX_FLAGS)); | |
113 | ||
114 | cb_hdr->rate = 5; /* txrate->bitrate / 5; */ | |
115 | ||
116 | if (pkt_offset & IS_MGMT_STATUS_SUCCES) { | |
117 | /* success */ | |
118 | cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS; | |
119 | } else { | |
120 | cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL; | |
121 | } | |
122 | ||
123 | } else { | |
124 | ||
125 | skb = dev_alloc_skb(size + sizeof(struct wilc_wfi_radiotap_hdr)); | |
126 | ||
127 | if (skb == NULL) { | |
128 | PRINT_INFO(HOSTAPD_DBG, "Monitor if : No memory to allocate skb"); | |
129 | return; | |
130 | } | |
131 | ||
132 | /* skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); */ | |
133 | /* if (skb == NULL) */ | |
134 | /* return; */ | |
135 | ||
136 | memcpy(skb_put(skb, size), buff, size); | |
137 | hdr = (struct wilc_wfi_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); | |
138 | memset(hdr, 0, sizeof(struct wilc_wfi_radiotap_hdr)); | |
139 | hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ | |
140 | /* hdr->hdr.it_pad = 0; */ | |
141 | hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_hdr)); | |
142 | PRINT_INFO(HOSTAPD_DBG, "Radiotap len %d\n", hdr->hdr.it_len); | |
143 | hdr->hdr.it_present = cpu_to_le32 | |
144 | (1 << IEEE80211_RADIOTAP_RATE); /* | */ | |
145 | /* (1 << IEEE80211_RADIOTAP_CHANNEL)); */ | |
146 | PRINT_INFO(HOSTAPD_DBG, "Presentflags %d\n", hdr->hdr.it_present); | |
147 | hdr->rate = 5; /* txrate->bitrate / 5; */ | |
148 | ||
149 | } | |
150 | ||
151 | /* if(INFO || if(skb->data[9] == 0x00 || skb->data[9] == 0xb0)) | |
152 | * { | |
153 | * for(i=0;i<skb->len;i++) | |
154 | * PRINT_INFO(HOSTAPD_DBG,"Mon RxData[%d] = %02x\n",i,skb->data[i]); | |
155 | * }*/ | |
156 | ||
157 | ||
158 | skb->dev = wilc_wfi_mon; | |
159 | skb_set_mac_header(skb, 0); | |
160 | skb->ip_summed = CHECKSUM_UNNECESSARY; | |
161 | skb->pkt_type = PACKET_OTHERHOST; | |
162 | skb->protocol = htons(ETH_P_802_2); | |
163 | memset(skb->cb, 0, sizeof(skb->cb)); | |
164 | ||
165 | netif_rx(skb); | |
166 | ||
167 | ||
168 | } | |
169 | ||
170 | struct tx_complete_mon_data { | |
171 | int size; | |
172 | void *buff; | |
173 | }; | |
174 | ||
175 | static void mgmt_tx_complete(void *priv, int status) | |
176 | { | |
177 | ||
178 | /* struct sk_buff *skb2; */ | |
179 | /* struct wilc_wfi_radiotap_cb_hdr *cb_hdr; */ | |
180 | ||
181 | struct tx_complete_mon_data *pv_data = (struct tx_complete_mon_data *)priv; | |
63d03e47 | 182 | u8 *buf = pv_data->buff; |
c5c77ba1 JK |
183 | |
184 | ||
185 | ||
186 | if (status == 1) { | |
187 | if (INFO || buf[0] == 0x10 || buf[0] == 0xb0) | |
188 | PRINT_INFO(HOSTAPD_DBG, "Packet sent successfully - Size = %d - Address = %p.\n", pv_data->size, pv_data->buff); | |
189 | } else { | |
190 | PRINT_INFO(HOSTAPD_DBG, "Couldn't send packet - Size = %d - Address = %p.\n", pv_data->size, pv_data->buff); | |
191 | } | |
192 | ||
193 | ||
194 | /* //(skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 ) | |
195 | * { | |
196 | * skb2 = dev_alloc_skb(pv_data->size+sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
197 | * | |
198 | * memcpy(skb_put(skb2,pv_data->size),pv_data->buff, pv_data->size); | |
199 | * | |
200 | * cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr)); | |
201 | * memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
202 | * | |
203 | * cb_hdr->hdr.it_version = 0;//PKTHDR_RADIOTAP_VERSION; | |
204 | * | |
205 | * cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
206 | * | |
207 | * cb_hdr->hdr.it_present = cpu_to_le32( | |
208 | * (1 << IEEE80211_RADIOTAP_RATE) | | |
209 | * (1 << IEEE80211_RADIOTAP_TX_FLAGS)); | |
210 | * | |
211 | * cb_hdr->rate = 5;//txrate->bitrate / 5; | |
212 | * cb_hdr->tx_flags = 0x0004; | |
213 | * | |
214 | * skb2->dev = wilc_wfi_mon; | |
215 | * skb_set_mac_header(skb2, 0); | |
216 | * skb2->ip_summed = CHECKSUM_UNNECESSARY; | |
217 | * skb2->pkt_type = PACKET_OTHERHOST; | |
218 | * skb2->protocol = htons(ETH_P_802_2); | |
219 | * memset(skb2->cb, 0, sizeof(skb2->cb)); | |
220 | * | |
221 | * netif_rx(skb2); | |
222 | * }*/ | |
223 | ||
224 | /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */ | |
225 | #ifndef WILC_FULLY_HOSTING_AP | |
226 | kfree(pv_data->buff); | |
227 | ||
228 | kfree(pv_data); | |
229 | #endif | |
230 | } | |
231 | static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len) | |
232 | { | |
c5c77ba1 JK |
233 | struct tx_complete_mon_data *mgmt_tx = NULL; |
234 | ||
235 | if (dev == NULL) { | |
236 | PRINT_D(HOSTAPD_DBG, "ERROR: dev == NULL\n"); | |
237 | return WILC_FAIL; | |
238 | } | |
c5c77ba1 JK |
239 | |
240 | netif_stop_queue(dev); | |
25fe2274 | 241 | mgmt_tx = kmalloc(sizeof(struct tx_complete_mon_data), GFP_ATOMIC); |
c5c77ba1 JK |
242 | if (mgmt_tx == NULL) { |
243 | PRINT_ER("Failed to allocate memory for mgmt_tx structure\n"); | |
244 | return WILC_FAIL; | |
245 | } | |
246 | ||
247 | #ifdef WILC_FULLY_HOSTING_AP | |
248 | /* add space for the pointer to tx_complete_mon_data */ | |
249 | len += sizeof(struct tx_complete_mon_data *); | |
250 | #endif | |
251 | ||
30ef5c8b | 252 | mgmt_tx->buff = kmalloc(len, GFP_ATOMIC); |
c5c77ba1 JK |
253 | if (mgmt_tx->buff == NULL) { |
254 | PRINT_ER("Failed to allocate memory for mgmt_tx buff\n"); | |
255 | return WILC_FAIL; | |
256 | ||
257 | } | |
258 | ||
259 | mgmt_tx->size = len; | |
260 | ||
261 | #ifndef WILC_FULLY_HOSTING_AP | |
262 | memcpy(mgmt_tx->buff, buf, len); | |
263 | #else | |
264 | memcpy(mgmt_tx->buff, buf, len - sizeof(struct tx_complete_mon_data *)); | |
265 | memcpy((mgmt_tx->buff) + (len - sizeof(struct tx_complete_mon_data *)), &mgmt_tx, sizeof(struct tx_complete_mon_data *)); | |
266 | ||
267 | /* filter data frames to handle it's PS */ | |
72ed4dc7 | 268 | if (filter_monitor_data_frames((mgmt_tx->buff), len) == true) { |
c5c77ba1 JK |
269 | return; |
270 | } | |
271 | ||
272 | #endif /* WILC_FULLY_HOSTING_AP */ | |
273 | ||
274 | g_linux_wlan->oup.wlan_add_mgmt_to_tx_que(mgmt_tx, mgmt_tx->buff, mgmt_tx->size, mgmt_tx_complete); | |
275 | ||
276 | netif_wake_queue(dev); | |
277 | return 0; | |
278 | } | |
279 | ||
280 | /** | |
281 | * @brief WILC_WFI_mon_xmit | |
282 | * @details | |
283 | * @param[in] | |
284 | * @return int : Return 0 on Success | |
285 | * @author mdaftedar | |
286 | * @date 12 JUL 2012 | |
287 | * @version 1.0 | |
288 | */ | |
289 | static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb, | |
290 | struct net_device *dev) | |
291 | { | |
4e4467fd | 292 | u32 rtap_len, i, ret = 0; |
c5c77ba1 JK |
293 | struct WILC_WFI_mon_priv *mon_priv; |
294 | ||
295 | struct sk_buff *skb2; | |
296 | struct wilc_wfi_radiotap_cb_hdr *cb_hdr; | |
297 | ||
298 | /* Bug 4601 */ | |
299 | if (wilc_wfi_mon == NULL) | |
300 | return WILC_FAIL; | |
301 | ||
302 | /* if(skb->data[3] == 0x10 || skb->data[3] == 0xb0) */ | |
303 | ||
304 | mon_priv = netdev_priv(wilc_wfi_mon); | |
305 | ||
306 | if (mon_priv == NULL) { | |
307 | PRINT_ER("Monitor interface private structure is NULL\n"); | |
308 | return WILC_FAIL; | |
309 | } | |
310 | ||
c5c77ba1 JK |
311 | |
312 | rtap_len = ieee80211_get_radiotap_len(skb->data); | |
313 | if (skb->len < rtap_len) { | |
314 | PRINT_ER("Error in radiotap header\n"); | |
315 | return -1; | |
316 | } | |
317 | /* skip the radiotap header */ | |
318 | PRINT_INFO(HOSTAPD_DBG, "Radiotap len: %d\n", rtap_len); | |
319 | ||
320 | if (INFO) { | |
321 | for (i = 0; i < rtap_len; i++) | |
322 | PRINT_INFO(HOSTAPD_DBG, "Radiotap_hdr[%d] %02x\n", i, skb->data[i]); | |
323 | } | |
324 | /* Skip the ratio tap header */ | |
325 | skb_pull(skb, rtap_len); | |
326 | ||
327 | if (skb->data[0] == 0xc0) | |
328 | PRINT_INFO(HOSTAPD_DBG, "%x:%x:%x:%x:%x%x\n", skb->data[4], skb->data[5], skb->data[6], skb->data[7], skb->data[8], skb->data[9]); | |
329 | ||
330 | if (skb->data[0] == 0xc0 && (!(memcmp(broadcast, &skb->data[4], 6)))) { | |
331 | skb2 = dev_alloc_skb(skb->len + sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
332 | ||
333 | memcpy(skb_put(skb2, skb->len), skb->data, skb->len); | |
334 | ||
335 | cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb2, sizeof(*cb_hdr)); | |
336 | memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
337 | ||
338 | cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ | |
339 | ||
340 | cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
341 | ||
342 | cb_hdr->hdr.it_present = cpu_to_le32( | |
343 | (1 << IEEE80211_RADIOTAP_RATE) | | |
344 | (1 << IEEE80211_RADIOTAP_TX_FLAGS)); | |
345 | ||
346 | cb_hdr->rate = 5; /* txrate->bitrate / 5; */ | |
347 | cb_hdr->tx_flags = 0x0004; | |
348 | ||
349 | skb2->dev = wilc_wfi_mon; | |
350 | skb_set_mac_header(skb2, 0); | |
351 | skb2->ip_summed = CHECKSUM_UNNECESSARY; | |
352 | skb2->pkt_type = PACKET_OTHERHOST; | |
353 | skb2->protocol = htons(ETH_P_802_2); | |
354 | memset(skb2->cb, 0, sizeof(skb2->cb)); | |
355 | ||
356 | netif_rx(skb2); | |
357 | ||
358 | return 0; | |
359 | } | |
360 | skb->dev = mon_priv->real_ndev; | |
361 | ||
362 | PRINT_INFO(HOSTAPD_DBG, "Skipping the radiotap header\n"); | |
363 | ||
364 | ||
365 | ||
366 | /* actual deliver of data is device-specific, and not shown here */ | |
367 | PRINT_INFO(HOSTAPD_DBG, "SKB netdevice name = %s\n", skb->dev->name); | |
368 | PRINT_INFO(HOSTAPD_DBG, "MONITOR real dev name = %s\n", mon_priv->real_ndev->name); | |
369 | ||
9690df3f | 370 | #if USE_WIRELESS |
c5c77ba1 JK |
371 | /* Identify if Ethernet or MAC header (data or mgmt) */ |
372 | memcpy(srcAdd, &skb->data[10], 6); | |
373 | memcpy(bssid, &skb->data[16], 6); | |
374 | /* if source address and bssid fields are equal>>Mac header */ | |
375 | /*send it to mgmt frames handler */ | |
376 | if (!(memcmp(srcAdd, bssid, 6))) { | |
377 | mon_mgmt_tx(mon_priv->real_ndev, skb->data, skb->len); | |
378 | dev_kfree_skb(skb); | |
379 | } else | |
380 | ret = mac_xmit(skb, mon_priv->real_ndev); | |
381 | #endif | |
382 | ||
383 | /* return NETDEV_TX_OK; */ | |
384 | return ret; | |
385 | } | |
386 | ||
387 | static const struct net_device_ops wilc_wfi_netdev_ops = { | |
388 | .ndo_start_xmit = WILC_WFI_mon_xmit, | |
389 | ||
390 | }; | |
391 | ||
392 | #ifdef WILC_FULLY_HOSTING_AP | |
393 | /* | |
394 | * @brief WILC_mgm_HOSTAPD_ACK | |
395 | * @details report the status of transmitted mgmt frames to HOSTAPD | |
396 | * @param[in] priv : pointer to tx_complete_mon_data struct | |
397 | * bStatus : status of transmission | |
398 | * @author Abd Al-Rahman Diab | |
399 | * @date 9 May 2013 | |
400 | * @version 1.0 | |
401 | */ | |
72ed4dc7 | 402 | void WILC_mgm_HOSTAPD_ACK(void *priv, bool bStatus) |
c5c77ba1 JK |
403 | { |
404 | struct sk_buff *skb; | |
405 | struct wilc_wfi_radiotap_cb_hdr *cb_hdr; | |
406 | ||
407 | struct tx_complete_mon_data *pv_data = (struct tx_complete_mon_data *)priv; | |
63d03e47 | 408 | u8 *buf = pv_data->buff; |
c5c77ba1 JK |
409 | |
410 | /* len of the original frame without the added pointer at the tail */ | |
d85f5326 | 411 | u16 u16len = (pv_data->size) - sizeof(struct tx_complete_mon_data *); |
c5c77ba1 JK |
412 | |
413 | ||
414 | /*if(bStatus == 1){ | |
415 | * if(INFO || buf[0] == 0x10 || buf[0] == 0xb0) | |
416 | * PRINT_D(HOSTAPD_DBG,"Packet sent successfully - Size = %d - Address = %p.\n",u16len,pv_data->buff); | |
417 | * }else{ | |
418 | * PRINT_D(HOSTAPD_DBG,"Couldn't send packet - Size = %d - Address = %p.\n",u16len,pv_data->buff); | |
419 | * } | |
420 | */ | |
421 | ||
422 | /* (skb->data[9] == 0x00 || skb->data[9] == 0xb0 || skb->data[9] == 0x40 || skb->data[9] == 0xd0 ) */ | |
423 | { | |
424 | skb = dev_alloc_skb(u16len + sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
425 | ||
426 | memcpy(skb_put(skb, u16len), pv_data->buff, u16len); | |
427 | ||
428 | cb_hdr = (struct wilc_wfi_radiotap_cb_hdr *) skb_push(skb, sizeof(*cb_hdr)); | |
429 | memset(cb_hdr, 0, sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
430 | ||
431 | cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */ | |
432 | ||
433 | cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr)); | |
434 | ||
435 | cb_hdr->hdr.it_present = cpu_to_le32( | |
436 | (1 << IEEE80211_RADIOTAP_RATE) | | |
437 | (1 << IEEE80211_RADIOTAP_TX_FLAGS)); | |
438 | ||
439 | cb_hdr->rate = 5; /* txrate->bitrate / 5; */ | |
440 | ||
441 | ||
5a66bf20 | 442 | if (bStatus) { |
c5c77ba1 JK |
443 | /* success */ |
444 | cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_RTS; | |
445 | } else { | |
446 | cb_hdr->tx_flags = IEEE80211_RADIOTAP_F_TX_FAIL; | |
447 | } | |
448 | ||
449 | skb->dev = wilc_wfi_mon; | |
450 | skb_set_mac_header(skb, 0); | |
451 | skb->ip_summed = CHECKSUM_UNNECESSARY; | |
452 | skb->pkt_type = PACKET_OTHERHOST; | |
453 | skb->protocol = htons(ETH_P_802_2); | |
454 | memset(skb->cb, 0, sizeof(skb->cb)); | |
455 | ||
456 | netif_rx(skb); | |
457 | } | |
458 | ||
459 | /* incase of fully hosting mode, the freeing will be done in response to the cfg packet */ | |
460 | kfree(pv_data->buff); | |
461 | ||
462 | kfree(pv_data); | |
463 | ||
464 | } | |
465 | #endif /* WILC_FULLY_HOSTING_AP */ | |
466 | ||
467 | /** | |
468 | * @brief WILC_WFI_mon_setup | |
469 | * @details | |
470 | * @param[in] | |
471 | * @return int : Return 0 on Success | |
472 | * @author mdaftedar | |
473 | * @date 12 JUL 2012 | |
474 | * @version 1.0 | |
475 | */ | |
476 | static void WILC_WFI_mon_setup(struct net_device *dev) | |
477 | { | |
478 | ||
479 | dev->netdev_ops = &wilc_wfi_netdev_ops; | |
480 | /* dev->destructor = free_netdev; */ | |
481 | PRINT_INFO(CORECONFIG_DBG, "In Ethernet setup function\n"); | |
482 | ether_setup(dev); | |
483 | dev->tx_queue_len = 0; | |
484 | dev->type = ARPHRD_IEEE80211_RADIOTAP; | |
8ca1b55a | 485 | eth_zero_addr(dev->dev_addr); |
c5c77ba1 JK |
486 | |
487 | #ifdef USE_WIRELESS | |
488 | { | |
489 | /* u8 * mac_add; */ | |
490 | unsigned char mac_add[] = {0x00, 0x50, 0xc2, 0x5e, 0x10, 0x8f}; | |
491 | /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */ | |
63d03e47 | 492 | /* mac_add = (u8*)WILC_MALLOC(ETH_ALEN); */ |
c5c77ba1 JK |
493 | /* status = host_int_get_MacAddress(priv->hWILCWFIDrv,mac_add); */ |
494 | /* mac_add[ETH_ALEN-1]+=1; */ | |
495 | memcpy(dev->dev_addr, mac_add, ETH_ALEN); | |
496 | } | |
497 | #else | |
498 | dev->dev_addr[0] = 0x12; | |
499 | #endif | |
500 | ||
501 | } | |
502 | ||
503 | /** | |
504 | * @brief WILC_WFI_init_mon_interface | |
505 | * @details | |
506 | * @param[in] | |
507 | * @return int : Return 0 on Success | |
508 | * @author mdaftedar | |
509 | * @date 12 JUL 2012 | |
510 | * @version 1.0 | |
511 | */ | |
057d1e97 | 512 | struct net_device *WILC_WFI_init_mon_interface(const char *name, struct net_device *real_dev) |
c5c77ba1 JK |
513 | { |
514 | ||
515 | ||
4e4467fd | 516 | u32 ret = WILC_SUCCESS; |
c5c77ba1 JK |
517 | struct WILC_WFI_mon_priv *priv; |
518 | ||
519 | /*If monitor interface is already initialized, return it*/ | |
520 | if (wilc_wfi_mon) { | |
521 | return wilc_wfi_mon; | |
522 | } | |
c5c77ba1 JK |
523 | |
524 | wilc_wfi_mon = alloc_etherdev(sizeof(struct WILC_WFI_mon_priv)); | |
525 | if (!wilc_wfi_mon) { | |
526 | PRINT_ER("failed to allocate memory\n"); | |
527 | return NULL; | |
528 | ||
529 | } | |
530 | ||
531 | wilc_wfi_mon->type = ARPHRD_IEEE80211_RADIOTAP; | |
532 | strncpy(wilc_wfi_mon->name, name, IFNAMSIZ); | |
533 | wilc_wfi_mon->name[IFNAMSIZ - 1] = 0; | |
534 | wilc_wfi_mon->netdev_ops = &wilc_wfi_netdev_ops; | |
535 | ||
536 | ret = register_netdevice(wilc_wfi_mon); | |
537 | if (ret) { | |
538 | PRINT_ER(" register_netdevice failed (%d)\n", ret); | |
539 | return NULL; | |
540 | } | |
541 | priv = netdev_priv(wilc_wfi_mon); | |
542 | if (priv == NULL) { | |
543 | PRINT_ER("private structure is NULL\n"); | |
544 | return NULL; | |
545 | } | |
546 | ||
547 | priv->real_ndev = real_dev; | |
548 | ||
549 | return wilc_wfi_mon; | |
550 | } | |
551 | ||
552 | /** | |
553 | * @brief WILC_WFI_deinit_mon_interface | |
554 | * @details | |
555 | * @param[in] | |
556 | * @return int : Return 0 on Success | |
557 | * @author mdaftedar | |
558 | * @date 12 JUL 2012 | |
559 | * @version 1.0 | |
560 | */ | |
a96c47e1 | 561 | int WILC_WFI_deinit_mon_interface(void) |
c5c77ba1 JK |
562 | { |
563 | bool rollback_lock = false; | |
564 | ||
565 | if (wilc_wfi_mon != NULL) { | |
566 | PRINT_D(HOSTAPD_DBG, "In Deinit monitor interface\n"); | |
567 | PRINT_D(HOSTAPD_DBG, "RTNL is being locked\n"); | |
568 | if (rtnl_is_locked()) { | |
569 | rtnl_unlock(); | |
570 | rollback_lock = true; | |
571 | } | |
572 | PRINT_D(HOSTAPD_DBG, "Unregister netdev\n"); | |
573 | unregister_netdev(wilc_wfi_mon); | |
574 | /* free_netdev(wilc_wfi_mon); */ | |
575 | ||
576 | if (rollback_lock) { | |
577 | rtnl_lock(); | |
578 | rollback_lock = false; | |
579 | } | |
580 | wilc_wfi_mon = NULL; | |
581 | } | |
582 | return WILC_SUCCESS; | |
583 | ||
584 | } | |
585 | #endif /* WILC_AP_EXTERNAL_MLME */ |