WARP Project Forums - Wireless Open-Access Research Platform

You are not logged in.

#1 2016-May-16 10:31:39

Edlmann
Member
Registered: 2015-Sep-09
Posts: 30

Disabling DSSS in v 1.5.1

Hi WARP Team,

we're currently in the process of developing a TDMA-style MAC and recently ported the system over to the Reference Design 1.5.1 hoping that we could remove the workaround for the blocking RX-PHY in v 1.4.

Now in 1.5.1, we observed two behaviours we cannot quite explain:

1. Even if we configure the MAC-Core using

Code:

    REG_SET_BITS(WLAN_MAC_REG_CONTROL, (WLAN_MAC_CTRL_MASK_CCA_IGNORE_PHY_CS | WLAN_MAC_CTRL_MASK_CCA_IGNORE_NAV | WLAN_MAC_CTRL_MASK_DISABLE_NAV));

calls to wlan_mac_get_status still indicate WLAN_MAC_STATUS_MASK_CCA_BUSY unless we add

Code:

	wlan_phy_rx_set_cca_thresh(0xFFFF);

Is this behaviour intended?

2. Due to their timing behaviour, we want to fully disable DSSS receptions.

We tried doing so with two different approaches:
First, we utilized the function

Code:

wlan_mac_low_DSSS_rx_disable();

but were still seeing DSSS receptions in wlan_mac_low_poll_frame_rx, even though we are sure that the DSSS is never enabled again afterwards, and to be sure we even called

Code:

wlan_mac_low_DSSS_rx_disable();

everytime a new DSSS packet was received, to make sure it didn't get enabled again. DSSS Packets were however still received.
As a second method, we disabled it in wlan_phy_init as indicated in its comments:

Code:

void wlan_phy_init() {
  //-snip-

    // Configure the DSSS auto-correlation packet detector
    //  wlan_phy_pktDet_autoCorr_dsss_cfg(corr_thresh, energy_thresh, timeout_ones, timeout_count)
    //
    // To effectively disable DSSS detection with high thresholds, substitute with the following line:
    wlan_phy_rx_pktDet_autoCorr_dsss_cfg(0xFF, 0x3FF, 30, 40);
    //wlan_phy_rx_pktDet_autoCorr_dsss_cfg(0x60, 400, 30, 40);

  //-snip-
}

but are still seeing DSSS receptions in wlan_mac_low_poll_frame_rx. Is there anything we're missing?

Greetings

Offline

 

#2 2016-May-17 14:31:37

chunter
Administrator
From: Mango Communications
Registered: 2006-Aug-24
Posts: 1212

Re: Disabling DSSS in v 1.5.1

Regarding the DSSS behavior, I wasn't able to reproduce the issue with the v1.5.1 release. I added the following line:

Code:

xil_printf("wlan_mac_get_rx_phy_sel() = %08x\n", wlan_mac_get_rx_phy_sel());

to line 562. With no other changes to an otherwise idle AP+DCF design, there are a bunch of prints of "0x00000000" for DSSS and "0x1000000" for OFDM from surrounding Wi-Fi traffic.

Next, I added a call to wlan_mac_low_DSSS_rx_disable() at the end of wlan_mac_low_init() on line 243. After this call, I only ever see prints of "0x10000000" for OFDM.

1) Where are you calling wlan_mac_low_DSSS_rx_disable()? You mentioned that you tried calling it after every DSSS reception -- where in the code did this call take place?
2) Where in wlan_mac_low_poll_frame_rx() are you seeing a DSSS reception? Are you checking the status bit after the PHY Rx has started? (i.e. mac_hw_status & WLAN_MAC_STATUS_MASK_RX_PHY_STARTED)

Offline

 

#3 2016-May-17 15:03:35

Edlmann
Member
Registered: 2015-Sep-09
Posts: 30

Re: Disabling DSSS in v 1.5.1

chunter wrote:

1) Where are you calling wlan_mac_low_DSSS_rx_disable()? You mentioned that you tried calling it after every DSSS reception -- where in the code did this call take place?

