wiki:802.11/wlan_exp/app_notes/tutorial_token_mac/CPU_HIGH

Version 2 (modified by chunter, 9 years ago) (diff)

--

Alterations to CPU_HIGH

In this section, we will describe and discuss the changes needed to the high-level MAC code to realize the design. Specifically, we will modify the AP codebase to allow it to determine which node in the network should have the token and for how long it should have it.

Overview of Changes

The main concept of TokenMAC is that the token should rotate among members of the network. This inherently requires knowledge of the membership of the network so that that it can be determined who should be given the token and for how long they should have it. In the 802.11 Reference Design, knowledge of network membership (or "association") belongs to the AP. As such, the AP project is well-suited to being modified with the behavior of managing token passing. In a sense, the AP becomes a sort of "traffic cop" and halts traffic from certain associations while enabling traffic to others.

Additionally, we will need to make some small changes to the MAC High Framework to deal with some new inter-processor communication (IPC) messages with CPU_LOW.

Specific Changes

Access Point (AP)

Changes should be made to wlan_mac_ap.c.


  1. We need to create a function that, when called, knows how to issue a new token for a reservation period to a device on the network. Note: the AP itself needs to be able to transmit, so it should include itself as one of the devices that get issued a token. Add the following function to the AP code:
void set_new_reservation(){

#define DEFAULT_RESERVATION_DURATION_USEC 20000

    interrupt_state_t curr_interrupt_state;

    static dl_entry* next_station_info_entry = NULL;
    dl_entry* curr_station_info_entry;

    station_info* curr_station_info;

    wlan_ipc_msg       ipc_msg_to_low;
    ipc_token_new_reservation ipc_payload;

    ipc_msg_to_low.msg_id            = IPC_MBOX_MSG_ID(IPC_MBOX_TOKEN_NEW_RESERVATION);

    if( (sizeof(u32)*(sizeof(ipc_token_new_reservation)/sizeof(u32))) ==  sizeof(ipc_token_new_reservation) ){
        ipc_msg_to_low.num_payload_words = (sizeof(ipc_token_new_reservation)/sizeof(u32));
    } else {
        ipc_msg_to_low.num_payload_words = (sizeof(ipc_token_new_reservation)/sizeof(u32)) + 1;
    }

    ipc_msg_to_low.payload_ptr       = (u32*)(&ipc_payload);


    curr_interrupt_state = wlan_mac_high_interrupt_stop();

    // Send an IPC message down to CPU_LOW to let it know we are moving to a new
    // reservation period.

    curr_station_info_entry = next_station_info_entry;

    // Loop through all associated stations' queues
    if(curr_station_info_entry == NULL){
        // It's the AP's reservation
        next_station_info_entry = my_bss_info->associated_stations.first;

        //SEND IPC for AP

        memcpy( ipc_payload.addr, my_bss_info->bssid, 6 );
        ipc_payload.res_duration = DEFAULT_RESERVATION_DURATION_USEC;
        ipc_mailbox_write_msg(&ipc_msg_to_low);

        curr_station_info_entry = next_station_info_entry;

    } else {
        curr_station_info = (station_info*)(curr_station_info_entry->data);
        if( wlan_mac_high_is_valid_association(&my_bss_info->associated_stations, curr_station_info) ){
            if(curr_station_info_entry == my_bss_info->associated_stations.last){
                // We've reached the end of the table, so we wrap around to the beginning
                next_station_info_entry = NULL;
            } else {
                next_station_info_entry = dl_entry_next(curr_station_info_entry);
            }

            //SEND IPC for curr_station_info

            memcpy( ipc_payload.addr, curr_station_info->addr, 6 );
            ipc_payload.res_duration = DEFAULT_RESERVATION_DURATION_USEC;
            ipc_mailbox_write_msg(&ipc_msg_to_low);

            curr_station_info_entry = next_station_info_entry;

        } else {
            // This curr_station_info is invalid. Perhaps it was removed from
            // the association table before poll_tx_queues was called. We will
            // start the round robin checking back at broadcast.
            next_station_info_entry = NULL;
        } // END if(is_valid_association)
    }

    wlan_mac_high_interrupt_restore_state(curr_interrupt_state);

}

Take a minute and read through what that code snippet is doing. Every time it is called, it will move on to the next member of the association table doubly-linked list and send an IPC message to CPU_LOW indicating the address of that member along with a duration of time the token reservation for that member should last. After every loop through of the association table, it will issue an IPC message to CPU_LOW using its own BSSID as the address in the IPC payload. This indicates that the medium is now reserved for the AP itself.