blob: 0e176d3b06c645f3ec1bef3948f132489de89205 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_WLAN_DRIVERS_WLANSOFTMAC_SOFTMAC_DRIVER_H_
#define SRC_CONNECTIVITY_WLAN_DRIVERS_WLANSOFTMAC_SOFTMAC_DRIVER_H_
#include <fidl/fuchsia.wlan.softmac/cpp/driver/fidl.h>
#include <fuchsia/hardware/ethernet/cpp/banjo.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/driver/compat/cpp/banjo_server.h>
#include <lib/driver/compat/cpp/device_server.h>
#include <lib/driver/component/cpp/driver_base.h>
#include <lib/fdf/cpp/channel_read.h>
#include <lib/fdf/cpp/dispatcher.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/operation/ethernet.h>
#include <lib/trace/event.h>
#include <lib/zx/channel.h>
#include <lib/zx/result.h>
#include <zircon/compiler.h>
#include <memory>
#include <mutex>
#include <ddktl/device.h>
#include <fbl/ref_ptr.h>
#include <wlan/common/macaddr.h>
#include <wlan/drivers/log.h>
#include "fuchsia/hardware/ethernet/c/banjo.h"
#include "softmac_bridge.h"
namespace wlan::drivers::wlansoftmac {
class SoftmacDriver : public fdf::DriverBase, public ddk::EthernetImplProtocol<SoftmacDriver> {
public:
SoftmacDriver(fdf::DriverStartArgs start_args,
fdf::UnownedSynchronizedDispatcher driver_dispatcher);
~SoftmacDriver() = default;
static constexpr inline SoftmacDriver* from(void* ctx) {
return static_cast<SoftmacDriver*>(ctx);
}
zx_status_t EthernetImplQuery(uint32_t options, ethernet_info_t* out_info);
zx_status_t EthernetImplStart(const ethernet_ifc_protocol_t* ifc)
__TA_EXCLUDES(ethernet_proxy_lock_);
void EthernetImplStop() __TA_EXCLUDES(ethernet_proxy_lock_);
void EthernetImplQueueTx(uint32_t options, ethernet_netbuf_t* netbuf,
ethernet_impl_queue_tx_callback callback, void* cookie);
zx_status_t EthernetImplSetParam(uint32_t param, int32_t value, const uint8_t* data_buffer,
size_t data_size);
void EthernetImplGetBti(zx::bti* out_bti2);
private:
compat::BanjoServer banjo_server_;
compat::AsyncInitializedDeviceServer compat_server_;
fidl::SharedClient<fuchsia_driver_framework::Node> node_client_;
void Start(fdf::StartCompleter completer) override;
void PrepareStop(fdf::PrepareStopCompleter completer) override;
void Stop() override;
// Mark `ethernet_proxy_lock_` as a mutable member of this class to allow const functions
// to acquire it.
mutable std::shared_ptr<std::mutex> ethernet_proxy_lock_;
ddk::EthernetIfcProtocolClient ethernet_proxy_ __TA_GUARDED(ethernet_proxy_lock_);
// If MLME calls `WlanSoftmacBridge.SetEthernetStatus` before the ethernet device calls
// `EthernetImpl.Start`, the status from MLME is stored in `cached_ethernet_status_`.
// When the ethernet device calls `EthernetImpl.Start`, the cached status, if any, will be
// forwarded to `EthernetImplIfc.Start`.
//
// When MLME calls `WlanSoftmacBridge.SetEthernetStatus` multiple times before the
// ethernet device calls `EthernetImpl.Start`, the `cached_ethernet_status_` is always
// overwritten with the most recent status from MLME.
//
// This field is shared with the `SoftmacBridge` instance (in `softmac_bridge_`) which
// writes to `cached_ethernet_status_` when `SoftmacBridge::SetEthernetStatus` is called.
mutable std::optional<uint32_t> cached_ethernet_status_ __TA_GUARDED(ethernet_proxy_lock_);
std::unique_ptr<SoftmacBridge> softmac_bridge_;
// The FIDL client to communicate with the parent driver's WlanSoftmac server.
fdf::SharedClient<fuchsia_wlan_softmac::WlanSoftmac> softmac_client_;
ethernet_impl_protocol_ops_t ethernet_impl_protocol_ops_;
};
} // namespace wlan::drivers::wlansoftmac
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_WLANSOFTMAC_SOFTMAC_DRIVER_H_