Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/wifi_hal_nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -14698,6 +14698,60 @@ static int nl80211_mbssid(struct nl_msg *msg, struct wpa_driver_ap_params *param
}
#endif

int nl_set_beacon_rate_ioctl(wifi_interface_info_t *interface, wifi_vap_info_t *vap, unsigned int force_bcn_rspec)
{
struct nl_msg *msg;
struct nlattr *nlattr_vendor;
int ret = RETURN_ERR;

wifi_hal_dbg_print("%s:%d: Setting beacon rate %d for vap index %d\n", __func__, __LINE__, force_bcn_rspec, vap->vap_index);

/* Per requirement on wifi_setApBeaconRate, user shall only select on of the following
* rate as beacon rate
* "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"*/
if (force_bcn_rspec == 1 || force_bcn_rspec == 5.5 || force_bcn_rspec == 6 ||
force_bcn_rspec == 2 || force_bcn_rspec == 11 || force_bcn_rspec == 12 ||
force_bcn_rspec == 24) {
//BCM mapping
force_bcn_rspec = force_bcn_rspec*2;
wifi_hal_dbg_print("%s:%d: Mapped beacon rate %d for vap index %d\n", __func__, __LINE__, force_bcn_rspec, vap->vap_index);
} else {
wifi_hal_error_print("%s:%d: Invalid beacon rate %d\n", __func__, __LINE__, force_bcn_rspec);
return -1;
}

msg = nl80211_drv_vendor_cmd_msg(g_wifi_hal.nl80211_id, interface, 0, OUI_COMCAST, RDK_VENDOR_NL80211_SUBCMD_SET_BEACON_RATE);
if (msg == NULL) {
wifi_hal_error_print("%s:%d: Failed to create NL command\n", __func__, __LINE__);
return -1;
}

nlattr_vendor = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);

if (nla_put(msg, RDK_VENDOR_ATTR_BEACON_RATE, sizeof(force_bcn_rspec), &force_bcn_rspec) < 0) {
wifi_hal_error_print("%s:%d: Failed to set beacon rate\n", __func__, __LINE__);
nlmsg_free(msg);
return -1;
}

nla_nest_end(msg, nlattr_vendor);

wifi_hal_dbg_print("%s:%d: Disabling AP before setting beacon rate\n", __func__, __LINE__);
nl80211_enable_ap(interface, false);

ret = nl80211_send_and_recv(msg, NULL, &force_bcn_rspec, NULL, NULL);

if (ret) {
wifi_hal_error_print("%s:%d Failed to send NL message: %d (%s)\n", __func__, __LINE__, ret, strerror(-ret));
return -1;
}

wifi_hal_dbg_print("%s:%d: Enabling AP after setting beacon rate\n", __func__, __LINE__);
nl80211_enable_ap(interface, true);

return 0;
}

int wifi_drv_set_ap(void *priv, struct wpa_driver_ap_params *params)
{
#if defined(CONFIG_IEEE80211BE) && defined(CONFIG_MLO)
Expand Down Expand Up @@ -14758,6 +14812,25 @@ int wifi_drv_set_ap(void *priv, struct wpa_driver_ap_params *params)
if (params->beacon_int > 0) {
nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
}

/* Beacon frame rate can be only in BEACON_RATE_LEGACY i.e, 6Mbps to 54Mbps basic rates.
BEACON_RATE_HT/VHT/HE uses MCS set/NSS for beacon frame which are not valid for commercial gateways */
params->rate_type = BEACON_RATE_LEGACY;

/*update beacon rate params and interface struct.
NL expects beacon rate in 100kbps units*/
params->beacon_rate = convert_enum_beaconrate_to_int(vap->u.bss_info.beaconRate)*10;
interface->u.ap.hapd.iconf->beacon_rate = vap->u.bss_info.beaconRate;

if (params->beacon_rate != 0) {
ret = nl_set_beacon_rate_ioctl(interface, vap, convert_enum_beaconrate_to_int(vap->u.bss_info.beaconRate));
if (ret != 0) {
wifi_hal_error_print("%s:%d: Failed to set beacon rate %d for vap index %d\n", __func__, __LINE__, convert_enum_beaconrate_to_int(vap->u.bss_info.beaconRate), vap->vap_index);
nlmsg_free(msg);
return -1;
}
}

#if HOSTAPD_VERSION < 210
nl80211_put_beacon_rate(msg, drv->capa.flags, params);
#else
Expand Down
22 changes: 22 additions & 0 deletions src/wifi_hal_nl80211_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2553,6 +2553,28 @@ int get_wifi_op_class_info(wifi_countrycode_type_t country_code, wifi_country_ra
return RETURN_OK;
}

int convert_enum_beaconrate_to_int(wifi_bitrate_t rates)
{
switch (rates) {
case WIFI_BITRATE_1MBPS: return 1;
case WIFI_BITRATE_2MBPS: return 2;
case WIFI_BITRATE_5_5MBPS: return 5.5;
case WIFI_BITRATE_11MBPS: return 11;
case WIFI_BITRATE_6MBPS: return 6;
case WIFI_BITRATE_9MBPS: return 9;
case WIFI_BITRATE_12MBPS: return 12;
case WIFI_BITRATE_18MBPS: return 18;
case WIFI_BITRATE_24MBPS: return 24;
case WIFI_BITRATE_36MBPS: return 36;
case WIFI_BITRATE_48MBPS: return 48;
case WIFI_BITRATE_54MBPS: return 54;
default:
wifi_hal_error_print("%s:%d: failed to convert beacon rate %d to nl80211 rate\n",
__func__, __LINE__, rates);
return RETURN_ERR;
}
}

int get_op_class_from_radio_params(wifi_radio_operationParam_t *param)
{
unsigned int i, j;
Expand Down
1 change: 1 addition & 0 deletions src/wifi_hal_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,7 @@ int wifi_sta_get_seqnum(const char *ifname, void *priv, const u8 *addr, int
int wifi_commit(void *priv);
wifi_radio_info_t *get_radio_by_rdk_index(wifi_radio_index_t index);
int set_interface_properties(unsigned int phy_index, wifi_interface_info_t *interface);
int convert_enum_beaconrate_to_int(wifi_bitrate_t rates);
int get_op_class_from_radio_params(wifi_radio_operationParam_t *param);
void wifi_send_wpa_supplicant_event(int ap_index, uint8_t *frame, int len);
int wifi_send_response_failure(int ap_index, const u8 *mac, int frame_type, int status_code, int rssi);
Expand Down
Loading