First, we called it directly before our protocol starts its main loop (equivalent to after http://warpproject.org/trac/browser/Ref … =5490#L112 )
When we still saw DSS receptions, we added it to the if branch here to make sure it gets called + not overwritten http://warpproject.org/trac/browser/Ref … =5490#L564

chunter wrote:

2) Where in wlan_mac_low_poll_frame_rx() are you seeing a DSSS reception? Are you checking the status bit after the PHY Rx has started? (i.e. mac_hw_status & WLAN_MAC_STATUS_MASK_RX_PHY_STARTED)

We added a printout to the if branch at http://warpproject.org/trac/browser/Ref … =5490#L564 which we expected to not get triggered after disabling DSSS, but wlan_mac_get_rx_phy_sel() == WLAN_MAC_PHY_RX_PHY_HDR_PHY_SEL_DSSS still triggered.

To add a bit more background to our current setup: We're in the process of evaluating the protocol at high interference, and are running an iperf data stream over consumer wlan hardware (802.11a on 5GHz channel 3, bandwidth 40MHz with raw bitrates of up to 130Mbit/s) on the same channel as the protocol which runs at 20MHz on channel 3.

Last edited by Edlmann (2016-May-17 15:06:05)

Offline

 

#4 2016-May-17 15:30:12

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

Re: Disabling DSSS in v 1.5.1

I've been reviewing the MAC and Rx PHY logic to see how it might behave this way when the DSSS Rx pipeline is in reset; I haven't found anything.

Can you try an experiment to rule out your other design customizations? Start with the v1.5.1 design, then modify it to include a print in the WLAN_MAC_PHY_RX_PHY_HDR_PHY_SEL_DSSS clause and to set WLAN_DEFAULT_CHANNEL to your 5GHz channel. Does this design ever enter the PHY_SEL_DSSS clause? If so, try adding wlan_mac_low_DSSS_rx_disable() at the end of wlan_mac_low_init() and testing again.

Offline

 

#5 2016-May-17 16:34:47

Edlmann
Member
Registered: 2015-Sep-09
Posts: 30

Re: Disabling DSSS in v 1.5.1

After modifying the system to never transmit anything and simplyfing the main loop to

Code:

	wlan_mac_low_DSSS_rx_disable();

	while(1) {
		wlan_mac_low_poll_frame_rx();
		wlan_mac_low_poll_ipc_rx();  //We utilize custom IPC messages to reconfigure the boards at runtime (channel, modulation etc, necessitating this callback aswell)
	}

with receptions beeing only handled as outlined below, except for any further processing and a print included

Code:

    	// Check whether this is an OFDM or DSSS Rx
        if(wlan_mac_get_rx_phy_sel() == WLAN_MAC_PHY_RX_PHY_HDR_PHY_SEL_DSSS) {
        	xil_printf("DSSSRec\r\n");
            // DSSS Rx - PHY Rx length is already valid, other params unused for DSSS
            phy_details.phy_mode = PHY_MODE_DSSS;
            phy_details.N_DBPS   = 0;

            // 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      = 0;

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

        } else {

it never gets triggered. Only once transmissions are enabled the printout is triggered. It seems to be some interaction between transmissions / receptions causing this behaviour.
I'll try to compile the changes we made compared to the nomac system:

Initialization:

Code:

void wlan_phy_init() {
    // Configure the DSSS Rx pipeline
    //  wlan_phy_DSSS_rx_config(code_corr, despread_dly, sfd_timeout)
    //wlan_phy_DSSS_rx_config(0x30, 5, 140);
    wlan_phy_DSSS_rx_config(0xFFFF, 5, 1); //Original values show the same behaviour

    // Configure the DSSS auto-correlation packet detector
    //  wlan_phy_pktDet_autoCorr_dsss_cfg(corr_thresh, energy_thresh, timeout_ones, timeout_count)
    //
    // To effectively disable DSSS detection with high thresholds, substitute with the following line:
    wlan_phy_rx_pktDet_autoCorr_dsss_cfg(0xFF, 0x3FF, 30, 40);
    //wlan_phy_rx_pktDet_autoCorr_dsss_cfg(0x60, 400, 30, 40);
}

void main() {
    
	wlan_mac_low_init();
    // - snip -
	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));
    wlan_phy_rx_set_cca_thresh(0xFFFF);
    set_phy_samp_rate(PHY_20M);

    REG_SET_BITS(WLAN_MAC_REG_CONTROL, (WLAN_MAC_CTRL_MASK_DISABLE_NAV | WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_TX ));

	wlan_mac_low_DSSS_rx_disable();
    // - snip - main loop
}

