Skip to content

Commit fc0a4f8

Browse files
src/cyw43_ctrl: Rework roam/interference config to use ioctl helpers
Reimplement the WiFi roaming and interference-mitigation configuration in terms of cyw43_ioctl() instead of dedicated low-level (cyw43_ll_*) functions, per maintainer feedback on PR #146. This keeps the footprint small: only the generic u32 ioctl helpers cost binary space, while the per-feature wrappers are static inline and the named-iovar helpers are the only additional functions. Add public helpers: - cyw43_ioctl_set_u32() / cyw43_ioctl_get_u32() Wrap cyw43_ioctl() for the common case of a 4-byte ioctl value. Add CYW43_IOCTL_xxx constants (encoded as (WLC_cmd << 1) | is_set, the same scheme as the existing CYW43_IOCTL_ defines): - GET/SET_ROAM_TRIGGER, GET/SET_ROAM_DELTA, GET/SET_ROAM_SCAN_PERIOD - GET/SET_INTERFERENCE_MODE Roaming/interference API (behaviour unchanged from PR #146; the bytes sent to the chip are identical, only the call path differs): - cyw43_wifi_set_roam_params() / cyw43_wifi_get_roam_params() static inline, built on the u32 ioctl helpers. - cyw43_wifi_set_interference_mode() / cyw43_wifi_get_interference_mode() static inline, built on the u32 ioctl helpers. - cyw43_wifi_set_roam_enabled() / cyw43_wifi_get_roam_enabled() Toggle/read the "roam_off" iovar via WLC_SET_VAR / WLC_GET_VAR. Remove the cyw43_ll_wifi_{set,get}_roam_* and cyw43_ll_wifi_{set,get}_interference_mode low-level functions and their WLC_* defines, which are no longer needed. function order
1 parent ece6e7b commit fc0a4f8

4 files changed

Lines changed: 144 additions & 183 deletions

File tree

src/cyw43.h

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@
107107
/*!
108108
* \name Interference mitigation mode
109109
* \anchor CYW43_IFMODE_
110-
* \see cyw43_wifi_interference_mode_set() to set the mitigation mode
111-
* \see cyw43_wifi_interference_mode_get() to get the mitigation mode
110+
* \see cyw43_wifi_set_interference_mode() to set the mitigation mode
111+
* \see cyw43_wifi_get_interference_mode() to get the mitigation mode
112112
*/
113113
//!\{
114114
#define CYW43_IFMODE_NONE (0) ///< None/Disabled
@@ -200,6 +200,34 @@ void cyw43_deinit(cyw43_t *self);
200200
*/
201201
int cyw43_ioctl(cyw43_t *self, uint32_t cmd, size_t len, uint8_t *buf, uint32_t iface);
202202

203+
/*!
204+
* \brief Set an ioctl whose value is a single unsigned 32-bit integer
205+
*
206+
* Convenience wrapper around \ref cyw43_ioctl for the common case of an ioctl
207+
* that takes a 4-byte value, e.g. the various \c CYW43_IOCTL_SET_xxx commands.
208+
*
209+
* \param self the driver state object. This should always be \c &cyw43_state
210+
* \param cmd the ioctl command to send, e.g. one of the \c CYW43_IOCTL_SET_xxx defines
211+
* \param val the value to set
212+
* \param iface the interface to use, either \ref CYW43_ITF_STA or \ref CYW43_ITF_AP
213+
* \return 0 on success, negative error code on failure
214+
*/
215+
int cyw43_ioctl_set_u32(cyw43_t *self, uint32_t cmd, uint32_t val, uint32_t iface);
216+
217+
/*!
218+
* \brief Get an ioctl whose value is a single unsigned 32-bit integer
219+
*
220+
* Convenience wrapper around \ref cyw43_ioctl for the common case of an ioctl
221+
* that returns a 4-byte value, e.g. the various \c CYW43_IOCTL_GET_xxx commands.
222+
*
223+
* \param self the driver state object. This should always be \c &cyw43_state
224+
* \param cmd the ioctl command to send, e.g. one of the \c CYW43_IOCTL_GET_xxx defines
225+
* \param out_val Output: the value that was read. May be NULL.
226+
* \param iface the interface to use, either \ref CYW43_ITF_STA or \ref CYW43_ITF_AP
227+
* \return 0 on success, negative error code on failure
228+
*/
229+
int cyw43_ioctl_get_u32(cyw43_t *self, uint32_t cmd, uint32_t *out_val, uint32_t iface);
230+
203231
/*!
204232
* \brief Send a raw ethernet packet
205233
*
@@ -228,7 +256,9 @@ int cyw43_send_ethernet(cyw43_t *self, int itf, size_t len, const void *buf, boo
228256
* \param mode Interference mitigation mode, one of \ref CYW43_IFMODE_
229257
* \return 0 on success, negative error code on failure
230258
*/
231-
int cyw43_wifi_set_interference_mode(cyw43_t *self, uint32_t mode);
259+
static inline int cyw43_wifi_set_interference_mode(cyw43_t *self, uint32_t mode) {
260+
return cyw43_ioctl_set_u32(self, CYW43_IOCTL_SET_INTERFERENCE_MODE, mode, CYW43_ITF_STA);
261+
}
232262

