[brcmfmac] Fix ownership in the bus interface
This commit moves the state held in the brcmf_device struct into a
Device class, which proper C++ lifetime semantics. Most of the state
formerly held in brcmf_device (which is not much) is moved into
brcmf_pub.
This allows us to fix the brcmf_bus_ops interface to take a brcmf_bus
instance as its context, rather than a brcmf_device.
This change also performs some cleanup of static state:
* The async dispatcher is now a member of Device, rather than a static
instance, and its lifetime is properly tied to its Device.
* The irq_callback_lock is now a brcmf_pub member, and instantiated
per-device.
Change-Id: I70362e57aa5f5aa269cc1dff919fc99c1333c468
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/BUILD.gn b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/BUILD.gn
index c12bf83..fa4e775 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/BUILD.gn
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/BUILD.gn
@@ -79,47 +79,47 @@
# "bus.cc" is not included here; see top-of-file comment.
"bcdc.cc",
"bits.cc",
+ "bits.h",
"btcoex.cc",
+ "btcoex.h",
"cfg80211.cc",
+ "cfg80211.h",
"chip.cc",
"common.cc",
"core.cc",
"d11.cc",
"device.cc",
"feature.cc",
+ "feature.h",
"fweh.cc",
"fwil.cc",
"fwsignal.cc",
- "of.cc",
+ "fwsignal.h",
"p2p.cc",
+ "p2p.h",
"pno.cc",
+ "pno.h",
"proto.cc",
+ "proto.h",
+ "timer.cc",
"utils.cc",
]
public = [
"bcdc.h",
- "bits.h",
"brcm_hw_ids.h",
"brcmu_d11.h",
"brcmu_utils.h",
"brcmu_wifi.h",
- "btcoex.h",
"bus.h",
- "cfg80211.h",
"chip.h",
"common.h",
"core.h",
"device.h",
- "feature.h",
"fweh.h",
"fwil.h",
"fwil_types.h",
- "fwsignal.h",
- "of.h",
- "p2p.h",
- "pno.h",
- "proto.h",
"soc.h",
+ "timer.h",
]
deps = [
":debug",
@@ -134,9 +134,11 @@
"//zircon/public/banjo/ddk.protocol.wlanphyimpl",
"//zircon/public/lib/async",
"//zircon/public/lib/async-loop",
+ "//zircon/public/lib/ddktl",
"//zircon/public/lib/sync",
"//zircon/system/public",
]
+ friend = [ "test/*" ]
}
source_set("firmware") {
@@ -204,6 +206,7 @@
"sim.h",
]
deps = [
+ ":core",
":debug",
"//src/connectivity/wlan/drivers/testing/lib/sim-device",
"//zircon/public/lib/ddk",
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.cc
index 9850d9d..bf479ad 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.cc
@@ -26,7 +26,6 @@
#include "bus.h"
#include "core.h"
#include "debug.h"
-#include "device.h"
#include "fwil.h"
#include "fwsignal.h"
#include "linuxisms.h"
@@ -336,18 +335,13 @@
return brcmf_bus_txdata(drvr->bus_if, pktbuf);
}
-void brcmf_proto_bcdc_txflowblock(struct brcmf_device* dev, bool state) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_pub* drvr = bus_if->drvr.get();
-
+void brcmf_proto_bcdc_txflowblock(brcmf_pub* drvr, bool state) {
BRCMF_DBG(TRACE, "Enter\n");
-
brcmf_fws_bus_blocked(drvr, state);
}
-void brcmf_proto_bcdc_txcomplete(struct brcmf_device* dev, struct brcmf_netbuf* txp, bool success) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_bcdc* bcdc = static_cast<decltype(bcdc)>(bus_if->drvr->proto->pd);
+void brcmf_proto_bcdc_txcomplete(brcmf_pub* drvr, struct brcmf_netbuf* txp, bool success) {
+ struct brcmf_bcdc* bcdc = static_cast<decltype(bcdc)>(drvr->proto->pd);
struct brcmf_if* ifp;
/* await txstatus signal for firmware if active */
@@ -356,7 +350,7 @@
brcmf_fws_bustxfail(bcdc->fws, txp);
}
} else {
- if (brcmf_proto_bcdc_hdrpull(bus_if->drvr.get(), false, txp, &ifp)) {
+ if (brcmf_proto_bcdc_hdrpull(drvr, false, txp, &ifp)) {
brcmu_pkt_buf_free_netbuf(txp);
} else {
brcmf_txfinalize(ifp, txp, success);
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.h
index 4b75d76..bfb6003 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcdc.h
@@ -17,7 +17,6 @@
#define SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_BCDC_H_
#include "core.h"
-#include "device.h"
#include "netbuf.h"
struct brcmf_proto_bcdc_dcmd {
@@ -54,10 +53,10 @@
// clang-format on
-zx_status_t brcmf_proto_bcdc_attach(struct brcmf_pub* drvr);
-void brcmf_proto_bcdc_detach(struct brcmf_pub* drvr);
-void brcmf_proto_bcdc_txflowblock(struct brcmf_device* dev, bool state);
-void brcmf_proto_bcdc_txcomplete(struct brcmf_device* dev, struct brcmf_netbuf* txp, bool success);
-struct brcmf_fws_info* drvr_to_fws(struct brcmf_pub* drvr);
+zx_status_t brcmf_proto_bcdc_attach(brcmf_pub* drvr);
+void brcmf_proto_bcdc_detach(brcmf_pub* drvr);
+void brcmf_proto_bcdc_txflowblock(brcmf_pub* drvr, bool state);
+void brcmf_proto_bcdc_txcomplete(brcmf_pub* drvr, brcmf_netbuf* txp, bool success);
+struct brcmf_fws_info* drvr_to_fws(brcmf_pub* drvr);
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_BCDC_H_
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcmsdh.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcmsdh.cc
index c48c793..e064514 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcmsdh.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bcmsdh.cc
@@ -43,7 +43,6 @@
#include "common.h"
#include "debug.h"
#include "defs.h"
-#include "device.h"
#include "linuxisms.h"
#include "netbuf.h"
#include "sdio.h"
@@ -91,7 +90,7 @@
uint8_t bootloader_macaddr[8];
size_t actual_len;
zx_status_t ret =
- device_get_metadata(sdiodev->dev->zxdev, DEVICE_METADATA_MAC_ADDRESS, bootloader_macaddr,
+ device_get_metadata(sdiodev->drvr->zxdev, DEVICE_METADATA_MAC_ADDRESS, bootloader_macaddr,
sizeof(bootloader_macaddr), &actual_len);
if (ret != ZX_OK || actual_len < ETH_ALEN) {
@@ -113,7 +112,7 @@
pdata->oob_irq_supported = false;
wifi_config_t config;
size_t actual;
- ret = device_get_metadata(sdiodev->dev->zxdev, DEVICE_METADATA_WIFI_CONFIG, &config,
+ ret = device_get_metadata(sdiodev->drvr->zxdev, DEVICE_METADATA_WIFI_CONFIG, &config,
sizeof(wifi_config_t), &actual);
if ((ret != ZX_OK && ret != ZX_ERR_NOT_FOUND) ||
(ret == ZX_OK && actual != sizeof(wifi_config_t))) {
@@ -769,7 +768,7 @@
{/* end: all zeroes */}};
#endif // TODO_ADD_SDIO_IDS
-zx_status_t brcmf_sdio_register(struct brcmf_device* device) {
+zx_status_t brcmf_sdio_register(brcmf_pub* drvr, std::unique_ptr<brcmf_bus>* out_bus) {
zx_status_t err;
zx_status_t status;
@@ -781,7 +780,7 @@
BRCMF_DBG(SDIO, "Enter\n");
composite_protocol_t composite_proto = {};
- status = device_get_protocol(device->zxdev, ZX_PROTOCOL_COMPOSITE, &composite_proto);
+ status = device_get_protocol(drvr->zxdev, ZX_PROTOCOL_COMPOSITE, &composite_proto);
if (status != ZX_OK) {
return status;
}
@@ -856,7 +855,7 @@
/* Set MMC_QUIRK_LENIENT_FN0 for this card */
// func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
- bus_if = std::make_unique<struct brcmf_bus>();
+ bus_if = std::make_unique<brcmf_bus>();
func1 = static_cast<decltype(func1)>(calloc(1, sizeof(struct sdio_func)));
if (!func1) {
err = ZX_ERR_NO_MEMORY;
@@ -898,9 +897,8 @@
sdiodev->bus_if = bus_if.get();
sdiodev->func1 = func1;
sdiodev->func2 = func2;
- sdiodev->dev = device;
+ sdiodev->drvr = drvr;
bus_if->bus_priv.sdio = sdiodev;
- device->bus = std::move(bus_if);
sdiodev->manufacturer_id = devinfo.funcs_hw_info[SDIO_FN_1].manufacturer_id;
sdiodev->product_id = devinfo.funcs_hw_info[SDIO_FN_1].product_id;
@@ -916,6 +914,8 @@
pthread_mutexattr_destroy(&mutex_attr);
BRCMF_DBG(SDIO, "F2 init completed...\n");
+
+ *out_bus = std::move(bus_if);
return ZX_OK;
fail:
@@ -957,18 +957,10 @@
BRCMF_DBG(SDIO, "Exit\n");
}
-void brcmf_sdio_wowl_config(struct brcmf_device* dev, bool enabled) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
-
- BRCMF_DBG(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
- sdiodev->wowl_enabled = enabled;
-}
-
-void brcmf_sdio_exit(struct brcmf_device* device) {
+void brcmf_sdio_exit(brcmf_bus* bus) {
BRCMF_DBG(SDIO, "Enter\n");
- brcmf_ops_sdio_remove(device->bus->bus_priv.sdio);
- delete device->bus->bus_priv.sdio;
- device->bus.reset();
+ brcmf_ops_sdio_remove(bus->bus_priv.sdio);
+ delete bus->bus_priv.sdio;
+ bus->bus_priv.sdio = nullptr;
}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/binding.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/binding.cc
index 1236416..392086f 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/binding.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/binding.cc
@@ -11,130 +11,21 @@
// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE.
-#include <zircon/types.h>
-
#include <memory>
#include <ddk/binding.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>
-#include <ddktl/device.h>
-#include <ddktl/protocol/wlanphyimpl.h>
#include <hw/pci.h>
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/brcm_hw_ids.h"
-#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h"
-#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.h"
-#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h"
-namespace wlan {
-namespace brcmfmac {
-
-// This class uses the DDKTL classes to manage the lifetime of a brcmfmac driver instance.
-class WlanphyImplDevice : public ::ddk::Device<WlanphyImplDevice, ::ddk::Unbindable>,
- public ::ddk::WlanphyImplProtocol<WlanphyImplDevice, ddk::base_protocol> {
- public:
- // Static factory function for WlanphyImplDevice instances. This factory does not return the
- // instance itself, as on successful invocation the instance will have its lifecycle managed by
- // the devhost.
- static zx_status_t Create(zx_device_t* device);
-
- // DDK interface implementation.
- void DdkUnbind();
- void DdkRelease();
-
- // WlanphyImpl protocol implementation.
- zx_status_t WlanphyImplQuery(wlanphy_impl_info_t* out_info);
- zx_status_t WlanphyImplCreateIface(const wlanphy_impl_create_iface_req_t* req,
- uint16_t* out_iface_id);
- zx_status_t WlanphyImplDestroyIface(uint16_t iface_id);
- zx_status_t WlanphyImplSetCountry(const wlanphy_country_t* country);
-
- protected:
- using DeviceType = ::ddk::Device<WlanphyImplDevice, ::ddk::Unbindable>;
-
- explicit WlanphyImplDevice(zx_device_t* parent);
- ~WlanphyImplDevice() = default;
-
- private:
- brcmf_device device_;
-};
-
-// static
-zx_status_t WlanphyImplDevice::Create(zx_device_t* device) {
- zx_status_t status = ZX_OK;
-
- const auto ddk_remover = [](WlanphyImplDevice* device) { device->DdkRemove(); };
- std::unique_ptr<WlanphyImplDevice, decltype(ddk_remover)> wlanphyimpl_device(
- new WlanphyImplDevice(device), ddk_remover);
- if ((status = wlanphyimpl_device->DdkAdd("brcmfmac-wlanphy", DEVICE_ADD_INVISIBLE)) != ZX_OK) {
- delete wlanphyimpl_device.release();
- return status;
- }
- wlanphyimpl_device->device_.zxdev = device;
- wlanphyimpl_device->device_.phy_zxdev = wlanphyimpl_device->zxdev();
-
- if ((status = brcmf_core_init(&wlanphyimpl_device->device_)) != ZX_OK) {
- return status;
- }
-
- wlanphyimpl_device.release(); // This now has its lifecycle managed by the devhost.
- return ZX_OK;
-}
-
-void WlanphyImplDevice::DdkUnbind() {
- brcmf_core_exit(&device_);
- DdkRemove();
-}
-
-void WlanphyImplDevice::DdkRelease() { delete this; }
-
-zx_status_t WlanphyImplDevice::WlanphyImplQuery(wlanphy_impl_info_t* out_info) {
- if (!device_.bus) {
- return ZX_ERR_BAD_STATE;
- }
- brcmf_if* const ifp = device_.bus->drvr->iflist[0];
- return brcmf_phy_query(ifp, out_info);
-}
-
-zx_status_t WlanphyImplDevice::WlanphyImplCreateIface(const wlanphy_impl_create_iface_req_t* req,
- uint16_t* out_iface_id) {
- if (!device_.bus) {
- return ZX_ERR_BAD_STATE;
- }
- brcmf_if* const ifp = device_.bus->drvr->iflist[0];
- return brcmf_phy_create_iface(ifp, req, out_iface_id);
-}
-
-zx_status_t WlanphyImplDevice::WlanphyImplDestroyIface(uint16_t iface_id) {
- if (!device_.bus) {
- return ZX_ERR_BAD_STATE;
- }
- brcmf_if* const ifp = device_.bus->drvr->iflist[0];
- return brcmf_phy_destroy_iface(ifp, iface_id);
-}
-
-zx_status_t WlanphyImplDevice::WlanphyImplSetCountry(const wlanphy_country_t* country) {
- if (!device_.bus) {
- return ZX_ERR_BAD_STATE;
- }
- brcmf_if* const ifp = device_.bus->drvr->iflist[0];
- return brcmf_phy_set_country(ifp, country);
-}
-
-WlanphyImplDevice::WlanphyImplDevice(zx_device_t* parent) : DeviceType(parent), device_() {}
-
-} // namespace brcmfmac
-} // namespace wlan
-
static constexpr zx_driver_ops_t brcmfmac_driver_ops = {
.version = DRIVER_OPS_VERSION,
- .init = [](void** out_ctx) { return brcmfmac_module_init(); },
.bind = [](void* ctx,
- zx_device_t* device) { return ::wlan::brcmfmac::WlanphyImplDevice::Create(device); },
- .release = [](void* ctx) { return brcmfmac_module_exit(); },
+ zx_device_t* device) { return ::wlan::brcmfmac::Device::Create(device, nullptr); },
};
// clang-format off
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/btcoex.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/btcoex.cc
index fa1c091..2be9ca6 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/btcoex.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/btcoex.cc
@@ -22,7 +22,6 @@
#include "core.h"
#include "debug.h"
#include "defs.h"
-#include "device.h"
#include "fwil.h"
#include "fwil_types.h"
#include "linuxisms.h"
@@ -264,13 +263,13 @@
* brcmf_btcoex_timerfunc() - BT coex timer callback
*/
static void brcmf_btcoex_timerfunc(void* data) {
- pthread_mutex_lock(&irq_callback_lock);
struct brcmf_btcoex_info* bt_local = static_cast<decltype(bt_local)>(data);
+ bt_local->cfg->pub->irq_callback_lock.lock();
BRCMF_DBG(TRACE, "enter\n");
bt_local->timer_on = false;
workqueue_schedule_default(&bt_local->work);
- pthread_mutex_unlock(&irq_callback_lock);
+ bt_local->cfg->pub->irq_callback_lock.unlock();
}
/**
@@ -362,7 +361,7 @@
/* Set up timer for BT */
btci->timer_on = false;
btci->timeout = BRCMF_BTCOEX_OPPR_WIN_TIME_MSEC;
- brcmf_timer_init(&btci->timer, brcmf_btcoex_timerfunc, btci);
+ brcmf_timer_init(&btci->timer, cfg->pub->dispatcher, brcmf_btcoex_timerfunc, btci);
btci->cfg = cfg;
btci->saved_regs_part1 = false;
btci->saved_regs_part2 = false;
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.cc
index 5d2edf8..210bde4 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.cc
@@ -11,18 +11,18 @@
// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
// OF THIS SOFTWARE.
-#include "bus.h"
+#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h"
-#include "debug.h"
+#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/debug.h"
// Note that this file does not include any headers that define the bus-specific functions it calls,
// since it cannot depend on them. Hence we just declare them directly before use.
-zx_status_t brcmf_bus_register(struct brcmf_device* device) {
+zx_status_t brcmf_bus_register(brcmf_pub* drvr, std::unique_ptr<brcmf_bus>* out_bus) {
#if CONFIG_BRCMFMAC_SDIO
{
- extern zx_status_t brcmf_sdio_register(struct brcmf_device * device);
- const zx_status_t result = brcmf_sdio_register(device);
+ extern zx_status_t brcmf_sdio_register(brcmf_pub * drvr, std::unique_ptr<brcmf_bus> * out_bus);
+ const zx_status_t result = brcmf_sdio_register(drvr, out_bus);
if (result != ZX_OK) {
BRCMF_DBG(INFO, "SDIO registration failed: %d\n", result);
} else {
@@ -33,8 +33,8 @@
#if CONFIG_BRCMFMAC_SIM
{
- extern zx_status_t brcmf_sim_register(struct brcmf_device * device);
- const zx_status_t result = brcmf_sim_register(device);
+ extern zx_status_t brcmf_sim_register(brcmf_pub * drvr, std::unique_ptr<brcmf_bus> * out_bus);
+ const zx_status_t result = brcmf_sim_register(drvr, out_bus);
if (result != ZX_OK) {
BRCMF_DBG(INFO, "SIM registration failed: %d\n", result);
} else {
@@ -46,14 +46,14 @@
return ZX_ERR_NOT_SUPPORTED;
}
-void brcmf_bus_exit(struct brcmf_device* device) {
+void brcmf_bus_exit(brcmf_bus* bus) {
#if CONFIG_BRCMFMAC_SDIO
- extern void brcmf_sdio_exit(struct brcmf_device * device);
- brcmf_sdio_exit(device);
+ extern void brcmf_sdio_exit(brcmf_bus * bus);
+ brcmf_sdio_exit(bus);
#endif
#if CONFIG_BRCMFMAC_SIM
- extern void brcmf_sim_exit(struct brcmf_device * device);
- brcmf_sim_exit(device);
+ extern void brcmf_sim_exit(brcmf_bus * bus);
+ brcmf_sim_exit(bus);
#endif
}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h
index 5d77d1b..e7cd956 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h
@@ -23,8 +23,6 @@
#include <ddk/device.h>
#include <ddk/driver.h>
-#include "core.h"
-#include "device.h"
#include "netbuf.h"
// HW/SW bus in use
@@ -36,6 +34,7 @@
BRCMF_BUS_UP /* Ready for frame transfers */
};
+struct brcmf_pub;
struct brcmf_mp_device;
struct brcmf_bus_dcmd {
@@ -72,22 +71,21 @@
* indicated otherwise these callbacks are mandatory.
*/
-#include "device.h"
+struct brcmf_bus;
struct brcmf_bus_ops {
enum brcmf_bus_type (*get_bus_type)();
- zx_status_t (*preinit)(struct brcmf_device* dev);
- void (*stop)(struct brcmf_device* dev);
- zx_status_t (*txdata)(struct brcmf_device* dev, struct brcmf_netbuf* netbuf);
- zx_status_t (*txctl)(struct brcmf_device* dev, unsigned char* msg, uint len);
- zx_status_t (*rxctl)(struct brcmf_device* dev, unsigned char* msg, uint len, int* rxlen_out);
- struct pktq* (*gettxq)(struct brcmf_device* dev);
- void (*wowl_config)(struct brcmf_device* dev, bool enabled);
- size_t (*get_ramsize)(struct brcmf_device* dev);
- zx_status_t (*get_memdump)(struct brcmf_device* dev, void* data, size_t len);
- zx_status_t (*get_fwname)(struct brcmf_device* dev, uint chip, uint chiprev,
- unsigned char* fw_name);
- zx_status_t (*get_bootloader_macaddr)(struct brcmf_device* dev, uint8_t* mac_addr);
+ zx_status_t (*preinit)(brcmf_bus* bus);
+ void (*stop)(brcmf_bus* bus);
+ zx_status_t (*txdata)(brcmf_bus* bus, struct brcmf_netbuf* netbuf);
+ zx_status_t (*txctl)(brcmf_bus* bus, unsigned char* msg, uint len);
+ zx_status_t (*rxctl)(brcmf_bus* bus, unsigned char* msg, uint len, int* rxlen_out);
+ struct pktq* (*gettxq)(brcmf_bus* bus);
+ void (*wowl_config)(brcmf_bus* bus, bool enabled);
+ size_t (*get_ramsize)(brcmf_bus* bus);
+ zx_status_t (*get_memdump)(brcmf_bus* bus, void* data, size_t len);
+ zx_status_t (*get_fwname)(brcmf_bus* bus, uint chip, uint chiprev, unsigned char* fw_name);
+ zx_status_t (*get_bootloader_macaddr)(brcmf_bus* bus, uint8_t* mac_addr);
zx_status_t (*device_add)(zx_device_t* parent, device_add_args_t* args, zx_device_t** out);
};
@@ -123,8 +121,6 @@
struct brcmf_pciedev* pcie;
struct brcmf_simdev* sim;
} bus_priv;
- struct brcmf_device* dev;
- std::unique_ptr<struct brcmf_pub> drvr;
enum brcmf_bus_state state;
struct brcmf_bus_stats stats;
uint maxctl;
@@ -143,22 +139,22 @@
if (!bus->ops->preinit) {
return ZX_OK;
}
- return bus->ops->preinit(bus->dev);
+ return bus->ops->preinit(bus);
}
-static inline void brcmf_bus_stop(struct brcmf_bus* bus) { bus->ops->stop(bus->dev); }
+static inline void brcmf_bus_stop(struct brcmf_bus* bus) { bus->ops->stop(bus); }
static inline int brcmf_bus_txdata(struct brcmf_bus* bus, struct brcmf_netbuf* netbuf) {
- return bus->ops->txdata(bus->dev, netbuf);
+ return bus->ops->txdata(bus, netbuf);
}
static inline int brcmf_bus_txctl(struct brcmf_bus* bus, unsigned char* msg, uint len) {
- return bus->ops->txctl(bus->dev, msg, len);
+ return bus->ops->txctl(bus, msg, len);
}
static inline int brcmf_bus_rxctl(struct brcmf_bus* bus, unsigned char* msg, uint len,
int* rxlen_out) {
- return bus->ops->rxctl(bus->dev, msg, len, rxlen_out);
+ return bus->ops->rxctl(bus, msg, len, rxlen_out);
}
static inline zx_status_t brcmf_bus_gettxq(struct brcmf_bus* bus, struct pktq** txq_out) {
@@ -169,14 +165,14 @@
return ZX_ERR_NOT_FOUND;
}
if (txq_out) {
- *txq_out = bus->ops->gettxq(bus->dev);
+ *txq_out = bus->ops->gettxq(bus);
}
return ZX_OK;
}
static inline void brcmf_bus_wowl_config(struct brcmf_bus* bus, bool enabled) {
if (bus->ops->wowl_config) {
- bus->ops->wowl_config(bus->dev, enabled);
+ bus->ops->wowl_config(bus, enabled);
}
}
@@ -185,7 +181,7 @@
return 0;
}
- return bus->ops->get_ramsize(bus->dev);
+ return bus->ops->get_ramsize(bus);
}
static inline zx_status_t brcmf_bus_get_memdump(struct brcmf_bus* bus, void* data, size_t len) {
@@ -193,17 +189,17 @@
return ZX_ERR_NOT_FOUND;
}
- return bus->ops->get_memdump(bus->dev, data, len);
+ return bus->ops->get_memdump(bus, data, len);
}
static inline zx_status_t brcmf_bus_get_fwname(struct brcmf_bus* bus, uint chip, uint chiprev,
unsigned char* fw_name) {
- return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name);
+ return bus->ops->get_fwname(bus, chip, chiprev, fw_name);
}
static inline zx_status_t brcmf_bus_get_bootloader_macaddr(struct brcmf_bus* bus,
uint8_t* mac_addr) {
- return bus->ops->get_bootloader_macaddr(bus->dev, mac_addr);
+ return bus->ops->get_bootloader_macaddr(bus, mac_addr);
}
static inline zx_status_t brcmf_bus_device_add(struct brcmf_bus* bus, zx_device_t* parent,
@@ -211,32 +207,8 @@
return bus->ops->device_add(parent, args, out);
}
-/*
- * interface functions from common layer
- */
-
-/* Receive frame for delivery to OS. Callee disposes of rxp. */
-void brcmf_rx_frame(struct brcmf_device* dev, struct brcmf_netbuf* rxp, bool handle_event);
-/* Receive async event packet from firmware. Callee disposes of rxp. */
-void brcmf_rx_event(struct brcmf_device* dev, struct brcmf_netbuf* rxp);
-
-/* Indication from bus module regarding presence/insertion of dongle. */
-zx_status_t brcmf_attach(struct brcmf_device* dev, struct brcmf_mp_device* settings);
-/* Indication from bus module regarding removal/absence of dongle */
-void brcmf_detach(struct brcmf_device* dev);
-/* Indication from bus module that dongle should be reset */
-void brcmf_dev_reset(struct brcmf_device* dev);
-
-/* Configure the "global" bus state used by upper layers */
-void brcmf_bus_change_state(struct brcmf_bus* bus, enum brcmf_bus_state state);
-
-zx_status_t brcmf_bus_started(struct brcmf_device* dev);
-zx_status_t brcmf_iovar_data_set(struct brcmf_device* dev, const char* name, void* data,
- uint32_t len, int32_t* fwerr_ptr);
-void brcmf_bus_add_txhdrlen(struct brcmf_device* dev, uint len);
-
// Interface to the system bus.
-zx_status_t brcmf_bus_register(struct brcmf_device* device);
-void brcmf_bus_exit(struct brcmf_device* device);
+zx_status_t brcmf_bus_register(brcmf_pub* drvr, std::unique_ptr<brcmf_bus>* out_bus);
+void brcmf_bus_exit(brcmf_bus* bus);
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_BUS_H_
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.cc
index aa339d6..425a770 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.cc
@@ -35,7 +35,6 @@
#include "core.h"
#include "debug.h"
#include "defs.h"
-#include "device.h"
#include "feature.h"
#include "fwil.h"
#include "fwil_types.h"
@@ -1146,13 +1145,12 @@
}
static void brcmf_disconnect_timeout(void* data) {
- pthread_mutex_lock(&irq_callback_lock);
-
struct brcmf_cfg80211_info* cfg = static_cast<decltype(cfg)>(data);
+ cfg->pub->irq_callback_lock.lock();
BRCMF_DBG(TRACE, "Enter\n");
workqueue_schedule_default(&cfg->disconnect_timeout_work);
- pthread_mutex_unlock(&irq_callback_lock);
+ cfg->pub->irq_callback_lock.unlock();
}
static zx_status_t brcmf_cfg80211_disconnect(struct net_device* ndev,
@@ -1198,7 +1196,7 @@
goto done;
}
- brcmf_timer_init(&cfg->disconnect_timeout, brcmf_disconnect_timeout, cfg);
+ brcmf_timer_init(&cfg->disconnect_timeout, ifp->drvr->dispatcher, brcmf_disconnect_timeout, cfg);
brcmf_timer_set(&cfg->disconnect_timeout, BRCMF_DISCONNECT_TIMEOUT);
done:
@@ -1572,14 +1570,14 @@
}
static void brcmf_escan_timeout(void* data) {
- pthread_mutex_lock(&irq_callback_lock);
struct brcmf_cfg80211_info* cfg = static_cast<decltype(cfg)>(data);
+ cfg->pub->irq_callback_lock.lock();
if (cfg->int_escan_map || cfg->scan_request) {
BRCMF_ERR("timer expired\n");
workqueue_schedule_default(&cfg->escan_timeout_work);
}
- pthread_mutex_unlock(&irq_callback_lock);
+ cfg->pub->irq_callback_lock.unlock();
}
static bool brcmf_compare_update_same_bss(struct brcmf_cfg80211_info* cfg,
@@ -1720,7 +1718,7 @@
cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
/* Init scan_timeout timer */
cfg->escan_timeout.data = cfg;
- brcmf_timer_init(&cfg->escan_timeout, brcmf_escan_timeout, cfg);
+ brcmf_timer_init(&cfg->escan_timeout, cfg->pub->dispatcher, brcmf_escan_timeout, cfg);
workqueue_init_work(&cfg->escan_timeout_work, brcmf_cfg80211_escan_timeout_worker);
}
@@ -4491,8 +4489,7 @@
free(wiphy);
}
-struct brcmf_cfg80211_info* brcmf_cfg80211_attach(struct brcmf_pub* drvr,
- struct brcmf_device* busdev, bool p2pdev_forced) {
+struct brcmf_cfg80211_info* brcmf_cfg80211_attach(struct brcmf_pub* drvr) {
struct net_device* ndev = brcmf_get_ifp(drvr, 0)->ndev;
struct brcmf_cfg80211_info* cfg;
struct wiphy* wiphy;
@@ -4520,7 +4517,6 @@
goto wiphy_out;
}
memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
- wiphy->dev = busdev;
cfg = wiphy_to_cfg(wiphy);
cfg->wiphy = wiphy;
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.h
index b09a129..adb29f2 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/cfg80211.h
@@ -27,9 +27,9 @@
/* for brcmu_d11inf */
#include "brcmu_d11.h"
#include "core.h"
-#include "device.h"
#include "fwil_types.h"
#include "p2p.h"
+#include "timer.h"
#include "workqueue.h"
// clang-format off
@@ -418,8 +418,7 @@
return &cfg->conn_info;
}
-struct brcmf_cfg80211_info* brcmf_cfg80211_attach(struct brcmf_pub* drvr,
- struct brcmf_device* busdev, bool p2pdev_forced);
+struct brcmf_cfg80211_info* brcmf_cfg80211_attach(struct brcmf_pub* drvr);
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info* cfg);
zx_status_t brcmf_cfg80211_up(struct net_device* ndev);
zx_status_t brcmf_cfg80211_down(struct net_device* ndev);
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/chip.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/chip.cc
index c755b5b..1563397 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/chip.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/chip.cc
@@ -24,7 +24,6 @@
#include "chipcommon.h"
#include "debug.h"
#include "defs.h"
-#include "device.h"
#include "linuxisms.h"
#include "soc.h"
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.cc
index d0d6635..c5638fe 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.cc
@@ -25,11 +25,9 @@
#include "brcmu_wifi.h"
#include "bus.h"
#include "debug.h"
-#include "device.h"
#include "fwil.h"
#include "fwil_types.h"
#include "linuxisms.h"
-#include "of.h"
MODULE_AUTHOR("Broadcom Corporation")
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.")
@@ -49,10 +47,6 @@
module_param_named(feature_disable, brcmf_feature_disable, int, 0)
MODULE_PARM_DESC(feature_disable, "Disable features")
- static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN] = "brcmfmac/";
-module_param_string(alternative_fw_path, brcmf_firmware_path, BRCMF_FW_ALTPATH_LEN, S_IRUSR)
- MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path")
-
static int brcmf_fcmode;
module_param_named(fcmode, brcmf_fcmode, int, 0)
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control")
@@ -67,8 +61,6 @@
MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging")
#endif // !defined(NDEBUG)
- struct brcmf_mp_global_t brcmf_mp_global;
-
void brcmf_c_set_joinpref_default(struct brcmf_if* ifp) {
struct brcmf_join_pref_params join_pref_params[2];
zx_status_t err;
@@ -338,16 +330,7 @@
return err;
}
-static void brcmf_mp_attach(void) {
- /* If module param firmware path is set then this will always be used,
- * if not set then if available use the platform data version. To make
- * sure it gets initialized at all, always copy the module param version
- */
- strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, BRCMF_FW_ALTPATH_LEN);
-}
-
-struct brcmf_mp_device* brcmf_get_module_param(struct brcmf_device* dev,
- enum brcmf_bus_type bus_type, uint32_t chip,
+struct brcmf_mp_device* brcmf_get_module_param(enum brcmf_bus_type bus_type, uint32_t chip,
uint32_t chiprev) {
struct brcmf_mp_device* settings;
@@ -406,43 +389,8 @@
}
}
}
- if (!found) {
- /* No platform data for this device, try OF (Open Firwmare) */
- brcmf_of_probe(dev, bus_type, settings);
- }
#endif /* USE_PLATFORM_DATA */
return settings;
}
void brcmf_release_module_param(struct brcmf_mp_device* module_param) { free(module_param); }
-
-zx_status_t brcmfmac_module_init(void) {
- zx_status_t err = ZX_OK;
-
- async_loop_t* async_loop;
- async_loop_config_t async_config;
- memset(&async_config, 0, sizeof(async_config));
- err = async_loop_create(&async_config, &async_loop);
- if (err != ZX_OK) {
- BRCMF_ERR("Returning err %d %s", err, zx_status_get_string(err));
- return err;
- }
- err = async_loop_start_thread(async_loop, "async_thread", NULL);
- if (err != ZX_OK) {
- async_loop_destroy(async_loop);
- BRCMF_ERR("Returning err %d %s", err, zx_status_get_string(err));
- return err;
- }
- default_dispatcher = async_loop_get_dispatcher(async_loop);
-
- /* Initialize global module paramaters */
- brcmf_mp_attach();
-
- return ZX_OK;
-}
-
-void brcmfmac_module_exit(void) {
- if (default_dispatcher != NULL) {
- async_loop_destroy(async_loop_from_dispatcher(default_dispatcher));
- }
-}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.h
index 0536d35..4c7caaa 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/common.h
@@ -17,32 +17,12 @@
#include "bus.h"
#include "core.h"
-#include "device.h"
#include "fwil_types.h"
#include "linuxisms.h"
#define BRCMF_FW_ALTPATH_LEN 256
#define BRCMF_FW_NAME_LEN 320
-/* Definitions for the module global and device specific settings are defined
- * here. Two structs are used for them. brcmf_mp_global_t and brcmf_mp_device.
- * The mp_global is instantiated once in a global struct and gets initialized
- * by the common_attach function which should be called before any other
- * (module) initiliazation takes place. The device specific settings is part
- * of the drvr struct and should be initialized on every brcmf_attach.
- */
-
-/**
- * struct brcmf_mp_global_t - Global module paramaters.
- *
- * @firmware_path: Alternative firmware path.
- */
-struct brcmf_mp_global_t {
- char firmware_path[BRCMF_FW_ALTPATH_LEN];
-};
-
-extern struct brcmf_mp_global_t brcmf_mp_global;
-
/**
* struct brcmfmac_sdio_pd - SDIO-specific device module parameters
*/
@@ -78,15 +58,11 @@
void brcmf_c_set_joinpref_default(struct brcmf_if* ifp);
-struct brcmf_mp_device* brcmf_get_module_param(struct brcmf_device* dev,
- enum brcmf_bus_type bus_type, uint32_t chip,
+struct brcmf_mp_device* brcmf_get_module_param(enum brcmf_bus_type bus_type, uint32_t chip,
uint32_t chiprev);
void brcmf_release_module_param(struct brcmf_mp_device* module_param);
/* Sets dongle media info (drv_version, mac address). */
zx_status_t brcmf_c_preinit_dcmds(struct brcmf_if* ifp);
-zx_status_t brcmfmac_module_init();
-void brcmfmac_module_exit();
-
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_COMMON_H_
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.cc
index 4f4001b..d0ac119 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.cc
@@ -33,7 +33,6 @@
#include "cfg80211.h"
#include "common.h"
#include "debug.h"
-#include "device.h"
#include "feature.h"
#include "fwil.h"
#include "fwil_types.h"
@@ -46,14 +45,12 @@
#define MAX_WAIT_FOR_8021X_TX_MSEC (950)
-#define BRCMF_BSSIDX_INVALID -1
-
-static inline struct brcmf_device* if_to_dev(struct brcmf_if* ifp) {
- return ifp->drvr->bus_if->dev;
+static inline brcmf_pub* if_to_pub(struct brcmf_if* ifp) {
+ return ifp->drvr;
}
-static inline struct brcmf_device* ndev_to_dev(struct net_device* ndev) {
- return if_to_dev(ndev_to_if(ndev));
+static inline brcmf_pub* ndev_to_pub(struct net_device* ndev) {
+ return if_to_pub(ndev_to_if(ndev));
}
const char* brcmf_ifname(struct brcmf_if* ifp) {
@@ -301,7 +298,7 @@
ifp->netif_stop, reason, state);
// spin_lock_irqsave(&ifp->netif_stop_lock, flags);
- pthread_mutex_lock(&irq_callback_lock);
+ ifp->drvr->irq_callback_lock.lock();
if (state) {
if (!ifp->netif_stop) {
@@ -315,7 +312,7 @@
}
}
// spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
- pthread_mutex_unlock(&irq_callback_lock);
+ ifp->drvr->irq_callback_lock.unlock();
}
void brcmf_netif_rx(struct brcmf_if* ifp, struct brcmf_netbuf* netbuf) {
@@ -377,12 +374,10 @@
return ZX_OK;
}
-void brcmf_rx_frame(struct brcmf_device* dev, struct brcmf_netbuf* netbuf, bool handle_event) {
+void brcmf_rx_frame(brcmf_pub* drvr, brcmf_netbuf* netbuf, bool handle_event) {
struct brcmf_if* ifp;
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_pub* drvr = bus_if->drvr.get();
- BRCMF_DBG(DATA, "Enter: %s: rxp=%p\n", device_get_name(dev->zxdev), netbuf);
+ BRCMF_DBG(DATA, "Enter: %s: rxp=%p\n", device_get_name(drvr->zxdev), netbuf);
if (brcmf_rx_hdrpull(drvr, netbuf, &ifp)) {
BRCMF_DBG(TEMP, "hdrpull returned nonzero\n");
@@ -401,12 +396,10 @@
}
}
-void brcmf_rx_event(struct brcmf_device* dev, struct brcmf_netbuf* netbuf) {
+void brcmf_rx_event(brcmf_pub* drvr, brcmf_netbuf* netbuf) {
struct brcmf_if* ifp;
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_pub* drvr = bus_if->drvr.get();
- BRCMF_DBG(EVENT, "Enter: %s: rxp=%p\n", device_get_name(dev->zxdev), netbuf);
+ BRCMF_DBG(EVENT, "Enter: %s: rxp=%p\n", device_get_name(drvr->zxdev), netbuf);
if (brcmf_rx_hdrpull(drvr, netbuf, &ifp)) {
return;
@@ -543,11 +536,11 @@
.proto_ops = &if_impl_proto_ops,
};
- struct brcmf_device* device = ifp->drvr->bus_if->dev;
- struct brcmf_bus* bus = device->bus.get();
+ brcmf_pub* const drvr = ifp->drvr;
+ brcmf_bus* const bus = drvr->bus_if;
BRCMF_DBG(TEMP, "About to add if_dev");
- result = brcmf_bus_device_add(bus, device->phy_zxdev, &args, &device->if_zxdev);
+ result = brcmf_bus_device_add(bus, drvr->phy_zxdev, &args, &drvr->if_zxdev);
if (result != ZX_OK) {
BRCMF_ERR("Failed to device_add: %s", zx_status_get_string(result));
return result;
@@ -591,23 +584,19 @@
ndev->needed_headroom += drvr->hdrlen;
workqueue_init_work(&ifp->multicast_work, _brcmf_set_multicast_list);
- device_make_visible(ifp->drvr->bus_if->dev->phy_zxdev);
-
- BRCMF_DBG(TEMP, "device_make_visible() succeeded. Activated phy hooks.\n");
-
return ZX_OK;
}
static void brcmf_net_detach(struct net_device* ndev, bool rtnl_locked) {
- struct brcmf_device* device = ndev_to_dev(ndev);
+ brcmf_pub* drvr = ndev_to_pub(ndev);
// TODO(cphoenix): Make sure devices are removed and memory is freed properly. This code
// is probably wrong. See WLAN-1057.
brcmf_free_net_device_vif(ndev);
brcmf_free_net_device(ndev);
- if (device->phy_zxdev != NULL) {
- device_remove(device->phy_zxdev);
- device->phy_zxdev = NULL;
+ if (drvr->phy_zxdev != NULL) {
+ device_remove(drvr->phy_zxdev);
+ drvr->phy_zxdev = NULL;
}
}
@@ -787,52 +776,36 @@
brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
}
-zx_status_t brcmf_attach(struct brcmf_device* dev, struct brcmf_mp_device* settings) {
+zx_status_t brcmf_attach(brcmf_pub* drvr, brcmf_bus* bus_if, brcmf_mp_device* settings) {
zx_status_t ret = ZX_OK;
- int i;
BRCMF_DBG(TRACE, "Enter\n");
- /* Allocate primary brcmf_info */
- auto drvr = std::make_unique<struct brcmf_pub>();
- if (!drvr) {
- return ZX_ERR_NO_MEMORY;
- }
-
- for (i = 0; i < (int)countof(drvr->if2bss); i++) {
- drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
- }
-
- mtx_init(&drvr->proto_block, mtx_plain);
-
/* Link to bus module */
drvr->hdrlen = 0;
- drvr->bus_if = dev_to_bus(dev);
+ drvr->bus_if = bus_if;
drvr->settings = settings;
/* Attach and link in the protocol */
- ret = brcmf_proto_attach(drvr.get());
+ ret = brcmf_proto_attach(drvr);
if (ret != ZX_OK) {
BRCMF_ERR("brcmf_prot_attach failed\n");
goto fail;
}
/* attach firmware event handler */
- brcmf_fweh_attach(drvr.get());
-
- drvr->bus_if->drvr = std::move(drvr);
+ brcmf_fweh_attach(drvr);
return ret;
fail:
- brcmf_detach(dev);
+ brcmf_detach(drvr);
return ret;
}
-zx_status_t brcmf_bus_started(struct brcmf_device* dev) {
+zx_status_t brcmf_bus_started(brcmf_pub* drvr) {
zx_status_t ret = ZX_ERR_IO;
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_pub* drvr = bus_if->drvr.get();
+ struct brcmf_bus* bus_if = drvr->bus_if;
struct brcmf_if* ifp;
struct brcmf_if* p2p_ifp;
zx_status_t err;
@@ -871,7 +844,7 @@
brcmf_proto_add_if(drvr, ifp);
- drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev, drvr->settings->p2p_enable);
+ drvr->config = brcmf_cfg80211_attach(drvr);
if (drvr->config == NULL) {
ret = ZX_ERR_IO;
goto fail;
@@ -911,19 +884,13 @@
return ret;
}
-void brcmf_bus_add_txhdrlen(struct brcmf_device* dev, uint len) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_pub* drvr = bus_if->drvr.get();
-
+void brcmf_bus_add_txhdrlen(brcmf_pub* drvr, uint len) {
if (drvr) {
drvr->hdrlen += len;
}
}
-void brcmf_dev_reset(struct brcmf_device* dev) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_pub* drvr = bus_if->drvr.get();
-
+void brcmf_dev_reset(brcmf_pub* drvr) {
if (drvr == NULL) {
return;
}
@@ -933,11 +900,8 @@
}
}
-void brcmf_detach(struct brcmf_device* dev) {
+void brcmf_detach(brcmf_pub* drvr) {
int32_t i;
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_pub* drvr = bus_if->drvr.get();
-
BRCMF_DBG(TRACE, "Enter\n");
if (drvr == NULL) {
@@ -947,7 +911,7 @@
/* stop firmware event handling */
brcmf_fweh_detach(drvr);
- brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
+ brcmf_bus_change_state(drvr->bus_if, BRCMF_BUS_DOWN);
/* make sure primary interface removed last */
for (i = BRCMF_MAX_IFS - 1; i > -1; i--) {
@@ -959,14 +923,11 @@
brcmf_bus_stop(drvr->bus_if);
brcmf_proto_detach(drvr);
-
- bus_if->drvr.reset();
}
-zx_status_t brcmf_iovar_data_set(struct brcmf_device* dev, const char* name, void* data,
+zx_status_t brcmf_iovar_data_set(brcmf_pub* drvr, const char* name, void* data,
uint32_t len, int32_t* fwerr_ptr) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_if* ifp = bus_if->drvr->iflist[0];
+ struct brcmf_if* ifp = drvr->iflist[0];
return brcmf_fil_iovar_data_set(ifp, name, data, len, fwerr_ptr);
}
@@ -1012,13 +973,14 @@
}
void brcmf_bus_change_state(struct brcmf_bus* bus, enum brcmf_bus_state state) {
- struct brcmf_pub* drvr = bus->drvr.get();
- struct net_device* ndev;
- int ifidx;
-
BRCMF_DBG(TRACE, "%d -> %d\n", bus->state, state);
bus->state = state;
+#if 0
+ struct brcmf_pub* drvr = bus->priv.sdio->drvr.get();
+ struct net_device* ndev;
+ int ifidx;
+
if (state == BRCMF_BUS_UP) {
for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {
if ((drvr->iflist[ifidx]) && (drvr->iflist[ifidx]->ndev)) {
@@ -1029,23 +991,5 @@
}
}
}
+#endif
}
-
-zx_status_t brcmf_core_init(struct brcmf_device* device) {
- pthread_mutexattr_t pmutex_attributes;
- zx_status_t result;
-
- BRCMF_DBG(TEMP, "brcmfmac: core_init was called\n");
-
- pthread_mutexattr_init(&pmutex_attributes);
- pthread_mutexattr_settype(&pmutex_attributes, PTHREAD_MUTEX_NORMAL | PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&irq_callback_lock, &pmutex_attributes);
-
- result = brcmf_bus_register(device);
- if (result != ZX_OK) {
- BRCMF_ERR("Bus registration failed: %s\n", zx_status_get_string(result));
- }
- return result;
-}
-
-void brcmf_core_exit(struct brcmf_device* device) { brcmf_bus_exit(device); }
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h
index b4e941c..d44a9ae 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h
@@ -23,14 +23,16 @@
#include <threads.h>
#include <atomic>
+#include <mutex>
#include <ddk/protocol/ethernet.h>
#include <ddk/protocol/wlanphyimpl.h>
+#include <lib/async/dispatcher.h>
#include <netinet/if_ether.h>
#include <lib/sync/completion.h>
#include <wlan/protocol/if-impl.h>
-#include "device.h"
+#include "bus.h"
#include "fweh.h"
#include "linuxisms.h"
#include "netbuf.h"
@@ -39,6 +41,8 @@
#define TOE_TX_CSUM_OL 0x00000001
#define TOE_RX_CSUM_OL 0x00000002
+#define BRCMF_BSSIDX_INVALID -1
+
/* For supporting multiple interfaces */
#define BRCMF_MAX_IFS 16
@@ -125,6 +129,12 @@
/* Common structure for module and instance linkage */
struct brcmf_pub {
+ zx_device_t* zxdev;
+ zx_device_t* phy_zxdev;
+ zx_device_t* if_zxdev;
+ async_dispatcher_t* dispatcher;
+ std::recursive_mutex irq_callback_lock;
+
/* Linkage ponters */
struct brcmf_bus* bus_if;
struct brcmf_proto* proto;
@@ -142,7 +152,7 @@
struct brcmf_if* iflist[BRCMF_MAX_IFS];
int32_t if2bss[BRCMF_MAX_IFS];
- mtx_t proto_block;
+ std::mutex proto_block;
unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
struct brcmf_fweh_info fweh;
@@ -240,8 +250,6 @@
void brcmf_txfinalize(struct brcmf_if* ifp, struct brcmf_netbuf* txp, bool success);
void brcmf_netif_rx(struct brcmf_if* ifp, struct brcmf_netbuf* netbuf);
void brcmf_net_setcarrier(struct brcmf_if* ifp, bool on);
-zx_status_t brcmf_core_init(struct brcmf_device* dev);
-void brcmf_core_exit(struct brcmf_device* dev);
// Used in net_device.flags to indicate interface is up.
#define IFF_UP 1
@@ -281,4 +289,28 @@
zx_status_t brcmf_phy_destroy_iface(void* ctx, uint16_t id);
zx_status_t brcmf_phy_set_country(void* ctx, const wlanphy_country_t* country);
+/*
+ * interface functions from common layer
+ */
+
+/* Receive frame for delivery to OS. Callee disposes of rxp. */
+void brcmf_rx_frame(brcmf_pub* drvr, brcmf_netbuf* rxp, bool handle_event);
+/* Receive async event packet from firmware. Callee disposes of rxp. */
+void brcmf_rx_event(brcmf_pub* drvr, brcmf_netbuf* rxp);
+
+/* Indication from bus module regarding presence/insertion of dongle. */
+zx_status_t brcmf_attach(brcmf_pub* drvr, brcmf_bus* bus_if, brcmf_mp_device* settings);
+/* Indication from bus module regarding removal/absence of dongle */
+void brcmf_detach(brcmf_pub* drvr);
+/* Indication from bus module that dongle should be reset */
+void brcmf_dev_reset(brcmf_pub* drvr);
+
+/* Configure the "global" bus state used by upper layers */
+void brcmf_bus_change_state(brcmf_bus* bus, enum brcmf_bus_state state);
+
+zx_status_t brcmf_bus_started(brcmf_pub* drvr);
+zx_status_t brcmf_iovar_data_set(brcmf_pub* drvr, const char* name, void* data, uint32_t len,
+ int32_t* fwerr_ptr);
+void brcmf_bus_add_txhdrlen(brcmf_pub* drvr, uint len);
+
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_CORE_H_
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.cc
index 7d7eef9..9bbeb52 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.cc
@@ -1,71 +1,110 @@
-/*
- * Copyright (c) 2018 The Fuchsia Authors
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
+// Copyright (c) 2019 The Fuchsia Authors
+//
+// Permission to use, copy, modify, and/or distribute this software for any purpose with or without
+// fee is hereby granted, provided that the above copyright notice and this permission notice
+// appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+// SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+// OF THIS SOFTWARE.
-#include "device.h"
+#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h"
-#include <lib/async/time.h> // for async_now()
+#include <zircon/status.h>
-#include "debug.h"
+#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/debug.h"
-pthread_mutex_t irq_callback_lock;
+namespace wlan {
+namespace brcmfmac {
-async_dispatcher_t* default_dispatcher;
+// static
+zx_status_t Device::Create(zx_device_t* parent_device, Device** device_out) {
+ zx_status_t status = ZX_OK;
-static void brcmf_timer_handler(async_dispatcher_t* dispatcher, async_task_t* task,
- zx_status_t status) {
- if (status != ZX_OK) {
- return;
+ auto dispatcher = std::make_unique<::async::Loop>(&kAsyncLoopConfigNoAttachToThread);
+ if ((status = dispatcher->StartThread("brcmfmac-worker", nullptr)) != ZX_OK) {
+ return status;
}
- brcmf_timer_info_t* timer = containerof(task, brcmf_timer_info_t, task);
- timer->callback_function(timer->data);
- mtx_lock(&timer->lock);
- timer->scheduled = false;
- sync_completion_signal(&timer->finished);
- mtx_unlock(&timer->lock);
-}
-void brcmf_timer_init(brcmf_timer_info_t* timer, brcmf_timer_callback_t* callback, void* data) {
- memset(&timer->task.state, 0, sizeof(timer->task.state));
- timer->task.handler = brcmf_timer_handler;
- timer->data = data;
- timer->callback_function = callback;
- timer->finished = {};
- timer->scheduled = false;
- mtx_init(&timer->lock, mtx_plain);
-}
-
-void brcmf_timer_set(brcmf_timer_info_t* timer, zx_duration_t delay) {
- mtx_lock(&timer->lock);
- async_cancel_task(default_dispatcher, &timer->task); // Make sure it's not scheduled
- timer->task.deadline = delay + async_now(default_dispatcher);
- timer->scheduled = true;
- sync_completion_reset(&timer->finished);
- async_post_task(default_dispatcher, &timer->task);
- mtx_unlock(&timer->lock);
-}
-
-void brcmf_timer_stop(brcmf_timer_info_t* timer) {
- mtx_lock(&timer->lock);
- if (!timer->scheduled) {
- mtx_unlock(&timer->lock);
- return;
+ const auto ddk_remover = [](Device* device) { device->DdkRemove(); };
+ std::unique_ptr<Device, decltype(ddk_remover)> device(new Device(parent_device), ddk_remover);
+ if ((status = device->DdkAdd("brcmfmac-wlanphy", DEVICE_ADD_INVISIBLE)) != ZX_OK) {
+ delete device.release();
+ return status;
}
- zx_status_t result = async_cancel_task(default_dispatcher, &timer->task);
- mtx_unlock(&timer->lock);
- if (result != ZX_OK) {
- sync_completion_wait(&timer->finished, ZX_TIME_INFINITE);
+
+ auto pub = std::make_unique<brcmf_pub>();
+ pub->zxdev = parent_device;
+ pub->phy_zxdev = device->zxdev();
+ pub->dispatcher = dispatcher->dispatcher();
+ for (auto& entry : pub->if2bss) {
+ entry = BRCMF_BSSIDX_INVALID;
+ }
+
+ std::unique_ptr<brcmf_bus> bus;
+ if ((status = brcmf_bus_register(pub.get(), &bus)) != ZX_OK) {
+ BRCMF_ERR("brcmf_bus_register() returned %s\n", zx_status_get_string(status));
+ return status;
+ }
+
+ device->dispatcher_ = std::move(dispatcher);
+ device->brcmf_pub_ = std::move(pub);
+ device->brcmf_bus_ = std::move(bus);
+ device->DdkMakeVisible();
+
+ if (device_out != nullptr) {
+ *device_out = device.get();
+ }
+ device.release(); // This now has its lifecycle managed by the devhost.
+ return ZX_OK;
+}
+
+void Device::SimUnbind() {
+ // Simulate the devhost unbind/remove process.
+ DdkUnbind();
+
+ // device_remove() on this device causes the equivalent of Unbind() to be invoked on its children.
+ brcmf_phy_destroy_iface(brcmf_pub_->iflist[0], 0);
+
+ // Now this device is released.
+ DdkRelease();
+}
+
+void Device::DdkUnbind() { DdkRemove(); }
+
+void Device::DdkRelease() { delete this; }
+
+zx_status_t Device::WlanphyImplQuery(wlanphy_impl_info_t* out_info) {
+ return brcmf_phy_query(brcmf_pub_->iflist[0], out_info);
+}
+
+zx_status_t Device::WlanphyImplCreateIface(const wlanphy_impl_create_iface_req_t* req,
+ uint16_t* out_iface_id) {
+ return brcmf_phy_create_iface(brcmf_pub_->iflist[0], req, out_iface_id);
+}
+
+zx_status_t Device::WlanphyImplDestroyIface(uint16_t iface_id) {
+ return brcmf_phy_destroy_iface(brcmf_pub_->iflist[0], iface_id);
+}
+
+zx_status_t Device::WlanphyImplSetCountry(const wlanphy_country_t* country) {
+ return brcmf_phy_set_country(brcmf_pub_->iflist[0], country);
+}
+
+Device::Device(zx_device_t* parent) : ::ddk::Device<Device, ::ddk::Unbindable>(parent) {}
+
+Device::~Device() {
+ // Make sure any asynchronous work is stopped first.
+ if (dispatcher_ != nullptr) {
+ dispatcher_->Shutdown();
+ }
+ if (brcmf_bus_ != nullptr) {
+ brcmf_bus_exit(brcmf_bus_.get());
}
}
+
+} // namespace brcmfmac
+} // namespace wlan
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h
index 88d772c..c57e3df 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h
@@ -1,69 +1,73 @@
-/*
- * Copyright (c) 2018 The Fuchsia Authors
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
+// Copyright (c) 2019 The Fuchsia Authors
+//
+// Permission to use, copy, modify, and/or distribute this software for any purpose with or without
+// fee is hereby granted, provided that the above copyright notice and this permission notice
+// appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+// SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+// OF THIS SOFTWARE.
#ifndef SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_DEVICE_H_
#define SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_DEVICE_H_
-#include <lib/async-loop/loop.h> // to start the worker thread
-#include <lib/async/task.h> // for async_post_task()
-#include <lib/sync/completion.h>
-#include <pthread.h>
+#include <lib/async-loop/cpp/loop.h>
#include <zircon/types.h>
#include <memory>
#include <ddk/device.h>
+#include <ddktl/device.h>
+#include <ddktl/protocol/wlanphyimpl.h>
-extern async_dispatcher_t* default_dispatcher;
+#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/bus.h"
+#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h"
-// This is the function that timer users write to receive callbacks.
-typedef void(brcmf_timer_callback_t)(void* data);
+namespace wlan {
+namespace brcmfmac {
-typedef struct brcmf_timer_info {
- async_task_t task;
- void* data;
- brcmf_timer_callback_t* callback_function;
- bool scheduled;
- sync_completion_t finished;
- mtx_t lock;
-} brcmf_timer_info_t;
+// This class uses the DDKTL classes to manage the lifetime of a brcmfmac driver instance.
+class Device : public ::ddk::Device<Device, ::ddk::Unbindable>,
+ public ::ddk::WlanphyImplProtocol<Device, ::ddk::base_protocol> {
+ public:
+ // Static factory function for Device instances. This factory does not return an owned instance,
+ // as on successful invocation the instance will have its lifecycle maanged by the devhost.
+ static zx_status_t Create(zx_device_t* parent_device, Device** device_out);
+ explicit Device(std::unique_ptr<::async::Loop> dispatcher, std::unique_ptr<brcmf_pub> brcmf_pub,
+ std::unique_ptr<brcmf_bus> brcmf_bus);
-void brcmf_timer_init(brcmf_timer_info_t* timer, brcmf_timer_callback_t* callback, void* data);
+ Device(const Device& device) = delete;
+ Device& operator=(const Device& other) = delete;
-void brcmf_timer_set(brcmf_timer_info_t* timer, zx_duration_t delay);
+ // For testing: unbind this instance explicitly, when no devhost is available. After this call,
+ // the instance is deleted.
+ void SimUnbind();
-void brcmf_timer_stop(brcmf_timer_info_t* timer);
+ // DDK interface implementation.
+ void DdkUnbind();
+ void DdkRelease();
-struct brcmf_bus;
+ // WlanphyImpl protocol implementation.
+ zx_status_t WlanphyImplQuery(wlanphy_impl_info_t* out_info);
+ zx_status_t WlanphyImplCreateIface(const wlanphy_impl_create_iface_req_t* req,
+ uint16_t* out_iface_id);
+ zx_status_t WlanphyImplDestroyIface(uint16_t iface_id);
+ zx_status_t WlanphyImplSetCountry(const wlanphy_country_t* country);
-struct brcmf_device {
- void* of_node;
- void* parent;
- std::unique_ptr<struct brcmf_bus> bus;
- zx_device_t* zxdev;
- zx_device_t* phy_zxdev;
- zx_device_t* if_zxdev;
+ protected:
+ explicit Device(zx_device_t* parent);
+ ~Device();
+
+ private:
+ std::unique_ptr<::async::Loop> dispatcher_;
+ std::unique_ptr<brcmf_pub> brcmf_pub_;
+ std::unique_ptr<brcmf_bus> brcmf_bus_;
};
-static inline struct brcmf_bus* dev_to_bus(struct brcmf_device* dev) { return dev->bus.get(); }
-
-// TODO(cphoenix): Wrap around whatever completion functions exist in PCIE and SDIO.
-// TODO(cphoenix): To improve efficiency, analyze which spinlocks only need to protect small
-// critical subsections of the completion functions. For those, bring back the individual spinlock.
-// Note: This is a pthread_mutex_t instead of mtx_t because mtx_t doesn't implement recursive.
-extern pthread_mutex_t irq_callback_lock;
+} // namespace brcmfmac
+} // namespace wlan
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_DEVICE_H_
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.cc
index 1088509..f6ac568 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.cc
@@ -22,7 +22,6 @@
#include "common.h"
#include "core.h"
#include "debug.h"
-#include "device.h"
#include "linuxisms.h"
#define BRCMF_FW_MAX_NVRAM_SIZE 64000
@@ -30,6 +29,8 @@
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */
#define BRCMF_FW_DEFAULT_BOARDREV "boardrev=0xff"
+constexpr char kDefaultFirmwarePath[] = "brcmfmac/";
+
enum nvram_parser_state { IDLE, KEY, VALUE, COMMENT, END };
/**
@@ -425,13 +426,13 @@
void brcmf_fw_nvram_free(void* nvram) { free(nvram); }
struct brcmf_fw {
- struct brcmf_device* dev;
+ brcmf_pub* drvr;
uint16_t flags;
const struct brcmf_firmware* code;
const char* nvram_name;
uint16_t domain_nr;
uint16_t bus_nr;
- void (*done)(struct brcmf_device* dev, zx_status_t err, const struct brcmf_firmware* fw,
+ void (*done)(brcmf_pub* drvr, zx_status_t err, const struct brcmf_firmware* fw,
void* nvram_image, uint32_t nvram_len);
};
@@ -443,7 +444,7 @@
size_t data_len;
bool raw_nvram;
- BRCMF_DBG(TRACE, "enter: dev=%s\n", device_get_name(fwctx->dev->zxdev));
+ BRCMF_DBG(TRACE, "enter: dev=%s\n", device_get_name(fwctx->drvr->zxdev));
if (fw && fw->data) {
data = (uint8_t*)fw->data;
data_len = fw->size;
@@ -466,26 +467,24 @@
goto fail;
}
- fwctx->done(fwctx->dev, ZX_OK, fwctx->code, nvram, nvram_length);
+ fwctx->done(fwctx->drvr, ZX_OK, fwctx->code, nvram, nvram_length);
free(fwctx);
return ZX_OK;
fail:
- BRCMF_DBG(TRACE, "failed: dev=%s\n", device_get_name(fwctx->dev->zxdev));
- fwctx->done(fwctx->dev, ZX_ERR_NOT_FOUND, NULL, NULL, 0);
+ BRCMF_DBG(TRACE, "failed: dev=%s\n", device_get_name(fwctx->drvr->zxdev));
+ fwctx->done(fwctx->drvr, ZX_ERR_NOT_FOUND, NULL, NULL, 0);
free(fwctx);
return ZX_ERR_NO_RESOURCES;
}
-zx_status_t request_firmware_nowait(bool b, const char* name, struct brcmf_device* dev,
- struct brcmf_fw* ctx,
- zx_status_t (*callback)(const struct brcmf_firmware* fw,
- void* ctx)) {
+zx_status_t request_firmware_nowait(bool b, const char* name, brcmf_pub* drvr, brcmf_fw* ctx,
+ zx_status_t (*callback)(const brcmf_firmware* fw, void* ctx)) {
zx_status_t result;
zx_handle_t fw_vmo;
struct brcmf_firmware fw;
- result = load_firmware(dev->zxdev, name, &fw_vmo, &fw.size);
+ result = load_firmware(drvr->zxdev, name, &fw_vmo, &fw.size);
BRCMF_DBG(TEMP, "load_firmware of '%s' -> ret %d, size %ld", name, result, fw.size);
if (result != ZX_OK) {
return result;
@@ -514,7 +513,7 @@
struct brcmf_fw* fwctx = static_cast<decltype(fwctx)>(ctx);
zx_status_t result = ZX_OK;
- BRCMF_DBG(TRACE, "enter: dev=%s\n", device_get_name(fwctx->dev->zxdev));
+ BRCMF_DBG(TRACE, "enter: dev=%s\n", device_get_name(fwctx->drvr->zxdev));
if (!fw) {
result = ZX_ERR_INVALID_ARGS;
goto fail;
@@ -525,7 +524,7 @@
}
fwctx->code = fw;
- result = request_firmware_nowait(true, fwctx->nvram_name, fwctx->dev, fwctx,
+ result = request_firmware_nowait(true, fwctx->nvram_name, fwctx->drvr, fwctx,
brcmf_fw_request_nvram_done);
/* pass NULL to nvram callback for bcm47xx fallback */
@@ -535,22 +534,22 @@
return result;
fail:
- BRCMF_DBG(TRACE, "failed: dev=%s\n", device_get_name(fwctx->dev->zxdev));
+ BRCMF_DBG(TRACE, "failed: dev=%s\n", device_get_name(fwctx->drvr->zxdev));
done:
- fwctx->done(fwctx->dev, result, fw, NULL, 0);
+ fwctx->done(fwctx->drvr, result, fw, NULL, 0);
free(fwctx);
return result;
}
-zx_status_t brcmf_fw_get_firmwares_pcie(struct brcmf_device* dev, uint16_t flags, const char* code,
+zx_status_t brcmf_fw_get_firmwares_pcie(brcmf_pub* drvr, uint16_t flags, const char* code,
const char* nvram,
- void (*fw_cb)(struct brcmf_device* dev, zx_status_t err,
- const struct brcmf_firmware* fw,
- void* nvram_image, uint32_t nvram_len),
+ void (*fw_cb)(brcmf_pub* drvr, zx_status_t err,
+ const brcmf_firmware* fw, void* nvram_image,
+ uint32_t nvram_len),
uint16_t domain_nr, uint16_t bus_nr) {
struct brcmf_fw* fwctx;
- BRCMF_DBG(TRACE, "enter: dev=%s\n", device_get_name(dev->zxdev));
+ BRCMF_DBG(TRACE, "enter: dev=%s\n", device_get_name(drvr->zxdev));
if (!fw_cb || !code) {
return ZX_ERR_INVALID_ARGS;
}
@@ -564,7 +563,7 @@
return ZX_ERR_NO_MEMORY;
}
- fwctx->dev = dev;
+ fwctx->drvr = drvr;
fwctx->flags = flags;
fwctx->done = fw_cb;
if (flags & BRCMF_FW_REQUEST_NVRAM) {
@@ -573,15 +572,15 @@
fwctx->domain_nr = domain_nr;
fwctx->bus_nr = bus_nr;
- return request_firmware_nowait(true, code, dev, fwctx, brcmf_fw_request_code_done);
+ return request_firmware_nowait(true, code, drvr, fwctx, brcmf_fw_request_code_done);
}
-zx_status_t brcmf_fw_get_firmwares(struct brcmf_device* dev, uint16_t flags, const char* code,
+zx_status_t brcmf_fw_get_firmwares(brcmf_pub* drvr, uint16_t flags, const char* code,
const char* nvram,
- void (*fw_cb)(struct brcmf_device* dev, zx_status_t err,
- const struct brcmf_firmware* fw, void* nvram_image,
+ void (*fw_cb)(brcmf_pub* drvr, zx_status_t err,
+ const brcmf_firmware* fw, void* nvram_image,
uint32_t nvram_len)) {
- return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0, 0);
+ return brcmf_fw_get_firmwares_pcie(drvr, flags, code, nvram, fw_cb, 0, 0);
}
zx_status_t brcmf_fw_map_chip_to_name(uint32_t chip, uint32_t chiprev,
@@ -603,13 +602,13 @@
}
/* check if firmware path is provided by module parameter */
- if (brcmf_mp_global.firmware_path[0] != '\0') {
- strlcpy(fw_name, brcmf_mp_global.firmware_path, BRCMF_FW_NAME_LEN);
+ if (kDefaultFirmwarePath[0] != '\0') {
+ strlcpy(fw_name, kDefaultFirmwarePath, BRCMF_FW_NAME_LEN);
if ((nvram_name) && (mapping_table[i].nvram)) {
- strlcpy(nvram_name, brcmf_mp_global.firmware_path, BRCMF_FW_NAME_LEN);
+ strlcpy(nvram_name, kDefaultFirmwarePath, BRCMF_FW_NAME_LEN);
}
- end = brcmf_mp_global.firmware_path[strlen(brcmf_mp_global.firmware_path) - 1];
+ end = kDefaultFirmwarePath[strlen(kDefaultFirmwarePath) - 1];
if (end != '/') {
strlcat(fw_name, "/", BRCMF_FW_NAME_LEN);
if ((nvram_name) && (mapping_table[i].nvram)) {
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.h
index 7ffa723..c83b801 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/firmware.h
@@ -17,7 +17,6 @@
#define SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_FIRMWARE_H_
#include "common.h"
-#include "device.h"
#include "linuxisms.h"
// clang-format off
@@ -78,16 +77,16 @@
* fails it will not use the callback, but call device_release_driver()
* instead which will call the driver .remove() callback.
*/
-zx_status_t brcmf_fw_get_firmwares_pcie(struct brcmf_device* dev, uint16_t flags, const char* code,
+zx_status_t brcmf_fw_get_firmwares_pcie(brcmf_pub* drvr, uint16_t flags, const char* code,
const char* nvram,
- void (*fw_cb)(struct brcmf_device* dev, zx_status_t err,
- const struct brcmf_firmware* fw,
- void* nvram_image, uint32_t nvram_len),
+ void (*fw_cb)(brcmf_pub* drvr, zx_status_t err,
+ const brcmf_firmware* fw, void* nvram_image,
+ uint32_t nvram_len),
uint16_t domain_nr, uint16_t bus_nr);
-zx_status_t brcmf_fw_get_firmwares(struct brcmf_device* dev, uint16_t flags, const char* code,
+zx_status_t brcmf_fw_get_firmwares(brcmf_pub* drvr, uint16_t flags, const char* code,
const char* nvram,
- void (*fw_cb)(struct brcmf_device* dev, zx_status_t err,
- const struct brcmf_firmware* fw, void* nvram_image,
+ void (*fw_cb)(brcmf_pub* drvr, zx_status_t err,
+ const brcmf_firmware* fw, void* nvram_image,
uint32_t nvram_len));
#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_FIRMWARE_H_
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fweh.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fweh.cc
index 033c3654..7b5d4f6 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fweh.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fweh.cc
@@ -24,7 +24,6 @@
#include "cfg80211.h"
#include "core.h"
#include "debug.h"
-#include "device.h"
#include "fwil.h"
#include "linuxisms.h"
#include "proto.h"
@@ -89,13 +88,14 @@
* @fweh: firmware event handling info.
* @event: event queue entry.
*/
-static void brcmf_fweh_queue_event(struct brcmf_fweh_info* fweh,
- struct brcmf_fweh_queue_item* event) {
+static void brcmf_fweh_queue_event(brcmf_pub* drvr,
+ brcmf_fweh_info* fweh,
+ brcmf_fweh_queue_item* event) {
// spin_lock_irqsave(&fweh->evt_q_lock, flags);
- pthread_mutex_lock(&irq_callback_lock);
+ drvr->irq_callback_lock.lock();
list_add_tail(&fweh->event_q, &event->q);
// spin_unlock_irqrestore(&fweh->evt_q_lock, flags);
- pthread_mutex_unlock(&irq_callback_lock);
+ drvr->irq_callback_lock.unlock();
workqueue_schedule_default(&fweh->event_work);
}
@@ -194,17 +194,18 @@
*
* @fweh: firmware event handling info.
*/
-static struct brcmf_fweh_queue_item* brcmf_fweh_dequeue_event(struct brcmf_fweh_info* fweh) {
+static struct brcmf_fweh_queue_item* brcmf_fweh_dequeue_event(brcmf_pub* drvr,
+ brcmf_fweh_info* fweh) {
struct brcmf_fweh_queue_item* event = NULL;
// spin_lock_irqsave(&fweh->evt_q_lock, flags);
- pthread_mutex_lock(&irq_callback_lock);
+ drvr->irq_callback_lock.lock();
if (!list_is_empty(&fweh->event_q)) {
event = list_peek_head_type(&fweh->event_q, struct brcmf_fweh_queue_item, q);
list_delete(&event->q);
}
// spin_unlock_irqrestore(&fweh->evt_q_lock, flags);
- pthread_mutex_unlock(&irq_callback_lock);
+ drvr->irq_callback_lock.unlock();
return event;
}
@@ -226,7 +227,7 @@
fweh = containerof(work, struct brcmf_fweh_info, event_work);
drvr = containerof(fweh, struct brcmf_pub, fweh);
- while ((event = brcmf_fweh_dequeue_event(fweh))) {
+ while ((event = brcmf_fweh_dequeue_event(drvr, fweh))) {
BRCMF_DBG(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n",
brcmf_fweh_event_name(event->code), event->code, event->emsg.ifidx,
event->emsg.bsscfgidx, event->emsg.addr);
@@ -429,5 +430,5 @@
memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN);
// BRCMF_DBG(TEMP, "Queueing event!");
- brcmf_fweh_queue_event(fweh, event);
+ brcmf_fweh_queue_event(drvr, fweh, event);
}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwil.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwil.cc
index ead38af..6ed30e6 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwil.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwil.cc
@@ -142,13 +142,13 @@
int32_t* fwerr_ptr) {
zx_status_t err;
- mtx_lock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.lock();
BRCMF_DBG(FIL, "ifidx=%d, cmd=%d, len=%d\n", ifp->ifidx, cmd, len);
BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(FIL), data, min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
err = brcmf_fil_cmd_data(ifp, cmd, data, len, true, fwerr_ptr);
- mtx_unlock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.unlock();
return err;
}
@@ -157,13 +157,13 @@
int32_t* fwerr_ptr) {
zx_status_t err;
- mtx_lock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.lock();
err = brcmf_fil_cmd_data(ifp, cmd, data, len, false, fwerr_ptr);
BRCMF_DBG(FIL, "ifidx=%d, cmd=%d, len=%d\n", ifp->ifidx, cmd, len);
BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(FIL), data, min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
- mtx_unlock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.unlock();
return err;
}
@@ -173,10 +173,10 @@
zx_status_t err;
uint32_t data_le = data;
- mtx_lock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.lock();
BRCMF_DBG(FIL, "ifidx=%d, cmd=%d, value=%d\n", ifp->ifidx, cmd, data);
err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), true, fwerr_ptr);
- mtx_unlock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.unlock();
return err;
}
@@ -186,9 +186,9 @@
zx_status_t err;
uint32_t data_le = *data;
- mtx_lock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.lock();
err = brcmf_fil_cmd_data(ifp, cmd, &data_le, sizeof(data_le), false, fwerr_ptr);
- mtx_unlock(&ifp->drvr->proto_block);
+ ifp->drvr->proto_block.unlock();
*data = data_le;
BRCMF_DBG(FIL, "ifidx=%d, cmd=%d, value=%d\n", ifp->ifidx, cmd, *data);
@@ -221,7 +221,7 @@
zx_status_t err;
uint32_t buflen;
- mtx_lock(&drvr->proto_block);
+ drvr->proto_block.lock();
BRCMF_DBG(FIL, "ifidx=%d, name=%s, len=%d\n", ifp->ifidx, name, len);
BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(FIL), data, min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
@@ -234,7 +234,7 @@
BRCMF_ERR("Creating iovar failed\n");
}
- mtx_unlock(&drvr->proto_block);
+ drvr->proto_block.unlock();
return err;
}
@@ -244,7 +244,7 @@
zx_status_t err;
uint32_t buflen;
- mtx_lock(&drvr->proto_block);
+ drvr->proto_block.lock();
buflen = brcmf_create_iovar(name, data, len, (char*)drvr->proto_buf, sizeof(drvr->proto_buf));
if (buflen) {
@@ -260,7 +260,7 @@
BRCMF_DBG(FIL, "ifidx=%d, name=%s, len=%d\n", ifp->ifidx, name, len);
BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(FIL), data, min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
- mtx_unlock(&drvr->proto_block);
+ drvr->proto_block.unlock();
return err;
}
@@ -334,7 +334,7 @@
zx_status_t err;
uint32_t buflen;
- mtx_lock(&drvr->proto_block);
+ drvr->proto_block.lock();
BRCMF_DBG(FIL, "ifidx=%d, bsscfgidx=%d, name=%s, len=%d\n", ifp->ifidx, ifp->bsscfgidx, name,
len);
@@ -349,7 +349,7 @@
BRCMF_ERR("Creating bsscfg failed\n");
}
- mtx_unlock(&drvr->proto_block);
+ drvr->proto_block.unlock();
return err;
}
@@ -359,7 +359,7 @@
zx_status_t err;
uint32_t buflen;
- mtx_lock(&drvr->proto_block);
+ drvr->proto_block.lock();
buflen = brcmf_create_bsscfg(ifp->bsscfgidx, name, data, len, (char*)drvr->proto_buf,
sizeof(drvr->proto_buf));
@@ -376,7 +376,7 @@
len);
BRCMF_DBG_HEX_DUMP(BRCMF_IS_ON(FIL), data, min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
- mtx_unlock(&drvr->proto_block);
+ drvr->proto_block.unlock();
return err;
}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwsignal.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwsignal.cc
index 37db696..4e6ac61 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwsignal.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/fwsignal.cc
@@ -26,7 +26,6 @@
#include "common.h"
#include "core.h"
#include "debug.h"
-#include "device.h"
#include "fweh.h"
#include "fwil.h"
#include "fwil_types.h"
@@ -545,12 +544,12 @@
static void brcmf_fws_lock(struct brcmf_fws_info* fws) { // __TA_ACQUIRE(&fws->spinlock) {
// spin_lock_irqsave(&fws->spinlock, fws->flags);
- pthread_mutex_lock(&irq_callback_lock);
+ fws->drvr->irq_callback_lock.lock();
}
static void brcmf_fws_unlock(struct brcmf_fws_info* fws) { // __TA_RELEASE(&fws->spinlock) {
// spin_unlock_irqrestore(&fws->spinlock, fws->flags);
- pthread_mutex_unlock(&irq_callback_lock);
+ fws->drvr->irq_callback_lock.unlock();
}
static bool brcmf_fws_ifidx_match(struct brcmf_netbuf* netbuf, void* arg) {
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/linuxisms.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/linuxisms.h
index 6f758bd..c9ddb8f 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/linuxisms.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/linuxisms.h
@@ -364,7 +364,6 @@
const struct wiphy_vendor_command* vendor_commands;
uint8_t perm_addr[ETH_ALEN];
struct brcmf_cfg80211_info* cfg80211_info;
- struct brcmf_device* dev;
};
struct vif_params {
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/of.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/of.cc
deleted file mode 100644
index 9f46b67..0000000
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/of.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2014 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "of.h"
-
-#include "common.h"
-#include "core.h"
-#include "debug.h"
-#include "defs.h"
-#include "device.h"
-#include "linuxisms.h"
-
-void brcmf_of_probe(struct brcmf_device* dev, enum brcmf_bus_type bus_type,
- struct brcmf_mp_device* settings) {
- struct brcmfmac_sdio_pd* sdio = &settings->bus.sdio;
- struct device_node* np = static_cast<decltype(np)>(dev->of_node);
- int irq;
- uint32_t irqf;
- uint32_t val;
-
- if (!np || bus_type != BRCMF_BUS_TYPE_SDIO || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) {
- return;
- }
-
- if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) {
- sdio->drive_strength = val;
- }
-
- /* make sure there are interrupts defined in the node */
- if (!of_find_property(np, "interrupts", NULL)) {
- return;
- }
-
- irq = irq_of_parse_and_map(np, 0);
- if (!irq) {
- BRCMF_ERR("interrupt could not be mapped\n");
- return;
- }
- irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
-
- sdio->oob_irq_supported = true;
-}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/of.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/of.h
deleted file mode 100644
index cf57bd74..0000000
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/of.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2014 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_OF_H_
-#define SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_OF_H_
-
-#include "common.h"
-#include "device.h"
-
-void brcmf_of_probe(struct brcmf_device* dev, enum brcmf_bus_type bus_type,
- struct brcmf_mp_device* settings);
-
-#endif // SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_OF_H_
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.cc
index a1dc4b2..5e3651e2 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.cc
@@ -39,11 +39,11 @@
#include "core.h"
#include "debug.h"
#include "defs.h"
-#include "device.h"
#include "firmware.h"
#include "linuxisms.h"
#include "netbuf.h"
#include "soc.h"
+#include "timer.h"
#include "workqueue.h"
#define DCMD_RESP_TIMEOUT_MSEC (2500)
@@ -100,7 +100,6 @@
#include "bus.h"
#include "chipcommon.h"
#include "debug.h"
-#include "device.h"
#define TXQLEN 2048 /* bulk tx queue length */
#define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */
@@ -1571,9 +1570,9 @@
brcmf_netbuf_list_prev(&bus->glom, pfirst));
brcmf_netbuf_list_remove(&bus->glom, pfirst);
if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN])) {
- brcmf_rx_event(bus->sdiodev->dev, pfirst);
+ brcmf_rx_event(bus->sdiodev->drvr, pfirst);
} else {
- brcmf_rx_frame(bus->sdiodev->dev, pfirst, false);
+ brcmf_rx_frame(bus->sdiodev->drvr, pfirst, false);
}
bus->sdcnt.rxglompkts++;
}
@@ -1671,11 +1670,11 @@
/* Point to valid data and indicate its length */
// spin_lock_bh(&bus->rxctl_lock);
- pthread_mutex_lock(&irq_callback_lock);
+ bus->sdiodev->drvr->irq_callback_lock.lock();
if (bus->rxctl) {
BRCMF_ERR("last control frame is being processed.\n");
// spin_unlock_bh(&bus->rxctl_lock);
- pthread_mutex_unlock(&irq_callback_lock);
+ bus->sdiodev->drvr->irq_callback_lock.unlock();
free(buf);
goto done;
}
@@ -1683,7 +1682,7 @@
bus->rxctl_orig = buf;
bus->rxlen = len - doff;
// spin_unlock_bh(&bus->rxctl_lock);
- pthread_mutex_unlock(&irq_callback_lock);
+ bus->sdiodev->drvr->irq_callback_lock.unlock();
done:
/* Awake any waiters */
@@ -1884,9 +1883,9 @@
if (pkt->len == 0) {
brcmu_pkt_buf_free_netbuf(pkt);
} else if (rd->channel == SDPCM_EVENT_CHANNEL) {
- brcmf_rx_event(bus->sdiodev->dev, pkt);
+ brcmf_rx_event(bus->sdiodev->drvr, pkt);
} else {
- brcmf_rx_frame(bus->sdiodev->dev, pkt, false);
+ brcmf_rx_frame(bus->sdiodev->drvr, pkt, false);
}
/* prepare the descriptor for the next read */
@@ -2056,7 +2055,7 @@
}
brcmf_netbuf_list_for_every_safe(pktq, pkt_next, tmp) {
brcmf_netbuf_list_remove(pktq, pkt_next);
- brcmf_proto_bcdc_txcomplete(bus->sdiodev->dev, pkt_next, ret == ZX_OK);
+ brcmf_proto_bcdc_txcomplete(bus->sdiodev->drvr, pkt_next, ret == ZX_OK);
}
return ret;
}
@@ -2081,7 +2080,7 @@
pkt_num = min_t(uint32_t, pkt_num, brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
brcmf_netbuf_list_init(&pktq);
// spin_lock_bh(&bus->txq_lock);
- pthread_mutex_lock(&irq_callback_lock);
+ bus->sdiodev->drvr->irq_callback_lock.lock();
for (i = 0; i < pkt_num; i++) {
pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
if (pkt == NULL) {
@@ -2090,7 +2089,7 @@
brcmf_netbuf_list_add_tail(&pktq, pkt);
}
// spin_unlock_bh(&bus->txq_lock);
- pthread_mutex_unlock(&irq_callback_lock);
+ bus->sdiodev->drvr->irq_callback_lock.unlock();
if (i == 0) {
break;
}
@@ -2119,7 +2118,7 @@
/* Deflow-control stack if needed */
if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) && bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
bus->txoff = false;
- brcmf_proto_bcdc_txflowblock(bus->sdiodev->dev, false);
+ brcmf_proto_bcdc_txflowblock(bus->sdiodev->drvr, false);
}
return cnt;
@@ -2184,8 +2183,7 @@
return ret;
}
-static void brcmf_sdio_bus_stop(struct brcmf_device* dev) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
+static void brcmf_sdio_bus_stop(brcmf_bus* bus_if) {
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
struct brcmf_core* core = bus->sdio_core;
@@ -2244,10 +2242,10 @@
/* Clear rx control and wake any waiters */
// spin_lock_bh(&bus->rxctl_lock);
- pthread_mutex_lock(&irq_callback_lock);
+ sdiodev->drvr->irq_callback_lock.lock();
bus->rxlen = 0;
// spin_unlock_bh(&bus->rxctl_lock);
- pthread_mutex_unlock(&irq_callback_lock);
+ sdiodev->drvr->irq_callback_lock.unlock();
// TODO(cphoenix): I think the original Linux code in brcmf_sdio_dcmd_resp_wait() would have
// gone right back to sleep, since rxlen is 0. In the current code, it will exit;
// brcmf_sdio_bus_rxctl() will return ZX_ERR_SHOULD_WAIT; the loop in brcmf_proto_bcdc_cmplt
@@ -2436,14 +2434,20 @@
}
}
-static struct pktq* brcmf_sdio_bus_gettxq(struct brcmf_device* dev) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
+static struct pktq* brcmf_sdio_bus_gettxq(brcmf_bus* bus_if) {
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
return &bus->txq;
}
+static void brcmf_sdio_wowl_config(brcmf_bus* bus_if, bool enabled) {
+ struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
+
+ BRCMF_DBG(SDIO, "Configuring WOWL, enabled=%d\n", enabled);
+ sdiodev->wowl_enabled = enabled;
+}
+
static bool brcmf_sdio_prec_enq(struct pktq* q, struct brcmf_netbuf* pkt, int prec) {
struct brcmf_netbuf* p;
int eprec = -1; /* precedence to evict from */
@@ -2489,10 +2493,9 @@
return p != NULL;
}
-static zx_status_t brcmf_sdio_bus_txdata(struct brcmf_device* dev, struct brcmf_netbuf* pkt) {
+static zx_status_t brcmf_sdio_bus_txdata(brcmf_bus* bus_if, brcmf_netbuf* pkt) {
zx_status_t ret;
uint prec;
- struct brcmf_bus* bus_if = dev_to_bus(dev);
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
@@ -2514,7 +2517,7 @@
/* Priority based enq */
// spin_lock_bh(&bus->txq_lock);
- pthread_mutex_lock(&irq_callback_lock);
+ sdiodev->drvr->irq_callback_lock.lock();
/* reset bus_flags in packet workspace */
*(uint16_t*)(pkt->workspace) = 0;
if (!brcmf_sdio_prec_enq(&bus->txq, pkt, prec)) {
@@ -2527,10 +2530,10 @@
if (pktq_len(&bus->txq) >= TXHI) {
bus->txoff = true;
- brcmf_proto_bcdc_txflowblock(dev, true);
+ brcmf_proto_bcdc_txflowblock(sdiodev->drvr, true);
}
// spin_unlock_bh(&bus->txq_lock);
- pthread_mutex_unlock(&irq_callback_lock);
+ sdiodev->drvr->irq_callback_lock.unlock();
#if !defined(NDEBUG)
if (pktq_plen(&bus->txq, prec) > qcount[prec]) {
@@ -2630,8 +2633,7 @@
}
#endif /* !defined(NDEBUG) */
-static zx_status_t brcmf_sdio_bus_txctl(struct brcmf_device* dev, unsigned char* msg, uint msglen) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
+static zx_status_t brcmf_sdio_bus_txctl(brcmf_bus* bus_if, unsigned char* msg, uint msglen) {
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
zx_status_t ret;
@@ -2723,13 +2725,12 @@
}
#endif /* !defined(NDEBUG) */
-static zx_status_t brcmf_sdio_bus_rxctl(struct brcmf_device* dev, unsigned char* msg, uint msglen,
+static zx_status_t brcmf_sdio_bus_rxctl(brcmf_bus* bus_if, unsigned char* msg, uint msglen,
int* rxlen_out) {
bool timeout;
uint rxlen = 0;
bool pending;
uint8_t* buf;
- struct brcmf_bus* bus_if = dev_to_bus(dev);
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
@@ -2742,7 +2743,7 @@
timeout = (brcmf_sdio_dcmd_resp_wait(bus, &pending) != ZX_OK);
// spin_lock_bh(&bus->rxctl_lock);
- pthread_mutex_lock(&irq_callback_lock);
+ sdiodev->drvr->irq_callback_lock.lock();
rxlen = bus->rxlen;
memcpy(msg, bus->rxctl, std::min(msglen, rxlen));
bus->rxctl = NULL;
@@ -2750,7 +2751,7 @@
bus->rxctl_orig = NULL;
bus->rxlen = 0;
// spin_unlock_bh(&bus->rxctl_lock);
- pthread_mutex_unlock(&irq_callback_lock);
+ sdiodev->drvr->irq_callback_lock.unlock();
free(buf);
if (rxlen) {
@@ -2970,8 +2971,7 @@
return ZX_OK;
}
-static zx_status_t brcmf_sdio_bus_preinit(struct brcmf_device* dev) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
+static zx_status_t brcmf_sdio_bus_preinit(brcmf_bus* bus_if) {
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
struct brcmf_core* core = bus->sdio_core;
@@ -2985,13 +2985,13 @@
if (core->rev < 12) {
/* for sdio core rev < 12, disable txgloming */
value = 0;
- err = brcmf_iovar_data_set(dev, "bus:txglom", &value, sizeof(uint32_t), nullptr);
+ err = brcmf_iovar_data_set(sdiodev->drvr, "bus:txglom", &value, sizeof(uint32_t), nullptr);
} else {
/* otherwise, set txglomalign */
value = sdiodev->settings->bus.sdio.sd_sgentry_align;
/* SDIO ADMA requires at least 32 bit alignment */
value = std::max<uint32_t>(value, DMA_ALIGNMENT);
- err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, sizeof(uint32_t), nullptr);
+ err = brcmf_iovar_data_set(sdiodev->drvr, "bus:txglomalign", &value, sizeof(uint32_t), nullptr);
}
// No support for txglomming, requires SDIO scatter/gather support (see WLAN-882)
@@ -3001,23 +3001,20 @@
}
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
- brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
+ brcmf_bus_add_txhdrlen(sdiodev->drvr, bus->tx_hdrlen);
done:
return err;
}
-static size_t brcmf_sdio_bus_get_ramsize(struct brcmf_device* dev) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
+static size_t brcmf_sdio_bus_get_ramsize(brcmf_bus* bus_if) {
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
return bus->ci->ramsize - bus->ci->srsize;
}
-static zx_status_t brcmf_sdio_bus_get_memdump(struct brcmf_device* dev, void* data,
- size_t mem_size) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
+static zx_status_t brcmf_sdio_bus_get_memdump(brcmf_bus* bus_if, void* data, size_t mem_size) {
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
zx_status_t err;
@@ -3455,8 +3452,7 @@
goto fail;
}
- sdiodev->settings =
- brcmf_get_module_param(sdiodev->dev, BRCMF_BUS_TYPE_SDIO, bus->ci->chip, bus->ci->chiprev);
+ sdiodev->settings = brcmf_get_module_param(BRCMF_BUS_TYPE_SDIO, bus->ci->chip, bus->ci->chiprev);
if (!sdiodev->settings) {
BRCMF_ERR("Failed to get device parameters\n");
err = ZX_ERR_INTERNAL;
@@ -3573,8 +3569,8 @@
}
static void brcmf_sdio_watchdog(void* data) {
- pthread_mutex_lock(&irq_callback_lock);
struct brcmf_sdio* bus = static_cast<decltype(bus)>(data);
+ bus->sdiodev->drvr->irq_callback_lock.lock();
if (bus->watchdog_tsk) {
// Currently signaling watchdog_wait does nothing; brcmf_sdio_watchdog_thread() will
@@ -3589,12 +3585,11 @@
brcmf_timer_set(&bus->timer, ZX_MSEC(BRCMF_WD_POLL_MSEC));
}
}
- pthread_mutex_unlock(&irq_callback_lock);
+ bus->sdiodev->drvr->irq_callback_lock.unlock();
}
-static zx_status_t brcmf_sdio_get_fwname(struct brcmf_device* dev, uint32_t chip, uint32_t chiprev,
+static zx_status_t brcmf_sdio_get_fwname(brcmf_bus* bus_if, uint32_t chip, uint32_t chiprev,
uint8_t* fw_name) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
int ret = ZX_OK;
@@ -3607,8 +3602,7 @@
return ret;
}
-static zx_status_t brcmf_sdio_get_bootloader_macaddr(struct brcmf_device* dev, uint8_t* mac_addr) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
+static zx_status_t brcmf_sdio_get_bootloader_macaddr(brcmf_bus* bus_if, uint8_t* mac_addr) {
struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
return brcmf_sdiod_get_bootloader_macaddr(sdiodev, mac_addr);
}
@@ -3629,27 +3623,22 @@
.device_add = device_add,
};
-static void brcmf_sdio_firmware_callback(struct brcmf_device* dev, zx_status_t err,
- const struct brcmf_firmware* code, void* nvram,
+static void brcmf_sdio_firmware_callback(brcmf_pub* drvr, zx_status_t err,
+ const brcmf_firmware* code, void* nvram,
uint32_t nvram_len) {
- struct brcmf_bus* bus_if = dev_to_bus(dev);
- struct brcmf_sdio_dev* sdiodev = bus_if->bus_priv.sdio;
+ struct brcmf_sdio_dev* sdiodev = drvr->bus_if->bus_priv.sdio;
struct brcmf_sdio* bus = sdiodev->bus;
struct brcmf_sdio_dev* sdiod = bus->sdiodev;
struct brcmf_core* core = bus->sdio_core;
struct sdpcm_shared sh = {};
uint8_t saveclk = 0;
- BRCMF_DBG(TRACE, "Enter: dev=%s, err=%d\n", device_get_name(dev->zxdev), err);
+ BRCMF_DBG(TRACE, "Enter: dev=%s, err=%d\n", device_get_name(sdiodev->drvr->zxdev), err);
if (err != ZX_OK) {
goto fail;
}
- if (!bus_if->drvr) {
- return;
- }
-
/* try to download image and nvram to the dongle */
bus->alp_only = true;
err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
@@ -3757,7 +3746,7 @@
sdio_release_host(sdiodev->func1);
zx_nanosleep(zx_deadline_after(ZX_MSEC(100)));
- err = brcmf_bus_started(dev);
+ err = brcmf_bus_started(sdiodev->drvr);
if (err != ZX_OK) {
BRCMF_ERR("dongle is not responding\n");
goto fail;
@@ -3767,7 +3756,7 @@
release:
sdio_release_host(sdiodev->func1);
fail:
- BRCMF_DBG(TRACE, "failed: dev=%s, err=%d\n", device_get_name(dev->zxdev), err);
+ BRCMF_DBG(TRACE, "failed: dev=%s, err=%d\n", device_get_name(sdiodev->drvr->zxdev), err);
BRCMF_ERR("Need to implement driver release logic (WLAN-888)\n");
// TODO(WLAN-888)
// device_release_driver(&sdiodev->func2->dev);
@@ -3799,7 +3788,7 @@
/* single-threaded workqueue */
char name[WORKQUEUE_NAME_MAXLEN];
static int queue_uniquify = 0;
- snprintf(name, WORKQUEUE_NAME_MAXLEN, "brcmf_wq/%s%d", device_get_name(sdiodev->dev->zxdev),
+ snprintf(name, WORKQUEUE_NAME_MAXLEN, "brcmf_wq/%s%d", device_get_name(sdiodev->drvr->zxdev),
queue_uniquify++);
wq = workqueue_create(name);
if (!wq) {
@@ -3822,7 +3811,7 @@
bus->dcmd_resp_wait = {};
/* Set up the watchdog timer */
- brcmf_timer_init(&bus->timer, brcmf_sdio_watchdog, bus);
+ brcmf_timer_init(&bus->timer, sdiodev->drvr->dispatcher, brcmf_sdio_watchdog, bus);
/* Initialize watchdog thread */
bus->watchdog_wait = {};
bus->watchdog_should_stop.store(false);
@@ -3836,7 +3825,6 @@
bus->dpc_running = false;
/* Assign bus interface call back */
- bus->sdiodev->bus_if->dev = sdiodev->dev;
bus->sdiodev->bus_if->ops = &brcmf_sdio_bus_ops;
bus->sdiodev->bus_if->chip = bus->ci->chip;
bus->sdiodev->bus_if->chiprev = bus->ci->chiprev;
@@ -3845,7 +3833,7 @@
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
/* Attach to the common layer, reserve hdr space */
- ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings);
+ ret = brcmf_attach(bus->sdiodev->drvr, bus->sdiodev->bus_if, bus->sdiodev->settings);
if (ret != ZX_OK) {
BRCMF_ERR("brcmf_attach failed\n");
goto fail;
@@ -3896,7 +3884,7 @@
goto fail;
}
- ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM, sdiodev->fw_name,
+ ret = brcmf_fw_get_firmwares(sdiodev->drvr, BRCMF_FW_REQUEST_NVRAM, sdiodev->fw_name,
sdiodev->nvram_name, brcmf_sdio_firmware_callback);
if (ret != ZX_OK) {
BRCMF_ERR("async firmware request failed: %d\n", ret);
@@ -3918,7 +3906,7 @@
/* De-register interrupt handler */
brcmf_sdiod_intr_unregister(bus->sdiodev);
- brcmf_detach(bus->sdiodev->dev);
+ brcmf_detach(bus->sdiodev->drvr);
workqueue_cancel_work(&bus->datawork);
if (bus->brcmf_wq) {
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.h
index ad770ea..066a71e 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sdio.h
@@ -22,7 +22,6 @@
#include <ddk/protocol/sdio.h>
#include "defs.h"
-#include "device.h"
#include "firmware.h"
#include "linuxisms.h"
#include "netbuf.h"
@@ -200,7 +199,7 @@
bool has_debug_gpio;
zx_handle_t irq_handle;
thrd_t isr_thread;
- struct brcmf_device* dev;
+ struct brcmf_pub* drvr;
uint32_t sbwad; /* Save backplane window address */
struct brcmf_core* cc_core; /* chipcommon core info struct */
struct brcmf_sdio* bus;
@@ -393,7 +392,6 @@
void brcmf_sdio_isr(struct brcmf_sdio* bus);
void brcmf_sdio_wd_timer(struct brcmf_sdio* bus, bool active);
-void brcmf_sdio_wowl_config(struct brcmf_device* dev, bool enabled);
zx_status_t brcmf_sdio_sleep(struct brcmf_sdio* bus, bool sleep);
void brcmf_sdio_trigger_dpc(struct brcmf_sdio* bus);
int brcmf_sdio_oob_irqhandler(void* cookie);
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.cc
index ee3cad5..b86390c 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.cc
@@ -24,33 +24,30 @@
#include "chip.h"
#include "common.h"
#include "debug.h"
-#include "device.h"
#include "src/connectivity/wlan/drivers/testing/lib/sim-device/device.h"
-#define BUS_OP(dev) dev->bus->bus_priv.sim->sim_fw
+#define BUS_OP(bus) bus->bus_priv.sim->sim_fw
static const struct brcmf_bus_ops brcmf_sim_bus_ops = {
.get_bus_type = []() { return BRCMF_BUS_TYPE_SIM; },
- .preinit = [](struct brcmf_device* dev) { return BUS_OP(dev)->BusPreinit(); },
- .stop = [](struct brcmf_device* dev) { return BUS_OP(dev)->BusStop(); },
- .txdata = [](struct brcmf_device* dev,
- struct brcmf_netbuf* netbuf) { return BUS_OP(dev)->BusTxData(netbuf); },
- .txctl = [](struct brcmf_device* dev, unsigned char* msg,
- uint len) { return BUS_OP(dev)->BusTxCtl(msg, len); },
- .rxctl = [](struct brcmf_device* dev, unsigned char* msg, uint len,
- int* rxlen_out) { return BUS_OP(dev)->BusRxCtl(msg, len, rxlen_out); },
- .gettxq = [](struct brcmf_device* dev) { return BUS_OP(dev)->BusGetTxQueue(); },
- .wowl_config = [](struct brcmf_device* dev,
- bool enabled) { return BUS_OP(dev)->BusWowlConfig(enabled); },
- .get_ramsize = [](struct brcmf_device* dev) { return BUS_OP(dev)->BusGetRamsize(); },
- .get_memdump = [](struct brcmf_device* dev, void* data,
- size_t len) { return BUS_OP(dev)->BusGetMemdump(data, len); },
+ .preinit = [](brcmf_bus* bus) { return BUS_OP(bus)->BusPreinit(); },
+ .stop = [](brcmf_bus* bus) { return BUS_OP(bus)->BusStop(); },
+ .txdata = [](brcmf_bus* bus, brcmf_netbuf* netbuf) { return BUS_OP(bus)->BusTxData(netbuf); },
+ .txctl = [](brcmf_bus* bus, unsigned char* msg,
+ uint len) { return BUS_OP(bus)->BusTxCtl(msg, len); },
+ .rxctl = [](brcmf_bus* bus, unsigned char* msg, uint len,
+ int* rxlen_out) { return BUS_OP(bus)->BusRxCtl(msg, len, rxlen_out); },
+ .gettxq = [](brcmf_bus* bus) { return BUS_OP(bus)->BusGetTxQueue(); },
+ .wowl_config = [](brcmf_bus* bus, bool enabled) { return BUS_OP(bus)->BusWowlConfig(enabled); },
+ .get_ramsize = [](brcmf_bus* bus) { return BUS_OP(bus)->BusGetRamsize(); },
+ .get_memdump = [](brcmf_bus* bus, void* data,
+ size_t len) { return BUS_OP(bus)->BusGetMemdump(data, len); },
.get_fwname =
- [](struct brcmf_device* dev, uint chip, uint chiprev, unsigned char* fw_name) {
- return BUS_OP(dev)->BusGetFwName(chip, chiprev, fw_name);
+ [](brcmf_bus* bus, uint chip, uint chiprev, unsigned char* fw_name) {
+ return BUS_OP(bus)->BusGetFwName(chip, chiprev, fw_name);
},
.get_bootloader_macaddr =
- [](struct brcmf_device* dev, uint8_t* mac_addr) {
- return BUS_OP(dev)->BusGetBootloaderMacAddr(mac_addr);
+ [](brcmf_bus* bus, uint8_t* mac_addr) {
+ return BUS_OP(bus)->BusGetBootloaderMacAddr(mac_addr);
},
.device_add = wlan_sim_device_add};
#undef BUS_OP
@@ -63,7 +60,7 @@
bus->chip = chip;
bus->chiprev = chiprev;
- bus->bus_priv.sim->settings = brcmf_get_module_param(bus->dev, BRCMF_BUS_TYPE_SIM, chip, chiprev);
+ bus->bus_priv.sim->settings = brcmf_get_module_param(BRCMF_BUS_TYPE_SIM, chip, chiprev);
if (bus->bus_priv.sim->settings == nullptr) {
BRCMF_ERR("Failed to get device parameters\n");
return ZX_ERR_INTERNAL;
@@ -73,7 +70,7 @@
}
// Allocate necessary memory and initialize simulator-specific structures
-zx_status_t brcmf_sim_register(struct brcmf_device* device) {
+zx_status_t brcmf_sim_register(brcmf_pub* drvr, std::unique_ptr<brcmf_bus>* out_bus) {
zx_status_t status = ZX_OK;
auto simdev = std::make_unique<brcmf_simdev>();
auto bus_if = std::make_unique<brcmf_bus>();
@@ -81,7 +78,6 @@
// Initialize inter-structure pointers
simdev->sim_fw = std::make_unique<SimFirmware>();
bus_if->bus_priv.sim = simdev.get();
- bus_if->dev = device;
BRCMF_DBG(SIM, "Registering simulator target\n");
status = brcmf_sim_probe(bus_if.get());
@@ -91,8 +87,7 @@
}
bus_if->ops = &brcmf_sim_bus_ops;
- device->bus = std::move(bus_if);
- status = brcmf_attach(device, simdev->settings);
+ status = brcmf_attach(drvr, bus_if.get(), simdev->settings);
if (status != ZX_OK) {
BRCMF_ERR("brcmf_attach failed\n");
return status;
@@ -101,19 +96,18 @@
// Here is where we would likely simulate loading the firmware into the target. For now,
// we don't try.
- status = brcmf_bus_started(device);
+ status = brcmf_bus_started(drvr);
if (status != ZX_OK) {
BRCMF_ERR("Failed to start (simulated) bus\n");
return status;
}
simdev.release();
+ *out_bus = std::move(bus_if);
return ZX_OK;
}
-void brcmf_sim_exit(struct brcmf_device* device) {
- delete device->bus->bus_priv.sim;
- device->bus->bus_priv.sim = nullptr;
-
- device->bus.reset();
+void brcmf_sim_exit(brcmf_bus* bus) {
+ delete bus->bus_priv.sim;
+ bus->bus_priv.sim = nullptr;
}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.h
index 7e66a8f..c552c11 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.h
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/sim.h
@@ -20,7 +20,6 @@
#include <memory>
#include "bus.h"
-#include "device.h"
#include "sim-fw/sim_fw.h"
struct brcmf_simdev {
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/lifecycle_test.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/lifecycle_test.cc
index dbee855..4251468 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/lifecycle_test.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/lifecycle_test.cc
@@ -23,19 +23,21 @@
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/core.h"
#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/device.h"
+namespace wlan {
+namespace brcmfmac {
namespace {
TEST(LifecycleTest, StartStop) {
zx_status_t status = ZX_OK;
- brcmf_device device = {};
+ Device* device = nullptr;
- status = brcmfmac_module_init();
- EXPECT_EQ(status, ZX_OK);
- status = brcmf_core_init(&device);
+ status = Device::Create(nullptr, &device);
EXPECT_EQ(status, ZX_OK);
- brcmf_core_exit(&device);
- brcmfmac_module_exit();
+ device->SimUnbind();
+ device = nullptr;
}
} // namespace
+} // namespace brcmfmac
+} // namespace wlan
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/sdio_test.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/sdio_test.cc
index 092919a..21c6b15 100644
--- a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/sdio_test.cc
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/test/sdio_test.cc
@@ -78,7 +78,7 @@
wifi_config_t config = {ZX_INTERRUPT_MODE_LEVEL_LOW};
ddk.SetMetadata(&config, sizeof(config));
- brcmf_device dev = {};
+ brcmf_pub drvr = {};
brcmf_sdio_dev sdio_dev = {};
sdio_func func1 = {};
MockSdio sdio1;
@@ -91,7 +91,7 @@
sdio_dev.gpios[WIFI_OOB_IRQ_GPIO_INDEX] = *gpio.GetProto();
sdio_dev.sdio_proto_fn1 = *sdio1.GetProto();
sdio_dev.sdio_proto_fn2 = *sdio2.GetProto();
- sdio_dev.dev = &dev;
+ sdio_dev.drvr = &drvr;
sdio_dev.bus_if = &bus_if;
sdio_dev.settings = &settings;
@@ -109,7 +109,7 @@
}
TEST(Sdio, IntrUnregister) {
- brcmf_device dev = {};
+ brcmf_pub drvr = {};
brcmf_sdio_dev sdio_dev = {};
sdio_func func1 = {};
@@ -118,7 +118,7 @@
sdio_dev.func1 = &func1;
sdio_dev.sdio_proto_fn1 = *sdio1.GetProto();
sdio_dev.sdio_proto_fn2 = *sdio2.GetProto();
- sdio_dev.dev = &dev;
+ sdio_dev.drvr = &drvr;
sdio_dev.oob_irq_requested = true;
sdio1.ExpectDoVendorControlRwByte(ZX_OK, true, 0xf2, 0, 0).ExpectDisableFnIntr(ZX_OK);
@@ -135,7 +135,7 @@
sdio_dev.func1 = &func1;
sdio_dev.sdio_proto_fn1 = *sdio1.GetProto();
sdio_dev.sdio_proto_fn2 = *sdio2.GetProto();
- sdio_dev.dev = &dev;
+ sdio_dev.drvr = &drvr;
sdio_dev.sd_irq_requested = true;
sdio1.ExpectDisableFnIntr(ZX_OK);
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.cc b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.cc
new file mode 100644
index 0000000..c1bef06
--- /dev/null
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2019 The Fuchsia Authors
+//
+// Permission to use, copy, modify, and/or distribute this software for any purpose with or without
+// fee is hereby granted, provided that the above copyright notice and this permission notice
+// appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+// SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+// OF THIS SOFTWARE.
+
+#include "src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.h"
+
+#include <lib/async/time.h>
+#include <zircon/listnode.h>
+#include <zircon/types.h>
+
+static void brcmf_timer_handler(async_dispatcher_t* dispatcher, async_task_t* task,
+ zx_status_t status) {
+ if (status != ZX_OK) {
+ return;
+ }
+ brcmf_timer_info_t* timer = containerof(task, brcmf_timer_info_t, task);
+ timer->callback_function(timer->data);
+ timer->lock.lock();
+ timer->scheduled = false;
+ sync_completion_signal(&timer->finished);
+ timer->lock.unlock();
+}
+
+void brcmf_timer_init(brcmf_timer_info_t* timer, async_dispatcher_t* dispatcher,
+ brcmf_timer_callback_t* callback, void* data) {
+ memset(&timer->task.state, 0, sizeof(timer->task.state));
+ timer->task.handler = brcmf_timer_handler;
+ timer->dispatcher = dispatcher;
+ timer->data = data;
+ timer->callback_function = callback;
+ timer->finished = {};
+ timer->scheduled = false;
+}
+
+void brcmf_timer_set(brcmf_timer_info_t* timer, zx_duration_t delay) {
+ timer->lock.lock();
+ async_cancel_task(timer->dispatcher, &timer->task); // Make sure it's not scheduled
+ timer->task.deadline = delay + async_now(timer->dispatcher);
+ timer->scheduled = true;
+ sync_completion_reset(&timer->finished);
+ async_post_task(timer->dispatcher, &timer->task);
+ timer->lock.unlock();
+}
+
+void brcmf_timer_stop(brcmf_timer_info_t* timer) {
+ timer->lock.lock();
+ if (!timer->scheduled) {
+ timer->lock.unlock();
+ return;
+ }
+ zx_status_t result = async_cancel_task(timer->dispatcher, &timer->task);
+ timer->lock.unlock();
+ if (result != ZX_OK) {
+ sync_completion_wait(&timer->finished, ZX_TIME_INFINITE);
+ }
+}
diff --git a/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.h b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.h
new file mode 100644
index 0000000..3d40b8c
--- /dev/null
+++ b/src/connectivity/wlan/drivers/third_party/broadcom/brcmfmac/timer.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2019 The Fuchsia Authors
+//
+// Permission to use, copy, modify, and/or distribute this software for any purpose with or without
+// fee is hereby granted, provided that the above copyright notice and this permission notice
+// appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+// SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+// OF THIS SOFTWARE.
+
+#include <lib/async/dispatcher.h>
+#include <lib/async/task.h>
+#include <lib/sync/completion.h>
+#include <zircon/time.h>
+
+#include <mutex>
+
+// This is the function that timer users write to receive callbacks.
+typedef void(brcmf_timer_callback_t)(void* data);
+
+typedef struct brcmf_timer_info {
+ async_task_t task;
+ async_dispatcher_t* dispatcher;
+ void* data;
+ brcmf_timer_callback_t* callback_function;
+ bool scheduled;
+ sync_completion_t finished;
+ std::mutex lock;
+} brcmf_timer_info_t;
+
+void brcmf_timer_init(brcmf_timer_info_t* timer, async_dispatcher_t* dispatcher,
+ brcmf_timer_callback_t* callback, void* data);
+
+void brcmf_timer_set(brcmf_timer_info_t* timer, zx_duration_t delay);
+
+void brcmf_timer_stop(brcmf_timer_info_t* timer);