| /* |
| * Copyright (c) 2010 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_BUS_H_ |
| #define SRC_CONNECTIVITY_WLAN_DRIVERS_THIRD_PARTY_BROADCOM_BRCMFMAC_BUS_H_ |
| |
| #include <atomic> |
| #include <memory> |
| |
| #include <ddk/device.h> |
| #include <ddk/driver.h> |
| |
| #include "netbuf.h" |
| |
| // HW/SW bus in use |
| enum brcmf_bus_type { BRCMF_BUS_TYPE_SDIO, BRCMF_BUS_TYPE_SIM, BRCMF_BUS_TYPE_USB }; |
| |
| /* The level of bus communication with the dongle */ |
| enum brcmf_bus_state { |
| BRCMF_BUS_DOWN, /* Not ready for frame transfers */ |
| BRCMF_BUS_UP /* Ready for frame transfers */ |
| }; |
| |
| struct brcmf_pub; |
| struct brcmf_mp_device; |
| |
| struct brcmf_bus_dcmd { |
| const char* name; |
| char* param; |
| int param_len; |
| struct list_node list; |
| }; |
| |
| /** |
| * struct brcmf_bus_ops - bus callback operations. |
| * |
| * @preinit: execute bus/device specific dongle init commands (optional). |
| * @init: prepare for communication with dongle. |
| * @stop: clear pending frames, disable data flow. |
| * @txdata: send a data frame to the dongle. When the data |
| * has been transferred, the common driver must be |
| * notified using brcmf_txcomplete(). The common |
| * driver calls this function with interrupts |
| * disabled. |
| * @txctl: transmit a control request message to dongle. |
| * @rxctl: receive a control response message from dongle. |
| * @gettxq: obtain a reference of bus transmit queue (optional). |
| * @wowl_config: specify if dongle is configured for wowl when going to suspend |
| * @get_ramsize: obtain size of device memory. |
| * @get_memdump: obtain device memory dump in provided buffer. |
| * @get_fwname: obtain firmware name. |
| * @get_bootloader_macaddr: obtain mac address from bootloader, if supported. |
| * @device_add: register device. |
| * |
| * This structure provides an abstract interface towards the |
| * bus specific driver. For control messages to common driver |
| * will assure there is only one active transaction. Unless |
| * indicated otherwise these callbacks are mandatory. |
| */ |
| |
| struct brcmf_bus; |
| |
| struct brcmf_bus_ops { |
| enum brcmf_bus_type (*get_bus_type)(); |
| 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); |
| }; |
| |
| /** |
| * struct brcmf_bus_stats - bus statistic counters. |
| * |
| * @pktcowed: packets cowed for extra headroom/unorphan. |
| * @pktcow_failed: packets dropped due to failed cow-ing. |
| */ |
| struct brcmf_bus_stats { |
| std::atomic<int> pktcowed; |
| std::atomic<int> pktcow_failed; |
| }; |
| |
| /** |
| * struct brcmf_bus - interface structure between common and bus layer |
| * |
| * @bus_priv: pointer to private bus device. |
| * @dev: device pointer of bus device. |
| * @drvr: public driver information. |
| * @state: operational state of the bus interface. |
| * @stats: statistics shared between common and bus layer. |
| * @maxctl: maximum size for rxctl request message. |
| * @chip: device identifier of the dongle chip. |
| * @always_use_fws_queue: bus wants use queue also when fwsignal is inactive. |
| * @wowl_supported: is wowl supported by bus driver. |
| * @chiprev: revision of the dongle chip. |
| */ |
| struct brcmf_bus { |
| union { |
| struct brcmf_sdio_dev* sdio; |
| struct brcmf_usbdev* usb; |
| struct brcmf_pciedev* pcie; |
| struct brcmf_simdev* sim; |
| } bus_priv; |
| enum brcmf_bus_state state; |
| struct brcmf_bus_stats stats; |
| uint maxctl; |
| uint32_t chip; |
| uint32_t chiprev; |
| bool always_use_fws_queue; |
| bool wowl_supported; |
| |
| const struct brcmf_bus_ops* ops; |
| }; |
| |
| /* |
| * callback wrappers |
| */ |
| static inline zx_status_t brcmf_bus_preinit(struct brcmf_bus* bus) { |
| if (!bus->ops->preinit) { |
| return ZX_OK; |
| } |
| return bus->ops->preinit(bus); |
| } |
| |
| 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, netbuf); |
| } |
| |
| static inline int brcmf_bus_txctl(struct brcmf_bus* bus, unsigned char* msg, uint 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, msg, len, rxlen_out); |
| } |
| |
| static inline zx_status_t brcmf_bus_gettxq(struct brcmf_bus* bus, struct pktq** txq_out) { |
| if (!bus->ops->gettxq) { |
| if (txq_out) { |
| *txq_out = NULL; |
| } |
| return ZX_ERR_NOT_FOUND; |
| } |
| if (txq_out) { |
| *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, enabled); |
| } |
| } |
| |
| static inline size_t brcmf_bus_get_ramsize(struct brcmf_bus* bus) { |
| if (!bus->ops->get_ramsize) { |
| return 0; |
| } |
| |
| return bus->ops->get_ramsize(bus); |
| } |
| |
| static inline zx_status_t brcmf_bus_get_memdump(struct brcmf_bus* bus, void* data, size_t len) { |
| if (!bus->ops->get_memdump) { |
| return ZX_ERR_NOT_FOUND; |
| } |
| |
| 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, 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, mac_addr); |
| } |
| |
| static inline zx_status_t brcmf_bus_device_add(struct brcmf_bus* bus, zx_device_t* parent, |
| device_add_args_t* args, zx_device_t** out) { |
| return bus->ops->device_add(parent, args, out); |
| } |
| |
| // Interface to the system bus. |
| 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_ |