Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ network tools::
Use ``ifup wlan0``, not ``ifconfig wlan0 up``: ``ifconfig`` interprets its
second argument as an IP address.

.. note::
The station is WPA2-only. A WPA3-transition network (WPA2/WPA3 mixed
mode) associates through WPA2-PSK; a WPA3(SAE)-only network is refused
up front with ``ENOTSUP`` and a console message naming the unsupported
AKM, instead of letting the prebuilt supplicant attempt the SAE
handshake (which faults).

The RTC and the SNTP client are enabled, so the clock can be set from the
network::

Expand Down Expand Up @@ -296,9 +303,10 @@ ble
``wapi`` plus BLE (``CONFIG_GD32VW55X_BLE``) and the demo GATT service
(``CONFIG_GD32VW55X_BLE_GATT_DEMO``). The board advertises a connectable set
named ``NuttX`` and registers a minimal "transparent UART" service (16-bit
UUIDs ``0xffe0`` / RX ``0xffe1`` / TX ``0xffe2``). A central connects,
discovers the service, and a write to the RX characteristic is logged on the
board console::
UUIDs ``0xffe0`` / RX ``0xffe1`` / TX ``0xffe2``). Advertising restarts on
every disconnection, so the device stays discoverable across connections. A
central connects, discovers the service, and a write to the RX characteristic
is logged on the board console::

nsh> BLE RX (11): Hello world

Expand Down
32 changes: 32 additions & 0 deletions arch/risc-v/src/gd32vw55x/gdble/gd32_ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "ble_gap.h"
#include "ble_adapter.h"
#include "ble_adv.h"
#include "ble_conn.h"
#include "wrapper_os.h"
#include "gd32vw55x_platform.h"

Expand Down Expand Up @@ -217,6 +218,8 @@ static void gd32_ble_adv_start(uint8_t adv_idx)
*
****************************************************************************/

static uint8_t g_adv_idx = 0xff; /* 0xff = no advertising set yet */

static void gd32_ble_adv_evt_handler(ble_adv_evt_t adv_evt, void *p_data,
void *p_context)
{
Expand All @@ -231,6 +234,7 @@ static void gd32_ble_adv_evt_handler(ble_adv_evt_t adv_evt, void *p_data,

if (chg->state == BLE_ADV_STATE_CREATE)
{
g_adv_idx = chg->adv_idx;
gd32_ble_adv_start(chg->adv_idx);
}
else if (chg->state == BLE_ADV_STATE_START)
Expand All @@ -239,6 +243,30 @@ static void gd32_ble_adv_evt_handler(ble_adv_evt_t adv_evt, void *p_data,
}
}

/****************************************************************************
* Name: gd32_ble_conn_evt_handler
*
* Description:
* A connection stops the legacy advertising set and the stack leaves it
* stopped, so after the first central connects (or aborts the attempt)
* the device would never be discoverable again until a reset. Restart
* the set on every disconnection.
*
****************************************************************************/

static void gd32_ble_conn_evt_handler(ble_conn_evt_t event,
ble_conn_data_u *p_data)
{
if (event == BLE_CONN_EVT_STATE_CHG &&
p_data->conn_state.state == BLE_CONN_STATE_DISCONNECTD &&
g_adv_idx != 0xff)
{
wlinfo("BLE disconnected (reason 0x%x), restarting advertising\n",
p_data->conn_state.info.discon_info.reason);
ble_adv_restart(g_adv_idx);
}
}

/****************************************************************************
* Name: gd32_ble_adv_create
*
Expand Down Expand Up @@ -483,6 +511,10 @@ int gd32_ble_initialize(void)

ble_adp_callback_register(gd32_ble_adp_evt_handler);

/* Restart advertising when a central disconnects */

ble_conn_callback_register(gd32_ble_conn_evt_handler);

#ifdef CONFIG_GD32VW55X_BLE_GATT_DEMO
/* Register the demo GATT service (RX write / TX notify) */

Expand Down
8 changes: 8 additions & 0 deletions arch/risc-v/src/gd32vw55x/gdwifi/Wireless.mk
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@
# not use: WPA comes from the lightweight libwpas.a, via wifi_wpa.c.
CFLAGS += -DCFG_RTOS -DEXEC_USING_STD_PRINTF -DGDWIFI_NUTTX

# The vendor SDK sources are not NuttX-warning-clean (undefined macros in
# #if, %d for uint32_t, shadowed locals, K&R prototypes, ...). These
# suppressions are scoped to this chip's build; the macro redefinitions
# that no -Wno flag covers are fixed in the SDK patch instead
# (riscv_encoding.h, wifi_management.h).
CFLAGS += -Wno-undef -Wno-format -Wno-shadow -Wno-address
CFLAGS += -Wno-unused-function -Wno-strict-prototypes -Wno-array-parameter

# Include paths: our patched config dir must come first

INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)gd32vw55x$(DELIM)gdwifi$(DELIM)config
Expand Down
13 changes: 13 additions & 0 deletions arch/risc-v/src/gd32vw55x/gdwifi/config/build_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@

