1d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/*
2d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * FST module implementation
3d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Copyright (c) 2014, Qualcomm Atheros, Inc.
4d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *
5d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * See README for more details.
7d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */
8d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
9d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "utils/includes.h"
10d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
11d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "utils/common.h"
12d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "utils/eloop.h"
13d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst.h"
14d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst_internal.h"
15d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst_defs.h"
16d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst_ctrl_iface.h"
17d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
18d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidtstatic int fst_global_initialized = 0;
19d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstruct dl_list fst_global_ctrls_list;
20d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
21d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
22d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_ctrl_iface_notify_peer_state_change(struct fst_iface *iface,
23d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt						    Boolean connected,
24d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt						    const u8 *peer_addr)
25d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
26d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	union fst_event_extra extra;
27d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
28d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	extra.peer_state.connected = connected;
29d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	os_strlcpy(extra.peer_state.ifname, fst_iface_get_name(iface),
30d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		   sizeof(extra.peer_state.ifname));
31d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	os_memcpy(extra.peer_state.addr, peer_addr, ETH_ALEN);
32d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
33d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	foreach_fst_ctrl_call(on_event, EVENT_PEER_STATE_CHANGED,
34d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			      iface, NULL, &extra);
35d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
36d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
37d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
38d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstruct fst_iface * fst_attach(const char *ifname, const u8 *own_addr,
39d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			      const struct fst_wpa_obj *iface_obj,
40d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			      const struct fst_iface_cfg *cfg)
41d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
42d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	struct fst_group *g;
43d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	struct fst_group *group = NULL;
44d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	struct fst_iface *iface = NULL;
45d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	Boolean new_group = FALSE;
46d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
47d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	WPA_ASSERT(ifname != NULL);
48d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	WPA_ASSERT(iface_obj != NULL);
49d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	WPA_ASSERT(cfg != NULL);
50d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
51d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	foreach_fst_group(g) {
52d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		if (os_strcmp(cfg->group_id, fst_group_get_id(g)) == 0) {
53d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			group = g;
54d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			break;
55d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		}
56d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	}
57d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
58d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (!group) {
59d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		group = fst_group_create(cfg->group_id);
60d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		if (!group) {
61d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			fst_printf(MSG_ERROR, "%s: FST group cannot be created",
62d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt				   cfg->group_id);
63d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			return NULL;
64d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		}
65d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		new_group = TRUE;
66d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	}
67d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
68d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	iface = fst_iface_create(group, ifname, own_addr, iface_obj, cfg);
69d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (!iface) {
70d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		fst_printf_group(group, MSG_ERROR, "cannot create iface for %s",
71d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt				 ifname);
72d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		if (new_group)
73d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			fst_group_delete(group);
74d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return NULL;
75d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	}
76d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
77d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_group_attach_iface(group, iface);
78d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_group_update_ie(group);
79d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
80d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	foreach_fst_ctrl_call(on_iface_added, iface);
81d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
82d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_printf_iface(iface, MSG_DEBUG,
83d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			 "iface attached to group %s (prio=%d, llt=%d)",
84d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			 cfg->group_id, cfg->priority, cfg->llt);
85d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
86d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	return iface;
87d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
88d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
89d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
90d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid fst_detach(struct fst_iface *iface)
91d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
92d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	struct fst_group *group = fst_iface_get_group(iface);
93d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
94d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_printf_iface(iface, MSG_DEBUG, "iface detached from group %s",
95d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			 fst_group_get_id(group));
96d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_session_global_on_iface_detached(iface);
97d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	foreach_fst_ctrl_call(on_iface_removed, iface);
98d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_group_detach_iface(group, iface);
99d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_iface_delete(iface);
100d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_group_update_ie(group);
101d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_group_delete_if_empty(group);
102d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
103d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
104d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
105d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint fst_global_init(void)
106d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
107d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	dl_list_init(&fst_global_groups_list);
108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	dl_list_init(&fst_global_ctrls_list);
109d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_session_global_init();
110d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt	fst_global_initialized = 1;
111d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	return 0;
112d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
113d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
114d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
115d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid fst_global_deinit(void)
116d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
117d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	struct fst_group *group;
118d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	struct fst_ctrl_handle *h;
119d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
120d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt	if (!fst_global_initialized)
121d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt		return;
122d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt
123d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_session_global_deinit();
124d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	while ((group = fst_first_group()) != NULL)
125d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		fst_group_delete(group);
126d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	while ((h = dl_list_first(&fst_global_ctrls_list,
127d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt				  struct fst_ctrl_handle,
128d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt				  global_ctrls_lentry)))
129d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		fst_global_del_ctrl(h);
130d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt	fst_global_initialized = 0;
131d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
132d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
133d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
134d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstruct fst_ctrl_handle * fst_global_add_ctrl(const struct fst_ctrl *ctrl)
135d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
136d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	struct fst_ctrl_handle *h;
137d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
138d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (!ctrl)
139d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return NULL;
140d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
141d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	h = os_zalloc(sizeof(*h));
142d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (!h)
143d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return NULL;
144d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
145d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (ctrl->init && ctrl->init()) {
146d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		os_free(h);
147d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return NULL;
148d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	}
149d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
150d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	h->ctrl = *ctrl;
151d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	dl_list_add_tail(&fst_global_ctrls_list, &h->global_ctrls_lentry);
152d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
153d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	return h;
154d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
155d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
156d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
157d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid fst_global_del_ctrl(struct fst_ctrl_handle *h)
158d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
159d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	dl_list_del(&h->global_ctrls_lentry);
160d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (h->ctrl.deinit)
161d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		h->ctrl.deinit();
162d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	os_free(h);
163d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
164d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
165d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
166d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid fst_rx_action(struct fst_iface *iface, const struct ieee80211_mgmt *mgmt,
167d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		   size_t len)
168d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
169d7ff03d48f825360eec2a371e3361306f2fd721bDmitry Shmidt	if (fst_iface_is_connected(iface, mgmt->sa, FALSE))
170d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		fst_session_on_action_rx(iface, mgmt, len);
171d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	else
172d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		wpa_printf(MSG_DEBUG,
173d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			   "FST: Ignore FST Action frame - no FST connection with "
174d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			   MACSTR, MAC2STR(mgmt->sa));
175d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
176d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
177d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
178d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid fst_notify_peer_connected(struct fst_iface *iface, const u8 *addr)
179d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
180d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (is_zero_ether_addr(addr))
181d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return;
182d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
183d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef HOSTAPD
184d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_group_update_ie(fst_iface_get_group(iface));
185d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* HOSTAPD */
186d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
187d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_printf_iface(iface, MSG_DEBUG, MACSTR " became connected",
188d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			 MAC2STR(addr));
189d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
190d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_ctrl_iface_notify_peer_state_change(iface, TRUE, addr);
191d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
192d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
193d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
194d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid fst_notify_peer_disconnected(struct fst_iface *iface, const u8 *addr)
195d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
196d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (is_zero_ether_addr(addr))
197d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return;
198d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
199d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef HOSTAPD
200d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_group_update_ie(fst_iface_get_group(iface));
201d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* HOSTAPD */
202d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
203d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_printf_iface(iface, MSG_DEBUG, MACSTR " became disconnected",
204d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt			 MAC2STR(addr));
205d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
206d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	fst_ctrl_iface_notify_peer_state_change(iface, FALSE, addr);
207d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
208d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
209d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
210d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry ShmidtBoolean fst_are_ifaces_aggregated(struct fst_iface *iface1,
211d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt				  struct fst_iface *iface2)
212d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
213d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	return fst_iface_get_group(iface1) == fst_iface_get_group(iface2);
214d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
215d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
216d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
217d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtenum mb_band_id fst_hw_mode_to_band(enum hostapd_hw_mode mode)
218d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
219d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	switch (mode) {
220d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	case HOSTAPD_MODE_IEEE80211B:
221d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	case HOSTAPD_MODE_IEEE80211G:
222d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return MB_BAND_ID_WIFI_2_4GHZ;
223d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	case HOSTAPD_MODE_IEEE80211A:
224d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return MB_BAND_ID_WIFI_5GHZ;
225d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	case HOSTAPD_MODE_IEEE80211AD:
226d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return MB_BAND_ID_WIFI_60GHZ;
227d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	default:
228d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		WPA_ASSERT(0);
229d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return MB_BAND_ID_WIFI_2_4GHZ;
230d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	}
231d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
232