Reception:

Code:

u32 frame_receive(u8 rx_pkt_buf, phy_rx_details_t* phy_details){
	rx_frame_info_t* mpdu_info;
	//u32 mac_hw_status;
	//u8 ctrl_tx_gain;
	u8* pkt_buf_addr;
	pkt_buf_addr = (void *)RX_PKT_BUF_TO_ADDR(rx_pkt_buf);

	mpdu_info = (rx_frame_info_t*)pkt_buf_addr;

	// - snip - collect metadata about reception

	if (phy_details->length < NUM_HEADER_BYTES ||
			phy_details->length > MAX_PACKET_LENGTH ||
			(phy_details->mcs != WLAN_MAC_MCS_12M) || phy_details->phy_mode == PHY_MODE_DSSS) {
                //This block was testing for clearing an rx faster, but is disabled to track down the current issue
		/*wlan_mac_hw_clear_rx_started();
		REG_SET_BITS(WLAN_MAC_REG_CONTROL, WLAN_MAC_CTRL_MASK_RESET_PHY_ACTIVE_LATCHES);
		REG_CLEAR_BITS(WLAN_MAC_REG_CONTROL, WLAN_MAC_CTRL_MASK_RESET_PHY_ACTIVE_LATCHES);*/
                //Early return for packets that cannot be from the protocol
		return -1;
	}
	mpdu_info->state = CALLBACK_ERROR;

	mpdu_info->state = wlan_mac_hw_rx_finish();

        // - snip - process received packet if mpdu_info->state == 1
}

The logic inside wlan_mac_low_poll_frame_rx is unchanged except for the added printout.

Transmission:

Code:

int frame_transmit(u8 pkt_buf, u8 mcs, u16 length) {
	//This function manages the MAC5_DCF_HW core.

	void* pkt_buf_addr = (void *)TX_PKT_BUF_TO_ADDR(pkt_buf);
	tx_frame_info_t* mpdu_info = (tx_frame_info_t*) (pkt_buf_addr);
	int curr_tx_pow;

	u32 mac_hw_status;
    u32 mac_tx_ctrl_status;
	s8 retVal = CALLBACK_ERROR;

	//Write the SIGNAL field (interpreted by the PHY during Tx waveform generation)
	write_phy_preamble(pkt_buf, PHY_MODE_NONHT, mcs, length);

	unsigned char mpdu_tx_ant_mask = 0x1;

	mpdu_info->num_tx_attempts = 1;
    // Update tx_frame_info with current PHY sampling rate
	mpdu_info->phy_samp_rate	= (u8)wlan_mac_low_get_phy_samp_rate();

	//curr_tx_pow = wlan_mac_low_dbm_to_gain_target(mpdu_info->params.phy.power);
	curr_tx_pow = wlan_mac_low_get_current_ctrl_tx_pow();

	//wlan_mac_tx_ctrl_A_params(pktBuf, antMask, preTx_backoff_slots, preWait_postRxTimer1, preWait_postTxTimer1, postWait_postTxTimer2)
	wlan_mac_tx_ctrl_A_params(pkt_buf, mpdu_tx_ant_mask, 0, 0, 0, 0, PHY_MODE_NONHT);

	//Set Tx Gains
	wlan_mac_tx_ctrl_A_gains(curr_tx_pow, curr_tx_pow, curr_tx_pow, curr_tx_pow);


	//Before we mess with any PHY state, we need to make sure it isn't actively
	if (wlan_mac_get_status() & WLAN_MAC_STATUS_MASK_TX_PHY_ACTIVE) {
		xil_printf("TX active still\r\n"); // Never occurs
		goto frame_transmit_end;
	}

	//Submit the MPDU for transmission - this starts the MAC hardware's MPDU Tx state machine
	wlan_mac_tx_ctrl_A_start(1);
	wlan_mac_tx_ctrl_A_start(0);

	// Wait for the PHY Tx to finish
	do{

		// Get the MAC HW status
		mac_hw_status = wlan_mac_get_status();
		mac_tx_ctrl_status = wlan_mac_get_tx_ctrl_status();

		// If the MAC HW is done, fill in the remaining Tx low details and return
		if (mac_tx_ctrl_status & WLAN_MAC_TXCTRL_STATUS_MASK_TX_A_DONE) {

			// Set return value based on Tx A result
			switch (mac_tx_ctrl_status & WLAN_MAC_TXCTRL_STATUS_MASK_TX_A_RESULT) {
			case WLAN_MAC_TXCTRL_STATUS_TX_A_RESULT_NONE:
			case WLAN_MAC_TXCTRL_STATUS_TX_A_RESULT_RX_STARTED:
					retVal = CALLBACK_OK;
					goto frame_transmit_end;
					break;
				default:
					retVal = CALLBACK_ERROR;
					goto frame_transmit_end;
				break;
			}
		}
	} while (mac_hw_status & WLAN_MAC_STATUS_MASK_TX_A_PENDING);

	frame_transmit_end:;
	if (retVal == CALLBACK_ERROR) {
//		wlan_mac_reset_tx_ctrl_a(1);
//		wlan_mac_reset_tx_ctrl_a(0);
	} 
	if (retVal == CALLBACK_ERROR) {
		return TX_MPDU_RESULT_FAILURE;
	} else {
		return TX_MPDU_RESULT_SUCCESS;
	}
}

