nRF7002 Linux driver with softap support

I'm developing a linux device driver for nrf7002 and adding softap support. From the Nordic Playground driver it looks like there is no current support, but a lot of the cfg80211 api functions are set up to support it. I'm adding in the nrf70 api functions to start the ap, change the beacon, etc. but I'm having issues authenticating. I'm very confident that the issue is what I'm sending the nrf70, but I'm not sure what a valid configuration/steps are.

From looking through zephyr, it seems I need to init the ap, register mgmt frames, then start the ap. I've tried this, and while the AP does appear, when I try authenticating (as open authentication) it attempts to authenticate but never succeeds. Debug messages indicate that when I'm attempting to authenticate nothing is happening outside of beacon broadcasts. The broadcasts are occurring every 100ms, which I'm not sure if that would cause issues or not.

Again, not sure what I'm failing to send down to the nrf7002, but it seems to be ignoring authentication. Any guidance on what I might be missing is appreciated.

Parents
  • Hi,

    This request seems to be relative vague and general since it is so large, but I do understand the need for making such a request. I know this is not quite what you were hoping for with this query, but I would recommend to have a thorough look through the following resources to see if you're able to get a good enough overview to narrow down the request somewhat

    1. https://academy.nordicsemi.com/courses/wi-fi-fundamentals/
    2. https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/wifi/index.html 
    3. https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/drivers/wifi/nrf700x/nrf700x.html#driver_to_nrf70_series_device_communication

    Please let me know if you're able to do so

    Kind regards,
    Andreas

  • Thank you for the information. I went through the provided materials and while my question wasn't answered, I was able to make some progress on my own and have a more pointed question.

    My linux driver with softap capability is able to broadcast, and now when connecting to it with my laptop I'm able to go through an Authentication step. When the laptop is trying to associate with the softap, it doesn't seem to get the event. 

    This is a wireshark capture of the attempt

    This is the debug output.

    [17207.434883] calling  init_module+0x0/0x1000 [nrf7002_wmac] @ 22565
    [17207.441476] initcall init_module+0x0/0x1000 [nrf7002_wmac] returned 0 after 113 usecs
    [17207.607664] Firmware (v1.2.10.0) booted successfully
    [17207.778793] nrf_wifi_netdev_open: open
    [17207.801041] nrf_wifi_netdev_if_state_chg_callbk_fn: state chg carr=0
    [17209.036108] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.042454] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.048805] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.055257] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.061615] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.068032] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.074420] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.080829] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.087215] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.093644] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.100114] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.106599] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.113153] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.119675] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.126116] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.132566] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.139114] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.145603] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.152039] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.158438] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.165022] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17209.171519] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17220.543392] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17220.549669] nrf_wifi_cfg80211_chg_vif: Changing to 3
    [17220.554751] nrf_wifi_cfg80211_chg_vif: Changing to ap
    [17220.559910] nrf_wifi_fmac_chg_vif: sending command
    [17220.561457] nrf_wifi_set_if_callbk_fn: Received -16 status
    [17221.211542] nrf_wifi_netdev_close: Closed
    [17221.222671] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.228939] nrf_wifi_cfg80211_chg_vif: Changing to 3
    [17221.234089] nrf_wifi_cfg80211_chg_vif: Changing to ap
    [17221.239327] nrf_wifi_fmac_chg_vif: sending command
    [17221.241115] nrf_wifi_set_if_callbk_fn: Received 0 status
    [17221.447762] nrf_wifi_netdev_open: open
    [17221.466153] nrf_wifi_netdev_if_state_chg_callbk_fn: state chg carr=0
    [17221.839481] nrf_wifi_netdev_open: ap mode
    [17221.845722] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.852199] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.858650] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.865032] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.871480] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.877988] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.885223] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.892442] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.899697] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.906812] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.914234] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.921497] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.928690] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.935919] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.942934] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.950069] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.957285] nrf_wifi_cfg80211_mgmt_frame_reg: Updating framge reg
    [17221.966593] nrf_wifi_cfg80211_del_sta: deleting
    [17221.973166] nrf_wifi_cfg80211_mgmt_tx: mgmt tx
    [17221.977722] nrf_wifi_cfg80211_mgmt_tx: Sending frame to RPU: cookie=1 wait_time=0 no_ack=0 flags=00 params=0
    [17221.980197] nrf_wifi_cookie_rsp_callbk_fn: cookie
    [17221.994927] nrf_wifi_cfg80211_mgmt_tx: Finished
    [17222.228141] nrf_wifi_cfg80211_start_ap: beacon int=100
    [17222.228185] nrf_wifi_cfg80211_start_ap: Starting
    [17222.249460] nrf_wifi_netdev_if_state_chg_callbk_fn: state chg carr=1
    [17222.256456] nrf_wifi_cfg80211_chg_bss: changing
    [17222.262356] IPv6: ADDRCONF(NETDEV_CHANGE): nrf_wifi: link becomes ready
    [17243.026079] nrf_wifi_cfg80211_mgmt_rx_callbk_fn: mgmt rx callback
    [17243.032906] nrf_wifi_cfg80211_mgmt_tx: mgmt tx
    [17243.037495] nrf_wifi_cfg80211_mgmt_tx: Sending frame to RPU: cookie=2 wait_time=0 no_ack=0 flags=00 params=0
    [17243.040176] nrf_wifi_cookie_rsp_callbk_fn: cookie
    [17243.056524] nrf_wifi_cfg80211_tx_status_callbk_fn: tx status
    [17243.062279] nrf_wifi_cfg80211_tx_status_callbk_fn: found cookie = 2
    [17243.063517] nrf_wifi_cfg80211_mgmt_tx: Finished
    [17244.088978] nrf_wifi_cfg80211_mgmt_rx_callbk_fn: mgmt rx callback
    [17244.095820] nrf_wifi_cfg80211_mgmt_tx: mgmt tx
    [17244.100397] nrf_wifi_cfg80211_mgmt_tx: Sending frame to RPU: cookie=3 wait_time=0 no_ack=0 flags=00 params=0
    [17244.102967] nrf_wifi_cookie_rsp_callbk_fn: cookie
    [17244.119767] nrf_wifi_cfg80211_tx_status_callbk_fn: tx status
    [17244.123541] nrf_wifi_cfg80211_mgmt_tx: Finished
    [17244.125515] nrf_wifi_cfg80211_tx_status_callbk_fn: found cookie = 3
    [17245.150160] nrf_wifi_cfg80211_mgmt_rx_callbk_fn: mgmt rx callback
    [17245.156917] nrf_wifi_cfg80211_mgmt_tx: mgmt tx
    [17245.161510] nrf_wifi_cfg80211_mgmt_tx: Sending frame to RPU: cookie=4 wait_time=0 no_ack=0 flags=00 params=0
    [17245.164166] nrf_wifi_cookie_rsp_callbk_fn: cookie
    [17245.180524] nrf_wifi_cfg80211_tx_status_callbk_fn: tx status
    [17245.183567] nrf_wifi_cfg80211_mgmt_tx: Finished
    [17245.186275] nrf_wifi_cfg80211_tx_status_callbk_fn: found cookie = 4

    I'm not sure why the association is not being replied to. I don't know if there's something I'm not sending to the nrf, but if it should work then it may be a linux issue.

  • Glad to hear that you had some progress.

    I've started a discussion with my colleagues regarding some input to this issue. It may take some time, but I will get back to you when I have some input for you (atleast you'll get a status within the upcoming week)

    In the meanwhile let me know if you're able to progress further

    Kind regards,
    Andreas

  • Thanks for looking into it but I've figured out the issue.

    The issue may only affect the version of linux I'm working on (5.13), but the root cause was the frame types were not being setup correctly. Instead of updating each new frame type, it was skipping the majority of them due to an incorrect match condition. This was due to a misunderstanding that `struct mgmt_frame_regs.interface_stypes` were frame types, but they were actually flags.

    The following is the updated function (excuse the excessive debug):

    void nrf_wifi_cfg80211_mgmt_frame_reg(struct wiphy *wiphy,
    				      struct wireless_dev *wdev,
    				      struct mgmt_frame_regs *upd)
    {
    	struct nrf_wifi_ctx_lnx *rpu_ctx_lnx = NULL;
    	struct nrf_wifi_fmac_vif_ctx_lnx *vif_ctx_lnx = NULL;
    	struct nrf_wifi_umac_mgmt_frame_info *frame_info = NULL;
    	struct nrf_wifi_cfg80211_mgmt_registration *reg = NULL;
    	bool frame_type_match = false;
    	static u16 last_upd = 0;
    	int status = -1;
    
    	pr_info("%s: Updating frame reg=%04x global=%04x\n", __func__, upd->interface_stypes, upd->global_stypes);
    
    	vif_ctx_lnx = netdev_priv(wdev->netdev);
    	rpu_ctx_lnx = vif_ctx_lnx->rpu_ctx;
    
    	frame_info = kzalloc(sizeof(*frame_info), GFP_KERNEL);
    
    	if (!frame_info) {
    		pr_err("%s: Unable to allocate memory\n", __func__);
    		goto out;
    	}
    
    	if (last_upd == upd->interface_stypes) {
    		pr_err("%s: no update\n", __func__);
    		goto out;
    	}
    	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
    		pr_info("%s: reg type=%04x", __func__, le16_to_cpu(reg->frame_type));
    		if ((last_upd ^ upd->interface_stypes) != BIT(le16_to_cpu(reg->frame_type) >> 4))
    			continue;
    		frame_type_match = true;
    
    		break;
    	}
    
    	if (!frame_type_match ) {
    		pr_err("%s: frametype not match %04x", __func__, le16_to_cpu(reg->frame_type));
    		goto out;
    	}
    	frame_info->frame_type = le16_to_cpu(reg->frame_type);
    	pr_info("%s: frametype=%04x len=%d", __func__, frame_info->frame_type, reg->match_len);
    	frame_info->frame_match.frame_match_len = reg->match_len;
    	if (reg->match_len >= NRF_WIFI_FRAME_MATCH_MAX_LEN) {
    		pr_err("%s: match_len too big: %d (max %d)", __func__, reg->match_len, NRF_WIFI_FRAME_MATCH_MAX_LEN);
    		goto out;
    	}
    	memcpy(frame_info->frame_match.frame_match, reg->match, reg->match_len);
    
    	status = nrf_wifi_fmac_mgmt_frame_reg(rpu_ctx_lnx->rpu_ctx,
    										vif_ctx_lnx->if_idx,
    										frame_info);
    	if (status != NRF_WIFI_STATUS_SUCCESS) {
    		pr_err("%s: nrf_wifi_fmac_mgmt_frame_reg failed", __func__);
    		goto out;
    	}
    
    out:
    	if (frame_info)
    		kfree(frame_info);
    	last_upd = upd->interface_stypes;
    
    	return;
    }

    For some reason type 0xd0 was able to go through correctly, which is why authentication worked, but any other frame type (0x0000 is association request) would fail. The updated function allows open authentication to work successfully, while more work is needed to add security.

