159 lines · c
1/* SPDX-License-Identifier: GPL-2.0+ */2/* Copyright (c) 2015 Quantenna Communications. All rights reserved. */3 4#ifndef QTNFMAC_BUS_H5#define QTNFMAC_BUS_H6 7#include <linux/netdevice.h>8#include <linux/workqueue.h>9 10#include "trans.h"11#include "core.h"12 13#define QTNF_MAX_MAC 314 15#define HBM_FRAME_META_MAGIC_PATTERN_S 0xAB16#define HBM_FRAME_META_MAGIC_PATTERN_E 0xBA17 18struct qtnf_frame_meta_info {19 u8 magic_s;20 u8 ifidx;21 u8 macid;22 u8 magic_e;23} __packed;24 25enum qtnf_fw_state {26 QTNF_FW_STATE_DETACHED,27 QTNF_FW_STATE_BOOT_DONE,28 QTNF_FW_STATE_ACTIVE,29 QTNF_FW_STATE_RUNNING,30 QTNF_FW_STATE_DEAD,31};32 33struct qtnf_bus;34 35struct qtnf_bus_ops {36 /* mgmt methods */37 int (*preinit)(struct qtnf_bus *);38 void (*stop)(struct qtnf_bus *);39 40 /* control path methods */41 int (*control_tx)(struct qtnf_bus *, struct sk_buff *);42 43 /* data xfer methods */44 int (*data_tx)(struct qtnf_bus *bus, struct sk_buff *skb,45 unsigned int macid, unsigned int vifid);46 void (*data_tx_timeout)(struct qtnf_bus *, struct net_device *);47 void (*data_tx_use_meta_set)(struct qtnf_bus *bus, bool use_meta);48 void (*data_rx_start)(struct qtnf_bus *);49 void (*data_rx_stop)(struct qtnf_bus *);50};51 52struct qtnf_bus {53 struct device *dev;54 enum qtnf_fw_state fw_state;55 u32 chip;56 u32 chiprev;57 struct qtnf_bus_ops *bus_ops;58 struct qtnf_wmac *mac[QTNF_MAX_MAC];59 struct qtnf_qlink_transport trans;60 struct qtnf_hw_info hw_info;61 struct napi_struct mux_napi;62 struct net_device *mux_dev;63 struct workqueue_struct *workqueue;64 struct workqueue_struct *hprio_workqueue;65 struct work_struct fw_work;66 struct work_struct event_work;67 struct mutex bus_lock; /* lock during command/event processing */68 struct dentry *dbg_dir;69 struct notifier_block netdev_nb;70 u8 hw_id[ETH_ALEN];71 /* bus private data */72 char bus_priv[] __aligned(sizeof(void *));73};74 75static inline bool qtnf_fw_is_up(struct qtnf_bus *bus)76{77 enum qtnf_fw_state state = bus->fw_state;78 79 return ((state == QTNF_FW_STATE_ACTIVE) ||80 (state == QTNF_FW_STATE_RUNNING));81}82 83static inline bool qtnf_fw_is_attached(struct qtnf_bus *bus)84{85 enum qtnf_fw_state state = bus->fw_state;86 87 return ((state == QTNF_FW_STATE_ACTIVE) ||88 (state == QTNF_FW_STATE_RUNNING) ||89 (state == QTNF_FW_STATE_DEAD));90}91 92static inline void *get_bus_priv(struct qtnf_bus *bus)93{94 if (WARN(!bus, "qtnfmac: invalid bus pointer"))95 return NULL;96 97 return &bus->bus_priv;98}99 100/* callback wrappers */101 102static inline int qtnf_bus_preinit(struct qtnf_bus *bus)103{104 if (!bus->bus_ops->preinit)105 return 0;106 return bus->bus_ops->preinit(bus);107}108 109static inline void qtnf_bus_stop(struct qtnf_bus *bus)110{111 if (!bus->bus_ops->stop)112 return;113 bus->bus_ops->stop(bus);114}115 116static inline int qtnf_bus_data_tx(struct qtnf_bus *bus, struct sk_buff *skb,117 unsigned int macid, unsigned int vifid)118{119 return bus->bus_ops->data_tx(bus, skb, macid, vifid);120}121 122static inline void123qtnf_bus_data_tx_timeout(struct qtnf_bus *bus, struct net_device *ndev)124{125 return bus->bus_ops->data_tx_timeout(bus, ndev);126}127 128static inline int qtnf_bus_control_tx(struct qtnf_bus *bus, struct sk_buff *skb)129{130 return bus->bus_ops->control_tx(bus, skb);131}132 133static inline void qtnf_bus_data_rx_start(struct qtnf_bus *bus)134{135 return bus->bus_ops->data_rx_start(bus);136}137 138static inline void qtnf_bus_data_rx_stop(struct qtnf_bus *bus)139{140 return bus->bus_ops->data_rx_stop(bus);141}142 143static __always_inline void qtnf_bus_lock(struct qtnf_bus *bus)144{145 mutex_lock(&bus->bus_lock);146}147 148static __always_inline void qtnf_bus_unlock(struct qtnf_bus *bus)149{150 mutex_unlock(&bus->bus_lock);151}152 153/* interface functions from common layer */154 155int qtnf_core_attach(struct qtnf_bus *bus);156void qtnf_core_detach(struct qtnf_bus *bus);157 158#endif /* QTNFMAC_BUS_H */159