16b4cac81SBjoern A. Zeeb /*- 2d9f59799SBjoern A. Zeeb * Copyright (c) 2020-2022 The FreeBSD Foundation 36b4cac81SBjoern A. Zeeb * Copyright (c) 2020-2021 Bjoern A. Zeeb 46b4cac81SBjoern A. Zeeb * 56b4cac81SBjoern A. Zeeb * This software was developed by Björn Zeeb under sponsorship from 66b4cac81SBjoern A. Zeeb * the FreeBSD Foundation. 76b4cac81SBjoern A. Zeeb * 86b4cac81SBjoern A. Zeeb * Redistribution and use in source and binary forms, with or without 96b4cac81SBjoern A. Zeeb * modification, are permitted provided that the following conditions 106b4cac81SBjoern A. Zeeb * are met: 116b4cac81SBjoern A. Zeeb * 1. Redistributions of source code must retain the above copyright 126b4cac81SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer. 136b4cac81SBjoern A. Zeeb * 2. Redistributions in binary form must reproduce the above copyright 146b4cac81SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer in the 156b4cac81SBjoern A. Zeeb * documentation and/or other materials provided with the distribution. 166b4cac81SBjoern A. Zeeb * 176b4cac81SBjoern A. Zeeb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 186b4cac81SBjoern A. Zeeb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 196b4cac81SBjoern A. Zeeb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 206b4cac81SBjoern A. Zeeb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 216b4cac81SBjoern A. Zeeb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 226b4cac81SBjoern A. Zeeb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 236b4cac81SBjoern A. Zeeb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 246b4cac81SBjoern A. Zeeb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 256b4cac81SBjoern A. Zeeb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 266b4cac81SBjoern A. Zeeb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 276b4cac81SBjoern A. Zeeb * SUCH DAMAGE. 286b4cac81SBjoern A. Zeeb */ 296b4cac81SBjoern A. Zeeb 306b4cac81SBjoern A. Zeeb /* 316b4cac81SBjoern A. Zeeb * Public functions are called linuxkpi_*(). 326b4cac81SBjoern A. Zeeb * Internal (static) functions are called lkpi_*(). 336b4cac81SBjoern A. Zeeb * 346b4cac81SBjoern A. Zeeb * The internal structures holding metadata over public structures are also 356b4cac81SBjoern A. Zeeb * called lkpi_xxx (usually with a member at the end called xxx). 366b4cac81SBjoern A. Zeeb * Note: we do not replicate the structure names but the general variable names 376b4cac81SBjoern A. Zeeb * for these (e.g., struct hw -> struct lkpi_hw, struct sta -> struct lkpi_sta). 386b4cac81SBjoern A. Zeeb * There are macros to access one from the other. 396b4cac81SBjoern A. Zeeb * We call the internal versions lxxx (e.g., hw -> lhw, sta -> lsta). 406b4cac81SBjoern A. Zeeb */ 416b4cac81SBjoern A. Zeeb 426b4cac81SBjoern A. Zeeb #ifndef _LKPI_SRC_LINUX_80211_H 436b4cac81SBjoern A. Zeeb #define _LKPI_SRC_LINUX_80211_H 446b4cac81SBjoern A. Zeeb 456b4cac81SBjoern A. Zeeb struct lkpi_radiotap_tx_hdr { 466b4cac81SBjoern A. Zeeb struct ieee80211_radiotap_header wt_ihdr; 476b4cac81SBjoern A. Zeeb uint8_t wt_flags; 486b4cac81SBjoern A. Zeeb uint8_t wt_rate; 496b4cac81SBjoern A. Zeeb uint16_t wt_chan_freq; 506b4cac81SBjoern A. Zeeb uint16_t wt_chan_flags; 516b4cac81SBjoern A. Zeeb } __packed; 526b4cac81SBjoern A. Zeeb #define LKPI_RTAP_TX_FLAGS_PRESENT \ 536b4cac81SBjoern A. Zeeb ((1 << IEEE80211_RADIOTAP_FLAGS) | \ 546b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_RATE) | \ 556b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_CHANNEL)) 566b4cac81SBjoern A. Zeeb 576b4cac81SBjoern A. Zeeb struct lkpi_radiotap_rx_hdr { 586b4cac81SBjoern A. Zeeb struct ieee80211_radiotap_header wr_ihdr; 596b4cac81SBjoern A. Zeeb uint64_t wr_tsft; 606b4cac81SBjoern A. Zeeb uint8_t wr_flags; 616b4cac81SBjoern A. Zeeb uint8_t wr_rate; 626b4cac81SBjoern A. Zeeb uint16_t wr_chan_freq; 636b4cac81SBjoern A. Zeeb uint16_t wr_chan_flags; 646b4cac81SBjoern A. Zeeb int8_t wr_dbm_antsignal; 656b4cac81SBjoern A. Zeeb int8_t wr_dbm_antnoise; 666b4cac81SBjoern A. Zeeb } __packed __aligned(8); 676b4cac81SBjoern A. Zeeb #define LKPI_RTAP_RX_FLAGS_PRESENT \ 686b4cac81SBjoern A. Zeeb ((1 << IEEE80211_RADIOTAP_TSFT) | \ 696b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_FLAGS) | \ 706b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_RATE) | \ 716b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_CHANNEL) | \ 726b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ 736b4cac81SBjoern A. Zeeb (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) 746b4cac81SBjoern A. Zeeb 756b4cac81SBjoern A. Zeeb struct lkpi_txq { 766b4cac81SBjoern A. Zeeb bool seen_dequeue; 776b4cac81SBjoern A. Zeeb struct sk_buff_head skbq; 786b4cac81SBjoern A. Zeeb 796b4cac81SBjoern A. Zeeb /* Must be last! */ 806b4cac81SBjoern A. Zeeb struct ieee80211_txq txq __aligned(CACHE_LINE_SIZE); 816b4cac81SBjoern A. Zeeb }; 826b4cac81SBjoern A. Zeeb #define TXQ_TO_LTXQ(_txq) container_of(_txq, struct lkpi_txq, txq) 836b4cac81SBjoern A. Zeeb 846b4cac81SBjoern A. Zeeb 856b4cac81SBjoern A. Zeeb struct lkpi_sta { 866b4cac81SBjoern A. Zeeb TAILQ_ENTRY(lkpi_sta) lsta_entry; 876b4cac81SBjoern A. Zeeb struct ieee80211_node *ni; 886b4cac81SBjoern A. Zeeb 896b4cac81SBjoern A. Zeeb /* Deferred TX path. */ 906b4cac81SBjoern A. Zeeb /* Eventually we might want to migrate this into net80211 entirely. */ 916b4cac81SBjoern A. Zeeb /* XXX-BZ can we use sta->txq[] instead directly? */ 926b4cac81SBjoern A. Zeeb struct task txq_task; 936b4cac81SBjoern A. Zeeb struct mbufq txq; 946b4cac81SBjoern A. Zeeb struct mtx txq_mtx; 956b4cac81SBjoern A. Zeeb 966b4cac81SBjoern A. Zeeb struct ieee80211_key_conf *kc; 976b4cac81SBjoern A. Zeeb enum ieee80211_sta_state state; 986b4cac81SBjoern A. Zeeb bool added_to_drv; /* Driver knows; i.e. we called ...(). */ 99d9f59799SBjoern A. Zeeb bool in_mgd; /* XXX-BZ should this be per-vif? */ 1006b4cac81SBjoern A. Zeeb 1016b4cac81SBjoern A. Zeeb /* Must be last! */ 1026b4cac81SBjoern A. Zeeb struct ieee80211_sta sta __aligned(CACHE_LINE_SIZE); 1036b4cac81SBjoern A. Zeeb }; 1046b4cac81SBjoern A. Zeeb #define STA_TO_LSTA(_sta) container_of(_sta, struct lkpi_sta, sta) 1056b4cac81SBjoern A. Zeeb #define LSTA_TO_STA(_lsta) (&(_lsta)->sta) 1066b4cac81SBjoern A. Zeeb 1076b4cac81SBjoern A. Zeeb struct lkpi_vif { 1086b4cac81SBjoern A. Zeeb TAILQ_ENTRY(lkpi_vif) lvif_entry; 1096b4cac81SBjoern A. Zeeb struct ieee80211vap iv_vap; 1106b4cac81SBjoern A. Zeeb 1116b4cac81SBjoern A. Zeeb struct mtx mtx; 1126b4cac81SBjoern A. Zeeb struct wireless_dev wdev; 1136b4cac81SBjoern A. Zeeb 1146b4cac81SBjoern A. Zeeb /* Other local stuff. */ 1156b4cac81SBjoern A. Zeeb int (*iv_newstate)(struct ieee80211vap *, 1166b4cac81SBjoern A. Zeeb enum ieee80211_state, int); 117d9f59799SBjoern A. Zeeb struct ieee80211_node * (*iv_update_bss)(struct ieee80211vap *, 118d9f59799SBjoern A. Zeeb struct ieee80211_node *); 1196b4cac81SBjoern A. Zeeb TAILQ_HEAD(, lkpi_sta) lsta_head; 1206b4cac81SBjoern A. Zeeb bool added_to_drv; /* Driver knows; i.e. we called add_interface(). */ 1216b4cac81SBjoern A. Zeeb 1226b4cac81SBjoern A. Zeeb /* Must be last! */ 1236b4cac81SBjoern A. Zeeb struct ieee80211_vif vif __aligned(CACHE_LINE_SIZE); 1246b4cac81SBjoern A. Zeeb }; 1256b4cac81SBjoern A. Zeeb #define VAP_TO_LVIF(_vap) container_of(_vap, struct lkpi_vif, iv_vap) 1266b4cac81SBjoern A. Zeeb #define LVIF_TO_VAP(_lvif) (&(_lvif)->iv_vap) 1276b4cac81SBjoern A. Zeeb #define VIF_TO_LVIF(_vif) container_of(_vif, struct lkpi_vif, vif) 1286b4cac81SBjoern A. Zeeb #define LVIF_TO_VIF(_lvif) (&(_lvif)->vif) 1296b4cac81SBjoern A. Zeeb 1306b4cac81SBjoern A. Zeeb 1316b4cac81SBjoern A. Zeeb struct lkpi_hw { /* name it mac80211_sc? */ 1326b4cac81SBjoern A. Zeeb const struct ieee80211_ops *ops; 1336b4cac81SBjoern A. Zeeb struct ieee80211_scan_request *hw_req; 1346b4cac81SBjoern A. Zeeb struct workqueue_struct *workq; 1356b4cac81SBjoern A. Zeeb 1366b4cac81SBjoern A. Zeeb /* FreeBSD specific compat. */ 1376b4cac81SBjoern A. Zeeb /* Linux device is in hw.wiphy->dev after SET_IEEE80211_DEV(). */ 1386b4cac81SBjoern A. Zeeb struct ieee80211com *ic; 1396b4cac81SBjoern A. Zeeb struct lkpi_radiotap_tx_hdr rtap_tx; 1406b4cac81SBjoern A. Zeeb struct lkpi_radiotap_rx_hdr rtap_rx; 1416b4cac81SBjoern A. Zeeb 1426b4cac81SBjoern A. Zeeb TAILQ_HEAD(, lkpi_vif) lvif_head; 1438891c455SBjoern A. Zeeb struct sx lvif_sx; 1446b4cac81SBjoern A. Zeeb 1456b4cac81SBjoern A. Zeeb struct mtx mtx; 1466b4cac81SBjoern A. Zeeb 1476b4cac81SBjoern A. Zeeb /* Node functions we overload to sync state. */ 1486b4cac81SBjoern A. Zeeb struct ieee80211_node * (*ic_node_alloc)(struct ieee80211vap *, 1496b4cac81SBjoern A. Zeeb const uint8_t [IEEE80211_ADDR_LEN]); 1506b4cac81SBjoern A. Zeeb int (*ic_node_init)(struct ieee80211_node *); 1516b4cac81SBjoern A. Zeeb void (*ic_node_cleanup)(struct ieee80211_node *); 1526b4cac81SBjoern A. Zeeb void (*ic_node_free)(struct ieee80211_node *); 1536b4cac81SBjoern A. Zeeb 1546b4cac81SBjoern A. Zeeb #define LKPI_MAC80211_DRV_STARTED 0x00000001 1556b4cac81SBjoern A. Zeeb uint32_t sc_flags; 1566b4cac81SBjoern A. Zeeb #define LKPI_SCAN_RUNNING 0x00000001 1576b4cac81SBjoern A. Zeeb uint32_t scan_flags; 158*d9945d78SBjoern A. Zeeb 159*d9945d78SBjoern A. Zeeb int supbands; /* Number of supported bands. */ 160*d9945d78SBjoern A. Zeeb int max_rates; /* Maximum number of bitrates supported in any channel. */ 161*d9945d78SBjoern A. Zeeb int scan_ie_len; /* Length of common per-band scan IEs. */ 162*d9945d78SBjoern A. Zeeb 1636b4cac81SBjoern A. Zeeb bool update_mc; 1646b4cac81SBjoern A. Zeeb 1656b4cac81SBjoern A. Zeeb /* Must be last! */ 1666b4cac81SBjoern A. Zeeb struct ieee80211_hw hw __aligned(CACHE_LINE_SIZE); 1676b4cac81SBjoern A. Zeeb }; 1686b4cac81SBjoern A. Zeeb #define LHW_TO_HW(_lhw) (&(_lhw)->hw) 1696b4cac81SBjoern A. Zeeb #define HW_TO_LHW(_hw) container_of(_hw, struct lkpi_hw, hw) 1706b4cac81SBjoern A. Zeeb 1716b4cac81SBjoern A. Zeeb struct lkpi_wiphy { 1726b4cac81SBjoern A. Zeeb const struct cfg80211_ops *ops; 1736b4cac81SBjoern A. Zeeb 1746b4cac81SBjoern A. Zeeb /* Must be last! */ 1756b4cac81SBjoern A. Zeeb struct wiphy wiphy __aligned(CACHE_LINE_SIZE); 1766b4cac81SBjoern A. Zeeb }; 1776b4cac81SBjoern A. Zeeb #define WIPHY_TO_LWIPHY(_wiphy) container_of(_wiphy, struct lkpi_wiphy, wiphy) 1786b4cac81SBjoern A. Zeeb #define LWIPHY_TO_WIPHY(_lwiphy) (&(_lwiphy)->wiphy) 1796b4cac81SBjoern A. Zeeb 1806b4cac81SBjoern A. Zeeb 1816b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_LOCK(_lhw) mtx_lock(&(_lhw)->mtx) 1826b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_UNLOCK(_lhw) mtx_unlock(&(_lhw)->mtx) 1836b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_LOCK_ASSERT(_lhw) \ 1846b4cac81SBjoern A. Zeeb mtx_assert(&(_lhw)->mtx, MA_OWNED) 1856b4cac81SBjoern A. Zeeb #define LKPI_80211_LHW_UNLOCK_ASSERT(_lhw) \ 1866b4cac81SBjoern A. Zeeb mtx_assert(&(_lhw)->mtx, MA_NOTOWNED) 1876b4cac81SBjoern A. Zeeb 1888891c455SBjoern A. Zeeb #define LKPI_80211_LHW_LVIF_LOCK(_lhw) sx_xlock(&(_lhw)->lvif_sx) 1898891c455SBjoern A. Zeeb #define LKPI_80211_LHW_LVIF_UNLOCK(_lhw) sx_xunlock(&(_lhw)->lvif_sx) 1908891c455SBjoern A. Zeeb 1916b4cac81SBjoern A. Zeeb #define LKPI_80211_LVIF_LOCK(_lvif) mtx_lock(&(_lvif)->mtx) 1926b4cac81SBjoern A. Zeeb #define LKPI_80211_LVIF_UNLOCK(_lvif) mtx_unlock(&(_lvif)->mtx) 1936b4cac81SBjoern A. Zeeb 1946b4cac81SBjoern A. Zeeb #define LKPI_80211_LSTA_LOCK(_lsta) mtx_lock(&(_lsta)->txq_mtx) 1956b4cac81SBjoern A. Zeeb #define LKPI_80211_LSTA_UNLOCK(_lsta) mtx_unlock(&(_lsta)->txq_mtx) 1966b4cac81SBjoern A. Zeeb 1976b4cac81SBjoern A. Zeeb 1986b4cac81SBjoern A. Zeeb int lkpi_80211_mo_start(struct ieee80211_hw *); 1996b4cac81SBjoern A. Zeeb void lkpi_80211_mo_stop(struct ieee80211_hw *); 2006b4cac81SBjoern A. Zeeb int lkpi_80211_mo_set_frag_threshold(struct ieee80211_hw *, uint32_t); 2016b4cac81SBjoern A. Zeeb int lkpi_80211_mo_set_rts_threshold(struct ieee80211_hw *, uint32_t); 2026b4cac81SBjoern A. Zeeb int lkpi_80211_mo_add_interface(struct ieee80211_hw *, struct ieee80211_vif *); 2036b4cac81SBjoern A. Zeeb void lkpi_80211_mo_remove_interface(struct ieee80211_hw *, struct ieee80211_vif *); 2046b4cac81SBjoern A. Zeeb int lkpi_80211_mo_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *, 2056b4cac81SBjoern A. Zeeb struct ieee80211_scan_request *); 2066b4cac81SBjoern A. Zeeb void lkpi_80211_mo_cancel_hw_scan(struct ieee80211_hw *, struct ieee80211_vif *); 2076b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sw_scan_complete(struct ieee80211_hw *, struct ieee80211_vif *); 2086b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sw_scan_start(struct ieee80211_hw *, struct ieee80211_vif *, 2096b4cac81SBjoern A. Zeeb const u8 *); 2106b4cac81SBjoern A. Zeeb u64 lkpi_80211_mo_prepare_multicast(struct ieee80211_hw *, 2116b4cac81SBjoern A. Zeeb struct netdev_hw_addr_list *); 2126b4cac81SBjoern A. Zeeb void lkpi_80211_mo_configure_filter(struct ieee80211_hw *, unsigned int, 2136b4cac81SBjoern A. Zeeb unsigned int *, u64); 2146b4cac81SBjoern A. Zeeb int lkpi_80211_mo_sta_state(struct ieee80211_hw *, struct ieee80211_vif *, 2156b4cac81SBjoern A. Zeeb struct ieee80211_sta *, enum ieee80211_sta_state); 2166b4cac81SBjoern A. Zeeb int lkpi_80211_mo_config(struct ieee80211_hw *, uint32_t); 2176b4cac81SBjoern A. Zeeb int lkpi_80211_mo_assign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *, 2186b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf *); 2196b4cac81SBjoern A. Zeeb void lkpi_80211_mo_unassign_vif_chanctx(struct ieee80211_hw *, struct ieee80211_vif *, 2206b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf **); 2216b4cac81SBjoern A. Zeeb int lkpi_80211_mo_add_chanctx(struct ieee80211_hw *, struct ieee80211_chanctx_conf *); 2226b4cac81SBjoern A. Zeeb void lkpi_80211_mo_change_chanctx(struct ieee80211_hw *, 2236b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf *, uint32_t); 2246b4cac81SBjoern A. Zeeb void lkpi_80211_mo_remove_chanctx(struct ieee80211_hw *, 2256b4cac81SBjoern A. Zeeb struct ieee80211_chanctx_conf *); 2266b4cac81SBjoern A. Zeeb void lkpi_80211_mo_bss_info_changed(struct ieee80211_hw *, struct ieee80211_vif *, 2276b4cac81SBjoern A. Zeeb struct ieee80211_bss_conf *, uint32_t); 2286b4cac81SBjoern A. Zeeb int lkpi_80211_mo_conf_tx(struct ieee80211_hw *, struct ieee80211_vif *, 2296b4cac81SBjoern A. Zeeb uint16_t, const struct ieee80211_tx_queue_params *); 2306b4cac81SBjoern A. Zeeb void lkpi_80211_mo_flush(struct ieee80211_hw *, struct ieee80211_vif *, 2316b4cac81SBjoern A. Zeeb uint32_t, bool); 2326b4cac81SBjoern A. Zeeb void lkpi_80211_mo_mgd_prepare_tx(struct ieee80211_hw *, struct ieee80211_vif *, 2336b4cac81SBjoern A. Zeeb struct ieee80211_prep_tx_info *); 2346b4cac81SBjoern A. Zeeb void lkpi_80211_mo_mgd_complete_tx(struct ieee80211_hw *, struct ieee80211_vif *, 2356b4cac81SBjoern A. Zeeb struct ieee80211_prep_tx_info *); 2366b4cac81SBjoern A. Zeeb void lkpi_80211_mo_tx(struct ieee80211_hw *, struct ieee80211_tx_control *, 2376b4cac81SBjoern A. Zeeb struct sk_buff *); 2386b4cac81SBjoern A. Zeeb void lkpi_80211_mo_wake_tx_queue(struct ieee80211_hw *, struct ieee80211_txq *); 2396b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sync_rx_queues(struct ieee80211_hw *); 2406b4cac81SBjoern A. Zeeb void lkpi_80211_mo_sta_pre_rcu_remove(struct ieee80211_hw *, 2416b4cac81SBjoern A. Zeeb struct ieee80211_vif *, struct ieee80211_sta *); 2426b4cac81SBjoern A. Zeeb int lkpi_80211_mo_set_key(struct ieee80211_hw *, enum set_key_cmd, 2436b4cac81SBjoern A. Zeeb struct ieee80211_vif *, struct ieee80211_sta *, 2446b4cac81SBjoern A. Zeeb struct ieee80211_key_conf *); 2456b4cac81SBjoern A. Zeeb 2466b4cac81SBjoern A. Zeeb #endif /* _LKPI_SRC_LINUX_80211_H */ 247