WARP Project Forums - Wireless Open-Access Research Platform

You are not logged in.

#1 2016-Feb-13 11:20:46

Christian
Member
Registered: 2010-Feb-26
Posts: 124

80211 Design: own MAC packets

Hi,

while migrating from an old 80211 design to the new design v1.4.0, we face some lockups of the PHY.

The context is the following: We want to design an own MAC scheme (incompatible to 80211). For this, we created an own MAC header and placed it in the buffer in the "beginning", i.e. in that location that is used by the PHY for transmission. As we are only interested in an OFDM transmission, we disabled DSSS using

Code:

wlan_phy_DSSS_rx_disable();
wlan_phy_rx_pktDet_autoCorr_dsss_cfg(0xFF, 0x3FF, 30, 40);

Then, we simplified the wlan_mac_low_poll_frame_rx() as follows:

Code:

inline u32 wlan_mac_low_poll_frame_rx(){
    int            i;
    phy_rx_details phy_details;
    volatile u32   mac_hw_status;
    u32            mac_hw_phy_rx_params;
    u32            return_status = 0;

    // Read the MAC/PHY status
    mac_hw_status = wlan_mac_get_status();

    // Check if PHY is currently receiving or has finished receiving
    if(mac_hw_status & (WLAN_MAC_STATUS_MASK_RX_PHY_ACTIVE | WLAN_MAC_STATUS_MASK_RX_PHY_BLOCKED_FCS_GOOD | WLAN_MAC_STATUS_MASK_RX_PHY_BLOCKED)) {

        return_status |= POLL_MAC_STATUS_RECEIVED_PKT;               // We received something in this poll

        if (DBG_PRINT) { xil_printf("MAC Rx: 0x%08x\n", mac_hw_status); }

        i = 0;

        // Check whether this is an OFDM or DSSS Rx
        if(wlan_mac_get_rx_phy_sel() == WLAN_MAC_PHY_RX_PARAMS_PHY_SEL_DSSS) {
/*
            // DSSS Rx - PHY Rx length is already valid, other params unused for DSSS
            phy_details.phy_mode = PHY_RX_DETAILS_MODE_DSSS;
            phy_details.N_DBPS   = 0;                                // Invalid for DSSS

            // Strip off extra pre-MAC-header bytes used in DSSS frames; this adjustment allows the next
            //     function to treat OFDM and DSSS payloads the same
            phy_details.length   = wlan_mac_get_rx_phy_length() - 5;
            phy_details.mcs      = WLAN_MAC_MCS_1M;

            if (DBG_PRINT) { xil_printf("DSSS Rx callback: %d / %d / %d\n", phy_details.phy_mode, phy_details.length, phy_details.mcs); }

            // Call the user callback to handle this Rx, capture return value
            return_status       |= frame_rx_callback(rx_pkt_buf, &phy_details);

            if (DBG_PRINT) { xil_printf("DSSS Rx callback return: 0x%08x\n", return_status); }
*/
        	wlan_mac_dcf_hw_rx_finish();
            wlan_mac_dcf_hw_unblock_rx_phy();
        } else {

            // OFDM Rx - must wait for PHY_RX_PARAMS to be valid before reading mcs/length
            do {
                mac_hw_phy_rx_params = wlan_mac_get_rx_params();

                if (DBG_PRINT) { xil_printf("MAC Rx Poll 1 (%4d): 0x%08x  0x%08x\n", i++, mac_hw_phy_rx_params, wlan_mac_get_status()); }

            } while((mac_hw_phy_rx_params & WLAN_MAC_PHY_RX_PARAMS_MASK_PARAMS_VALID) == 0);

            i = 0;

            // Check if PHY is continuing Rx (11a: valid SIGNAL, 11n: valid+supported HT-SIG)
            if((mac_hw_phy_rx_params & (WLAN_MAC_PHY_RX_PARAMS_MASK_UNSUPPORTED | WLAN_MAC_PHY_RX_PARAMS_MASK_RX_ERROR))) {
#ifdef DEBUG // added specifically for v1.4.0
            	//Write msg header (first 32b word)
                u64 timestamp = get_system_time_usec();
#define DEBUG_MAX_DELAY_US 1000
                do {
                    mac_hw_status = wlan_mac_get_status();
                } while (mac_hw_status & WLAN_MAC_STATUS_MASK_RX_PHY_ACTIVE && get_system_time_usec() < (timestamp + DEBUG_MAX_DELAY_US));

            	if (get_system_time_usec() >= (timestamp + DEBUG_MAX_DELAY_US)) {
            		debug(DBG_FATAL, "T\r\n");

            		REG_SET_BITS(WLAN_RX_REG_CTRL, WLAN_RX_REG_CTRL_RESET);
            		wlan_mac_reset(1);

            		REG_CLEAR_BITS(WLAN_RX_REG_CTRL, WLAN_RX_REG_CTRL_RESET);
            		wlan_mac_reset(0);
            	}
#else
                // PHY is not processing this Rx - do not call user callback
                return_status = return_status & ~POLL_MAC_STATUS_RECEIVED_PKT;

                // Wait for PHY to finish, then clear block
                do {
                    mac_hw_status = wlan_mac_get_status();

                    if (DBG_PRINT) { xil_printf("MAC Rx Poll 2 (%4d): 0x%08x  0x%08x\n", i++, mac_hw_phy_rx_params, wlan_mac_get_status()); }
                } while(mac_hw_status & WLAN_MAC_STATUS_MASK_RX_PHY_ACTIVE);
#endif
                wlan_mac_dcf_hw_unblock_rx_phy();
            } else {
                // PHY is processing this Rx - read mcs/length/phy-mode
                phy_details.phy_mode = wlan_mac_get_rx_phy_mode();
                phy_details.length   = wlan_mac_get_rx_phy_length();
                phy_details.mcs      = wlan_mac_get_rx_phy_mcs();
                phy_details.N_DBPS   = wlan_mac_low_mcs_to_n_dbps(phy_details.mcs);

                if (DBG_PRINT) { xil_printf("OFDM Rx callback: %d / %d / %d\n", phy_details.phy_mode, phy_details.length, phy_details.mcs); }

                // Call the user callback to handle this Rx, capture return value
                return_status       |= frame_rx_callback(rx_pkt_buf, &phy_details);

                if (DBG_PRINT) { xil_printf("OFDM Rx callback return: 0x%08x\n", return_status); }
            }
        }
    }
    return return_status;
}