233263
/*!
234264
* \brief Get the current WiFi interference mitigation mode
@@ -237,7 +267,9 @@ int cyw43_wifi_set_interference_mode(cyw43_t *self, uint32_t mode);
237267
* \param mode Output: current interference mitigation mode, one of \ref CYW43_IFMODE_
238268
* \return 0 on success, negative error code on failure
239269
*/
240-
int cyw43_wifi_get_interference_mode(cyw43_t *self, uint32_t *mode);
270+
static inline int cyw43_wifi_get_interference_mode(cyw43_t *self, uint32_t *mode) {
271+
return cyw43_ioctl_get_u32(self, CYW43_IOCTL_GET_INTERFERENCE_MODE, mode, CYW43_ITF_STA);
272+
}
241273

242274
/*!
243275
* \brief Set the wifi power management mode
@@ -414,6 +446,17 @@ int cyw43_wifi_leave(cyw43_t *self, int itf);
414446
*/
415447
int cyw43_wifi_set_roam_enabled(cyw43_t *self, bool enabled);
416448

449+
/*!
450+
* \brief Query whether WiFi roaming is enabled on the STA interface
451+
*
452+
* Reads back the current state of the \c roam_off iovar.
453+
*
454+
* \param self The driver state object, always \c &cyw43_state
455+
* \param enabled Output: true if roaming is enabled, false if disabled
456+
* \return 0 on success, negative error code on failure
457+
*/
458+
int cyw43_wifi_get_roam_enabled(cyw43_t *self, bool *enabled);
459+
417460
/*!
418461
* \brief Configure WiFi roaming parameters for the STA interface
419462
*
@@ -437,7 +480,17 @@ int cyw43_wifi_set_roam_enabled(cyw43_t *self, bool enabled);
437480
* APs while below the trigger threshold.
438481
* \return 0 on success, negative error code on failure
439482
*/
440-
int cyw43_wifi_set_roam_params(cyw43_t *self, int trigger_dbm, int candidate_delta_db, int scan_period_ms);
483+
static inline int cyw43_wifi_set_roam_params(cyw43_t *self, int trigger_dbm, int candidate_delta_db, int scan_period_ms) {
484+
int ret = cyw43_ioctl_set_u32(self, CYW43_IOCTL_SET_ROAM_TRIGGER, (uint32_t)trigger_dbm, CYW43_ITF_STA);
485+
if (ret) {
486+
return ret;
487+
}
488+
ret = cyw43_ioctl_set_u32(self, CYW43_IOCTL_SET_ROAM_DELTA, (uint32_t)candidate_delta_db, CYW43_ITF_STA);
489+
if (ret) {
490+
return ret;
491+
}
492+
return cyw43_ioctl_set_u32(self, CYW43_IOCTL_SET_ROAM_SCAN_PERIOD, (uint32_t)scan_period_ms, CYW43_ITF_STA);
493+
}
441494