Reply
  • Thanks for looking into it but I've figured out the issue.

    The issue may only affect the version of linux I'm working on (5.13), but the root cause was the frame types were not being setup correctly. Instead of updating each new frame type, it was skipping the majority of them due to an incorrect match condition. This was due to a misunderstanding that `struct mgmt_frame_regs.interface_stypes` were frame types, but they were actually flags.

    The following is the updated function (excuse the excessive debug):

    void nrf_wifi_cfg80211_mgmt_frame_reg(struct wiphy *wiphy,
    				      struct wireless_dev *wdev,
    				      struct mgmt_frame_regs *upd)
    {
    	struct nrf_wifi_ctx_lnx *rpu_ctx_lnx = NULL;
    	struct nrf_wifi_fmac_vif_ctx_lnx *vif_ctx_lnx = NULL;
    	struct nrf_wifi_umac_mgmt_frame_info *frame_info = NULL;
    	struct nrf_wifi_cfg80211_mgmt_registration *reg = NULL;
    	bool frame_type_match = false;
    	static u16 last_upd = 0;
    	int status = -1;
    
    	pr_info("%s: Updating frame reg=%04x global=%04x\n", __func__, upd->interface_stypes, upd->global_stypes);
    
    	vif_ctx_lnx = netdev_priv(wdev->netdev);
    	rpu_ctx_lnx = vif_ctx_lnx->rpu_ctx;
    
    	frame_info = kzalloc(sizeof(*frame_info), GFP_KERNEL);
    
    	if (!frame_info) {
    		pr_err("%s: Unable to allocate memory\n", __func__);
    		goto out;
    	}
    
    	if (last_upd == upd->interface_stypes) {
    		pr_err("%s: no update\n", __func__);
    		goto out;
    	}
    	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
    		pr_info("%s: reg type=%04x", __func__, le16_to_cpu(reg->frame_type));
    		if ((last_upd ^ upd->interface_stypes) != BIT(le16_to_cpu(reg->frame_type) >> 4))
    			continue;
    		frame_type_match = true;
    
    		break;
    	}
    
    	if (!frame_type_match ) {
    		pr_err("%s: frametype not match %04x", __func__, le16_to_cpu(reg->frame_type));
    		goto out;
    	}
    	frame_info->frame_type = le16_to_cpu(reg->frame_type);
    	pr_info("%s: frametype=%04x len=%d", __func__, frame_info->frame_type, reg->match_len);
    	frame_info->frame_match.frame_match_len = reg->match_len;
    	if (reg->match_len >= NRF_WIFI_FRAME_MATCH_MAX_LEN) {
    		pr_err("%s: match_len too big: %d (max %d)", __func__, reg->match_len, NRF_WIFI_FRAME_MATCH_MAX_LEN);
    		goto out;
    	}
    	memcpy(frame_info->frame_match.frame_match, reg->match, reg->match_len);
    
    	status = nrf_wifi_fmac_mgmt_frame_reg(rpu_ctx_lnx->rpu_ctx,
    										vif_ctx_lnx->if_idx,
    										frame_info);
    	if (status != NRF_WIFI_STATUS_SUCCESS) {
    		pr_err("%s: nrf_wifi_fmac_mgmt_frame_reg failed", __func__);
    		goto out;
    	}
    
    out:
    	if (frame_info)
    		kfree(frame_info);
    	last_upd = upd->interface_stypes;
    
    	return;
    }

    For some reason type 0xd0 was able to go through correctly, which is why authentication worked, but any other frame type (0x0000 is association request) would fail. The updated function allows open authentication to work successfully, while more work is needed to add security.

Children
No Data
Related