Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | // SPDX-License-Identifier: ISC /* * Copyright (c) 2010 Broadcom Corporation */ #ifndef BRCMFMAC_BUS_H #define BRCMFMAC_BUS_H #include <linux/kernel.h> #include <linux/firmware.h> #include <linux/device.h> #include "debug.h" /* IDs of the 6 default common rings of msgbuf protocol */ #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT 0 #define BRCMF_H2D_MSGRING_RXPOST_SUBMIT 1 #define BRCMF_H2D_MSGRING_FLOWRING_IDSTART 2 #define BRCMF_D2H_MSGRING_CONTROL_COMPLETE 2 #define BRCMF_D2H_MSGRING_TX_COMPLETE 3 #define BRCMF_D2H_MSGRING_RX_COMPLETE 4 #define BRCMF_NROF_H2D_COMMON_MSGRINGS 2 #define BRCMF_NROF_D2H_COMMON_MSGRINGS 3 #define BRCMF_NROF_COMMON_MSGRINGS (BRCMF_NROF_H2D_COMMON_MSGRINGS + \ BRCMF_NROF_D2H_COMMON_MSGRINGS) /* The interval to poll console */ #define BRCMF_CONSOLE 10 /* The maximum console interval value (5 mins) */ #define MAX_CONSOLE_INTERVAL (5 * 60) enum brcmf_fwvendor { BRCMF_FWVENDOR_WCC, BRCMF_FWVENDOR_CYW, BRCMF_FWVENDOR_BCA, /* keep last */ BRCMF_FWVENDOR_NUM, BRCMF_FWVENDOR_INVALID }; /* 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 */ }; /* The level of bus communication with the dongle */ enum brcmf_bus_protocol_type { BRCMF_PROTO_BCDC, BRCMF_PROTO_MSGBUF }; /* Firmware blobs that may be available */ enum brcmf_blob_type { BRCMF_BLOB_CLM, BRCMF_BLOB_TXCAP, }; struct brcmf_mp_device; struct brcmf_bus_dcmd { char *name; char *param; int param_len; struct list_head 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_blob: obtain a firmware blob. * @remove: initiate unbind of the 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_ops { int (*preinit)(struct device *dev); void (*stop)(struct device *dev); int (*txdata)(struct device *dev, struct sk_buff *skb); int (*txctl)(struct device *dev, unsigned char *msg, uint len); int (*rxctl)(struct device *dev, unsigned char *msg, uint len); struct pktq * (*gettxq)(struct device *dev); void (*wowl_config)(struct device *dev, bool enabled); size_t (*get_ramsize)(struct device *dev); int (*get_memdump)(struct device *dev, void *data, size_t len); int (*get_blob)(struct device *dev, const struct firmware **fw, enum brcmf_blob_type type); void (*debugfs_create)(struct device *dev); int (*reset)(struct device *dev); void (*remove)(struct device *dev); }; /** * struct brcmf_bus_msgbuf - bus ringbuf if in case of msgbuf. * * @commonrings: commonrings which are always there. * @flowrings: commonrings which are dynamically created and destroyed for data. * @rx_dataoffset: if set then all rx data has this offset. * @max_rxbufpost: maximum number of buffers to post for rx. * @max_flowrings: maximum number of tx flow rings supported. * @max_submissionrings: maximum number of submission rings(h2d) supported. * @max_completionrings: maximum number of completion rings(d2h) supported. */ struct brcmf_bus_msgbuf { struct brcmf_commonring *commonrings[BRCMF_NROF_COMMON_MSGRINGS]; struct brcmf_commonring **flowrings; u32 rx_dataoffset; u32 max_rxbufpost; u16 max_flowrings; u16 max_submissionrings; u16 max_completionrings; }; /** * 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 { atomic_t pktcowed; atomic_t pktcow_failed; }; /** * struct brcmf_bus - interface structure between common and bus layer * * @bus_priv: pointer to private bus device. * @proto_type: protocol type, bcdc or msgbuf * @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. * @chiprev: revision of the dongle chip. * @fwvid: firmware vendor-support identifier of the device. * @always_use_fws_queue: bus wants use queue also when fwsignal is inactive. * @wowl_supported: is wowl supported by bus driver. * @ops: callbacks for this bus instance. * @msgbuf: msgbuf protocol parameters provided by bus layer. * @list: member used to add this bus instance to linked list. */ struct brcmf_bus { union { struct brcmf_sdio_dev *sdio; struct brcmf_usbdev *usb; struct brcmf_pciedev *pcie; } bus_priv; enum brcmf_bus_protocol_type proto_type; struct device *dev; struct brcmf_pub *drvr; enum brcmf_bus_state state; struct brcmf_bus_stats stats; uint maxctl; u32 chip; u32 chiprev; enum brcmf_fwvendor fwvid; bool always_use_fws_queue; bool wowl_supported; const struct brcmf_bus_ops *ops; struct brcmf_bus_msgbuf *msgbuf; struct list_head list; }; /* * callback wrappers */ static inline int brcmf_bus_preinit(struct brcmf_bus *bus) { if (!bus->ops->preinit) return 0; return bus->ops->preinit(bus->dev); } static inline void brcmf_bus_stop(struct brcmf_bus *bus) { bus->ops->stop(bus->dev); } static inline int brcmf_bus_txdata(struct brcmf_bus *bus, struct sk_buff *skb) { return bus->ops->txdata(bus->dev, skb); } static inline int brcmf_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint len) { return bus->ops->txctl(bus->dev, msg, len); } static inline int brcmf_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint len) { return bus->ops->rxctl(bus->dev, msg, len); } static inline struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus) { if (!bus->ops->gettxq) return ERR_PTR(-ENOENT); return bus->ops->gettxq(bus->dev); } 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); } 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->dev); } static inline int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len) { if (!bus->ops->get_memdump) return -EOPNOTSUPP; return bus->ops->get_memdump(bus->dev, data, len); } static inline int brcmf_bus_get_blob(struct brcmf_bus *bus, const struct firmware **fw, enum brcmf_blob_type type) { return bus->ops->get_blob(bus->dev, fw, type); } static inline void brcmf_bus_debugfs_create(struct brcmf_bus *bus) { if (!bus->ops->debugfs_create) return; return bus->ops->debugfs_create(bus->dev); } static inline int brcmf_bus_reset(struct brcmf_bus *bus) { if (!bus->ops->reset) return -EOPNOTSUPP; return bus->ops->reset(bus->dev); } static inline void brcmf_bus_remove(struct brcmf_bus *bus) { if (!bus->ops->remove) { device_release_driver(bus->dev); return; } bus->ops->remove(bus->dev); } /* * interface functions from common layer */ /* Receive frame for delivery to OS. Callee disposes of rxp. */ void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event, bool inirq); /* Receive async event packet from firmware. Callee disposes of rxp. */ void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings); /* Indication from bus module regarding presence/insertion of dongle. */ int brcmf_attach(struct device *dev); /* Indication from bus module regarding removal/absence of dongle */ void brcmf_detach(struct device *dev); void brcmf_free(struct device *dev); /* Indication from bus module that dongle should be reset */ void brcmf_dev_reset(struct device *dev); /* Request from bus module to initiate a coredump */ void brcmf_dev_coredump(struct device *dev); /* Indication that firmware has halted or crashed */ void brcmf_fw_crashed(struct 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); s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len); void brcmf_bus_add_txhdrlen(struct device *dev, uint len); #ifdef CONFIG_BRCMFMAC_SDIO void brcmf_sdio_exit(void); int brcmf_sdio_register(void); #else static inline void brcmf_sdio_exit(void) { } static inline int brcmf_sdio_register(void) { return 0; } #endif #ifdef CONFIG_BRCMFMAC_USB void brcmf_usb_exit(void); int brcmf_usb_register(void); #else static inline void brcmf_usb_exit(void) { } static inline int brcmf_usb_register(void) { return 0; } #endif #ifdef CONFIG_BRCMFMAC_PCIE void brcmf_pcie_exit(void); int brcmf_pcie_register(void); #else static inline void brcmf_pcie_exit(void) { } static inline int brcmf_pcie_register(void) { return 0; } #endif #endif /* BRCMFMAC_BUS_H */ |