442495
/*!
443496
* \brief Retrieve the current WiFi roaming parameters for the STA interface
@@ -454,7 +507,32 @@ int cyw43_wifi_set_roam_params(cyw43_t *self, int trigger_dbm, int candidate_del
454507
* for better APs while below the trigger threshold.
455508
* \return 0 on success, negative error code on failure
456509
*/
457-
int cyw43_wifi_get_roam_params(cyw43_t *self, int *trigger_dbm, int *candidate_delta_db, int *scan_period_ms);
510+
static inline int cyw43_wifi_get_roam_params(cyw43_t *self, int *trigger_dbm, int *candidate_delta_db, int *scan_period_ms) {
511+
uint32_t val;
512+
int ret;
513+
if (trigger_dbm != NULL) {
514+
ret = cyw43_ioctl_get_u32(self, CYW43_IOCTL_GET_ROAM_TRIGGER, &val, CYW43_ITF_STA);
515+
if (ret) {
516+
return ret;
517+
}
518+
*trigger_dbm = (int)(int32_t)val;
519+
}
520+
if (candidate_delta_db != NULL) {
521+
ret = cyw43_ioctl_get_u32(self, CYW43_IOCTL_GET_ROAM_DELTA, &val, CYW43_ITF_STA);
522+
if (ret) {
523+
return ret;
524+
}
525+
*candidate_delta_db = (int)(int32_t)val;
526+
}
527+
if (scan_period_ms != NULL) {
528+
ret = cyw43_ioctl_get_u32(self, CYW43_IOCTL_GET_ROAM_SCAN_PERIOD, &val, CYW43_ITF_STA);
529+
if (ret) {
530+
return ret;
531+
}
532+
*scan_period_ms = (int)(int32_t)val;
533+
}
534+
return 0;
535+
}
458536