#include_next "build_config.h"

/* The port is WPA2-only: the SAE (WPA3) handshake faults inside the
* prebuilt supplicant (load access fault in the elliptic-curve math).
* Undefining CONFIG_WPA3_SAE activates the vendor's own fallback in
* wifi_netlink.c: the SAE/OWE AKMs are stripped from the connection
* config and the SAE auth algorithm is never selected, so a
* WPA3-transition AP associates through WPA2-PSK and an SAE-only AP is
* rejected by the AP instead of crashing the supplicant. (The glue also
* refuses SAE-only networks up front with a clear error -- see
* gdwifi_netdev.c.)
*/

#undef CONFIG_WPA3_SAE

#ifndef __LITTLE_ENDIAN
#define __LITTLE_ENDIAN 1234
#endif
Expand Down
76 changes: 75 additions & 1 deletion arch/risc-v/src/gd32vw55x/gdwifi/gdwifi_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include <stddef.h>
#include <net/if_arp.h>
#include <debug.h>
#include <syslog.h>
#include <netinet/in.h>

#include <nuttx/kmalloc.h>
Expand Down Expand Up @@ -528,7 +529,6 @@ static int gdwifi_ifdown(struct netdev_lowerhalf_s *dev)

static int gdwifi_transmit(struct netdev_lowerhalf_s *dev, netpkt_t *pkt)
{
struct gdwifi_dev_s *priv = (struct gdwifi_dev_s *)dev;
unsigned int len = netpkt_getdatalen(dev, pkt);
struct pbuf *p;

Expand Down Expand Up @@ -599,6 +599,74 @@ static int g_mode = IW_MODE_INFRA; /* INFRA = station, MASTER = softAP */
#define GDWIFI_AUTH_WPA2 3 /* AUTH_MODE_WPA2 (SAE/WPA3 no AP estoura o crypto) */
#define GDWIFI_AP_CHANNEL 11

/****************************************************************************
* Name: gdwifi_target_supported
*
* Description:
* The port is WPA2-only (the SAE handshake faults inside the prebuilt
* supplicant), so refuse a network that offers no AKM we can complete --
* WPA3(SAE)-only being the common case -- with a clear error instead of
* letting the association fail obscurely. A targeted blocking scan
* fetches the AKM bitmap of the AP; if the network cannot be found the
* decision is left to the vendor connect path (same behavior as today).
*
****************************************************************************/

static int gdwifi_target_supported(void)
{
struct macif_scan_results *results;
size_t ssid_len = strlen(g_essid);
uint32_t supported = CO_BIT(MAC_AKM_NONE) | CO_BIT(MAC_AKM_PRE_RSN) |
CO_BIT(MAC_AKM_PSK) | CO_BIT(MAC_AKM_PSK_SHA256);
int ret = OK;
uint32_t i;

if (wifi_management_scan(1, g_essid) != 0)
{
return OK;
}

results = sys_malloc(sizeof(*results));
if (results == NULL)
{
return -ENOMEM;
}

if (wifi_netlink_scan_results_get(GDWIFI_VIF_STA, results) != 0)
{
sys_mfree(results);
return OK;
}

for (i = 0; i < results->result_cnt; i++)
{
struct mac_scan_result *ap = &results->result[i];

if (!ap->valid_flag || ap->ssid.length != ssid_len ||
memcmp(ap->ssid.array, g_essid, ssid_len) != 0)
{
continue;
}

if ((ap->akm & supported) == 0)
{
/* syslog, not nerr: the rejection must be visible in release
* configs too, or the refused connect looks like a silent no-op.
*/

syslog(LOG_ERR, "gdwifi: '%s' offers no supported AKM (bitmap "
"0x%lx): WPA3/SAE, OWE and 802.1X are not supported, "
"WPA2-PSK only\n", g_essid, (unsigned long)ap->akm);
ret = -ENOTSUP;
}

break;
}

sys_mfree(results);
return ret;
}

static int gdwifi_connect(struct netdev_lowerhalf_s *dev)
{
int ret;
Expand All @@ -623,6 +691,12 @@ static int gdwifi_connect(struct netdev_lowerhalf_s *dev)
return ret == 0 ? OK : -EAGAIN;
}

ret = gdwifi_target_supported();
if (ret < 0)
{
return ret;
}

ninfo("connect '%s'\n", g_essid);
ret = wifi_management_connect(g_essid,
g_passwd[0] ? g_passwd : NULL, 1);
Expand Down
68 changes: 68 additions & 0 deletions arch/risc-v/src/gd32vw55x/gdwifi/patches/0001-nuttx-port.patch
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
diff --git a/MSDK/plf/riscv/NMSIS/Core/Include/riscv_encoding.h b/MSDK/plf/riscv/NMSIS/Core/Include/riscv_encoding.h
index 8b87225..51cb931 100644
--- a/MSDK/plf/riscv/NMSIS/Core/Include/riscv_encoding.h
+++ b/MSDK/plf/riscv/NMSIS/Core/Include/riscv_encoding.h
@@ -31,6 +31,45 @@
* The following macros are used for CSR encodings
* @{
*/
+/* NuttX port: the NuttX <arch/csr.h> (pulled in through <nuttx/irq.h>)
+ * already defines several of these names with its own encodings; undefine
+ * them so this header provides the NMSIS values to the SDK sources without
+ * macro redefinition warnings.
+ */
+
+#undef CSR_FCSR
+#undef CSR_FFLAGS
+#undef CSR_FRM
+#undef CSR_MINTSTATUS
+#undef CSR_USTATUS
+#undef MIE_MEIE
+#undef MIE_MSIE
+#undef MIE_MTIE
+#undef MIE_SEIE
+#undef MIE_SSIE
+#undef MIE_STIE
+#undef MIP_MEIP
+#undef MIP_MSIP
+#undef MIP_MTIP
+#undef MIP_SEIP
+#undef MIP_SSIP
+#undef MIP_STIP
+#undef MSTATUS_FS
+#undef MSTATUS_FS_CLEAN
+#undef MSTATUS_FS_DIRTY
+#undef MSTATUS_MIE
+#undef MSTATUS_MPIE
+#undef MSTATUS_MPRV
+#undef MSTATUS_MXR
+#undef MSTATUS_SIE
+#undef MSTATUS_SPIE
+#undef MSTATUS_UIE
+#undef MSTATUS_XS
+#undef SSTATUS_FS
+#undef SSTATUS_SIE
+#undef SSTATUS_SPIE
+#undef SSTATUS_XS
+
/* === Standard CSR bit mask === */
#define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002
diff --git a/MSDK/plf/riscv/gd32vw55x/gd32vw55x.h b/MSDK/plf/riscv/gd32vw55x/gd32vw55x.h
index f4e200e..c9189ca 100644
--- a/MSDK/plf/riscv/gd32vw55x/gd32vw55x.h
Expand Down Expand Up @@ -37,6 +87,24 @@ index e7f393f..8731cb8 100644

/* 2. wifi power on */
wifi_exist_flag = 1;
diff --git a/MSDK/wifi_manager/wifi_management.h b/MSDK/wifi_manager/wifi_management.h
index 3a108f9..3923f02 100644
--- a/MSDK/wifi_manager/wifi_management.h
+++ b/MSDK/wifi_manager/wifi_management.h
@@ -94,6 +94,13 @@ extern "C" {
#define wifi_sm_printf(...)
#endif

+/* NuttX port: <nuttx/compiler.h> also defines COMPILE_TIME_ASSERT; use the
+ * SDK's own definition here without redefining the other one.
+ */
+#ifdef COMPILE_TIME_ASSERT
+#undef COMPILE_TIME_ASSERT
+#endif
+
#define COMPILE_TIME_ASSERT(constant_expr) \
do { \
switch(0) { \
diff --git a/MSDK/wifi_manager/wifi_netlink.c b/MSDK/wifi_manager/wifi_netlink.c
index aec26cc..445c109 100644
--- a/MSDK/wifi_manager/wifi_netlink.c
Expand Down
22 changes: 0 additions & 22 deletions arch/risc-v/src/gd32vw55x/gdwifi/wrapper_nuttx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,28 +1033,6 @@ void sys_sched_unlock(void)
* Public Functions - timers
****************************************************************************/

static void timer_worker_fixed(void *arg)
{
struct nx_timer_s *t = arg;

if (!t->active)
{
return;
}

if (t->periodic)
{
wd_start(&t->wdog, MSEC2TICK(t->delay_ms), timer_wdog_handler,
(wdparm_t)(uintptr_t)t);
}
else
{
t->active = 0;
}

t->func(t, t->arg);
}

void sys_timer_init(os_timer_t *timer, const uint8_t *name, uint32_t delay,
uint8_t periodic, timer_func_t func, void *arg)
{
Expand Down
8 changes: 6 additions & 2 deletions arch/risc-v/src/gd32vw55x/hardware/gd32vw55x_eclic.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,14 @@

#define ECLIC_INTCTL_LEVEL(l) ((((l) & 0xf) << 4) | 0x0f)

/* Nuclei-specific CSRs used with the ECLIC */
/* Nuclei-specific CSRs used with the ECLIC. Note: the Nuclei interrupt
* level status CSR lives at 0x346, not at the standard CLIC MINTSTATUS
* address that arch/risc-v/include/csr.h names CSR_MINTSTATUS (0xfb1); a
* distinct name avoids redefining it.
*/

#define CSR_MTVT 0x307 /* Vector table base */
#define CSR_MINTSTATUS 0x346 /* Interrupt level status */
#define CSR_NUCLEI_MINTSTATUS 0x346 /* Interrupt level status */
#define CSR_MCACHE_CTL 0x7ca /* I-cache control */
#define CSR_MMISC_CTL 0x7d0 /* Misc control (NMI base) */
#define CSR_MTVT2 0x7ec /* Non-vectored irq entry */
Expand Down
Loading