nl80211: Add ACS support for Broadcom device
BRCM vendor command used to trigger ACS scan. After ACS finished, DHD driver will send results by event BRCM_VENDOR_EVENT_ACS. Signed-off-by: Xinrui Sun <xinrui.sun@broadcom.com>
This commit is contained in:
parent
90d3ee383f
commit
61a258e784
7 changed files with 322 additions and 0 deletions
|
@ -28,6 +28,9 @@ CONFIG_LIBNL20=y
|
|||
# QCA vendor extensions to nl80211
|
||||
CONFIG_DRIVER_NL80211_QCA=y
|
||||
|
||||
# Broadcom vendor extensions to nl80211
|
||||
#CONFIG_DRIVER_NL80211_BRCM=y
|
||||
|
||||
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
|
||||
#CONFIG_DRIVER_BSD=y
|
||||
#CFLAGS += -I/usr/local/include
|
||||
|
|
156
src/common/brcm_vendor.h
Normal file
156
src/common/brcm_vendor.h
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Broadcom Corporation OUI and vendor specific assignments
|
||||
* Copyright (c) 2020, Broadcom Corporation.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef BRCM_VENDOR_H
|
||||
#define BRCM_VENDOR_H
|
||||
|
||||
/*
|
||||
* This file is a registry of identifier assignments from the Broadcom
|
||||
* OUI 00:10:18 for purposes other than MAC address assignment. New identifiers
|
||||
* can be assigned through normal review process for changes to the upstream
|
||||
* hostap.git repository.
|
||||
*/
|
||||
|
||||
#define OUI_BRCM 0x001018
|
||||
|
||||
/**
|
||||
* enum brcm_nl80211_vendor_subcmds - BRCM nl80211 vendor command identifiers
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_UNSPEC: Reserved value 0
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_PRIV_STR: Provide vendor private cmds to send to FW.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_BCM_STR: Provide vendor cmds to BCMDHD driver.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_BCM_PSK: Used to set SAE password.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_SET_PMK: Command to check driver support
|
||||
* for DFS offloading.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_GET_FEATURES: Command to get the features
|
||||
* supported by the driver.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_SET_MAC: Set random mac address for P2P interface.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS: Set some connect parameters.
|
||||
* Used for the case that FW handle SAE.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_SET_START_AP_PARAMS: Set SoftAP paramters.
|
||||
* Used for the case that FW handle SAE.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_ACS: ACS command/event which is used to
|
||||
* invoke the ACS function in device and pass selected channels to
|
||||
* hostapd. Uses enum qca_wlan_vendor_attr_acs_offload attributes.
|
||||
*
|
||||
* @BRCM_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
|
||||
* Make sure it located at the end of the list.
|
||||
*
|
||||
*/
|
||||
enum brcm_nl80211_vendor_subcmds {
|
||||
BRCM_VENDOR_SCMD_UNSPEC = 0,
|
||||
BRCM_VENDOR_SCMD_PRIV_STR = 1,
|
||||
BRCM_VENDOR_SCMD_BCM_STR = 2,
|
||||
BRCM_VENDOR_SCMD_BCM_PSK = 3,
|
||||
BRCM_VENDOR_SCMD_SET_PMK = 4,
|
||||
BRCM_VENDOR_SCMD_GET_FEATURES = 5,
|
||||
BRCM_VENDOR_SCMD_SET_MAC = 6,
|
||||
BRCM_VENDOR_SCMD_SET_CONNECT_PARAMS = 7,
|
||||
BRCM_VENDOR_SCMD_SET_START_AP_PARAMS = 8,
|
||||
BRCM_VENDOR_SCMD_ACS = 9,
|
||||
BRCM_VENDOR_SCMD_MAX = 10
|
||||
};
|
||||
|
||||
/**
|
||||
* enum brcm_nl80211_vendor_events - BRCM nl80211 asynchoronous event identifiers
|
||||
*
|
||||
* @BRCM_VENDOR_EVENT_UNSPEC: Reserved value 0
|
||||
*
|
||||
* @BRCM_VENDOR_EVENT_PRIV_STR: String command/event
|
||||
*/
|
||||
enum brcm_nl80211_vendor_events {
|
||||
BRCM_VENDOR_EVENT_UNSPEC = 0,
|
||||
BRCM_VENDOR_EVENT_PRIV_STR = 1,
|
||||
GOOGLE_GSCAN_SIGNIFICANT_EVENT = 2,
|
||||
GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT = 3,
|
||||
GOOGLE_GSCAN_BATCH_SCAN_EVENT = 4,
|
||||
GOOGLE_SCAN_FULL_RESULTS_EVENT = 5,
|
||||
GOOGLE_RTT_COMPLETE_EVENT = 6,
|
||||
GOOGLE_SCAN_COMPLETE_EVENT = 7,
|
||||
GOOGLE_GSCAN_GEOFENCE_LOST_EVENT = 8,
|
||||
GOOGLE_SCAN_EPNO_EVENT = 9,
|
||||
GOOGLE_DEBUG_RING_EVENT = 10,
|
||||
GOOGLE_FW_DUMP_EVENT = 11,
|
||||
GOOGLE_PNO_HOTSPOT_FOUND_EVENT = 12,
|
||||
GOOGLE_RSSI_MONITOR_EVENT = 13,
|
||||
GOOGLE_MKEEP_ALIVE_EVENT = 14,
|
||||
|
||||
/*
|
||||
* BRCM specific events should be placed after
|
||||
* the Generic events so that enums don't mismatch
|
||||
* between the DHD and HAL
|
||||
*/
|
||||
GOOGLE_NAN_EVENT_ENABLED = 15,
|
||||
GOOGLE_NAN_EVENT_DISABLED = 16,
|
||||
GOOGLE_NAN_EVENT_SUBSCRIBE_MATCH = 17,
|
||||
GOOGLE_NAN_EVENT_REPLIED = 18,
|
||||
GOOGLE_NAN_EVENT_PUBLISH_TERMINATED = 19,
|
||||
GOOGLE_NAN_EVENT_SUBSCRIBE_TERMINATED = 20,
|
||||
GOOGLE_NAN_EVENT_DE_EVENT = 21,
|
||||
GOOGLE_NAN_EVENT_FOLLOWUP = 22,
|
||||
GOOGLE_NAN_EVENT_TRANSMIT_FOLLOWUP_IND = 23,
|
||||
GOOGLE_NAN_EVENT_DATA_REQUEST = 24,
|
||||
GOOGLE_NAN_EVENT_DATA_CONFIRMATION = 25,
|
||||
GOOGLE_NAN_EVENT_DATA_END = 26,
|
||||
GOOGLE_NAN_EVENT_BEACON = 27,
|
||||
GOOGLE_NAN_EVENT_SDF = 28,
|
||||
GOOGLE_NAN_EVENT_TCA = 29,
|
||||
GOOGLE_NAN_EVENT_SUBSCRIBE_UNMATCH = 30,
|
||||
GOOGLE_NAN_EVENT_UNKNOWN = 31,
|
||||
GOOGLE_ROAM_EVENT_START = 32,
|
||||
BRCM_VENDOR_EVENT_HANGED = 33,
|
||||
BRCM_VENDOR_EVENT_SAE_KEY = 34,
|
||||
BRCM_VENDOR_EVENT_BEACON_RECV = 35,
|
||||
BRCM_VENDOR_EVENT_PORT_AUTHORIZED = 36,
|
||||
GOOGLE_FILE_DUMP_EVENT = 37,
|
||||
BRCM_VENDOR_EVENT_CU = 38,
|
||||
BRCM_VENDOR_EVENT_WIPS = 39,
|
||||
NAN_ASYNC_RESPONSE_DISABLED = 40,
|
||||
BRCM_VENDOR_EVENT_RCC_INFO = 41,
|
||||
BRCM_VENDOR_EVENT_ACS = 42,
|
||||
BRCM_VENDOR_EVENT_LAST
|
||||
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BRCM_SAE
|
||||
enum wifi_sae_key_attr {
|
||||
BRCM_SAE_KEY_ATTR_BSSID,
|
||||
BRCM_SAE_KEY_ATTR_PMK,
|
||||
BRCM_SAE_KEY_ATTR_PMKID
|
||||
};
|
||||
#endif /* CONFIG_BRCM_SAE */
|
||||
|
||||
enum wl_vendor_attr_acs_offload {
|
||||
BRCM_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0,
|
||||
BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ,
|
||||
BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ,
|
||||
BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
|
||||
BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
|
||||
|
||||
BRCM_VENDOR_ATTR_ACS_HW_MODE,
|
||||
BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
|
||||
BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
|
||||
BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
|
||||
BRCM_VENDOR_ATTR_ACS_CHWIDTH,
|
||||
BRCM_VENDOR_ATTR_ACS_CH_LIST,
|
||||
BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
|
||||
|
||||
BRCM_VENDOR_ATTR_ACS_LAST
|
||||
};
|
||||
|
||||
|
||||
#endif /* BRCM_VENDOR_H */
|
|
@ -27,6 +27,7 @@
|
|||
#include "eloop.h"
|
||||
#include "common/qca-vendor.h"
|
||||
#include "common/qca-vendor-attr.h"
|
||||
#include "common/brcm_vendor.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "common/wpa_common.h"
|
||||
|
@ -11605,6 +11606,60 @@ fail:
|
|||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
|
||||
|
||||
#ifdef CONFIG_DRIVER_NL80211_BRCM
|
||||
static int wpa_driver_do_broadcom_acs(void *priv, struct drv_acs_params *params)
|
||||
{
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
struct nl_msg *msg;
|
||||
struct nlattr *data;
|
||||
int freq_list_len;
|
||||
int ret = -1;
|
||||
|
||||
freq_list_len = int_array_len(params->freq_list);
|
||||
wpa_printf(MSG_DEBUG, "%s: freq_list_len=%d",
|
||||
__func__, freq_list_len);
|
||||
|
||||
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
|
||||
if (!msg ||
|
||||
nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
|
||||
BRCM_VENDOR_SCMD_ACS) ||
|
||||
!(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
|
||||
nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HW_MODE, params->hw_mode) ||
|
||||
nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT_ENABLED,
|
||||
params->ht_enabled) ||
|
||||
nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_HT40_ENABLED,
|
||||
params->ht40_enabled) ||
|
||||
nla_put_u8(msg, BRCM_VENDOR_ATTR_ACS_VHT_ENABLED,
|
||||
params->vht_enabled) ||
|
||||
nla_put_u16(msg, BRCM_VENDOR_ATTR_ACS_CHWIDTH, params->ch_width) ||
|
||||
(freq_list_len > 0 &&
|
||||
nla_put(msg, BRCM_VENDOR_ATTR_ACS_FREQ_LIST,
|
||||
sizeof(int) * freq_list_len, params->freq_list)))
|
||||
goto fail;
|
||||
nla_nest_end(msg, data);
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: ACS Params: HW_MODE: %d HT: %d HT40: %d VHT: %d BW: %d",
|
||||
params->hw_mode, params->ht_enabled, params->ht40_enabled,
|
||||
params->vht_enabled, params->ch_width);
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
if (ret) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"nl80211: BRCM Failed to invoke driver ACS function: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
msg = NULL;
|
||||
fail:
|
||||
nlmsg_free(msg);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_DRIVER_NL80211_BRCM */
|
||||
|
||||
|
||||
static int nl80211_write_to_file(const char *name, unsigned int val)
|
||||
{
|
||||
int fd, len;
|
||||
|
@ -12050,6 +12105,9 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|||
.set_bssid_tmp_disallow = nl80211_set_bssid_tmp_disallow,
|
||||
.add_sta_node = nl80211_add_sta_node,
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
#ifdef CONFIG_DRIVER_NL80211_BRCM
|
||||
.do_acs = wpa_driver_do_broadcom_acs,
|
||||
#endif /* CONFIG_DRIVER_NL80211_BRCM */
|
||||
.configure_data_frame_filters = nl80211_configure_data_frame_filters,
|
||||
.get_ext_capab = nl80211_get_ext_capab,
|
||||
.update_connect_params = nl80211_update_connection_params,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "common/wpa_common.h"
|
||||
#include "common/qca-vendor.h"
|
||||
#include "common/qca-vendor-attr.h"
|
||||
#include "common/brcm_vendor.h"
|
||||
#include "driver_nl80211.h"
|
||||
|
||||
|
||||
|
@ -1019,6 +1020,16 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
|||
break;
|
||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||
}
|
||||
#ifdef CONFIG_DRIVER_NL80211_BRCM
|
||||
} else if (vinfo->vendor_id == OUI_BRCM) {
|
||||
switch (vinfo->subcmd) {
|
||||
case BRCM_VENDOR_SCMD_ACS:
|
||||
drv->capa.flags |=
|
||||
WPA_DRIVER_FLAGS_ACS_OFFLOAD;
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Enabled BRCM ACS");
|
||||
}
|
||||
#endif /* CONFIG_DRIVER_NL80211_BRCM */
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "utils/eloop.h"
|
||||
#include "common/qca-vendor.h"
|
||||
#include "common/qca-vendor-attr.h"
|
||||
#include "common/brcm_vendor.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "driver_nl80211.h"
|
||||
|
@ -2381,6 +2382,87 @@ static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DRIVER_NL80211_BRCM
|
||||
|
||||
static void brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
|
||||
const u8 *data, size_t len)
|
||||
{
|
||||
struct nlattr *tb[BRCM_VENDOR_ATTR_ACS_LAST + 1];
|
||||
union wpa_event_data event;
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: BRCM ACS channel selection vendor event received");
|
||||
|
||||
if (nla_parse(tb, BRCM_VENDOR_ATTR_ACS_LAST, (struct nlattr *) data,
|
||||
len, NULL) ||
|
||||
!tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ] ||
|
||||
!tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
|
||||
return;
|
||||
|
||||
os_memset(&event, 0, sizeof(event));
|
||||
if (tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ])
|
||||
event.acs_selected_channels.pri_freq =
|
||||
nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]);
|
||||
if (tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
|
||||
event.acs_selected_channels.sec_freq =
|
||||
nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]);
|
||||
if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
|
||||
event.acs_selected_channels.vht_seg0_center_ch =
|
||||
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
|
||||
if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
|
||||
event.acs_selected_channels.vht_seg1_center_ch =
|
||||
nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
|
||||
if (tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH])
|
||||
event.acs_selected_channels.ch_width =
|
||||
nla_get_u16(tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]);
|
||||
if (tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]) {
|
||||
event.acs_selected_channels.hw_mode = nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]);
|
||||
if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
|
||||
event.acs_selected_channels.hw_mode ==
|
||||
HOSTAPD_MODE_IEEE80211ANY) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Invalid hw_mode %d in ACS selection event",
|
||||
event.acs_selected_channels.hw_mode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
|
||||
event.acs_selected_channels.pri_freq,
|
||||
event.acs_selected_channels.sec_freq,
|
||||
event.acs_selected_channels.ch_width,
|
||||
event.acs_selected_channels.vht_seg0_center_ch,
|
||||
event.acs_selected_channels.vht_seg1_center_ch,
|
||||
event.acs_selected_channels.hw_mode);
|
||||
wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
|
||||
}
|
||||
|
||||
|
||||
static void nl80211_vendor_event_brcm(struct wpa_driver_nl80211_data *drv,
|
||||
u32 subcmd, u8 *data, size_t len)
|
||||
{
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Got BRCM vendor event %u", subcmd);
|
||||
switch (subcmd) {
|
||||
case BRCM_VENDOR_EVENT_PRIV_STR:
|
||||
case BRCM_VENDOR_EVENT_HANGED:
|
||||
/* Dump the event on to the console */
|
||||
wpa_msg(NULL, MSG_INFO, "%s", data);
|
||||
break;
|
||||
case BRCM_VENDOR_EVENT_ACS:
|
||||
brcm_nl80211_acs_select_ch(drv, data, len);
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"%s: Ignore unsupported BRCM vendor event %u",
|
||||
__func__, subcmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DRIVER_NL80211_BRCM */
|
||||
|
||||
|
||||
static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
|
@ -2425,6 +2507,11 @@ static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
|
|||
case OUI_QCA:
|
||||
nl80211_vendor_event_qca(drv, subcmd, data, len);
|
||||
break;
|
||||
#ifdef CONFIG_DRIVER_NL80211_BRCM
|
||||
case OUI_BRCM:
|
||||
nl80211_vendor_event_brcm(drv, subcmd, data, len);
|
||||
break;
|
||||
#endif /* CONFIG_DRIVER_NL80211_BRCM */
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
|
||||
break;
|
||||
|
|
|
@ -26,6 +26,10 @@ NEED_LIBNL=y
|
|||
CONFIG_LIBNL3_ROUTE=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_NL80211_BRCM
|
||||
DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_MACSEC_QCA
|
||||
DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_QCA
|
||||
DRV_OBJS += ../src/drivers/driver_macsec_qca.o
|
||||
|
|
|
@ -41,6 +41,9 @@ DRV_OBJS += src/drivers/driver_nl80211_scan.c
|
|||
ifdef CONFIG_DRIVER_NL80211_QCA
|
||||
DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_QCA
|
||||
endif
|
||||
ifdef CONFIG_DRIVER_NL80211_BRCM
|
||||
DRV_CFLAGS += -DCONFIG_DRIVER_NL80211_BRCM
|
||||
endif
|
||||
NEED_SME=y
|
||||
NEED_AP_MLME=y
|
||||
NEED_NETLINK=y
|
||||
|
|
Loading…
Reference in a new issue