Changes between Version 10 and Version 11 of 802.11/wlan_exp/app_notes/tutorial_token_mac/CPU_LOW


Ignore:
Timestamp:
Jul 10, 2015, 2:06:11 PM (9 years ago)
Author:
chunter
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • 802.11/wlan_exp/app_notes/tutorial_token_mac/CPU_LOW

    v10 v11  
    365365#!c
    366366
     367#define POLL_MAC_STATUS_TOKEN_OFFER_ACCEPTED 0x10000000
    367368void token_new_reservation(ipc_token_new_reservation* new_reservation){
    368369
     
    517518}
    518519
     520}}}
     521
    519522Now we need to call the new function whenever we can. In the primary {{{while(1)}}} loop of the {{{main()}}} function of NoMAC, simply add a call to {{{poll_reservation_time()}}}.
    520523
    521524----
    522525
    523 {{{
    524 #!c
    525 
    526 }}}
    527 
    528 ----
    529 }}}
     526Next, we need to change the {{{frame_receive()}}} function of the to deal with two potential kinds of receptions:
     527
     5281. If we are a STA, we could expect to receive a token offer from the AP. If we do, we should respond with a token response before the AP times out on the offer. After sending the token response, we know that we have entered a token reservation period so we should allow the transmission of new MPDUs and set the {{{reservation_ts_end}}} variable to represent the time when our token reservation period ends.
     5292. If we are an AP, we could expect to receive a token response from other STAs. If we do, we need to let the {{{token_new_reservation()}}} context know that we did. Note in a previous change that {{{token_new_reservation()}}} actively looks for a {{{POLL_MAC_STATUS_TOKEN_OFFER_ACCEPTED}}} flag to be returned from the receive context. We should raise this flag.
     530
     531The following function is a drop-in replacement to the existing {{{frame_receive function}}} that implements the above behavior:
     532
     533{{{
     534#!c
     535
     536u32 frame_receive(u8 rx_pkt_buf, phy_rx_details* phy_details){
     537        //This function is called after a good SIGNAL field is detected by either PHY (OFDM or DSSS)
     538        //It is the responsibility of this function to wait until a sufficient number of bytes have been received
     539        // before it can start to process those bytes. When this function is called the eventual checksum status is
     540        // unknown. The packet contents can be provisionally processed (e.g. prepare an ACK for fast transmission),
     541        // but post-reception actions must be conditioned on the eventual FCS status (good or bad).
     542        //
     543        // Note: The timing of this function is critical for correct operation of the 802.11 DCF. It is not
     544        // safe to add large delays to this function (e.g. xil_printf or usleep)
     545        //
     546        //Two primary job responsibilities of this function:
     547        // (1): Prepare outgoing ACK packets and instruct the MAC_DCF_HW core whether or not to send ACKs
     548        // (2): Pass up MPDUs (FCS valid or invalid) to CPU_HIGH
     549
     550        u8 unicast_to_me;
     551        mac_header_80211* rx_header;
     552        mac_frame_custom_token* rx_token_frame;
     553        u8 ctrl_tx_gain;
     554        u32 tx_length;
     555        u32 return_value = 0;
     556        u32 mac_hw_status;
     557        wlan_ipc_msg       ipc_msg_to_high_start;
     558        ipc_token_new_reservation ipc_payload_start;
     559
     560        ipc_msg_to_high_start.msg_id            = IPC_MBOX_MSG_ID(IPC_MBOX_TOKEN_NEW_RESERVATION);
     561
     562        if( (sizeof(u32)*(sizeof(ipc_token_new_reservation)/sizeof(u32))) ==  sizeof(ipc_token_new_reservation) ){
     563                ipc_msg_to_high_start.num_payload_words = (sizeof(ipc_token_new_reservation)/sizeof(u32));
     564        } else {
     565                ipc_msg_to_high_start.num_payload_words = (sizeof(ipc_token_new_reservation)/sizeof(u32)) + 1;
     566        }
     567
     568        ipc_msg_to_high_start.payload_ptr       = (u32*)(&ipc_payload_start);
     569
     570        rx_frame_info* mpdu_info;
     571        void* pkt_buf_addr = (void *)RX_PKT_BUF_TO_ADDR(rx_pkt_buf);
     572
     573        mpdu_info = (rx_frame_info*)pkt_buf_addr;
     574
     575        rx_header = (mac_header_80211*)((void*)(pkt_buf_addr + PHY_RX_PKT_BUF_MPDU_OFFSET));
     576
     577        //Wait until the PHY has written enough bytes so that the first address field can be processed
     578        while(wlan_mac_get_last_byte_index() < MAC_HW_LASTBYTE_TOKEN){
     579        };
     580
     581        unicast_to_me = wlan_addr_eq(rx_header->address_1, eeprom_addr);
     582
     583        if(unicast_to_me && (rx_header->frame_control_1 == MAC_FRAME_CTRL1_SUBTYPE_TOKEN_OFFER)){
     584                //Received a token offer
     585                rx_token_frame = (mac_frame_custom_token*)rx_header;
     586
     587                //Set up a Token Response
     588                //wlan_mac_tx_ctrl_B_params(pktBuf, antMask, req_zeroNAV, preWait_postRxTimer1, preWait_postRxTimer2, postWait_postTxTimer1)
     589                wlan_mac_tx_ctrl_B_params(TX_PKT_BUF_TOKEN, 0x1, 0, 1, 0, 0);
     590
     591                //ACKs are transmitted with a nominal Tx power used for all control packets
     592                ctrl_tx_gain = wlan_mac_low_dbm_to_gain_target(15);
     593                wlan_mac_tx_ctrl_B_gains(ctrl_tx_gain, ctrl_tx_gain, ctrl_tx_gain, ctrl_tx_gain);
     594
     595                //Construct the token response frame in the dedicated Tx pkt buf
     596                tx_length = wlan_create_token_response_frame((void*)(TX_PKT_BUF_TO_ADDR(TX_PKT_BUF_TOKEN) + PHY_TX_PKT_BUF_MPDU_OFFSET),
     597                                                                                                          rx_token_frame->address_ta,
     598                                                                                                      eeprom_addr,
     599                                                                                                      0,
     600                                                                                                      rx_token_frame->res_duration_usec); //TODO: Calculate appropriate duration
     601
     602
     603                //Write the SIGNAL field for the ACK
     604                wlan_phy_set_tx_signal(TX_PKT_BUF_TOKEN, WLAN_PHY_RATE_BPSK12, tx_length);
     605
     606                mpdu_info->state = wlan_mac_dcf_hw_rx_finish();
     607
     608                if(mpdu_info->state == RX_MPDU_STATE_FCS_GOOD){
     609
     610                        memcpy( ipc_payload_start.addr, rx_token_frame->address_ra, 6 );
     611                        ipc_payload_start.res_duration = rx_token_frame->res_duration_usec;
     612                        ipc_mailbox_write_msg(&ipc_msg_to_high_start);
     613
     614                        wlan_mac_tx_ctrl_B_start(1);
     615                        wlan_mac_tx_ctrl_B_start(0);
     616
     617                        do{
     618                                mac_hw_status = wlan_mac_get_status();
     619
     620                                if( (mac_hw_status & WLAN_MAC_STATUS_MASK_TX_B_STATE) == WLAN_MAC_STATUS_TX_B_STATE_DO_TX ) {
     621                                        break;
     622                                }
     623                        } while(mac_hw_status & WLAN_MAC_STATUS_MASK_TX_B_PENDING);
     624
     625                        //Since this is our reservation period, we are now allowed to transmit
     626                        in_reservation = 1;
     627                        reservation_ts_end = get_usec_timestamp() + ((u64)rx_token_frame->res_duration_usec);
     628                        wlan_mac_low_enable_new_mpdu_tx();
     629                }
     630        } else if(unicast_to_me && (rx_header->frame_control_1 == MAC_FRAME_CTRL1_SUBTYPE_TOKEN_RESPONSE)) {
     631                //Received a token offer
     632                rx_token_frame = (mac_frame_custom_token*)rx_header;
     633
     634                if(rx_token_frame->res_duration_usec != 0){
     635                        mpdu_info->state = wlan_mac_dcf_hw_rx_finish();
     636                        if(mpdu_info->state == RX_MPDU_STATE_FCS_GOOD){
     637                                return_value |= POLL_MAC_STATUS_TOKEN_OFFER_ACCEPTED;
     638                        }
     639                }
     640        } else {
     641                mpdu_info->state = wlan_mac_dcf_hw_rx_finish(); //Blocks until reception is complete
     642        }
     643
     644        mpdu_info->flags = 0;
     645        mpdu_info->phy_details = *phy_details;
     646        mpdu_info->channel = wlan_mac_low_get_active_channel();
     647        mpdu_info->timestamp = get_rx_start_timestamp();
     648
     649
     650        mpdu_info->ant_mode = wlan_phy_rx_get_active_rx_ant();
     651
     652        mpdu_info->rf_gain = wlan_phy_rx_get_agc_RFG(mpdu_info->ant_mode);
     653        mpdu_info->bb_gain = wlan_phy_rx_get_agc_BBG(mpdu_info->ant_mode);
     654        mpdu_info->rx_power = wlan_mac_low_calculate_rx_power(wlan_phy_rx_get_pkt_rssi(mpdu_info->ant_mode), wlan_phy_rx_get_agc_RFG(mpdu_info->ant_mode));
     655
     656        if(mpdu_info->state == RX_MPDU_STATE_FCS_GOOD){
     657                green_led_index = (green_led_index + 1) % NUM_LEDS;
     658                userio_write_leds_green(USERIO_BASEADDR, (1<<green_led_index));
     659        } else {
     660                red_led_index = (red_led_index + 1) % NUM_LEDS;
     661                userio_write_leds_red(USERIO_BASEADDR, (1<<red_led_index));
     662        }
     663
     664        //Unlock the pkt buf mutex before passing the packet up
     665        // If this fails, something has gone horribly wrong
     666        if(unlock_pkt_buf_rx(rx_pkt_buf) != PKT_BUF_MUTEX_SUCCESS){
     667                xil_printf("Error: unable to unlock RX pkt_buf %d\n", rx_pkt_buf);
     668                wlan_mac_low_send_exception(EXC_MUTEX_RX_FAILURE);
     669        } else {
     670                wlan_mac_low_frame_ipc_send();
     671                //Find a free packet buffer and begin receiving packets there (blocks until free buf is found)
     672                wlan_mac_low_lock_empty_rx_pkt_buf();
     673        }
     674
     675        //Unblock the PHY post-Rx (no harm calling this if the PHY isn't actually blocked)
     676        wlan_mac_dcf_hw_unblock_rx_phy();
     677
     678        return return_value;
     679
     680}
     681}}}
     682
     683----
     684
     685