Unfortunately, this does not work anymore with v1.4.0 if we use the system in a channel, where leagcy Wifi devices operate. First (without the #ifdef DEBUG branch), the system never returned if WLAN_MAC_PHY_RX_PARAMS_MASK_RX_ERROR was raised as the phy was always active. With the #ifdef, the system breaks out of this loop, but seems to lockup on (one of) the next packets, as the PHY again is always active.

Could it be related to changes you made with respect to 11n? As there is a HT-SIG field in the payload part of the packet, could it be that our MAC header coincidentally creates a "strange", but valid HT-SIG field?

Offline

 

#2 2016-Feb-13 16:02:07

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 4954

Re: 80211 Design: own MAC packets

Apologies for the delay in responding to your other thread. We're still trying to isolate the behavior you've observed.

The context is the following: We want to design an own MAC scheme (incompatible to 80211). For this, we created an own MAC header and placed it in the buffer in the "beginning", i.e. in that location that is used by the PHY for transmission.

Where specifically did you place your custom MAC header - in the usual location of the MAC payload (TX_PKT_BUF_TO_ADDR(pkt_buf) + PHY_TX_PKT_BUF_MPDU_OFFSET)? This is the first "safe" byte address for arbitrary MAC payloads. Bytes before that address are used for the PHY header (SIGNAL/SERVICE or L-SIG/HT-SIG/SERVICE). The PHY header must be valid even if the MAC payload is non-standard.

There is definitely a bug in the v1.4 Rx PHY where the RX_ERROR output does not assert coincident with RX_END when an unsupported HT-SIG is received. For example if the HT-SIG indicates MCS=8, the Rx PHY pipeline will terminate (as it should) but the RX_ERROR signal asserts a few cycles after RX_END asserts. The MAC core uses (RX_ERROR!=0 && RX_END==1) as its error checking condition. Thus, the MAC core does not observe the Rx PHY error condition. So far, this is the only bug we've found that results in a node hanging in the MAC_HW_LASTBYTE_ADDR1 while loop. See this thread for one workaround. This bug is already fixed in the latest Rx PHY, to be used in v1.5 soon.

Unfortunately, this does not work anymore with v1.4.0 if we use the system in a channel, where leagcy Wifi devices operate. First (without the #ifdef DEBUG branch), the system never returned if WLAN_MAC_PHY_RX_PARAMS_MASK_RX_ERROR was raised as the phy was always active. With the #ifdef, the system breaks out of this loop, but seems to lockup on (one of) the next packets, as the PHY again is always active.

The MAC RX_PHY_ACTIVE status bit asserts on the PHY's RX_START output and clears on the PHY's RX_END output. In the case of a valid but unsupported HT-SIG the Rx PHY is supposed to assert RX_END at the end of the incoming waveform, even though the PHY pipeline is not attempting to decode the waveform. This allows the MAC state to accurately reflect the medium state (i.e. the medium is busy even if the local PHY can't decode the current waveform). I'm working on cleaning up the logic for v1.5 to handle all cases of valid/invalid/unsupported L-SIG/HT-SIG.

One observation on your debug code- some Wi-Fi frames are longer duration than 1000usec. I'd be curious to know if the node is actually stuck or would finish eventually if your timeout were larger (10+ msec).

It would also be very helpful to know the Rx PHY and MAC state at the time that your timeout occurs. Can you add the printing code in this post and post the output here?

Offline

 

#3 2016-Feb-14 06:34:32

Christian
Member
Registered: 2010-Feb-26
Posts: 124

Re: 80211 Design: own MAC packets

murphpo wrote:

Where specifically did you place your custom MAC header - in the usual location of the MAC payload (TX_PKT_BUF_TO_ADDR(pkt_buf) + PHY_TX_PKT_BUF_MPDU_OFFSET)?

Yes, exactly at this address.

murphpo wrote:

One observation on your debug code- some Wi-Fi frames are longer duration than 1000usec. I'd be curious to know if the node is actually stuck or would finish eventually if your timeout were larger (10+ msec).

You are  right. We increased it to 10ms. So far, we did not observe another stuck of the station, but the external wifi devices are not that heavily used on weekends. To confirm that more reliably, we have to wait and test longer.

It would also be very helpful to know the Rx PHY and MAC state at the time that your timeout occurs. Can you add the printing code in this post and post the output here?

This code is added. We "just" have to wait now.

Thank you for your feedback!

Offline

 

#4 2016-Feb-14 08:45:10

Christian
Member
Registered: 2010-Feb-26
Posts: 124

Re: 80211 Design: own MAC packets

Ok, it just happened. Multiple runs of up to 30min without problem. Now after ~10min of normal operation, one out of four stations had this (the others are located right next to it).

After replacing the #ifdef DEBUG branch from the earlier source with the code you suggested:

Code:

 //Write msg header (first 32b word)
    u64 timestamp = get_system_time_usec();
#define DEBUG_MAX_DELAY_US 10000
    do {
        mac_hw_status = wlan_mac_get_status();
     if (XUartLite_IsReceiveEmpty(UartLite.RegBaseAddress) == 0) {
    //  u8 value = 0;
    //  XUartLite_Recv(&UartLite,&value,1);
      xil_printf("RX_INVALID %d, %d\r\n", mac_hw_status, XUartLite_RecvByte(UartLite.RegBaseAddress));
     }
    } while (mac_hw_status & WLAN_MAC_STATUS_MASK_RX_PHY_ACTIVE && get_system_time_usec() < (timestamp + DEBUG_MAX_DELAY_US));

 if (get_system_time_usec() >= (timestamp + DEBUG_MAX_DELAY_US)) {
  debug(DBG_FATAL, "RX-Time: %d\r\n", mac_hw_status);
        // PHY is processing this Rx - read mcs/length/phy-mode
  phy_details.phy_mode = wlan_mac_get_rx_phy_mode();
        phy_details.length   = wlan_mac_get_rx_phy_length();
        phy_details.mcs      = wlan_mac_get_rx_phy_mcs();
        phy_details.N_DBPS   = wlan_mac_low_mcs_to_n_dbps(phy_details.mcs);
  xil_printf("\n\n---Stuck in frame_receive()---\n");
  xil_printf("wlan_mac_get_last_byte_index() =       %d\n", wlan_mac_get_last_byte_index());
  xil_printf("phy_details->length =                  %d\n", phy_details.length);
  xil_printf("phy_details->mcs =                     0x%x\n", phy_details.mcs);
  xil_printf("phy_details->phy_mode =                0x%x\n", phy_details.phy_mode);
  xil_printf("phy_details->N_DBPS =                  0x%x\n", phy_details.N_DBPS);
  xil_printf("Xil_In32(WLAN_MAC_REG_PHY_RX_PARAMS) = 0x%08x\n", Xil_In32(WLAN_MAC_REG_PHY_RX_PARAMS));
  xil_printf("Xil_In32(WLAN_RX_STATUS) =             0x%08x\n", Xil_In32(WLAN_RX_STATUS));
  xil_printf("\nPacket buffer contents:\n");
  u32 idx_start, idx_end, temp_idx;
  u8* temp_pkt_buf = RX_PKT_BUF_TO_ADDR(rx_pkt_buf);
  idx_start = 0;
  idx_end = idx_start + PHY_RX_PKT_BUF_PHY_HDR_OFFSET - 1;
  xil_printf("------[%d] - [%d] : rx_frame_info\n", idx_start, idx_end);
  for(temp_idx = idx_start; temp_idx <= idx_end; temp_idx++){
   xil_printf("%02x ", temp_pkt_buf[temp_idx]);
  }
  xil_printf("\n");
  idx_start = idx_end + 1;
  idx_end = idx_start + PHY_RX_PKT_BUF_PHY_HDR_SIZE - 1;
  xil_printf("------[%d] - [%d] : PHY_RX_PKT_BUF_PHY_HDR\n", idx_start, idx_end);
  for(temp_idx = idx_start; temp_idx <= idx_end; temp_idx++){
   xil_printf("%02x ", temp_pkt_buf[temp_idx]);
  }
  xil_printf("\n");
  idx_start = idx_end + 1;
  idx_end = idx_start + 100 - 1; //Just print 100 bytes of MAC payload
  xil_printf("------[%d] - [%d] : MAC Payload\n", idx_start, idx_end);
  for(temp_idx = idx_start; temp_idx <= idx_end; temp_idx++){
   xil_printf("%02x ", temp_pkt_buf[temp_idx]);
  }
  xil_printf("\n");
  while(1) {};

  REG_SET_BITS(WLAN_RX_REG_CTRL, WLAN_RX_REG_CTRL_RESET);
  wlan_mac_reset(1);

  REG_CLEAR_BITS(WLAN_RX_REG_CTRL, WLAN_RX_REG_CTRL_RESET);
  wlan_mac_reset(0);
 }

This is the output:

Code:

mac_hw_status: 0x28002

---Stuck in frame_receive()---
wlan_mac_get_last_byte_index() =       247
phy_details->length =                  248
phy_details->mcs =                     0x2
phy_details->phy_mode =                0x1
phy_details->N_DBPS =                  0x30
Xil_In32(WLAN_MAC_REG_PHY_RX_PARAMS) = 0x330200F8
Xil_In32(WLAN_RX_STATUS) =             0x00000010

Packet buffer contents:
------[0] - [311] : rx_frame_info
02 00 00 B3 01 02 CB 00 30 00 00 00 03 12 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3F DE 2A 10 00 00 00 00 00 00 00 00 D7 17 32 28 CD 10 8A 2E B5 03 D3 2E 5A F9 2C 2E 25 F2 34 2B 33 E6 54 29 C4 E2 F8 1F 98 DF 99 14 8A D9 38 11 64 D6 47 06 4A D8 32 FC 99 D9 3B FB 25 E3 4A F7 E2 DF 20 DF 7C DD 9C E0 01 EB 29 DB 93 F9 36 D4 1A 08 F0 CE 23 0A 5A D5 18 24 EF D8 D8 26 1E ED 4A 28 A5 FC 53 1C AB 0F DE 11 DE 10 C8 09 C1 1B 58 FE D7 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 24 ED 14 CC 18 7A 23 3A 08 75 22 59 FE 19 30 FF E0 FC 28 A5 CE 44 22 11 C1 72 02 27 B7 68 EA A5 D1 19 D4 1E E3 98 C2 D2 FB 77 D1 A7 0A B1 CA 75 1A 7C D1 F7 1D 3A E0 A4 1B A1 E9 06 27 DE F2 94 20 4E F0 8B 21 25 ED 7F 1E B9 FB D5 22 29 FD 84 20 29 FF AB 1E EF 0F 09 1F CF 10 70 26 27 17 A0 22 02 16 63 17 B5 26 

------[312] - [327] : PHY_RX_PKT_BUF_PHY_HDR
0A 1F 02 70 4F 00 00 00 00 00 00 00 00 00 00 00 

------[328] - [427] : MAC Payload
93 40 64 74 6D 30 2B E7 2D 54 5F 8A 1D 7F B8 A7 49 20 32 BA 36 98 95 F3 16 AA 2F C5 8E 3F DC D3 24 10 19 5D 1B CC CA 79 0B D5 97 62 C7 1F EE 69 12 88 8C AE 0D 66 E5 BC 85 76 FE 3E C3 D1 93 A6 CD E5 87 03 4B B3 60 31 82 D4 9F 1D 97 8F 97 23 A6 AD 40 2D D0 79 42 1A 63 25 0D A1 5B 88 E7 D1 A4 E0 8A 6C

Last edited by Christian (2016-Feb-14 08:53:56)

Offline

 

#5 2016-Feb-14 08:55:15

Christian
Member
Registered: 2010-Feb-26
Posts: 124

Re: 80211 Design: own MAC packets

Ok, and now again after reloading in just 10sec:

Code:

mac_hw_status: 0x28002

---Stuck in frame_receive()---
wlan_mac_get_last_byte_index() =       202
phy_details->length =                  203
phy_details->mcs =                     0x2
phy_details->phy_mode =                0x1
phy_details->N_DBPS =                  0x30
Xil_In32(WLAN_MAC_REG_PHY_RX_PARAMS) = 0x330200CB
Xil_In32(WLAN_RX_STATUS) =             0x00000010

Packet buffer contents:
------[0] - [311] : rx_frame_info
02 00 00 D2 01 02 14 00 30 00 00 00 02 0C 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 89 0B 66 1D 00 00 00 00 00 00 00 00 07 DA DA FE 3B E1 DA F0 E2 E4 12 E6 3C E9 EC E4 8F F0 87 E3 F4 E8 5F D9 99 F8 63 DE 2C 02 77 D5 A7 03 1B CB 72 07 5C CE AA 20 03 E4 FF 21 2D E5 C6 1F 93 E8 11 2C 6D EB B5 3C 1B 04 68 2C C9 12 02 32 CC 20 25 28 94 25 A6 09 83 43 97 F7 FF 31 1E E7 92 31 39 D8 D6 0D E5 D2 29 11 EC E1 9B FF CE F0 10 F3 6D E9 8E EB 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 AA F0 79 F7 34 FD BF FC 04 E4 68 FC CF F1 39 F6 90 01 C7 D7 9C FA D7 E1 2C 14 72 D0 51 22 E8 D8 C7 2D E8 E5 49 2A 59 04 3C 23 B5 FE A3 21 FB 11 69 1A 14 1A 27 19 C4 24 94 0C A8 2D E7 0A DB 25 1D F4 DF 21 06 FB 9A 38 EE F0 9E 1D DA E8 F5 1D 9E F6 88 28 C9 DD 5C 17 4E CD 8D 0A 3E DD 85 F1 08 DD 69 FD C6 E7 7E F0 

------[312] - [327] : PHY_RX_PKT_BUF_PHY_HDR
6A 19 02 00 00 00 07 58 03 00 00 00 00 00 00 00 

------[328] - [427] : MAC Payload
80 00 00 00 FF FF FF FF FF FF 2E E3 4E A2 F6 6C CA 79 0B D5 97 62 C7 1F EE 69 12 88 8C AE 0D 66 E5 BC 85 EA 4B B1 E3 0F F7 34 09 44 46 D7 06 B3 72 DE 42 F5 A5 D8 F1 87 7B 9A 04 22 A3 6B 83 59 39 6F A1 FA 52 EC F8 C3 3D 4D 02 E9 B0 1E A6 4F 85 FE 5B 24 19 D7 BC B2 C6 C6 5C AF 44 1E 85 16 F1 25 FE 23

and

Code:

---Stuck in frame_receive()---
wlan_mac_get_last_byte_index() =       241
phy_details->length =                  242
phy_details->mcs =                     0x2
phy_details->phy_mode =                0x1
phy_details->N_DBPS =                  0x30
Xil_In32(WLAN_MAC_REG_PHY_RX_PARAMS) = 0x330200F2
Xil_In32(WLAN_RX_STATUS) =             0x00000010

Packet buffer contents:
------[0] - [311] : rx_frame_info
02 00 00 BA 01 02 14 00 30 00 00 00 03 0F 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2F F7 A9 1D 00 00 00 00 00 00 00 00 1C C9 38 F8 3C EB 64 E1 B9 ED 90 E5 A5 EE 23 DC 39 EF 3A EA D8 FE 3A DA 82 06 42 BB 5A 19 28 DF 3C 11 0E D5 3A 20 EB D6 E0 2A FD E2 97 22 6B E2 64 39 51 F0 17 2E 02 19 CA 1E 4D 24 3F 18 DC 25 A0 15 24 32 DE 0B CC 31 1E F5 48 38 F8 F7 42 2A 2D E0 06 0E 87 E5 FC 0A B0 E8 93 FB B2 F3 6B E2 9F 04 2D F7 5C FC FC F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F9 D6 96 EF 36 E3 20 D7 49 F1 0B D9 B0 10 1A C7 63 1F 36 D2 B3 1B 2D D5 42 3F 4D DB 62 29 25 F8 4B 23 A5 14 68 2E 08 10 B8 2D 4C 22 DC 12 8A 3D F4 19 7D 38 BE 18 C2 17 91 05 96 44 3C 03 0A 17 9E EE 71 3D A3 F2 88 21 22 E3 D4 3B 0F D3 A0 01 2C E3 2C 35 7C E1 9F 08 8D C6 B5 0D F3 D4 96 EB 55 E1 7F FC FD E0 94 EE 

------[312] - [327] : PHY_RX_PKT_BUF_PHY_HDR
4A 1E 02 70 4F 00 0F E8 03 00 00 00 00 00 00 00 

------[328] - [427] : MAC Payload
93 40 64 74 6D 30 2B E7 2D 54 5F 8A 1D 7F B8 A7 49 20 32 BA 36 98 95 F3 16 AA 2F C5 8E 3F DC D3 24 10 19 5D 1B CC CA 79 0B D5 97 62 C7 1F EE 69 12 88 8C AE 0D 66 E5 BC 85 F6 2B 70 20 08 DE C5 9A E9 5A 32 6B 33 8F 33 7D 54 B0 ED BE 62 14 92 C1 51 D7 4B 08 05 29 F9 02 A2 1D 48 36 90 C3 DF EF 82 91 7F

We think it might have to do with our own MAC protocol that sends packets to specific times (in contrast to waiting for a free channel). We have setup the system as

Code:

// wlan_mac_low_init_dcf():
REG_SET_BITS(WLAN_MAC_REG_CONTROL, (WLAN_MAC_CTRL_MASK_RX_PHY_BLOCK_EN | WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_TX | WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_VALID_RXEND));
// own main(): after calling wlan_mac_low_init_finish()
REG_SET_BITS(WLAN_MAC_REG_CONTROL, (WLAN_MAC_CTRL_MASK_CCA_IGNORE_PHY_CS | WLAN_MAC_CTRL_MASK_CCA_IGNORE_NAV));

We are wondering what would happen if a reception just started, but the CPU has not realized this yet. In frame_transmit before triggering the transmission via tx_ctrl_A_start(1) and then (0), there is just a check for another ongoing TX

Code:

while(wlan_mac_get_status() & WLAN_MAC_STATUS_MASK_TX_PHY_ACTIVE){}

but not any for an ongoing RX?!

Last edited by Christian (2016-Feb-14 09:46:19)

Offline

 

#6 2016-Feb-16 14:40:19

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 4954

Re: 80211 Design: own MAC packets

We think it might have to do with our own MAC protocol that sends packets to specific times (in contrast to waiting for a free channel). We have setup the system as

Code:

// wlan_mac_low_init_dcf():
REG_SET_BITS(WLAN_MAC_REG_CONTROL, (WLAN_MAC_CTRL_MASK_RX_PHY_BLOCK_EN | WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_TX | WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_VALID_RXEND));
// own main(): after calling wlan_mac_low_init_finish()
REG_SET_BITS(WLAN_MAC_REG_CONTROL, (WLAN_MAC_CTRL_MASK_CCA_IGNORE_PHY_CS | WLAN_MAC_CTRL_MASK_CCA_IGNORE_NAV));

Ah, yes, this is important, and probably explains the issue you're seeing.

When the Tx PHY is active, the MAC core normally asserts the PHY_RX_BLOCK_PKTDET output. This connects to the Rx PHY's PHY_RX_BLOCK_PKTDET input. If the Rx PHY has already sent an RX_START indication to the MAC when the PHY_RX_BLOCK_PKTDET signal asserts, the Rx PHY asserts the RX_ERROR (via the "RX_ENDED_UNEXPECTEDLY" goto in 'Sync & Antenna Sel/Resets/') output. In the v1.4 PHY this RX_ERROR assertion does not assert RX_END. This leads the MAC to observe an Rx PHY event that starts but does not end.

In normal operation the Tx PHY will not start when the Rx PHY is running as the Rx PHY asserts CCA.BUSY whenever it is attempting a reception. This protection is disabled when the MAC core control bit WLAN_MAC_CTRL_MASK_CCA_IGNORE_PHY_CS is set. I would recommend leaving WLAN_MAC_CTRL_MASK_CCA_IGNORE_PHY_CS=0 (i.e. enable deferring to Rx PHY CCA.BUSY), then increasing the Rx physical carrier sensing threshold to its max (wlan_phy_rx_set_cca_thresh(0xFFFF)). The Rx PHY will then assert CCA.BUSY only when it is attempting a reception, not for RSSI>thresh.

Offline

 

#7 2016-Feb-17 09:55:38

Christian
Member
Registered: 2010-Feb-26
Posts: 124

Re: 80211 Design: own MAC packets

Hi Patrick,

yes, this seems to have fixed it. We were not aware of the integration of CCA into the logic that defers the PHY TX. Thanks!

We've put a check of mac_hw_state & (PHY_RX_ACTIVE | PHY_CCA_BUSY) before to prevent unwanted delays (by skipping TX altogether) in the while loop inside of frame_transmit (in addition to a length check in the loop itself).

Last edited by Christian (2016-Feb-17 09:57:38)

Offline

 

Board footer