Skip to content

Commit 0d0bf88

Browse files
c6c7CQ Bot
authored andcommitted
[wlan-ffi-transport][wlan-mlme] FrameSender,FrameProcessor -> EthernetRx/Tx WlanRx/Tx
This change splits FrameSender into EthernetRx and WlanTx, and FrameProcessor into EthernetTx and WlanRx and moves each to the wlan-ffi-transport crate. By splitting the protocols, this change positions wlansoftmac to implement a NetworkBridge that handles EthernetImpl and EthernetIfc messages similar to how SoftmacBridge handles WlanSoftmac and WlanSoftmacIfc messages. This is last of the most recent series of changes to the FFI surface between the Rust and C++ portions of the wlansoftmac driver. The remaining portions of the FFI are more or less permanent in the sense that fuchsia.wlan.softmac API changes will not in general requires changes in the FFI. Thank you to kiettran@, seanolson@, swiggett@, and johntan@ for your numerous reviews, input, and changes to conclude the migration of wlansoftmac off Banjo bindings and onto this more stable FFI surface. Test: Successful iface creation, scan, connect, disconnect with iwlwifi on NUC Multiply: fuchsia-pkg://fuchsia.com/wlan-mlme-tests Multiply: fuchsia-pkg://fuchsia.com/wlansoftmac-rust-tests Multiply: fuchsia-pkg://fuchsia.com/wlan-hw-sim-contemporary-privacy-tests Multiply: fuchsia-pkg://fuchsia.com/wlan-hw-sim-legacy-privacy-tests Multiply: fuchsia-pkg://fuchsia.com/wlan-hw-sim-rate-selection-tests Change-Id: I43055757f5deb7c884820d07eeabddbfb40e5aec Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1039994 Reviewed-by: Dylan Swiggett <swiggett@google.com> Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com> Reviewed-by: Rebecca Silberstein <silberst@google.com> Fuchsia-Auto-Submit: Charles Celerier <chcl@google.com> API-Review: Rebecca Silberstein <silberst@google.com>
1 parent 2fe6631 commit 0d0bf88

File tree

14 files changed

+670
-485
lines changed

14 files changed

+670
-485
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"fidl/fuchsia.wlan.softmac": "ea2fbf40da8b4ae8adbe4b09eb857544"
2+
"fidl/fuchsia.wlan.softmac": "ebf4cf8da7cb019a6e9870094d28abe6"
33
}

sdk/fidl/fuchsia.wlan.softmac/softmac.fidl

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -356,62 +356,73 @@ closed protocol WlanSoftmacIfcBridge {
356356
strict StopBridgedDriver() -> ();
357357
};
358358

359+
/// Protocol for sending an Ethernet frame from the bridged wlansoftmac
360+
/// driver to the wlansoftmac driver.
361+
///
362+
/// # Experimental
363+
///
364+
/// This protocol is implemented as a foreign function interface (FFI)
365+
/// between the wlansoftmac driver and the bridged driver solely to improve
366+
/// the performance of processing data frames through the wlan-mlme library.
367+
@available(added=HEAD)
368+
closed protocol EthernetRx {
369+
strict Transfer(table {
370+
1: packet_address uint64;
371+
2: packet_size uint64;
372+
}) -> () error zx.Status;
373+
};
359374