Offline

 

#6 2016-May-18 21:49:53

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

Re: Disabling DSSS in v 1.5.1

Does your custom code ever start a Tx while the Rx PHY is currently receiving a frame? That's definitely a combination of states we don't use. It's possible that would expose some interaction in the Rx PHY -> MAC state. I'll dig deeper if this is a possibility in your code.

Offline

 

#7 2016-May-19 02:27:21

Edlmann
Member
Registered: 2015-Sep-09
Posts: 30

Re: Disabling DSSS in v 1.5.1

Yes, that can happen. As soon as we enter the rx-callback with a packet we can discard based on the PLCP, the frame_receive callback returns early. In this case, wlan_mac_hw_clear_rx_started(); is still beeing called however. But if the protocol is currently busy processing an event (timing based / reaction to a past reception) it might generate a new transmission, calling frame_transmit directly. We removed the check for rx-activity inside the frame_transmit callback, since we need this function be fully fire and forget, with as little delay before a transmission is started as possible. A transmission should always take precedence over a reception. Is there a better way to achieve this without unintended side effects?

Offline

 

#8 2016-May-19 09:25:36

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

Re: Disabling DSSS in v 1.5.1

I have two ideas-
-Check the 'WLAN_MAC_PHY_RX_PHY_HDR_READY' bit in the code block that detects the bogus DSSS Rx - it should be 0 for a DSSS Rx
-De-assert the 'WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_TX' option in wlan_mac_hw_init().