459537
/*!
460538
* \brief Get the signal strength (RSSI) of the wifi network

src/cyw43_ctrl.c

Lines changed: 52 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,22 @@ int cyw43_ioctl(cyw43_t *self, uint32_t cmd, size_t len, uint8_t *buf, uint32_t
455455
return ret;
456456
}
457457

458+
int cyw43_ioctl_set_u32(cyw43_t *self, uint32_t cmd, uint32_t val, uint32_t iface) {
459+
// The wire format is little-endian; RP2 hosts are little-endian so the
460+
// value can be passed straight through (matching cyw43_wifi_get_rssi()).
461+
uint32_t buf = val;
462+
return cyw43_ioctl(self, cmd, sizeof(buf), (uint8_t *)&buf, iface);
463+
}
464+
465+
int cyw43_ioctl_get_u32(cyw43_t *self, uint32_t cmd, uint32_t *out_val, uint32_t iface) {
466+
uint32_t buf = 0;
467+
int ret = cyw43_ioctl(self, cmd, sizeof(buf), (uint8_t *)&buf, iface);
468+
if (ret == 0 && out_val != NULL) {
469+
*out_val = buf;
470+
}
471+
return ret;
472+
}
473+
458474
int cyw43_send_ethernet(cyw43_t *self, int itf, size_t len, const void *buf, bool is_pbuf) {
459475
CYW43_THREAD_ENTER;
460476
int ret = cyw43_ensure_up(self);
@@ -491,41 +507,6 @@ static int cyw43_wifi_on(cyw43_t *self, uint32_t country) {
491507
return ret;
492508
}
493509

494-
int cyw43_wifi_set_interference_mode(cyw43_t *self, uint32_t mode)
495-
{
496-
CYW43_THREAD_ENTER;
497-
int ret = cyw43_ensure_up(self);
498-
if (ret) {
499-
CYW43_THREAD_EXIT;
500-
return ret;
501-
}
502-
503-
ret = cyw43_ll_wifi_set_interference_mode(&self->cyw43_ll, mode);
504-
505-
CYW43_THREAD_EXIT;
506-
return ret;
507-
}
508-
509-
int cyw43_wifi_get_interference_mode(cyw43_t *self, uint32_t *mode)
510-
{
511-
CYW43_THREAD_ENTER;
512-
if (!mode) {
513-
CYW43_THREAD_EXIT;
514-
return -CYW43_EINVAL;
515-
}
516-
517-
int ret = cyw43_ensure_up(self);
518-
if (ret) {
519-
CYW43_THREAD_EXIT;
520-
return ret;
521-
}
522-
523-
ret = cyw43_ll_wifi_get_interference_mode(&self->cyw43_ll, mode);
524-
525-
CYW43_THREAD_EXIT;
526-
return ret;
527-
}
528-
529510
int cyw43_wifi_pm(cyw43_t *self, uint32_t pm_in) {
530511
CYW43_THREAD_ENTER;
531512
int ret = cyw43_ensure_up(self);
@@ -703,63 +684,44 @@ int cyw43_wifi_leave(cyw43_t *self, int itf) {
703684
return cyw43_ioctl(self, CYW43_IOCTL_SET_DISASSOC, 0, NULL, itf);
704685
}
705686

706-
int cyw43_wifi_set_roam_enabled(cyw43_t *self, bool enabled)
707-
{
708-
CYW43_THREAD_ENTER;
709-
if (!CYW43_STA_IS_ACTIVE(self)) {
710-
CYW43_THREAD_EXIT;
711-
return -CYW43_EPERM;
712-
}
713-
714-
int ret = cyw43_ensure_up(self);
715-
if (ret) {
716-
CYW43_THREAD_EXIT;
717-
return ret;
718-
}
719-
720-
ret = cyw43_ll_wifi_set_roam_enabled(&self->cyw43_ll, enabled);
721-
722-
CYW43_THREAD_EXIT;
723-
return ret;
724-
}
725-
726-
int cyw43_wifi_set_roam_params(cyw43_t *self, int trigger_dbm, int candidate_delta_db, int scan_period_ms)
727-
{
728-
CYW43_THREAD_ENTER;
729-
if (!CYW43_STA_IS_ACTIVE(self)) {
730-
CYW43_THREAD_EXIT;
731-
return -CYW43_EPERM;
732-
}
733-
734-
int ret = cyw43_ensure_up(self);
735-
if (ret) {
736-
CYW43_THREAD_EXIT;
737-
return ret;
738-
}
739-
740-
ret = cyw43_ll_wifi_set_roam_params(&self->cyw43_ll, trigger_dbm, candidate_delta_db, scan_period_ms);
741-
742-
CYW43_THREAD_EXIT;
743-
return ret;
744-
}
745-
746-
int cyw43_wifi_get_roam_params(cyw43_t *self, int *trigger_dbm, int *candidate_delta_db, int *scan_period_ms)
747-
{
748-
CYW43_THREAD_ENTER;
749-
if (!CYW43_STA_IS_ACTIVE(self)) {
750-
CYW43_THREAD_EXIT;
751-
return -CYW43_EPERM;
687+
int cyw43_wifi_set_roam_enabled(cyw43_t *self, bool enabled) {
688+
// "roam_off" is a string-named iovar rather than a numbered ioctl, so it is
689+
// sent via the WLC_SET_VAR ioctl with a "<name>\0<le32 value>" payload.
690+
static const char var[] = "roam_off";
691+
const size_t name_len = sizeof(var); // includes the NUL terminator
692+
uint8_t buf[sizeof(var) + 4];
693+
memcpy(buf, var, name_len);
694+
// roam_off == 1 disables roaming, 0 enables it. Only the low byte is
695+
// significant; store little-endian byte-wise to avoid unaligned access.
696+
buf[name_len + 0] = enabled ? 0 : 1;
697+
buf[name_len + 1] = 0;
698+
buf[name_len + 2] = 0;
699+
buf[name_len + 3] = 0;
700+
return cyw43_ioctl(self, CYW43_IOCTL_SET_VAR, name_len + 4, buf, CYW43_ITF_STA);
701+
}
702+
703+
int cyw43_wifi_get_roam_enabled(cyw43_t *self, bool *enabled) {
704+
if (enabled == NULL) {
705+
return -CYW43_EINVAL;
752706
}
753-
754-
int ret = cyw43_ensure_up(self);
755-
if (ret) {
756-
CYW43_THREAD_EXIT;
757-
return ret;
707+
// Read the "roam_off" iovar back via the WLC_GET_VAR ioctl. The variable
708+
// name is written into the buffer and the firmware replaces it with the
709+
// little-endian u32 value on return (see how CYW43_IOCTL_GET_VAR is used).
710+
static const char var[] = "roam_off";
711+
const size_t name_len = sizeof(var); // includes the NUL terminator
712+
uint8_t buf[sizeof(var) + 4];
713+
memcpy(buf, var, name_len);
714+
buf[name_len + 0] = 0;
715+
buf[name_len + 1] = 0;
716+
buf[name_len + 2] = 0;
717+
buf[name_len + 3] = 0;
718+
int ret = cyw43_ioctl(self, CYW43_IOCTL_GET_VAR, name_len + 4, buf, CYW43_ITF_STA);
719+
if (ret == 0) {
720+
uint32_t roam_off = (uint32_t)buf[0] | ((uint32_t)buf[1] << 8) |
721+
((uint32_t)buf[2] << 16) | ((uint32_t)buf[3] << 24);
722+
// roam_off != 0 means roaming is disabled.
723+
*enabled = (roam_off == 0);
758724
}
759-
760-
ret = cyw43_ll_wifi_get_roam_params(&self->cyw43_ll, trigger_dbm, candidate_delta_db, scan_period_ms);
761-
762-
CYW43_THREAD_EXIT;
763725
return ret;
764726
}
765727

0 commit comments

Comments
 (0)