source: ReferenceDesigns/w3_802.11/c/wlan_mac_high_framework/wlan_mac_eth_util.c

Last change on this file was 6319, checked in by chunter, 5 years ago

1.8.0 release wlan-mac-se

File size: 21.7 KB
Line 
1/** @file wlan_mac_eth_util.c
2 *  @brief Ethernet Framework
3 *
4 *  Contains code for using Ethernet, including encapsulation and de-encapsulation.
5 *
6 *  @copyright Copyright 2013-2019, Mango Communications. All rights reserved.
7 *          Distributed under the Mango Communications Reference Design License
8 *              See LICENSE.txt included in the design archive or
9 *              at http://mangocomm.com/802.11/license
10 *
11 *  This file is part of the Mango 802.11 Reference Design (https://mangocomm.com/802.11)
12 */
13
14/***************************** Include Files *********************************/
15
16
17
18
19
20#include "stdlib.h"
21#include "stddef.h"
22#include "xil_types.h"
23#include "string.h"
24
25#include "wlan_platform_high.h"
26#include "wlan_mac_high.h"
27#include "wlan_mac_common.h"
28#include "wlan_mac_eth_util.h"
29#include "wlan_mac_dl_list.h"
30#include "wlan_mac_queue.h"
31#include "wlan_mac_station_info.h"
32#include "wlan_mac_802_11_defs.h"
33#include "wlan_mac_pkt_buf_util.h"
34
35#include "wlan_mac_high_sw_config.h"
36
37/*************************** Variable Definitions ****************************/
38
39#if WLAN_SW_CONFIG_ENABLE_ETH_BRIDGE
40
41// Ethernet Station MAC Address
42//
43//   The station code's implementation of encapsulation and de-encapsulation has an important
44// limitation: only one device may be plugged into the station's Ethernet port. The station
45// does not provide NAT. It assumes that the last received Ethernet src MAC address is used
46// as the destination MAC address on any Ethernet transmissions. This is fine when there is
47// only one device on the station's Ethernet port, but will definitely not work if the station
48// is plugged into a switch with more than one device.
49//
50static u8 mac_addr_to_overwrite[6];
51
52
53/*********************** Global Variable Definitions *************************/
54
55// Controls whether or not portal behaviors will be enabled
56static u8 gl_portal_en;
57static int _portal_eth_rx_qid;
58static int _portal_eth_tx_qid;
59
60// Callback for top-level processing of Ethernet received packets
61static function_ptr_t eth_rx_callback;
62
63
64/*************************** Functions Prototypes ****************************/
65
66void _portal_eth_rx_queue_occupancy_change(int callback_arg, u32 queue_len);
67void _portal_eth_tx_queue_occupancy_change(int callback_arg, u32 queue_len);
68
69#if PERF_MON_ETH_BD
70void     print_bd_high_water_mark() { xil_printf("BD HWM = %d\n", bd_high_water_mark); }
71#endif
72
73
74/*****************************************************************************/
75/**
76 * @brief Initialize the Ethernet utility sub-system
77 *
78 * Initialize Ethernet A hardware and framework for handling Ethernet Tx/Rx via
79 * the DMA.  This function must be called once at boot, before any Ethernet
80 * configuration or Tx/Rx operations.
81 *
82 * @return WLAN_SUCCESS
83 */
84int wlan_eth_util_init() {
85
86    // Open a queue for Rx Ethernet frames
87    _portal_eth_rx_qid = queue_open((void*)_portal_eth_rx_queue_occupancy_change, 0, PORTAL_MAX_QUEUE_LEN);
88
89    // Open a queue for Tx Ethernet frames
90    _portal_eth_tx_qid = queue_open((void*)_portal_eth_tx_queue_occupancy_change, 0, PORTAL_MAX_QUEUE_LEN);
91
92    if((_portal_eth_rx_qid == -1) || (_portal_eth_tx_qid == -1)) xil_printf("Error in wlan_eth_util_init(), unable to open queue\n");
93
94    // Initialize Callback
95    eth_rx_callback = (function_ptr_t)wlan_null_callback;
96
97    // Enable bridging of the wired-wireless networks (a.k.a. the "portal" between networks)
98    wlan_eth_portal_en(1);
99    return WLAN_SUCCESS;
100}
101
102/*****************************************************************************/
103/**
104 * @brief Sets the MAC callback to process Ethernet receptions
105 *
106 * The framework will call the MAC's callback for each Ethernet reception that is a candidate
107 * for wireless transmission. The framework may reject some packets for malformed or unrecognized
108 * Ethernet headers. The MAC may reject more, based on Ethernet address or packet contents.
109 *
110 * @param void(*callback)
111 *  -Function pointer to the MAC's Ethernet Rx callback
112 */
113void wlan_mac_util_set_eth_rx_callback(void(*callback)()) {
114    eth_rx_callback = (function_ptr_t)callback;
115}
116
117int wlan_enqueue_eth_rx(eth_rx_queue_buffer_t* eth_rx_queue_buffer){
118    u8 is_claimed = 0;
119    int status;
120    status = queue_enqueue(_portal_eth_rx_qid, eth_rx_queue_buffer->pyld_queue_hdr.dle);
121    if(status == 0) is_claimed = 1;
122    return is_claimed;
123}
124
125int wlan_enqueue_eth_tx(dl_entry* queue_entry){
126    int status;
127    status = queue_enqueue(_portal_eth_tx_qid, queue_entry);
128    return status;
129}
130
131u32 wlan_poll_eth_rx_queue(){
132    dl_entry* packet_to_process;
133    int ret;
134    u32 i;
135
136    for(i = 0; i < WLAN_MIN(queue_length(_portal_eth_rx_qid), WLAN_MAX_ETH_RX_PROCESS_PER_ISR); i++){
137        packet_to_process = queue_dequeue(_portal_eth_rx_qid);
138        if(packet_to_process == NULL) return WLAN_SUCCESS; // should not be possible
139        ret = wlan_process_eth_rx((eth_rx_queue_buffer_t*)(packet_to_process->data));
140        if( ret != 0 ){
141            // This Ethernet packet was rejected so we must return
142            //  the entry back to the free list.
143            queue_checkin(packet_to_process);
144        }
145    }
146
147    return queue_length(_portal_eth_rx_qid);
148}
149
150u32 wlan_poll_eth_tx_queue(){
151    dl_entry* packet_to_process;
152    u32 i;
153    int status;
154
155    for(i = 0; i < WLAN_MIN(queue_length(_portal_eth_tx_qid), WLAN_MAX_ETH_TX_PROCESS_PER_ISR); i++){
156        packet_to_process = queue_dequeue(_portal_eth_tx_qid);
157        if(packet_to_process == NULL) return WLAN_SUCCESS; // should not be possible
158
159        // Platform Ethernet Send functions are required to check in
160        //  packet_to_process when they are done with them if they were successful.
161        status = wlan_platform_portal_eth_send((eth_tx_queue_buffer_t*)(packet_to_process->data));
162
163        if(status != 0){
164            // We were unable to transmit this packet. This is mostly likely due to an ongoing transmission
165            //  causing there to be no free BDs. Re-enqueue this packet back into the head of the _eth_tx_qid
166            //  queue;
167
168            status = enqueue_head(_portal_eth_tx_qid, packet_to_process);
169
170            if( status == -1 ){
171                queue_checkin(packet_to_process);
172            }
173        }
174    }
175
176    return queue_length(_portal_eth_tx_qid);
177}
178
179/*****************************************************************************/
180/**
181 * @brief Process an Ethernet packet that has been received by the ETH DMA
182 *
183 * This function processes an Ethernet DMA buffer descriptor.  This design assumes
184 * a 1-to-1 correspondence between buffer descriptors and Ethernet packets.  For
185 * each packet, this function encapsulates the Ethernet packet and calls the
186 * MAC's callback to either enqueue (for eventual wireless Tx) or reject the packet.
187 *
188 * NOTE:  Processed ETH DMA buffer descriptors are freed but not resubmitted to
189 * hardware for use by future Ethernet receptions.  This is the responsibility of
190 * higher level code (see comment at the end of the function if this behavior needs
191 * to change).
192 *
193 * This function requires the MAC implement a function (assigned to the eth_rx_callback
194 * function pointer) that returns 0 or 1, indicating the MAC's handling of the packet:
195 *     0: Packet was not enqueued and will not be processed by wireless MAC; framework
196 *        should immediately discard
197 *     1: Packet was enqueued for eventual wireless transmission; MAC will check in
198 *        occupied queue entry when finished
199 *
200 */
201int wlan_process_eth_rx(eth_rx_queue_buffer_t* eth_rx_queue_buffer) {
202
203    int return_value = -1;
204    int packet_claimed = 0;
205
206#if PERF_MON_ETH_PROCESS_RX
207    wlan_mac_set_dbg_hdr_out(0x4);
208#endif
209
210    // Check arguments
211    if( eth_rx_queue_buffer == NULL ) {
212        xil_printf("ERROR:  Tried to process NULL Ethernet packet\n");
213        return return_value;
214    }
215
216    ////////////////////
217    // 1. The first potential claimant for this packet is wlan_exp. It is expected that wlan_exp
218    //    processing will be light and will simply save the packet away for future processing if
219    //    it decides to claim it.
220        // TODO:
221    // wlan_exp_process_this_packet(pyld_queue_eth)
222    packet_claimed = 0; //wlan_exp should return 1 if it is holding on to this packet
223
224    if(packet_claimed == 0){
225        ////////////////////
226        // 2. The second potential claimant for this packet is the 802.11 portal.
227        packet_claimed = eth_rx_callback(eth_rx_queue_buffer);
228        if (packet_claimed) {
229                return_value = 0;
230        }
231    }
232#if PERF_MON_ETH_PROCESS_RX
233    wlan_mac_clear_dbg_hdr_out(0x4);
234#endif
235    return return_value;
236}
237
238void wlan_eth_portal_en(u8 enable){
239    gl_portal_en = enable;
240}
241
242
243
244#endif /* WLAN_SW_CONFIG_ENABLE_ETH_BRIDGE */
245
246
247/*****************************************************************************/
248/**
249 * @brief Encapsulates Ethernet packets for wireless transmission
250 *
251 * This function implements the encapsulation process for 802.11 transmission of
252 * Ethernet packets
253 *
254 * The encapsulation process depends on the node's role:
255 *
256 * AP:
257 *     - Copy original packet's source and destination addresses to temporary space
258 *     - Add an LLC header (8 bytes) in front of the Ethernet payload
259 *         - LLC header includes original packet's ETHER_TYPE field; only IPV4 and ARP
260 *           are currently supported
261 *
262 * STA:
263 *    - Copy original packet's source and destination addresses to temporary space
264 *    - Add an LLC header (8 bytes) in front of the Ethernet payload
265 *        - LLC header includes original packet's ETHER_TYPE field; only IPV4 and ARP
266 *          are currently supported
267 *    - If packet is ARP Request, overwrite ARP header's source address with STA
268 *      wireless MAC address
269 *    - If packet is UDP packet containing a DHCP request
270 *        - Assert DHCP header's BROADCAST flag
271 *        - Disable the UDP packet checksum (otherwise it would be invliad after
272 *          modifying the BROADCAST flag)
273 *
274 */
275tx_80211_queue_buffer_t* wlan_eth_encap( eth_rx_queue_buffer_t* eth_rx_queue_buffer, u32 flags ) {
276#if WLAN_SW_CONFIG_ENABLE_ETH_BRIDGE
277    ethernet_header_t* eth_hdr;
278    llc_header_t* llc_hdr;
279    ipv4_header_t* ip_hdr;
280    arp_ipv4_packet_t* arp;
281    udp_header_t* udp;
282    dhcp_packet* dhcp;
283
284    //Cast the Rx Ethernet Stencil as a Tx 802.11 Stencil
285    tx_80211_queue_buffer_t* tx_queue_buffer = (tx_80211_queue_buffer_t*)eth_rx_queue_buffer;
286
287    // Calculate actual wireless Tx len (eth payload - eth header + wireless header)
288    tx_queue_buffer->length = eth_rx_queue_buffer->length - sizeof(ethernet_header_t)  + sizeof(llc_header_t) + sizeof(mac_header_80211) + WLAN_PHY_FCS_NBYTES;
289
290    // Update metadata so dequeue operation knows how to construct contiguous series of bytes that form the MPDU
291    //  1) The C0 section starting at tx_queue_buffer->pkt contains an 802.11 header and an LLC header.
292    tx_queue_buffer->seg0_len = sizeof(mac_header_80211) + sizeof(llc_header_t);
293
294    //  2) The C1 section starts after both the C0 section and an Ethernet header. The Ethernet header must remain
295    //     in this buffer for other processes in this framework, but the bytes themselves are not copied to CPU_LOW
296    //     on dequeue. This offset allows the dequeue operation to skip these bytes.
297    tx_queue_buffer->seg1_offset = tx_queue_buffer->seg0_len + sizeof(ethernet_header_t);
298
299    //  3) Together, the C0 and C1 section lengths total the wireless Tx length calculated above in tx_queue_buffer->pyld_queue_hdr.length
300    tx_queue_buffer->seg1_len = tx_queue_buffer->length - tx_queue_buffer->seg0_len;
301
302    // Read pointers to interpret fields in the new MPDU
303    eth_hdr = (ethernet_header_t*)eth_rx_queue_buffer->pkt;
304
305    // Write pointers to fill fields in the new MPDU
306    llc_hdr = (llc_header_t*)(tx_queue_buffer->pkt + sizeof(mac_header_80211));
307
308    // Prepare the MPDU LLC header
309    llc_hdr->dsap = LLC_SNAP;
310    llc_hdr->ssap = LLC_SNAP;
311    llc_hdr->control_field = LLC_CNTRL_UNNUMBERED;
312    bzero((void *)(llc_hdr->org_code), 3); //Org Code 0x000000: Encapsulated Ethernet
313    if( flags & WLAN_ETH_ENCAP_FLAGS_OVERWRITE_PYLD_ADDRS ){
314            memcpy(mac_addr_to_overwrite, eth_hdr->src_mac_addr, 6);
315    }
316    switch(eth_hdr->ethertype){
317            case ETH_TYPE_ARP:
318                    llc_hdr->type = LLC_TYPE_ARP;
319                    if( flags & WLAN_ETH_ENCAP_FLAGS_OVERWRITE_PYLD_ADDRS ){
320                            arp = (arp_ipv4_packet_t*)((void*)eth_hdr + sizeof(ethernet_header_t));
321                            memcpy(arp->sender_haddr, get_mac_hw_addr_wlan(), 6);
322                    }
323            break;
324            case ETH_TYPE_IP:
325                    llc_hdr->type = LLC_TYPE_IP;
326                    if( flags & WLAN_ETH_ENCAP_FLAGS_OVERWRITE_PYLD_ADDRS ){
327                            // Check if IPv4 packet is a DHCP Discover in a UDP frame
328                                ip_hdr = (ipv4_header_t*)((void*)eth_hdr + sizeof(ethernet_header_t));
329                                if (ip_hdr->protocol == IPV4_PROT_UDP) {
330                                        udp = (udp_header_t*)((void*)ip_hdr + 4*((u8)(ip_hdr->version_ihl) & 0xF));
331                                        // All Bootstrap Protocol packets contain the client MAC address as part of the
332                                        // payload. For STA encapsulation, we need to replace the wired MAC address of
333                                        // the client with the wireless MAC address of the STA.
334                                        if ((Xil_Ntohs(udp->src_port) == UDP_SRC_PORT_BOOTPC) ||
335                                                (Xil_Ntohs(udp->src_port) == UDP_SRC_PORT_BOOTPS)) {
336                                                // Disable the checksum since this will change the bytes in the packet
337                                                udp->checksum = 0;
338                                                dhcp = (dhcp_packet*)((void*)udp + sizeof(udp_header_t));
339                                                if (Xil_Ntohl(dhcp->magic_cookie) == DHCP_MAGIC_COOKIE) {
340                                                        // Overwrite DHCP client MAC address with the station's wireless MAC address
341                                                        memcpy(dhcp->chaddr, get_mac_hw_addr_wlan(), 6);
342                                                } // END is DHCP valid
343                                        } // END is DHCP
344                                } // END is UDP
345                    }
346            break;
347            default:
348                    return NULL;
349            break;
350    }
351    return tx_queue_buffer;
352#else
353    return NULL;
354#endif
355}
356
357int wlan_eth_decap_and_send( u8* rx_mac_payload,
358                             u8* addr_da,
359                             u8* addr_sa,
360                             u16 rx_length,
361                             u32 flags ) {
362
363#if WLAN_SW_CONFIG_ENABLE_ETH_BRIDGE
364    eth_tx_queue_buffer_t* eth_tx_queue_buffer;
365    dl_entry* eth_tx_queue_entry;
366    mac_header_80211* rx80211_hdr;
367    u32 eth_length;
368    llc_header_t* llc_hdr;
369    u16 pre_llc_offset;
370    int status;
371
372    // Read pointers -- these point to Rx packet buffers
373    u8* eth_payload_read;
374    arp_ipv4_packet_t* arp_read;
375    ipv4_header_t* ip_hdr_read;
376    udp_header_t* udp_read;
377    dhcp_packet* dhcp_read;
378
379    // Write pointers -- these point into Queue buffer in DRAM
380    ethernet_header_t* eth_hdr_write;
381    arp_ipv4_packet_t* arp_write;
382    ipv4_header_t* ip_hdr_write;
383    udp_header_t* udp_write;
384    dhcp_packet* dhcp_write;
385
386    u8 addr_da_localcopy[MAC_ADDR_LEN];
387    u8 addr_sa_localcopy[MAC_ADDR_LEN];
388
389    // Because the decapsulation procedure is destructive to the 802.11 header,
390    // we need to make copies of the addr_da and addr_sa arguments
391    if( flags & WLAN_ETH_ENCAP_FLAGS_OVERWRITE_PYLD_ADDRS ){
392        memcpy(addr_da_localcopy, mac_addr_to_overwrite, MAC_ADDR_LEN);
393    } else {
394        memcpy(addr_da_localcopy, addr_da, MAC_ADDR_LEN);
395    }
396    memcpy(addr_sa_localcopy, addr_sa, MAC_ADDR_LEN);
397
398    // Get helper pointers to various byte offsets in the packet payload
399    rx80211_hdr = (mac_header_80211*)(rx_mac_payload);
400
401    switch(rx80211_hdr->frame_control_1){
402        case MAC_FRAME_CTRL1_SUBTYPE_QOSDATA:
403            pre_llc_offset = sizeof(qos_control);
404        break;
405        case MAC_FRAME_CTRL1_SUBTYPE_DATA:
406            pre_llc_offset = 0;
407        break;
408        default:
409            // Unrecognized type -- cannot decapsulate
410            return WLAN_FAILURE;
411        break;
412    }
413
414    llc_hdr = (llc_header_t*)(rx_mac_payload + sizeof(mac_header_80211) + pre_llc_offset);
415    eth_payload_read = (u8*)(rx_mac_payload + sizeof(mac_header_80211) + sizeof(llc_header_t) + pre_llc_offset);
416    eth_length = rx_length - sizeof(mac_header_80211) - sizeof(llc_header_t) - pre_llc_offset - WLAN_PHY_FCS_NBYTES + sizeof(ethernet_header_t);
417
418    if(eth_length <= sizeof(ethernet_header_t)){
419        //This packet has no payload, we should quit now.
420        return WLAN_FAILURE;
421    }
422
423    // Speculatively check out a queue buffer and begin CDMA of the payload. This enables decapsulation
424    //  processing to be pipelined with the bulk of the copy
425
426    eth_tx_queue_entry = queue_checkout();
427
428    if(eth_tx_queue_entry == NULL){
429        return WLAN_FAILURE;
430    }
431
432    eth_tx_queue_buffer = (eth_tx_queue_buffer_t*)(eth_tx_queue_entry->data);
433    eth_hdr_write = (ethernet_header_t*)(eth_tx_queue_buffer->seg0);
434    eth_tx_queue_buffer->seg0_len = eth_length;
435    eth_tx_queue_buffer->seg1_len = 0;
436
437    // Start the transfer
438    wlan_mac_high_cdma_start_transfer((u8*)eth_hdr_write + sizeof(ethernet_header_t),
439                                      eth_payload_read,
440                                      eth_length - sizeof(ethernet_header_t));
441
442    // Create Ethernet Header
443    switch(llc_hdr->type){
444        case LLC_TYPE_ARP:
445            eth_hdr_write->ethertype = ETH_TYPE_ARP;
446        break;
447
448        case LLC_TYPE_IP:
449            eth_hdr_write->ethertype = ETH_TYPE_IP;
450        break;
451
452        default:
453            // Unrecognized type -- cannot decapsulate
454            wlan_mac_high_cdma_finish_transfer();
455            queue_checkin(eth_tx_queue_entry);
456            return WLAN_FAILURE;
457        break;
458    }
459    memcpy(eth_hdr_write->dest_mac_addr, addr_da_localcopy, MAC_ADDR_LEN);
460    memcpy(eth_hdr_write->src_mac_addr,  addr_sa_localcopy, MAC_ADDR_LEN);
461
462    // (Optional) -- overwrite MAC address present in the payload of the Ethernet frame
463    // with one stored previously during encapsulation
464    if( flags & WLAN_ETH_ENCAP_FLAGS_OVERWRITE_PYLD_ADDRS ){
465
466        // We are about to start modifying bytes deep into the payload of the packet. We should
467        //  wait for the CDMA operation to finish so we avoid a race.
468        wlan_mac_high_cdma_finish_transfer();
469
470        switch(llc_hdr->type){
471            case LLC_TYPE_ARP:
472                // If the ARP packet is addressed to this wireless address, replace the ARP dest address
473                // with the connected wired device's MAC address
474                arp_read = (arp_ipv4_packet_t *)(eth_payload_read); //eth_payload_read
475                arp_write = (arp_ipv4_packet_t *)((u8*)eth_hdr_write + sizeof(ethernet_header_t));
476                if (wlan_addr_eq(arp_read->target_haddr, get_mac_hw_addr_wlan())) {
477                    memcpy(arp_write->target_haddr, mac_addr_to_overwrite, MAC_ADDR_LEN);
478                }
479            break;
480
481            case ETH_TYPE_IP:
482                ip_hdr_read = (ipv4_header_t*)(eth_payload_read);
483                ip_hdr_write = (ipv4_header_t*)((u8*)eth_hdr_write + sizeof(ethernet_header_t));
484
485                if (ip_hdr_read->protocol == IPV4_PROT_UDP) {
486                    udp_read = (udp_header_t*)((void*)ip_hdr_read + 4*((u8)(ip_hdr_read->version_ihl) & 0xF));
487                    udp_write = (udp_header_t*)((void*)ip_hdr_write + 4*((u8)(ip_hdr_read->version_ihl) & 0xF));
488
489                    // All Bootstrap Protocol packets contain the client MAC address as part of the
490                    // payload. For STA de-encapsulation, we need to replace the wireless MAC address
491                    // of the STA with the wired MAC address of the client
492                    if ((Xil_Ntohs(udp_read->src_port) == UDP_SRC_PORT_BOOTPC) ||
493                        (Xil_Ntohs(udp_read->src_port) == UDP_SRC_PORT_BOOTPS)) {
494
495                        // Disable the checksum since this will change the bytes in the packet
496                        udp_write->checksum = 0;
497
498                        dhcp_read = (dhcp_packet*)((u8*)udp_read + sizeof(udp_header_t));
499                        dhcp_write = (dhcp_packet*)((u8*)udp_write + sizeof(udp_header_t));
500
501                        if (Xil_Ntohl(dhcp_read->magic_cookie) == DHCP_MAGIC_COOKIE) {
502                            // Overwrite DHCP client MAC address with the station's wireless MAC address
503                            memcpy(dhcp_write->chaddr, mac_addr_to_overwrite, MAC_ADDR_LEN);
504                        } // END is DHCP valid
505                    } // END is DHCP
506                } // END is UDP
507
508            break;
509
510            default:
511            break;
512        }
513    }
514
515    // Wait for CDMA to finish. If ~WLAN_ETH_ENCAP_FLAGS_OVERWRITE_PYLD_ADDRS, we have not called this yet
516    wlan_mac_high_cdma_finish_transfer();
517
518    // Add it to the Tx queue
519    status = wlan_enqueue_eth_tx(eth_tx_queue_entry);
520
521    if(status == -1){
522        queue_checkin(eth_tx_queue_entry);
523        return WLAN_FAILURE;
524    } else {
525        return WLAN_SUCCESS;
526    }
527#else
528    return WLAN_FAILURE;
529#endif
530}
531
532#if WLAN_SW_CONFIG_ENABLE_ETH_BRIDGE
533// Local functions
534
535void _portal_eth_rx_queue_occupancy_change(int callback_arg, u32 queue_len){
536    // callback_arg is not used. It was set to 0 when opening the queue
537
538    if(queue_len == 0){
539        wlan_platform_clear_sw_intr(SW_INTR_ID_PORTAL_ETH_RX);
540    } else {
541        wlan_platform_assert_sw_intr(SW_INTR_ID_PORTAL_ETH_RX);
542    }
543}
544
545void _portal_eth_tx_queue_occupancy_change(int callback_arg, u32 queue_len){
546    // callback_arg is not used. It was set to 0 when opening the queue
547
548    if(queue_len == 0){
549        wlan_platform_clear_sw_intr(SW_INTR_ID_PORTAL_ETH_TX);
550    } else {
551        wlan_platform_assert_sw_intr(SW_INTR_ID_PORTAL_ETH_TX);
552    }
553}
554#endif
Note: See TracBrowser for help on using the repository browser.