break;
}
+ /* The operating channel changed when CSA finished, so need to update
+ * hw_mode for all following operations to cover the cases where the
+ * driver changed the operating band. */
+ if (finished && hostapd_csa_update_hwmode(hapd->iface))
+ return;
+
switch (hapd->iface->current_mode->mode) {
case HOSTAPD_MODE_IEEE80211A:
if (cf1 == 5935)
}
-void hostapd_determine_mode(struct hostapd_iface *iface)
+int hostapd_determine_mode(struct hostapd_iface *iface)
{
int i;
enum hostapd_hw_mode target_mode;
if (iface->current_mode ||
iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY)
- return;
+ return 0;
if (iface->freq < 4000)
target_mode = HOSTAPD_MODE_IEEE80211G;
}
}
- if (!iface->current_mode)
- wpa_printf(MSG_ERROR, "ACS: Cannot decide mode");
+ if (!iface->current_mode) {
+ wpa_printf(MSG_ERROR, "ACS/CSA: Cannot decide mode");
+ return -1;
+ }
+ return 0;
}
}
+/**
+ * hostapd_csa_update_hwmode - Update hardware mode
+ * @iface: Pointer to interface data.
+ * Returns: 0 on success, < 0 on failure
+ *
+ * Update hardware mode when the operating channel changed because of CSA.
+ */
+int hostapd_csa_update_hwmode(struct hostapd_iface *iface)
+{
+ if (!iface || !iface->conf)
+ return -1;
+
+ iface->current_mode = NULL;
+ iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211ANY;
+
+ return hostapd_determine_mode(iface);
+}
+
+
/**
* hostapd_select_hw_mode - Select the hardware mode
* @iface: Pointer to interface data.
void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
size_t num_hw_features);
int hostapd_get_hw_features(struct hostapd_iface *iface);
+int hostapd_csa_update_hwmode(struct hostapd_iface *iface);
int hostapd_acs_completed(struct hostapd_iface *iface, int err);
int hostapd_select_hw_mode(struct hostapd_iface *iface);
const char * hostapd_hw_mode_txt(int mode);
void hostapd_stop_setup_timers(struct hostapd_iface *iface);
int hostapd_hw_skip_mode(struct hostapd_iface *iface,
struct hostapd_hw_modes *mode);
-void hostapd_determine_mode(struct hostapd_iface *iface);
+int hostapd_determine_mode(struct hostapd_iface *iface);
#else /* NEED_AP_MLME */
static inline void
hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
return -1;
}
+static inline int hostapd_csa_update_hwmode(struct hostapd_iface *iface)
+{
+ return 0;
+}
+
static inline int hostapd_acs_completed(struct hostapd_iface *iface, int err)
{
return -1;
return 0;
}
-static inline void hostapd_determine_mode(struct hostapd_iface *iface)
+static inline int hostapd_determine_mode(struct hostapd_iface *iface)
{
+ return 0;
}
#endif /* NEED_AP_MLME */