1*6b4cac81SBjoern A. Zeeb /*- 2*6b4cac81SBjoern A. Zeeb * Copyright (c) 2020-2021 The FreeBSD Foundation 3*6b4cac81SBjoern A. Zeeb * Copyright (c) 2020-2021 Bjoern A. Zeeb 4*6b4cac81SBjoern A. Zeeb * 5*6b4cac81SBjoern A. Zeeb * This software was developed by Björn Zeeb under sponsorship from 6*6b4cac81SBjoern A. Zeeb * the FreeBSD Foundation. 7*6b4cac81SBjoern A. Zeeb * 8*6b4cac81SBjoern A. Zeeb * Redistribution and use in source and binary forms, with or without 9*6b4cac81SBjoern A. Zeeb * modification, are permitted provided that the following conditions 10*6b4cac81SBjoern A. Zeeb * are met: 11*6b4cac81SBjoern A. Zeeb * 1. Redistributions of source code must retain the above copyright 12*6b4cac81SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer. 13*6b4cac81SBjoern A. Zeeb * 2. Redistributions in binary form must reproduce the above copyright 14*6b4cac81SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer in the 15*6b4cac81SBjoern A. Zeeb * documentation and/or other materials provided with the distribution. 16*6b4cac81SBjoern A. Zeeb * 17*6b4cac81SBjoern A. Zeeb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*6b4cac81SBjoern A. Zeeb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*6b4cac81SBjoern A. Zeeb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*6b4cac81SBjoern A. Zeeb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21*6b4cac81SBjoern A. Zeeb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*6b4cac81SBjoern A. Zeeb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*6b4cac81SBjoern A. Zeeb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*6b4cac81SBjoern A. Zeeb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*6b4cac81SBjoern A. Zeeb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*6b4cac81SBjoern A. Zeeb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*6b4cac81SBjoern A. Zeeb * SUCH DAMAGE. 28*6b4cac81SBjoern A. Zeeb */ 29*6b4cac81SBjoern A. Zeeb 30*6b4cac81SBjoern A. Zeeb /* 31*6b4cac81SBjoern A. Zeeb * Public functions are called linuxkpi_*(). 32*6b4cac81SBjoern A. Zeeb * Internal (static) functions are called lkpi_*(). 33*6b4cac81SBjoern A. Zeeb * 34*6b4cac81SBjoern A. Zeeb * The internal structures holding metadata over public structures are also 35*6b4cac81SBjoern A. Zeeb * called lkpi_xxx (usually with a member at the end called xxx). 36*6b4cac81SBjoern A. Zeeb * Note: we do not replicate the structure names but the general variable names 37*6b4cac81SBjoern A. Zeeb * for these (e.g., struct hw -> struct lkpi_hw, struct sta -> struct lkpi_sta). 38*6b4cac81SBjoern A. Zeeb * There are macros to access one from the other. 39*6b4cac81SBjoern A. Zeeb * We call the internal versions lxxx (e.g., hw -> lhw, sta -> lsta). 40*6b4cac81SBjoern A. Zeeb */ 41*6b4cac81SBjoern A. Zeeb 42*6b4cac81SBjoern A. Zeeb #ifndef _LKPI_SRC_LINUX_80211_H 43*6b4cac81SBjoern A. Zeeb #define _LKPI_SRC_LINUX_80211_H 44*6b4cac81SBjoern A. Zeeb 45*6b4cac81SBjoern A. Zeeb struct lkpi_radiotap_tx_hdr { 46*6b4cac81SBjoern A. Zeeb struct ieee80211_radiotap_header wt_ihdr; 47*6b4cac81SBjoern A. Zeeb uint8_t wt_flags; 48*6b4cac81SBjoern A. Zeeb uint8_t wt_rate; 49*6b4cac81SBjoern A. Zeeb uint16_t wt_chan_freq; 50*6b4cac81SBjoern A. Zeeb uint16_t wt_chan_flags; 51*6b4cac81SBjoern A. Zeeb } __packed; 52*6b4cac81SBjoern A. Zeeb #define LKPI_RTAP_TX_FLAGS_PRESENT \ 53*6b4cac81SBjoern A. Zeeb ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 54*6b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_RATE) | \ 55*6b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_CHANNEL)) 56*6b4cac81SBjoern A. Zeeb 57*6b4cac81SBjoern A. Zeeb struct lkpi_radiotap_rx_hdr { 58*6b4cac81SBjoern A. Zeeb struct ieee80211_radiotap_header wr_ihdr; 59*6b4cac81SBjoern A. Zeeb uint64_t wr_tsft; 60*6b4cac81SBjoern A. Zeeb uint8_t wr_flags; 61*6b4cac81SBjoern A. Zeeb uint8_t wr_rate; 62*6b4cac81SBjoern A. Zeeb uint16_t wr_chan_freq; 63*6b4cac81SBjoern A. Zeeb uint16_t wr_chan_flags; 64*6b4cac81SBjoern A. Zeeb int8_t wr_dbm_antsignal; 65*6b4cac81SBjoern A. Zeeb int8_t wr_dbm_antnoise; 66*6b4cac81SBjoern A. Zeeb } __packed __aligned(8); 67*6b4cac81SBjoern A. Zeeb #define LKPI_RTAP_RX_FLAGS_PRESENT \ 68*6b4cac81SBjoern A. Zeeb ((1 << IEEE80211_RADIOTAP_TSFT) | \ 69*6b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_FLAGS) | \ 70*6b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_RATE) | \ 71*6b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 72*6b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 73*6b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 74*6b4cac81SBjoern A. Zeeb 75*6b4cac81SBjoern A. Zeeb struct lkpi_txq { 76*6b4cac81SBjoern A. Zeeb bool seen_dequeue; 77*6b4cac81SBjoern A. Zeeb struct sk_buff_head skbq; 78*6b4cac81SBjoern A. Zeeb 79*6b4cac81SBjoern A. Zeeb /* Must be last! */ 80*6b4cac81SBjoern A. Zeeb struct ieee80211_txq txq __aligned(CACHE_LINE_SIZE); 81*6b4cac81SBjoern A. Zeeb }; 82*6b4cac81SBjoern A. Zeeb #define TXQ_TO_LTXQ(_txq) container_of(_txq, struct lkpi_txq, txq) 83*6b4cac81SBjoern A. Zeeb 84*6b4cac81SBjoern A. Zeeb 85*6b4cac81SBjoern A. Zeeb struct lkpi_sta { 86*6b4cac81SBjoern A. Zeeb TAILQ_ENTRY(lkpi_sta) lsta_entry; 87*6b4cac81SBjoern A. Zeeb struct ieee80211_node *ni; 88*6b4cac81SBjoern A. Zeeb 89*6b4cac81SBjoern A. Zeeb /* Deferred TX path. */ 90*6b4cac81SBjoern A. Zeeb /* Eventually we might want to migrate this into net80211 entirely. */ 91*6b4cac81SBjoern A. Zeeb /* XXX-BZ can we use sta->txq[] instead directly? */ 92*6b4cac81SBjoern A. Zeeb struct task txq_task; 93*6b4cac81SBjoern A. Zeeb struct mbufq txq; 94*6b4cac81SBjoern A. Zeeb struct mtx txq_mtx; 95*6b4cac81SBjoern A. Zeeb 96*6b4cac81SBjoern A. Zeeb struct ieee80211_key_conf *kc; 97*6b4cac81SBjoern A. Zeeb enum ieee80211_sta_state state; 98*6b4cac81SBjoern A. Zeeb bool added_to_drv; /* Driver knows; i.e. we called ...(). */ 99*6b4cac81SBjoern A. Zeeb bool in_mgd; 100*6b4cac81SBjoern A. Zeeb 101*6b4cac81SBjoern A. Zeeb /* Must be last! */ 102*6b4cac81SBjoern A. Zeeb struct ieee80211_sta sta __aligned(CACHE_LINE_SIZE); 103*6b4cac81SBjoern A. Zeeb }; 104*6b4cac81SBjoern A. Zeeb #define STA_TO_LSTA(_sta) container_of(_sta, struct lkpi_sta, sta) 105*6b4cac81SBjoern A. Zeeb #define LSTA_TO_STA(_lsta) (&(_lsta)->sta) 106*6b4cac81SBjoern A. Zeeb 107*6b4cac81SBjoern A. Zeeb struct lkpi_vif { 108*6b4cac81SBjoern A. Zeeb TAILQ_ENTRY(lkpi_vif) lvif_entry; 109*6b4cac81SBjoern A. Zeeb struct ieee80211vap iv_vap; 110*6b4cac81SBjoern A. Zeeb 111*6b4cac81SBjoern A. Zeeb struct mtx mtx; 112*6b4cac81SBjoern A. Zeeb struct wireless_dev wdev; 113*6b4cac81SBjoern A. Zeeb 114*6b4cac81SBjoern A. Zeeb /* Other local stuff. */ 115*6b4cac81SBjoern A. Zeeb int (*iv_newstate)(struct ieee80211vap *, 116*6b4cac81SBjoern A. Zeeb enum ieee80211_state, int); 117*6b4cac81SBjoern A. Zeeb TAILQ_HEAD(, lkpi_sta) lsta_head; 118*6b4cac81SBjoern A. Zeeb bool added_to_drv; /* Driver knows; i.e. we called add_interface(). */ 119*6b4cac81SBjoern A. Zeeb 120*6b4cac81SBjoern A. Zeeb /* Must be last! */ 121*6b4cac81SBjoern A. Zeeb struct ieee80211_vif vif __aligned(CACHE_LINE_SIZE); 122*6b4cac81SBjoern A. Zeeb }; 123*6b4cac81SBjoern A. Zeeb #define VAP_TO_LVIF(_vap) container_of(_vap, struct lkpi_vif, iv_vap) 124*6b4cac81SBjoern A. Zeeb #define LVIF_TO_VAP(_lvif) (&(_lvif)->iv_vap) 125*6b4cac81SBjoern A. Zeeb #define VIF_TO_LVIF(_vif) container_of(_vif, struct lkpi_vif, vif) 126*6b4cac81SBjoern A. Zeeb #define LVIF_TO_VIF(_lvif) (&(_lvif)->vif) 127*6b4cac81SBjoern A. Zeeb 128*6b4cac81SBjoern A. Zeeb 129*6b4cac81SBjoern A. Zeeb struct lkpi_hw { /* name it mac80211_sc? */ 130*6b4cac81SBjoern A. Zeeb const struct ieee80211_ops *ops; 131*6b4cac81SBjoern A. Zeeb struct ieee80211_scan_request *hw_req; 132*6b4cac81SBjoern A. Zeeb struct workqueue_struct *workq; 133*6b4cac81SBjoern A. Zeeb 134*6b4cac81SBjoern A. Zeeb /* FreeBSD specific compat. */ 135*6b4cac81SBjoern A. Zeeb /* Linux device is in hw.wiphy->dev after SET_IEEE80211_DEV(). */ 136*6b4cac81SBjoern A. Zeeb struct ieee80211com *ic; 137*6b4cac81SBjoern A. Zeeb struct lkpi_radiotap_tx_hdr rtap_tx; 138*6b4cac81SBjoern A. Zeeb struct lkpi_radiotap_rx_hdr rtap_rx; 139*6b4cac81SBjoern A. Zeeb 140*6b4cac81SBjoern A. Zeeb TAILQ_HEAD(, lkpi_vif) lvif_head; 141*6b4cac81SBjoern A. Zeeb 142*6b4cac81SBjoern A. Zeeb struct mtx mtx; 143*6b4cac81SBjoern A. Zeeb 144*6b4cac81SBjoern A. Zeeb /* Node functions we overload to sync state. */ 145*6b4cac81SBjoern A. Zeeb struct ieee80211_node * (*ic_node_alloc)(struct ieee80211vap *, 146*6b4cac81SBjoern A. Zeeb const uint8_t [IEEE80211_ADDR_LEN]); 147*6b4cac81SBjoern A. Zeeb int (*ic_node_init)(struct ieee80211_node *); 148*6b4cac81SBjoern A. Zeeb void (*ic_node_cleanup)(struct ieee80211_node *); 149*6b4cac81SBjoern A. Zeeb void (*ic_node_free)(struct ieee80211_node *); 150*6b4cac81SBjoern A. Zeeb 151*6b4cac81SBjoern A. Zeeb #define LKPI_MAC80211_DRV_STARTED 0x00000001 152*6b4cac81SBjoern A. Zeeb uint32_t sc_flags; 153*6b4cac81SBjoern A. Zeeb #define LKPI_SCAN_RUNNING 0x00000001 154*6b4cac81SBjoern A. Zeeb uint32_t scan_flags; 155*6b4cac81SBjoern A. Zeeb bool update_mc; 156*6b4cac81SBjoern A. Zeeb 157*6b4cac81SBjoern A. Zeeb /* Must be last! */ 158*6b4cac81SBjoern A. Zeeb struct ieee80211_hw hw __aligned(CACHE_LINE_SIZE); 159*6b4cac81SBjoern A. Zeeb }; 160*6b4cac81SBjoern A. Zeeb #define LHW_TO_HW(_lhw) (&(_lhw)->hw) 161*6b4cac81SBjoern A. Zeeb #define HW_TO_LHW(_hw) container_of(_hw, struct lkpi_hw, hw) 162*6b4cac81SBjoern A. Zeeb 163*6b4cac81SBjoern A. Zeeb struct lkpi_wiphy { 164*6b4cac81SBjoern A. Zeeb const struct cfg80211_ops *ops; 165*6b4cac81SBjoern A. Zeeb 166*6b4cac81SBjoern A. Zeeb /* Must be last! */ 167*6b4cac81SBjoern A. Zeeb struct wiphy wiphy __aligned(CACHE_LINE_SIZE); 168*6b4cac81SBjoern A. Zeeb }; 169*6b4cac81SBjoern A. Zeeb #define WIPHY_TO_LWIPHY(_wiphy) container_of(_wiphy, struct lkpi_wiphy, wiphy) 170*6b4cac81SBjoern A. Zeeb #define LWIPHY_TO_WIPHY(_lwiphy) (&(_lwiphy)->wiphy) 171*6b4cac81SBjoern A. Zeeb 172*6b4cac81SBjoern A. Zeeb 173*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_LOCK(_lhw) mtx_lock(&(_lhw)->mtx) 174*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_UNLOCK(_lhw) mtx_unlock(&(_lhw)->mtx) 175*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_LOCK_ASSERT(_lhw) \ 176*6b4cac81SBjoern A. Zeeb mtx_assert(&(_lhw)->mtx, MA_OWNED) 177*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_UNLOCK_ASSERT(_lhw) \ 178*6b4cac81SBjoern A. Zeeb mtx_assert(&(_lhw)->mtx, MA_NOTOWNED) 179*6b4cac81SBjoern A. Zeeb 180*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LVIF_LOCK(_lvif) mtx_lock(&(_lvif)->mtx) 181*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LVIF_UNLOCK(_lvif) mtx_unlock(&(_lvif)->mtx) 182*6b4cac81SBjoern A. Zeeb 183*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LSTA_LOCK(_lsta) mtx_lock(&(_lsta)->txq_mtx) 184*6b4cac81SBjoern A. Zeeb #define LKPI_80211_LSTA_UNLOCK(_lsta) mtx_unlock(&(_lsta)->txq_mtx) 185*6b4cac81SBjoern A. Zeeb 186*6b4cac81SBjoern A. Zeeb 187*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_start(struct ieee80211_hw *); 188*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_stop(struct ieee80211_hw *); 189*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_set_frag_threshold(struct ieee80211_hw *, uint32_t); 190*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_set_rts_threshold(struct ieee80211_hw *, uint32_t); 191*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_add_interface(struct ieee80211_hw *, struct ieee80211_vif *); 192*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_remove_interface(struct ieee80211_hw *, struct ieee80211_vif *); 193*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *, 194*6b4cac81SBjoern A. Zeeb struct ieee80211_scan_request *); 195*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_cancel_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *); 196*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sw_scan_complete(struct ieee80211_hw *, struct ieee80211_vif *); 197*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sw_scan_start(struct ieee80211_hw *, struct ieee80211_vif *, 198*6b4cac81SBjoern A. Zeeb const u8 *); 199*6b4cac81SBjoern A. Zeeb u64 lkpi_80211_mo_prepare_multicast(struct ieee80211_hw *, 200*6b4cac81SBjoern A. Zeeb struct netdev_hw_addr_list *); 201*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_configure_filter(struct ieee80211_hw *, unsigned int, 202*6b4cac81SBjoern A. Zeeb unsigned int *, u64); 203*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_sta_state(struct ieee80211_hw *, struct ieee80211_vif *, 204*6b4cac81SBjoern A. Zeeb struct ieee80211_sta *, enum ieee80211_sta_state); 205*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_config(struct ieee80211_hw *, uint32_t); 206*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_assign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *, 207*6b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf *); 208*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_unassign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *, 209*6b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf **); 210*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_add_chanctx(struct ieee80211_hw *, struct ieee80211_chanctx_conf *); 211*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_change_chanctx(struct ieee80211_hw *, 212*6b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf *, uint32_t); 213*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *, 214*6b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf *); 215*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *, struct ieee80211_vif *, 216*6b4cac81SBjoern A. Zeeb struct ieee80211_bss_conf *, uint32_t); 217*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_conf_tx(struct ieee80211_hw *, struct ieee80211_vif *, 218*6b4cac81SBjoern A. Zeeb uint16_t, const struct ieee80211_tx_queue_params *); 219*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_flush(struct ieee80211_hw *, struct ieee80211_vif *, 220*6b4cac81SBjoern A. Zeeb uint32_t, bool); 221*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_mgd_prepare_tx(struct ieee80211_hw *, struct ieee80211_vif *, 222*6b4cac81SBjoern A. Zeeb struct ieee80211_prep_tx_info *); 223*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_mgd_complete_tx(struct ieee80211_hw *, struct ieee80211_vif *, 224*6b4cac81SBjoern A. Zeeb struct ieee80211_prep_tx_info *); 225*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_tx(struct ieee80211_hw *, struct ieee80211_tx_control *, 226*6b4cac81SBjoern A. Zeeb struct sk_buff *); 227*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *, struct ieee80211_txq *); 228*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sync_rx_queues(struct ieee80211_hw *); 229*6b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sta_pre_rcu_remove(struct ieee80211_hw *, 230*6b4cac81SBjoern A. Zeeb struct ieee80211_vif *, struct ieee80211_sta *); 231*6b4cac81SBjoern A. Zeeb int lkpi_80211_mo_set_key(struct ieee80211_hw *, enum set_key_cmd, 232*6b4cac81SBjoern A. Zeeb struct ieee80211_vif *, struct ieee80211_sta *, 233*6b4cac81SBjoern A. Zeeb struct ieee80211_key_conf *); 234*6b4cac81SBjoern A. Zeeb 235*6b4cac81SBjoern A. Zeeb #endif /* _LKPI_SRC_LINUX_80211_H */ 236