360-
/// Protocol for sending Ethernet and WLAN frames from the wlansoftmac driver to the bridged
375+
/// Protocol for sending an Ethernet frame from the wlansoftmac driver to the bridged
361376
/// wlansoftmac driver.
362377
///
363378
/// # Experimental
364379
///
365380
/// This protocol is implemented as a foreign function interface (FFI)
366381
/// between the wlansoftmac driver and the bridged driver solely to improve
367382
/// the performance of processing data frames through the wlan-mlme library.
383+
@available(added=HEAD)
384+
closed protocol EthernetTx {
385+
strict Transfer(table {
386+
1: packet_address uint64;
387+
2: packet_size uint64;
388+
3: async_id uint64;
389+
}) -> () error zx.Status;
390+
};
391+
392+
/// Protocol for sending a WLAN frame from the wlansoftmac driver to the bridged
393+
/// wlansoftmac driver.
394+
///
395+
/// # Experimental
368396
///
369-
/// By using an FFI, messages through this protocol never enter a FIDL
370-
/// channel and thus do not incur the cost of the associated system calls
371-
/// Empirically, we observed implementing this protocol as an FFI saves on
372-
/// the order of ~500µs per frame processed when compared to implementing
373-
/// this protocol with a FIDL channel.
397+
/// This protocol is implemented as a foreign function interface (FFI)
398+
/// between the wlansoftmac driver and the bridged driver solely to improve
399+
/// the performance of processing data frames through the wlan-mlme library.
374400
@available(added=HEAD)
375-
closed protocol FrameProcessor {
376-
strict WlanRx(table {
401+
closed protocol WlanRx {
402+
strict Transfer(table {
377403
1: packet_address uint64;
378404
2: packet_size uint64;
379405
3: packet_info WlanRxInfo;
380406
4: async_id uint64;
381407
}) -> ();
382-
strict EthernetTx(table {
383-
1: packet_address uint64;
384-
2: packet_size uint64;
385-
3: async_id uint64;
386-
}) -> () error zx.Status;
387408
};
388409

389-
/// Protocol for sending Ethernet and WLAN frames from the bridged wlansoftmac
410+
/// Protocol for sending a WLAN frame from the bridged wlansoftmac
390411
/// driver to the wlansoftmac driver.
391412
///
392413
/// # Experimental
393414
///
394415
/// This protocol is implemented as a foreign function interface (FFI)
395416
/// between the wlansoftmac driver and the bridged driver solely to improve
396417
/// the performance of processing data frames through the wlan-mlme library.
397-
///
398-
/// By using an FFI, messages through this protocol never enter a FIDL
399-
/// channel and thus do not incur the cost of the associated system calls
400-
/// Empirically, we observed implementing this protocol as an FFI saves on
401-
/// the order of ~500µs per frame processed when compared to implementing
402-
/// this protocol with a FIDL channel.
403418
@available(added=HEAD)
404-
closed protocol FrameSender {
405-
strict WlanTx(table {
419+
closed protocol WlanTx {
420+
strict Transfer(table {
406421
1: packet_address uint64;
407422
2: packet_size uint64;
408423
3: packet_info WlanTxInfo;
409424
4: async_id uint64;
410425
}) -> () error zx.Status;
411-
strict EthernetRx(table {
412-
1: packet_address uint64;
413-
2: packet_size uint64;
414-
}) -> () error zx.Status;
415426
};
416427

417428
@discoverable
@@ -816,13 +827,16 @@ closed protocol WlanSoftmacBridge {
816827
/// - `ifc_bridge`: The client end of a `WlanSoftmacIfcBridge` server which the
817828
/// `wlansoftmac` driver will use to forward `WlanSoftmacIfc` events to
818829
/// the bridged driver.
819-
/// - `frame_processor`: A `frame_processor_t*` casted to a `uint64`. The
820-
/// `frame_processor_t` is defined in
830+
/// - `ethernet_tx`: A `ethernet_tx_t*` casted to a `uint64`. The
831+
/// `ethernet_tx_t` is defined in
832+
/// `//src/connectivity/wlan/drivers/wlansoftmac/rust_driver/c-binding/bindings.h`.
833+
/// - `wlan_rx`: A `wlan_rx_t*` casted to a `uint64`. The
834+
/// `wlan_rx_t` is defined in
821835
/// `//src/connectivity/wlan/drivers/wlansoftmac/rust_driver/c-binding/bindings.h`.
822836
///
823-
/// The server must copy the contents of the `frame_processor_t` before
824-
/// returning from this method. The lifetime of the `frame_processor_t*` is only as
825-
/// long as this method call, but the contents of the `frame_processor_t` will
837+
/// The server must copy the contents of `ethernet_tx_t` and `wlan_rx_t` before
838+
/// returning from this method. The lifetimes of `ethernet_tx_t*` and `wlan_rx_t*` are only as
839+
/// long as this method call, but the contents of `ethernet_tx_t` and `wlan_rx_t` will
826840
/// live until the server stops the MLME.
827841
///
828842
/// The server returns a server end of a `fuchsia.wlan.mlme/MLME` protocol. The SME
@@ -834,8 +848,8 @@ closed protocol WlanSoftmacBridge {
834848
/// protocols, so `WlanSoftmacIfcBridge` protocol must be Zircon transported to be
835849
/// usable by the bridged driver. Second, the Zircon transport adds
836850
/// significant latency compared to the Driver transport. As a result, the
837-
/// `frame_processor` argument provides an FFI for the wlansoftmac driver
838-
/// to send Ethernet and WLAN packets to the bridged driver with
851+
/// `ethernet_tx` and `wlan_rx` arguments provide an FFI for the wlansoftmac driver
852+
/// to send Ethernet and receive WLAN packets to the bridged driver with
839853
/// latency comparable or better than a Driver transported protocol.
840854
///
841855
/// Except where noted, `WlanSoftmacBridge` methods must only be called after
@@ -847,7 +861,8 @@ closed protocol WlanSoftmacBridge {
847861
@available(added=HEAD)
848862
strict Start(resource struct {
849863
ifc_bridge client_end:WlanSoftmacIfcBridge;
850-
frame_processor uint64;
864+
ethernet_tx uint64;
865+
wlan_rx uint64;
851866
}) -> (resource struct {
852867
sme_channel zx.Handle:CHANNEL;
853868
}) error zx.Status;

src/connectivity/wlan/drivers/wlansoftmac/rust_driver/c-binding/bindings.h

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,28 @@
1818
typedef struct {
1919
void *ctx;
2020
/**
21-
* Sends a WLAN MAC frame to the C++ portion of wlansoftmac.
21+
* Sends an Ethernet frame to the C++ portion of wlansoftmac.
2222
*
2323
* # Safety
2424
*
25-
* Behavior is undefined unless `payload` contains a persisted `FrameSender.WlanTx` request
25+
* Behavior is undefined unless `payload` contains a persisted `EthernetRx.Transfer` request
2626
* and `payload_len` is the length of the persisted byte array.
2727
*/
28-
zx_status_t (*wlan_tx)(void *ctx, const uint8_t *payload, uintptr_t payload_len);
28+
zx_status_t (*transfer)(void *ctx, const uint8_t *payload, uintptr_t payload_len);
29+
} ethernet_rx_t;
30+
31+
typedef struct {
32+
void *ctx;
2933
/**
30-
* Sends an Ethernet frame to the C++ portion of wlansoftmac.
34+
* Sends a WLAN MAC frame to the C++ portion of wlansoftmac.
3135
*
3236
* # Safety
3337
*
34-
* Behavior is undefined unless `payload` contains a persisted `FrameSender.EthernetRx` request
38+
* Behavior is undefined unless `payload` contains a persisted `WlanTx.Transfer` request
3539
* and `payload_len` is the length of the persisted byte array.
3640
*/
37-
zx_status_t (*ethernet_rx)(void *ctx, const uint8_t *payload, uintptr_t payload_len);
38-
} frame_sender_t;
41+
zx_status_t (*transfer)(void *ctx, const uint8_t *payload, uintptr_t payload_len);
42+
} wlan_tx_t;
3943

4044
/**
4145
* Type that wraps a pointer to a buffer allocated in the C++ portion of wlansoftmac.
@@ -87,9 +91,13 @@ typedef struct {
8791

8892
typedef struct {
8993
const void *ctx;
90-
void (*wlan_rx)(const void *ctx, const uint8_t *request, uintptr_t request_size);
91-
zx_status_t (*ethernet_tx)(const void *ctx, const uint8_t *request, uintptr_t request_size);
92-
} frame_processor_t;
94+
zx_status_t (*transfer)(const void *ctx, const uint8_t *request, uintptr_t request_size);
95+
} ethernet_tx_t;
96+
97+
typedef struct {
98+
const void *ctx;
99+
void (*transfer)(const void *ctx, const uint8_t *request, uintptr_t request_size);
100+
} wlan_rx_t;
93101

94102
/**
95103
* Start and run a bridged wlansoftmac driver hosting an MLME server and an SME server.
@@ -132,7 +140,7 @@ typedef struct {
132140
*/
133141
extern "C" zx_status_t start_and_run_bridged_wlansoftmac(
134142
void *init_completer, void (*run_init_completer)(void *init_completer, zx_status_t status),
135-
frame_sender_t frame_sender, wlansoftmac_buffer_provider_ops_t buffer_provider,
143+
ethernet_rx_t ethernet_rx, wlan_tx_t wlan_tx, wlansoftmac_buffer_provider_ops_t buffer_provider,
136144
zx_handle_t wlan_softmac_bridge_client_handle);
137145

138146
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_WLANSOFTMAC_RUST_DRIVER_C_BINDING_BINDINGS_H_

src/connectivity/wlan/drivers/wlansoftmac/rust_driver/c-binding/cbindgen.toml

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,31 @@ sys_includes = [ "zircon/types.h" ]
1717

1818
[parse]
1919
parse_deps = true
20-
include = ["wlan_mlme", "wlan_ffi_transport"]
20+
include = ["wlan_ffi_transport"]
2121

2222
[export]
23-
include = [
24-
"FfiFrameProcessor",
25-
"FfiFrameProcessorOps",
26-
]
23+
include = [ "FfiEthernetTx", "FfiWlanRx" ]
2724
exclude = [
28-
# Unused types
29-
"LinkStatus",
30-
3125
# Voided types.
3226
"FfiBufferCtx",
33-
"FfiFrameProcessorCtx",
34-
"FfiFrameSenderCtx",
27+
"FfiEthernetRxCtx",
28+
"FfiEthernetTxCtx",
29+
"FfiWlanRxCtx",
30+
"FfiWlanTxCtx",
3531
]
3632

3733
[export.rename]
38-
# wlan-ffi-transport types
3934
"FfiBuffer" = "wlansoftmac_buffer_t"
40-
"FfiBufferProvider" = "wlansoftmac_buffer_provider_ops_t"
41-
42-
# wlan-mlme types
43-
"FfiFrameProcessor" = "frame_processor_t"
44-
"FfiFrameSender" = "frame_sender_t"
45-
46-
# This struct is used for void* context fields for data path operations.
4735
"FfiBufferCtx" = "void"
48-
"FfiFrameProcessorCtx" = "void"
49-
"FfiFrameSenderCtx" = "void"
36+
"FfiBufferProvider" = "wlansoftmac_buffer_provider_ops_t"
37+
"FfiEthernetRx" = "ethernet_rx_t"
38+
"FfiEthernetRxCtx" = "void"
39+
"FfiEthernetTx" = "ethernet_tx_t"
40+
"FfiEthernetTxCtx" = "void"
41+
"FfiWlanRx" = "wlan_rx_t"
42+
"FfiWlanRxCtx" = "void"
43+
"FfiWlanTx" = "wlan_tx_t"
44+
"FfiWlanTxCtx" = "void"
5045

5146
[fn]
5247
prefix = 'extern "C"'

src/connectivity/wlan/drivers/wlansoftmac/rust_driver/c-binding/src/lib.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ use {
1010
fuchsia_async::LocalExecutor,
1111
fuchsia_zircon as zx,
1212
std::{ffi::c_void, sync::Once},
13-
wlan_ffi_transport::{BufferProvider, FfiBufferProvider},
14-
wlan_mlme::device::{Device, FfiFrameSender},
13+
wlan_ffi_transport::{
14+
BufferProvider, EthernetRx, FfiBufferProvider, FfiEthernetRx, FfiWlanTx, WlanTx,
15+
},
16+
wlan_mlme::device::Device,
1517
};
1618

1719
static LOGGER_ONCE: Once = Once::new();
@@ -57,7 +59,8 @@ static LOGGER_ONCE: Once = Once::new();
5759
pub unsafe extern "C" fn start_and_run_bridged_wlansoftmac(
5860
init_completer: *mut c_void,
5961
run_init_completer: unsafe extern "C" fn(init_completer: *mut c_void, status: zx::zx_status_t),
60-
frame_sender: FfiFrameSender,
62+
ethernet_rx: FfiEthernetRx,
63+
wlan_tx: FfiWlanTx,
6164
buffer_provider: FfiBufferProvider,
6265
wlan_softmac_bridge_client_handle: zx::sys::zx_handle_t,
6366
) -> zx::sys::zx_status_t {
@@ -83,7 +86,8 @@ pub unsafe extern "C" fn start_and_run_bridged_wlansoftmac(
8386
let channel = fidl::AsyncChannel::from_channel(channel);
8487
fidl_softmac::WlanSoftmacBridgeProxy::new(channel)
8588
};
86-
let device = Device::new(wlan_softmac_bridge_proxy, frame_sender.into());
89+
let device =
90+
Device::new(wlan_softmac_bridge_proxy, EthernetRx::new(ethernet_rx), WlanTx::new(wlan_tx));
8791

8892
let result = executor.run_singlethreaded(wlansoftmac_rust::start_and_serve(
8993
move |result: Result<(), zx::Status>| match result {

src/connectivity/wlan/drivers/wlansoftmac/rust_driver/src/lib.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ use {
2020
},
2121
std::pin::Pin,
2222
tracing::{error, info},
23-
wlan_ffi_transport::BufferProvider,
23+
wlan_ffi_transport::{BufferProvider, EthernetTx, WlanRx},
2424
wlan_fidl_ext::{ResponderExt, SendResultExt, WithName},
2525
wlan_mlme::{
26-
device::{completers::InitCompleter, DeviceOps, FrameProcessor},
26+
device::{completers::InitCompleter, DeviceOps},
2727
DriverEvent, DriverEventSink,
2828
},
2929
wlan_sme::serve::create_sme,
@@ -444,14 +444,20 @@ async fn bootstrap_generic_sme<D: DeviceOps>(
444444
// Calling WlanSoftmac.Start() indicates to the vendor driver that this driver (wlansoftmac) is
445445
// ready to receive WlanSoftmacIfc messages. wlansoftmac will buffer all WlanSoftmacIfc messages
446446
// in an mpsc::UnboundedReceiver<DriverEvent> sink until the MLME server drains them.
447-
let usme_bootstrap_channel_via_iface_creation =
448-
match device.start(ifc_bridge, FrameProcessor::new(driver_event_sink)).await {
449-
Ok(channel) => channel,
450-
Err(status) => {
451-
error!("Failed to receive a UsmeBootstrap handle: {}", status);
452-
return Err(status);
453-
}
454-
};
447+
let usme_bootstrap_channel_via_iface_creation = match device
448+
.start(
449+
ifc_bridge,
450+
EthernetTx::new(Box::new(driver_event_sink.clone())),
451+
WlanRx::new(Box::new(driver_event_sink)),
452+
)
453+
.await
454+
{
455+
Ok(channel) => channel,
456+
Err(status) => {
457+
error!("Failed to receive a UsmeBootstrap handle: {}", status);
458+
return Err(status);
459+
}
460+
};
455461
let server = fidl::endpoints::ServerEnd::<fidl_sme::UsmeBootstrapMarker>::new(
456462
usme_bootstrap_channel_via_iface_creation,
457463
);

0 commit comments

Comments
 (0)