The wlan_mac_hw register 'PHY_RX_PARAMS' updates twice per OFDM reception- once at RX_START, again after the 9th byte (HT-SIG) is decoded. On the second update the 'WLAN_MAC_PHY_RX_PHY_HDR_READY' bit will be asserted. For DSSS receptions this register only updates at RX_START and the 'WLAN_MAC_PHY_RX_PHY_HDR_READY' bit will never be asserted (since the OFDM pipeline isn't even running). The 'PHY_RX_PARAMS' register also captures the 'PHY_SEL' bit (0=DSSS, 1=OFDM). This bit is driven by a latch that asserts on an OFDM RX_START and stays asserted until OFDM RX_END. Normally RX_END occurs when the last byte is decoded. However if a Tx starts during an Rx, the MAC core asserts the Rx PHY's RX_RESET input. This mimics an RX_END (via the 'RX_RESET_WHILE_ACTIVE' goto) and clears the PHY_SEL latch. There is a narrow window where the Rx PHY could be decoding the HT-SIG (about to assert RX_PHY_HDR_READY) when the RX_RESET occurs. This would clear the PHY_SEL latch, leading to a 'PHY_RX_PARAMS' where PHY_SEL=0 ("DSSS", but not really) and RX_PHY_HDR_READY=1 (OFDM decoded the PHY header).

Offline

 

#9 2016-May-19 16:46:35

Edlmann
Member
Registered: 2015-Sep-09
Posts: 30

Re: Disabling DSSS in v 1.5.1

The WLAN_MAC_PHY_RX_PHY_HDR_READY bit is indeed asserted for those DSSS receptions. (Full phy_hdr_params are switching between 0x9040085, 0x9000085, 0xA870085 and 0xA000085 at the beginning of the DSSS-Clause).
De-asserting WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_TX does indeed get rid of the unwanted DSSS signals.

Are there any side-effects that we would need to be aware of with this configuration? With the new config I noticed that the RX is now sometimes active directly after (or during) a transmission. Due to the TDMA nature of our MAC, this is most likely a packet received from an interfering system, and should not be further processed. How would we go about discarding these receptions directly after transmission? Utilizing wlan_mac_hw_clear_rx_started(); seems to lead to some unintended side-effects with invalid packets being marked as valid for further processing (If this is not as expected, i can try to track it down further. Just did some initial testing).

Thanks a lot already for your help murphpo + chunter

Offline

 

#10 2016-May-19 21:50:35

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

Re: Disabling DSSS in v 1.5.1

The WLAN_MAC_PHY_RX_PHY_HDR_READY bit is indeed asserted for those DSSS receptions. (Full phy_hdr_params are switching between 0x9040085, 0x9000085, 0xA870085 and 0xA000085 at the beginning of the DSSS-Clause).
De-asserting WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_TX does indeed get rid of the unwanted DSSS signals.

Great- I think that means we've narrowed down the underlying issue.

Decoding those PHY_HDR_PARAMS values (bit masks in wlan_mac_low.h):

Code:

0x09040085
Length: 0x85
MCS: 4
Unsupported: False
PHY Mode: 1 (NONHT)
Header Ready: True
PHY Sel: 0 (DSSS)

0x09000085
Length: 0x85
MCS: 0
Unsupported: False
PHY Mode: 1 (NONHT)
Header Ready: True
PHY Sel: 0 (DSSS)

0x0A870085
Length: 0x85
MCS: 7
Unsupported: True
PHY Mode: 2 (HTMF)
Header Ready: True
PHY Sel: 0 (DSSS)

0x0A000085
Length: 0x85
MCS: 0
Unsupported: False
PHY Mode: 2 (HTMF)
Header Ready: True
PHY Sel: 0 (DSSS)

Those are all consistent with OFDM receptions that were interrupted by an Rx PHY reset between RX_START and PHY_HDR_READY. The reset signal clears the latch in the "MAC I/O" block that selects between DSSS and OFDM parameters. When the PHY asserts the PHY_HDR_READY signal the multiplexed params (including length and PHY_SEL) have reverted to the DSSS defaults. These defaults (length = 133 = 0x85, PHY_SEL = DSSS = 0) are captured in the MAC core's PHY_HDR_PARAMS register, giving the bogus-looking combinations of params above.

I would suggest leaving WLAN_MAC_CTRL_MASK_BLOCK_RX_ON_TX enabled. This should simplify detecting the edge cases resulting from an Rx that is interrupted by Tx.

I think the best way to handle this edge case is to modify wlan_mac_low_poll_frame_rx() to handle this case explicitly, looking for the combination of params that indicate an early Rx PHY reset:

Code:

// Check if PHY has started a new reception
if(mac_hw_status & WLAN_MAC_STATUS_MASK_RX_PHY_STARTED) {

    // First check if Rx PHY was reset before RX_PHY_HDR_READY asserted. In this case
    //  the PHY_HDR_PARAMS cannot be trusted. The RX_STARTED latch should be cleared,
    //  allowing the Rx PHY to start over with the next reception
    if((wlan_mac_get_rx_phy_sel() == WLAN_MAC_PHY_RX_PHY_HDR_PHY_SEL_DSSS) && 
       (phy_hdr_params & WLAN_MAC_PHY_RX_PHY_HDR_READY)) {
           
        // Set no return flags (nothing was received); fall through to clear RX_STARTED
        return_status = 0;

    } else if(wlan_mac_get_rx_phy_sel() == WLAN_MAC_PHY_RX_PHY_HDR_PHY_SEL_DSSS) {
        // DSSS Rx - PHY Rx length is already valid, other params unused for DSSS
...

Offline

 

Board footer